001 //$HeadURL: svn+ssh://rbezema@svn.wald.intevation.org/deegree/base/branches/2.2_testing/src/org/deegree/ogcwebservices/wms/configuration/WMSConfigurationDocument_1_3_0.java $
002 /*---------------- FILE HEADER ------------------------------------------
003
004 This file is part of deegree.
005 Copyright (C) 2001-2008 by:
006 EXSE, Department of Geography, University of Bonn
007 http://www.giub.uni-bonn.de/deegree/
008 lat/lon GmbH
009 http://www.lat-lon.de
010
011 This library is free software; you can redistribute it and/or
012 modify it under the terms of the GNU Lesser General Public
013 License as published by the Free Software Foundation; either
014 version 2.1 of the License, or (at your option) any later version.
015
016 This library is distributed in the hope that it will be useful,
017 but WITHOUT ANY WARRANTY; without even the implied warranty of
018 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
019 Lesser General Public License for more details.
020
021 You should have received a copy of the GNU Lesser General Public
022 License along with this library; if not, write to the Free Software
023 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
024
025 Contact:
026
027 Andreas Poth
028 lat/lon GmbH
029 Aennchenstr. 19
030 53115 Bonn
031 Germany
032 E-Mail: poth@lat-lon.de
033
034 Prof. Dr. Klaus Greve
035 Department of Geography
036 University of Bonn
037 Meckenheimer Allee 166
038 53115 Bonn
039 Germany
040 E-Mail: greve@giub.uni-bonn.de
041
042
043 ---------------------------------------------------------------------------*/
044 package org.deegree.ogcwebservices.wms.configuration;
045
046 import java.awt.Color;
047 import java.io.IOException;
048 import java.net.MalformedURLException;
049 import java.net.URL;
050 import java.util.ArrayList;
051 import java.util.Arrays;
052 import java.util.HashMap;
053 import java.util.List;
054 import java.util.Map;
055
056 import javax.xml.transform.TransformerException;
057
058 import org.deegree.datatypes.QualifiedName;
059 import org.deegree.enterprise.Proxy;
060 import org.deegree.framework.log.ILogger;
061 import org.deegree.framework.log.LoggerFactory;
062 import org.deegree.framework.util.BootLogger;
063 import org.deegree.framework.util.IDGenerator;
064 import org.deegree.framework.util.KVP2Map;
065 import org.deegree.framework.util.StringTools;
066 import org.deegree.framework.xml.InvalidConfigurationException;
067 import org.deegree.framework.xml.XMLFragment;
068 import org.deegree.framework.xml.XMLParsingException;
069 import org.deegree.framework.xml.XMLTools;
070 import org.deegree.framework.xml.XSLTDocument;
071 import org.deegree.model.crs.UnknownCRSException;
072 import org.deegree.model.metadata.iso19115.OnlineResource;
073 import org.deegree.model.spatialschema.Envelope;
074 import org.deegree.model.spatialschema.GMLGeometryAdapter;
075 import org.deegree.model.spatialschema.Geometry;
076 import org.deegree.model.spatialschema.GeometryException;
077 import org.deegree.ogcbase.CommonNamespaces;
078 import org.deegree.ogcwebservices.OGCWebService;
079 import org.deegree.ogcwebservices.getcapabilities.MetadataURL;
080 import org.deegree.ogcwebservices.getcapabilities.OGCCapabilities;
081 import org.deegree.ogcwebservices.wcs.WCService;
082 import org.deegree.ogcwebservices.wcs.configuration.WCSConfiguration;
083 import org.deegree.ogcwebservices.wcs.getcoverage.GetCoverage;
084 import org.deegree.ogcwebservices.wfs.RemoteWFService;
085 import org.deegree.ogcwebservices.wfs.WFServiceFactory;
086 import org.deegree.ogcwebservices.wfs.capabilities.WFSCapabilities;
087 import org.deegree.ogcwebservices.wfs.capabilities.WFSCapabilitiesDocument;
088 import org.deegree.ogcwebservices.wfs.configuration.WFSConfiguration;
089 import org.deegree.ogcwebservices.wfs.configuration.WFSConfigurationDocument;
090 import org.deegree.ogcwebservices.wfs.operation.Query;
091 import org.deegree.ogcwebservices.wms.RemoteWMService;
092 import org.deegree.ogcwebservices.wms.capabilities.Attribution;
093 import org.deegree.ogcwebservices.wms.capabilities.AuthorityURL;
094 import org.deegree.ogcwebservices.wms.capabilities.DataURL;
095 import org.deegree.ogcwebservices.wms.capabilities.Dimension;
096 import org.deegree.ogcwebservices.wms.capabilities.FeatureListURL;
097 import org.deegree.ogcwebservices.wms.capabilities.Identifier;
098 import org.deegree.ogcwebservices.wms.capabilities.Layer;
099 import org.deegree.ogcwebservices.wms.capabilities.LayerBoundingBox;
100 import org.deegree.ogcwebservices.wms.capabilities.LegendURL;
101 import org.deegree.ogcwebservices.wms.capabilities.ScaleHint;
102 import org.deegree.ogcwebservices.wms.capabilities.Style;
103 import org.deegree.ogcwebservices.wms.capabilities.StyleSheetURL;
104 import org.deegree.ogcwebservices.wms.capabilities.StyleURL;
105 import org.deegree.ogcwebservices.wms.capabilities.WMSCapabilities;
106 import org.deegree.ogcwebservices.wms.capabilities.WMSCapabilitiesDocument;
107 import org.deegree.ogcwebservices.wms.capabilities.WMSCapabilitiesDocumentFactory;
108 import org.deegree.ogcwebservices.wms.capabilities.WMSCapabilitiesDocument_1_3_0;
109 import org.deegree.ogcwebservices.wms.operation.GetMap;
110 import org.deegree.owscommon_new.OperationsMetadata;
111 import org.deegree.owscommon_new.ServiceIdentification;
112 import org.deegree.owscommon_new.ServiceProvider;
113 import org.w3c.dom.Element;
114 import org.w3c.dom.Node;
115 import org.xml.sax.SAXException;
116
117 /**
118 * <code>WMSConfigurationDocument_1_3_0</code> is the parser class for a WMS 1.3.0 configuration
119 * document.
120 *
121 * @author <a href="mailto:schmitz@lat-lon.de">Andreas Schmitz</a>
122 * @author last edited by: $Author: apoth $
123 *
124 * @version 2.0, $Revision: 9345 $, $Date: 2007-12-27 17:22:25 +0100 (Do, 27 Dez 2007) $
125 *
126 * @since 2.0
127 */
128
129 public class WMSConfigurationDocument_1_3_0 extends WMSCapabilitiesDocument_1_3_0 {
130
131 private static final long serialVersionUID = -2304421871404603016L;
132
133 private static Map<URL, OGCCapabilities> capaCache = new HashMap<URL, OGCCapabilities>();
134
135 private static final String XML_TEMPLATE = "WMSConfigurationTemplate_1_3_0.xml";
136
137 private static final String XSLT_TEMPLATE_NAME = "WMSConfigurationTransform_1_3_0.xsl";
138
139 private static XSLTDocument XSLT_TEMPLATE;
140
141 private static final ILogger LOG = LoggerFactory.getLogger( WMSConfigurationDocument_1_3_0.class );
142
143 private static final String PWMS = CommonNamespaces.WMS_PREFIX + ":";
144
145 private static final QualifiedName DEFAULT_GEO_PROP = new QualifiedName(
146 "app",
147 "GEOM",
148 CommonNamespaces.buildNSURI( "http://www.deegree.org/app" ) );
149 static {
150 XSLT_TEMPLATE = new XSLTDocument();
151 try {
152 XSLT_TEMPLATE.load( WMSConfigurationDocument_1_3_0.class.getResource( XSLT_TEMPLATE_NAME ) );
153 } catch ( Exception e ) {
154 BootLogger.logError( "Error loading XSLT sheet in WMSConfigurationDocument_1_3_0.", e );
155 }
156 }
157
158 /**
159 *
160 */
161 public static void resetCapabilitiesCache() {
162 capaCache.clear();
163 }
164
165 @Override
166 public void createEmptyDocument()
167 throws IOException, SAXException {
168 URL url = WMSConfigurationDocument_1_3_0.class.getResource( XML_TEMPLATE );
169 if ( url == null ) {
170 throw new IOException( "The resource '" + XML_TEMPLATE + " could not be found." );
171 }
172 load( url );
173 }
174
175 /**
176 * Added the prefix.
177 *
178 * @return the parsed configuration
179 * @throws InvalidConfigurationException
180 * @throws XMLParsingException
181 */
182 public WMSConfiguration_1_3_0 parseConfiguration()
183 throws InvalidConfigurationException, XMLParsingException {
184
185 try {
186 // transform document to fill missing elements and attributes with
187 // default values
188 XMLFragment frag = XSLT_TEMPLATE.transform( this );
189 this.setRootElement( frag.getRootElement() );
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
276 URL dtdLocation = null;
277 if ( XMLTools.getNode( root, "deegreewms:DTDLocation", nsContext ) != null ) {
278 elem = (Element) XMLTools.getRequiredNode( root, "./deegreewms:DTDLocation/deegreewms:OnlineResource",
279 nsContext );
280 OnlineResource olr = parseOnLineResource( elem );
281 dtdLocation = olr.getLinkage().getHref();
282 } else {
283 dtdLocation = new URL( "http://schemas.opengis.net/wms/1.1.1/WMS_MS_Capabilities.dtd" );
284 }
285
286 URL featureSchemaLocation = null;
287 String featureSchemaNamespace = null;
288 if ( XMLTools.getNode( root, "deegreewms:FeatureInfoSchema", nsContext ) != null ) {
289 featureSchemaNamespace = XMLTools.getRequiredNodeAsString(
290 root,
291 "deegreewms:FeatureInfoSchema/deegreewms:Namespace",
292 nsContext );
293 elem = (Element) XMLTools.getRequiredNode( root, "deegreewms:FeatureInfoSchema/deegreewms:OnlineResource",
294 nsContext );
295 OnlineResource link = parseOnLineResource( elem );
296 featureSchemaLocation = link.getLinkage().getHref();
297 }
298
299 boolean antiAliased = XMLTools.getNodeAsBoolean( root, "./deegreewms:AntiAliased", nsContext, true );
300
301 Proxy proxy = parseProxy( root );
302
303 List<String> supportedVersions = parseSupportedVersions( root );
304
305 WMSDeegreeParams deegreeParams = new WMSDeegreeParams( cache, maxLifeTime, reqTimeLimit, (float) mapQuality,
306 ol, 0, 0, antiAliased, featureInfoRadius, copyright,
307 null, dtdLocation, proxy, supportedVersions,
308 featureSchemaLocation, featureSchemaNamespace );
309
310 return deegreeParams;
311 }
312
313 // returns the list of supported versions
314 private List<String> parseSupportedVersions( Node root )
315 throws XMLParsingException {
316
317 String[] versions = XMLTools.getNodesAsStrings( root, "./deegreewms:SupportedVersion", nsContext );
318
319 if ( versions != null )
320 return Arrays.asList( versions );
321
322 return new ArrayList<String>();
323
324 }
325
326 /**
327 * @param root
328 * @return the proxy
329 * @throws XMLParsingException
330 */
331 private Proxy parseProxy( Node root )
332 throws XMLParsingException {
333
334 Proxy proxy = null;
335 Node pro = XMLTools.getNode( root, "./deegreewms:Proxy", nsContext );
336 if ( pro != null ) {
337 String proxyHost = XMLTools.getRequiredNodeAsString( pro, "./@proxyHost", nsContext );
338 String proxyPort = XMLTools.getRequiredNodeAsString( pro, "./@proxyPort", nsContext );
339 proxy = new Proxy( proxyHost, proxyPort );
340 }
341
342 return proxy;
343 }
344
345 /*
346 * Removed Extent. Added prefix. Changed SRS to CRS.
347 */
348 @Override
349 protected Layer parseLayers( Element layerElem, Layer parent, ScaleHint scaleHint )
350 throws XMLParsingException, UnknownCRSException {
351
352 boolean queryable = XMLTools.getNodeAsBoolean( layerElem, "./@queryable", nsContext, false );
353 int cascaded = XMLTools.getNodeAsInt( layerElem, "./@cascaded", nsContext, 0 );
354 boolean opaque = XMLTools.getNodeAsBoolean( layerElem, "./@opaque", nsContext, false );
355 boolean noSubsets = XMLTools.getNodeAsBoolean( layerElem, "./@noSubsets", nsContext, false );
356 int fixedWidth = XMLTools.getNodeAsInt( layerElem, "./@fixedWidth", nsContext, 0 );
357 int fixedHeight = XMLTools.getNodeAsInt( layerElem, "./@fixedHeight", nsContext, 0 );
358 String name = XMLTools.getNodeAsString( layerElem, PWMS + "Name", nsContext, null );
359 String title = XMLTools.getRequiredNodeAsString( layerElem, PWMS + "Title", nsContext );
360 String layerAbstract = XMLTools.getNodeAsString( layerElem, PWMS + "Abstract", nsContext, null );
361 String[] keywords = XMLTools.getNodesAsStrings( layerElem, PWMS + "KeywordList/" + PWMS + "Keyword", nsContext );
362 String[] srs = XMLTools.getNodesAsStrings( layerElem, PWMS + "CRS", nsContext );
363
364 List<Element> nl = XMLTools.getElements( layerElem, PWMS + "BoundingBox", nsContext );
365 // TODO
366 // substitue with Envelope
367 LayerBoundingBox[] bboxes = null;
368 if ( nl.size() == 0 && parent != null ) {
369 // inherit BoundingBoxes from parent layer
370 bboxes = parent.getBoundingBoxes();
371 } else {
372 bboxes = parseLayerBoundingBoxes( nl );
373 }
374
375 Element llBox = (Element) XMLTools.getNode( layerElem, PWMS + "EX_GeographicBoundingBox", nsContext );
376 Envelope llBoundingBox = null;
377 if ( llBox == null && parent != null ) {
378 // inherit LatLonBoundingBox parent layer
379 llBoundingBox = parent.getLatLonBoundingBox();
380 } else {
381 llBoundingBox = parseEX_GeographicBoundingBox( llBox );
382 }
383
384 Dimension[] dimensions = parseDimensions( layerElem );
385 // Extent[] extents = parseExtents( layerElem );
386
387 Attribution attribution = parseAttribution( layerElem );
388
389 AuthorityURL[] authorityURLs = parseAuthorityURLs( layerElem );
390
391 MetadataURL[] metadataURLs = parseMetadataURLs( layerElem );
392
393 DataURL[] dataURLs = parseDataURL( layerElem );
394
395 Identifier[] identifiers = parseIdentifiers( layerElem );
396
397 FeatureListURL[] featureListURLs = parseFeatureListURL( layerElem );
398
399 Style[] styles = parseStyles( layerElem );
400
401 scaleHint = parseScaleHint( layerElem, scaleHint );
402
403 AbstractDataSource[] ds = parseDataSources( layerElem, name, scaleHint );
404
405 Layer layer = new Layer( queryable, cascaded, opaque, noSubsets, fixedWidth, fixedHeight, name, title,
406 layerAbstract, llBoundingBox, attribution, scaleHint, keywords, srs, bboxes,
407 dimensions, null, authorityURLs, identifiers, metadataURLs, dataURLs, featureListURLs,
408 styles, null, ds, parent );
409
410 // get Child layers
411 nl = XMLTools.getElements( layerElem, PWMS + "Layer", nsContext );
412 Layer[] layers = new Layer[nl.size()];
413 for ( int i = 0; i < layers.length; i++ ) {
414 layers[i] = parseLayers( nl.get( i ), layer, scaleHint );
415 }
416
417 // set child layers
418 layer.setLayer( layers );
419
420 return layer;
421 }
422
423 /*
424 * Added the prefix.
425 */
426 @Override
427 protected Style[] parseStyles( Element layerElem )
428 throws XMLParsingException {
429
430 List<Element> nl = XMLTools.getElements( layerElem, PWMS + "Style", nsContext );
431 Style[] styles = new Style[nl.size()];
432 for ( int i = 0; i < styles.length; i++ ) {
433 String name = XMLTools.getRequiredNodeAsString( nl.get( i ), PWMS + "Name", nsContext );
434 String title = XMLTools.getNodeAsString( nl.get( i ), PWMS + "Title", nsContext, null );
435 String styleAbstract = XMLTools.getNodeAsString( nl.get( i ), PWMS + "Abstract", nsContext, null );
436 LegendURL[] legendURLs = parseLegendURL( nl.get( i ) );
437 StyleURL styleURL = parseStyleURL( nl.get( i ) );
438 StyleSheetURL styleSheetURL = parseStyleSheetURL( nl.get( i ) );
439 String styleResource = XMLTools.getNodeAsString( nl.get( i ), "deegreewms:StyleResource", nsContext,
440 "styles.xml" );
441 URL sr = null;
442 try {
443 sr = resolve( styleResource );
444 } catch ( MalformedURLException e ) {
445 throw new XMLParsingException( "could not parse style resource of style: " + name, e );
446 }
447
448 String layerName = XMLTools.getRequiredNodeAsString( layerElem, PWMS + "Name", nsContext );
449 if ( name == null || name.length() == 0 ) {
450 name = "default:" + layerName;
451 }
452 if ( name.equals( "default" ) ) {
453 name += ":" + layerName;
454 }
455 if ( name.equals( "default:" ) ) {
456 name += layerName;
457 }
458
459 styles[i] = new Style( name, title, styleAbstract, legendURLs, styleSheetURL, styleURL, sr );
460 }
461
462 return styles;
463 }
464
465 /**
466 *
467 * @param layerElem
468 * @return the data sources
469 * @throws XMLParsingException
470 */
471 protected AbstractDataSource[] parseDataSources( Element layerElem, String layerName, ScaleHint scaleHint )
472 throws XMLParsingException {
473
474 List<Element> nl = XMLTools.getElements( layerElem, "./deegreewms:DataSource", nsContext );
475
476 AbstractDataSource[] ds = new AbstractDataSource[nl.size()];
477 for ( int i = 0; i < ds.length; i++ ) {
478 boolean failOnEx = XMLTools.getNodeAsBoolean( nl.get( i ), "./@failOnException", nsContext, true );
479 boolean queryable = XMLTools.getNodeAsBoolean( nl.get( i ), "./@queryable", nsContext, false );
480 QualifiedName name = XMLTools.getNodeAsQualifiedName( nl.get( i ), "./deegreewms:Name/text()", nsContext,
481 new QualifiedName( layerName ) );
482 String stype = XMLTools.getRequiredNodeAsString( nl.get( i ), "./deegreewms:Type", nsContext );
483
484 int reqTimeLimit = XMLTools.getNodeAsInt( nl.get( i ), "./deegreewms:RequestTimeLimit/text()", nsContext,
485 30 );
486
487 scaleHint = parseDSScaleHint( nl.get( i ), scaleHint );
488
489 String s = "./deegreewms:OWSCapabilities/deegreewms:OnlineResource";
490 Element node = XMLTools.getRequiredElement( nl.get( i ), s, nsContext );
491
492 URL url = parseOnLineResource( node ).getLinkage().getHref();
493
494 Geometry validArea = parseValidArea( nl.get( i ) );
495
496 try {
497 if ( "LOCALWFS".equals( stype ) ) {
498 ds[i] = createLocalWFSDataSource( nl.get( i ), failOnEx, queryable, name, url, scaleHint,
499 validArea, reqTimeLimit );
500 } else if ( "LOCALWCS".equals( stype ) ) {
501 ds[i] = createLocalWCSDataSource( nl.get( i ), failOnEx, queryable, name, url, scaleHint,
502 validArea, reqTimeLimit );
503 } else if ( "REMOTEWFS".equals( stype ) ) {
504 ds[i] = createRemoteWFSDataSource( nl.get( i ), failOnEx, queryable, name, url, scaleHint,
505 validArea, reqTimeLimit );
506 } else if ( "REMOTEWCS".equals( stype ) ) {
507 // int type = AbstractDataSource.REMOTEWCS;
508 // GetCoverage getCoverage =
509 parseWCSFilterCondition( nl.get( i ) );
510 // Color[] colors =
511 parseTransparentColors( nl.get( i ) );
512 // TODO
513 throw new XMLParsingException( "REMOTEWCS is not supported yet!" );
514 } else if ( "REMOTEWMS".equals( stype ) ) {
515 ds[i] = createRemoteWMSDataSource( nl.get( i ), failOnEx, queryable, name, url, scaleHint,
516 validArea, reqTimeLimit );
517 } else {
518 throw new XMLParsingException( "invalid DataSource type: " + stype + " defined "
519 + "in deegree WMS configuration for DataSource: " + name );
520 }
521 } catch ( Exception e ) {
522 e.printStackTrace();
523 throw new XMLParsingException( "could not create service instance for WMS datasource: " + name, e );
524 }
525 }
526
527 return ds;
528 }
529
530 /**
531 * parses the ScaleHint for a Datasource
532 *
533 * @param layerElem
534 * @param scaleHint
535 * @return the ScaleHint for the Datasource
536 * @throws XMLParsingException
537 */
538 protected ScaleHint parseDSScaleHint( Element layerElem, ScaleHint scaleHint )
539 throws XMLParsingException {
540
541 Node scNode = XMLTools.getNode( layerElem, "./deegreewms:ScaleHint", nsContext );
542 if ( scNode != null ) {
543 double mn = XMLTools.getNodeAsDouble( scNode, "./@min", nsContext, 0 );
544 double mx = XMLTools.getNodeAsDouble( scNode, "./@max", nsContext, Double.MAX_VALUE );
545 scaleHint = new ScaleHint( mn, mx );
546 }
547
548 if ( scaleHint == null ) {
549 // set default value to avoid NullPointerException
550 // when accessing a layers scalehint
551 scaleHint = new ScaleHint( 0, Double.MAX_VALUE );
552 }
553
554 return scaleHint;
555 }
556
557 /**
558 * returns the area a data source is valid. If the optional element <ValidArea>is not defined in
559 * the configuration <code>null</code>.
560 *
561 * @param node
562 * @return the geom
563 * @throws Exception
564 */
565 private Geometry parseValidArea( Node node )
566 throws XMLParsingException {
567
568 Geometry geom = null;
569
570 List<Node> nl = XMLTools.getNodes( node, "./deegreewms:ValidArea/*", nsContext );
571 if ( node != null ) {
572
573 try {
574 for ( int i = 0; i < nl.size(); i++ ) {
575
576 if ( nl.get( 0 ).getNamespaceURI().equals( GMLNS.toString() ) ) {
577
578 geom = GMLGeometryAdapter.wrap( (Element) nl.get( 0 ), null );
579 break;
580 }
581 }
582 } catch ( GeometryException e ) {
583 e.printStackTrace();
584 throw new XMLParsingException( "couldn't parse/create valid aera of a datasource", e );
585 }
586 }
587
588 return geom;
589 }
590
591 /**
592 * @param node
593 * @param failOnEx
594 * @param queryable
595 * @param name
596 * @param geoProp
597 * @param url
598 * @param scaleHint
599 * @throws Exception
600 */
601 private RemoteWMSDataSource createRemoteWMSDataSource( Node node, boolean failOnEx, boolean queryable,
602 QualifiedName name, URL url, ScaleHint scaleHint,
603 Geometry validArea, int reqTimeLimit )
604 throws Exception {
605 int type = AbstractDataSource.REMOTEWMS;
606
607 String s = "./deegreewms:FeatureInfoTransformation/deegreewms:OnlineResource";
608 Node fitNode = XMLTools.getNode( node, s, nsContext );
609 URL fitURL = null;
610 if ( fitNode != null ) {
611 fitURL = parseOnLineResource( (Element) fitNode ).getLinkage().getHref();
612 }
613
614 GetMap getMap = parseWMSFilterCondition( node );
615 Color[] colors = parseTransparentColors( node );
616 WMSCapabilities wCapa = null;
617 if ( capaCache.get( url ) != null ) {
618 wCapa = (WMSCapabilities) capaCache.get( url );
619 } else {
620 WMSCapabilitiesDocument doc = WMSCapabilitiesDocumentFactory.getWMSCapabilitiesDocument( url );
621 LOG.logDebug( "Fetching remote WMS capabilities from URL " + url + " succeeded." );
622 wCapa = (WMSCapabilities) doc.parseCapabilities();
623 capaCache.put( url, wCapa );
624 }
625 OGCWebService ows = new RemoteWMService( wCapa );
626
627 // parse added/passed parameter map/list
628 Node vendor = XMLTools.getNode( node,
629 "deegreewms:FilterCondition/deegreewms:VendorspecificParameterDefinition",
630 nsContext );
631
632 List<String> passedParameters = WMSConfigurationDocument.parsePassedParameters( vendor );
633 Map<String, String> addedParameters = WMSConfigurationDocument.parseAddedParameters( vendor );
634
635 return new RemoteWMSDataSource( queryable, failOnEx, name, type, ows, url, scaleHint, validArea, getMap,
636 colors, fitURL, reqTimeLimit, passedParameters, addedParameters );
637 }
638
639 /**
640 * @param node
641 * @param failOnEx
642 * @param queryable
643 * @param name
644 * @param geoProp
645 * @param url
646 * @param scaleHint
647 * @throws Exception
648 */
649 private RemoteWFSDataSource createRemoteWFSDataSource( Node node, boolean failOnEx, boolean queryable,
650 QualifiedName name, URL url, ScaleHint scaleHint,
651 Geometry validArea, int reqTimeLimit )
652 throws Exception {
653 int type = AbstractDataSource.REMOTEWFS;
654 String s = "./deegreewms:FeatureInfoTransformation/deegreewms:OnlineResource";
655 Node fitNode = XMLTools.getNode( node, s, nsContext );
656 URL fitURL = null;
657 if ( fitNode != null ) {
658 fitURL = parseOnLineResource( (Element) fitNode ).getLinkage().getHref();
659 }
660 Query query = parseWFSFilterCondition( node );
661
662 WFSCapabilities wfsCapa = null;
663 if ( capaCache.get( url ) != null ) {
664 wfsCapa = (WFSCapabilities) capaCache.get( url );
665 } else {
666 WFSCapabilitiesDocument wfsDoc = new WFSCapabilitiesDocument();
667 wfsDoc.load( url );
668 wfsCapa = (WFSCapabilities) wfsDoc.parseCapabilities();
669 capaCache.put( url, wfsCapa );
670 }
671 OGCWebService ows = new RemoteWFService( wfsCapa );
672 // OGCWebService ows = null;
673
674 Node geoPropNode = XMLTools.getNode( node, "deegreewms:GeometryProperty/text()", nsContext );
675 QualifiedName geoProp = DEFAULT_GEO_PROP;
676 if ( geoPropNode != null ) {
677 geoProp = parseQualifiedName( geoPropNode );
678 }
679
680 return new RemoteWFSDataSource( queryable, failOnEx, name, type, geoProp, ows, url, scaleHint, validArea,
681 query, fitURL, reqTimeLimit );
682
683 }
684
685 /**
686 * @param node
687 * @param failOnEx
688 * @param queryable
689 * @param name
690 * @param geoProp
691 * @param url
692 * @param scaleHint
693 * @throws Exception
694 */
695 private LocalWCSDataSource createLocalWCSDataSource( Node node, boolean failOnEx, boolean queryable,
696 QualifiedName name, URL url, ScaleHint scaleHint,
697 Geometry validArea, int reqTimeLimit )
698 throws Exception {
699 int type = AbstractDataSource.LOCALWCS;
700 GetCoverage getCoverage = parseWCSFilterCondition( node );
701 Color[] colors = parseTransparentColors( node );
702 WCSConfiguration configuration = null;
703 if ( capaCache.get( url ) != null ) {
704 configuration = (WCSConfiguration) capaCache.get( url );
705 } else {
706 configuration = WCSConfiguration.create( url );
707 capaCache.put( url, configuration );
708 }
709
710 OGCWebService ows = new WCService( configuration );
711
712 return new LocalWCSDataSource( queryable, failOnEx, name, type, ows, url, scaleHint, validArea, getCoverage,
713 colors, reqTimeLimit );
714 }
715
716 /**
717 * @param node
718 * @param failOnEx
719 * @param queryable
720 * @param name
721 * @param geoProp
722 * @param url
723 * @param scaleHint
724 * @throws Exception
725 */
726 private LocalWFSDataSource createLocalWFSDataSource( Node node, boolean failOnEx, boolean queryable,
727 QualifiedName name, URL url, ScaleHint scaleHint,
728 Geometry validArea, int reqTimeLimit )
729 throws Exception {
730 int type = AbstractDataSource.LOCALWFS;
731 String s = "./deegreewms:FeatureInfoTransformation/deegreewms:OnlineResource";
732 Node fitNode = XMLTools.getNode( node, s, nsContext );
733 URL fitURL = null;
734 if ( fitNode != null ) {
735 fitURL = parseOnLineResource( (Element) fitNode ).getLinkage().getHref();
736 }
737 Query query = parseWFSFilterCondition( node );
738 WFSConfiguration wfsCapa = null;
739 if ( capaCache.get( url ) != null ) {
740 wfsCapa = (WFSConfiguration) capaCache.get( url );
741 } else {
742 WFSConfigurationDocument wfsDoc = new WFSConfigurationDocument();
743 wfsDoc.load( url );
744 wfsCapa = wfsDoc.getConfiguration();
745 // wfsCapa = new WFSCapabilitiesDocument( url ).createCapabilities();
746 capaCache.put( url, wfsCapa );
747 }
748 // OGCWebService ows = WFServiceFactory.getUncachedService( wfsCapa );
749 OGCWebService ows = WFServiceFactory.createInstance( wfsCapa );
750
751 Node geoPropNode = XMLTools.getNode( node, "deegreewms:GeometryProperty/text()", nsContext );
752 QualifiedName geoProp = DEFAULT_GEO_PROP;
753 if ( geoPropNode != null ) {
754 geoProp = parseQualifiedName( geoPropNode );
755 }
756
757 LOG.logDebug( "geometry property", geoProp );
758
759 return new LocalWFSDataSource( queryable, failOnEx, name, type, geoProp, ows, url, scaleHint, validArea, query,
760 fitURL, reqTimeLimit );
761 }
762
763 /**
764 * @param nl
765 * @param type
766 * @throws XMLParsingException
767 */
768 private Color[] parseTransparentColors( Node node )
769 throws XMLParsingException {
770
771 String s = "./deegreewms:TransparentColors/deegreewms:Color";
772 List<Node> clnl = XMLTools.getNodes( node, s, nsContext );
773 Color[] colors = new Color[clnl.size()];
774 for ( int j = 0; j < colors.length; j++ ) {
775 colors[j] = Color.decode( XMLTools.getStringValue( clnl.get( j ) ) );
776 }
777
778 return colors;
779 }
780
781 /**
782 *
783 * @param node
784 * @return the query
785 * @throws XMLParsingException
786 */
787 private Query parseWFSFilterCondition( Node node )
788 throws XMLParsingException {
789
790 Query o = null;
791
792 Node queryNode = XMLTools.getNode( node, "./deegreewms:FilterCondition/wfs:Query", nsContext );
793 if ( queryNode != null ) {
794 try {
795 o = Query.create( (Element) queryNode );
796 } catch ( Exception e ) {
797 throw new XMLParsingException( StringTools.stackTraceToString( e ) );
798 }
799 }
800
801 return o;
802 }
803
804 /**
805 *
806 * @param node
807 * @return the request object
808 * @throws XMLParsingException
809 */
810 private GetCoverage parseWCSFilterCondition( Node node )
811 throws XMLParsingException {
812
813 GetCoverage o = null;
814
815 String id = "" + IDGenerator.getInstance().generateUniqueID();
816
817 StringBuffer sd = new StringBuffer( 1000 );
818 sd.append( "version=1.0.0&Coverage=%default%&" );
819 sd.append( "CRS=EPSG:4326&BBOX=0,0,1,1&Width=1" );
820 sd.append( "&Height=1&Format=%default%&" );
821 String s = XMLTools.getNodeAsString( node, "./deegreewms:FilterCondition/deegreewms:WCSRequest", nsContext, "" );
822 sd.append( s );
823 try {
824 o = GetCoverage.create( id, sd.toString() );
825 } catch ( Exception e ) {
826 throw new XMLParsingException( "could not create GetCoverage from layer FilterCondition", e );
827 }
828
829 return o;
830 }
831
832 /**
833 *
834 * @param node
835 * @return the request object
836 * @throws XMLParsingException
837 */
838 private GetMap parseWMSFilterCondition( Node node )
839 throws XMLParsingException {
840
841 GetMap o = null;
842
843 String id = "" + IDGenerator.getInstance().generateUniqueID();
844
845 StringBuffer sd = new StringBuffer( 1000 );
846 sd.append( "REQUEST=GetMap&LAYERS=%default%&" );
847 sd.append( "STYLES=&SRS=EPSG:4326&BBOX=0,0,1,1&WIDTH=1&" );
848 sd.append( "HEIGHT=1&FORMAT=%default%" );
849 Map<String, String> map1 = KVP2Map.toMap( sd.toString() );
850 String s = XMLTools.getRequiredNodeAsString( node, "./deegreewms:FilterCondition/deegreewms:WMSRequest",
851 nsContext );
852 Map<String, String> map2 = KVP2Map.toMap( s );
853 if ( map2.get( "VERSION" ) == null && map2.get( "WMTVER" ) == null ) {
854 map2.put( "VERSION", "1.1.1" );
855 }
856 // if no service is set use WMS as default
857 if ( map2.get( "SERVICE" ) == null ) {
858 map2.put( "SERVICE", "WMS" );
859 }
860 map1.putAll( map2 );
861 try {
862 map1.put( "ID", id );
863 o = GetMap.create( map1 );
864 } catch ( Exception e ) {
865 throw new XMLParsingException( "could not create GetMap from layer FilterCondition", e );
866 }
867
868 return o;
869 }
870
871 }