0001: //$HeadURL: https://svn.wald.intevation.org/svn/deegree/base/trunk/src/org/deegree/ogcwebservices/wmps/configuration/WMPSConfigurationDocument.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.wmps.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.HashMap;
0052: import java.util.List;
0053: import java.util.Map;
0054:
0055: import javax.xml.transform.TransformerException;
0056:
0057: import org.deegree.datatypes.QualifiedName;
0058: import org.deegree.enterprise.Proxy;
0059: import org.deegree.framework.log.ILogger;
0060: import org.deegree.framework.log.LoggerFactory;
0061: import org.deegree.framework.util.BootLogger;
0062: import org.deegree.framework.util.IDGenerator;
0063: import org.deegree.framework.util.KVP2Map;
0064: import org.deegree.framework.util.StringTools;
0065: import org.deegree.framework.xml.InvalidConfigurationException;
0066: import org.deegree.framework.xml.XMLFragment;
0067: import org.deegree.framework.xml.XMLParsingException;
0068: import org.deegree.framework.xml.XMLTools;
0069: import org.deegree.framework.xml.XSLTDocument;
0070: import org.deegree.model.crs.UnknownCRSException;
0071: import org.deegree.model.metadata.iso19115.OnlineResource;
0072: import org.deegree.model.spatialschema.Envelope;
0073: import org.deegree.model.spatialschema.GMLGeometryAdapter;
0074: import org.deegree.model.spatialschema.Geometry;
0075: import org.deegree.model.spatialschema.GeometryException;
0076: import org.deegree.ogcbase.CommonNamespaces;
0077: import org.deegree.ogcwebservices.OGCWebService;
0078: import org.deegree.ogcwebservices.getcapabilities.MetadataURL;
0079: import org.deegree.ogcwebservices.getcapabilities.OperationsMetadata;
0080: import org.deegree.ogcwebservices.getcapabilities.ServiceIdentification;
0081: import org.deegree.ogcwebservices.getcapabilities.ServiceProvider;
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.WFServiceFactory;
0086: import org.deegree.ogcwebservices.wfs.capabilities.WFSCapabilities;
0087: import org.deegree.ogcwebservices.wfs.capabilities.WFSCapabilitiesDocument;
0088: import org.deegree.ogcwebservices.wfs.configuration.WFSConfiguration;
0089: import org.deegree.ogcwebservices.wfs.configuration.WFSConfigurationDocument;
0090: import org.deegree.ogcwebservices.wfs.operation.Query;
0091: import org.deegree.ogcwebservices.wmps.capabilities.WMPSCapabilitiesDocument;
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.GazetteerParam;
0100: import org.deegree.ogcwebservices.wms.capabilities.Identifier;
0101: import org.deegree.ogcwebservices.wms.capabilities.Layer;
0102: import org.deegree.ogcwebservices.wms.capabilities.LayerBoundingBox;
0103: import org.deegree.ogcwebservices.wms.capabilities.LegendURL;
0104: import org.deegree.ogcwebservices.wms.capabilities.ScaleHint;
0105: import org.deegree.ogcwebservices.wms.capabilities.Style;
0106: import org.deegree.ogcwebservices.wms.capabilities.StyleSheetURL;
0107: import org.deegree.ogcwebservices.wms.capabilities.StyleURL;
0108: import org.deegree.ogcwebservices.wms.capabilities.UserDefinedSymbolization;
0109: import org.deegree.ogcwebservices.wms.capabilities.WMSCapabilities;
0110: import org.deegree.ogcwebservices.wms.capabilities.WMSCapabilitiesDocument;
0111: import org.deegree.ogcwebservices.wms.capabilities.WMSCapabilitiesDocumentFactory;
0112: import org.deegree.ogcwebservices.wms.configuration.AbstractDataSource;
0113: import org.deegree.ogcwebservices.wms.configuration.LocalWCSDataSource;
0114: import org.deegree.ogcwebservices.wms.configuration.LocalWFSDataSource;
0115: import org.deegree.ogcwebservices.wms.configuration.RemoteWFSDataSource;
0116: import org.deegree.ogcwebservices.wms.configuration.RemoteWMSDataSource;
0117: import org.deegree.ogcwebservices.wms.operation.GetMap;
0118: import org.w3c.dom.Element;
0119: import org.w3c.dom.Node;
0120: import org.xml.sax.SAXException;
0121:
0122: /**
0123: * Represents an XML configuration document for a deegree WMPS 1.0 instance, i.e. it consists of all
0124: * sections common to an OGC WMS 1.1.1 capabilities document plus a deegree specific section named
0125: * <code>deegreeParams</code> and... TODO
0126: *
0127: * @author <a href="mailto:deshmukh@lat-lon.de">Anup Deshmukh</a>
0128: * @author last edited by: $Author: apoth $
0129: *
0130: * @version 2.0, $Revision: 9345 $, $Date: 2007-12-27 08:22:25 -0800 (Thu, 27 Dec 2007) $
0131: */
0132: public class WMPSConfigurationDocument extends WMPSCapabilitiesDocument {
0133:
0134: private static final long serialVersionUID = -7940857863171829848L;
0135:
0136: private static final ILogger LOG = LoggerFactory
0137: .getLogger(WMPSConfigurationDocument.class);
0138:
0139: protected static final URI DEEGREEWPSNS = CommonNamespaces.DEEGREEWMPS;
0140:
0141: private static final String XML_TEMPLATE = "WMPSConfigurationTemplate.xml";
0142:
0143: private static final String XSLT_TEMPLATE_NAME = "WMPSConfigurationTransform.xsl";
0144:
0145: private static XSLTDocument XSLT_TEMPLATE;
0146:
0147: private static Map<URL, Object> capaCache = new HashMap<URL, Object>();
0148:
0149: static {
0150: XSLT_TEMPLATE = new XSLTDocument();
0151: try {
0152: XSLT_TEMPLATE.load(WMPSConfigurationDocument.class
0153: .getResource(XSLT_TEMPLATE_NAME));
0154: } catch (Exception e) {
0155: BootLogger
0156: .logError(
0157: "Error loading XSLT sheet in WMPSConfigurationDocument.",
0158: e);
0159: }
0160: }
0161:
0162: /**
0163: *
0164: */
0165: public static void resetCapabilitiesCache() {
0166: capaCache.clear();
0167: }
0168:
0169: /**
0170: * Creates a skeleton capabilities document that contains the mandatory elements only.
0171: *
0172: * @throws IOException
0173: * @throws SAXException
0174: */
0175: @Override
0176: public void createEmptyDocument() throws IOException, SAXException {
0177: URL url = WMPSConfigurationDocument.class
0178: .getResource(XML_TEMPLATE);
0179: if (url == null) {
0180: throw new IOException("The resource '" + XML_TEMPLATE
0181: + " could not be found.");
0182: }
0183: load(url);
0184: }
0185:
0186: /**
0187: * Creates a class representation of the document.
0188: *
0189: * @return class representation of the configuration document
0190: * @throws InvalidConfigurationException
0191: */
0192: public WMPSConfiguration parseConfiguration()
0193: throws InvalidConfigurationException {
0194:
0195: try {
0196: // transform document to fill missing elements and attributes with default values
0197: XMLFragment frag = XSLT_TEMPLATE.transform(this );
0198: this .setRootElement(frag.getRootElement());
0199: } catch (TransformerException e) {
0200: String msg = "Error transforming WMPS configuration document (in order to fill "
0201: + "in default value). " + e.getMessage();
0202: LOG.logError(msg, e);
0203: throw new InvalidConfigurationException(msg, e);
0204: }
0205:
0206: ServiceIdentification serviceIdentification = null;
0207: ServiceProvider serviceProvider = null;
0208: UserDefinedSymbolization uds = null;
0209: OperationsMetadata metadata = null;
0210: Layer layer = null;
0211: WMPSDeegreeParams params = null;
0212: String version = parseVersion();
0213: try {
0214: Node node = XMLTools.getRequiredNode(getRootElement(),
0215: "deegreewmps:DeegreeParam", nsContext);
0216: params = parseDeegreeParams(node);
0217: serviceIdentification = parseServiceIdentification();
0218: serviceProvider = parseServiceProvider();
0219: uds = parseUserDefinedSymbolization();
0220: metadata = parseOperationsMetadata();
0221: Element layerElem = (Element) XMLTools.getRequiredNode(
0222: getRootElement(), "./Capability/Layer", nsContext);
0223: layer = parseLayers(layerElem, null);
0224: } catch (XMLParsingException e) {
0225: e.printStackTrace();
0226: throw new InvalidConfigurationException(e.getMessage()
0227: + StringTools.stackTraceToString(e));
0228: } catch (MalformedURLException e) {
0229: throw new InvalidConfigurationException(e.getMessage()
0230: + " - " + StringTools.stackTraceToString(e));
0231: } catch (UnknownCRSException e) {
0232: throw new InvalidConfigurationException(getClass()
0233: .getName(), e.getMessage());
0234: }
0235: WMPSConfiguration wmpsConfiguration = new WMPSConfiguration(
0236: version, serviceIdentification, serviceProvider, uds,
0237: metadata, layer, params, getSystemId());
0238:
0239: return wmpsConfiguration;
0240: }
0241:
0242: /**
0243: * Creates a class representation of the <code>deegreeParams</code>- section.
0244: *
0245: * @param root
0246: * @return WMPSDeegreeParams
0247: * @throws XMLParsingException
0248: * @throws MalformedURLException
0249: */
0250: public WMPSDeegreeParams parseDeegreeParams(Node root)
0251: throws XMLParsingException, MalformedURLException {
0252:
0253: String xPath = "./deegreewmps:DefaultOnlineResource";
0254: Element elem = (Element) XMLTools.getRequiredNode(root, xPath,
0255: nsContext);
0256:
0257: OnlineResource ol = parseOnLineResource(elem);
0258: xPath = "./deegreewmps:CacheSize";
0259: int cache = XMLTools.getNodeAsInt(root, xPath, nsContext, 100);
0260: xPath = "./deegreewmps:MaxLifeTime";
0261: int maxLifeTime = XMLTools.getNodeAsInt(root, xPath, nsContext,
0262: 3600);
0263: xPath = "./deegreewmps:RequestTimeLimit";
0264: int reqTimeLimit = XMLTools.getNodeAsInt(root, xPath,
0265: nsContext, 15);
0266: reqTimeLimit *= 1000;
0267: xPath = "./deegreewmps:MapQuality";
0268: double mapQuality = XMLTools.getNodeAsDouble(root, xPath,
0269: nsContext, 0.95);
0270: xPath = "./deegreewmps:MaxMapWidth";
0271: int maxMapWidth = XMLTools.getNodeAsInt(root, xPath, nsContext,
0272: 1000);
0273: xPath = "./deegreewmps:MaxMapHeight";
0274: int maxMapHeight = XMLTools.getNodeAsInt(root, xPath,
0275: nsContext, 1000);
0276: xPath = "./deegreewmps:FeatureInfoRadius";
0277: int featureInfoRadius = XMLTools.getNodeAsInt(root, xPath,
0278: nsContext, 5);
0279: xPath = "./deegreewmps:Copyright";
0280: String copyright = XMLTools.getNodeAsString(root, xPath,
0281: nsContext, "");
0282: URL dtdLocation = null;
0283: xPath = "deegreewmps:DTDLocation";
0284: if (XMLTools.getNode(root, xPath, nsContext) != null) {
0285: xPath = "./deegreewmps:DTDLocation/deegreewmps:OnlineResource";
0286: elem = (Element) XMLTools.getRequiredNode(root, xPath,
0287: nsContext);
0288: OnlineResource olr = parseOnLineResource(elem);
0289: dtdLocation = olr.getLinkage().getHref();
0290: } else {
0291: dtdLocation = new URL(
0292: "http://schemas.opengis.net/wms/1.1.1/WMS_MS_Capabilities.dtd");
0293: }
0294: xPath = "./deegreewmps:AntiAliased";
0295: boolean antiAliased = XMLTools.getNodeAsBoolean(root, xPath,
0296: nsContext, true);
0297: xPath = "./deegreewmps:GazetteerParameter";
0298: elem = (Element) XMLTools.getNode(root, xPath, nsContext);
0299: GazetteerParam gazetteer = null;
0300: if (elem != null) {
0301: gazetteer = parseGazetteerParameter(elem);
0302: }
0303:
0304: Proxy proxy = parseProxy(root);
0305:
0306: List<String> synchList = parseSynchTemplates(root);
0307:
0308: CacheDatabase cacheDatabase = parseCacheDatabase(root);
0309:
0310: PrintMapParam printMapParam = parsePrintMapParam(root);
0311:
0312: WMPSDeegreeParams deegreeParams = new WMPSDeegreeParams(cache,
0313: maxLifeTime, reqTimeLimit, (float) mapQuality, ol,
0314: maxMapWidth, maxMapHeight, antiAliased,
0315: featureInfoRadius, copyright, gazetteer, null,
0316: dtdLocation, proxy, synchList, cacheDatabase,
0317: printMapParam);
0318:
0319: return deegreeParams;
0320: }
0321:
0322: /**
0323: * Parse the cache database parameters used by the wmps to store the asynchronous requests.
0324: *
0325: * @param root
0326: * @return CacheDatabase
0327: * @throws XMLParsingException
0328: */
0329: private CacheDatabase parseCacheDatabase(Node root)
0330: throws XMLParsingException {
0331:
0332: CacheDatabase cacheDatabase = null;
0333: String xPath = "./deegreewmps:CacheDatabase";
0334: Node cacheDb = XMLTools.getNode(root, xPath, nsContext);
0335: if (cacheDb != null) {
0336: xPath = "./deegreewmps:JDBCConnection";
0337: Node jdbcConnection = XMLTools.getRequiredNode(cacheDb,
0338: xPath, nsContext);
0339: String driver = XMLTools.getRequiredNodeAsString(
0340: jdbcConnection, "./deegreewmps:Driver", nsContext);
0341: String url = XMLTools.getRequiredNodeAsString(
0342: jdbcConnection, "./deegreewmps:Url", nsContext);
0343: String user = XMLTools.getRequiredNodeAsString(
0344: jdbcConnection, "./deegreewmps:User", nsContext);
0345: String password = XMLTools
0346: .getRequiredNodeAsString(jdbcConnection,
0347: "./deegreewmps:Password", nsContext);
0348: cacheDatabase = new CacheDatabase(driver, url, user,
0349: password);
0350: LOG
0351: .logDebug("Successfully parsed the deegree wmps cache database parameters.");
0352: }
0353:
0354: return cacheDatabase;
0355: }
0356:
0357: /**
0358: * Parse the PrintMapParam node and retrieve the (jasper reports)template directory, the default
0359: * template name if none is specified in the request. Also parse the output directory location
0360: * and the location of the printed image output directory.
0361: *
0362: * @param root
0363: * @return PrintMapParam
0364: * @throws XMLParsingException
0365: * @throws MalformedURLException
0366: */
0367: private PrintMapParam parsePrintMapParam(Node root)
0368: throws XMLParsingException, MalformedURLException {
0369:
0370: Node printParam = XMLTools.getRequiredNode(root,
0371: "./deegreewmps:PrintMapParam", nsContext);
0372: // set default as pdf
0373: String format = XMLTools.getNodeAsString(printParam,
0374: "./deegreewmps:Format", nsContext, "pdf");
0375: Node templ = XMLTools.getRequiredNode(printParam,
0376: "./deegreewmps:Template", nsContext);
0377: String templateDirectory = XMLTools.getRequiredNodeAsString(
0378: templ, "./deegreewmps:Directory", nsContext);
0379:
0380: templateDirectory = this .resolve(templateDirectory)
0381: .toExternalForm();
0382: if (!templateDirectory.endsWith("/")) {
0383: templateDirectory = templateDirectory + '/';
0384: }
0385: String plotDirectory = XMLTools.getRequiredNodeAsString(
0386: printParam, "./deegreewmps:PlotDirectory", nsContext);
0387: plotDirectory = this .resolve(plotDirectory).toExternalForm();
0388: String onlineResource = XMLTools.getRequiredNodeAsString(
0389: printParam, "./deegreewmps:OnlineResource", nsContext);
0390: String plotImgDir = XMLTools.getRequiredNodeAsString(
0391: printParam, "./deegreewmps:PlotImageDirectory",
0392: nsContext);
0393: plotImgDir = this .resolve(plotImgDir).toExternalForm();
0394: String adminMail = XMLTools.getRequiredNodeAsString(printParam,
0395: "./deegreewmps:AdministratorEMailAddress", nsContext);
0396: String mailHost = XMLTools.getRequiredNodeAsString(printParam,
0397: "./deegreewmps:MailHost", nsContext);
0398:
0399: String mailTextTemplate = XMLTools.getNodeAsString(printParam,
0400: "./deegreewmps:MailTextTemplate", nsContext,
0401: "You can access the printMap result at {1}");
0402:
0403: int targetRes = XMLTools.getNodeAsInt(printParam,
0404: "./deegreewmps:TargetResolution", nsContext, 300);
0405:
0406: PrintMapParam printMapParam = new PrintMapParam(format,
0407: templateDirectory, onlineResource, plotDirectory,
0408: plotImgDir, adminMail, mailHost, mailTextTemplate,
0409: targetRes);
0410:
0411: return printMapParam;
0412: }
0413:
0414: /**
0415: * parses the list of templates that shall be handled synchronously
0416: *
0417: * @param root
0418: * @return List
0419: * @throws XMLParsingException
0420: */
0421: private List<String> parseSynchTemplates(Node root)
0422: throws XMLParsingException {
0423:
0424: String xPath = "./deegreewmps:SynchronousTemplates/deegreewmps:Template";
0425: String[] nodes = XMLTools.getNodesAsStrings(root, xPath,
0426: nsContext);
0427: List<String> list = new ArrayList<String>(nodes.length);
0428: for (int i = 0; i < nodes.length; i++) {
0429: list.add(nodes[i]);
0430: }
0431:
0432: return list;
0433: }
0434:
0435: /**
0436: * @param root
0437: * @return Proxy
0438: * @throws XMLParsingException
0439: */
0440: private Proxy parseProxy(Node root) throws XMLParsingException {
0441:
0442: Proxy proxy = null;
0443: Node pro = XMLTools.getNode(root, "./deegreewmps:Proxy",
0444: nsContext);
0445: if (pro != null) {
0446: String proxyHost = XMLTools.getRequiredNodeAsString(pro,
0447: "./@proxyHost", nsContext);
0448: String proxyPort = XMLTools.getRequiredNodeAsString(pro,
0449: "./@proxyPort", nsContext);
0450: proxy = new Proxy(proxyHost, proxyPort);
0451: }
0452:
0453: return proxy;
0454: }
0455:
0456: /**
0457: * creates an object that describes the access to a gazetteer if one have been defined at the
0458: * <DeegreeParam>section of the capabilities/configuration
0459: *
0460: * @param element
0461: * @return GazetteerParam
0462: * @throws XMLParsingException
0463: */
0464: private GazetteerParam parseGazetteerParameter(Element element)
0465: throws XMLParsingException {
0466:
0467: GazetteerParam gazetteer = null;
0468:
0469: if (element != null) {
0470: String xPath = "./deegreewmps:OnlineResource";
0471: Element elem = (Element) XMLTools.getRequiredNode(element,
0472: xPath, nsContext);
0473: OnlineResource olr = parseOnLineResource(elem);
0474: URL onlineResource = olr.getLinkage().getHref();
0475: // optional: <LocationRadius>, default: 10
0476: double radius = XMLTools.getNodeAsDouble(element,
0477: "LocationRadius", nsContext, 10);
0478: gazetteer = new GazetteerParam(onlineResource, radius);
0479: }
0480:
0481: return gazetteer;
0482: }
0483:
0484: /**
0485: * returns the layers offered by the WMS
0486: *
0487: * @param layerElem
0488: * @param parent
0489: * @return Layer
0490: * @throws XMLParsingException
0491: * @throws UnknownCRSException
0492: */
0493: @Override
0494: protected Layer parseLayers(Element layerElem, Layer parent)
0495: throws XMLParsingException, UnknownCRSException {
0496:
0497: boolean queryable = XMLTools.getNodeAsBoolean(layerElem,
0498: "./@queryable", nsContext, false);
0499: int cascaded = XMLTools.getNodeAsInt(layerElem, "./@cascaded",
0500: nsContext, 0);
0501: boolean opaque = XMLTools.getNodeAsBoolean(layerElem,
0502: "./@opaque", nsContext, false);
0503: boolean noSubsets = XMLTools.getNodeAsBoolean(layerElem,
0504: "./@noSubsets", nsContext, false);
0505: int fixedWidth = XMLTools.getNodeAsInt(layerElem,
0506: "./@fixedWidth", nsContext, 0);
0507: int fixedHeight = XMLTools.getNodeAsInt(layerElem,
0508: "./@fixedHeight", nsContext, 0);
0509: String name = XMLTools.getNodeAsString(layerElem, "./Name",
0510: nsContext, null);
0511: String title = XMLTools.getRequiredNodeAsString(layerElem,
0512: "./Title", nsContext);
0513: String layerAbstract = XMLTools.getNodeAsString(layerElem,
0514: "./Abstract", nsContext, null);
0515: String[] keywords = XMLTools.getNodesAsStrings(layerElem,
0516: "./KeywordList/Keyword", nsContext);
0517: String[] srs = XMLTools.getNodesAsStrings(layerElem, "./SRS",
0518: nsContext);
0519: List nl = XMLTools.getNodes(layerElem, "./BoundingBox",
0520: nsContext);
0521: // substitue with Envelope
0522: LayerBoundingBox[] bboxes = null;
0523: if (nl.size() == 0 && parent != null) {
0524: // inherit BoundingBoxes from parent layer
0525: bboxes = parent.getBoundingBoxes();
0526: } else {
0527: bboxes = parseLayerBoundingBoxes(nl);
0528: }
0529:
0530: Element llBox = (Element) XMLTools.getNode(layerElem,
0531: "./LatLonBoundingBox", nsContext);
0532: Envelope llBoundingBox = null;
0533: if (llBox == null && parent != null) {
0534: // inherit LatLonBoundingBox parent layer
0535: llBoundingBox = parent.getLatLonBoundingBox();
0536: } else {
0537: llBoundingBox = parseLatLonBoundingBox(llBox);
0538: }
0539:
0540: Dimension[] dimensions = parseDimensions(layerElem);
0541: Extent[] extents = parseExtents(layerElem);
0542: Attribution attribution = parseAttribution(layerElem);
0543: AuthorityURL[] authorityURLs = parseAuthorityURLs(layerElem);
0544: MetadataURL[] metadataURLs = parseMetadataURLs(layerElem);
0545: DataURL[] dataURLs = parseDataURL(layerElem);
0546: Identifier[] identifiers = parseIdentifiers(layerElem);
0547: FeatureListURL[] featureListURLs = parseFeatureListURL(layerElem);
0548: Style[] styles = parseStyles(layerElem);
0549: ScaleHint scaleHint = parseScaleHint(layerElem);
0550: AbstractDataSource[] ds = parseDataSources(layerElem, name);
0551:
0552: Layer layer = new Layer(queryable, cascaded, opaque, noSubsets,
0553: fixedWidth, fixedHeight, name, title, layerAbstract,
0554: llBoundingBox, attribution, scaleHint, keywords, srs,
0555: bboxes, dimensions, extents, authorityURLs,
0556: identifiers, metadataURLs, dataURLs, featureListURLs,
0557: styles, null, ds, parent);
0558:
0559: // get Child layers
0560: nl = XMLTools.getNodes(layerElem, "./Layer", nsContext);
0561: Layer[] layers = new Layer[nl.size()];
0562: for (int i = 0; i < layers.length; i++) {
0563: layers[i] = parseLayers((Element) nl.get(i), layer);
0564: }
0565: // set child layers
0566: layer.setLayer(layers);
0567:
0568: return layer;
0569: }
0570:
0571: /**
0572: * Parse the Datasources element
0573: *
0574: * @param layerElem
0575: * @param layerName
0576: * @return AbstractDataSource[]
0577: * @throws XMLParsingException
0578: */
0579: private AbstractDataSource[] parseDataSources(Element layerElem,
0580: String layerName) throws XMLParsingException {
0581:
0582: List nl = XMLTools.getNodes(layerElem,
0583: "./deegreewmps:DataSource", nsContext);
0584:
0585: AbstractDataSource[] ds = new AbstractDataSource[nl.size()];
0586: for (int i = 0; i < ds.length; i++) {
0587:
0588: boolean failOnEx = XMLTools.getNodeAsBoolean((Node) nl
0589: .get(i), "./@failOnException", nsContext, true);
0590:
0591: boolean queryable = XMLTools.getNodeAsBoolean((Node) nl
0592: .get(i), "./@queryable", nsContext, false);
0593:
0594: QualifiedName name = XMLTools.getNodeAsQualifiedName(
0595: (Node) nl.get(i), "./deegreewmps:Name/text()",
0596: nsContext, new QualifiedName(layerName));
0597:
0598: String stype = XMLTools.getRequiredNodeAsString((Node) nl
0599: .get(i), "./deegreewmps:Type", nsContext);
0600:
0601: String xPath = "./deegreewmps:OWSCapabilities/deegreewmps:OnlineResource";
0602: Node node = XMLTools.getRequiredNode((Node) nl.get(i),
0603: xPath, nsContext);
0604:
0605: URL url = parseOnLineResource((Element) node).getLinkage()
0606: .getHref();
0607: ScaleHint scaleHint = parseScaleHint((Node) nl.get(i));
0608: Geometry validArea = parseValidArea((Node) nl.get(i));
0609:
0610: try {
0611: if ("LOCALWFS".equals(stype)) {
0612: ds[i] = createLocalWFSDataSource((Node) nl.get(i),
0613: failOnEx, queryable, name, url, scaleHint,
0614: validArea, 60);
0615: } else if ("LOCALWCS".equals(stype)) {
0616: ds[i] = createLocalWCSDataSource((Node) nl.get(i),
0617: failOnEx, queryable, name, url, scaleHint,
0618: validArea, 60);
0619: } else if ("REMOTEWFS".equals(stype)) {
0620: ds[i] = createRemoteWFSDataSource((Node) nl.get(i),
0621: failOnEx, queryable, name, url, scaleHint,
0622: validArea, 60);
0623: } else if ("REMOTEWCS".equals(stype)) {
0624: // TODO
0625: // int type = AbstractDataSource.REMOTEWCS;
0626: // GetCoverage getCoverage = parseWCSFilterCondition( (Node) nl.get( i ) );
0627: // Color[] colors = parseTransparentColors( (Node) nl.get( i ) );
0628: throw new UnsupportedOperationException(
0629: "REMOTEWCS is not supported as yet!");
0630: } else if ("REMOTEWMS".equals(stype)) {
0631: ds[i] = createRemoteWMSDataSource((Node) nl.get(i),
0632: failOnEx, queryable, name, url, scaleHint,
0633: validArea, 60);
0634: } else {
0635: throw new XMLParsingException(
0636: "invalid DataSource type: " + stype
0637: + " defined in deegree WMS "
0638: + "configuration for DataSource: "
0639: + name);
0640: }
0641: } catch (Exception e) {
0642: throw new XMLParsingException(
0643: "could not create service instance for "
0644: + "WMPS datasource: " + name, e);
0645: }
0646: }
0647:
0648: return ds;
0649: }
0650:
0651: /**
0652: * returns the area a data source is valid. If the optional element <ValidArea>is not defined in
0653: * the configuration returns <code>null</code>.
0654: *
0655: * @param node
0656: * @return Geometry
0657: * @throws XMLParsingException
0658: */
0659: private Geometry parseValidArea(Node node)
0660: throws XMLParsingException {
0661:
0662: Geometry geom = null;
0663: List nl = XMLTools.getNodes(node, "./deegreewmps:ValidArea/*",
0664: nsContext);
0665: if (node != null) {
0666: try {
0667: for (int i = 0; i < nl.size(); i++) {
0668: if (((Node) nl.get(0)).getNamespaceURI().equals(
0669: GMLNS)) {
0670: geom = GMLGeometryAdapter.wrap((Element) nl
0671: .get(0), null);
0672: break;
0673: }
0674: }
0675: } catch (GeometryException e) {
0676: throw new XMLParsingException(
0677: "couldn't parse/create valid area of a "
0678: + "datasource", e);
0679: }
0680: }
0681:
0682: return geom;
0683: }
0684:
0685: /**
0686: * Create a RemoteWMS datasource.
0687: *
0688: * @param node
0689: * @param failOnEx
0690: * @param queryable
0691: * @param name
0692: * @param url
0693: * @param scaleHint
0694: * @param validArea
0695: * @param reqTimeLimit
0696: * @return XMLParsingException
0697: * @throws Exception
0698: */
0699: private RemoteWMSDataSource createRemoteWMSDataSource(Node node,
0700: boolean failOnEx, boolean queryable, QualifiedName name,
0701: URL url, ScaleHint scaleHint, Geometry validArea,
0702: int reqTimeLimit) throws Exception {
0703:
0704: int type = AbstractDataSource.REMOTEWMS;
0705: String xPath = "./deegreewmps:FeatureInfoTransformation/deegreewmps:OnlineResource";
0706: Node fitNode = XMLTools.getNode(node, xPath, nsContext);
0707: URL fitURL = null;
0708: if (fitNode != null) {
0709: fitURL = parseOnLineResource((Element) fitNode)
0710: .getLinkage().getHref();
0711: }
0712:
0713: GetMap getMap = parseWMSFilterCondition(node);
0714: Color[] colors = parseTransparentColors(node);
0715: WMSCapabilities wCapa = null;
0716: try {
0717: if (capaCache.get(url) != null) {
0718: wCapa = (WMSCapabilities) capaCache.get(url);
0719: } else {
0720: WMSCapabilitiesDocument doc = WMSCapabilitiesDocumentFactory
0721: .getWMSCapabilitiesDocument(url);
0722: wCapa = (WMSCapabilities) doc.parseCapabilities();
0723: capaCache.put(url, wCapa);
0724: }
0725: } catch (Exception e) {
0726: LOG.logError("could not connet: " + url, e);
0727: }
0728: OGCWebService ows = new RemoteWMService(wCapa);
0729:
0730: // parse added/passed parameter map/list
0731: Node vendor = XMLTools
0732: .getNode(
0733: node,
0734: "deegreewmps:FilterCondition/deegreewmps:VendorspecificParameterDefinition",
0735: nsContext);
0736:
0737: List<String> passedParameters = parsePassedParameters(vendor);
0738: Map<String, String> addedParameters = parseAddedParameters(vendor);
0739:
0740: return new RemoteWMSDataSource(queryable, failOnEx, name, type,
0741: ows, url, scaleHint, validArea, getMap, colors, fitURL,
0742: reqTimeLimit, passedParameters, addedParameters);
0743: }
0744:
0745: /**
0746: * @param vendor
0747: * @return the parsed list
0748: * @throws XMLParsingException
0749: */
0750: private static List<String> parsePassedParameters(Node vendor)
0751: throws XMLParsingException {
0752: List<String> passedParameters = new ArrayList<String>(10);
0753:
0754: if (vendor == null) {
0755: return passedParameters;
0756: }
0757:
0758: List<Node> nl = XMLTools
0759: .getNodes(
0760: vendor,
0761: "deegreewmps:PassedVendorspecificParameter/deegreewmps:Name",
0762: nsContext);
0763:
0764: for (Object obj : nl) {
0765: passedParameters.add(((Node) obj).getTextContent()
0766: .toUpperCase());
0767: }
0768:
0769: return passedParameters;
0770: }
0771:
0772: /**
0773: * @param vendor
0774: * @return the parsed map
0775: * @throws XMLParsingException
0776: */
0777: private static Map<String, String> parseAddedParameters(Node vendor)
0778: throws XMLParsingException {
0779: Map<String, String> addedParameters = new HashMap<String, String>(
0780: 10);
0781:
0782: if (vendor == null) {
0783: return addedParameters;
0784: }
0785:
0786: List<Node> nl = XMLTools
0787: .getNodes(
0788: vendor,
0789: "deegreewmps:AddedVendorspecificParameter/deegreewmps:VendorspecificParameter",
0790: nsContext);
0791:
0792: for (Object obj : nl) {
0793: String pName = XMLTools.getRequiredNodeAsString((Node) obj,
0794: "deegreewmps:Name", nsContext);
0795: String pValue = XMLTools.getRequiredNodeAsString(
0796: (Node) obj, "deegreewmps:Value", nsContext);
0797:
0798: addedParameters.put(pName, pValue);
0799: }
0800: return addedParameters;
0801: }
0802:
0803: /**
0804: * Create a Remote WFS datasource.
0805: *
0806: * @param node
0807: * @param failOnEx
0808: * @param queryable
0809: * @param name
0810: * @param url
0811: * @param scaleHint
0812: * @param validArea
0813: * @param reqTimeLimit
0814: * @return RemoteWFSDataSource
0815: * @throws Exception
0816: */
0817: private RemoteWFSDataSource createRemoteWFSDataSource(Node node,
0818: boolean failOnEx, boolean queryable, QualifiedName name,
0819: URL url, ScaleHint scaleHint, Geometry validArea,
0820: int reqTimeLimit) throws Exception {
0821:
0822: int type = AbstractDataSource.REMOTEWFS;
0823: String xPath = "./deegreewmps:FeatureInfoTransformation/deegreewmps:OnlineResource";
0824: Node fitNode = XMLTools.getNode(node, xPath, nsContext);
0825: URL fitURL = null;
0826: if (fitNode != null) {
0827: fitURL = parseOnLineResource((Element) fitNode)
0828: .getLinkage().getHref();
0829: }
0830: Query query = parseWFSFilterCondition(node);
0831:
0832: WFSCapabilities wfsCapa = null;
0833: if (capaCache.get(url) != null) {
0834: wfsCapa = (WFSCapabilities) capaCache.get(url);
0835: } else {
0836: WFSCapabilitiesDocument wfsDoc = new WFSCapabilitiesDocument();
0837: wfsDoc.load(url);
0838: wfsCapa = (WFSCapabilities) wfsDoc.parseCapabilities();
0839: capaCache.put(url, wfsCapa);
0840: }
0841: // OGCWebService ows = new RemoteWFService( wfsCapa );
0842: OGCWebService ows = null;
0843: xPath = "./deegreewmps:GeometryProperty/text()";
0844: QualifiedName geom = new QualifiedName("app", "GEOM", new URI(
0845: "http://www.deegree.org/app"));
0846: QualifiedName geoProp = XMLTools.getNodeAsQualifiedName(node,
0847: xPath, nsContext, geom);
0848:
0849: return new RemoteWFSDataSource(queryable, failOnEx, name, type,
0850: geoProp, ows, url, scaleHint, validArea, query, fitURL,
0851: reqTimeLimit);
0852:
0853: }
0854:
0855: /**
0856: * Create a Local WCS Datasource
0857: *
0858: * @param node
0859: * @param failOnEx
0860: * @param queryable
0861: * @param name
0862: * @param url
0863: * @param scaleHint
0864: * @param validArea
0865: * @param reqTimeLimit
0866: * @return RemoteWFSDataSource
0867: * @throws Exception
0868: */
0869: private LocalWCSDataSource createLocalWCSDataSource(Node node,
0870: boolean failOnEx, boolean queryable, QualifiedName name,
0871: URL url, ScaleHint scaleHint, Geometry validArea,
0872: int reqTimeLimit) throws Exception {
0873:
0874: int type = AbstractDataSource.LOCALWCS;
0875: GetCoverage getCoverage = parseWCSFilterCondition(node);
0876: Color[] colors = parseTransparentColors(node);
0877: WCSConfiguration configuration = null;
0878: if (capaCache.get(url) != null) {
0879: configuration = (WCSConfiguration) capaCache.get(url);
0880: } else {
0881: configuration = WCSConfiguration.create(url);
0882: capaCache.put(url, configuration);
0883: }
0884:
0885: OGCWebService ows = new WCService(configuration);
0886:
0887: return new LocalWCSDataSource(queryable, failOnEx, name, type,
0888: ows, url, scaleHint, validArea, getCoverage, colors,
0889: reqTimeLimit);
0890: }
0891:
0892: /**
0893: * Create a Local WFS Datasource
0894: *
0895: * @param node
0896: * @param failOnEx
0897: * @param queryable
0898: * @param name
0899: * @param url
0900: * @param scaleHint
0901: * @param validArea
0902: * @param reqTimeLimit
0903: * @return LocalWFSDataSource
0904: * @throws Exception
0905: */
0906: private LocalWFSDataSource createLocalWFSDataSource(Node node,
0907: boolean failOnEx, boolean queryable, QualifiedName name,
0908: URL url, ScaleHint scaleHint, Geometry validArea,
0909: int reqTimeLimit) throws Exception {
0910:
0911: int type = AbstractDataSource.LOCALWFS;
0912: String xPath = null;
0913: Query query = parseWFSFilterCondition(node);
0914: WFSConfiguration wfsCapa = null;
0915: if (capaCache.get(url) != null) {
0916: wfsCapa = (WFSConfiguration) capaCache.get(url);
0917: } else {
0918: WFSConfigurationDocument wfsDoc = new WFSConfigurationDocument();
0919: wfsDoc.load(url);
0920: wfsCapa = wfsDoc.getConfiguration();
0921: capaCache.put(url, wfsCapa);
0922: }
0923: // OGCWebService ows = WFServiceFactory.getUncachedService( wfsCapa );
0924: OGCWebService ows = WFServiceFactory.createInstance(wfsCapa);
0925:
0926: QualifiedName geom = new QualifiedName("app", "GEOM", new URI(
0927: "http://www.deegree.org/app"));
0928: xPath = "./deegreewmps:GeometryProperty/text()";
0929: QualifiedName geoProp = XMLTools.getNodeAsQualifiedName(node,
0930: xPath, nsContext, geom);
0931:
0932: return new LocalWFSDataSource(queryable, failOnEx, name, type,
0933: geoProp, ows, url, scaleHint, validArea, query, null,
0934: reqTimeLimit);
0935: }
0936:
0937: /**
0938: * Parse trasparent colors.
0939: *
0940: * @param node
0941: * @return Color[]
0942: * @throws XMLParsingException
0943: */
0944: private Color[] parseTransparentColors(Node node)
0945: throws XMLParsingException {
0946:
0947: String xPath = "./deegreewmps:TransparentColors/deegreewmps:Color";
0948: List clnl = XMLTools.getNodes(node, xPath, nsContext);
0949: Color[] colors = new Color[clnl.size()];
0950: for (int i = 0; i < colors.length; i++) {
0951: colors[i] = Color.decode(XMLTools
0952: .getStringValue((Node) clnl.get(i)));
0953: }
0954:
0955: return colors;
0956: }
0957:
0958: /**
0959: * Parse Scale hint
0960: *
0961: * @param node
0962: * @return ScaleHint
0963: * @throws XMLParsingException
0964: */
0965: private ScaleHint parseScaleHint(Node node)
0966: throws XMLParsingException {
0967:
0968: String xPath = "./deegreewmps:ScaleHint/@min";
0969: double minScale = XMLTools.getNodeAsDouble(node, xPath,
0970: nsContext, 0);
0971: xPath = "./deegreewmps:ScaleHint/@max";
0972: double maxScale = XMLTools.getNodeAsDouble(node, xPath,
0973: nsContext, Double.MAX_VALUE);
0974:
0975: return new ScaleHint(minScale, maxScale);
0976: }
0977:
0978: /**
0979: * Parse WFS Filter condition
0980: *
0981: * @param node
0982: * @return Query
0983: * @throws XMLParsingException
0984: */
0985: private Query parseWFSFilterCondition(Node node)
0986: throws XMLParsingException {
0987:
0988: Query query = null;
0989: String xPath = "./deegreewmps:FilterCondition/wfs:Query";
0990: Node queryNode = XMLTools.getNode(node, xPath, nsContext);
0991: if (queryNode != null) {
0992: try {
0993: query = Query.create((Element) queryNode);
0994: } catch (Exception e) {
0995: throw new XMLParsingException(StringTools
0996: .stackTraceToString(e));
0997: }
0998: }
0999:
1000: return query;
1001: }
1002:
1003: /**
1004: * Parse WCS Filter Condition
1005: *
1006: * @param node
1007: * @return GetCoverage
1008: * @throws XMLParsingException
1009: */
1010: private GetCoverage parseWCSFilterCondition(Node node)
1011: throws XMLParsingException {
1012:
1013: GetCoverage getCoverage = null;
1014:
1015: String id = "" + IDGenerator.getInstance().generateUniqueID();
1016:
1017: StringBuffer sd = new StringBuffer(1000);
1018: sd.append("version=1.0.0&Coverage=%default%&");
1019: sd.append("CRS=EPSG:4326&BBOX=0,0,1,1&Width=1");
1020: sd.append("&Height=1&Format=%default%&");
1021: String xPath = "./deegreewmps:FilterCondition/deegreewmps:WCSRequest";
1022: String s = XMLTools.getNodeAsString(node, xPath, nsContext, "");
1023: sd.append(s);
1024: try {
1025: getCoverage = GetCoverage.create(id, sd.toString());
1026: } catch (Exception e) {
1027: throw new XMLParsingException(
1028: "could not create GetCoverage from WMS "
1029: + "FilterCondition", e);
1030: }
1031:
1032: return getCoverage;
1033: }
1034:
1035: /**
1036: * Returns a GetMap instance , parsing the WMS Filter condition
1037: *
1038: * @param node
1039: * @return GetMap
1040: * @throws XMLParsingException
1041: */
1042: private GetMap parseWMSFilterCondition(Node node)
1043: throws XMLParsingException {
1044:
1045: GetMap getMap = null;
1046:
1047: String id = "" + IDGenerator.getInstance().generateUniqueID();
1048:
1049: StringBuffer sd = new StringBuffer(1000);
1050: sd.append("REQUEST=GetMap&LAYERS=%default%&");
1051: sd.append("STYLES=&SRS=EPSG:4326&BBOX=0,0,1,1&WIDTH=1&");
1052: sd.append("HEIGHT=1&FORMAT=%default%");
1053: Map<String, String> map1 = KVP2Map.toMap(sd.toString());
1054: String xPath = "./deegreewmps:FilterCondition/deegreewmps:WMSRequest";
1055: String s = XMLTools.getRequiredNodeAsString(node, xPath,
1056: nsContext);
1057: Map<String, String> map2 = KVP2Map.toMap(s);
1058: if (map2.get("VERSION") == null && map2.get("WMTVER") == null) {
1059: map2.put("VERSION", "1.1.1");
1060: }
1061: // if no service is set use WMS as default
1062: if (map2.get("SERVICE") == null) {
1063: map2.put("SERVICE", "WMS");
1064: }
1065: map1.putAll(map2);
1066: try {
1067: map1.put("ID", id);
1068: getMap = GetMap.create(map1);
1069: } catch (Exception e) {
1070: throw new XMLParsingException(
1071: "could not create GetCoverage from WMS "
1072: + "FilterCondition", e);
1073: }
1074:
1075: return getMap;
1076: }
1077:
1078: /**
1079: * Returns a list of Style elements, parsing the style element
1080: *
1081: * @param layerElem
1082: * @return Style[]
1083: * @throws XMLParsingException
1084: */
1085: @Override
1086: protected Style[] parseStyles(Element layerElem)
1087: throws XMLParsingException {
1088:
1089: List nl = XMLTools.getNodes(layerElem, "./Style", nsContext);
1090: Style[] styles = new Style[nl.size()];
1091: for (int i = 0; i < styles.length; i++) {
1092: String name = XMLTools.getRequiredNodeAsString((Node) nl
1093: .get(i), "./Name", nsContext);
1094: String title = XMLTools.getNodeAsString((Node) nl.get(i),
1095: "./Title", nsContext, null);
1096: String styleAbstract = XMLTools.getNodeAsString((Node) nl
1097: .get(i), "./Abstract", nsContext, null);
1098: LegendURL[] legendURLs = parseLegendURL((Node) nl.get(i));
1099: StyleURL styleURL = parseStyleURL((Node) nl.get(i));
1100: StyleSheetURL styleSheetURL = parseStyleSheetURL((Node) nl
1101: .get(i));
1102: String xPath = "deegreewmps:StyleResource";
1103: String styleResource = XMLTools.getNodeAsString((Node) nl
1104: .get(i), xPath, nsContext, "styles.xml");
1105: URL sr = null;
1106: try {
1107: sr = resolve(styleResource);
1108: } catch (MalformedURLException e) {
1109: throw new XMLParsingException(
1110: "could not parse style resource of "
1111: + "style: " + name, e);
1112: }
1113: styles[i] = new Style(name, title, styleAbstract,
1114: legendURLs, styleSheetURL, styleURL, sr);
1115: }
1116:
1117: return styles;
1118: }
1119:
1120: }
|