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