001 //$HeadURL: svn+ssh://jwilden@svn.wald.intevation.org/deegree/base/branches/2.5_testing/src/org/deegree/ogcwebservices/wfs/configuration/WFSConfigurationDocument.java $ 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 package org.deegree.ogcwebservices.wfs.configuration; 037 038 import static org.deegree.framework.xml.XMLTools.getNodeAsBoolean; 039 import static org.deegree.framework.xml.XMLTools.getRequiredElement; 040 041 import java.io.File; 042 import java.net.URI; 043 import java.net.URL; 044 import java.util.HashMap; 045 import java.util.List; 046 import java.util.Map; 047 048 import org.deegree.datatypes.QualifiedName; 049 import org.deegree.framework.log.ILogger; 050 import org.deegree.framework.log.LoggerFactory; 051 import org.deegree.framework.util.CharsetUtils; 052 import org.deegree.framework.util.StringTools; 053 import org.deegree.framework.xml.InvalidConfigurationException; 054 import org.deegree.framework.xml.XMLParsingException; 055 import org.deegree.framework.xml.XMLTools; 056 import org.deegree.model.metadata.iso19115.Keywords; 057 import org.deegree.model.metadata.iso19115.OnlineResource; 058 import org.deegree.model.spatialschema.Envelope; 059 import org.deegree.ogcwebservices.getcapabilities.DCPType; 060 import org.deegree.ogcwebservices.getcapabilities.HTTP; 061 import org.deegree.ogcwebservices.getcapabilities.MetadataURL; 062 import org.deegree.ogcwebservices.getcapabilities.Operation; 063 import org.deegree.ogcwebservices.getcapabilities.OperationsMetadata; 064 import org.deegree.ogcwebservices.getcapabilities.Protocol; 065 import org.deegree.ogcwebservices.wfs.capabilities.FormatType; 066 import org.deegree.ogcwebservices.wfs.capabilities.WFSCapabilitiesDocument; 067 import org.deegree.ogcwebservices.wfs.capabilities.WFSFeatureType; 068 import org.deegree.ogcwebservices.wfs.capabilities.WFSOperationsMetadata; 069 import org.deegree.owscommon.OWSDomainType; 070 import org.w3c.dom.Element; 071 import org.w3c.dom.Node; 072 073 /** 074 * Represents an XML configuration document for a deegree WFS instance, i.e. it consists of all sections common to an 075 * OGC WFS 1.1 capabilities document plus some deegree specific elements. 076 * 077 * @author <a href="mailto:mschneider@lat-lon.de">Markus Schneider </a> 078 * @author last edited by: $Author: mschneider $ 079 * 080 * @version $Revision: 18195 $, $Date: 2009-06-18 17:55:39 +0200 (Do, 18 Jun 2009) $ 081 */ 082 public class WFSConfigurationDocument extends WFSCapabilitiesDocument { 083 084 private static final long serialVersionUID = -6415476866015999971L; 085 086 protected static final ILogger LOG = LoggerFactory.getLogger( WFSConfigurationDocument.class ); 087 088 /** 089 * Creates an object representation of the document. 090 * 091 * @return class representation of the configuration document 092 * @throws InvalidConfigurationException 093 */ 094 public WFSConfiguration getConfiguration() 095 throws InvalidConfigurationException { 096 097 WFSConfiguration config = null; 098 099 try { 100 WFSDeegreeParams deegreeParams = getDeegreeParams(); 101 102 // get default Urls (used when DCP element is ommitted in Operation-elements) 103 OnlineResource defaultOnlineResource = deegreeParams.getDefaultOnlineResource(); 104 String defaultUrl = defaultOnlineResource.getLinkage().getHref().toString(); 105 if ( defaultUrl.endsWith( "?" ) ) { 106 defaultUrl = defaultUrl.substring( 0, defaultUrl.length() - 1 ); 107 } 108 URL defaultUrlGet = new URL( defaultUrl + '?' ); 109 URL defaultUrlPost = new URL( defaultUrl ); 110 111 OperationsMetadata opMetadata = getOperationsMetadata( defaultUrlGet, defaultUrlPost ); 112 config = new WFSConfiguration( parseVersion(), parseUpdateSequence(), getServiceIdentification(), 113 getServiceProvider(), opMetadata, getFeatureTypeList(), 114 getServesGMLObjectTypeList(), getSupportsGMLObjectTypeList(), null, 115 getFilterCapabilities(), deegreeParams ); 116 } catch ( Exception e ) { 117 throw new InvalidConfigurationException( e.getMessage() + "\n" + StringTools.stackTraceToString( e ) ); 118 } 119 return config; 120 } 121 122 /** 123 * Creates an object representation of the <code>deegreeParams</code>- section. 124 * 125 * @return class representation of the <code>deegreeParams</code>- section 126 * @throws InvalidConfigurationException 127 */ 128 public WFSDeegreeParams getDeegreeParams() 129 throws InvalidConfigurationException { 130 131 WFSDeegreeParams deegreeParams = null; 132 133 try { 134 Element element = (Element) XMLTools.getRequiredNode( getRootElement(), "deegreewfs:deegreeParams", 135 nsContext ); 136 OnlineResource defaultOnlineResource = parseOnLineResource( getRequiredElement( 137 element, 138 "deegreewfs:DefaultOnlineResource", 139 nsContext ) ); 140 int cacheSize = XMLTools.getNodeAsInt( element, "deegreewfs:CacheSize/text()", nsContext, 100 ); 141 int requestTimeLimit = XMLTools.getNodeAsInt( element, "deegreewfs:RequestTimeLimit/text()", nsContext, 10 ); 142 143 boolean checkUTMZones = getNodeAsBoolean( element, "deegreewfs:CheckUTMZones", nsContext, false ); 144 boolean switchAxes = getNodeAsBoolean( element, "deegreewfs:SwitchAxesForEPSG4326", nsContext, false ); 145 boolean printGeomIds = getNodeAsBoolean( element, "deegreewfs:PrintGeometryGmlIds", nsContext, false ); 146 147 String characterSet = XMLTools.getNodeAsString( element, "deegreewfs:Encoding/text()", nsContext, 148 CharsetUtils.getSystemCharset() ); 149 String[] dataDirectories = XMLTools.getNodesAsStrings( 150 element, 151 "deegreewfs:DataDirectoryList/deegreewfs:DataDirectory/text()", 152 nsContext ); 153 if ( dataDirectories.length == 0 ) { 154 LOG.logInfo( "No data directory specified. Using configuration document directory." ); 155 dataDirectories = new String[] { "." }; 156 } 157 for ( int i = 0; i < dataDirectories.length; i++ ) { 158 try { 159 dataDirectories[i] = resolve( dataDirectories[i] ).toURI().getPath(); 160 } catch ( Exception e ) { 161 String msg = "DataDirectory '" + dataDirectories[i] + "' cannot be resolved as a directory: " 162 + e.getMessage(); 163 throw new InvalidConfigurationException( msg ); 164 } 165 } 166 167 String lockManagerString = XMLTools.getNodeAsString( element, "deegreewfs:LockManagerDirectory/text()", 168 nsContext, null ); 169 File lockManagerDir = null; 170 if ( lockManagerString != null ) { 171 try { 172 lockManagerDir = new File( this.resolve( lockManagerString ).toURI().toURL().getFile() ); 173 } catch ( Exception e ) { 174 String msg = "Specified value (" + lockManagerDir 175 + ") for 'deegreewfs:LockManagerDirectory' is invalid."; 176 throw new InvalidConfigurationException( msg, e ); 177 } 178 } 179 deegreeParams = new WFSDeegreeParams( defaultOnlineResource, cacheSize, requestTimeLimit, characterSet, 180 dataDirectories, lockManagerDir, checkUTMZones, switchAxes, 181 printGeomIds ); 182 } catch ( XMLParsingException e ) { 183 throw new InvalidConfigurationException( "Error parsing the deegreeParams " 184 + "section of the WFS configuration: \n" + e.getMessage() 185 + StringTools.stackTraceToString( e ) ); 186 } 187 return deegreeParams; 188 } 189 190 /** 191 * Creates an object representation of the <code>ows:OperationsMetadata</code> section. 192 * 193 * @param defaultUrlGet 194 * @param defaultUrlPost 195 * @return object representation of the <code>ows:OperationsMetadata</code> section 196 * @throws XMLParsingException 197 */ 198 public OperationsMetadata getOperationsMetadata( URL defaultUrlGet, URL defaultUrlPost ) 199 throws XMLParsingException { 200 201 List<Node> operationElementList = XMLTools.getNodes( getRootElement(), "ows:OperationsMetadata/ows:Operation", 202 nsContext ); 203 204 // build HashMap of 'ows:Operation'-elements for easier access 205 Map<String, Element> operations = new HashMap<String, Element>(); 206 for ( int i = 0; i < operationElementList.size(); i++ ) { 207 operations.put( XMLTools.getRequiredNodeAsString( operationElementList.get( i ), "@name", nsContext ), 208 (Element) operationElementList.get( i ) ); 209 } 210 211 Operation getCapabilities = getOperation( OperationsMetadata.GET_CAPABILITIES_NAME, true, operations, 212 defaultUrlGet, defaultUrlPost ); 213 Operation describeFeatureType = getOperation( WFSOperationsMetadata.DESCRIBE_FEATURETYPE_NAME, true, 214 operations, defaultUrlGet, defaultUrlPost ); 215 Operation getFeature = getOperation( WFSOperationsMetadata.GET_FEATURE_NAME, false, operations, defaultUrlGet, 216 defaultUrlPost ); 217 Operation getFeatureWithLock = getOperation( WFSOperationsMetadata.GET_FEATURE_WITH_LOCK_NAME, false, 218 operations, defaultUrlGet, defaultUrlPost ); 219 Operation getGMLObject = getOperation( WFSOperationsMetadata.GET_GML_OBJECT_NAME, false, operations, 220 defaultUrlGet, defaultUrlPost ); 221 Operation lockFeature = getOperation( WFSOperationsMetadata.LOCK_FEATURE_NAME, false, operations, 222 defaultUrlGet, defaultUrlPost ); 223 Operation transaction = getOperation( WFSOperationsMetadata.TRANSACTION_NAME, false, operations, defaultUrlGet, 224 defaultUrlPost ); 225 226 List<Element> parameterElementList = XMLTools.getElements( getRootElement(), 227 "ows:OperationsMetadata/ows:Parameter", nsContext ); 228 OWSDomainType[] parameters = new OWSDomainType[parameterElementList.size()]; 229 for ( int i = 0; i < parameters.length; i++ ) { 230 parameters[i] = getOWSDomainType( null, parameterElementList.get( i ) ); 231 } 232 233 List<Element> constraintElementList = XMLTools.getElements( getRootElement(), 234 "ows:OperationsMetadata/ows:Constraint", nsContext ); 235 OWSDomainType[] constraints = new OWSDomainType[constraintElementList.size()]; 236 for ( int i = 0; i < constraints.length; i++ ) { 237 constraints[i] = getOWSDomainType( null, constraintElementList.get( i ) ); 238 } 239 WFSOperationsMetadata metadata = new WFSOperationsMetadata( getCapabilities, describeFeatureType, getFeature, 240 getFeatureWithLock, getGMLObject, lockFeature, 241 transaction, parameters, constraints ); 242 243 return metadata; 244 } 245 246 /** 247 * Creates an object representation of an <code>ows:Operation</code>- element. 248 * 249 * @param name 250 * @param isMandatory 251 * @param operations 252 * @param defaultUrlGet 253 * @param defaultUrlPost 254 * @return object representation of <code>ows:Operation</code>- element 255 * @throws XMLParsingException 256 */ 257 protected Operation getOperation( String name, boolean isMandatory, Map<String, Element> operations, 258 URL defaultUrlGet, URL defaultUrlPost ) 259 throws XMLParsingException { 260 261 Operation operation = null; 262 Element operationElement = operations.get( name ); 263 if ( operationElement == null ) { 264 if ( isMandatory ) { 265 throw new XMLParsingException( "Mandatory operation '" + name + "' not defined in " 266 + "'OperationsMetadata'-section." ); 267 } 268 } else { 269 // "ows:Parameter"-elements 270 List<Element> parameterElements = XMLTools.getElements( operationElement, "ows:Parameter", nsContext ); 271 OWSDomainType[] parameters = new OWSDomainType[parameterElements.size()]; 272 for ( int i = 0; i < parameters.length; i++ ) { 273 parameters[i] = getOWSDomainType( name, parameterElements.get( i ) ); 274 } 275 276 DCPType[] dcps = null; 277 List<Element> nl = XMLTools.getElements( operationElement, "ows:DCP", nsContext ); 278 if ( nl.size() > 0 ) { 279 dcps = getDCPs( nl ); 280 } else { 281 // add default URLs 282 dcps = new DCPType[1]; 283 Protocol protocol = new HTTP( new URL[] { defaultUrlGet }, new URL[] { defaultUrlPost } ); 284 dcps[0] = new DCPType( protocol ); 285 } 286 operation = new Operation( name, dcps, parameters ); 287 } 288 return operation; 289 } 290 291 /** 292 * Returns the object representation for an element of type <code>wfs:FeatureTypeType</code>. 293 * 294 * @param element 295 * @return object representation for the element of type <code>wfs:OperationsType</code> 296 * @throws XMLParsingException 297 */ 298 @Override 299 public WFSFeatureType getFeatureTypeType( Element element ) 300 throws XMLParsingException { 301 302 QualifiedName name = parseQualifiedName( XMLTools.getRequiredNode( element, "wfs:Name/text()", nsContext ) ); 303 String title = XMLTools.getRequiredNodeAsString( element, "wfs:Title/text()", nsContext ); 304 String abstract_ = XMLTools.getNodeAsString( element, "wfs:Abstract/text()", nsContext, null ); 305 Keywords[] keywords = getKeywords( XMLTools.getNodes( element, "ows:Keywords", nsContext ) ); 306 307 URI defaultSrs = null; 308 URI[] otherSrs = null; 309 Node noSrsElement = XMLTools.getNode( element, "wfs:NoSRS", nsContext ); 310 if ( noSrsElement == null ) { 311 defaultSrs = XMLTools.getNodeAsURI( element, "wfs:DefaultSRS/text()", nsContext, null ); 312 otherSrs = XMLTools.getNodesAsURIs( element, "wfs:OtherSRS/text()", nsContext ); 313 } 314 315 org.deegree.ogcwebservices.wfs.capabilities.Operation[] operations = null; 316 Element operationsTypeElement = (Element) XMLTools.getNode( element, "wfs:Operations", nsContext ); 317 if ( operationsTypeElement != null ) { 318 operations = getOperationsType( operationsTypeElement ); 319 } 320 List<Element> formatElementList = XMLTools.getElements( element, "wfs:OutputFormats/wfs:Format", nsContext ); 321 FormatType[] formats = new FormatType[formatElementList.size()]; 322 for ( int i = 0; i < formats.length; i++ ) { 323 formats[i] = getFormatType( formatElementList.get( i ) ); 324 } 325 List<Element> wgs84BoundingBoxElements = XMLTools.getElements( element, "ows:WGS84BoundingBox", nsContext ); 326 if ( wgs84BoundingBoxElements.size() < 1 ) { 327 throw new XMLParsingException( "A 'wfs:FeatureTypeType' must contain at least one " 328 + "'ows:WGS84BoundingBox'-element." ); 329 } 330 Envelope[] wgs84BoundingBoxes = new Envelope[wgs84BoundingBoxElements.size()]; 331 for ( int i = 0; i < wgs84BoundingBoxes.length; i++ ) { 332 wgs84BoundingBoxes[i] = getWGS84BoundingBoxType( wgs84BoundingBoxElements.get( i ) ); 333 } 334 List<Element> metadataURLElementList = XMLTools.getElements( element, "wfs:MetadataURL", nsContext ); 335 MetadataURL[] metadataUrls = new MetadataURL[metadataURLElementList.size()]; 336 for ( int i = 0; i < metadataUrls.length; i++ ) { 337 metadataUrls[i] = getMetadataURL( metadataURLElementList.get( i ) ); 338 } 339 WFSFeatureType featureType = new WFSFeatureType( name, title, abstract_, keywords, defaultSrs, otherSrs, 340 operations, formats, wgs84BoundingBoxes, metadataUrls ); 341 342 return featureType; 343 } 344 }