001 //$HeadURL: svn+ssh://rbezema@svn.wald.intevation.org/deegree/base/branches/2.2_testing/src/org/deegree/ogcwebservices/wms/capabilities/WMSCapabilitiesDocument_1_3_0.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.ogcbase.CommonNamespaces;
080 import org.deegree.ogcwebservices.getcapabilities.InvalidCapabilitiesException;
081 import org.deegree.ogcwebservices.getcapabilities.MetadataURL;
082 import org.deegree.ogcwebservices.getcapabilities.OGCCapabilities;
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_1_3_0</code> is a parser class for capabilities documents
097 * according to the OGC WMS 1.3.0 specification.
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: 9348 $, $Date: 2007-12-27 17:59:14 +0100 (Do, 27 Dez 2007) $
103 *
104 * @since 2.0
105 */
106
107 public class WMSCapabilitiesDocument_1_3_0 extends WMSCapabilitiesDocument {
108
109 private static final long serialVersionUID = -5085466301546020723L;
110
111 private static final String XML_TEMPLATE = "WMSCapabilitiesTemplate_1_3_0.xml";
112
113 private static final ILogger LOG = LoggerFactory.getLogger( WMSCapabilitiesDocument_1_3_0.class );
114
115 private static final String PWMS = CommonNamespaces.WMS_PREFIX + ":";
116
117 private static final String PSLD = CommonNamespaces.SLD_PREFIX + ":";
118
119 /*
120 * Just using a different XML_TEMPLATE.
121 */
122 @Override
123 public void createEmptyDocument()
124 throws IOException, SAXException {
125
126 URL url = WMSCapabilitiesDocument.class.getResource( XML_TEMPLATE );
127 if ( url == null ) {
128 throw new IOException( "The resource '" + XML_TEMPLATE + " could not be found." );
129 }
130 load( url );
131 }
132
133 @Override
134 protected List<String> parseExceptionFormats( Element elem )
135 throws XMLParsingException {
136 String[] formats = XMLTools.getRequiredNodesAsStrings( elem, PWMS + "Format", nsContext );
137 return Arrays.asList( formats );
138 }
139
140 /*
141 * Prefix added, not parsing UserDefinedSymbolization. Parsing new LayerLimit, MaxWidth,
142 * MaxHeight elements.
143 */
144 @Override
145 public OGCCapabilities parseCapabilities()
146 throws InvalidCapabilitiesException {
147 ServiceIdentification serviceIdentification = null;
148 ServiceProvider serviceProvider = null;
149 OperationsMetadata metadata = null;
150 Layer layer = null;
151 String version = parseVersion();
152 String updateSeq = parseUpdateSequence();
153 List<String> exceptions;
154
155 Element root = getRootElement();
156
157 int layerLimit = 0;
158 int maxWidth = 0;
159 int maxHeight = 0;
160
161 try {
162 Element serviceElement = (Element) XMLTools.getRequiredNode( root, PWMS + "Service", nsContext );
163
164 layerLimit = XMLTools.getNodeAsInt( serviceElement, PWMS + "LayerLimit", nsContext, 0 );
165 maxWidth = XMLTools.getNodeAsInt( serviceElement, PWMS + "MaxWidth", nsContext, 0 );
166 maxHeight = XMLTools.getNodeAsInt( serviceElement, PWMS + "MaxHeight", nsContext, 0 );
167
168 serviceIdentification = parseServiceIdentification();
169 serviceProvider = parseServiceProvider();
170 metadata = parseOperationsMetadata();
171
172 Element exceptionElement = XMLTools.getRequiredElement( getRootElement(), PWMS + "Capability/" + PWMS
173 + "Exception", nsContext );
174 exceptions = parseExceptionFormats( exceptionElement );
175
176 Element layerElem = (Element) XMLTools.getRequiredNode( root, PWMS + "Capability/" + PWMS + "Layer",
177 nsContext );
178 layer = parseLayers( layerElem, null, null );
179 } catch ( XMLParsingException e ) {
180 LOG.logError( e.getLocalizedMessage(), e );
181 throw new InvalidCapabilitiesException( e.getMessage() + StringTools.stackTraceToString( e ) );
182 } catch ( Exception e ) {
183 LOG.logError( e.getLocalizedMessage(), e );
184 throw new InvalidCapabilitiesException( e.getMessage() + StringTools.stackTraceToString( e ) );
185 }
186
187 WMSCapabilities_1_3_0 wmsCapabilities = new WMSCapabilities_1_3_0( version, updateSeq, serviceIdentification,
188 serviceProvider, metadata, layer,
189 layerLimit, maxWidth, maxHeight, exceptions );
190 return wmsCapabilities;
191 }
192
193 /*
194 * Prefix added. Name is now "WMS" instead of "OGC:WMS"
195 */
196 @Override
197 protected ServiceIdentification parseServiceIdentification()
198 throws XMLParsingException {
199
200 String name = XMLTools.getNodeAsString( getRootElement(), PWMS + "Service/" + PWMS + "Name", nsContext, null );
201 String title = XMLTools.getNodeAsString( getRootElement(), PWMS + "Service/" + PWMS + "Title", nsContext, name );
202 String serviceAbstract = XMLTools.getNodeAsString( getRootElement(), PWMS + "Service/" + PWMS + "Abstract",
203 nsContext, null );
204
205 String[] kw = XMLTools.getNodesAsStrings( getRootElement(), PWMS + "Service/" + PWMS + "KeywordList/" + PWMS
206 + "Keyword", nsContext );
207
208 Keywords[] keywordArray = new Keywords[] { new Keywords( kw ) };
209 List<Keywords> keywords = Arrays.asList( keywordArray );
210
211 String fees = XMLTools.getNodeAsString( getRootElement(), PWMS + "Service/" + PWMS + "Fees", nsContext, null );
212
213 List<Constraints> accessConstraints = new ArrayList<Constraints>();
214
215 String[] constraints = XMLTools.getNodesAsStrings( getRootElement(), PWMS + "Service/" + PWMS
216 + "AccessConstraints", nsContext );
217
218 for ( String constraint : constraints ) {
219 List<String> limits = new ArrayList<String>();
220 limits.add( constraint );
221 accessConstraints.add( new Constraints( fees, null, null, null, limits, null, null, null ) );
222 }
223
224 List<String> versions = new ArrayList<String>();
225 versions.add( "1.0.0" );
226 versions.add( "1.1.0" );
227 versions.add( "1.1.1" );
228 versions.add( "1.2.0" );
229 versions.add( "1.3.0" );
230
231 ServiceIdentification serviceIdentification = new ServiceIdentification(
232 new Code( "WMS" ),
233 versions,
234 title,
235 null,
236 new Date( System.currentTimeMillis() ),
237 title, serviceAbstract, keywords,
238 accessConstraints );
239
240 return serviceIdentification;
241 }
242
243 /*
244 * Prefix added.
245 */
246 @Override
247 protected ServiceProvider parseServiceProvider()
248 throws XMLParsingException {
249 Node ci = XMLTools.getNode( getRootElement(), PWMS + "Service/" + PWMS + "ContactInformation", nsContext );
250
251 // according to WMS 1.1.1 specification this element is mandatory
252 // but there are several services online which does not contain
253 // this element in its capabilities :-(
254 String s = XMLTools.getNodeAsString( getRootElement(), PWMS + "Service/" + PWMS + "OnlineResource/@xlink:href",
255 nsContext, null );
256
257 OnlineResource providerSite = null;
258
259 if ( s != null ) {
260 try {
261 providerSite = new OnlineResource( new Linkage( new URL( s ) ) );
262 } catch ( MalformedURLException e ) {
263 throw new XMLParsingException( "could not parse service online resource", e );
264 }
265 } else {
266 // use default if no online resource is contained in the
267 // capabilities (see comment above)
268 try {
269 providerSite = new OnlineResource( new Linkage( new URL( "http://www.opengeospatial.org/" ) ) );
270 } catch ( MalformedURLException neverHappens ) {
271 // useless exception
272 }
273 }
274
275 String person = null;
276 String orga = null;
277 String position = null;
278 if ( ci != null ) {
279 person = XMLTools.getNodeAsString( ci, PWMS + "ContactPersonPrimary/" + PWMS + "ContactPerson", nsContext,
280 null );
281 orga = XMLTools.getNodeAsString( ci, PWMS + "ContactPersonPrimary/" + PWMS + "ContactOrganization",
282 nsContext, null );
283 position = XMLTools.getNodeAsString( ci, PWMS + "ContactPosition", nsContext, null );
284 }
285 ContactInfo contact = parseContactInfo();
286
287 CitedResponsibleParty party = new CitedResponsibleParty( new ContactInfo[] { contact },
288 new String[] { person }, new String[] { orga },
289 new String[] { position }, null );
290 ServiceProvider sp = new ServiceProvider( person, providerSite, party );
291
292 return sp;
293 }
294
295 /*
296 * Prefix added.
297 */
298 @Override
299 protected ContactInfo parseContactInfo()
300 throws XMLParsingException {
301 Node ci = XMLTools.getNode( getRootElement(), PWMS + "Service/" + PWMS + "ContactInformation", nsContext );
302 ContactInfo cont = null;
303 if ( ci != null ) {
304 String[] addr = XMLTools.getNodesAsStrings( ci, PWMS + "ContactAddress/" + PWMS + "Address", nsContext );
305 // String addrType =
306 // XMLTools.getNodeAsString( ci, "./ContactAddress/AddressType", nsContext, null );
307 String city = XMLTools.getNodeAsString( ci, PWMS + "ContactAddress/" + PWMS + "City", nsContext, null );
308 String state = XMLTools.getNodeAsString( ci, PWMS + "ContactAddress/" + PWMS + "StateOrProvince",
309 nsContext, null );
310 String pc = XMLTools.getNodeAsString( ci, PWMS + "ContactAddress/" + PWMS + "PostCode", nsContext, null );
311 String country = XMLTools.getNodeAsString( ci, PWMS + "ContactAddress/" + PWMS + "Country", nsContext, null );
312 String[] mail = XMLTools.getNodesAsStrings( ci, PWMS + "ContactElectronicMailAddress", nsContext );
313 Address address = new Address( state, city, country, addr, mail, pc );
314
315 String[] phone = XMLTools.getNodesAsStrings( ci, PWMS + "ContactVoiceTelephone", nsContext );
316 String[] fax = XMLTools.getNodesAsStrings( ci, PWMS + "ContactFacsimileTelephone", nsContext );
317
318 Phone ph = new Phone( fax, phone );
319
320 cont = new ContactInfo( address, null, null, null, ph );
321 }
322
323 return cont;
324 }
325
326 /*
327 * Prefix added.
328 */
329 @Override
330 protected OperationsMetadata parseOperationsMetadata()
331 throws XMLParsingException {
332
333 Node opNode = XMLTools.getNode( getRootElement(), PWMS + "Capability/" + PWMS + "Request/" + PWMS
334 + "GetCapabilities", nsContext );
335
336 if ( opNode == null ) {
337 // may it is a WMS 1.0.0 capabilities document
338 opNode = XMLTools.getRequiredNode( getRootElement(), PWMS + "Capability/" + PWMS + "Request/" + PWMS
339 + "Capabilities", nsContext );
340 }
341 Operation getCapa = parseOperation( opNode );
342
343 opNode = XMLTools.getNode( getRootElement(), PWMS + "Capability/" + PWMS + "Request/" + PWMS + "GetMap",
344 nsContext );
345 if ( opNode == null ) {
346 // may it is a WMS 1.0.0 capabilities document
347 opNode = XMLTools.getRequiredNode( getRootElement(), PWMS + "Capability/" + PWMS + "Request/" + PWMS
348 + "Map", nsContext );
349 }
350 Operation getMap = parseOperation( opNode );
351
352 opNode = XMLTools.getNode( getRootElement(),
353 PWMS + "Capability/" + PWMS + "Request/" + PWMS + "GetFeatureInfo", nsContext );
354 Operation getFI = null;
355 if ( opNode != null ) {
356 getFI = parseOperation( opNode );
357 } else {
358 // maybe its WMS 1.0.0
359 opNode = XMLTools.getNode( getRootElement(), PWMS + "Capability/" + PWMS + "Request/" + PWMS
360 + "FeatureInfo", nsContext );
361 if ( opNode != null ) {
362 getFI = parseOperation( opNode );
363 }
364 }
365
366 opNode = XMLTools.getNode( getRootElement(), PWMS + "Capability/" + PWMS + "Request/" + PSLD
367 + "GetLegendGraphic", nsContext );
368 Operation getLG = null;
369 if ( opNode != null ) {
370 getLG = parseOperation( opNode );
371 }
372
373 opNode = XMLTools.getNode( getRootElement(), PWMS + "Capability/" + PWMS + "Request/" + PSLD + "DescribeLayer",
374 nsContext );
375 Operation descL = null;
376 if ( opNode != null ) {
377 descL = parseOperation( opNode );
378 }
379
380 opNode = XMLTools.getNode( getRootElement(), PWMS + "Capability/" + PWMS + "Request/" + PSLD + "GetStyles",
381 nsContext );
382 Operation getStyles = null;
383 if ( opNode != null ) {
384 getStyles = parseOperation( opNode );
385 }
386
387 opNode = XMLTools.getNode( getRootElement(), PWMS + "Capability/" + PWMS + "Request/" + PSLD + "PutStyles",
388 nsContext );
389 Operation putStyles = null;
390 if ( opNode != null ) {
391 putStyles = parseOperation( opNode );
392 }
393
394 List<Operation> operations = new ArrayList<Operation>();
395
396 StringBuffer debug = new StringBuffer();
397
398 if ( getCapa != null ) {
399 operations.add( getCapa );
400 debug.append( " GetCapabilities" );
401 }
402 if ( getMap != null ) {
403 operations.add( getMap );
404 debug.append( " GetMap" );
405 }
406 if ( getFI != null ) {
407 operations.add( getFI );
408 debug.append( " GetFeatureInfo" );
409 }
410 if ( getLG != null ) {
411 operations.add( getLG );
412 debug.append( " GetLegendGraphic" );
413 }
414 if ( descL != null ) {
415 operations.add( descL );
416 debug.append( " DescribeLayer" );
417 }
418 if ( getStyles != null ) {
419 operations.add( getStyles );
420 debug.append( " GetStyles" );
421 }
422 if ( putStyles != null ) {
423 operations.add( putStyles );
424 debug.append( " PutStyles" );
425 }
426
427 LOG.logDebug( "Configured request types:" + debug );
428
429 OperationsMetadata metadata = new OperationsMetadata( null, null, operations, null );
430
431 return metadata;
432 }
433
434 /*
435 * Prefix added.
436 */
437 @Override
438 protected Operation parseOperation( Node node )
439 throws XMLParsingException {
440 // use node name as name of the Operation to be defined
441 String name = node.getNodeName();
442 if ( name.equals( "Capabilities" ) ) {
443 name = "GetCapabilities";
444 } else if ( name.equals( "Map" ) ) {
445 name = "GetMap";
446 } else if ( name.equals( "FeatureInfo" ) ) {
447 name = "GetFeatureInfo";
448 }
449
450 String[] tmp = XMLTools.getRequiredNodesAsStrings( node, PWMS + "Format", nsContext );
451 List<TypedLiteral> values = new ArrayList<TypedLiteral>();
452
453 URI stringURI = null;
454 try {
455 stringURI = new URI( null, "String", null );
456 } catch ( URISyntaxException e ) {
457 // cannot happen, why do I have to catch this?
458 }
459
460 for ( String str : tmp )
461 values.add( new TypedLiteral( str, stringURI ) );
462
463 DomainType owsDomainType = new DomainType( false, true, null, 0, new QualifiedName( "Format" ), values, null,
464 null, false, null, false, null, null, null, null );
465 List<Parameter> parameters = new ArrayList<Parameter>();
466 parameters.add( owsDomainType );
467
468 List<?> nl = XMLTools.getRequiredNodes( node, PWMS + "DCPType", nsContext );
469 List<DCP> dcps = new ArrayList<DCP>();
470
471 for ( Object element : nl ) {
472 dcps.add( parseDCP( (Element) element ) );
473 }
474
475 return new Operation( new QualifiedName( name ), dcps, parameters, null, null, null );
476 }
477
478 /*
479 * Prefix added.
480 */
481 @Override
482 protected DCP parseDCP( Element element )
483 throws XMLParsingException {
484 List<HTTP.Type> types = new ArrayList<HTTP.Type>();
485 List<OnlineResource> links = new ArrayList<OnlineResource>();
486
487 Element elem = (Element) XMLTools.getRequiredNode( element, PWMS + "HTTP", nsContext );
488 String s = null;
489 try {
490 List<?> nl = XMLTools.getNodes( elem, PWMS + "Get", nsContext );
491
492 for ( int i = 0; i < nl.size(); i++ ) {
493 s = XMLTools.getNodeAsString( (Node) nl.get( i ), "./@xlink:href", nsContext, null );
494 if ( s == null ) {
495 s = XMLTools.getRequiredNodeAsString( (Node) nl.get( i ), PWMS + "OnlineResource/@xlink:href",
496 nsContext );
497 }
498 types.add( HTTP.Type.Get );
499 links.add( new OnlineResource( new Linkage( new URL( s ) ) ) );
500 }
501 } catch ( Exception e ) {
502 throw new XMLParsingException( Messages.getMessage( "WMS_DCPGET", s ) );
503 }
504 try {
505 List<?> nl = XMLTools.getNodes( elem, PWMS + "Post", nsContext );
506
507 for ( int i = 0; i < nl.size(); i++ ) {
508 s = XMLTools.getNodeAsString( (Node) nl.get( i ), "./@xlink:href", nsContext, null );
509 if ( s == null ) {
510 s = XMLTools.getRequiredNodeAsString( (Node) nl.get( i ), PWMS + "OnlineResource/@xlink:href",
511 nsContext );
512 }
513 types.add( HTTP.Type.Post );
514 links.add( new OnlineResource( new Linkage( new URL( s ) ) ) );
515 }
516
517 } catch ( MalformedURLException e ) {
518 throw new XMLParsingException( Messages.getMessage( "WMS_DCPPOST", s ) );
519 }
520 HTTP http = new HTTP( links, null, types );
521
522 return http;
523 }
524
525 /*
526 * Prefix added. Removed parsing of Extent. Removed parsing of ScaleHint. Changed SRS to CRS.
527 */
528 @Override
529 protected Layer parseLayers( Element layerElem, Layer parent, ScaleHint scaleHint )
530 throws XMLParsingException, UnknownCRSException {
531
532 boolean queryable = XMLTools.getNodeAsBoolean( layerElem, "./@queryable", nsContext, false );
533
534 int cascaded = XMLTools.getNodeAsInt( layerElem, "./@cascaded", nsContext, 0 );
535 boolean opaque = XMLTools.getNodeAsBoolean( layerElem, "./@opaque", nsContext, false );
536 boolean noSubsets = XMLTools.getNodeAsBoolean( layerElem, "./@noSubsets", nsContext, false );
537 int fixedWidth = XMLTools.getNodeAsInt( layerElem, "./@fixedWidth", nsContext, 0 );
538 int fixedHeight = XMLTools.getNodeAsInt( layerElem, "./@fixedHeight", nsContext, 0 );
539 String name = XMLTools.getNodeAsString( layerElem, PWMS + "Name", nsContext, null );
540 String title = XMLTools.getRequiredNodeAsString( layerElem, PWMS + "Title", nsContext );
541 String layerAbstract = XMLTools.getNodeAsString( layerElem, PWMS + "Abstract", nsContext, null );
542 String[] keywords = XMLTools.getNodesAsStrings( layerElem, PWMS + "KeywordList/" + PWMS + "Keyword", nsContext );
543 String[] srs = XMLTools.getNodesAsStrings( layerElem, PWMS + "CRS", nsContext );
544
545 List<Element> nl = XMLTools.getElements( layerElem, PWMS + "BoundingBox", nsContext );
546 // TODO
547 // substitue with Envelope
548 LayerBoundingBox[] bboxes = null;
549 if ( nl.size() == 0 && parent != null ) {
550 // inherit BoundingBoxes from parent layer
551 bboxes = parent.getBoundingBoxes();
552 } else {
553 bboxes = parseLayerBoundingBoxes( nl );
554 }
555
556 Element llBox = (Element) XMLTools.getNode( layerElem, PWMS + "EX_GeographicBoundingBox", nsContext );
557 Envelope llBoundingBox = null;
558
559 if ( llBox == null && parent != null ) {
560 // inherit LatLonBoundingBox parent layer
561 llBoundingBox = parent.getLatLonBoundingBox();
562 } else if ( llBox != null ) {
563 llBoundingBox = parseEX_GeographicBoundingBox( llBox );
564 } else {
565 llBoundingBox = GeometryFactory.createEnvelope( -180, -90, 180, 90, CRSFactory.create( "EPSG:4326" ) );
566 }
567
568 Dimension[] dimensions = parseDimensions( layerElem );
569
570 Attribution attribution = parseAttribution( layerElem );
571
572 AuthorityURL[] authorityURLs = parseAuthorityURLs( layerElem );
573
574 MetadataURL[] metadataURLs = parseMetadataURLs( layerElem );
575
576 DataURL[] dataURLs = parseDataURL( layerElem );
577
578 Identifier[] identifiers = parseIdentifiers( layerElem );
579
580 FeatureListURL[] featureListURLs = parseFeatureListURL( layerElem );
581
582 Style[] styles = parseStyles( layerElem );
583
584 scaleHint = parseScaleHint( layerElem, scaleHint );
585
586 Layer layer = new Layer( queryable, cascaded, opaque, noSubsets, fixedWidth, fixedHeight, name, title,
587 layerAbstract, llBoundingBox, attribution, scaleHint, keywords, srs, bboxes,
588 dimensions, null, authorityURLs, identifiers, metadataURLs, dataURLs, featureListURLs,
589 styles, null, null, parent );
590
591 // get Child layers
592 nl = XMLTools.getElements( layerElem, PWMS + "Layer", nsContext );
593 Layer[] layers = new Layer[nl.size()];
594 for ( int i = 0; i < layers.length; i++ ) {
595 layers[i] = parseLayers( nl.get( i ), layer, scaleHint );
596 }
597
598 // set child layers
599 layer.setLayer( layers );
600
601 return layer;
602 }
603
604 /*
605 * Prefix added. Changed to Min/MaxScaleDenominator.
606 */
607 @Override
608 protected ScaleHint parseScaleHint( Element layerElem, ScaleHint scaleHint )
609 throws XMLParsingException {
610
611 Node min = XMLTools.getNode( layerElem, PWMS + "MinScaleDenominator", nsContext );
612 Node max = XMLTools.getNode( layerElem, PWMS + "MaxScaleDenominator", nsContext );
613 if ( min != null ) {
614 double mn = XMLTools.getRequiredNodeAsDouble( min, ".", nsContext );
615 double mx = XMLTools.getRequiredNodeAsDouble( max, ".", nsContext );
616 scaleHint = new ScaleHint( mn, mx );
617 }
618
619 if ( scaleHint == null ) {
620 scaleHint = new ScaleHint( 0, Double.MAX_VALUE );
621 }
622
623 return scaleHint;
624 }
625
626 /*
627 * Prefix added. The following attributes have to be implemented: TODO
628 */
629 // <attribute name="name" type="string" use="required"/>
630 // <attribute name="units" type="string" use="required"/>
631 // <attribute name="unitSymbol" type="string"/>
632 // <attribute name="default" type="string"/>
633 // <attribute name="multipleValues" type="boolean"/>
634 // <attribute name="nearestValue" type="boolean"/>
635 // <attribute name="current" type="boolean"/>
636 @Override
637 protected Dimension[] parseDimensions( Element layerElem )
638 throws XMLParsingException {
639
640 List<?> nl = XMLTools.getNodes( layerElem, PWMS + "Dimension", nsContext );
641 Dimension[] dimensions = new Dimension[nl.size()];
642 for ( int i = 0; i < dimensions.length; i++ ) {
643 String name = XMLTools.getNodeAsString( (Node) nl.get( i ), "./@name", nsContext, null );
644 String units = XMLTools.getNodeAsString( (Node) nl.get( i ), "./@units", nsContext, null );
645 String unitSymbol = XMLTools.getNodeAsString( (Node) nl.get( i ), "./@unitSymbol", nsContext, null );
646 dimensions[i] = new Dimension( name, units, unitSymbol );
647 }
648
649 return dimensions;
650 }
651
652 /*
653 * Prefix added.
654 */
655 @Override
656 protected Attribution parseAttribution( Element layerElem )
657 throws XMLParsingException {
658
659 Attribution attribution = null;
660 Node node = XMLTools.getNode( layerElem, PWMS + "Attribution", nsContext );
661 if ( node != null ) {
662 String title = XMLTools.getRequiredNodeAsString( layerElem, PWMS + "Attribution/" + PWMS + "Title",
663 nsContext );
664 OnlineResource onLineResource = parseOnLineResource( (Element) XMLTools.getRequiredNode(
665 node,
666 PWMS
667 + "OnlineResource",
668 nsContext ) );
669 node = XMLTools.getNode( node, PWMS + "LogoURL", nsContext );
670 LogoURL logoURL = null;
671 if ( node != null ) {
672 int width = XMLTools.getRequiredNodeAsInt( node, "./@width", nsContext );
673 int height = XMLTools.getRequiredNodeAsInt( node, "./@height", nsContext );
674 String format = XMLTools.getRequiredNodeAsString( node, "./Format", nsContext );
675 OnlineResource logoOR = parseOnLineResource( (Element) XMLTools.getRequiredNode(
676 node,
677 PWMS
678 + "OnlineResource",
679 nsContext ) );
680 logoURL = new LogoURL( width, height, format, logoOR.getLinkage().getHref() );
681 }
682 attribution = new Attribution( title, onLineResource.getLinkage().getHref(), logoURL );
683 }
684
685 return attribution;
686 }
687
688 /*
689 * Prefix added.
690 */
691 @Override
692 protected AuthorityURL[] parseAuthorityURLs( Element layerElem )
693 throws XMLParsingException {
694
695 List<?> nl = XMLTools.getNodes( layerElem, PWMS + "AuthorityURL", nsContext );
696 AuthorityURL[] authorityURLs = new AuthorityURL[nl.size()];
697 for ( int i = 0; i < authorityURLs.length; i++ ) {
698 String name = XMLTools.getRequiredNodeAsString( (Node) nl.get( i ), "./@name", nsContext );
699 Element tmp = (Element) XMLTools.getRequiredNode( (Node) nl.get( i ), PWMS + "OnlineResource", nsContext );
700 OnlineResource olr = parseOnLineResource( tmp );
701 authorityURLs[i] = new AuthorityURL( name, olr.getLinkage().getHref() );
702 }
703
704 return authorityURLs;
705 }
706
707 /*
708 * Prefix added.
709 */
710 @Override
711 protected MetadataURL[] parseMetadataURLs( Element layerElem )
712 throws XMLParsingException {
713
714 List<?> nl = XMLTools.getNodes( layerElem, PWMS + "MetadataURL", nsContext );
715 MetadataURL[] metadataURL = new MetadataURL[nl.size()];
716 for ( int i = 0; i < metadataURL.length; i++ ) {
717 String type = XMLTools.getRequiredNodeAsString( (Node) nl.get( i ), "./@type", nsContext );
718 String format = XMLTools.getRequiredNodeAsString( (Node) nl.get( i ), PWMS + "Format", nsContext );
719 Element tmp = (Element) XMLTools.getRequiredNode( (Node) nl.get( i ), PWMS + "OnlineResource", nsContext );
720 OnlineResource olr = parseOnLineResource( tmp );
721 metadataURL[i] = new MetadataURL( type, format, olr.getLinkage().getHref() );
722
723 }
724
725 return metadataURL;
726 }
727
728 /*
729 * Prefix added.
730 */
731 @Override
732 protected DataURL[] parseDataURL( Element layerElem )
733 throws XMLParsingException {
734
735 List<?> nl = XMLTools.getNodes( layerElem, PWMS + "DataURL", nsContext );
736 DataURL[] dataURL = new DataURL[nl.size()];
737 for ( int i = 0; i < dataURL.length; i++ ) {
738
739 String format = XMLTools.getRequiredNodeAsString( (Node) nl.get( i ), PWMS + "Format", nsContext );
740 Element tmp = (Element) XMLTools.getRequiredNode( (Node) nl.get( i ), PWMS + "OnlineResource", nsContext );
741 OnlineResource olr = parseOnLineResource( tmp );
742 dataURL[i] = new DataURL( format, olr.getLinkage().getHref() );
743
744 }
745
746 return dataURL;
747 }
748
749 /*
750 * Prefix added.
751 */
752 @Override
753 protected FeatureListURL[] parseFeatureListURL( Element layerElem )
754 throws XMLParsingException {
755
756 List<?> nl = XMLTools.getNodes( layerElem, PWMS + "FeatureListURL", nsContext );
757 FeatureListURL[] flURL = new FeatureListURL[nl.size()];
758 for ( int i = 0; i < flURL.length; i++ ) {
759
760 String format = XMLTools.getRequiredNodeAsString( (Node) nl.get( i ), "./Format", nsContext );
761 Element tmp = (Element) XMLTools.getRequiredNode( (Node) nl.get( i ), PWMS + "OnlineResource", nsContext );
762 OnlineResource olr = parseOnLineResource( tmp );
763 flURL[i] = new FeatureListURL( format, olr.getLinkage().getHref() );
764
765 }
766
767 return flURL;
768 }
769
770 /*
771 * Prefix added.
772 */
773 @Override
774 protected Style[] parseStyles( Element layerElem )
775 throws XMLParsingException {
776
777 List<?> nl = XMLTools.getNodes( layerElem, PWMS + "Style", nsContext );
778 Style[] styles = new Style[nl.size()];
779 for ( int i = 0; i < styles.length; i++ ) {
780 String name = XMLTools.getRequiredNodeAsString( (Node) nl.get( i ), PWMS + "Name", nsContext );
781
782 if ( name == null ) {
783 throw new XMLParsingException( Messages.getMessage( "WMS_STYLENAME" ) );
784 }
785 String title = XMLTools.getNodeAsString( (Node) nl.get( i ), PWMS + "Title", nsContext, null );
786 if ( title == null ) {
787 throw new XMLParsingException( Messages.getMessage( "WMS_STYLETITLE" ) );
788 }
789 String styleAbstract = XMLTools.getNodeAsString( (Node) nl.get( i ), PWMS + "Abstract", nsContext, null );
790 LegendURL[] legendURLs = parseLegendURL( (Node) nl.get( i ) );
791 StyleURL styleURL = parseStyleURL( (Node) nl.get( i ) );
792 StyleSheetURL styleSheetURL = parseStyleSheetURL( (Node) nl.get( i ) );
793
794 styles[i] = new Style( name, title, styleAbstract, legendURLs, styleSheetURL, styleURL, null );
795 }
796
797 return styles;
798 }
799
800 /*
801 * Prefix added.
802 */
803 @Override
804 protected LegendURL[] parseLegendURL( Node node )
805 throws XMLParsingException {
806
807 List<?> nl = XMLTools.getNodes( node, PWMS + "LegendURL", nsContext );
808 LegendURL[] lURL = new LegendURL[nl.size()];
809 for ( int i = 0; i < lURL.length; i++ ) {
810 int width = XMLTools.getRequiredNodeAsInt( (Node) nl.get( i ), "./@width", nsContext );
811 int height = XMLTools.getRequiredNodeAsInt( (Node) nl.get( i ), "./@height", nsContext );
812 String format = XMLTools.getRequiredNodeAsString( (Node) nl.get( i ), PWMS + "Format", nsContext );
813 Element tmp = (Element) XMLTools.getRequiredNode( (Node) nl.get( i ), PWMS + "OnlineResource", nsContext );
814 OnlineResource olr = parseOnLineResource( tmp );
815 lURL[i] = new LegendURL( width, height, format, olr.getLinkage().getHref() );
816
817 }
818
819 return lURL;
820 }
821
822 /*
823 * Prefix added.
824 */
825 @Override
826 protected StyleURL parseStyleURL( Node node )
827 throws XMLParsingException {
828
829 StyleURL styleURL = null;
830 Node styleNode = XMLTools.getNode( node, PWMS + "StyleURL", nsContext );
831
832 if ( styleNode != null ) {
833 String format = XMLTools.getRequiredNodeAsString( styleNode, PWMS + "Format", nsContext );
834 Element tmp = (Element) XMLTools.getRequiredNode( styleNode, PWMS + "OnlineResource", nsContext );
835 OnlineResource olr = parseOnLineResource( tmp );
836 styleURL = new StyleURL( format, olr.getLinkage().getHref() );
837
838 }
839
840 return styleURL;
841 }
842
843 /*
844 * Prefix added.
845 */
846 @Override
847 protected StyleSheetURL parseStyleSheetURL( Node node )
848 throws XMLParsingException {
849
850 StyleSheetURL styleSheetURL = null;
851 Node styleNode = XMLTools.getNode( node, PWMS + "StyleSheetURL", nsContext );
852
853 if ( styleNode != null ) {
854 String format = XMLTools.getRequiredNodeAsString( styleNode, PWMS + "Format", nsContext );
855 Element tmp = (Element) XMLTools.getRequiredNode( styleNode, PWMS + "OnlineResource", nsContext );
856 OnlineResource olr = parseOnLineResource( tmp );
857 styleSheetURL = new StyleSheetURL( format, olr.getLinkage().getHref() );
858
859 }
860
861 return styleSheetURL;
862 }
863
864 /*
865 * Prefix added.
866 */
867 @Override
868 protected Identifier[] parseIdentifiers( Element layerElem )
869 throws XMLParsingException {
870
871 List<?> nl = XMLTools.getNodes( layerElem, PWMS + "Identifier", nsContext );
872 Identifier[] identifiers = new Identifier[nl.size()];
873 for ( int i = 0; i < identifiers.length; i++ ) {
874 String value = XMLTools.getStringValue( (Node) nl.get( i ) );
875 String authority = XMLTools.getNodeAsString( layerElem, "./@authority", nsContext, null );
876 identifiers[i] = new Identifier( value, authority );
877 }
878
879 return identifiers;
880 }
881
882 /*
883 * Changed SRS to CRS.
884 */
885 @Override
886 protected LayerBoundingBox[] parseLayerBoundingBoxes( List<Element> nl )
887 throws XMLParsingException {
888 LayerBoundingBox[] llBoxes = new LayerBoundingBox[nl.size()];
889 for ( int i = 0; i < llBoxes.length; i++ ) {
890 double minx = XMLTools.getRequiredNodeAsDouble( nl.get( i ), "./@minx", nsContext );
891 double maxx = XMLTools.getRequiredNodeAsDouble( nl.get( i ), "./@maxx", nsContext );
892 double miny = XMLTools.getRequiredNodeAsDouble( nl.get( i ), "./@miny", nsContext );
893 double maxy = XMLTools.getRequiredNodeAsDouble( nl.get( i ), "./@maxy", nsContext );
894 double resx = XMLTools.getNodeAsDouble( nl.get( i ), "./@resx", nsContext, -1 );
895 double resy = XMLTools.getNodeAsDouble( nl.get( i ), "./@resx", nsContext, -1 );
896 String srs = XMLTools.getRequiredNodeAsString( nl.get( i ), "./@CRS", nsContext );
897 if ( srs.startsWith( "EPSG" ) ) {
898 Position min = GeometryFactory.createPosition( miny, minx );
899 Position max = GeometryFactory.createPosition( maxy, maxx );
900 llBoxes[i] = new LayerBoundingBox( min, max, srs, resx, resy );
901 } else {
902 Position min = GeometryFactory.createPosition( minx, miny );
903 Position max = GeometryFactory.createPosition( maxx, maxy );
904 llBoxes[i] = new LayerBoundingBox( min, max, srs, resx, resy );
905 }
906 }
907
908 return llBoxes;
909 }
910
911 /**
912 *
913 * @param llBox
914 * @return the envelope
915 * @throws XMLParsingException
916 * @throws UnknownCRSException
917 */
918 protected Envelope parseEX_GeographicBoundingBox( Element llBox )
919 throws XMLParsingException, UnknownCRSException {
920
921 double minx = XMLTools.getRequiredNodeAsDouble( llBox, PWMS + "westBoundLongitude", nsContext );
922 double maxx = XMLTools.getRequiredNodeAsDouble( llBox, PWMS + "eastBoundLongitude", nsContext );
923 double miny = XMLTools.getRequiredNodeAsDouble( llBox, PWMS + "southBoundLatitude", nsContext );
924 double maxy = XMLTools.getRequiredNodeAsDouble( llBox, PWMS + "northBoundLatitude", nsContext );
925 CoordinateSystem crs = CRSFactory.create( "EPSG:4326" );
926
927 Envelope env = GeometryFactory.createEnvelope( minx, miny, maxx, maxy, crs );
928
929 return env;
930 }
931
932 }