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 }