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