0001: //$HeadURL: https://svn.wald.intevation.org/svn/deegree/base/trunk/src/org/deegree/ogcwebservices/wms/configuration/WMSConfigurationDocument.java $
0002: /*---------------- FILE HEADER ------------------------------------------
0003:
0004: This file is part of deegree.
0005: Copyright (C) 2001-2008 by:
0006: EXSE, Department of Geography, University of Bonn
0007: http://www.giub.uni-bonn.de/deegree/
0008: lat/lon GmbH
0009: http://www.lat-lon.de
0010:
0011: This library is free software; you can redistribute it and/or
0012: modify it under the terms of the GNU Lesser General Public
0013: License as published by the Free Software Foundation; either
0014: version 2.1 of the License, or (at your option) any later version.
0015:
0016: This library is distributed in the hope that it will be useful,
0017: but WITHOUT ANY WARRANTY; without even the implied warranty of
0018: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
0019: Lesser General Public License for more details.
0020:
0021: You should have received a copy of the GNU Lesser General Public
0022: License along with this library; if not, write to the Free Software
0023: Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
0024:
0025: Contact:
0026:
0027: Andreas Poth
0028: lat/lon GmbH
0029: Aennchenstraße 19
0030: 53177 Bonn
0031: Germany
0032: E-Mail: poth@lat-lon.de
0033:
0034: Prof. Dr. Klaus Greve
0035: Department of Geography
0036: University of Bonn
0037: Meckenheimer Allee 166
0038: 53115 Bonn
0039: Germany
0040: E-Mail: greve@giub.uni-bonn.de
0041:
0042: ---------------------------------------------------------------------------*/
0043: package org.deegree.ogcwebservices.wms.configuration;
0044:
0045: import java.awt.Color;
0046: import java.io.IOException;
0047: import java.net.MalformedURLException;
0048: import java.net.URI;
0049: import java.net.URL;
0050: import java.util.ArrayList;
0051: import java.util.Arrays;
0052: import java.util.HashMap;
0053: import java.util.List;
0054: import java.util.Map;
0055:
0056: import javax.xml.transform.TransformerException;
0057:
0058: import org.deegree.datatypes.QualifiedName;
0059: import org.deegree.enterprise.Proxy;
0060: import org.deegree.framework.log.ILogger;
0061: import org.deegree.framework.log.LoggerFactory;
0062: import org.deegree.framework.util.BootLogger;
0063: import org.deegree.framework.util.IDGenerator;
0064: import org.deegree.framework.util.KVP2Map;
0065: import org.deegree.framework.util.StringTools;
0066: import org.deegree.framework.xml.InvalidConfigurationException;
0067: import org.deegree.framework.xml.XMLFragment;
0068: import org.deegree.framework.xml.XMLParsingException;
0069: import org.deegree.framework.xml.XMLTools;
0070: import org.deegree.framework.xml.XSLTDocument;
0071: import org.deegree.i18n.Messages;
0072: import org.deegree.model.crs.UnknownCRSException;
0073: import org.deegree.model.metadata.iso19115.OnlineResource;
0074: import org.deegree.model.spatialschema.Envelope;
0075: import org.deegree.model.spatialschema.GMLGeometryAdapter;
0076: import org.deegree.model.spatialschema.Geometry;
0077: import org.deegree.model.spatialschema.GeometryException;
0078: import org.deegree.ogcbase.CommonNamespaces;
0079: import org.deegree.ogcwebservices.OGCWebService;
0080: import org.deegree.ogcwebservices.getcapabilities.MetadataURL;
0081: import org.deegree.ogcwebservices.getcapabilities.OGCCapabilities;
0082: import org.deegree.ogcwebservices.wcs.WCService;
0083: import org.deegree.ogcwebservices.wcs.configuration.WCSConfiguration;
0084: import org.deegree.ogcwebservices.wcs.getcoverage.GetCoverage;
0085: import org.deegree.ogcwebservices.wfs.RemoteWFService;
0086: import org.deegree.ogcwebservices.wfs.WFServiceFactory;
0087: import org.deegree.ogcwebservices.wfs.capabilities.WFSCapabilities;
0088: import org.deegree.ogcwebservices.wfs.capabilities.WFSCapabilitiesDocument;
0089: import org.deegree.ogcwebservices.wfs.configuration.WFSConfiguration;
0090: import org.deegree.ogcwebservices.wfs.configuration.WFSConfigurationDocument;
0091: import org.deegree.ogcwebservices.wfs.operation.Query;
0092: import org.deegree.ogcwebservices.wms.RemoteWMService;
0093: import org.deegree.ogcwebservices.wms.capabilities.Attribution;
0094: import org.deegree.ogcwebservices.wms.capabilities.AuthorityURL;
0095: import org.deegree.ogcwebservices.wms.capabilities.DataURL;
0096: import org.deegree.ogcwebservices.wms.capabilities.Dimension;
0097: import org.deegree.ogcwebservices.wms.capabilities.Extent;
0098: import org.deegree.ogcwebservices.wms.capabilities.FeatureListURL;
0099: import org.deegree.ogcwebservices.wms.capabilities.Identifier;
0100: import org.deegree.ogcwebservices.wms.capabilities.Layer;
0101: import org.deegree.ogcwebservices.wms.capabilities.LayerBoundingBox;
0102: import org.deegree.ogcwebservices.wms.capabilities.LegendURL;
0103: import org.deegree.ogcwebservices.wms.capabilities.ScaleHint;
0104: import org.deegree.ogcwebservices.wms.capabilities.Style;
0105: import org.deegree.ogcwebservices.wms.capabilities.StyleSheetURL;
0106: import org.deegree.ogcwebservices.wms.capabilities.StyleURL;
0107: import org.deegree.ogcwebservices.wms.capabilities.UserDefinedSymbolization;
0108: import org.deegree.ogcwebservices.wms.capabilities.WMSCapabilities;
0109: import org.deegree.ogcwebservices.wms.capabilities.WMSCapabilitiesDocument;
0110: import org.deegree.ogcwebservices.wms.capabilities.WMSCapabilitiesDocumentFactory;
0111: import org.deegree.ogcwebservices.wms.operation.GetMap;
0112: import org.deegree.owscommon_new.OperationsMetadata;
0113: import org.deegree.owscommon_new.ServiceIdentification;
0114: import org.deegree.owscommon_new.ServiceProvider;
0115: import org.w3c.dom.Element;
0116: import org.w3c.dom.Node;
0117: import org.xml.sax.SAXException;
0118:
0119: /**
0120: * <code>WMSConfigurationDocument</code> is the parser class for a standard 1.1.1 WMS
0121: * configuration document, ie, a capabilities document enriched by deegree parameters.
0122: *
0123: * @author <a href="mailto:mschneider@lat-lon.de">Markus Schneider </a>
0124: * @author last edited by: $Author: apoth $
0125: *
0126: * @version 2.0, $Revision: 9345 $, $Date: 2007-12-27 08:22:25 -0800 (Thu, 27 Dec 2007) $
0127: *
0128: * @since 2.0
0129: */
0130: public class WMSConfigurationDocument extends WMSCapabilitiesDocument {
0131:
0132: private static final long serialVersionUID = 2320990982989322325L;
0133:
0134: protected static final URI DEEGREEWMSNS = CommonNamespaces.DEEGREEWMS;
0135:
0136: private static final String XML_TEMPLATE = "WMSConfigurationTemplate.xml";
0137:
0138: private static final String XSLT_TEMPLATE_NAME = "WMSConfigurationTransform.xsl";
0139:
0140: private static XSLTDocument XSLT_TEMPLATE;
0141:
0142: private static Map<URL, OGCCapabilities> capaCache = new HashMap<URL, OGCCapabilities>();
0143:
0144: private static final ILogger LOG = LoggerFactory
0145: .getLogger(WMSConfigurationDocument.class);
0146:
0147: private static final QualifiedName DEFAULT_GEO_PROP = new QualifiedName(
0148: "app", "GEOM", CommonNamespaces
0149: .buildNSURI("http://www.deegree.org/app"));
0150:
0151: static {
0152: XSLT_TEMPLATE = new XSLTDocument();
0153: try {
0154: XSLT_TEMPLATE.load(WMSConfigurationDocument.class
0155: .getResource(XSLT_TEMPLATE_NAME));
0156: } catch (Exception e) {
0157: BootLogger
0158: .logError(
0159: "Error loading XSLT sheet in WMSConfigurationDocument.",
0160: e);
0161: }
0162: }
0163:
0164: /**
0165: *
0166: */
0167: public static void resetCapabilitiesCache() {
0168: capaCache.clear();
0169: }
0170:
0171: /**
0172: * Creates a skeleton capabilities document that contains the mandatory elements only.
0173: *
0174: * @throws IOException
0175: * @throws SAXException
0176: */
0177: @Override
0178: public void createEmptyDocument() throws IOException, SAXException {
0179: URL url = WMSConfigurationDocument.class
0180: .getResource(XML_TEMPLATE);
0181: if (url == null) {
0182: throw new IOException("The resource '" + XML_TEMPLATE
0183: + " could not be found.");
0184: }
0185: load(url);
0186: }
0187:
0188: /**
0189: * Creates a class representation of the document.
0190: *
0191: * @return class representation of the configuration document
0192: * @throws InvalidConfigurationException
0193: */
0194: public WMSConfiguration parseConfiguration()
0195: throws InvalidConfigurationException {
0196:
0197: try {
0198: // transform document to fill missing elements and attributes with
0199: // default values
0200: XMLFragment frag = XSLT_TEMPLATE.transform(this );
0201: this .setRootElement(frag.getRootElement());
0202: } catch (TransformerException e) {
0203: String msg = Messages
0204: .getMessage("WMS_CONFIGURATION_TRANSFORM");
0205: LOG.logError(msg, e);
0206: throw new InvalidConfigurationException(msg, e);
0207: }
0208:
0209: ServiceIdentification serviceIdentification = null;
0210: ServiceProvider serviceProvider = null;
0211: OperationsMetadata metadata = null;
0212: Layer layer = null;
0213: UserDefinedSymbolization uds = null;
0214: WMSDeegreeParams params = null;
0215: Element root = getRootElement();
0216: String version = root.getAttribute("version");
0217: String updateSeq = root.getAttribute("updateSequence");
0218: List<String> exceptions;
0219:
0220: try {
0221: Node node = XMLTools.getRequiredNode(getRootElement(),
0222: "./deegreewms:DeegreeParam", nsContext);
0223: params = parseDeegreeParams(node);
0224:
0225: serviceIdentification = parseServiceIdentification();
0226: serviceProvider = parseServiceProvider();
0227: metadata = parseOperationsMetadata();
0228:
0229: Element exceptionElement = XMLTools
0230: .getRequiredElement(getRootElement(),
0231: "Capability/Exception", nsContext);
0232: exceptions = parseExceptionFormats(exceptionElement);
0233:
0234: uds = parseUserDefinedSymbolization();
0235: Element layerElem = (Element) XMLTools.getRequiredNode(
0236: getRootElement(), "./Capability/Layer", nsContext);
0237: layer = parseLayers(layerElem, null, null);
0238:
0239: } catch (XMLParsingException e) {
0240: e.printStackTrace();
0241: throw new InvalidConfigurationException(e.getMessage()
0242: + StringTools.stackTraceToString(e));
0243: } catch (MalformedURLException e) {
0244: throw new InvalidConfigurationException(e.getMessage()
0245: + " - " + StringTools.stackTraceToString(e));
0246: } catch (UnknownCRSException e) {
0247: throw new InvalidConfigurationException(e.getMessage()
0248: + " - " + StringTools.stackTraceToString(e));
0249: }
0250:
0251: WMSConfiguration wmsConfiguration = new WMSConfiguration(
0252: version, updateSeq, serviceIdentification,
0253: serviceProvider, uds, metadata, layer, params,
0254: getSystemId(), exceptions);
0255:
0256: return wmsConfiguration;
0257: }
0258:
0259: /**
0260: * Creates a class representation of the <code>deegreeParams</code>- section.
0261: *
0262: * @param root
0263: *
0264: * @return the deegree params
0265: * @throws XMLParsingException
0266: * @throws MalformedURLException
0267: */
0268: public WMSDeegreeParams parseDeegreeParams(Node root)
0269: throws XMLParsingException, MalformedURLException {
0270:
0271: Element elem = (Element) XMLTools.getRequiredNode(root,
0272: "./deegreewms:DefaultOnlineResource", nsContext);
0273: OnlineResource ol = parseOnLineResource(elem);
0274: int cache = XMLTools.getNodeAsInt(root,
0275: "./deegreewms:CacheSize", nsContext, 100);
0276: int maxLifeTime = XMLTools.getNodeAsInt(root,
0277: "./deegreewms:MaxLifeTime", nsContext, 3600);
0278: int reqTimeLimit = XMLTools.getNodeAsInt(root,
0279: "./deegreewms:RequestTimeLimit", nsContext, 15);
0280: reqTimeLimit *= 1000;
0281: double mapQuality = XMLTools.getNodeAsDouble(root,
0282: "./deegreewms:MapQuality", nsContext, 0.95);
0283: int maxMapWidth = XMLTools.getNodeAsInt(root,
0284: "./deegreewms:MaxMapWidth", nsContext, 1000);
0285: int maxMapHeight = XMLTools.getNodeAsInt(root,
0286: "./deegreewms:MaxMapHeight", nsContext, 1000);
0287: int featureInfoRadius = XMLTools.getNodeAsInt(root,
0288: "./deegreewms:FeatureInfoRadius", nsContext, 5);
0289: String copyright = XMLTools.getNodeAsString(root,
0290: "./deegreewms:Copyright", nsContext, "");
0291:
0292: URL dtdLocation = null;
0293: if (XMLTools.getNode(root, "deegreewms:DTDLocation", nsContext) != null) {
0294: elem = (Element) XMLTools
0295: .getRequiredNode(
0296: root,
0297: "./deegreewms:DTDLocation/deegreewms:OnlineResource",
0298: nsContext);
0299: OnlineResource olr = parseOnLineResource(elem);
0300: dtdLocation = olr.getLinkage().getHref();
0301: } else {
0302: dtdLocation = new URL(
0303: "http://schemas.opengis.net/wms/1.1.1/WMS_MS_Capabilities.dtd");
0304: }
0305:
0306: URL featureSchemaLocation = null;
0307: String featureSchemaNamespace = null;
0308: if (XMLTools.getNode(root, "deegreewms:FeatureInfoSchema",
0309: nsContext) != null) {
0310: featureSchemaNamespace = XMLTools
0311: .getRequiredNodeAsString(
0312: root,
0313: "deegreewms:FeatureInfoSchema/deegreewms:Namespace",
0314: nsContext);
0315: elem = (Element) XMLTools
0316: .getRequiredNode(
0317: root,
0318: "deegreewms:FeatureInfoSchema/deegreewms:OnlineResource",
0319: nsContext);
0320: OnlineResource link = parseOnLineResource(elem);
0321: featureSchemaLocation = link.getLinkage().getHref();
0322: }
0323:
0324: boolean antiAliased = XMLTools.getNodeAsBoolean(root,
0325: "./deegreewms:AntiAliased", nsContext, true);
0326:
0327: Proxy proxy = parseProxy(root);
0328:
0329: List<String> supportedVersions = parseSupportedVersions(root);
0330:
0331: WMSDeegreeParams deegreeParams = new WMSDeegreeParams(cache,
0332: maxLifeTime, reqTimeLimit, (float) mapQuality, ol,
0333: maxMapWidth, maxMapHeight, antiAliased,
0334: featureInfoRadius, copyright, null, dtdLocation, proxy,
0335: supportedVersions, featureSchemaLocation,
0336: featureSchemaNamespace);
0337:
0338: return deegreeParams;
0339: }
0340:
0341: // returns the list of supported versions
0342: private List<String> parseSupportedVersions(Node root)
0343: throws XMLParsingException {
0344:
0345: String[] versions = XMLTools.getNodesAsStrings(root,
0346: "./deegreewms:SupportedVersion", nsContext);
0347:
0348: if (versions != null)
0349: return Arrays.asList(versions);
0350:
0351: return new ArrayList<String>();
0352:
0353: }
0354:
0355: /**
0356: * @param root
0357: * @return the proxy
0358: * @throws XMLParsingException
0359: */
0360: private Proxy parseProxy(Node root) throws XMLParsingException {
0361:
0362: Proxy proxy = null;
0363: Node pro = XMLTools.getNode(root, "./deegreewms:Proxy",
0364: nsContext);
0365: if (pro != null) {
0366: String proxyHost = XMLTools.getRequiredNodeAsString(pro,
0367: "./@proxyHost", nsContext);
0368: String proxyPort = XMLTools.getRequiredNodeAsString(pro,
0369: "./@proxyPort", nsContext);
0370: proxy = new Proxy(proxyHost, proxyPort);
0371: }
0372:
0373: return proxy;
0374: }
0375:
0376: /**
0377: * returns the layers offered by the WMS
0378: *
0379: * @throws XMLParsingException
0380: * @throws UnknownCRSException
0381: */
0382: @Override
0383: protected Layer parseLayers(Element layerElem, Layer parent,
0384: ScaleHint scaleHint) throws XMLParsingException,
0385: UnknownCRSException {
0386:
0387: boolean queryable = XMLTools.getNodeAsBoolean(layerElem,
0388: "./@queryable", nsContext, false);
0389: int cascaded = XMLTools.getNodeAsInt(layerElem, "./@cascaded",
0390: nsContext, 0);
0391: boolean opaque = XMLTools.getNodeAsBoolean(layerElem,
0392: "./@opaque", nsContext, false);
0393: boolean noSubsets = XMLTools.getNodeAsBoolean(layerElem,
0394: "./@noSubsets", nsContext, false);
0395: int fixedWidth = XMLTools.getNodeAsInt(layerElem,
0396: "./@fixedWidth", nsContext, 0);
0397: int fixedHeight = XMLTools.getNodeAsInt(layerElem,
0398: "./@fixedHeight", nsContext, 0);
0399: String name = XMLTools.getNodeAsString(layerElem, "./Name",
0400: nsContext, null);
0401: String title = XMLTools.getRequiredNodeAsString(layerElem,
0402: "./Title", nsContext);
0403: String layerAbstract = XMLTools.getNodeAsString(layerElem,
0404: "./Abstract", nsContext, null);
0405: String[] keywords = XMLTools.getNodesAsStrings(layerElem,
0406: "./KeywordList/Keyword", nsContext);
0407: String[] srs = XMLTools.getNodesAsStrings(layerElem, "./SRS",
0408: nsContext);
0409:
0410: List<Element> nl = XMLTools.getElements(layerElem,
0411: "./BoundingBox", nsContext);
0412: // TODO
0413: // substitue with Envelope
0414: LayerBoundingBox[] bboxes = null;
0415: if (nl.size() == 0 && parent != null) {
0416: // inherit BoundingBoxes from parent layer
0417: bboxes = parent.getBoundingBoxes();
0418: } else {
0419: bboxes = parseLayerBoundingBoxes(nl);
0420: }
0421:
0422: Element llBox = (Element) XMLTools.getNode(layerElem,
0423: "./LatLonBoundingBox", nsContext);
0424: Envelope llBoundingBox = null;
0425: if (llBox == null && parent != null) {
0426: // inherit LatLonBoundingBox parent layer
0427: llBoundingBox = parent.getLatLonBoundingBox();
0428: } else {
0429: llBoundingBox = parseLatLonBoundingBox(llBox);
0430: }
0431:
0432: Dimension[] dimensions = parseDimensions(layerElem);
0433: Extent[] extents = parseExtents(layerElem);
0434:
0435: Attribution attribution = parseAttribution(layerElem);
0436:
0437: AuthorityURL[] authorityURLs = parseAuthorityURLs(layerElem);
0438:
0439: MetadataURL[] metadataURLs = parseMetadataURLs(layerElem);
0440:
0441: DataURL[] dataURLs = parseDataURL(layerElem);
0442:
0443: Identifier[] identifiers = parseIdentifiers(layerElem);
0444:
0445: FeatureListURL[] featureListURLs = parseFeatureListURL(layerElem);
0446:
0447: Style[] styles = parseStyles(layerElem);
0448:
0449: scaleHint = parseScaleHint(layerElem, scaleHint);
0450:
0451: AbstractDataSource[] ds = parseDataSources(layerElem, name,
0452: scaleHint);
0453:
0454: Layer layer = new Layer(queryable, cascaded, opaque, noSubsets,
0455: fixedWidth, fixedHeight, name, title, layerAbstract,
0456: llBoundingBox, attribution, scaleHint, keywords, srs,
0457: bboxes, dimensions, extents, authorityURLs,
0458: identifiers, metadataURLs, dataURLs, featureListURLs,
0459: styles, null, ds, parent);
0460:
0461: // get Child layers
0462: nl = XMLTools.getElements(layerElem, "./Layer", nsContext);
0463: Layer[] layers = new Layer[nl.size()];
0464: for (int i = 0; i < layers.length; i++) {
0465: layers[i] = parseLayers(nl.get(i), layer, scaleHint);
0466: }
0467:
0468: // set child layers
0469: layer.setLayer(layers);
0470:
0471: return layer;
0472: }
0473:
0474: /**
0475: *
0476: * @param layerElem
0477: * @return the data sources
0478: * @throws XMLParsingException
0479: */
0480: protected AbstractDataSource[] parseDataSources(Element layerElem,
0481: String layerName, ScaleHint scaleHint)
0482: throws XMLParsingException {
0483:
0484: List<Node> nl = XMLTools.getNodes(layerElem,
0485: "./deegreewms:DataSource", nsContext);
0486:
0487: AbstractDataSource[] ds = new AbstractDataSource[nl.size()];
0488: for (int i = 0; i < ds.length; i++) {
0489: boolean failOnEx = XMLTools.getNodeAsBoolean(nl.get(i),
0490: "./@failOnException", nsContext, true);
0491: boolean queryable = XMLTools.getNodeAsBoolean(nl.get(i),
0492: "./@queryable", nsContext, false);
0493: QualifiedName name = XMLTools.getNodeAsQualifiedName(nl
0494: .get(i), "./deegreewms:Name/text()", nsContext,
0495: new QualifiedName(layerName));
0496: String stype = XMLTools.getRequiredNodeAsString(nl.get(i),
0497: "./deegreewms:Type", nsContext);
0498:
0499: int reqTimeLimit = XMLTools.getNodeAsInt(nl.get(i),
0500: "./deegreewms:RequestTimeLimit/text()", nsContext,
0501: 30);
0502:
0503: scaleHint = parseDSScaleHint((Element) nl.get(i), scaleHint);
0504:
0505: String s = "./deegreewms:OWSCapabilities/deegreewms:OnlineResource";
0506: Node node = XMLTools.getRequiredNode(nl.get(i), s,
0507: nsContext);
0508:
0509: URL url = parseOnLineResource((Element) node).getLinkage()
0510: .getHref();
0511:
0512: Geometry validArea = parseValidArea(nl.get(i));
0513:
0514: try {
0515: if ("LOCALWFS".equals(stype)) {
0516: ds[i] = createLocalWFSDataSource(nl.get(i),
0517: failOnEx, queryable, name, url, scaleHint,
0518: validArea, reqTimeLimit);
0519: } else if ("LOCALWCS".equals(stype)) {
0520: ds[i] = createLocalWCSDataSource(nl.get(i),
0521: failOnEx, queryable, name, url, scaleHint,
0522: validArea, reqTimeLimit);
0523: } else if ("REMOTEWFS".equals(stype)) {
0524: ds[i] = createRemoteWFSDataSource(nl.get(i),
0525: failOnEx, queryable, name, url, scaleHint,
0526: validArea, reqTimeLimit);
0527: } else if ("REMOTEWCS".equals(stype)) {
0528: // int type = AbstractDataSource.REMOTEWCS;
0529: // GetCoverage getCoverage =
0530: parseWCSFilterCondition(nl.get(i));
0531: // Color[] colors =
0532: parseTransparentColors(nl.get(i));
0533: // TODO
0534: throw new XMLParsingException(
0535: "REMOTEWCS is not supported yet!");
0536: } else if ("REMOTEWMS".equals(stype)) {
0537: ds[i] = createRemoteWMSDataSource(nl.get(i),
0538: failOnEx, queryable, name, url, scaleHint,
0539: validArea, reqTimeLimit);
0540: } else {
0541: throw new XMLParsingException(
0542: "invalid DataSource type: "
0543: + stype
0544: + " defined "
0545: + "in deegree WMS configuration for DataSource: "
0546: + name);
0547: }
0548: } catch (Exception e) {
0549: LOG.logError(e.getMessage(), e);
0550: throw new XMLParsingException(
0551: "could not create service instance for WMS "
0552: + "datasource: " + name, e);
0553: }
0554: }
0555:
0556: return ds;
0557: }
0558:
0559: /**
0560: * parses the ScaleHint for a Datasource
0561: *
0562: * @param layerElem
0563: * @param scaleHint
0564: * @return the scale hint for the datasource
0565: * @throws XMLParsingException
0566: */
0567: protected ScaleHint parseDSScaleHint(Element layerElem,
0568: ScaleHint scaleHint) throws XMLParsingException {
0569:
0570: Node scNode = XMLTools.getNode(layerElem,
0571: "./deegreewms:ScaleHint", nsContext);
0572: if (scNode != null) {
0573: double mn = XMLTools.getNodeAsDouble(scNode, "./@min",
0574: nsContext, 0);
0575: double mx = XMLTools.getNodeAsDouble(scNode, "./@max",
0576: nsContext, Double.MAX_VALUE);
0577: scaleHint = new ScaleHint(mn, mx);
0578: }
0579:
0580: if (scaleHint == null) {
0581: // set default value to avoid NullPointerException
0582: // when accessing a layers scalehint
0583: scaleHint = new ScaleHint(0, Double.MAX_VALUE);
0584: }
0585:
0586: return scaleHint;
0587: }
0588:
0589: /**
0590: * returns the area a data source is valid. If the optional element <ValidArea>is not defined in
0591: * the configuration <code>null</code>.
0592: *
0593: * @param node
0594: * @return the geometry
0595: * @throws Exception
0596: */
0597: private Geometry parseValidArea(Node node)
0598: throws XMLParsingException {
0599:
0600: Geometry geom = null;
0601:
0602: List<Node> nl = XMLTools.getNodes(node,
0603: "./deegreewms:ValidArea/*", nsContext);
0604: if (node != null) {
0605:
0606: try {
0607: for (int i = 0; i < nl.size(); i++) {
0608:
0609: if (nl.get(0).getNamespaceURI().equals(
0610: GMLNS.toString())) {
0611:
0612: geom = GMLGeometryAdapter.wrap((Element) nl
0613: .get(0), null);
0614: break;
0615: }
0616: }
0617: } catch (GeometryException e) {
0618: e.printStackTrace();
0619: throw new XMLParsingException(
0620: "couldn't parse/create valid aera of a datasource",
0621: e);
0622: }
0623: }
0624:
0625: return geom;
0626: }
0627:
0628: /**
0629: * @param vendor
0630: * @return the parsed list
0631: * @throws XMLParsingException
0632: */
0633: static List<String> parsePassedParameters(Node vendor)
0634: throws XMLParsingException {
0635: List<String> passedParameters = new ArrayList<String>(10);
0636:
0637: if (vendor == null) {
0638: return passedParameters;
0639: }
0640:
0641: List<Node> nl = XMLTools
0642: .getNodes(
0643: vendor,
0644: "deegreewms:PassedVendorspecificParameter/deegreewms:Name",
0645: nsContext);
0646:
0647: for (Object obj : nl) {
0648: passedParameters.add(((Node) obj).getTextContent()
0649: .toUpperCase());
0650: }
0651:
0652: return passedParameters;
0653: }
0654:
0655: /**
0656: * @param vendor
0657: * @return the parsed map
0658: * @throws XMLParsingException
0659: */
0660: static Map<String, String> parseAddedParameters(Node vendor)
0661: throws XMLParsingException {
0662: Map<String, String> addedParameters = new HashMap<String, String>(
0663: 10);
0664:
0665: if (vendor == null) {
0666: return addedParameters;
0667: }
0668:
0669: List<Node> nl = XMLTools
0670: .getNodes(
0671: vendor,
0672: "deegreewms:AddedVendorspecificParameter/deegreewms:VendorspecificParameter",
0673: nsContext);
0674:
0675: for (Object obj : nl) {
0676: String pName = XMLTools.getRequiredNodeAsString((Node) obj,
0677: "deegreewms:Name", nsContext);
0678: String pValue = XMLTools.getRequiredNodeAsString(
0679: (Node) obj, "deegreewms:Value", nsContext);
0680:
0681: addedParameters.put(pName, pValue);
0682: }
0683: return addedParameters;
0684: }
0685:
0686: /**
0687: * @param node
0688: * @param failOnEx
0689: * @param queryable
0690: * @param name
0691: * @param geoProp
0692: * @param url
0693: * @param scaleHint
0694: * @throws Exception
0695: */
0696: private RemoteWMSDataSource createRemoteWMSDataSource(Node node,
0697: boolean failOnEx, boolean queryable, QualifiedName name,
0698: URL url, ScaleHint scaleHint, Geometry validArea,
0699: int reqTimeLimit) throws Exception {
0700: int type = AbstractDataSource.REMOTEWMS;
0701:
0702: String s = "./deegreewms:FeatureInfoTransformation/deegreewms:OnlineResource";
0703: Node fitNode = XMLTools.getNode(node, s, nsContext);
0704: URL fitURL = null;
0705: if (fitNode != null) {
0706: fitURL = parseOnLineResource((Element) fitNode)
0707: .getLinkage().getHref();
0708: }
0709:
0710: GetMap getMap = parseWMSFilterCondition(node);
0711: Color[] colors = parseTransparentColors(node);
0712: WMSCapabilities wCapa = null;
0713: if (capaCache.get(url) != null) {
0714: wCapa = (WMSCapabilities) capaCache.get(url);
0715: } else {
0716: WMSCapabilitiesDocument doc = WMSCapabilitiesDocumentFactory
0717: .getWMSCapabilitiesDocument(url);
0718: LOG.logDebug("Fetching remote WMS capabilities from URL "
0719: + url + " succeeded.");
0720: wCapa = (WMSCapabilities) doc.parseCapabilities();
0721: capaCache.put(url, wCapa);
0722: }
0723: OGCWebService ows = new RemoteWMService(wCapa);
0724:
0725: // parse added/passed parameter map/list
0726: Node vendor = XMLTools
0727: .getNode(
0728: node,
0729: "deegreewms:FilterCondition/deegreewms:VendorspecificParameterDefinition",
0730: nsContext);
0731:
0732: List<String> passedParameters = parsePassedParameters(vendor);
0733: Map<String, String> addedParameters = parseAddedParameters(vendor);
0734:
0735: return new RemoteWMSDataSource(queryable, failOnEx, name, type,
0736: ows, url, scaleHint, validArea, getMap, colors, fitURL,
0737: reqTimeLimit, passedParameters, addedParameters);
0738: }
0739:
0740: /**
0741: * @param node
0742: * @param failOnEx
0743: * @param queryable
0744: * @param name
0745: * @param geoProp
0746: * @param url
0747: * @param scaleHint
0748: * @throws Exception
0749: */
0750: private RemoteWFSDataSource createRemoteWFSDataSource(Node node,
0751: boolean failOnEx, boolean queryable, QualifiedName name,
0752: URL url, ScaleHint scaleHint, Geometry validArea,
0753: int reqTimeLimit) throws Exception {
0754: int type = AbstractDataSource.REMOTEWFS;
0755: String s = "./deegreewms:FeatureInfoTransformation/deegreewms:OnlineResource";
0756: Node fitNode = XMLTools.getNode(node, s, nsContext);
0757: URL fitURL = null;
0758: if (fitNode != null) {
0759: fitURL = parseOnLineResource((Element) fitNode)
0760: .getLinkage().getHref();
0761: }
0762: Query query = parseWFSFilterCondition(node);
0763:
0764: WFSCapabilities wfsCapa = null;
0765: if (capaCache.get(url) != null) {
0766: wfsCapa = (WFSCapabilities) capaCache.get(url);
0767: } else {
0768: WFSCapabilitiesDocument wfsDoc = new WFSCapabilitiesDocument();
0769: wfsDoc.load(url);
0770: wfsCapa = (WFSCapabilities) wfsDoc.parseCapabilities();
0771: capaCache.put(url, wfsCapa);
0772: }
0773: OGCWebService ows = new RemoteWFService(wfsCapa);
0774: // OGCWebService ows = null;
0775:
0776: Node geoPropNode = XMLTools.getNode(node,
0777: "deegreewms:GeometryProperty/text()", nsContext);
0778: QualifiedName geoProp = DEFAULT_GEO_PROP;
0779: if (geoPropNode != null) {
0780: geoProp = parseQualifiedName(geoPropNode);
0781: }
0782:
0783: return new RemoteWFSDataSource(queryable, failOnEx, name, type,
0784: geoProp, ows, url, scaleHint, validArea, query, fitURL,
0785: reqTimeLimit);
0786:
0787: }
0788:
0789: /**
0790: * @param node
0791: * @param failOnEx
0792: * @param queryable
0793: * @param name
0794: * @param geoProp
0795: * @param url
0796: * @param scaleHint
0797: * @throws Exception
0798: */
0799: private LocalWCSDataSource createLocalWCSDataSource(Node node,
0800: boolean failOnEx, boolean queryable, QualifiedName name,
0801: URL url, ScaleHint scaleHint, Geometry validArea,
0802: int reqTimeLimit) throws Exception {
0803: int type = AbstractDataSource.LOCALWCS;
0804: GetCoverage getCoverage = parseWCSFilterCondition(node);
0805: Color[] colors = parseTransparentColors(node);
0806: WCSConfiguration configuration = null;
0807: if (capaCache.get(url) != null) {
0808: configuration = (WCSConfiguration) capaCache.get(url);
0809: } else {
0810: configuration = WCSConfiguration.create(url);
0811: capaCache.put(url, configuration);
0812: }
0813:
0814: OGCWebService ows = new WCService(configuration);
0815:
0816: return new LocalWCSDataSource(queryable, failOnEx, name, type,
0817: ows, url, scaleHint, validArea, getCoverage, colors,
0818: reqTimeLimit);
0819: }
0820:
0821: /**
0822: * @param node
0823: * @param failOnEx
0824: * @param queryable
0825: * @param name
0826: * @param geoProp
0827: * @param url
0828: * @param scaleHint
0829: * @throws Exception
0830: */
0831: private LocalWFSDataSource createLocalWFSDataSource(Node node,
0832: boolean failOnEx, boolean queryable, QualifiedName name,
0833: URL url, ScaleHint scaleHint, Geometry validArea,
0834: int reqTimeLimit) throws Exception {
0835: int type = AbstractDataSource.LOCALWFS;
0836: String s = "./deegreewms:FeatureInfoTransformation/deegreewms:OnlineResource";
0837: Node fitNode = XMLTools.getNode(node, s, nsContext);
0838: URL fitURL = null;
0839: if (fitNode != null) {
0840: fitURL = parseOnLineResource((Element) fitNode)
0841: .getLinkage().getHref();
0842: }
0843: Query query = parseWFSFilterCondition(node);
0844: WFSConfiguration wfsCapa = null;
0845: if (capaCache.get(url) != null) {
0846: wfsCapa = (WFSConfiguration) capaCache.get(url);
0847: } else {
0848: WFSConfigurationDocument wfsDoc = new WFSConfigurationDocument();
0849: wfsDoc.load(url);
0850: wfsCapa = wfsDoc.getConfiguration();
0851: // wfsCapa = new WFSCapabilitiesDocument( url ).createCapabilities();
0852: capaCache.put(url, wfsCapa);
0853: }
0854: // OGCWebService ows = WFServiceFactory.getUncachedService( wfsCapa );
0855: OGCWebService ows = WFServiceFactory.createInstance(wfsCapa);
0856:
0857: Node geoPropNode = XMLTools.getNode(node,
0858: "deegreewms:GeometryProperty/text()", nsContext);
0859: QualifiedName geoProp = DEFAULT_GEO_PROP;
0860: if (geoPropNode != null) {
0861: geoProp = parseQualifiedName(geoPropNode);
0862: }
0863:
0864: LOG.logDebug("geometry property", geoProp);
0865:
0866: return new LocalWFSDataSource(queryable, failOnEx, name, type,
0867: geoProp, ows, url, scaleHint, validArea, query, fitURL,
0868: reqTimeLimit);
0869: }
0870:
0871: /**
0872: * @param nl
0873: * @param type
0874: * @throws XMLParsingException
0875: */
0876: private Color[] parseTransparentColors(Node node)
0877: throws XMLParsingException {
0878:
0879: String s = "./deegreewms:TransparentColors/deegreewms:Color";
0880: List<Node> clnl = XMLTools.getNodes(node, s, nsContext);
0881: Color[] colors = new Color[clnl.size()];
0882: for (int j = 0; j < colors.length; j++) {
0883: colors[j] = Color.decode(XMLTools.getStringValue(clnl
0884: .get(j)));
0885: }
0886:
0887: return colors;
0888: }
0889:
0890: /**
0891: *
0892: * @param node
0893: * @return the query
0894: * @throws XMLParsingException
0895: */
0896: private Query parseWFSFilterCondition(Node node)
0897: throws XMLParsingException {
0898:
0899: Query o = null;
0900:
0901: Node queryNode = XMLTools.getNode(node,
0902: "./deegreewms:FilterCondition/wfs:Query", nsContext);
0903: if (queryNode != null) {
0904: try {
0905: o = Query.create((Element) queryNode);
0906: } catch (Exception e) {
0907: throw new XMLParsingException(StringTools
0908: .stackTraceToString(e));
0909: }
0910: }
0911:
0912: return o;
0913: }
0914:
0915: /**
0916: *
0917: * @param node
0918: * @return the request
0919: * @throws XMLParsingException
0920: */
0921: private GetCoverage parseWCSFilterCondition(Node node)
0922: throws XMLParsingException {
0923:
0924: GetCoverage o = null;
0925:
0926: String id = "" + IDGenerator.getInstance().generateUniqueID();
0927:
0928: StringBuffer sd = new StringBuffer(1000);
0929: sd.append("version=1.0.0&Coverage=%default%&");
0930: sd.append("CRS=EPSG:4326&BBOX=0,0,1,1&Width=1");
0931: sd.append("&Height=1&Format=%default%&");
0932: String s = XMLTools.getNodeAsString(node,
0933: "./deegreewms:FilterCondition/deegreewms:WCSRequest",
0934: nsContext, "");
0935: sd.append(s);
0936: try {
0937: o = GetCoverage.create(id, sd.toString());
0938: } catch (Exception e) {
0939: throw new XMLParsingException(
0940: "could not create GetCoverage from layer FilterCondition",
0941: e);
0942: }
0943:
0944: return o;
0945: }
0946:
0947: /**
0948: *
0949: * @param node
0950: * @return the request
0951: * @throws XMLParsingException
0952: */
0953: private GetMap parseWMSFilterCondition(Node node)
0954: throws XMLParsingException {
0955:
0956: GetMap o = null;
0957:
0958: String id = "" + IDGenerator.getInstance().generateUniqueID();
0959:
0960: StringBuffer sd = new StringBuffer(1000);
0961: sd.append("REQUEST=GetMap&LAYERS=%default%&");
0962: sd.append("STYLES=&SRS=EPSG:4326&BBOX=0,0,1,1&WIDTH=1&");
0963: sd.append("HEIGHT=1&FORMAT=%default%");
0964: Map<String, String> map1 = KVP2Map.toMap(sd.toString());
0965: String s = XMLTools.getRequiredNodeAsString(node,
0966: "./deegreewms:FilterCondition/deegreewms:WMSRequest",
0967: nsContext);
0968: Map<String, String> map2 = KVP2Map.toMap(s);
0969: if (map2.get("VERSION") == null && map2.get("WMTVER") == null) {
0970: map2.put("VERSION", "1.1.1");
0971: }
0972: // if no service is set use WMS as default
0973: if (map2.get("SERVICE") == null) {
0974: map2.put("SERVICE", "WMS");
0975: }
0976: map1.putAll(map2);
0977: try {
0978: map1.put("ID", id);
0979: o = GetMap.create(map1);
0980: } catch (Exception e) {
0981: throw new XMLParsingException(
0982: "could not create GetMap from layer FilterCondition",
0983: e);
0984: }
0985:
0986: return o;
0987: }
0988:
0989: /**
0990: *
0991: * @param layerElem
0992: * @throws XMLParsingException
0993: */
0994: @Override
0995: protected Style[] parseStyles(Element layerElem)
0996: throws XMLParsingException {
0997:
0998: List<Node> nl = XMLTools.getNodes(layerElem, "./Style",
0999: nsContext);
1000: Style[] styles = new Style[nl.size()];
1001: for (int i = 0; i < styles.length; i++) {
1002: String name = XMLTools.getRequiredNodeAsString(nl.get(i),
1003: "./Name", nsContext);
1004: String title = XMLTools.getNodeAsString(nl.get(i),
1005: "./Title", nsContext, null);
1006: String styleAbstract = XMLTools.getNodeAsString(nl.get(i),
1007: "./Abstract", nsContext, null);
1008: LegendURL[] legendURLs = parseLegendURL(nl.get(i));
1009: StyleURL styleURL = parseStyleURL(nl.get(i));
1010: StyleSheetURL styleSheetURL = parseStyleSheetURL(nl.get(i));
1011: String styleResource = XMLTools
1012: .getNodeAsString(nl.get(i),
1013: "deegreewms:StyleResource", nsContext,
1014: "styles.xml");
1015: URL sr = null;
1016: try {
1017: sr = resolve(styleResource);
1018: } catch (MalformedURLException e) {
1019: throw new XMLParsingException(
1020: "could not parse style resource of style: "
1021: + name, e);
1022: }
1023:
1024: String layerName = XMLTools.getRequiredNodeAsString(
1025: layerElem, "Name", nsContext);
1026: if (name == null || name.length() == 0) {
1027: name = "default:" + layerName;
1028: }
1029: if (name.equals("default")) {
1030: name += ":" + layerName;
1031: }
1032: if (name.equals("default:")) {
1033: name += layerName;
1034: }
1035:
1036: styles[i] = new Style(name, title, styleAbstract,
1037: legendURLs, styleSheetURL, styleURL, sr);
1038: }
1039:
1040: return styles;
1041: }
1042:
1043: }
|