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