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