001 //$HeadURL: svn+ssh://jwilden@svn.wald.intevation.org/deegree/base/branches/2.5_testing/src/org/deegree/ogcwebservices/wms/configuration/WMSConfigurationDocument_1_3_0.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.wms.configuration;
037
038 import static org.deegree.framework.xml.XMLTools.getElements;
039 import static org.deegree.framework.xml.XMLTools.getNodeAsBoolean;
040 import static org.deegree.framework.xml.XMLTools.getNodeAsString;
041 import static org.deegree.ogcwebservices.wms.configuration.WMSConfigurationDocument.createDatabaseSource;
042
043 import java.awt.Color;
044 import java.io.IOException;
045 import java.net.MalformedURLException;
046 import java.net.URL;
047 import java.util.ArrayList;
048 import java.util.Arrays;
049 import java.util.HashMap;
050 import java.util.LinkedList;
051 import java.util.List;
052 import java.util.Map;
053
054 import javax.xml.transform.TransformerException;
055
056 import org.deegree.datatypes.QualifiedName;
057 import org.deegree.enterprise.Proxy;
058 import org.deegree.framework.log.ILogger;
059 import org.deegree.framework.log.LoggerFactory;
060 import org.deegree.framework.util.BootLogger;
061 import org.deegree.framework.util.IDGenerator;
062 import org.deegree.framework.util.KVP2Map;
063 import org.deegree.framework.util.StringTools;
064 import org.deegree.framework.xml.InvalidConfigurationException;
065 import org.deegree.framework.xml.XMLFragment;
066 import org.deegree.framework.xml.XMLParsingException;
067 import org.deegree.framework.xml.XMLTools;
068 import org.deegree.framework.xml.XSLTDocument;
069 import org.deegree.model.crs.UnknownCRSException;
070 import org.deegree.model.metadata.iso19115.OnlineResource;
071 import org.deegree.model.spatialschema.Envelope;
072 import org.deegree.model.spatialschema.GMLGeometryAdapter;
073 import org.deegree.model.spatialschema.Geometry;
074 import org.deegree.model.spatialschema.GeometryException;
075 import org.deegree.ogcbase.CommonNamespaces;
076 import org.deegree.ogcwebservices.OGCWebService;
077 import org.deegree.ogcwebservices.getcapabilities.MetadataURL;
078 import org.deegree.ogcwebservices.getcapabilities.OGCCapabilities;
079 import org.deegree.ogcwebservices.wcs.WCService;
080 import org.deegree.ogcwebservices.wcs.configuration.WCSConfiguration;
081 import org.deegree.ogcwebservices.wcs.getcoverage.GetCoverage;
082 import org.deegree.ogcwebservices.wfs.RemoteWFService;
083 import org.deegree.ogcwebservices.wfs.WFServiceFactory;
084 import org.deegree.ogcwebservices.wfs.capabilities.WFSCapabilities;
085 import org.deegree.ogcwebservices.wfs.capabilities.WFSCapabilitiesDocument;
086 import org.deegree.ogcwebservices.wfs.configuration.WFSConfiguration;
087 import org.deegree.ogcwebservices.wfs.configuration.WFSConfigurationDocument;
088 import org.deegree.ogcwebservices.wfs.operation.Query;
089 import org.deegree.ogcwebservices.wms.RemoteWMService;
090 import org.deegree.ogcwebservices.wms.capabilities.Attribution;
091 import org.deegree.ogcwebservices.wms.capabilities.AuthorityURL;
092 import org.deegree.ogcwebservices.wms.capabilities.DataURL;
093 import org.deegree.ogcwebservices.wms.capabilities.Dimension;
094 import org.deegree.ogcwebservices.wms.capabilities.FeatureListURL;
095 import org.deegree.ogcwebservices.wms.capabilities.Identifier;
096 import org.deegree.ogcwebservices.wms.capabilities.Layer;
097 import org.deegree.ogcwebservices.wms.capabilities.LayerBoundingBox;
098 import org.deegree.ogcwebservices.wms.capabilities.LegendURL;
099 import org.deegree.ogcwebservices.wms.capabilities.ScaleHint;
100 import org.deegree.ogcwebservices.wms.capabilities.Style;
101 import org.deegree.ogcwebservices.wms.capabilities.StyleSheetURL;
102 import org.deegree.ogcwebservices.wms.capabilities.StyleURL;
103 import org.deegree.ogcwebservices.wms.capabilities.WMSCapabilities;
104 import org.deegree.ogcwebservices.wms.capabilities.WMSCapabilitiesDocument;
105 import org.deegree.ogcwebservices.wms.capabilities.WMSCapabilitiesDocumentFactory;
106 import org.deegree.ogcwebservices.wms.capabilities.WMSCapabilitiesDocument_1_3_0;
107 import org.deegree.ogcwebservices.wms.operation.GetMap;
108 import org.deegree.owscommon_new.OperationsMetadata;
109 import org.deegree.owscommon_new.ServiceIdentification;
110 import org.deegree.owscommon_new.ServiceProvider;
111 import org.w3c.dom.Element;
112 import org.w3c.dom.Node;
113 import org.xml.sax.SAXException;
114
115 /**
116 * <code>WMSConfigurationDocument_1_3_0</code> is the parser class for a WMS 1.3.0 configuration document.
117 *
118 * @author <a href="mailto:schmitz@lat-lon.de">Andreas Schmitz</a>
119 * @author last edited by: $Author: mschneider $
120 *
121 * @version 2.0, $Revision: 18195 $, $Date: 2009-06-18 17:55:39 +0200 (Do, 18 Jun 2009) $
122 *
123 * @since 2.0
124 */
125
126 public class WMSConfigurationDocument_1_3_0 extends WMSCapabilitiesDocument_1_3_0 {
127
128 private static final long serialVersionUID = -2304421871404603016L;
129
130 private static Map<URL, OGCCapabilities> capaCache = new HashMap<URL, OGCCapabilities>();
131
132 private static final String XML_TEMPLATE = "WMSConfigurationTemplate_1_3_0.xml";
133
134 private static final String XSLT_TEMPLATE_NAME = "WMSConfigurationTransform_1_3_0.xsl";
135
136 private static XSLTDocument XSLT_TEMPLATE;
137
138 private static final ILogger LOG = LoggerFactory.getLogger( WMSConfigurationDocument_1_3_0.class );
139
140 private static final String PWMS = CommonNamespaces.WMS_PREFIX + ":";
141
142 private static final QualifiedName DEFAULT_GEO_PROP = new QualifiedName(
143 "app",
144 "GEOM",
145 CommonNamespaces.buildNSURI( "http://www.deegree.org/app" ) );
146 static {
147 XSLT_TEMPLATE = new XSLTDocument();
148 try {
149 XSLT_TEMPLATE.load( WMSConfigurationDocument_1_3_0.class.getResource( XSLT_TEMPLATE_NAME ) );
150 } catch ( Exception e ) {
151 BootLogger.logError( "Error loading XSLT sheet in WMSConfigurationDocument_1_3_0.", e );
152 }
153 }
154
155 /**
156 *
157 */
158 public static void resetCapabilitiesCache() {
159 capaCache.clear();
160 }
161
162 @Override
163 public void createEmptyDocument()
164 throws IOException, SAXException {
165 URL url = WMSConfigurationDocument_1_3_0.class.getResource( XML_TEMPLATE );
166 if ( url == null ) {
167 throw new IOException( "The resource '" + XML_TEMPLATE + " could not be found." );
168 }
169 load( url );
170 }
171
172 /**
173 * Added the prefix.
174 *
175 * @return the parsed configuration
176 * @throws InvalidConfigurationException
177 * @throws XMLParsingException
178 */
179 public WMSConfiguration_1_3_0 parseConfiguration()
180 throws InvalidConfigurationException, XMLParsingException {
181
182 try {
183 // transform document to fill missing elements and attributes with
184 // default values
185 XMLFragment frag = XSLT_TEMPLATE.transform( this );
186 this.setRootElement( frag.getRootElement() );
187 if ( LOG.isDebug() ) {
188 LOG.logDebug( "Transformed WMS configuration document", getAsPrettyString() );
189 }
190 } catch ( TransformerException e ) {
191 String msg = "Error transforming WMS configuration document (in order to fill in default value).";
192 LOG.logError( msg, e );
193 throw new InvalidConfigurationException( msg, e );
194 }
195
196 ServiceIdentification serviceIdentification = null;
197 ServiceProvider serviceProvider = null;
198 OperationsMetadata metadata = null;
199 Layer layer = null;
200 WMSDeegreeParams params = null;
201 Element root = getRootElement();
202 String version = XMLTools.getRequiredNodeAsString( root, "@version", nsContext );
203 String updateSeq = XMLTools.getNodeAsString( root, "@updateSequence", nsContext, null );
204 List<String> exceptions;
205
206 int layerLimit = 0;
207
208 try {
209 Node node = XMLTools.getRequiredNode( root, "./deegreewms:DeegreeParam", nsContext );
210 params = parseDeegreeParams( node );
211
212 Element serviceElement = (Element) XMLTools.getRequiredNode( root, PWMS + "Service", nsContext );
213
214 layerLimit = XMLTools.getNodeAsInt( serviceElement, PWMS + "LayerLimit", nsContext, 0 );
215 int maxWidth = XMLTools.getNodeAsInt( serviceElement, PWMS + "MaxWidth", nsContext, 0 );
216 int maxHeight = XMLTools.getNodeAsInt( serviceElement, PWMS + "MaxHeight", nsContext, 0 );
217
218 params.setMaxMapHeight( maxHeight );
219 params.setMaxMapWidth( maxWidth );
220
221 serviceIdentification = parseServiceIdentification();
222 serviceProvider = parseServiceProvider();
223 metadata = parseOperationsMetadata();
224
225 Element layerElem = (Element) XMLTools.getRequiredNode( getRootElement(), PWMS + "Capability/" + PWMS
226 + "Layer", nsContext );
227 layer = parseLayers( layerElem, null, null );
228
229 Element exceptionElement = XMLTools.getRequiredElement( getRootElement(), PWMS + "Capability/" + PWMS
230 + "Exception", nsContext );
231 exceptions = parseExceptionFormats( exceptionElement );
232
233 } catch ( XMLParsingException e ) {
234 e.printStackTrace();
235 throw new InvalidConfigurationException( e.getMessage() + StringTools.stackTraceToString( e ) );
236 } catch ( MalformedURLException e ) {
237 throw new InvalidConfigurationException( e.getMessage() + " - " + StringTools.stackTraceToString( e ) );
238 } catch ( UnknownCRSException e ) {
239 throw new InvalidConfigurationException( e.getMessage() + " - " + StringTools.stackTraceToString( e ) );
240 }
241
242 WMSConfiguration_1_3_0 wmsConfiguration = new WMSConfiguration_1_3_0( version, updateSeq,
243 serviceIdentification, serviceProvider,
244 metadata, layer, params, getSystemId(),
245 layerLimit, exceptions );
246
247 return wmsConfiguration;
248 }
249
250 /**
251 * Creates a class representation of the <code>deegreeParams</code>- section.
252 *
253 * @param root
254 *
255 * @return the deegree params
256 * @throws XMLParsingException
257 * @throws MalformedURLException
258 */
259 public WMSDeegreeParams parseDeegreeParams( Node root )
260 throws XMLParsingException, MalformedURLException {
261
262 Element elem = (Element) XMLTools.getRequiredNode( root, "./deegreewms:DefaultOnlineResource", nsContext );
263 OnlineResource ol = parseOnLineResource( elem );
264 int cache = XMLTools.getNodeAsInt( root, "./deegreewms:CacheSize", nsContext, 100 );
265 int maxLifeTime = XMLTools.getNodeAsInt( root, "./deegreewms:MaxLifeTime", nsContext, 3600 );
266 int reqTimeLimit = XMLTools.getNodeAsInt( root, "./deegreewms:RequestTimeLimit", nsContext, 15 );
267 reqTimeLimit *= 1000;
268 double mapQuality = XMLTools.getNodeAsDouble( root, "./deegreewms:MapQuality", nsContext, 0.95 );
269 // int maxMapWidth = XMLTools.getNodeAsInt( root, "./deegreewms:MaxMapWidth", nsContext,
270 // 1000 );
271 // int maxMapHeight = XMLTools.getNodeAsInt( root, "./deegreewms:MaxMapHeight", nsContext,
272 // 1000 );
273 int featureInfoRadius = XMLTools.getNodeAsInt( root, "./deegreewms:FeatureInfoRadius", nsContext, 5 );
274 String copyright = XMLTools.getNodeAsString( root, "./deegreewms:Copyright", nsContext, "" );
275 String defaultPNGFormat = XMLTools.getNodeAsString( root, "deegreewms:DefaultPNGFormat", nsContext,
276 "image/png; mode=24bit" );
277
278 URL dtdLocation = null;
279 if ( XMLTools.getNode( root, "deegreewms:DTDLocation", nsContext ) != null ) {
280 elem = (Element) XMLTools.getRequiredNode( root, "./deegreewms:DTDLocation/deegreewms:OnlineResource",
281 nsContext );
282 OnlineResource olr = parseOnLineResource( elem );
283 dtdLocation = olr.getLinkage().getHref();
284 } else {
285 dtdLocation = new URL( "http://schemas.opengis.net/wms/1.1.1/WMS_MS_Capabilities.dtd" );
286 }
287
288 URL featureSchemaLocation = null;
289 String featureSchemaNamespace = null;
290 if ( XMLTools.getNode( root, "deegreewms:FeatureInfoSchema", nsContext ) != null ) {
291 featureSchemaNamespace = XMLTools.getRequiredNodeAsString(
292 root,
293 "deegreewms:FeatureInfoSchema/deegreewms:Namespace",
294 nsContext );
295 elem = (Element) XMLTools.getRequiredNode( root, "deegreewms:FeatureInfoSchema/deegreewms:OnlineResource",
296 nsContext );
297 OnlineResource link = parseOnLineResource( elem );
298 featureSchemaLocation = link.getLinkage().getHref();
299 }
300
301 boolean antiAliased = XMLTools.getNodeAsBoolean( root, "./deegreewms:AntiAliased", nsContext, true );
302
303 boolean filtersAllowed = getNodeAsBoolean( root, "./deegreewms:FiltersAllowed", nsContext, false );
304
305 Proxy proxy = parseProxy( root );
306
307 List<String> supportedVersions = parseSupportedVersions( root );
308
309 WMSDeegreeParams deegreeParams = new WMSDeegreeParams( cache, maxLifeTime, reqTimeLimit, (float) mapQuality,
310 ol, 0, 0, antiAliased, featureInfoRadius, copyright,
311 null, dtdLocation, proxy, supportedVersions,
312 featureSchemaLocation, featureSchemaNamespace,
313 filtersAllowed, defaultPNGFormat );
314
315 return deegreeParams;
316 }
317
318 // returns the list of supported versions
319 private List<String> parseSupportedVersions( Node root )
320 throws XMLParsingException {
321
322 String[] versions = XMLTools.getNodesAsStrings( root, "./deegreewms:SupportedVersion", nsContext );
323
324 if ( versions != null )
325 return Arrays.asList( versions );
326
327 return new ArrayList<String>();
328
329 }
330
331 /**
332 * @param root
333 * @return the proxy
334 * @throws XMLParsingException
335 */
336 private Proxy parseProxy( Node root )
337 throws XMLParsingException {
338
339 Proxy proxy = null;
340 Node pro = XMLTools.getNode( root, "./deegreewms:Proxy", nsContext );
341 if ( pro != null ) {
342 String proxyHost = XMLTools.getRequiredNodeAsString( pro, "./@proxyHost", nsContext );
343 String proxyPort = XMLTools.getRequiredNodeAsString( pro, "./@proxyPort", nsContext );
344 proxy = new Proxy( proxyHost, proxyPort );
345 }
346
347 return proxy;
348 }
349
350 /*
351 * Removed Extent. Added prefix. Changed SRS to CRS.
352 */
353 @Override
354 protected Layer parseLayers( Element layerElem, Layer parent, ScaleHint scaleHint )
355 throws XMLParsingException, UnknownCRSException {
356
357 boolean queryable = XMLTools.getNodeAsBoolean( layerElem, "./@queryable", nsContext, false );
358 int cascaded = XMLTools.getNodeAsInt( layerElem, "./@cascaded", nsContext, 0 );
359 boolean opaque = XMLTools.getNodeAsBoolean( layerElem, "./@opaque", nsContext, false );
360 boolean noSubsets = XMLTools.getNodeAsBoolean( layerElem, "./@noSubsets", nsContext, false );
361 int fixedWidth = XMLTools.getNodeAsInt( layerElem, "./@fixedWidth", nsContext, 0 );
362 int fixedHeight = XMLTools.getNodeAsInt( layerElem, "./@fixedHeight", nsContext, 0 );
363 String name = XMLTools.getNodeAsString( layerElem, PWMS + "Name", nsContext, null );
364 String title = XMLTools.getRequiredNodeAsString( layerElem, PWMS + "Title", nsContext );
365 String layerAbstract = XMLTools.getNodeAsString( layerElem, PWMS + "Abstract", nsContext, null );
366 String[] keywords = XMLTools.getNodesAsStrings( layerElem, PWMS + "KeywordList/" + PWMS + "Keyword", nsContext );
367 String[] srs = XMLTools.getNodesAsStrings( layerElem, PWMS + "CRS", nsContext );
368
369 List<Element> nl = XMLTools.getElements( layerElem, PWMS + "BoundingBox", nsContext );
370 // TODO
371 // substitue with Envelope
372 LayerBoundingBox[] bboxes = null;
373 if ( nl.size() == 0 && parent != null ) {
374 // inherit BoundingBoxes from parent layer
375 bboxes = parent.getBoundingBoxes();
376 } else {
377 bboxes = parseLayerBoundingBoxes( nl );
378 }
379
380 Element llBox = (Element) XMLTools.getNode( layerElem, PWMS + "EX_GeographicBoundingBox", nsContext );
381 Envelope llBoundingBox = null;
382 if ( llBox == null && parent != null ) {
383 // inherit LatLonBoundingBox parent layer
384 llBoundingBox = parent.getLatLonBoundingBox();
385 } else {
386 llBoundingBox = parseEX_GeographicBoundingBox( llBox );
387 }
388
389 Dimension[] dimensions = parseDimensions( layerElem );
390 // Extent[] extents = parseExtents( layerElem );
391
392 Attribution attribution = parseAttribution( layerElem );
393
394 AuthorityURL[] authorityURLs = parseAuthorityURLs( layerElem );
395
396 MetadataURL[] metadataURLs = parseMetadataURLs( layerElem );
397
398 DataURL[] dataURLs = parseDataURL( layerElem );
399
400 Identifier[] identifiers = parseIdentifiers( layerElem );
401
402 FeatureListURL[] featureListURLs = parseFeatureListURL( layerElem );
403
404 Style[] styles = parseStyles( layerElem );
405
406 scaleHint = parseScaleHint( layerElem, scaleHint );
407
408 AbstractDataSource[] ds = parseDataSources( layerElem, name, scaleHint );
409
410 Layer layer = new Layer( queryable, cascaded, opaque, noSubsets, fixedWidth, fixedHeight, name, title,
411 layerAbstract, llBoundingBox, attribution, scaleHint, keywords, srs, bboxes,
412 dimensions, null, authorityURLs, identifiers, metadataURLs, dataURLs, featureListURLs,
413 styles, null, ds, parent );
414
415 // get Child layers
416 nl = XMLTools.getElements( layerElem, PWMS + "Layer", nsContext );
417 Layer[] layers = new Layer[nl.size()];
418 for ( int i = 0; i < layers.length; i++ ) {
419 layers[i] = parseLayers( nl.get( i ), layer, scaleHint );
420 }
421
422 // set child layers
423 layer.setLayer( layers );
424
425 return layer;
426 }
427
428 /*
429 * Added the prefix.
430 */
431 @Override
432 protected Style[] parseStyles( Element layerElem )
433 throws XMLParsingException {
434
435 List<Element> nl = XMLTools.getElements( layerElem, PWMS + "Style", nsContext );
436 Style[] styles = new Style[nl.size()];
437 for ( int i = 0; i < styles.length; i++ ) {
438 String name = XMLTools.getRequiredNodeAsString( nl.get( i ), PWMS + "Name", nsContext );
439 String title = XMLTools.getNodeAsString( nl.get( i ), PWMS + "Title", nsContext, null );
440 String styleAbstract = XMLTools.getNodeAsString( nl.get( i ), PWMS + "Abstract", nsContext, null );
441 LegendURL[] legendURLs = parseLegendURL( nl.get( i ) );
442 StyleURL styleURL = parseStyleURL( nl.get( i ) );
443 StyleSheetURL styleSheetURL = parseStyleSheetURL( nl.get( i ) );
444 String styleResource = XMLTools.getNodeAsString( nl.get( i ), "deegreewms:StyleResource", nsContext,
445 "styles.xml" );
446 URL sr = null;
447 try {
448 sr = resolve( styleResource );
449 } catch ( MalformedURLException e ) {
450 throw new XMLParsingException( "could not parse style resource of style: " + name, e );
451 }
452
453 String layerName = XMLTools.getRequiredNodeAsString( layerElem, PWMS + "Name", nsContext );
454 if ( name == null || name.length() == 0 ) {
455 name = "default:" + layerName;
456 }
457 if ( name.equals( "default" ) ) {
458 name += ":" + layerName;
459 }
460 if ( name.equals( "default:" ) ) {
461 name += layerName;
462 }
463
464 styles[i] = new Style( name, title, styleAbstract, legendURLs, styleSheetURL, styleURL, sr );
465 }
466
467 return styles;
468 }
469
470 /**
471 *
472 * @param layerElem
473 * @return the data sources
474 * @throws XMLParsingException
475 */
476 protected AbstractDataSource[] parseDataSources( Element layerElem, String layerName, ScaleHint scaleHint )
477 throws XMLParsingException {
478
479 List<Element> nl = XMLTools.getElements( layerElem, "./deegreewms:DataSource", nsContext );
480
481 LinkedList<AbstractDataSource> ds = new LinkedList<AbstractDataSource>();
482
483 for ( Element datasource : nl ) {
484 boolean failOnEx = XMLTools.getNodeAsBoolean( datasource, "./@failOnException", nsContext, true );
485 boolean queryable = XMLTools.getNodeAsBoolean( datasource, "./@queryable", nsContext, false );
486 QualifiedName name = XMLTools.getNodeAsQualifiedName( datasource, "./deegreewms:Name/text()", nsContext,
487 new QualifiedName( layerName ) );
488 String stype = XMLTools.getRequiredNodeAsString( datasource, "./deegreewms:Type", nsContext );
489
490 int reqTimeLimit = XMLTools.getNodeAsInt( datasource, "./deegreewms:RequestTimeLimit/text()", nsContext, 30 );
491
492 String fiurl = getNodeAsString( datasource, "deegreewms:StaticGetFeatureInfoFile", nsContext, null );
493 URL featureInfoFile = null;
494 try {
495 featureInfoFile = fiurl == null ? null : resolve( fiurl );
496 } catch ( MalformedURLException e1 ) {
497 LOG.logError( "Unknown error", e1 );
498 }
499
500 scaleHint = parseDSScaleHint( datasource, scaleHint );
501
502 String s = "./deegreewms:OWSCapabilities/deegreewms:OnlineResource";
503 Element node = XMLTools.getRequiredElement( datasource, s, nsContext );
504
505 URL url = parseOnLineResource( node ).getLinkage().getHref();
506
507 Geometry validArea = parseValidArea( datasource );
508
509 try {
510 if ( "LOCALWFS".equals( stype ) ) {
511 ds.add( createLocalWFSDataSource( datasource, failOnEx, queryable, name, url, scaleHint, validArea,
512 reqTimeLimit ) );
513 } else if ( "LOCALWCS".equals( stype ) ) {
514 ds.add( createLocalWCSDataSource( datasource, failOnEx, queryable, name, url, scaleHint, validArea,
515 reqTimeLimit ) );
516 } else if ( "REMOTEWFS".equals( stype ) ) {
517 ds.add( createRemoteWFSDataSource( datasource, failOnEx, queryable, name, url, scaleHint,
518 validArea, reqTimeLimit ) );
519 } else if ( "REMOTEWCS".equals( stype ) ) {
520 // int type = AbstractDataSource.REMOTEWCS;
521 // GetCoverage getCoverage =
522 parseWCSFilterCondition( datasource );
523 // Color[] colors =
524 parseTransparentColors( datasource );
525 // TODO
526 throw new XMLParsingException( "REMOTEWCS is not supported yet!" );
527 } else if ( "REMOTEWMS".equals( stype ) ) {
528 ds.add( createRemoteWMSDataSource( datasource, failOnEx, queryable, name, url, scaleHint,
529 validArea, reqTimeLimit ) );
530 } else if ( "DATABASE".equals( stype ) ) {
531 ds.add( createDatabaseSource( datasource, failOnEx, queryable, name, scaleHint, validArea,
532 reqTimeLimit ) );
533 } else {
534 throw new XMLParsingException( "invalid DataSource type: " + stype + " defined "
535 + "in deegree WMS configuration for DataSource: " + name );
536 }
537 ds.getLast().setFeatureInfoURL( featureInfoFile );
538 } catch ( Exception e ) {
539 e.printStackTrace();
540 throw new XMLParsingException( "could not create service instance for WMS datasource: " + name, e );
541 }
542 }
543
544 return ds.toArray( new AbstractDataSource[nl.size()] );
545 }
546
547 /**
548 * parses the ScaleHint for a Datasource
549 *
550 * @param layerElem
551 * @param scaleHint
552 * @return the ScaleHint for the Datasource
553 * @throws XMLParsingException
554 */
555 protected ScaleHint parseDSScaleHint( Element layerElem, ScaleHint scaleHint )
556 throws XMLParsingException {
557
558 Node scNode = XMLTools.getNode( layerElem, "./deegreewms:ScaleHint", nsContext );
559 if ( scNode != null ) {
560 double mn = XMLTools.getNodeAsDouble( scNode, "./@min", nsContext, 0 );
561 double mx = XMLTools.getNodeAsDouble( scNode, "./@max", nsContext, Double.MAX_VALUE );
562 scaleHint = new ScaleHint( mn, mx );
563 }
564
565 if ( scaleHint == null ) {
566 // set default value to avoid NullPointerException
567 // when accessing a layers scalehint
568 scaleHint = new ScaleHint( 0, Double.MAX_VALUE );
569 }
570
571 return scaleHint;
572 }
573
574 /**
575 * returns the area a data source is valid. If the optional element <ValidArea>is not defined in the configuration
576 * <code>null</code>.
577 *
578 * @param node
579 * @return the geom
580 */
581 private Geometry parseValidArea( Node node )
582 throws XMLParsingException {
583
584 Geometry geom = null;
585
586 List<Node> nl = XMLTools.getNodes( node, "./deegreewms:ValidArea/*", nsContext );
587 if ( node != null ) {
588
589 try {
590 for ( int i = 0; i < nl.size(); i++ ) {
591
592 if ( nl.get( 0 ).getNamespaceURI().equals( GMLNS.toString() ) ) {
593
594 geom = GMLGeometryAdapter.wrap( (Element) nl.get( 0 ), null );
595 break;
596 }
597 }
598 } catch ( GeometryException e ) {
599 e.printStackTrace();
600 throw new XMLParsingException( "couldn't parse/create valid aera of a datasource", e );
601 }
602 }
603
604 return geom;
605 }
606
607 /**
608 * @param node
609 * @param failOnEx
610 * @param queryable
611 * @param name
612 * @param url
613 * @param scaleHint
614 * @throws Exception
615 */
616 private RemoteWMSDataSource createRemoteWMSDataSource( Node node, boolean failOnEx, boolean queryable,
617 QualifiedName name, URL url, ScaleHint scaleHint,
618 Geometry validArea, int reqTimeLimit )
619 throws Exception {
620 int type = AbstractDataSource.REMOTEWMS;
621
622 String s = "./deegreewms:FeatureInfoTransformation/deegreewms:OnlineResource";
623 Node fitNode = XMLTools.getNode( node, s, nsContext );
624 URL fitURL = null;
625 if ( fitNode != null ) {
626 fitURL = parseOnLineResource( (Element) fitNode ).getLinkage().getHref();
627 }
628
629 GetMap getMap = parseWMSFilterCondition( node );
630 Color[] colors = parseTransparentColors( node );
631 WMSCapabilities wCapa = null;
632 if ( capaCache.get( url ) != null ) {
633 wCapa = (WMSCapabilities) capaCache.get( url );
634 } else {
635 LOG.logDebug( "Fetching remote WMS capabilities from URL " + url );
636 WMSCapabilitiesDocument doc = WMSCapabilitiesDocumentFactory.getWMSCapabilitiesDocument( url );
637 wCapa = (WMSCapabilities) doc.parseCapabilities();
638 capaCache.put( url, wCapa );
639 }
640 OGCWebService ows = new RemoteWMService( wCapa );
641
642 // parse added/passed parameter map/list
643 Node vendor = XMLTools.getNode( node,
644 "deegreewms:FilterCondition/deegreewms:VendorspecificParameterDefinition",
645 nsContext );
646
647 List<String> passedParameters = WMSConfigurationDocument.parsePassedParameters( vendor );
648 Map<String, String> addedParameters = WMSConfigurationDocument.parseAddedParameters( vendor );
649
650 return new RemoteWMSDataSource( queryable, failOnEx, name, type, ows, url, scaleHint, validArea, getMap,
651 colors, fitURL, reqTimeLimit, passedParameters, addedParameters );
652 }
653
654 /**
655 * @param node
656 * @param failOnEx
657 * @param queryable
658 * @param name
659 * @param url
660 * @param scaleHint
661 * @throws Exception
662 */
663 private RemoteWFSDataSource createRemoteWFSDataSource( Node node, boolean failOnEx, boolean queryable,
664 QualifiedName name, URL url, ScaleHint scaleHint,
665 Geometry validArea, int reqTimeLimit )
666 throws Exception {
667 int type = AbstractDataSource.REMOTEWFS;
668 String s = "./deegreewms:FeatureInfoTransformation/deegreewms:OnlineResource";
669 Node fitNode = XMLTools.getNode( node, s, nsContext );
670 URL fitURL = null;
671 if ( fitNode != null ) {
672 fitURL = parseOnLineResource( (Element) fitNode ).getLinkage().getHref();
673 }
674 Query query = parseWFSFilterCondition( node );
675
676 WFSCapabilities wfsCapa = null;
677 if ( capaCache.get( url ) != null ) {
678 wfsCapa = (WFSCapabilities) capaCache.get( url );
679 } else {
680 LOG.logDebug( "Fetching remote WFS capabilities from URL " + url );
681 WFSCapabilitiesDocument wfsDoc = new WFSCapabilitiesDocument();
682 wfsDoc.load( url );
683 wfsCapa = (WFSCapabilities) wfsDoc.parseCapabilities();
684 capaCache.put( url, wfsCapa );
685 }
686 OGCWebService ows = new RemoteWFService( wfsCapa );
687 // OGCWebService ows = null;
688
689 Node geoPropNode = XMLTools.getNode( node, "deegreewms:GeometryProperty/text()", nsContext );
690 QualifiedName geoProp = DEFAULT_GEO_PROP;
691 if ( geoPropNode != null ) {
692 geoProp = parseQualifiedName( geoPropNode );
693 }
694
695 return new RemoteWFSDataSource( queryable, failOnEx, name, type, geoProp, ows, url, scaleHint, validArea,
696 query, fitURL, reqTimeLimit );
697
698 }
699
700 /**
701 * @param node
702 * @param failOnEx
703 * @param queryable
704 * @param name
705 * @param url
706 * @param scaleHint
707 * @throws Exception
708 */
709 private LocalWCSDataSource createLocalWCSDataSource( Node node, boolean failOnEx, boolean queryable,
710 QualifiedName name, URL url, ScaleHint scaleHint,
711 Geometry validArea, int reqTimeLimit )
712 throws Exception {
713 int type = AbstractDataSource.LOCALWCS;
714 GetCoverage getCoverage = parseWCSFilterCondition( node );
715 Color[] colors = parseTransparentColors( node );
716 WCSConfiguration configuration = null;
717 if ( capaCache.get( url ) != null ) {
718 configuration = (WCSConfiguration) capaCache.get( url );
719 } else {
720 configuration = WCSConfiguration.create( url );
721 capaCache.put( url, configuration );
722 }
723
724 OGCWebService ows = new WCService( configuration );
725
726 return new LocalWCSDataSource( queryable, failOnEx, name, type, ows, url, scaleHint, validArea, getCoverage,
727 colors, reqTimeLimit );
728 }
729
730 /**
731 * @param node
732 * @param failOnEx
733 * @param queryable
734 * @param name
735 * @param url
736 * @param scaleHint
737 * @throws Exception
738 */
739 private LocalWFSDataSource createLocalWFSDataSource( Node node, boolean failOnEx, boolean queryable,
740 QualifiedName name, URL url, ScaleHint scaleHint,
741 Geometry validArea, int reqTimeLimit )
742 throws Exception {
743 int type = AbstractDataSource.LOCALWFS;
744 String s = "./deegreewms:FeatureInfoTransformation/deegreewms:OnlineResource";
745 Node fitNode = XMLTools.getNode( node, s, nsContext );
746 URL fitURL = null;
747 if ( fitNode != null ) {
748 fitURL = parseOnLineResource( (Element) fitNode ).getLinkage().getHref();
749 }
750 Query query = parseWFSFilterCondition( node );
751 WFSConfiguration wfsCapa = null;
752 if ( capaCache.get( url ) != null ) {
753 wfsCapa = (WFSConfiguration) capaCache.get( url );
754 } else {
755 WFSConfigurationDocument wfsDoc = new WFSConfigurationDocument();
756 wfsDoc.load( url );
757 wfsCapa = wfsDoc.getConfiguration();
758 // wfsCapa = new WFSCapabilitiesDocument( url ).createCapabilities();
759 capaCache.put( url, wfsCapa );
760 }
761 // OGCWebService ows = WFServiceFactory.getUncachedService( wfsCapa );
762 OGCWebService ows = WFServiceFactory.createInstance( wfsCapa );
763
764 Node geoPropNode = XMLTools.getNode( node, "deegreewms:GeometryProperty/text()", nsContext );
765 QualifiedName geoProp = DEFAULT_GEO_PROP;
766 if ( geoPropNode != null ) {
767 geoProp = parseQualifiedName( geoPropNode );
768 }
769
770 Map<String, String> dimProps = new HashMap<String, String>();
771
772 for ( Element e : getElements( node, "deegreewms:DimensionProperty", nsContext ) ) {
773 dimProps.put( e.getAttribute( "name" ), e.getTextContent() );
774 }
775
776 LOG.logDebug( "geometry property", geoProp );
777
778 return new LocalWFSDataSource( queryable, failOnEx, name, type, geoProp, ows, url, scaleHint, validArea, query,
779 fitURL, reqTimeLimit, dimProps );
780 }
781
782 private Color[] parseTransparentColors( Node node )
783 throws XMLParsingException {
784
785 String s = "./deegreewms:TransparentColors/deegreewms:Color";
786 List<Node> clnl = XMLTools.getNodes( node, s, nsContext );
787 Color[] colors = new Color[clnl.size()];
788 for ( int j = 0; j < colors.length; j++ ) {
789 colors[j] = Color.decode( XMLTools.getStringValue( clnl.get( j ) ) );
790 }
791
792 return colors;
793 }
794
795 /**
796 *
797 * @param node
798 * @return the query
799 * @throws XMLParsingException
800 */
801 private Query parseWFSFilterCondition( Node node )
802 throws XMLParsingException {
803
804 Query o = null;
805
806 Node queryNode = XMLTools.getNode( node, "./deegreewms:FilterCondition/wfs:Query", nsContext );
807 if ( queryNode != null ) {
808 try {
809 o = Query.create( (Element) queryNode );
810 } catch ( Exception e ) {
811 throw new XMLParsingException( StringTools.stackTraceToString( e ) );
812 }
813 }
814
815 return o;
816 }
817
818 /**
819 *
820 * @param node
821 * @return the request object
822 * @throws XMLParsingException
823 */
824 private GetCoverage parseWCSFilterCondition( Node node )
825 throws XMLParsingException {
826
827 GetCoverage o = null;
828
829 String id = "" + IDGenerator.getInstance().generateUniqueID();
830
831 StringBuffer sd = new StringBuffer( 1000 );
832 sd.append( "version=1.0.0&Coverage=%default%&" );
833 sd.append( "CRS=EPSG:4326&BBOX=0,0,1,1&Width=1" );
834 sd.append( "&Height=1&Format=%default%&" );
835 String s = XMLTools.getNodeAsString( node, "./deegreewms:FilterCondition/deegreewms:WCSRequest", nsContext, "" );
836 sd.append( s );
837 try {
838 o = GetCoverage.create( id, sd.toString() );
839 } catch ( Exception e ) {
840 throw new XMLParsingException( "could not create GetCoverage from layer FilterCondition", e );
841 }
842
843 return o;
844 }
845
846 /**
847 *
848 * @param node
849 * @return the request object
850 * @throws XMLParsingException
851 */
852 private GetMap parseWMSFilterCondition( Node node )
853 throws XMLParsingException {
854
855 GetMap o = null;
856
857 String id = "" + IDGenerator.getInstance().generateUniqueID();
858
859 StringBuffer sd = new StringBuffer( 1000 );
860 sd.append( "REQUEST=GetMap&LAYERS=%default%&" );
861 sd.append( "STYLES=&SRS=EPSG:4326&BBOX=0,0,1,1&WIDTH=1&" );
862 sd.append( "HEIGHT=1&FORMAT=%default%" );
863 Map<String, String> map1 = KVP2Map.toMap( sd.toString() );
864 String s = XMLTools.getRequiredNodeAsString( node, "./deegreewms:FilterCondition/deegreewms:WMSRequest",
865 nsContext );
866 Map<String, String> map2 = KVP2Map.toMap( s );
867 if ( map2.get( "VERSION" ) == null && map2.get( "WMTVER" ) == null ) {
868 map2.put( "VERSION", "1.1.1" );
869 }
870 // if no service is set use WMS as default
871 if ( map2.get( "SERVICE" ) == null ) {
872 map2.put( "SERVICE", "WMS" );
873 }
874 map1.putAll( map2 );
875 try {
876 map1.put( "ID", id );
877 o = GetMap.create( map1 );
878 } catch ( Exception e ) {
879 throw new XMLParsingException( "could not create GetMap from layer FilterCondition", e );
880 }
881
882 return o;
883 }
884
885 }