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 }