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