001 // $HeadURL: svn+ssh://jwilden@svn.wald.intevation.org/deegree/base/branches/2.5_testing/src/org/deegree/ogcwebservices/wmps/capabilities/WMPSCapabilitiesDocument.java $
002 /*----------------------------------------------------------------------------
003 This file is part of deegree, http://deegree.org/
004 Copyright (C) 2001-2009 by:
005 Department of Geography, University of Bonn
006 and
007 lat/lon GmbH
008
009 This library is free software; you can redistribute it and/or modify it under
010 the terms of the GNU Lesser General Public License as published by the Free
011 Software Foundation; either version 2.1 of the License, or (at your option)
012 any later version.
013 This library is distributed in the hope that it will be useful, but WITHOUT
014 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
015 FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
016 details.
017 You should have received a copy of the GNU Lesser General Public License
018 along with this library; if not, write to the Free Software Foundation, Inc.,
019 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
020
021 Contact information:
022
023 lat/lon GmbH
024 Aennchenstr. 19, 53177 Bonn
025 Germany
026 http://lat-lon.de/
027
028 Department of Geography, University of Bonn
029 Prof. Dr. Klaus Greve
030 Postfach 1147, 53001 Bonn
031 Germany
032 http://www.geographie.uni-bonn.de/deegree/
033
034 e-mail: info@deegree.org
035 ----------------------------------------------------------------------------*/
036 package org.deegree.ogcwebservices.wmps.capabilities;
037
038 import java.io.IOException;
039 import java.net.MalformedURLException;
040 import java.net.URI;
041 import java.net.URISyntaxException;
042 import java.net.URL;
043 import java.util.List;
044
045 import org.deegree.datatypes.Code;
046 import org.deegree.datatypes.xlink.SimpleLink;
047 import org.deegree.framework.log.ILogger;
048 import org.deegree.framework.log.LoggerFactory;
049 import org.deegree.framework.util.StringTools;
050 import org.deegree.framework.xml.XMLParsingException;
051 import org.deegree.framework.xml.XMLTools;
052 import org.deegree.model.crs.CRSFactory;
053 import org.deegree.model.crs.CoordinateSystem;
054 import org.deegree.model.crs.UnknownCRSException;
055 import org.deegree.model.metadata.iso19115.Address;
056 import org.deegree.model.metadata.iso19115.ContactInfo;
057 import org.deegree.model.metadata.iso19115.Keywords;
058 import org.deegree.model.metadata.iso19115.OnlineResource;
059 import org.deegree.model.metadata.iso19115.Phone;
060 import org.deegree.model.spatialschema.Envelope;
061 import org.deegree.model.spatialschema.GeometryFactory;
062 import org.deegree.model.spatialschema.Position;
063 import org.deegree.ogcbase.CommonNamespaces;
064 import org.deegree.ogcwebservices.getcapabilities.DCPType;
065 import org.deegree.ogcwebservices.getcapabilities.HTTP;
066 import org.deegree.ogcwebservices.getcapabilities.InvalidCapabilitiesException;
067 import org.deegree.ogcwebservices.getcapabilities.MetadataURL;
068 import org.deegree.ogcwebservices.getcapabilities.OGCCapabilities;
069 import org.deegree.ogcwebservices.getcapabilities.Operation;
070 import org.deegree.ogcwebservices.getcapabilities.OperationsMetadata;
071 import org.deegree.ogcwebservices.getcapabilities.Protocol;
072 import org.deegree.ogcwebservices.getcapabilities.ServiceIdentification;
073 import org.deegree.ogcwebservices.getcapabilities.ServiceProvider;
074 import org.deegree.ogcwebservices.wms.capabilities.Attribution;
075 import org.deegree.ogcwebservices.wms.capabilities.AuthorityURL;
076 import org.deegree.ogcwebservices.wms.capabilities.DataURL;
077 import org.deegree.ogcwebservices.wms.capabilities.Dimension;
078 import org.deegree.ogcwebservices.wms.capabilities.Extent;
079 import org.deegree.ogcwebservices.wms.capabilities.FeatureListURL;
080 import org.deegree.ogcwebservices.wms.capabilities.Identifier;
081 import org.deegree.ogcwebservices.wms.capabilities.Layer;
082 import org.deegree.ogcwebservices.wms.capabilities.LayerBoundingBox;
083 import org.deegree.ogcwebservices.wms.capabilities.LegendURL;
084 import org.deegree.ogcwebservices.wms.capabilities.LogoURL;
085 import org.deegree.ogcwebservices.wms.capabilities.ScaleHint;
086 import org.deegree.ogcwebservices.wms.capabilities.Style;
087 import org.deegree.ogcwebservices.wms.capabilities.StyleSheetURL;
088 import org.deegree.ogcwebservices.wms.capabilities.StyleURL;
089 import org.deegree.ogcwebservices.wms.capabilities.UserDefinedSymbolization;
090 import org.deegree.owscommon.OWSCommonCapabilitiesDocument;
091 import org.deegree.owscommon.OWSDomainType;
092 import org.w3c.dom.Element;
093 import org.w3c.dom.Node;
094 import org.xml.sax.SAXException;
095
096 /**
097 * Represents an XML capabilities document for an OGC WFS 1.1.0 compliant web service.
098 *
099 * @author <a href="mailto:deshmukh@lat-lon.de">Anup Deshmukh </a>
100 *
101 * @version 2.0
102 */
103 public class WMPSCapabilitiesDocument extends OWSCommonCapabilitiesDocument {
104
105 private static final long serialVersionUID = -9098679671644329509L;
106
107 private static final ILogger LOG = LoggerFactory.getLogger( WMPSCapabilitiesDocument.class );
108
109 protected static final URI WMPSNS = CommonNamespaces.WMPSNS;
110
111 private static final String XML_TEMPLATE = "WMPSCapabilitiesTemplate.xml";
112
113 /**
114 * Creates a skeleton capabilities document that contains the mandatory elements only.
115 *
116 * @throws IOException
117 * @throws SAXException
118 */
119 public void createEmptyDocument()
120 throws IOException, SAXException {
121 URL url = WMPSCapabilitiesDocument.class.getResource( XML_TEMPLATE );
122 if ( url == null ) {
123 throw new IOException( "The resource '" + XML_TEMPLATE + " could not be found." );
124 }
125 load( url );
126 }
127
128 /**
129 * Creates a class representation of the document.
130 *
131 * @return OGCCapabilities class representation of the configuration document
132 * @throws InvalidCapabilitiesException
133 */
134 @Override
135 public OGCCapabilities parseCapabilities()
136 throws InvalidCapabilitiesException {
137
138
139 LOG.logDebug( "Parsing Capabilties Request." );
140 ServiceIdentification serviceIdentification = null;
141 ServiceProvider serviceProvider = null;
142 UserDefinedSymbolization uds = null;
143 OperationsMetadata metadata = null;
144 Layer layer = null;
145 String version = parseVersion();
146 try {
147 serviceIdentification = parseServiceIdentification();
148 serviceProvider = parseServiceProvider();
149 LOG.logDebug( "Retrieved serviceIdentification and serviceProvider information "
150 + "from the request." );
151 metadata = parseOperationsMetadata();
152 LOG.logDebug( "Retrieved metadData information from the request." );
153 uds = parseUserDefinedSymbolization();
154 Element layerElem = (Element) XMLTools.getRequiredNode( getRootElement(),
155 "./Capability/Layer", nsContext );
156 LOG.logDebug( "Layer Element retrieved." );
157 layer = parseLayers( layerElem, null );
158 } catch ( XMLParsingException e ) {
159 String msg = "Error parsing the capabilities request to retrieve 'serviceIdentification',"
160 + " 'serviceProvider', 'metaData' and 'layer' " + e.getMessage();
161 throw new InvalidCapabilitiesException( msg );
162 } catch (UnknownCRSException e) {
163 throw new InvalidCapabilitiesException( getClass().getName(), e.getMessage() );
164 }
165 WMPSCapabilities wmpsCapabilities = new WMPSCapabilities( version, serviceIdentification,
166 serviceProvider, uds, metadata,
167 layer );
168
169 return wmpsCapabilities;
170 }
171
172 /**
173 * Parse the UserDefinedSymbolization
174 *
175 * @return UserDefinedSymbolization
176 * @throws XMLParsingException
177 */
178 protected UserDefinedSymbolization parseUserDefinedSymbolization()
179 throws XMLParsingException {
180
181
182 String xPath = "./Capability/UserDefinedSymbolization/@SupportSLD";
183 boolean supportSLD = XMLTools.getNodeAsBoolean( getRootElement(), xPath, nsContext, false );
184
185 xPath = "./Capability/UserDefinedSymbolization/@UserLayer";
186 boolean userLayer = XMLTools.getNodeAsBoolean( getRootElement(), xPath, nsContext, false );
187
188 xPath = "./Capability/UserDefinedSymbolization/@UserStyle";
189 boolean userStyle = XMLTools.getNodeAsBoolean( getRootElement(), xPath, nsContext, false );
190
191 xPath = "./Capability/UserDefinedSymbolization/@RemoteWFS";
192 boolean remoteWFS = XMLTools.getNodeAsBoolean( getRootElement(), xPath, nsContext, false );
193
194 UserDefinedSymbolization uds = new UserDefinedSymbolization( supportSLD, userLayer,
195 remoteWFS, userStyle );
196
197
198 return uds;
199 }
200
201 /**
202 * returns the services indentification read from the WMPS capabilities service section
203 *
204 * @return ServiceIdentification
205 * @throws XMLParsingException
206 */
207 protected ServiceIdentification parseServiceIdentification()
208 throws XMLParsingException {
209
210
211 LOG.logDebug( "Parsing service identification parameter." );
212 String name = XMLTools.getNodeAsString( getRootElement(), "./Service/Name", nsContext, null );
213 String title = XMLTools.getNodeAsString( getRootElement(), "./Service/Title", nsContext,
214 name );
215 String serviceAbstract = XMLTools.getNodeAsString( getRootElement(), "./Service/Abstract",
216 nsContext, null );
217
218 String[] kw = XMLTools.getNodesAsStrings( getRootElement(),
219 "./Service/KeywordList/Keyword", nsContext );
220
221 Keywords[] keywords = new Keywords[] { new Keywords( kw ) };
222
223 String fees = XMLTools.getNodeAsString( getRootElement(), "./Service/Fees", nsContext, null );
224
225 String[] accessConstraints = XMLTools.getNodesAsStrings( getRootElement(),
226 "./Service/AccessConstraints",
227 nsContext );
228
229 String[] acceptedVersion = new String[] { "1.0.0" };
230 Code code = new Code( "WMPS" );
231 ServiceIdentification serviceIdentification = new ServiceIdentification( code,
232 acceptedVersion,
233 title,
234 serviceAbstract,
235 keywords, fees,
236 accessConstraints );
237
238 return serviceIdentification;
239 }
240
241 /**
242 * returns WMPS contact informaion encapsulated within a <code>ServiceProvider</code> object
243 *
244 * @return ServiceProvider
245 * @throws XMLParsingException
246 */
247 protected ServiceProvider parseServiceProvider()
248 throws XMLParsingException {
249
250
251 SimpleLink sLink = retrieveOnlineResourceSimpleLink();
252
253 LOG.logDebug( "Parsing service provider parameter." );
254 /**
255 * according to WMPS (draft) specification this element is mandatory but there are several
256 * services online which does not contain this element in its capabilities
257 */
258 Node contactInfo = XMLTools.getRequiredNode( getRootElement(),
259 "./Service/ContactInformation", nsContext );
260
261 String person = XMLTools.getRequiredNodeAsString( contactInfo,
262 "./ContactPersonPrimary/ContactPerson",
263 nsContext );
264 String orga = XMLTools.getRequiredNodeAsString(
265 contactInfo,
266 "./ContactPersonPrimary/ContactOrganization",
267 nsContext );
268 String position = XMLTools.getRequiredNodeAsString( contactInfo, "./ContactPosition",
269 nsContext );
270 ContactInfo contact = parseContactInfo();
271
272 ServiceProvider sp = new ServiceProvider( orga, sLink, person, position, contact, null );
273
274
275
276 return sp;
277 }
278
279 /**
280 * Returns the SimpleLink from the Online Resource node in the Service element.
281 *
282 * @return SimpleLink
283 * @throws XMLParsingException
284 */
285 private SimpleLink retrieveOnlineResourceSimpleLink()
286 throws XMLParsingException {
287
288
289
290 String simpleLink = XMLTools.getNodeAsString( getRootElement(),
291 "./Service/OnlineResource/@xlink:href",
292 nsContext, null );
293 SimpleLink sLink = null;
294 if ( simpleLink != null ) {
295 try {
296 sLink = new SimpleLink( new URI( simpleLink ) );
297 } catch ( URISyntaxException e ) {
298 throw new XMLParsingException( "Error parsing service online resource", e );
299 }
300 } else {
301 try {
302 /**
303 * use default if no online resource is contained in the capabilities (see comment
304 * above)
305 */
306 sLink = new SimpleLink( new URI( "http://www.opengeospatial.org/" ) );
307 } catch ( URISyntaxException neverHappens ) {
308 neverHappens.printStackTrace();
309 }
310 }
311
312 return sLink;
313 }
314
315 /**
316 * Parse Contact Information
317 *
318 * @return ContactInfo
319 * @throws XMLParsingException
320 */
321 protected ContactInfo parseContactInfo()
322 throws XMLParsingException {
323
324
325 LOG.logDebug( "Parsing contact information parameter." );
326 Node contactInfo = XMLTools.getNode( getRootElement(), "./Service/ContactInformation",
327 nsContext );
328 String[] addr = XMLTools.getNodesAsStrings( contactInfo, "./ContactAddress/Address",
329 nsContext );
330 // String addrType = XMLTools.getNodeAsString( contactInfo, "./ContactAddress/AddressType",
331 // nsContext, null );
332 String city = XMLTools.getNodeAsString( contactInfo, "./ContactAddress/City", nsContext,
333 null );
334 String state = XMLTools.getNodeAsString( contactInfo, "./ContactAddress/StateOrProvince",
335 nsContext, null );
336 String pc = XMLTools.getNodeAsString( contactInfo, "./ContactAddress/PostCode", nsContext,
337 null );
338 String country = XMLTools.getNodeAsString( contactInfo, "./ContactAddress/Country",
339 nsContext, null );
340 String[] mail = XMLTools.getNodesAsStrings( contactInfo, "./ContactElectronicMailAddress",
341 nsContext );
342 Address address = new Address( state, city, country, addr, mail, pc );
343
344 String[] phone = XMLTools.getNodesAsStrings( contactInfo, "./ContactVoiceTelephone",
345 nsContext );
346 String[] fax = XMLTools.getNodesAsStrings( contactInfo, "./ContactFacsimileTelephone",
347 nsContext );
348
349 Phone ph = new Phone( fax, phone );
350
351 ContactInfo cont = new ContactInfo( address, null, null, null, ph );
352
353
354 return cont;
355 }
356
357 /**
358 * returns the services capabilitiy read from the WMPS capabilities file
359 *
360 * @return OperationsMetadata
361 * @throws XMLParsingException
362 */
363 protected OperationsMetadata parseOperationsMetadata()
364 throws XMLParsingException {
365
366
367 LOG.logDebug( "Parsing operations metdata parameter." );
368 Node opNode = XMLTools.getNode( getRootElement(), "./Capability/Request/GetCapabilities",
369 nsContext );
370
371 Operation getCapabilities = parseOperation( opNode );
372 LOG.logDebug( "Operation getCapabilities created for the GetCapabilities node." );
373
374 opNode = XMLTools.getRequiredNode( getRootElement(), "./Capability/Request/PrintMap",
375 nsContext );
376
377 Operation printMap = parseOperation( opNode );
378
379 LOG.logDebug( "Operation printMap created for the PrintMap node." );
380
381 WMPSOperationsMetadata metadata = new WMPSOperationsMetadata( getCapabilities, printMap );
382
383
384 return metadata;
385 }
386
387 /**
388 * Creates an <tt>Operation</tt>-instance according to the contents of the DOM-subtree
389 * starting at the given <tt>Node</tt>.
390 * <p>
391 * Notice: operation to be parsed must be operations in sense of WMPS (draft). The method will
392 * return an OWSCommon Operation which encapsulates parsed WMPS operation
393 * <p>
394 *
395 * @param node
396 * the <tt>Element</tt> that describes an <tt>Operation</tt>
397 * @throws XMLParsingException
398 * if a syntactic or semantic error in the DOM-subtree is encountered
399 * @return the constructed <tt>Operation</tt>-instance
400 */
401 protected Operation parseOperation( Node node )
402 throws XMLParsingException {
403
404
405 LOG.logDebug( "Parsing Operation." );
406 // use node name as name of the Operation to be defined
407 String name = node.getNodeName();
408 String[] tmp = XMLTools.getRequiredNodesAsStrings( node, "./Format", nsContext );
409 OWSDomainType owsDomainType = new OWSDomainType( "Format", tmp, null );
410 OWSDomainType[] odt = new OWSDomainType[] { owsDomainType };
411
412 List<Node> nl = XMLTools.getRequiredNodes( node, "./DCPType", nsContext );
413 DCPType[] dcpTypes = new DCPType[nl.size()];
414 for ( int i = 0; i < dcpTypes.length; i++ ) {
415 dcpTypes[i] = getDCP( (Element) nl.get( i ) );
416 }
417 LOG.logDebug( "Creating operation with name, dcpTypes and OWSDomainType." );
418
419 return new Operation( name, dcpTypes, odt );
420 }
421
422 /**
423 * Creates a <code>DCPType</code> object from the passed <code>DCP</code> element.
424 * <p>
425 * NOTE: Currently the <code>OnlineResources</code> included in the <code>DCPType</code> are
426 * just stored as simple <code>URLs</code> (not as <code>OnLineResource</code> instances)!
427 * <p>
428 * NOTE: In an <code>OGCStandardCapabilitiesDocument</code> the <code>XLinks</code> (the
429 * <code>URLs</code>) are stored in separate elements (<code>OnlineResource</code>), in
430 * an <code>OGCCommonCapabilitiesDocument</code> they are the
431 * <code>Get<code>/<code>Post</code> elements themselves.
432 *
433 * @param element
434 *
435 * @return created <code>DCPType</code>
436 * @throws XMLParsingException
437 *
438 * @see org.deegree.ogcwebservices.getcapabilities.OGCStandardCapabilities
439 */
440 @Override
441 protected DCPType getDCP( Element element )
442 throws XMLParsingException {
443
444 DCPType dcpType = null;
445 try {
446 Element elem = (Element) XMLTools.getRequiredNode( element, "HTTP", nsContext );
447 List<Node> nl = XMLTools.getNodes( elem, "Get", nsContext );
448
449 URL[] get = new URL[nl.size()];
450 for ( int i = 0; i < get.length; i++ ) {
451 String s = XMLTools.getNodeAsString( (Node) nl.get( i ), "./@xlink:href",
452 nsContext, null );
453 if ( s == null ) {
454 s = XMLTools.getRequiredNodeAsString( (Node) nl.get( i ),
455 "./OnlineResource/@xlink:href", nsContext );
456 }
457 get[i] = new URL( s );
458 }
459 nl = XMLTools.getNodes( elem, "Post", nsContext );
460
461 URL[] post = new URL[nl.size()];
462 for ( int i = 0; i < post.length; i++ ) {
463 String s = XMLTools.getNodeAsString( (Node) nl.get( i ), "./@xlink:href",
464 nsContext, null );
465 if ( s == null ) {
466 s = XMLTools.getRequiredNodeAsString( (Node) nl.get( i ),
467 "./OnlineResource/@xlink:href", nsContext );
468 }
469 post[i] = new URL( s );
470 }
471 Protocol protocol = new HTTP( get, post );
472 dcpType = new DCPType( protocol );
473 } catch ( MalformedURLException e ) {
474 throw new XMLParsingException( "Couldn't parse DCPType onlineresource URL about: "
475 + StringTools.stackTraceToString( e ) );
476 }
477
478 return dcpType;
479 }
480
481 /**
482 * returns the layers offered by the WMPS
483 *
484 * @param layerElem
485 * @param parent
486 * @return Layer
487 * @throws XMLParsingException
488 * @throws UnknownCRSException
489 */
490 protected Layer parseLayers( Element layerElem, Layer parent )
491 throws XMLParsingException, UnknownCRSException {
492
493
494 boolean queryable = XMLTools.getNodeAsBoolean( layerElem, "./@queryable", nsContext, false );
495
496 int cascaded = XMLTools.getNodeAsInt( layerElem, "./@cascaded", nsContext, 0 );
497 boolean opaque = XMLTools.getNodeAsBoolean( layerElem, "./@opaque", nsContext, false );
498 boolean noSubsets = XMLTools.getNodeAsBoolean( layerElem, "./@noSubsets", nsContext, false );
499 int fixedWidth = XMLTools.getNodeAsInt( layerElem, "./@fixedWidth", nsContext, 0 );
500 int fixedHeight = XMLTools.getNodeAsInt( layerElem, "./@fixedHeight", nsContext, 0 );
501 String name = XMLTools.getNodeAsString( layerElem, "./Name", nsContext, null );
502 String title = XMLTools.getRequiredNodeAsString( layerElem, "./Title", nsContext );
503 String layerAbstract = XMLTools.getNodeAsString( layerElem, "./Abstract", nsContext, null );
504 String[] keywords = XMLTools.getNodesAsStrings( layerElem, "./KeywordList/Keyword",
505 nsContext );
506 String[] srs = XMLTools.getNodesAsStrings( layerElem, "./SRS", nsContext );
507
508 List<Node> nl = XMLTools.getNodes( layerElem, "./BoundingBox", nsContext );
509 // TODO replace with Envelope
510 LayerBoundingBox[] bboxes = null;
511 if ( nl.size() == 0 && parent != null ) {
512 // inherit BoundingBoxes from parent layer
513 bboxes = parent.getBoundingBoxes();
514 } else {
515 bboxes = parseLayerBoundingBoxes( nl );
516 }
517
518 Element llBox = (Element) XMLTools.getNode( layerElem, "./LatLonBoundingBox", nsContext );
519 Envelope llBoundingBox = null;
520
521 if ( llBox == null && parent != null ) {
522 // inherit LatLonBoundingBox parent layer
523 llBoundingBox = parent.getLatLonBoundingBox();
524 } else if ( llBox != null ) {
525 llBoundingBox = parseLatLonBoundingBox( llBox );
526 } else {
527 /** Default crs = EPSG:4326 */
528 CoordinateSystem crs = CRSFactory.create( "EPSG:4326" );
529 llBoundingBox = GeometryFactory.createEnvelope( -180, -90, 180, 90, crs );
530 }
531
532 Dimension[] dimensions = parseDimensions( layerElem );
533
534 Extent[] extents = parseExtents( layerElem );
535
536 Attribution attribution = parseAttribution( layerElem );
537
538 AuthorityURL[] authorityURLs = parseAuthorityURLs( layerElem );
539
540 MetadataURL[] metadataURLs = parseMetadataURLs( layerElem );
541
542 DataURL[] dataURLs = parseDataURL( layerElem );
543
544 Identifier[] identifiers = parseIdentifiers( layerElem );
545
546 FeatureListURL[] featureListURLs = parseFeatureListURL( layerElem );
547
548 Style[] styles = parseStyles( layerElem );
549
550 ScaleHint scaleHint = parseScaleHint( layerElem );
551
552 Layer layer = new Layer( queryable, cascaded, opaque, noSubsets, fixedWidth, fixedHeight,
553 name, title, layerAbstract, llBoundingBox, attribution, scaleHint,
554 keywords, srs, bboxes, dimensions, extents, authorityURLs,
555 identifiers, metadataURLs, dataURLs, featureListURLs, styles,
556 null, null, parent );
557
558 // get Child layers
559 nl = XMLTools.getNodes( layerElem, "./Layer", nsContext );
560 Layer[] layers = new Layer[nl.size()];
561 for ( int i = 0; i < layers.length; i++ ) {
562 layers[i] = parseLayers( (Element) nl.get( i ), layer );
563 }
564
565 // set child layers
566 layer.setLayer( layers );
567
568
569 return layer;
570 }
571
572 /**
573 * Parse Dimensions
574 *
575 * @param layerElem
576 * @return Dimension[]
577 * @throws XMLParsingException
578 */
579 protected Dimension[] parseDimensions( Element layerElem )
580 throws XMLParsingException {
581
582
583 List<Node> nl = XMLTools.getNodes( layerElem, "./Dimension", nsContext );
584 Dimension[] dimensions = new Dimension[nl.size()];
585 for ( int i = 0; i < dimensions.length; i++ ) {
586 String name = XMLTools.getNodeAsString( (Node) nl.get( i ), "./@name", nsContext, null );
587 String units = XMLTools.getNodeAsString( (Node) nl.get( i ), "./@units", nsContext,
588 null );
589 String unitSymbol = XMLTools.getNodeAsString( (Node) nl.get( i ), "./@unitSymbol",
590 nsContext, null );
591 dimensions[i] = new Dimension( name, units, unitSymbol );
592 }
593
594
595 return dimensions;
596 }
597
598 /**
599 * Parse Extents
600 *
601 * @param layerElem
602 * @return Extent[]
603 * @throws XMLParsingException
604 */
605 protected Extent[] parseExtents( Element layerElem )
606 throws XMLParsingException {
607
608
609 List<Node> nl = XMLTools.getNodes( layerElem, "./Extent", nsContext );
610 Extent[] extents = new Extent[nl.size()];
611 for ( int i = 0; i < extents.length; i++ ) {
612 String name = XMLTools.getNodeAsString( (Node) nl.get( i ), "./@name", nsContext, null );
613 String deflt = XMLTools.getNodeAsString( (Node) nl.get( i ), "./@default", nsContext,
614 null );
615 boolean nearestValue = XMLTools.getNodeAsBoolean( (Node) nl.get( i ),
616 "./@nearestValue", nsContext, false );
617 String value = XMLTools.getNodeAsString( (Node) nl.get( i ), ".", nsContext, "" );
618 extents[i] = new Extent( name, deflt, nearestValue, value );
619 }
620
621
622 return extents;
623 }
624
625 /**
626 * Parse Attribution
627 *
628 * @param layerElem
629 * @return Attribution
630 * @throws XMLParsingException
631 */
632 protected Attribution parseAttribution( Element layerElem )
633 throws XMLParsingException {
634
635
636 Attribution attribution = null;
637 Node node = XMLTools.getNode( layerElem, "./Attribution", nsContext );
638 if ( node != null ) {
639 String title = XMLTools.getRequiredNodeAsString( layerElem, "./Attribution/Title",
640 nsContext );
641 Node onlineR = XMLTools.getRequiredNode( node, "./OnlineResource", nsContext );
642 OnlineResource onLineResource = parseOnLineResource( (Element) onlineR );
643 node = XMLTools.getNode( node, "./LogoURL", nsContext );
644 LogoURL logoURL = null;
645 if ( node != null ) {
646 int width = XMLTools.getRequiredNodeAsInt( node, "./@width", nsContext );
647 int height = XMLTools.getRequiredNodeAsInt( node, "./@height", nsContext );
648 String format = XMLTools.getRequiredNodeAsString( node, "./Format", nsContext );
649 onlineR = XMLTools.getRequiredNode( node, "./OnlineResource", nsContext );
650 OnlineResource logoOR = parseOnLineResource( (Element) onlineR );
651 logoURL = new LogoURL( width, height, format, logoOR.getLinkage().getHref() );
652 }
653 attribution = new Attribution( title, onLineResource.getLinkage().getHref(), logoURL );
654 }
655
656
657 return attribution;
658 }
659
660 /**
661 * Parse AuthorityURL
662 *
663 * @param layerElem
664 * @return AuthorityURL[]
665 * @throws XMLParsingException
666 */
667 protected AuthorityURL[] parseAuthorityURLs( Element layerElem )
668 throws XMLParsingException {
669
670
671 List<Node> nl = XMLTools.getNodes( layerElem, "./AuthorityURL", nsContext );
672 AuthorityURL[] authorityURLs = new AuthorityURL[nl.size()];
673 for ( int i = 0; i < authorityURLs.length; i++ ) {
674 String name = XMLTools.getRequiredNodeAsString( (Node) nl.get( i ), "./@name",
675 nsContext );
676 Element tmp = (Element) XMLTools.getRequiredNode( (Node) nl.get( i ),
677 "./OnlineResource", nsContext );
678 OnlineResource olr = parseOnLineResource( tmp );
679 authorityURLs[i] = new AuthorityURL( name, olr.getLinkage().getHref() );
680 }
681
682
683 return authorityURLs;
684 }
685
686 /**
687 * Parse MetadataURL
688 *
689 * @param layerElem
690 * @return MetadataURL[]
691 * @throws XMLParsingException
692 */
693 protected MetadataURL[] parseMetadataURLs( Element layerElem )
694 throws XMLParsingException {
695
696
697 List<Node> nl = XMLTools.getNodes( layerElem, "./MetadataURL", nsContext );
698 MetadataURL[] metadataURL = new MetadataURL[nl.size()];
699 for ( int i = 0; i < metadataURL.length; i++ ) {
700 String type = XMLTools.getRequiredNodeAsString( (Node) nl.get( i ), "./@type",
701 nsContext );
702 String format = XMLTools.getRequiredNodeAsString( (Node) nl.get( i ), "./Format",
703 nsContext );
704 Element tmp = (Element) XMLTools.getRequiredNode( (Node) nl.get( i ),
705 "./OnlineResource", nsContext );
706 OnlineResource olr = parseOnLineResource( tmp );
707 metadataURL[i] = new MetadataURL( type, format, olr.getLinkage().getHref() );
708
709 }
710
711
712 return metadataURL;
713 }
714
715 /**
716 * Parse Data URL
717 *
718 * @param layerElem
719 * @return DataURL[]
720 * @throws XMLParsingException
721 */
722 protected DataURL[] parseDataURL( Element layerElem )
723 throws XMLParsingException {
724
725
726 List<Node> nl = XMLTools.getNodes( layerElem, "./DataURL", nsContext );
727 DataURL[] dataURL = new DataURL[nl.size()];
728 for ( int i = 0; i < dataURL.length; i++ ) {
729
730 String format = XMLTools.getRequiredNodeAsString( (Node) nl.get( i ), "./Format",
731 nsContext );
732 Element tmp = (Element) XMLTools.getRequiredNode( (Node) nl.get( i ),
733 "./OnlineResource", nsContext );
734 OnlineResource olr = parseOnLineResource( tmp );
735 dataURL[i] = new DataURL( format, olr.getLinkage().getHref() );
736
737 }
738
739
740 return dataURL;
741 }
742
743 /**
744 * Parse FeatureListURL
745 *
746 * @param layerElem
747 * @return FeatureListURL[]
748 * @throws XMLParsingException
749 */
750 protected FeatureListURL[] parseFeatureListURL( Element layerElem )
751 throws XMLParsingException {
752
753
754 List<Node> nl = XMLTools.getNodes( layerElem, "./FeatureListURL", nsContext );
755 FeatureListURL[] flURL = new FeatureListURL[nl.size()];
756 for ( int i = 0; i < flURL.length; i++ ) {
757
758 String format = XMLTools.getRequiredNodeAsString( (Node) nl.get( i ), "./Format",
759 nsContext );
760 Element tmp = (Element) XMLTools.getRequiredNode( (Node) nl.get( i ),
761 "./OnlineResource", nsContext );
762 OnlineResource olr = parseOnLineResource( tmp );
763 flURL[i] = new FeatureListURL( format, olr.getLinkage().getHref() );
764
765 }
766
767
768 return flURL;
769 }
770
771 /**
772 * Parse Styles
773 *
774 * @param layerElem
775 * @return Style[]
776 * @throws XMLParsingException
777 */
778 protected Style[] parseStyles( Element layerElem )
779 throws XMLParsingException {
780
781
782 List<Node> nl = XMLTools.getNodes( layerElem, "./Style", nsContext );
783 Style[] styles = new Style[nl.size()];
784 for ( int i = 0; i < styles.length; i++ ) {
785 String name = XMLTools.getRequiredNodeAsString( (Node) nl.get( i ), "./Name", nsContext );
786 String title = XMLTools.getNodeAsString( (Node) nl.get( i ), "./Title", nsContext, null );
787 String styleAbstract = XMLTools.getNodeAsString( (Node) nl.get( i ), "./Abstract",
788 nsContext, null );
789 LegendURL[] legendURLs = parseLegendURL( (Node) nl.get( i ) );
790 StyleURL styleURL = parseStyleURL( (Node) nl.get( i ) );
791 StyleSheetURL styleSheetURL = parseStyleSheetURL( (Node) nl.get( i ) );
792
793 styles[i] = new Style( name, title, styleAbstract, legendURLs, styleSheetURL, styleURL,
794 null );
795 }
796
797
798 return styles;
799 }
800
801 /**
802 * Parse Legend URL
803 *
804 * @param node
805 * @return LegendURL[]
806 * @throws XMLParsingException
807 */
808 protected LegendURL[] parseLegendURL( Node node )
809 throws XMLParsingException {
810
811
812 List<Node> nl = XMLTools.getNodes( node, "./LegendURL", nsContext );
813 LegendURL[] lURL = new LegendURL[nl.size()];
814 for ( int i = 0; i < lURL.length; i++ ) {
815 int width = XMLTools.getRequiredNodeAsInt( (Node) nl.get( i ), "./@width", nsContext );
816 int height = XMLTools.getRequiredNodeAsInt( (Node) nl.get( i ), "./@height", nsContext );
817 String format = XMLTools.getRequiredNodeAsString( (Node) nl.get( i ), "./Format",
818 nsContext );
819 Element tmp = (Element) XMLTools.getRequiredNode( (Node) nl.get( i ),
820 "./OnlineResource", nsContext );
821 OnlineResource olr = parseOnLineResource( tmp );
822 lURL[i] = new LegendURL( width, height, format, olr.getLinkage().getHref() );
823
824 }
825
826
827 return lURL;
828 }
829
830 /**
831 * Parse Style URL
832 *
833 * @param node
834 * @return StyleURL
835 * @throws XMLParsingException
836 */
837 protected StyleURL parseStyleURL( Node node )
838 throws XMLParsingException {
839
840
841 StyleURL styleURL = null;
842 Node styleNode = XMLTools.getNode( node, "./StyleURL", nsContext );
843
844 if ( styleNode != null ) {
845 String format = XMLTools.getRequiredNodeAsString( styleNode, "./Format", nsContext );
846 Element tmp = (Element) XMLTools.getRequiredNode( styleNode, "./OnlineResource",
847 nsContext );
848 OnlineResource olr = parseOnLineResource( tmp );
849 styleURL = new StyleURL( format, olr.getLinkage().getHref() );
850
851 }
852
853
854 return styleURL;
855 }
856
857 /**
858 * Parse Style Sheet URL
859 *
860 * @param node
861 * @return StyleSheetURL
862 * @throws XMLParsingException
863 */
864 protected StyleSheetURL parseStyleSheetURL( Node node )
865 throws XMLParsingException {
866
867
868 StyleSheetURL styleSheetURL = null;
869 Node styleNode = XMLTools.getNode( node, "./StyleSheetURL", nsContext );
870
871 if ( styleNode != null ) {
872 String format = XMLTools.getRequiredNodeAsString( styleNode, "./Format", nsContext );
873 Element tmp = (Element) XMLTools.getRequiredNode( styleNode, "./OnlineResource",
874 nsContext );
875 OnlineResource olr = parseOnLineResource( tmp );
876 styleSheetURL = new StyleSheetURL( format, olr.getLinkage().getHref() );
877
878 }
879
880
881 return styleSheetURL;
882 }
883
884 /**
885 * Parse Scale Hint
886 *
887 * @param layerElem
888 * @return ScaleHint
889 * @throws XMLParsingException
890 */
891 protected ScaleHint parseScaleHint( Element layerElem )
892 throws XMLParsingException {
893
894
895 ScaleHint scaleHint = null;
896
897 Node scNode = XMLTools.getNode( layerElem, "./ScaleHint", nsContext );
898 if ( scNode != null ) {
899 double mn = XMLTools.getNodeAsDouble( scNode, "./@min", nsContext, 0 );
900 double mx = XMLTools.getNodeAsDouble( scNode, "./@max", nsContext, Double.MAX_VALUE );
901 scaleHint = new ScaleHint( mn, mx );
902 } else {
903 // set default value to avoid NullPointerException
904 // when accessing a layers scalehint
905 scaleHint = new ScaleHint( 0, Double.MAX_VALUE );
906 }
907
908
909 return scaleHint;
910 }
911
912 /**
913 * Parse Identifiers
914 *
915 * @param layerElem
916 * @return Identifier[]
917 * @throws XMLParsingException
918 */
919 protected Identifier[] parseIdentifiers( Element layerElem )
920 throws XMLParsingException {
921
922
923 List<Node> nl = XMLTools.getNodes( layerElem, "./Identifier", nsContext );
924 Identifier[] identifiers = new Identifier[nl.size()];
925 for ( int i = 0; i < identifiers.length; i++ ) {
926 String value = XMLTools.getStringValue( (Node) nl.get( i ) );
927 String authority = XMLTools.getNodeAsString( layerElem, "./@authority", nsContext, null );
928 identifiers[i] = new Identifier( value, authority );
929 }
930
931
932 return identifiers;
933 }
934
935 /**
936 * Parse Layer Bounding Boxes
937 *
938 * @param nl
939 * @return LayerBoundingBox[]
940 * @throws XMLParsingException
941 */
942 protected LayerBoundingBox[] parseLayerBoundingBoxes( List<Node> nl )
943 throws XMLParsingException {
944
945 LayerBoundingBox[] llBoxes = new LayerBoundingBox[nl.size()];
946 for ( int i = 0; i < llBoxes.length; i++ ) {
947 double minx = XMLTools.getRequiredNodeAsDouble( (Node) nl.get( i ), "./@minx",
948 nsContext );
949 double maxx = XMLTools.getRequiredNodeAsDouble( (Node) nl.get( i ), "./@maxx",
950 nsContext );
951 double miny = XMLTools.getRequiredNodeAsDouble( (Node) nl.get( i ), "./@miny",
952 nsContext );
953 double maxy = XMLTools.getRequiredNodeAsDouble( (Node) nl.get( i ), "./@maxy",
954 nsContext );
955 double resx = XMLTools.getNodeAsDouble( (Node) nl.get( i ), "./@resx", nsContext, -1 );
956 double resy = XMLTools.getNodeAsDouble( (Node) nl.get( i ), "./@resx", nsContext, -1 );
957 String srs = XMLTools.getRequiredNodeAsString( (Node) nl.get( i ), "./@SRS", nsContext );
958 Position min = GeometryFactory.createPosition( minx, miny );
959 Position max = GeometryFactory.createPosition( maxx, maxy );
960 llBoxes[i] = new LayerBoundingBox( min, max, srs, resx, resy );
961 }
962
963 return llBoxes;
964 }
965
966 /**
967 * Parse Lat Lon Bounding Box
968 *
969 * @param llBox
970 * @return Envelope
971 * @throws XMLParsingException
972 * @throws UnknownCRSException
973 */
974 protected Envelope parseLatLonBoundingBox( Element llBox )
975 throws XMLParsingException, UnknownCRSException {
976
977
978 double minx = XMLTools.getRequiredNodeAsDouble( llBox, "./@minx", nsContext );
979 double maxx = XMLTools.getRequiredNodeAsDouble( llBox, "./@maxx", nsContext );
980 double miny = XMLTools.getRequiredNodeAsDouble( llBox, "./@miny", nsContext );
981 double maxy = XMLTools.getRequiredNodeAsDouble( llBox, "./@maxy", nsContext );
982 /** default crs = EPSG:4326 */
983 CoordinateSystem crs = CRSFactory.create( "EPSG:4326" );
984 Envelope env = GeometryFactory.createEnvelope( minx, miny, maxx, maxy, crs );
985
986
987 return env;
988 }
989
990 }