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 }