0001: //$HeadURL: https://svn.wald.intevation.org/svn/deegree/base/trunk/src/org/deegree/ogcwebservices/wms/capabilities/WMSCapabilitiesDocument.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: Aennchenstr. 19
0030: 53115 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: ---------------------------------------------------------------------------*/
0044: package org.deegree.ogcwebservices.wms.capabilities;
0045:
0046: import java.io.IOException;
0047: import java.net.MalformedURLException;
0048: import java.net.URI;
0049: import java.net.URISyntaxException;
0050: import java.net.URL;
0051: import java.util.ArrayList;
0052: import java.util.Arrays;
0053: import java.util.Date;
0054: import java.util.List;
0055:
0056: import org.deegree.datatypes.Code;
0057: import org.deegree.datatypes.QualifiedName;
0058: import org.deegree.datatypes.values.TypedLiteral;
0059: import org.deegree.framework.log.ILogger;
0060: import org.deegree.framework.log.LoggerFactory;
0061: import org.deegree.framework.util.StringTools;
0062: import org.deegree.framework.xml.XMLParsingException;
0063: import org.deegree.framework.xml.XMLTools;
0064: import org.deegree.i18n.Messages;
0065: import org.deegree.model.crs.CRSFactory;
0066: import org.deegree.model.crs.CoordinateSystem;
0067: import org.deegree.model.crs.UnknownCRSException;
0068: import org.deegree.model.metadata.iso19115.Address;
0069: import org.deegree.model.metadata.iso19115.CitedResponsibleParty;
0070: import org.deegree.model.metadata.iso19115.Constraints;
0071: import org.deegree.model.metadata.iso19115.ContactInfo;
0072: import org.deegree.model.metadata.iso19115.Keywords;
0073: import org.deegree.model.metadata.iso19115.Linkage;
0074: import org.deegree.model.metadata.iso19115.OnlineResource;
0075: import org.deegree.model.metadata.iso19115.Phone;
0076: import org.deegree.model.spatialschema.Envelope;
0077: import org.deegree.model.spatialschema.GeometryFactory;
0078: import org.deegree.model.spatialschema.Position;
0079: import org.deegree.ogcwebservices.getcapabilities.InvalidCapabilitiesException;
0080: import org.deegree.ogcwebservices.getcapabilities.MetadataURL;
0081: import org.deegree.ogcwebservices.getcapabilities.OGCCapabilities;
0082: import org.deegree.ogcwebservices.getcapabilities.OGCCapabilitiesDocument;
0083: import org.deegree.owscommon_new.DCP;
0084: import org.deegree.owscommon_new.DomainType;
0085: import org.deegree.owscommon_new.HTTP;
0086: import org.deegree.owscommon_new.Operation;
0087: import org.deegree.owscommon_new.OperationsMetadata;
0088: import org.deegree.owscommon_new.Parameter;
0089: import org.deegree.owscommon_new.ServiceIdentification;
0090: import org.deegree.owscommon_new.ServiceProvider;
0091: import org.w3c.dom.Element;
0092: import org.w3c.dom.Node;
0093: import org.xml.sax.SAXException;
0094:
0095: /**
0096: * <code>WMSCapabilitiesDocument</code> is the parser class for WMS capabilities documents that
0097: * uses the new OWS common classes to encapsulate the data.
0098: *
0099: * @author <a href="mailto:schmitz@lat-lon.de">Andreas Schmitz</a>
0100: * @author last edited by: $Author: apoth $
0101: *
0102: * @version 2.0, $Revision: 9345 $, $Date: 2007-12-27 08:22:25 -0800 (Thu, 27 Dec 2007) $
0103: *
0104: * @since 2.0
0105: */
0106:
0107: public class WMSCapabilitiesDocument extends OGCCapabilitiesDocument {
0108:
0109: private static final long serialVersionUID = -4165017479515126226L;
0110:
0111: private static final String XML_TEMPLATE = "WMSCapabilitiesTemplate.xml";
0112:
0113: private static final ILogger LOG = LoggerFactory
0114: .getLogger(WMSCapabilitiesDocument.class);
0115:
0116: /**
0117: * Creates a skeleton capabilities document that contains the mandatory elements only.
0118: *
0119: * @throws IOException
0120: * @throws SAXException
0121: */
0122: public void createEmptyDocument() throws IOException, SAXException {
0123:
0124: URL url = WMSCapabilitiesDocument.class
0125: .getResource(XML_TEMPLATE);
0126: if (url == null) {
0127: throw new IOException("The resource '" + XML_TEMPLATE
0128: + " could not be found.");
0129: }
0130: load(url);
0131: }
0132:
0133: protected List<String> parseExceptionFormats(Element elem)
0134: throws XMLParsingException {
0135: String[] formats = XMLTools.getRequiredNodesAsStrings(elem,
0136: "Format", nsContext);
0137: return Arrays.asList(formats);
0138: }
0139:
0140: /**
0141: * Creates a class representation of the document.
0142: *
0143: * @return class representation of the configuration document
0144: * @throws InvalidCapabilitiesException
0145: */
0146: @Override
0147: public OGCCapabilities parseCapabilities()
0148: throws InvalidCapabilitiesException {
0149: ServiceIdentification serviceIdentification = null;
0150: ServiceProvider serviceProvider = null;
0151: OperationsMetadata metadata = null;
0152: Layer layer = null;
0153: UserDefinedSymbolization uds = null;
0154: String version = parseVersion();
0155: List<String> exceptions;
0156:
0157: String updateSeq = parseUpdateSequence();
0158: try {
0159: serviceIdentification = parseServiceIdentification();
0160: serviceProvider = parseServiceProvider();
0161: metadata = parseOperationsMetadata();
0162:
0163: Element exceptionElement = XMLTools
0164: .getRequiredElement(getRootElement(),
0165: "Capability/Exception", nsContext);
0166: exceptions = parseExceptionFormats(exceptionElement);
0167:
0168: uds = parseUserDefinedSymbolization();
0169: Element layerElem = XMLTools.getRequiredElement(
0170: getRootElement(), "./Capability/Layer", nsContext);
0171: layer = parseLayers(layerElem, null, null);
0172: } catch (XMLParsingException e) {
0173: e.printStackTrace();
0174: throw new InvalidCapabilitiesException(e.getMessage()
0175: + StringTools.stackTraceToString(e));
0176: } catch (UnknownCRSException e) {
0177: e.printStackTrace();
0178: throw new InvalidCapabilitiesException(e.getMessage()
0179: + StringTools.stackTraceToString(e));
0180: }
0181:
0182: WMSCapabilities wmsCapabilities = new WMSCapabilities(version,
0183: updateSeq, serviceIdentification, serviceProvider, uds,
0184: metadata, layer, exceptions);
0185:
0186: return wmsCapabilities;
0187: }
0188:
0189: /**
0190: * returns the services indentification read from the WMS capabilities service section
0191: *
0192: * @throws XMLParsingException
0193: */
0194: protected ServiceIdentification parseServiceIdentification()
0195: throws XMLParsingException {
0196: String name = XMLTools.getNodeAsString(getRootElement(),
0197: "./Service/Name", nsContext, null);
0198: String title = XMLTools.getNodeAsString(getRootElement(),
0199: "./Service/Title", nsContext, name);
0200: String serviceAbstract = XMLTools
0201: .getNodeAsString(getRootElement(),
0202: "./Service/Abstract", nsContext, null);
0203:
0204: String[] kw = XMLTools.getNodesAsStrings(getRootElement(),
0205: "./Service/KeywordList/Keyword", nsContext);
0206:
0207: Keywords[] keywordArray = new Keywords[] { new Keywords(kw) };
0208: List<Keywords> keywords = Arrays.asList(keywordArray);
0209:
0210: String fees = XMLTools.getNodeAsString(getRootElement(),
0211: "./Service/Fees", nsContext, null);
0212:
0213: List<Constraints> accessConstraints = new ArrayList<Constraints>();
0214:
0215: String[] constraints = XMLTools.getNodesAsStrings(
0216: getRootElement(), "./Service/AccessConstraints",
0217: nsContext);
0218:
0219: for (String constraint : constraints) {
0220: List<String> limits = new ArrayList<String>();
0221: limits.add(constraint);
0222: accessConstraints.add(new Constraints(fees, null, null,
0223: null, limits, null, null, null));
0224: }
0225:
0226: List<String> versions = new ArrayList<String>();
0227: versions.add("1.0.0");
0228: versions.add("1.1.0");
0229: versions.add("1.1.1");
0230: versions.add("1.2.0");
0231: versions.add("1.3.0");
0232:
0233: ServiceIdentification serviceIdentification = new ServiceIdentification(
0234: new Code("OGC:WMS"), versions, title, null, new Date(
0235: System.currentTimeMillis()), title,
0236: serviceAbstract, keywords, accessConstraints);
0237:
0238: return serviceIdentification;
0239: }
0240:
0241: /**
0242: * returns WMS contact informaion encapsulated within a <code>ServiceProvider</code> object
0243: *
0244: * @return the service provider data
0245: * @throws XMLParsingException
0246: */
0247: protected ServiceProvider parseServiceProvider()
0248: throws XMLParsingException {
0249: Node ci = XMLTools.getNode(getRootElement(),
0250: "./Service/ContactInformation", nsContext);
0251: // according to WMS 1.1.1 specification this element is mandatory
0252: // but there are several services online which does not contain
0253: // this element in its capabilities :-(
0254: String s = XMLTools
0255: .getNodeAsString(getRootElement(),
0256: "./Service/OnlineResource/@xlink:href",
0257: nsContext, null);
0258:
0259: OnlineResource providerSite = null;
0260:
0261: if (s != null) {
0262: try {
0263: providerSite = new OnlineResource(new Linkage(
0264: new URL(s)));
0265: } catch (MalformedURLException e) {
0266: throw new XMLParsingException(
0267: "could not parse service online resource", e);
0268: }
0269: } else {
0270: // use default if no online resource is contained in the
0271: // capabilities (see comment above)
0272: try {
0273: providerSite = new OnlineResource(new Linkage(new URL(
0274: "http://www.opengeospatial.org/")));
0275: } catch (MalformedURLException neverHappens) {
0276: // useless exception
0277: }
0278: }
0279:
0280: String person = null;
0281: String orga = null;
0282: String position = null;
0283: if (ci != null) {
0284: person = XMLTools.getNodeAsString(ci,
0285: "./ContactPersonPrimary/ContactPerson", nsContext,
0286: null);
0287: orga = XMLTools.getNodeAsString(ci,
0288: "./ContactPersonPrimary/ContactOrganization",
0289: nsContext, null);
0290: position = XMLTools.getNodeAsString(ci,
0291: "./ContactPosition", nsContext, null);
0292: }
0293: ContactInfo contact = parseContactInfo();
0294: // ServiceProvider sp = new ServiceProvider( orga, sLink, person, position, contact, null );
0295: CitedResponsibleParty party = new CitedResponsibleParty(
0296: new ContactInfo[] { contact }, new String[] { person },
0297: new String[] { orga }, new String[] { position }, null);
0298: ServiceProvider sp = new ServiceProvider(person, providerSite,
0299: party);
0300:
0301: return sp;
0302: }
0303:
0304: /**
0305: *
0306: * @return the contact information
0307: * @throws XMLParsingException
0308: */
0309: protected ContactInfo parseContactInfo() throws XMLParsingException {
0310: Node ci = XMLTools.getNode(getRootElement(),
0311: "./Service/ContactInformation", nsContext);
0312: ContactInfo cont = null;
0313: if (ci != null) {
0314: String[] addr = XMLTools.getNodesAsStrings(ci,
0315: "./ContactAddress/Address", nsContext);
0316: // String addrType =
0317: // XMLTools.getNodeAsString( ci, "./ContactAddress/AddressType", nsContext, null );
0318: String city = XMLTools.getNodeAsString(ci,
0319: "./ContactAddress/City", nsContext, null);
0320: String state = XMLTools
0321: .getNodeAsString(ci,
0322: "./ContactAddress/StateOrProvince",
0323: nsContext, null);
0324: String pc = XMLTools.getNodeAsString(ci,
0325: "./ContactAddress/PostCode", nsContext, null);
0326: String country = XMLTools.getNodeAsString(ci,
0327: "./ContactAddress/Country", nsContext, null);
0328: String[] mail = XMLTools.getNodesAsStrings(ci,
0329: "./ContactElectronicMailAddress", nsContext);
0330: Address address = new Address(state, city, country, addr,
0331: mail, pc);
0332:
0333: String[] phone = XMLTools.getNodesAsStrings(ci,
0334: "./ContactVoiceTelephone", nsContext);
0335: String[] fax = XMLTools.getNodesAsStrings(ci,
0336: "./ContactFacsimileTelephone", nsContext);
0337:
0338: Phone ph = new Phone(fax, phone);
0339:
0340: cont = new ContactInfo(address, null, null, null, ph);
0341: }
0342:
0343: return cont;
0344: }
0345:
0346: /**
0347: * returns the services capabilitiy read from the WMS capabilities file
0348: *
0349: * @return the operations metadata
0350: * @throws XMLParsingException
0351: */
0352: protected OperationsMetadata parseOperationsMetadata()
0353: throws XMLParsingException {
0354:
0355: Node opNode = XMLTools.getNode(getRootElement(),
0356: "./Capability/Request/GetCapabilities", nsContext);
0357:
0358: if (opNode == null) {
0359: // may it is a WMS 1.0.0 capabilities document
0360: opNode = XMLTools.getRequiredNode(getRootElement(),
0361: "./Capability/Request/Capabilities", nsContext);
0362: }
0363: Operation getCapa = parseOperation(opNode);
0364:
0365: opNode = XMLTools.getNode(getRootElement(),
0366: "./Capability/Request/GetMap", nsContext);
0367: if (opNode == null) {
0368: // may it is a WMS 1.0.0 capabilities document
0369: opNode = XMLTools.getRequiredNode(getRootElement(),
0370: "./Capability/Request/Map", nsContext);
0371: }
0372: Operation getMap = parseOperation(opNode);
0373:
0374: opNode = XMLTools.getNode(getRootElement(),
0375: "./Capability/Request/GetFeatureInfo", nsContext);
0376: Operation getFI = null;
0377: if (opNode != null) {
0378: getFI = parseOperation(opNode);
0379: } else {
0380: // maybe its WMS 1.0.0
0381: opNode = XMLTools.getNode(getRootElement(),
0382: "./Capability/Request/FeatureInfo", nsContext);
0383: if (opNode != null) {
0384: getFI = parseOperation(opNode);
0385: }
0386: }
0387:
0388: opNode = XMLTools.getNode(getRootElement(),
0389: "./Capability/Request/GetLegendGraphic", nsContext);
0390: Operation getLG = null;
0391: if (opNode != null) {
0392: getLG = parseOperation(opNode);
0393: }
0394:
0395: opNode = XMLTools.getNode(getRootElement(),
0396: "./Capability/Request/DescribeLayer", nsContext);
0397: Operation descL = null;
0398: if (opNode != null) {
0399: descL = parseOperation(opNode);
0400: }
0401:
0402: opNode = XMLTools.getNode(getRootElement(),
0403: "./Capability/Request/GetStyles", nsContext);
0404: Operation getStyles = null;
0405: if (opNode != null) {
0406: getStyles = parseOperation(opNode);
0407: }
0408:
0409: opNode = XMLTools.getNode(getRootElement(),
0410: "./Capability/Request/PutStyles", nsContext);
0411: Operation putStyles = null;
0412: if (opNode != null) {
0413: putStyles = parseOperation(opNode);
0414: }
0415:
0416: List<Operation> operations = new ArrayList<Operation>();
0417: if (getCapa != null)
0418: operations.add(getCapa);
0419: if (getMap != null)
0420: operations.add(getMap);
0421: if (getFI != null)
0422: operations.add(getFI);
0423: if (getLG != null)
0424: operations.add(getLG);
0425: if (descL != null)
0426: operations.add(descL);
0427: if (getStyles != null)
0428: operations.add(getStyles);
0429: if (putStyles != null)
0430: operations.add(putStyles);
0431:
0432: OperationsMetadata metadata = new OperationsMetadata(null,
0433: null, operations, null);
0434:
0435: return metadata;
0436: }
0437:
0438: /**
0439: * Creates an <tt>Operation</tt>-instance according to the contents of the DOM-subtree
0440: * starting at the given <tt>Node</tt>.
0441: * <p>
0442: * Notice: operation to be parsed must be operations in sense of WMS 1.0.0 - 1.3.0 and not as
0443: * defined in OWSCommons. But the method will return an OWSCommon Operation which encapsulates
0444: * parsed WMS operation
0445: * <p>
0446: *
0447: * @param element
0448: * the <tt>Element</tt> that describes an <tt>Operation</tt>
0449: * @throws XMLParsingException
0450: * if a syntactic or semantic error in the DOM-subtree is encountered
0451: * @return the constructed <tt>Operation</tt>-instance
0452: */
0453: protected Operation parseOperation(Node node)
0454: throws XMLParsingException {
0455: // use node name as name of the Operation to be defined
0456: String name = node.getNodeName();
0457: if (name.equals("Capabilities")) {
0458: name = "GetCapabilities";
0459: } else if (name.equals("Map")) {
0460: name = "GetMap";
0461: } else if (name.equals("FeatureInfo")) {
0462: name = "GetFeatureInfo";
0463: }
0464:
0465: String[] tmp = XMLTools.getRequiredNodesAsStrings(node,
0466: "./Format", nsContext);
0467: List<TypedLiteral> values = new ArrayList<TypedLiteral>();
0468:
0469: URI stringURI = null;
0470: try {
0471: stringURI = new URI(null, "String", null);
0472: } catch (URISyntaxException e) {
0473: // cannot happen, why do I have to catch this?
0474: }
0475:
0476: for (String str : tmp)
0477: values.add(new TypedLiteral(str, stringURI));
0478:
0479: DomainType owsDomainType = new DomainType(false, true, null, 0,
0480: new QualifiedName("Format"), values, null, null, false,
0481: null, false, null, null, null, null);
0482: List<Parameter> parameters = new ArrayList<Parameter>();
0483: parameters.add(owsDomainType);
0484:
0485: List<Element> nl = XMLTools.getRequiredElements(node,
0486: "./DCPType", nsContext);
0487: List<DCP> dcps = new ArrayList<DCP>();
0488:
0489: for (Element element : nl) {
0490: dcps.add(parseDCP(element));
0491: }
0492:
0493: return new Operation(new QualifiedName(name), dcps, parameters,
0494: null, null, null);
0495: }
0496:
0497: /**
0498: * Parses a DCPType element. Does not override the method defined in the base class any more.
0499: *
0500: * @param element
0501: * @return created <code>DCPType</code>
0502: * @throws XMLParsingException
0503: * @see org.deegree.ogcwebservices.getcapabilities.OGCStandardCapabilities
0504: */
0505: protected DCP parseDCP(Element element) throws XMLParsingException {
0506:
0507: List<HTTP.Type> types = new ArrayList<HTTP.Type>();
0508: List<OnlineResource> links = new ArrayList<OnlineResource>();
0509:
0510: Element elem = XMLTools.getRequiredElement(element, "HTTP",
0511: nsContext);
0512: String s = null;
0513: try {
0514: List<Node> nl = XMLTools.getNodes(elem, "Get", nsContext);
0515:
0516: for (int i = 0; i < nl.size(); i++) {
0517: s = XMLTools.getNodeAsString(nl.get(i),
0518: "./@xlink:href", nsContext, null);
0519: if (s == null) {
0520: s = XMLTools.getRequiredNodeAsString(nl.get(i),
0521: "./OnlineResource/@xlink:href", nsContext);
0522: }
0523: types.add(HTTP.Type.Get);
0524: links.add(new OnlineResource(new Linkage(new URL(s))));
0525: }
0526: } catch (Exception e) {
0527: LOG.logError(e.getMessage(), e);
0528: throw new XMLParsingException(Messages.getMessage(
0529: "WMS_DCPGET", s));
0530: }
0531: try {
0532: List<Node> nl = XMLTools.getNodes(elem, "Post", nsContext);
0533:
0534: for (int i = 0; i < nl.size(); i++) {
0535: s = XMLTools.getNodeAsString(nl.get(i),
0536: "./@xlink:href", nsContext, null);
0537: if (s == null) {
0538: s = XMLTools.getRequiredNodeAsString(nl.get(i),
0539: "./OnlineResource/@xlink:href", nsContext);
0540: }
0541: types.add(HTTP.Type.Post);
0542: links.add(new OnlineResource(new Linkage(new URL(s))));
0543: }
0544:
0545: } catch (MalformedURLException e) {
0546: throw new XMLParsingException(Messages.getMessage(
0547: "WMS_DCPPOST", s));
0548: }
0549: HTTP http = new HTTP(links, null, types);
0550:
0551: return http;
0552: }
0553:
0554: /**
0555: *
0556: * @return the parsed data
0557: * @throws XMLParsingException
0558: */
0559: protected UserDefinedSymbolization parseUserDefinedSymbolization()
0560: throws XMLParsingException {
0561:
0562: boolean supportSLD = XMLTools.getNodeAsBoolean(
0563: getRootElement(),
0564: "./Capability/UserDefinedSymbolization/@SupportSLD",
0565: nsContext, false);
0566:
0567: boolean userLayer = XMLTools.getNodeAsBoolean(getRootElement(),
0568: "./Capability/UserDefinedSymbolization/@UserLayer",
0569: nsContext, false);
0570:
0571: boolean userStyle = XMLTools.getNodeAsBoolean(getRootElement(),
0572: "./Capability/UserDefinedSymbolization/@UserStyle",
0573: nsContext, false);
0574:
0575: boolean remoteWFS = XMLTools.getNodeAsBoolean(getRootElement(),
0576: "./Capability/UserDefinedSymbolization/@RemoteWFS",
0577: nsContext, false);
0578:
0579: UserDefinedSymbolization uds = new UserDefinedSymbolization(
0580: supportSLD, userLayer, remoteWFS, userStyle);
0581:
0582: return uds;
0583: }
0584:
0585: /**
0586: * returns the layers offered by the WMS
0587: *
0588: * @return the layer
0589: * @throws XMLParsingException
0590: * @throws UnknownCRSException
0591: */
0592: protected Layer parseLayers(Element layerElem, Layer parent,
0593: ScaleHint scaleHint) throws XMLParsingException,
0594: UnknownCRSException {
0595:
0596: boolean queryable = XMLTools.getNodeAsBoolean(layerElem,
0597: "./@queryable", nsContext, false);
0598:
0599: int cascaded = XMLTools.getNodeAsInt(layerElem, "./@cascaded",
0600: nsContext, 0);
0601: boolean opaque = XMLTools.getNodeAsBoolean(layerElem,
0602: "./@opaque", nsContext, false);
0603: boolean noSubsets = XMLTools.getNodeAsBoolean(layerElem,
0604: "./@noSubsets", nsContext, false);
0605: int fixedWidth = XMLTools.getNodeAsInt(layerElem,
0606: "./@fixedWidth", nsContext, 0);
0607: int fixedHeight = XMLTools.getNodeAsInt(layerElem,
0608: "./@fixedHeight", nsContext, 0);
0609: String name = XMLTools.getNodeAsString(layerElem, "./Name",
0610: nsContext, null);
0611: String title = XMLTools.getRequiredNodeAsString(layerElem,
0612: "./Title", nsContext);
0613: String layerAbstract = XMLTools.getNodeAsString(layerElem,
0614: "./Abstract", nsContext, null);
0615: String[] keywords = XMLTools.getNodesAsStrings(layerElem,
0616: "./KeywordList/Keyword", nsContext);
0617: String[] srs = XMLTools.getNodesAsStrings(layerElem, "./SRS",
0618: nsContext);
0619:
0620: List<Element> nl = XMLTools.getElements(layerElem,
0621: "./BoundingBox", nsContext);
0622: // TODO
0623: // substitue with Envelope
0624: LayerBoundingBox[] bboxes = null;
0625: if (nl.size() == 0 && parent != null) {
0626: // inherit BoundingBoxes from parent layer
0627: bboxes = parent.getBoundingBoxes();
0628: } else {
0629: bboxes = parseLayerBoundingBoxes(nl);
0630: }
0631:
0632: Element llBox = XMLTools.getElement(layerElem,
0633: "./LatLonBoundingBox", nsContext);
0634: Envelope llBoundingBox = null;
0635:
0636: if (llBox == null && parent != null) {
0637: // inherit LatLonBoundingBox parent layer
0638: llBoundingBox = parent.getLatLonBoundingBox();
0639: } else if (llBox != null) {
0640: llBoundingBox = parseLatLonBoundingBox(llBox);
0641: } else {
0642: llBoundingBox = GeometryFactory.createEnvelope(-180, -90,
0643: 180, 90, CRSFactory.create("EPSG:4326"));
0644: }
0645:
0646: Dimension[] dimensions = parseDimensions(layerElem);
0647: Extent[] extents = parseExtents(layerElem);
0648:
0649: Attribution attribution = parseAttribution(layerElem);
0650:
0651: AuthorityURL[] authorityURLs = parseAuthorityURLs(layerElem);
0652:
0653: MetadataURL[] metadataURLs = parseMetadataURLs(layerElem);
0654:
0655: DataURL[] dataURLs = parseDataURL(layerElem);
0656:
0657: Identifier[] identifiers = parseIdentifiers(layerElem);
0658:
0659: FeatureListURL[] featureListURLs = parseFeatureListURL(layerElem);
0660:
0661: Style[] styles = parseStyles(layerElem);
0662:
0663: scaleHint = parseScaleHint(layerElem, scaleHint);
0664:
0665: Layer layer = new Layer(queryable, cascaded, opaque, noSubsets,
0666: fixedWidth, fixedHeight, name, title, layerAbstract,
0667: llBoundingBox, attribution, scaleHint, keywords, srs,
0668: bboxes, dimensions, extents, authorityURLs,
0669: identifiers, metadataURLs, dataURLs, featureListURLs,
0670: styles, null, null, parent);
0671:
0672: // get Child layers
0673: nl = XMLTools.getElements(layerElem, "./Layer", nsContext);
0674: Layer[] layers = new Layer[nl.size()];
0675: for (int i = 0; i < layers.length; i++) {
0676: layers[i] = parseLayers(nl.get(i), layer, scaleHint);
0677: }
0678:
0679: // set child layers
0680: layer.setLayer(layers);
0681:
0682: return layer;
0683: }
0684:
0685: /**
0686: *
0687: * @param layerElem
0688: * @return the dimensions
0689: * @throws XMLParsingException
0690: */
0691: protected Dimension[] parseDimensions(Element layerElem)
0692: throws XMLParsingException {
0693:
0694: List<Node> nl = XMLTools.getNodes(layerElem, "./Dimension",
0695: nsContext);
0696: Dimension[] dimensions = new Dimension[nl.size()];
0697: for (int i = 0; i < dimensions.length; i++) {
0698: String name = XMLTools.getNodeAsString(nl.get(i),
0699: "./@name", nsContext, null);
0700: String units = XMLTools.getNodeAsString(nl.get(i),
0701: "./@units", nsContext, null);
0702: String unitSymbol = XMLTools.getNodeAsString(nl.get(i),
0703: "./@unitSymbol", nsContext, null);
0704: dimensions[i] = new Dimension(name, units, unitSymbol);
0705: }
0706:
0707: return dimensions;
0708: }
0709:
0710: /**
0711: *
0712: * @param layerElem
0713: * @return the extent
0714: * @throws XMLParsingException
0715: */
0716: protected Extent[] parseExtents(Element layerElem)
0717: throws XMLParsingException {
0718:
0719: List<Node> nl = XMLTools.getNodes(layerElem, "./Extent",
0720: nsContext);
0721: Extent[] extents = new Extent[nl.size()];
0722: for (int i = 0; i < extents.length; i++) {
0723: String name = XMLTools.getNodeAsString(nl.get(i),
0724: "./@name", nsContext, null);
0725: String deflt = XMLTools.getNodeAsString(nl.get(i),
0726: "./@default", nsContext, null);
0727: boolean nearestValue = XMLTools.getNodeAsBoolean(nl.get(i),
0728: "./@nearestValue", nsContext, false);
0729: String value = XMLTools.getNodeAsString(nl.get(i), ".",
0730: nsContext, "");
0731: extents[i] = new Extent(name, deflt, nearestValue, value);
0732: }
0733:
0734: return extents;
0735: }
0736:
0737: /**
0738: *
0739: * @param layerElem
0740: * @return the attribution
0741: * @throws XMLParsingException
0742: */
0743: protected Attribution parseAttribution(Element layerElem)
0744: throws XMLParsingException {
0745:
0746: Attribution attribution = null;
0747: Node node = XMLTools.getNode(layerElem, "./Attribution",
0748: nsContext);
0749: if (node != null) {
0750: String title = XMLTools.getRequiredNodeAsString(layerElem,
0751: "./Attribution/Title", nsContext);
0752: OnlineResource onLineResource = parseOnLineResource(XMLTools
0753: .getRequiredElement(node, "./OnlineResource",
0754: nsContext));
0755: node = XMLTools.getNode(node, "./LogoURL", nsContext);
0756: LogoURL logoURL = null;
0757: if (node != null) {
0758: int width = XMLTools.getRequiredNodeAsInt(node,
0759: "./@width", nsContext);
0760: int height = XMLTools.getRequiredNodeAsInt(node,
0761: "./@height", nsContext);
0762: String format = XMLTools.getRequiredNodeAsString(node,
0763: "./Format", nsContext);
0764: OnlineResource logoOR = parseOnLineResource(XMLTools
0765: .getRequiredElement(node, "./OnlineResource",
0766: nsContext));
0767: logoURL = new LogoURL(width, height, format, logoOR
0768: .getLinkage().getHref());
0769: }
0770: attribution = new Attribution(title, onLineResource
0771: .getLinkage().getHref(), logoURL);
0772: }
0773:
0774: return attribution;
0775: }
0776:
0777: /**
0778: *
0779: * @param layerElem
0780: * @return the URLs
0781: * @throws XMLParsingException
0782: */
0783: protected AuthorityURL[] parseAuthorityURLs(Element layerElem)
0784: throws XMLParsingException {
0785:
0786: List<Node> nl = XMLTools.getNodes(layerElem, "./AuthorityURL",
0787: nsContext);
0788: AuthorityURL[] authorityURLs = new AuthorityURL[nl.size()];
0789: for (int i = 0; i < authorityURLs.length; i++) {
0790: String name = XMLTools.getRequiredNodeAsString(nl.get(i),
0791: "./@name", nsContext);
0792: Element tmp = XMLTools.getRequiredElement(nl.get(i),
0793: "./OnlineResource", nsContext);
0794: OnlineResource olr = parseOnLineResource(tmp);
0795: authorityURLs[i] = new AuthorityURL(name, olr.getLinkage()
0796: .getHref());
0797: }
0798:
0799: return authorityURLs;
0800: }
0801:
0802: /**
0803: *
0804: * @param layerElem
0805: * @return the URLs
0806: * @throws XMLParsingException
0807: */
0808: protected MetadataURL[] parseMetadataURLs(Element layerElem)
0809: throws XMLParsingException {
0810:
0811: List<Node> nl = XMLTools.getNodes(layerElem, "./MetadataURL",
0812: nsContext);
0813: MetadataURL[] metadataURL = new MetadataURL[nl.size()];
0814: for (int i = 0; i < metadataURL.length; i++) {
0815: String type = XMLTools.getRequiredNodeAsString(nl.get(i),
0816: "./@type", nsContext);
0817: String format = XMLTools.getRequiredNodeAsString(nl.get(i),
0818: "./Format", nsContext);
0819: Element tmp = XMLTools.getRequiredElement(nl.get(i),
0820: "./OnlineResource", nsContext);
0821: OnlineResource olr = parseOnLineResource(tmp);
0822: metadataURL[i] = new MetadataURL(type, format, olr
0823: .getLinkage().getHref());
0824:
0825: }
0826:
0827: return metadataURL;
0828: }
0829:
0830: /**
0831: *
0832: * @param layerElem
0833: * @return the URLs
0834: * @throws XMLParsingException
0835: */
0836: protected DataURL[] parseDataURL(Element layerElem)
0837: throws XMLParsingException {
0838:
0839: List<Node> nl = XMLTools.getNodes(layerElem, "./DataURL",
0840: nsContext);
0841: DataURL[] dataURL = new DataURL[nl.size()];
0842: for (int i = 0; i < dataURL.length; i++) {
0843:
0844: String format = XMLTools.getRequiredNodeAsString(nl.get(i),
0845: "./Format", nsContext);
0846: Element tmp = XMLTools.getRequiredElement(nl.get(i),
0847: "./OnlineResource", nsContext);
0848: OnlineResource olr = parseOnLineResource(tmp);
0849: dataURL[i] = new DataURL(format, olr.getLinkage().getHref());
0850:
0851: }
0852:
0853: return dataURL;
0854: }
0855:
0856: /**
0857: *
0858: * @param layerElem
0859: * @return the URLs
0860: * @throws XMLParsingException
0861: */
0862: protected FeatureListURL[] parseFeatureListURL(Element layerElem)
0863: throws XMLParsingException {
0864:
0865: List<Node> nl = XMLTools.getNodes(layerElem,
0866: "./FeatureListURL", nsContext);
0867: FeatureListURL[] flURL = new FeatureListURL[nl.size()];
0868: for (int i = 0; i < flURL.length; i++) {
0869:
0870: String format = XMLTools.getRequiredNodeAsString(nl.get(i),
0871: "./Format", nsContext);
0872: Element tmp = XMLTools.getRequiredElement(nl.get(i),
0873: "./OnlineResource", nsContext);
0874: OnlineResource olr = parseOnLineResource(tmp);
0875: flURL[i] = new FeatureListURL(format, olr.getLinkage()
0876: .getHref());
0877:
0878: }
0879:
0880: return flURL;
0881: }
0882:
0883: /**
0884: *
0885: * @param layerElem
0886: * @return the styles
0887: * @throws XMLParsingException
0888: */
0889: protected Style[] parseStyles(Element layerElem)
0890: throws XMLParsingException {
0891:
0892: List<Node> nl = XMLTools.getNodes(layerElem, "./Style",
0893: nsContext);
0894: Style[] styles = new Style[nl.size()];
0895: for (int i = 0; i < styles.length; i++) {
0896: String name = XMLTools.getRequiredNodeAsString(nl.get(i),
0897: "./Name", nsContext);
0898:
0899: if (name == null) {
0900: throw new XMLParsingException(Messages
0901: .getMessage("WMS_STYLENAME"));
0902: }
0903: String title = XMLTools.getNodeAsString(nl.get(i),
0904: "./Title", nsContext, null);
0905: if (title == null) {
0906: throw new XMLParsingException(Messages
0907: .getMessage("WMS_STYLETITLE"));
0908: }
0909: String styleAbstract = XMLTools.getNodeAsString(nl.get(i),
0910: "./Abstract", nsContext, null);
0911: LegendURL[] legendURLs = parseLegendURL(nl.get(i));
0912: StyleURL styleURL = parseStyleURL(nl.get(i));
0913: StyleSheetURL styleSheetURL = parseStyleSheetURL(nl.get(i));
0914:
0915: styles[i] = new Style(name, title, styleAbstract,
0916: legendURLs, styleSheetURL, styleURL, null);
0917: }
0918:
0919: return styles;
0920: }
0921:
0922: /**
0923: *
0924: * @param node
0925: * @return the URLs
0926: * @throws XMLParsingException
0927: */
0928: protected LegendURL[] parseLegendURL(Node node)
0929: throws XMLParsingException {
0930:
0931: List<Node> nl = XMLTools.getNodes(node, "./LegendURL",
0932: nsContext);
0933: LegendURL[] lURL = new LegendURL[nl.size()];
0934: for (int i = 0; i < lURL.length; i++) {
0935: int width = XMLTools.getRequiredNodeAsInt(nl.get(i),
0936: "./@width", nsContext);
0937: int height = XMLTools.getRequiredNodeAsInt(nl.get(i),
0938: "./@height", nsContext);
0939: String format = XMLTools.getRequiredNodeAsString(nl.get(i),
0940: "./Format", nsContext);
0941: Element tmp = XMLTools.getRequiredElement(nl.get(i),
0942: "./OnlineResource", nsContext);
0943: OnlineResource olr = parseOnLineResource(tmp);
0944: lURL[i] = new LegendURL(width, height, format, olr
0945: .getLinkage().getHref());
0946:
0947: }
0948:
0949: return lURL;
0950: }
0951:
0952: /**
0953: *
0954: * @param node
0955: * @return the URL
0956: * @throws XMLParsingException
0957: */
0958: protected StyleURL parseStyleURL(Node node)
0959: throws XMLParsingException {
0960:
0961: StyleURL styleURL = null;
0962: Node styleNode = XMLTools
0963: .getNode(node, "./StyleURL", nsContext);
0964:
0965: if (styleNode != null) {
0966: String format = XMLTools.getRequiredNodeAsString(styleNode,
0967: "./Format", nsContext);
0968: Element tmp = XMLTools.getRequiredElement(styleNode,
0969: "./OnlineResource", nsContext);
0970: OnlineResource olr = parseOnLineResource(tmp);
0971: styleURL = new StyleURL(format, olr.getLinkage().getHref());
0972:
0973: }
0974:
0975: return styleURL;
0976: }
0977:
0978: /**
0979: *
0980: * @param node
0981: * @return the URL
0982: * @throws XMLParsingException
0983: */
0984: protected StyleSheetURL parseStyleSheetURL(Node node)
0985: throws XMLParsingException {
0986:
0987: StyleSheetURL styleSheetURL = null;
0988: Node styleNode = XMLTools.getNode(node, "./StyleSheetURL",
0989: nsContext);
0990:
0991: if (styleNode != null) {
0992: String format = XMLTools.getRequiredNodeAsString(styleNode,
0993: "./Format", nsContext);
0994: Element tmp = XMLTools.getRequiredElement(styleNode,
0995: "./OnlineResource", nsContext);
0996: OnlineResource olr = parseOnLineResource(tmp);
0997: styleSheetURL = new StyleSheetURL(format, olr.getLinkage()
0998: .getHref());
0999:
1000: }
1001:
1002: return styleSheetURL;
1003: }
1004:
1005: /**
1006: *
1007: * @param layerElem
1008: * @param scaleHint
1009: * the default scale hint
1010: * @return the scale hint
1011: * @throws XMLParsingException
1012: */
1013: protected ScaleHint parseScaleHint(Element layerElem,
1014: ScaleHint scaleHint) throws XMLParsingException {
1015:
1016: Node scNode = XMLTools.getNode(layerElem, "./ScaleHint",
1017: nsContext);
1018: if (scNode != null) {
1019: double mn = XMLTools.getNodeAsDouble(scNode, "./@min",
1020: nsContext, 0);
1021: double mx = XMLTools.getNodeAsDouble(scNode, "./@max",
1022: nsContext, Double.MAX_VALUE);
1023: scaleHint = new ScaleHint(mn, mx);
1024: }
1025:
1026: if (scaleHint == null) {
1027: // set default value to avoid NullPointerException
1028: // when accessing a layers scalehint
1029: scaleHint = new ScaleHint(0, Double.MAX_VALUE);
1030: }
1031:
1032: return scaleHint;
1033: }
1034:
1035: /**
1036: *
1037: * @param layerElem
1038: * @return the identifiers
1039: * @throws XMLParsingException
1040: */
1041: protected Identifier[] parseIdentifiers(Element layerElem)
1042: throws XMLParsingException {
1043:
1044: List<Node> nl = XMLTools.getNodes(layerElem, "./Identifier",
1045: nsContext);
1046: Identifier[] identifiers = new Identifier[nl.size()];
1047: for (int i = 0; i < identifiers.length; i++) {
1048: String value = XMLTools.getStringValue(nl.get(i));
1049: String authority = XMLTools.getNodeAsString(layerElem,
1050: "./@authority", nsContext, null);
1051: identifiers[i] = new Identifier(value, authority);
1052: }
1053:
1054: return identifiers;
1055: }
1056:
1057: /**
1058: *
1059: * @param nl
1060: * @return the bboxes
1061: * @throws XMLParsingException
1062: */
1063: protected LayerBoundingBox[] parseLayerBoundingBoxes(
1064: List<Element> nl) throws XMLParsingException {
1065:
1066: LayerBoundingBox[] llBoxes = new LayerBoundingBox[nl.size()];
1067: for (int i = 0; i < llBoxes.length; i++) {
1068: double minx = XMLTools.getRequiredNodeAsDouble(nl.get(i),
1069: "./@minx", nsContext);
1070: double maxx = XMLTools.getRequiredNodeAsDouble(nl.get(i),
1071: "./@maxx", nsContext);
1072: double miny = XMLTools.getRequiredNodeAsDouble(nl.get(i),
1073: "./@miny", nsContext);
1074: double maxy = XMLTools.getRequiredNodeAsDouble(nl.get(i),
1075: "./@maxy", nsContext);
1076: double resx = XMLTools.getNodeAsDouble(nl.get(i),
1077: "./@resx", nsContext, -1);
1078: double resy = XMLTools.getNodeAsDouble(nl.get(i),
1079: "./@resx", nsContext, -1);
1080: String srs = XMLTools.getRequiredNodeAsString(nl.get(i),
1081: "./@SRS", nsContext);
1082: Position min = GeometryFactory.createPosition(minx, miny);
1083: Position max = GeometryFactory.createPosition(maxx, maxy);
1084: llBoxes[i] = new LayerBoundingBox(min, max, srs, resx, resy);
1085: }
1086:
1087: return llBoxes;
1088: }
1089:
1090: /**
1091: *
1092: * @param llBox
1093: * @return the envelope
1094: * @throws XMLParsingException
1095: * @throws UnknownCRSException
1096: */
1097: protected Envelope parseLatLonBoundingBox(Element llBox)
1098: throws XMLParsingException, UnknownCRSException {
1099:
1100: double minx = XMLTools.getRequiredNodeAsDouble(llBox,
1101: "./@minx", nsContext);
1102: double maxx = XMLTools.getRequiredNodeAsDouble(llBox,
1103: "./@maxx", nsContext);
1104: double miny = XMLTools.getRequiredNodeAsDouble(llBox,
1105: "./@miny", nsContext);
1106: double maxy = XMLTools.getRequiredNodeAsDouble(llBox,
1107: "./@maxy", nsContext);
1108: CoordinateSystem crs = CRSFactory.create("EPSG:4326");
1109:
1110: Envelope env = GeometryFactory.createEnvelope(minx, miny, maxx,
1111: maxy, crs);
1112:
1113: return env;
1114: }
1115:
1116: }
|