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