001 //$HeadURL$
002 /*----------------------------------------------------------------------------
003 This file is part of deegree, http://deegree.org/
004 Copyright (C) 2001-2009 by:
005 Department of Geography, University of Bonn
006 and
007 lat/lon GmbH
008
009 This library is free software; you can redistribute it and/or modify it under
010 the terms of the GNU Lesser General Public License as published by the Free
011 Software Foundation; either version 2.1 of the License, or (at your option)
012 any later version.
013 This library is distributed in the hope that it will be useful, but WITHOUT
014 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
015 FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
016 details.
017 You should have received a copy of the GNU Lesser General Public License
018 along with this library; if not, write to the Free Software Foundation, Inc.,
019 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
020
021 Contact information:
022
023 lat/lon GmbH
024 Aennchenstr. 19, 53177 Bonn
025 Germany
026 http://lat-lon.de/
027
028 Department of Geography, University of Bonn
029 Prof. Dr. Klaus Greve
030 Postfach 1147, 53001 Bonn
031 Germany
032 http://www.geographie.uni-bonn.de/deegree/
033
034 e-mail: info@deegree.org
035 ----------------------------------------------------------------------------*/
036
037 package org.deegree.ogcwebservices.csw.manager;
038
039 import java.io.InputStream;
040 import java.net.MalformedURLException;
041 import java.net.URI;
042 import java.util.ArrayList;
043 import java.util.List;
044 import java.util.Map;
045
046 import org.deegree.framework.log.ILogger;
047 import org.deegree.framework.log.LoggerFactory;
048 import org.deegree.framework.xml.ElementList;
049 import org.deegree.framework.xml.XMLException;
050 import org.deegree.framework.xml.XMLFragment;
051 import org.deegree.framework.xml.XMLParsingException;
052 import org.deegree.framework.xml.XMLTools;
053 import org.deegree.i18n.Messages;
054 import org.deegree.model.filterencoding.AbstractFilter;
055 import org.deegree.model.filterencoding.Filter;
056 import org.deegree.ogcbase.CommonNamespaces;
057 import org.deegree.ogcbase.ExceptionCode;
058 import org.deegree.ogcwebservices.InvalidParameterValueException;
059 import org.deegree.ogcwebservices.MissingParameterValueException;
060 import org.deegree.ogcwebservices.OGCWebServiceException;
061 import org.w3c.dom.Document;
062 import org.w3c.dom.Element;
063 import org.w3c.dom.Node;
064
065 /**
066 *
067 *
068 * @author <a href="mailto:poth@lat-lon.de">Andreas Poth</a>
069 * @author last edited by: $Author: poth $
070 *
071 * @version $Revision: 6251 $, $Date: 2007-03-19 16:59:28 +0100 (Mo, 19 Mrz 2007) $
072 */
073 public class TransactionDocument_2_0_2 extends TransactionDocument {
074
075 private static final long serialVersionUID = 6197050847554898458L;
076
077 protected static final ILogger LOG = LoggerFactory.getLogger( TransactionDocument_2_0_2.class );
078
079 /**
080 * initializes an empty TransactionDocument
081 *
082 */
083 public TransactionDocument_2_0_2() {
084 try {
085 setSystemId( XMLFragment.DEFAULT_URL );
086 } catch ( MalformedURLException e ) {
087 LOG.logError( e.getMessage(), e );
088 }
089 }
090
091 /**
092 * initializes a TransactionDocument by reading a DOM object from the passed
093 *
094 * @see InputStream
095 *
096 * @param transRoot
097 * @throws XMLException
098 */
099 public TransactionDocument_2_0_2( Element transRoot ) throws XMLException {
100 setRootElement( transRoot );
101 }
102
103 /**
104 *
105 */
106 @Override
107 public void createEmptyDocument() {
108 Document doc = XMLTools.create();
109 Element root = doc.createElementNS( CommonNamespaces.CSW202NS.toASCIIString(), "csw202:Transaction" );
110 setRootElement( root );
111
112 }
113
114 /**
115 * parses a CS-W 2.0 transaction request
116 *
117 * @param id
118 * of the TransactionRequest
119 *
120 * @return a new transaction parsed from the this xml-encoded request.
121 * @throws XMLParsingException
122 * @throws OGCWebServiceException
123 */
124 @Override
125 public Transaction parse( String id )
126 throws XMLParsingException, OGCWebServiceException {
127
128 LOG.logDebug( "parsing CS-W Transaction request" );
129
130 // 'service'-attribute (required, must be CSW)
131 String service = XMLTools.getRequiredNodeAsString( getRootElement(), "@service", nsContext );
132 if ( !service.equals( "CSW" ) ) {
133 ExceptionCode code = ExceptionCode.INVALIDPARAMETERVALUE;
134 throw new InvalidParameterValueException( "GetRecordById", "'service' must be 'CSW'", code );
135 }
136
137 String version = XMLTools.getRequiredNodeAsString( getRootElement(), "@version", nsContext );
138 if ( !"2.0.2".equals( version ) ) {
139 throw new OGCWebServiceException( "GetRecordByIdDocument_2_0_2",
140 Messages.getMessage( "CSW_NOT_SUPPORTED_VERSION", "2.0.2", "2.0.2",
141 version ), ExceptionCode.INVALIDPARAMETERVALUE );
142 }
143 boolean verbose = XMLTools.getNodeAsBoolean( getRootElement(), "./@verboseResponse", nsContext, false );
144
145 List<Operation> ops = new ArrayList<Operation>();
146
147 ElementList el = XMLTools.getChildElements( getRootElement() );
148 for ( int i = 0; i < el.getLength(); i++ ) {
149 Element e = el.item( i );
150 // TODO check for qualified name
151 if ( "Insert".equals( e.getLocalName() ) ) {
152 ops.add( parseInsert( e ) );
153 } else if ( "Update".equals( e.getLocalName() ) ) {
154 ops.add( parseUpdate( e ) );
155 } else if ( "Delete".equals( e.getLocalName() ) ) {
156 ops.add( parseDelete( e ) );
157 }
158 }
159
160 // in the future the vendorSpecificParameters
161 Map<String, String> vendorSpecificParameters = parseDRMParams( this.getRootElement() );
162
163 return new Transaction( version, id, vendorSpecificParameters, ops, verbose );
164 }
165
166 /**
167 * parses a Delete element contained in a CS-W Transaction.
168 *
169 * @param element
170 * @return the Delete class parsed from the given Delete element.
171 * @throws XMLParsingException
172 * @throws MissingParameterValueException
173 * @throws InvalidParameterValueException
174 */
175 private Delete parseDelete( Element element )
176 throws XMLParsingException, MissingParameterValueException, InvalidParameterValueException {
177
178 LOG.logDebug( "parsing CS-W Transaction-Delete" );
179
180 String handle = XMLTools.getNodeAsString( element, "@handle", nsContext, null );
181 String tmp = XMLTools.getNodeAsString( element, "@typeName", nsContext, null );
182 URI typeName = null;
183 if ( tmp != null ) {
184 // part of the corrected CS-W 2.0 spec
185 try {
186 typeName = new URI( tmp );
187 } catch ( Exception e ) {
188 throw new XMLParsingException( "if defined attribute 'typeName' must be a valid URI" );
189 }
190 }
191
192 Element elem = (Element) XMLTools.getRequiredNode( element, "./csw202:Constraint", nsContext );
193 String ver = XMLTools.getNodeAsString( elem, "@version", nsContext, null );
194 if ( ver == null ) {
195 String s = Messages.getMessage( "CSW_MISSING_CONSTRAINT_VERSION" );
196 throw new MissingParameterValueException( s );
197 }
198 if ( !"1.0.0".equals( ver ) && !"1.1.0".equals( ver ) ) {
199 String s = Messages.getMessage( "CSW_INVALID_CONSTRAINT_VERSION", ver );
200 throw new InvalidParameterValueException( s );
201 }
202
203 elem = (Element) XMLTools.getRequiredNode( elem, "./ogc:Filter", nsContext );
204
205 Filter constraint = AbstractFilter.buildFromDOM( elem, "1.0.0".equals( ver ) );
206 return new Delete( handle, typeName, constraint );
207 }
208
209 /**
210 * parses a Update element contained in a CS-W Transaction.
211 *
212 * @param element
213 * @return the update class containing all parsed values
214 * @throws XMLParsingException
215 * @throws MissingParameterValueException
216 * @throws InvalidParameterValueException
217 */
218 private Update parseUpdate( Element element )
219 throws XMLParsingException, MissingParameterValueException, InvalidParameterValueException {
220
221 LOG.logDebug( "parsing CS-W Transaction-Update" );
222
223 String handle = XMLTools.getNodeAsString( element, "@handle", nsContext, null );
224 String tmp = XMLTools.getNodeAsString( element, "@typeName", nsContext, null );
225 URI typeName = null;
226 if ( tmp != null ) {
227 // part of the corrected CS-W 2.0 spec
228 try {
229 typeName = new URI( tmp );
230 } catch ( Exception e ) {
231 throw new XMLParsingException( "if defined attribute 'typeName' must be a valid URI" );
232 }
233 }
234
235 Element elem = (Element) XMLTools.getRequiredNode( element, "./csw202:Constraint", nsContext );
236 String ver = XMLTools.getNodeAsString( elem, "@version", nsContext, null );
237 if ( ver == null ) {
238 String s = Messages.getMessage( "CSW_MISSING_CONSTRAINT_VERSION" );
239 throw new MissingParameterValueException( s );
240 }
241 if ( !"1.0.0".equals( ver ) && !"1.1.0".equals( ver ) ) {
242 String s = Messages.getMessage( "CSW_INVALID_CONSTRAINT_VERSION", ver );
243 throw new InvalidParameterValueException( s );
244 }
245
246 elem = (Element) XMLTools.getRequiredNode( elem, "./ogc:Filter", nsContext );
247
248 Filter constraint = AbstractFilter.buildFromDOM( elem, "1.0.0".equals( ver ) );
249
250 List<Node> children = null;
251 List<Node> rp = XMLTools.getNodes( getRootElement(), "./csw202:RecordProperty", nsContext );
252 if ( rp.size() != 0 ) {
253 // at the moment will always be null because it is part of the
254 // CS-W 2.0 corrected version that will not be implemented yet
255 } else {
256 children = XMLTools.getNodes( element, "./child::*", nsContext );
257 if ( children.size() == 0 ) {
258 throw new XMLParsingException( "one record must be defined within a CS-W update element" );
259 }
260 }
261 return new Update( handle, typeName, constraint, (Element) children.get( 0 ), null );
262 }
263
264 /**
265 * parses a Insert element contained in a CS-W Transaction.
266 *
267 * @param element
268 * @return an Insert instance
269 * @throws XMLParsingException
270 */
271 private Insert parseInsert( Element element )
272 throws XMLParsingException {
273
274 LOG.logDebug( "parsing CS-W Transaction-Insert" );
275
276 String handle = XMLTools.getNodeAsString( element, "@handle", nsContext, "" );
277 List<Element> recList = new ArrayList<Element>();
278 List<Node> children = XMLTools.getNodes( element, "*", nsContext );
279 if ( children.size() == 0 ) {
280 LOG.logError( "at least one record must be defined within a CS-W insert element" );
281 throw new XMLParsingException( "at least one record must be defined within a CS-W insert element" );
282 }
283
284 for ( Object n : children ) {
285 LOG.logDebug( "TransactionDocument(insert): adding the element: " + element.getLocalName()
286 + " to the records list. " );
287 recList.add( (Element) n );
288 }
289
290 // if no ebrim is done, create the old insert class.
291 return new Insert( handle, recList );
292 }
293
294 }