001 //$HeadURL: svn+ssh://rbezema@svn.wald.intevation.org/deegree/base/tags/2.1/src/org/deegree/ogcwebservices/wpvs/capabilities/WPVSCapabilitiesDocument.java $
002 /*---------------- FILE HEADER ------------------------------------------
003
004 This file is part of deegree.
005 Copyright (C) 2001-2006 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 Aennchenstraße 19
030 53177 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.wpvs.capabilities;
045
046 import java.io.IOException;
047 import java.net.MalformedURLException;
048 import java.net.URI;
049 import java.net.URL;
050 import java.util.ArrayList;
051 import java.util.Arrays;
052 import java.util.HashMap;
053 import java.util.List;
054 import java.util.Map;
055 import java.util.Queue;
056 import java.util.concurrent.LinkedBlockingQueue;
057
058 import org.deegree.datatypes.values.TypedLiteral;
059 import org.deegree.datatypes.values.ValueRange;
060 import org.deegree.datatypes.xlink.SimpleLink;
061 import org.deegree.framework.log.ILogger;
062 import org.deegree.framework.log.LoggerFactory;
063 import org.deegree.framework.util.StringTools;
064 import org.deegree.framework.xml.NamespaceContext;
065 import org.deegree.framework.xml.XMLParsingException;
066 import org.deegree.framework.xml.XMLTools;
067 import org.deegree.i18n.Messages;
068 import org.deegree.model.crs.CRSFactory;
069 import org.deegree.model.crs.CoordinateSystem;
070 import org.deegree.model.crs.UnknownCRSException;
071 import org.deegree.model.metadata.iso19115.Keywords;
072 import org.deegree.model.spatialschema.Envelope;
073 import org.deegree.model.spatialschema.GeometryFactory;
074 import org.deegree.ogcbase.CommonNamespaces;
075 import org.deegree.ogcwebservices.InvalidParameterValueException;
076 import org.deegree.ogcwebservices.MissingParameterValueException;
077 import org.deegree.ogcwebservices.OGCWebServiceException;
078 import org.deegree.ogcwebservices.getcapabilities.DCPType;
079 import org.deegree.ogcwebservices.getcapabilities.InvalidCapabilitiesException;
080 import org.deegree.ogcwebservices.getcapabilities.OGCCapabilities;
081 import org.deegree.ogcwebservices.getcapabilities.OperationsMetadata;
082 import org.deegree.ogcwebservices.getcapabilities.Protocol;
083 import org.deegree.owscommon.OWSCommonCapabilitiesDocument;
084 import org.deegree.owscommon.OWSMetadata;
085 import org.deegree.owscommon.com110.HTTP110;
086 import org.deegree.owscommon.com110.OWSAllowedValues;
087 import org.deegree.owscommon.com110.OWSDomainType110;
088 import org.deegree.owscommon.com110.OWSRequestMethod;
089 import org.deegree.owscommon.com110.Operation110;
090 import org.w3c.dom.Element;
091 import org.w3c.dom.Node;
092 import org.xml.sax.SAXException;
093
094 /**
095 * This class represents a <code>WPVSCapabilitiesDocument</code> object.
096 *
097 * @author <a href="mailto:mays@lat-lon.de">Judit Mays</a>
098 * @author last edited by: $Author: rbezema $
099 *
100 * $Revision: 7949 $, $Date: 2007-08-09 11:56:40 +0200 (Do, 09 Aug 2007) $
101 *
102 */
103 public class WPVSCapabilitiesDocument extends OWSCommonCapabilitiesDocument {
104
105 private ArrayList<String> datasetIdentifiers = new ArrayList<String>();
106
107 private ArrayList<String> styleIdentifiers = new ArrayList<String>();
108
109 /**
110 *
111 */
112 private static final long serialVersionUID = 2633513531080190745L;
113
114 private static final ILogger LOG = LoggerFactory.getLogger( WPVSCapabilitiesDocument.class );
115
116 private static final String XML_TEMPLATE = "WPVSCapabilitiesTemplate.xml";
117
118 private static String PRE_WPVS = CommonNamespaces.WPVS_PREFIX + ":";
119
120 private static String PRE_OWS = CommonNamespaces.OWS_PREFIX + ":";
121
122 /**
123 * Creates a skeleton capabilities document that contains the mandatory elements only.
124 *
125 * @throws IOException
126 * @throws SAXException
127 */
128 public void createEmptyDocument()
129 throws IOException, SAXException {
130 URL url = WPVSCapabilitiesDocument.class.getResource( XML_TEMPLATE );
131 if ( url == null ) {
132 throw new IOException( "The resource '" + XML_TEMPLATE + " could not be found." );
133 }
134 load( url );
135 }
136
137 /**
138 * @see org.deegree.ogcwebservices.getcapabilities.OGCCapabilitiesDocument#parseCapabilities()
139 */
140 @Override
141 public OGCCapabilities parseCapabilities()
142 throws InvalidCapabilitiesException {
143 WPVSCapabilities wpvsCapabilities = null;
144
145 try {
146 wpvsCapabilities = new WPVSCapabilities( parseVersion(), parseUpdateSequence(),
147 getServiceIdentification(),
148 getServiceProvider(),
149 parseOperationsMetadata(), null, getDataset() );
150
151 } catch ( XMLParsingException e ) {
152 throw new InvalidCapabilitiesException( e.getMessage() + "\n"
153 + StringTools.stackTraceToString( e ) );
154
155 } catch ( MissingParameterValueException e ) {
156 throw new InvalidCapabilitiesException( e.getMessage() + "\n"
157 + StringTools.stackTraceToString( e ) );
158
159 } catch ( InvalidParameterValueException e ) {
160 throw new InvalidCapabilitiesException( e.getMessage() + "\n"
161 + StringTools.stackTraceToString( e ) );
162
163 } catch ( OGCWebServiceException e ) {
164 throw new InvalidCapabilitiesException( e.getMessage() + "\n"
165 + StringTools.stackTraceToString( e ) );
166 }
167
168 return wpvsCapabilities;
169 }
170
171 /**
172 * Gets the <code>Dataset</code> object from the root element of the WPVSCapabilities element.
173 *
174 *
175 * @return Returns the Dataset object form root element.
176 * @throws XMLParsingException
177 * @throws OGCWebServiceException
178 * @throws InvalidParameterValueException
179 * @throws MissingParameterValueException
180 */
181 private Dataset getDataset()
182 throws XMLParsingException, MissingParameterValueException,
183 InvalidParameterValueException, OGCWebServiceException {
184
185 Element datasetElement = (Element) XMLTools.getRequiredNode( getRootElement(), PRE_WPVS
186 + "Dataset",
187 nsContext );
188 Dataset dataset = parseDataset( datasetElement, null, null, null );
189
190 return dataset;
191 }
192
193 /**
194 * Creates and returns a new <code>Dataset</code> object from the given <code>Element</code>
195 * and the parent <code>Dataset</code> object.
196 *
197 * @param datasetElement
198 * @param parent
199 * may be null if root node
200 * @param defaultCoordinateSystem
201 * @param defaultElevationModel
202 * @return Returns a new Dataset object.
203 * @throws XMLParsingException
204 * @throws OGCWebServiceException
205 * @throws InvalidParameterValueException
206 */
207 private Dataset parseDataset( Element datasetElement, Dataset parent,
208 CoordinateSystem defaultCoordinateSystem,
209 ElevationModel defaultElevationModel )
210 throws XMLParsingException, InvalidParameterValueException,
211 OGCWebServiceException {
212
213 // attributes are all optional
214 boolean queryable = XMLTools.getNodeAsBoolean( datasetElement, "@queryable", nsContext,
215 false );
216 boolean opaque = XMLTools.getNodeAsBoolean( datasetElement, "@opaque", nsContext, false );
217 boolean noSubsets = XMLTools.getNodeAsBoolean( datasetElement, "@noSubsets", nsContext,
218 false );
219 int fixedWidth = XMLTools.getNodeAsInt( datasetElement, "@fixedWidth", nsContext, 0 );
220 int fixedHeight = XMLTools.getNodeAsInt( datasetElement, "@fixedHeight", nsContext, 0 );
221
222 // elements
223 String name = XMLTools.getNodeAsString( datasetElement, PRE_WPVS + "Name/text()",
224 nsContext, null );
225 String title = XMLTools.getRequiredNodeAsString( datasetElement, PRE_WPVS + "Title/text()",
226 nsContext );
227 String abstract_ = XMLTools.getNodeAsString( datasetElement, PRE_WPVS + "Abstract/text()",
228 nsContext, null );
229 // keywords == optional
230 Keywords[] keywords = getKeywords( XMLTools.getNodes( datasetElement, PRE_OWS + "Keywords",
231 nsContext ) );
232 // crsstrings == optional
233 String[] crsStrings = XMLTools.getNodesAsStrings( datasetElement, PRE_WPVS + "CRS/text()",
234 nsContext );
235 List<CoordinateSystem> crsList = parseCoordinateSystems( crsStrings );
236 ElevationModel elevationModel = parseElevationModel( datasetElement, defaultElevationModel );
237 // create a default ElevationModel if not exists allready, a little HACK to circumvent the
238 // optional deegree:dataset:ElevationModel mapping onto the mandatory
239 // ogc:dataset:ElevationModel
240 if ( defaultElevationModel == null && elevationModel != null ) {
241 defaultElevationModel = elevationModel;
242 // found an ElevationModel setting it to default
243 // and update the parents of this dataset, until we have the root,
244
245 if ( parent != null ) {
246 // first find root parent
247 Dataset tmpParent = parent;
248 while ( tmpParent.getParent() != null ) {
249 tmpParent = tmpParent.getParent();
250 }
251 // now iterate over all so far created children to set an default elevationmodel
252 tmpParent.setElevationModel( defaultElevationModel );
253 Queue<Dataset> children = new LinkedBlockingQueue<Dataset>(
254 Arrays.asList( tmpParent.getDatasets() ) );
255 while ( !children.isEmpty() ) {
256 Dataset child = children.poll();
257 if ( child != null ) {
258 child.setElevationModel( defaultElevationModel );
259 for ( Dataset dataset : child.getDatasets() ) {
260 children.offer( dataset );
261 }
262 }
263 }
264 }
265 }
266 // now find a defaultcoordinatesystem to use if no crs is given in a child dataset
267 if ( parent == null ) { // root dataset
268 if ( crsList.size() == 0 || crsList.get( 0 ) == null ) {
269 throw new InvalidCapabilitiesException(
270 Messages.getMessage(
271 "WPVS_NO_TOPLEVEL_DATASET_CRS",
272 title ) );
273 }
274 defaultCoordinateSystem = crsList.get( 0 );
275 }
276
277 String[] format = XMLTools.getRequiredNodesAsStrings( datasetElement, PRE_WPVS
278 + "Format/text()",
279 nsContext );
280 // wgs84 == mandatory
281 Element boundingBoxElement = (Element) XMLTools.getRequiredNode(
282 datasetElement,
283 PRE_OWS
284 + "WGS84BoundingBox",
285 nsContext );
286 Envelope wgs84BoundingBox = getWGS84BoundingBoxType( boundingBoxElement );
287
288 // boundingboxes can be used to make a more precise specification of the useable area of
289 // this dataset in it's native crs's, the wgs84 bbox can be inaccurate
290 Envelope[] boundingBoxes = getBoundingBoxes( datasetElement, defaultCoordinateSystem );
291
292 // optional
293 Dimension[] dimensions = parseDimensions( datasetElement );
294
295 // optional
296 DataProvider dataProvider = parseDataProvider( datasetElement );
297
298 // mandatory
299 Identifier identifier = parseDatasetIdentifier( datasetElement, PRE_WPVS + "Identifier" );
300
301 // optional
302 MetaData[] metaData = parseMetaData( datasetElement );
303
304 // optional
305 DatasetReference[] datasetRefs = parseDatasetReferences( datasetElement );
306
307 // optional
308 FeatureListReference[] featureListRefs = parseFeatureListReferences( datasetElement );
309
310 // optional
311 Style[] style = parseStyles( datasetElement );
312
313 // mandatory
314 double minScaleDenom = XMLTools.getRequiredNodeAsDouble(
315 datasetElement,
316 PRE_WPVS
317 + "MinimumScaleDenominator/text()",
318 nsContext );
319 // mandatory
320 double maxScaleDenom = XMLTools.getRequiredNodeAsDouble(
321 datasetElement,
322 PRE_WPVS
323 + "MaximumScaleDenominator/text()",
324 nsContext );
325
326 if ( minScaleDenom > maxScaleDenom ) {
327 throw new InvalidCapabilitiesException(
328 Messages.getMessage( "WPVS_WRONG_SCALE_DENOMINATORS" ) );
329 }
330
331 // create new root dataset
332 Dataset dataset = new Dataset( queryable, opaque, noSubsets, fixedWidth, fixedHeight, name,
333 title, abstract_, keywords, crsList, format,
334 wgs84BoundingBox, boundingBoxes, dimensions, dataProvider,
335 identifier, metaData, datasetRefs, featureListRefs, style,
336 minScaleDenom, maxScaleDenom, null, elevationModel, null,
337 parent );
338
339 // get child datasets
340 List nl = XMLTools.getNodes( datasetElement, PRE_WPVS + "Dataset", nsContext );
341 Dataset[] childDatasets = new Dataset[nl.size()];
342 for ( int i = 0; i < childDatasets.length; i++ ) {
343 childDatasets[i] = parseDataset( (Element) nl.get( i ), dataset,
344 defaultCoordinateSystem, defaultElevationModel );
345 }
346
347 // set child datasets
348 dataset.setDatasets( childDatasets );
349
350 return dataset;
351 }
352
353 /**
354 * @param coordinateStrings
355 * the Strings to create the coordinates from
356 * @return a List of coordinatesystems, if no coordinateString were given (null || length==0 )
357 * an emtpy list is returned.
358 */
359 protected List<CoordinateSystem> parseCoordinateSystems( String[] coordinateStrings ) {
360 if ( coordinateStrings == null )
361 return new ArrayList<CoordinateSystem>();
362 ArrayList<CoordinateSystem> crsList = new ArrayList<CoordinateSystem>(
363 coordinateStrings.length );
364 for ( String tmpCRS : coordinateStrings ) {
365 try {
366 CoordinateSystem crs = CRSFactory.create( tmpCRS );
367 crsList.add( crs );
368 } catch ( UnknownCRSException e ) {
369 // fail configuration notify the user
370 LOG.logError( e.getLocalizedMessage(), e );
371 }
372 }
373 return crsList;
374 }
375
376 /**
377 * Creates and returns a new <code>ElevationModel</code> object from the given
378 * <code>Element</code>.
379 *
380 * This OGC ElevationModel contains only a String. ATTENTION ogc elevation model is mandatory,
381 * we IGNORE this and say it's mandatory.
382 *
383 * @param datasetElement
384 * @param defaultElevationModel
385 * the defaultElevationModel will be used if no elevationmodel was defined in this
386 * dataset(for example the topdatasets dgm-name)
387 * @return Returns the ElevationModel object or <code>null</code> if none defined (optional)
388 * @throws XMLParsingException
389 * @throws InvalidCapabilitiesException
390 */
391 private ElevationModel parseElevationModel( Element datasetElement,
392 ElevationModel defaultElevationModel )
393 throws XMLParsingException {
394 // ATTENTION ogc elevation model is mandatory, we IGNORE it for the capabilities.
395 String name = XMLTools.getNodeAsString( datasetElement, PRE_WPVS + "ElevationModel/text()",
396 nsContext, null );
397 if ( name == null ) {
398 if ( defaultElevationModel == null ) {
399 return null;
400 }
401 return defaultElevationModel;
402 }
403 ElevationModel elevationModel = new ElevationModel( name );
404
405 return elevationModel;
406 }
407
408 /**
409 * Creates and returns a new array of <code>Style</code> objects from the given
410 * <code>Element</code>.
411 *
412 * @param datasetElement
413 * @return Returns a new array of Style objects or <code>null</code> if none were defined
414 * @throws XMLParsingException
415 * @throws InvalidCapabilitiesException
416 */
417 protected Style[] parseStyles( Element datasetElement )
418 throws XMLParsingException, InvalidCapabilitiesException {
419
420 List styleList = XMLTools.getNodes( datasetElement, PRE_WPVS + "Style", nsContext );
421 // optional therefore return null if not present
422 if ( styleList.size() == 0 ) {
423 return null;
424 }
425
426 Style[] styles = new Style[styleList.size()];
427
428 for ( int i = 0; i < styles.length; i++ ) {
429
430 Element styleElement = (Element) styleList.get( i );
431
432 String name = XMLTools.getRequiredNodeAsString( styleElement, PRE_WPVS + "Name/text()",
433 nsContext );
434 String title = XMLTools.getRequiredNodeAsString( styleElement, PRE_WPVS
435 + "Title/text()",
436 nsContext );
437 String abstract_ = XMLTools.getRequiredNodeAsString( styleElement, PRE_WPVS
438 + "Abstract/text()",
439 nsContext );
440 // optional
441 Keywords[] keywords = getKeywords( XMLTools.getNodes( styleElement, PRE_OWS
442 + "Keywords",
443 nsContext ) );
444 // mandatory
445 Identifier identifier = parseStyleIdentifier( styleElement, PRE_WPVS + "Identifier" );
446
447 // optional
448 LegendURL[] legendURLs = parseLegendURLs( styleElement );
449
450 // optional
451 StyleSheetURL styleSheetURL = parseStyleSheetURL( styleElement );
452 StyleURL styleURL = parseStyleURL( styleElement );
453
454 styles[i] = new Style( name, title, abstract_, keywords, identifier, legendURLs,
455 styleSheetURL, styleURL );
456 }
457
458 return styles;
459 }
460
461 /**
462 * Creates and returns a new <code>StyleURL</code> object from the given <code>Element</code>.
463 *
464 * @param styleElement
465 * @return Returns a new StyleURL object or <code>null</code> if not defined (optional)
466 * @throws XMLParsingException
467 * @throws InvalidCapabilitiesException
468 */
469 private StyleURL parseStyleURL( Element styleElement )
470 throws XMLParsingException, InvalidCapabilitiesException {
471
472 Element styleURLElement = (Element) XMLTools.getNode( styleElement, PRE_WPVS + "StyleURL",
473 nsContext );
474 if ( styleURLElement == null ) {
475 return null;
476 }
477 String format = XMLTools.getRequiredNodeAsString( styleURLElement, PRE_WPVS
478 + "Format/text()",
479 nsContext );
480
481 // optional
482 URI onlineResourceURI = XMLTools.getNodeAsURI( styleURLElement,
483 PRE_WPVS + "OnlineResource/@xlink:href",
484 nsContext, null );
485 URL onlineResource = null;
486 if ( onlineResourceURI != null ) {
487 try {
488 onlineResource = onlineResourceURI.toURL();
489 } catch ( MalformedURLException e ) {
490 throw new InvalidCapabilitiesException( onlineResourceURI
491 + " does not represent a valid URL: "
492 + e.getMessage() );
493 }
494 }
495 return new StyleURL( format, onlineResource );
496 }
497
498 /**
499 * Creates and returns a new <code>StyleSheetURL</code> object from the given
500 * <code>Element</code>.
501 *
502 * @param styleElement
503 * @return Returns a new StyleSheetURL object or <code>null</code> if no stylSheetURL was given
504 * (optional)
505 * @throws XMLParsingException
506 * @throws InvalidCapabilitiesException
507 */
508 private StyleSheetURL parseStyleSheetURL( Element styleElement )
509 throws XMLParsingException, InvalidCapabilitiesException {
510
511 Element styleSheetURLElement = (Element) XMLTools.getNode( styleElement, PRE_WPVS
512 + "StyleSheetURL",
513 nsContext );
514 if ( styleSheetURLElement == null ) {
515 return null;
516 }
517 String format = XMLTools.getRequiredNodeAsString( styleSheetURLElement, PRE_WPVS
518 + "Format/text()",
519 nsContext );
520
521 // optional onlineResource
522 URI onlineResourceURI = XMLTools.getNodeAsURI( styleSheetURLElement,
523 PRE_WPVS + "OnlineResource/@xlink:href",
524 nsContext, null );
525 URL onlineResource = null;
526 if ( onlineResourceURI != null ) {
527 try {
528 onlineResource = onlineResourceURI.toURL();
529 } catch ( MalformedURLException e ) {
530 throw new InvalidCapabilitiesException( onlineResourceURI
531 + " does not represent a valid URL: "
532 + e.getMessage() );
533 }
534 }
535
536 return new StyleSheetURL( format, onlineResource );
537 }
538
539 /**
540 * Creates and returns a new array of <code>LegendURL</code> objects from the given
541 * <code>Element</code>.
542 *
543 * @param styleElement
544 * @return Returns a new array of LegendURL objects or <code>null</code> if none were defined
545 * (optional).
546 * @throws XMLParsingException
547 * @throws InvalidCapabilitiesException
548 */
549 private LegendURL[] parseLegendURLs( Element styleElement )
550 throws XMLParsingException, InvalidCapabilitiesException {
551
552 List legendList = XMLTools.getNodes( styleElement, PRE_WPVS + "LegendURL", nsContext );
553 if ( legendList.size() == 0 ) {
554 return null;
555 }
556
557 LegendURL[] legendURLs = new LegendURL[legendList.size()];
558
559 for ( int i = 0; i < legendURLs.length; i++ ) {
560
561 Element legendURLElement = (Element) legendList.get( i );
562
563 int width = XMLTools.getRequiredNodeAsInt( legendURLElement, "@width", nsContext );
564 int height = XMLTools.getRequiredNodeAsInt( legendURLElement, "@height", nsContext );
565 if ( width < 0 || height < 0 ) {
566 throw new InvalidCapabilitiesException( "The attributes width and height of '"
567 + legendURLElement.getNodeName()
568 + "' must be positive!" );
569 }
570
571 String format = XMLTools.getRequiredNodeAsString( legendURLElement, PRE_WPVS
572 + "Format/text()",
573 nsContext );
574 // optional
575 URI onlineResourceURI = XMLTools.getNodeAsURI( legendURLElement,
576 PRE_WPVS + "OnlineResource/@xlink:href",
577 nsContext, null );
578
579 URL onlineResource = null;
580 if ( onlineResourceURI != null ) {
581 try {
582 onlineResource = onlineResourceURI.toURL();
583 } catch ( MalformedURLException e ) {
584 throw new InvalidCapabilitiesException( onlineResourceURI
585 + " does not represent a valid URL: "
586 + e.getMessage() );
587 }
588 }
589
590 legendURLs[i] = new LegendURL( width, height, format, onlineResource );
591 }
592 return legendURLs;
593 }
594
595 /**
596 * Creates and returns a new array of <code>FeatureListReference</code> objects from the given
597 * <code>Element</code>.
598 *
599 * @param datasetElement
600 * @return Returns an array of FeatureListReference instances or <code>null</code> if none were
601 * defined (optional).
602 * @throws XMLParsingException
603 * @throws InvalidCapabilitiesException
604 */
605 protected FeatureListReference[] parseFeatureListReferences( Element datasetElement )
606 throws XMLParsingException, InvalidCapabilitiesException {
607
608 List featureList = XMLTools.getNodes( datasetElement, PRE_WPVS + "FeatureListReference",
609 nsContext );
610 if ( featureList.size() == 0 ) {
611 return null;
612 }
613 FeatureListReference[] featureRefs = new FeatureListReference[featureList.size()];
614 for ( int i = 0; i < featureRefs.length; i++ ) {
615
616 Element featureRefElement = (Element) featureList.get( i );
617
618 String format = XMLTools.getRequiredNodeAsString( featureRefElement, PRE_WPVS
619 + "Format/text()",
620 nsContext );
621
622 URI onlineResourceURI = XMLTools.getNodeAsURI( featureRefElement,
623 PRE_WPVS + "OnlineResource/@xlink:href",
624 nsContext, null );
625 URL onlineResource = null;
626 if ( onlineResourceURI != null ) {
627 try {
628 onlineResource = onlineResourceURI.toURL();
629 } catch ( MalformedURLException e ) {
630 throw new InvalidCapabilitiesException( onlineResourceURI
631 + " does not represent a valid URL: "
632 + e.getMessage() );
633 }
634 }
635 featureRefs[i] = new FeatureListReference( format, onlineResource );
636 }
637 return featureRefs;
638 }
639
640 /**
641 * Creates and returns a new array of <code>DatasetReference</code> objects from the given
642 * <code>Element</code>.
643 *
644 * @param datasetElement
645 * @return Returns a new array of DatasetReference objects or <code>null</code> if no
646 * DatasetReferences are specified in this dataset (optional)
647 * @throws XMLParsingException
648 * @throws InvalidCapabilitiesException
649 */
650 protected DatasetReference[] parseDatasetReferences( Element datasetElement )
651 throws XMLParsingException, InvalidCapabilitiesException {
652
653 List datasetRefList = XMLTools.getNodes( datasetElement, PRE_WPVS + "DatasetReference",
654 nsContext );
655 if ( datasetRefList == null ) {
656 return null;
657 }
658 DatasetReference[] datasetRefs = new DatasetReference[datasetRefList.size()];
659
660 for ( int i = 0; i < datasetRefs.length; i++ ) {
661
662 Element datasetRefElement = (Element) datasetRefList.get( i );
663
664 String format = XMLTools.getRequiredNodeAsString( datasetRefElement, PRE_WPVS
665 + "Format/text()",
666 nsContext );
667
668 URI onlineResourceURI = XMLTools.getNodeAsURI( datasetRefElement,
669 PRE_WPVS + "OnlineResource/@xlink:href",
670 nsContext, null );
671 URL onlineResource = null;
672 if ( onlineResourceURI != null ) {
673 try {
674 onlineResource = onlineResourceURI.toURL();
675 } catch ( MalformedURLException e ) {
676 throw new InvalidCapabilitiesException( onlineResourceURI
677 + " does not represent a valid URL: "
678 + e.getMessage() );
679 }
680 }
681 datasetRefs[i] = new DatasetReference( format, onlineResource );
682 }
683
684 return datasetRefs;
685 }
686
687 /**
688 * Creates and returns a new <code>MetaData</code> object from the given <code>Element</code>.
689 *
690 * @param datasetElement
691 * @return Returns an array of MetaData objects, or <code>null</code> if no metadata was specified
692 * in the dataset (optional).
693 * @throws XMLParsingException
694 * @throws InvalidCapabilitiesException
695 */
696 protected MetaData[] parseMetaData( Element datasetElement )
697 throws XMLParsingException, InvalidCapabilitiesException {
698
699 List metaDataList = XMLTools.getNodes( datasetElement, PRE_WPVS + "MetaData", nsContext );
700 if ( metaDataList.size() == 0 ) {
701 return null;
702 }
703 MetaData[] metaData = new MetaData[metaDataList.size()];
704
705 for ( int i = 0; i < metaData.length; i++ ) {
706
707 Element metaDataElement = (Element) metaDataList.get( i );
708
709 String type = XMLTools.getRequiredNodeAsString( metaDataElement, "@type", nsContext );
710
711 String format = XMLTools.getRequiredNodeAsString( metaDataElement, PRE_WPVS
712 + "Format/text()",
713 nsContext );
714 URI onlineResourceURI = XMLTools.getNodeAsURI( metaDataElement,
715 PRE_WPVS + "OnlineResource/@xlink:href",
716 nsContext, null );
717 URL onlineResource = null;
718 if ( onlineResourceURI != null ) {
719 try {
720 onlineResource = onlineResourceURI.toURL();
721 } catch ( MalformedURLException e ) {
722 throw new InvalidCapabilitiesException( onlineResourceURI
723 + " does not represent a valid URL: "
724 + e.getMessage() );
725 }
726 }
727
728 metaData[i] = new MetaData( type, format, onlineResource );
729 }
730
731 return metaData;
732 }
733
734 /**
735 * Creates and returns a new <code>Identifier</code> object from the given
736 * <code>Element</code> and the given <cod>xPathQuery</code>.
737 *
738 * @param element
739 * @param xPathQuery
740 * @return Returns a new Identifier object.
741 * @throws XMLParsingException
742 * @throws InvalidCapabilitiesException
743 * if no (valid) identifier is found
744 */
745 protected Identifier parseStyleIdentifier( Element element, String xPathQuery )
746 throws XMLParsingException, InvalidCapabilitiesException {
747
748 Element identifierElement = (Element) XMLTools.getRequiredNode( element, xPathQuery,
749 nsContext );
750
751 String value = XMLTools.getStringValue( identifierElement ).trim();
752 if ( "".equals( value ) ) {
753 throw new InvalidCapabilitiesException(
754 Messages.getMessage(
755 "WPVS_NO_VALID_IDENTIFIER",
756 "style" ) );
757 }
758 URI codeSpace = XMLTools.getNodeAsURI( identifierElement, "@codeSpace", nsContext, null );
759
760 Identifier id = new Identifier( value, codeSpace );
761 if ( styleIdentifiers.contains( id.toString() ) ) {
762 throw new InvalidCapabilitiesException(
763 Messages.getMessage(
764 "WPVS_NO_UNIQUE_IDENTIFIER",
765 "styles", id.toString() ) );
766
767 }
768 styleIdentifiers.add( id.toString() );
769 return id;
770 }
771
772 /**
773 * Creates and returns a new <code>Identifier</code> object from the given
774 * <code>Element</code> and the given <cod>xPathQuery</code>.
775 *
776 * @param element
777 * @param xPathQuery
778 * @return Returns a new Identifier object.
779 * @throws XMLParsingException
780 * @throws InvalidCapabilitiesException
781 * if no (valid) identifier is found
782 */
783 protected Identifier parseDatasetIdentifier( Element element, String xPathQuery )
784 throws XMLParsingException, InvalidCapabilitiesException {
785
786 Element identifierElement = (Element) XMLTools.getRequiredNode( element, xPathQuery,
787 nsContext );
788
789 String value = XMLTools.getStringValue( identifierElement ).trim();
790 if ( "".equals( value ) ) {
791 throw new InvalidCapabilitiesException(
792 Messages.getMessage(
793 "WPVS_NO_VALID_IDENTIFIER",
794 "dataset" ) );
795 }
796 URI codeSpace = XMLTools.getNodeAsURI( identifierElement, "@codeSpace", nsContext, null );
797 Identifier id = new Identifier( value, codeSpace );
798 if ( datasetIdentifiers.contains( id.toString() ) ) {
799 throw new InvalidCapabilitiesException(
800 Messages.getMessage(
801 "WPVS_NO_UNIQUE_IDENTIFIER",
802 "datasets", id.toString() ) );
803
804 }
805 datasetIdentifiers.add( id.toString() );
806
807 return id;
808 }
809
810 /**
811 * Creates and returns a new <code>DataProvider</code> object from the given
812 * <code>Element</code>.
813 *
814 * @param datasetElement
815 * @return Returns a new DataProvider object or <code>null</code>if no provider was defined.
816 * @throws XMLParsingException
817 * @throws InvalidCapabilitiesException
818 */
819 protected DataProvider parseDataProvider( Element datasetElement )
820 throws XMLParsingException, InvalidCapabilitiesException {
821
822 String providerName = null;
823 URL providerSite = null;
824 LogoURL logoURL = null;
825
826 Element dataProviderElement = (Element) XMLTools.getNode( datasetElement, PRE_WPVS
827 + "DataProvider",
828 nsContext );
829 if ( dataProviderElement == null )
830 return null;
831
832 providerName = XMLTools.getNodeAsString( dataProviderElement, PRE_WPVS
833 + "ProviderName/text()",
834 nsContext, null );
835 URI providerSiteURI = XMLTools.getNodeAsURI( dataProviderElement,
836 PRE_WPVS + "ProviderSite/@xlink:href",
837 nsContext, null );
838 if ( providerSiteURI != null ) {
839 try {
840 providerSite = providerSiteURI.toURL();
841 } catch ( MalformedURLException e ) {
842 throw new InvalidCapabilitiesException( providerSiteURI
843 + " does not represent a valid URL: "
844 + e.getMessage() );
845 }
846 }
847
848 Node logoURLElement = XMLTools.getNode( dataProviderElement, PRE_WPVS + "LogoURL",
849 nsContext );
850 if ( logoURLElement != null ) {
851
852 int width = XMLTools.getRequiredNodeAsInt( logoURLElement, "@width", nsContext );
853 int height = XMLTools.getRequiredNodeAsInt( logoURLElement, "@height", nsContext );
854 if ( width < 0 || height < 0 ) {
855 throw new InvalidCapabilitiesException( "width and height of '" + logoURLElement
856 + "' must be positive!" );
857 }
858
859 String format = XMLTools.getRequiredNodeAsString( logoURLElement, PRE_WPVS
860 + "Format/text()",
861 nsContext );
862
863 URI onlineResourceURI = XMLTools.getNodeAsURI( logoURLElement,
864 PRE_WPVS + "OnlineResource/@xlink:href",
865 nsContext, null );
866 URL onlineResource = null;
867 if ( onlineResourceURI != null ) {
868 try {
869 onlineResource = onlineResourceURI.toURL();
870 } catch ( MalformedURLException e ) {
871 throw new InvalidCapabilitiesException( onlineResourceURI
872 + " does not represent a valid URL: "
873 + e.getMessage() );
874 }
875 }
876
877 logoURL = new LogoURL( width, height, format, onlineResource );
878 }
879 return new DataProvider( providerName, providerSite, logoURL );
880 }
881
882 /**
883 *
884 * @param element
885 * @return the Dimensions of a given element or <code>null</code> if no dimension is found
886 * (optional).
887 * @throws XMLParsingException
888 */
889 protected Dimension[] parseDimensions( Element element )
890 throws XMLParsingException {
891
892 List nl = XMLTools.getNodes( element, PRE_WPVS + "Dimension", nsContext );
893 if ( nl.size() == 0 ) {
894 return null;
895 }
896 Dimension[] dimensions = new Dimension[nl.size()];
897
898 for ( int i = 0; i < dimensions.length; i++ ) {
899
900 String name = XMLTools.getRequiredNodeAsString( (Node) nl.get( i ), "@name", nsContext );
901 String units = XMLTools.getRequiredNodeAsString( (Node) nl.get( i ), "@units",
902 nsContext );
903 String unitSymbol = XMLTools.getNodeAsString( (Node) nl.get( i ), "@unitSymbol",
904 nsContext, null );
905 String default_ = XMLTools.getNodeAsString( (Node) nl.get( i ), "@default", nsContext,
906 null );
907 Boolean multipleValues = Boolean.valueOf( XMLTools.getNodeAsBoolean(
908 (Node) nl.get( i ),
909 "@multipleValues",
910 nsContext, true ) );
911 Boolean nearestValues = Boolean.valueOf( XMLTools.getNodeAsBoolean( (Node) nl.get( i ),
912 "@nearestValues",
913 nsContext, true ) );
914 Boolean current = Boolean.valueOf( XMLTools.getNodeAsBoolean( (Node) nl.get( i ),
915 "@current", nsContext,
916 true ) );
917 String value = XMLTools.getNodeAsString( (Node) nl.get( i ), ".", nsContext, null );
918
919 dimensions[i] = new Dimension( name, units, unitSymbol, default_, multipleValues,
920 nearestValues, current, value );
921 }
922
923 return dimensions;
924 }
925
926 /**
927 * Gets an array of <code>boundingBoxes</code> from the given <code>Element</code>. This
928 * method returns all boundingBoxes together in one array.
929 *
930 * @param element
931 * @param defaultCoordinateSystem
932 * to be used for not defined coordinate system attribute in the bbox element
933 * @return Returns an array of boundingBoxes.
934 * @throws XMLParsingException
935 * @throws InvalidParameterValueException
936 */
937 protected Envelope[] getBoundingBoxes( Element element, CoordinateSystem defaultCoordinateSystem )
938 throws XMLParsingException, InvalidParameterValueException {
939
940 List boundingBoxList = XMLTools.getNodes( element, PRE_OWS + "BoundingBox", nsContext );
941
942 List<Envelope> bboxesList = new ArrayList<Envelope>( boundingBoxList.size() );
943
944 for ( int i = 0; i < boundingBoxList.size(); i++ ) {
945 bboxesList.add( parseBoundingBox( (Element) boundingBoxList.get( i ),
946 defaultCoordinateSystem ) );
947 }
948
949 // The ogc_wpvs schema says: wgs84 is mandatory therefore-> not checking parents to use it's
950 // bboxes.
951
952 // if ( parent != null ) {
953 // Envelope[] boundingBoxes = parent.getBoundingBoxes();
954 // for ( int i = 0; i < boundingBoxes.length; i++ ) {
955 // bboxesList.add( boundingBoxes[i] );
956 // }
957 // }
958
959 Envelope[] boxes = bboxesList.toArray( new Envelope[bboxesList.size()] );
960 return boxes;
961 }
962
963 /**
964 * Usable with any BoundingBox. Changed crs from null to given attribute value of crs. Added
965 * check for min values to be smaler than max values.
966 *
967 * Creates an <code>Envelope</code> object from the given element of type
968 * <code>ows:WGS84BoundingBox</code> or <code>ows:BoundingBox</code>.
969 *
970 * @param element
971 * @param defaultCoordinateSystem
972 * if the crs-attribute of the bbox element is not defined
973 * @return a boundingbox of a dataset
974 * @throws XMLParsingException
975 * @throws InvalidParameterValueException
976 */
977 protected Envelope parseBoundingBox( Element element, CoordinateSystem defaultCoordinateSystem )
978 throws XMLParsingException, InvalidParameterValueException {
979
980 // Envelope env = getWGS84BoundingBoxType( element );
981
982 String crsAtt = element.getAttribute( "crs" );
983 System.out.println( "------------------------------crsAtt: " + crsAtt );
984 CoordinateSystem crs = null;
985 if ( crsAtt == null ) {
986 crs = defaultCoordinateSystem;
987 } else {
988 try {
989 crs = CRSFactory.create( crsAtt );
990 } catch ( UnknownCRSException e ) {
991 throw new InvalidParameterValueException( e.getMessage() );
992 }
993 }
994
995 double[] lowerCorner = XMLTools.getRequiredNodeAsDoubles( element, PRE_OWS
996 + "LowerCorner/text()",
997 nsContext, " " );
998 if ( lowerCorner.length < 2 ) {
999 throw new XMLParsingException( Messages.getMessage( "WPVS_NO_VALID_BBOX_POINT",
1000 PRE_OWS + "LowerCorner" ) );
1001 }
1002 double[] upperCorner = XMLTools.getRequiredNodeAsDoubles( element, PRE_OWS
1003 + "UpperCorner/text()",
1004 nsContext, " " );
1005 if ( upperCorner.length < 2 ) {
1006 throw new XMLParsingException( Messages.getMessage( "WPVS_NO_VALID_BBOX_POINT",
1007 PRE_OWS + "UpperCorner" ) );
1008 }
1009 if ( upperCorner.length != lowerCorner.length ) {
1010 throw new XMLParsingException( Messages.getMessage( "WPVS_DIFFERENT_BBOX_DIMENSIONS",
1011 PRE_OWS + "LowerCorner",
1012 PRE_OWS + "UpperCorner" ) );
1013 }
1014
1015 for ( int i = 0; i < upperCorner.length; ++i ) {
1016 if ( lowerCorner[i] >= upperCorner[i] ) {
1017 throw new InvalidParameterValueException(
1018 Messages.getMessage(
1019 "WPVS_WRONG_BBOX_POINT_POSITIONS",
1020 new Integer( i ),
1021 new Double(
1022 lowerCorner[i] ),
1023 PRE_OWS
1024 + "LowerCorner",
1025 new Double(
1026 upperCorner[i] ),
1027 PRE_OWS
1028 + "UpperCorner" ) );
1029
1030 }
1031 }
1032
1033 return GeometryFactory.createEnvelope( lowerCorner[0], lowerCorner[1], upperCorner[0],
1034 upperCorner[1], crs );
1035
1036 }
1037
1038 /**
1039 * Creates and returns a new <code>OperationsMetadata</code> object.
1040 *
1041 * @return Returns a new OperationsMetadata object.
1042 * @throws XMLParsingException
1043 * @throws InvalidCapabilitiesException
1044 */
1045 protected OperationsMetadata parseOperationsMetadata()
1046 throws XMLParsingException, InvalidCapabilitiesException {
1047
1048 Node operationMetadata = XMLTools.getRequiredNode( getRootElement(),
1049 PRE_OWS + "OperationsMetadata",
1050 nsContext );
1051 List operationElementList = XMLTools.getNodes( operationMetadata, PRE_OWS + "Operation",
1052 nsContext );
1053
1054 Map<String, Element> operations = new HashMap<String, Element>();
1055 for ( int i = 0; i < operationElementList.size(); i++ ) {
1056 operations.put( XMLTools.getRequiredNodeAsString( (Node) operationElementList.get( i ),
1057 "@name", nsContext ),
1058 (Element) operationElementList.get( i ) );
1059 }
1060
1061 Operation110 getCapabilities = getOperation110( OperationsMetadata.GET_CAPABILITIES_NAME,
1062 true, operations );
1063 Operation110 getView = getOperation110( WPVSOperationsMetadata.GET_VIEW_NAME, true,
1064 operations );
1065 Operation110 getDescription = getOperation110( WPVSOperationsMetadata.GET_DESCRIPTION_NAME,
1066 false, operations );
1067
1068 Operation110 get3DFeatureInfo = getOperation110( WPVSOperationsMetadata.GET_3D_FEATURE_INFO,
1069 false, operations );
1070
1071 Operation110 getLegendGraphics = getOperation110( WPVSOperationsMetadata.GET_LEGEND_GRAPHIC_NAME,
1072 false, operations );
1073
1074 List parameterElementList = XMLTools.getNodes( operationMetadata, PRE_OWS + "Parameter",
1075 nsContext );
1076 OWSDomainType110[] parameters = new OWSDomainType110[parameterElementList.size()];
1077 for ( int i = 0; i < parameters.length; i++ ) {
1078 parameters[i] = getOWSDomainType110( (Element) parameterElementList.get( i ) );
1079 }
1080
1081 List constraintElementList = XMLTools.getNodes( operationMetadata, PRE_OWS + "Constraint",
1082 nsContext );
1083 OWSDomainType110[] constraints = new OWSDomainType110[constraintElementList.size()];
1084 for ( int i = 0; i < constraints.length; i++ ) {
1085 constraints[i] = getOWSDomainType110( (Element) constraintElementList.get( i ) );
1086 }
1087
1088 List extendedCapsList = XMLTools.getNodes( operationMetadata, PRE_OWS
1089 + "ExtendedCapabilities",
1090 nsContext );
1091 Object[] extendedCapabilities = new Object[extendedCapsList.size()];
1092 for ( int i = 0; i < extendedCapabilities.length; i++ ) {
1093 extendedCapabilities[i] = extendedCapsList.get( i );
1094 }
1095
1096 WPVSOperationsMetadata metadata = new WPVSOperationsMetadata( getCapabilities, getView,
1097 getDescription,
1098 getLegendGraphics,
1099 parameters, constraints,
1100 extendedCapabilities, get3DFeatureInfo );
1101
1102 return metadata;
1103 }
1104
1105 /**
1106 * FIXME needs to be handled, when OWSDomainType110 ceases to exist.
1107 *
1108 * @see org.deegree.owscommon.OWSCommonCapabilitiesDocument#getOperation()
1109 *
1110 * @param name
1111 * @param isMandatory
1112 * @param operations
1113 * @return the Operation110 with the given name from the map
1114 * @throws XMLParsingException
1115 * @throws InvalidCapabilitiesException
1116 */
1117 private Operation110 getOperation110( String name, boolean isMandatory,
1118 Map<String, Element> operations )
1119 throws XMLParsingException, InvalidCapabilitiesException {
1120
1121 Operation110 operation = null;
1122 Element operationElement = operations.get( name );
1123 if ( operationElement == null ) {
1124 if ( isMandatory ) {
1125 throw new XMLParsingException( "Mandatory operation '" + name + "' not defined in "
1126 + "'OperationsMetadata'-section." );
1127 }
1128 } else {
1129 // 'ows:DCP' - elements
1130 DCPType[] dcps = getDCPs( XMLTools.getRequiredNodes( operationElement, PRE_OWS + "DCP",
1131 nsContext ) );
1132
1133 // 'Parameter' - elements
1134 List parameterList = XMLTools.getNodes( operationElement, PRE_OWS + "Parameter",
1135 nsContext );
1136 OWSDomainType110[] parameters = new OWSDomainType110[parameterList.size()];
1137 for ( int i = 0; i < parameters.length; i++ ) {
1138 parameters[i] = getOWSDomainType110( (Element) parameterList.get( i ) );
1139 }
1140 // 'Constraint' - elements
1141 List constraintList = XMLTools.getNodes( operationElement, PRE_OWS + "Constraint",
1142 nsContext );
1143 OWSDomainType110[] constraints = new OWSDomainType110[constraintList.size()];
1144 for ( int i = 0; i < constraintList.size(); i++ ) {
1145 constraints[i] = getOWSDomainType110( (Element) constraintList.get( i ) );
1146 }
1147 // 'ows:Metadata' - element
1148 List metadataList = XMLTools.getNodes( operationElement, PRE_OWS + "Metadata",
1149 nsContext );
1150 OWSMetadata[] metadata = new OWSMetadata[metadataList.size()];
1151 for ( int i = 0; i < metadata.length; i++ ) {
1152 metadata[i] = getOWSMetadata( operationElement, PRE_OWS + "Metadata", nsContext );
1153 }
1154
1155 // return new Operation110 object
1156 operation = new Operation110( name, dcps, parameters, constraints, metadata );
1157 }
1158
1159 return operation;
1160 }
1161
1162 /**
1163 * FIXME there is a similar method in
1164 * org.deegree.owscommon.OWSCommonCapabilitiesDocument#getDCP. overrides that method!
1165 *
1166 * Creates a <code>DCPType</code> object from the passed <code>DCP</code> element.
1167 *
1168 * @param element
1169 * @return created <code>DCPType</code>
1170 * @throws XMLParsingException
1171 * @see org.deegree.ogcwebservices.getcapabilities.OGCStandardCapabilities
1172 */
1173 @Override
1174 protected DCPType getDCP( Element element )
1175 throws XMLParsingException {
1176 DCPType dcpType = null;
1177 Element httpElement = (Element) XMLTools.getRequiredNode( element, PRE_OWS + "HTTP",
1178 nsContext );
1179
1180 try {
1181 List requestList = XMLTools.getNodes( httpElement, PRE_OWS + "Get", nsContext );
1182 OWSRequestMethod[] getRequests = new OWSRequestMethod[requestList.size()];
1183 for ( int i = 0; i < getRequests.length; i++ ) {
1184
1185 List constraintList = XMLTools.getNodes( (Node) requestList.get( i ),
1186 PRE_OWS + "Constraint", nsContext );
1187 OWSDomainType110[] constraint = new OWSDomainType110[constraintList.size()];
1188 for ( int j = 0; j < constraint.length; j++ ) {
1189 constraint[j] = getOWSDomainType110( (Element) constraintList.get( i ) );
1190 }
1191
1192 SimpleLink link = parseSimpleLink( (Element) requestList.get( i ) );
1193
1194 getRequests[i] = new OWSRequestMethod( link, constraint );
1195 }
1196
1197 requestList = XMLTools.getNodes( httpElement, PRE_OWS + "Post", nsContext );
1198 OWSRequestMethod[] postRequests = new OWSRequestMethod[requestList.size()];
1199 for ( int i = 0; i < postRequests.length; i++ ) {
1200
1201 List constraintList = XMLTools.getNodes( (Node) requestList.get( i ),
1202 PRE_OWS + "Constraint", nsContext );
1203 OWSDomainType110[] constraint = new OWSDomainType110[constraintList.size()];
1204 for ( int j = 0; j < constraint.length; j++ ) {
1205 constraint[j] = getOWSDomainType110( (Element) constraintList.get( i ) );
1206 }
1207
1208 SimpleLink link = parseSimpleLink( (Element) requestList.get( i ) );
1209
1210 postRequests[i] = new OWSRequestMethod( link, constraint );
1211 }
1212
1213 Protocol protocol = new HTTP110( getRequests, postRequests );
1214 dcpType = new DCPType( protocol );
1215
1216 } catch ( InvalidCapabilitiesException e ) {
1217 throw new XMLParsingException( "Couldn't parse the OWSDomainType110 within DCPType: "
1218 + StringTools.stackTraceToString( e ) );
1219 }
1220
1221 return dcpType;
1222 }
1223
1224 /**
1225 * FIXME needs to be handled, when OWSDomainType110 ceases to exist.
1226 *
1227 * @see org.deegree.owscommon.OWSCommonCapabilitiesDocument#getOWSDomainType()
1228 *
1229 * @param element
1230 * @return Returns owsDomainType110 object.
1231 * @throws InvalidCapabilitiesException
1232 */
1233 private OWSDomainType110 getOWSDomainType110( Element element )
1234 throws XMLParsingException, InvalidCapabilitiesException {
1235
1236 // 'name' - attribute
1237 String name = XMLTools.getRequiredNodeAsString( element, "@name", nsContext );
1238
1239 // 'ows:AllowedValues' - element
1240 Element allowedElement = (Element) XMLTools.getNode( element, PRE_OWS + "AllowedValues",
1241 nsContext );
1242 OWSAllowedValues allowedValues = null;
1243 if ( allowedElement != null ) {
1244
1245 // 'ows:Value' - elements
1246 String[] values = XMLTools.getNodesAsStrings( allowedElement, PRE_OWS + "Value/text()",
1247 nsContext );
1248 TypedLiteral[] literals = null;
1249 if ( values != null ) {
1250 literals = new TypedLiteral[values.length];
1251 for ( int i = 0; i < literals.length; i++ ) {
1252 literals[i] = new TypedLiteral( values[i], null );
1253 }
1254 }
1255
1256 // 'ows:Range' - elements
1257 List rangeList = XMLTools.getNodes( allowedElement, PRE_OWS + "Range", nsContext );
1258 ValueRange[] ranges = new ValueRange[rangeList.size()];
1259 for ( int i = 0; i < ranges.length; i++ ) {
1260 String minimum = XMLTools.getNodeAsString( (Node) rangeList.get( i ),
1261 PRE_OWS + "MinimumValue", nsContext,
1262 null );
1263 String maximum = XMLTools.getNodeAsString( (Node) rangeList.get( i ),
1264 PRE_OWS + "MaximumValue", nsContext,
1265 null );
1266 String spacing = XMLTools.getNodeAsString( (Node) rangeList.get( i ), PRE_OWS
1267 + "Spacing",
1268 nsContext, null );
1269 TypedLiteral min = new TypedLiteral( minimum, null );
1270 TypedLiteral max = new TypedLiteral( maximum, null );
1271 TypedLiteral space = new TypedLiteral( spacing, null );
1272
1273 ranges[i] = new ValueRange( min, max, space );
1274 }
1275
1276 if ( values.length < 1 && ranges.length < 1 ) {
1277 throw new XMLParsingException(
1278 "At least one 'ows:Value'-element or one 'ows:Range'-element must be defined "
1279 + "in each element of type 'ows:AllowedValues'." );
1280 }
1281
1282 allowedValues = new OWSAllowedValues( literals, ranges );
1283 }
1284
1285 // FIXME manage elements: ows:AnyValue, ows:NoValues.
1286 boolean anyValue = false;
1287 boolean noValues = false;
1288
1289 // 'ows:ValuesListReference' - element
1290 OWSMetadata valuesListReference = getOWSMetadata( element, PRE_OWS + "ValuesListReference",
1291 nsContext );
1292
1293 // 'ows:DefaulValue' - element
1294 String defaultValue = XMLTools.getNodeAsString( element, PRE_OWS + "DefaultValue/text()",
1295 nsContext, null );
1296
1297 // 'ows:Meaning' - element
1298 OWSMetadata meaning = getOWSMetadata( element, PRE_OWS + "Meaning", nsContext );
1299
1300 // 'ows:DataType - element
1301 OWSMetadata dataType = getOWSMetadata( element, PRE_OWS + "DataType", nsContext );
1302
1303 // choose up to one measurement element
1304 String measurementType = null;
1305 // 'ows:ReferenceSystem' - element
1306 Element referenceElement = (Element) XMLTools.getNode( element,
1307 PRE_OWS + "ReferenceSystem",
1308 nsContext );
1309 // 'ows:UOM' - element
1310 Element uomElement = (Element) XMLTools.getNode( element, PRE_OWS + "UOM", nsContext );
1311 OWSMetadata measurement = null;
1312
1313 if ( referenceElement != null && uomElement != null ) {
1314 throw new InvalidCapabilitiesException( "Within an 'ows:DomainType'-Element only one "
1315 + "of the following elements is allowed: "
1316 + "'ows:ReferenceSystem' OR 'ows:UOM'." );
1317 } else if ( referenceElement != null ) {
1318 measurementType = OWSDomainType110.REFERENCE_SYSTEM;
1319 measurement = getOWSMetadata( element, PRE_OWS + "ReferenceSystem", nsContext );
1320 } else if ( uomElement != null ) {
1321 measurementType = OWSDomainType110.UOM;
1322 measurement = getOWSMetadata( element, PRE_OWS + "UOM", nsContext );
1323 }
1324
1325 // 'ows:Metadata' - elements
1326 List metaList = XMLTools.getNodes( element, PRE_OWS + "Metadata", nsContext );
1327 OWSMetadata[] metadata = new OWSMetadata[metaList.size()];
1328 for ( int i = 0; i < metadata.length; i++ ) {
1329 metadata[i] = getOWSMetadata( (Element) metaList.get( i ), PRE_OWS + "Metadata",
1330 nsContext );
1331 }
1332
1333 // return new OWSDomainType110
1334 OWSDomainType110 domainType110 = null;
1335 if ( allowedValues != null && !anyValue && !noValues && valuesListReference == null ) {
1336 domainType110 = new OWSDomainType110( allowedValues, defaultValue, meaning, dataType,
1337 measurementType, measurement, metadata, name );
1338 } else if ( ( anyValue || noValues ) && allowedValues == null
1339 && valuesListReference == null ) {
1340 domainType110 = new OWSDomainType110( anyValue, noValues, defaultValue, meaning,
1341 dataType, measurementType, measurement, metadata,
1342 name );
1343 } else if ( valuesListReference != null && allowedValues == null && !anyValue && !noValues ) {
1344 domainType110 = new OWSDomainType110( valuesListReference, defaultValue, meaning,
1345 dataType, measurementType, measurement, metadata,
1346 name );
1347 } else {
1348 throw new InvalidCapabilitiesException(
1349 "Only one of the following elements may be "
1350 + "contained within an 'ows:DomainType': 'ows:AllowedValues', 'ows:AnyValue', "
1351 + "'ows:NoValues' or 'ows:ValuesListReference'." );
1352 }
1353
1354 return domainType110;
1355 }
1356
1357 /**
1358 * FIXME check, wether the URIs go to the correct address within OWSMetadata. So far, no example
1359 * was given to check this with.
1360 *
1361 * Creates and returns a new <code>OWSMetadata</code> object (or null) from the given
1362 * <code>Element</code> at the given <code>XPath</code>.
1363 *
1364 * @param element
1365 * @param xPath
1366 * @param nsContext
1367 * @return Returns a new OWSMetadata object (may be null).
1368 * @throws XMLParsingException
1369 */
1370 private OWSMetadata getOWSMetadata( Element element, String xPath, NamespaceContext nsContext )
1371 throws XMLParsingException {
1372
1373 Element child = (Element) XMLTools.getNode( element, xPath, nsContext );
1374
1375 if ( child == null ) {
1376 return null;
1377 }
1378
1379 // attrib about
1380 URI about = XMLTools.getNodeAsURI( child, "@about", nsContext, null );
1381
1382 // attribs for SimpleLink
1383 URI href = XMLTools.getNodeAsURI( child, "@xlink:href", nsContext, null );
1384 URI role = XMLTools.getNodeAsURI( child, "@xlink:role", nsContext, null );
1385 URI arcrole = XMLTools.getNodeAsURI( child, "@xlink:arcrole", nsContext, null );
1386 String title = XMLTools.getNodeAsString( child, "@xlink:title", nsContext, null );
1387 String show = XMLTools.getNodeAsString( child, "@xlink:show", nsContext, null );
1388 String actuate = XMLTools.getNodeAsString( child, "@xlink:actuate", nsContext, null );
1389
1390 // ows:name (ows:AbstractMetaData)
1391 String name = XMLTools.getNodeAsString( child, "text()", nsContext, null );
1392
1393 SimpleLink link = new SimpleLink( href, role, arcrole, title, show, actuate );
1394
1395 return new OWSMetadata( about, link, name );
1396 }
1397
1398 }
1399
1400 /***************************************************************************************************
1401 * Changes to this class. What the people have been up to: $Log$
1402 * Changes to this class. What the people have been up to: Revision 1.39 2007/03/08 10:16:02 bezema
1403 * Changes to this class. What the people have been up to: changed <tt> into <code>
1404 * Changes to this class. What the people have been up to:
1405 * Changes to this class. What the people have been up to: Revision 1.38 2007/03/05 10:19:29 bezema
1406 * Changes to this class. What the people have been up to: removed the usage of an deprectated api, and some small docu fixes
1407 * Changes to this class. What the people have been up to:
1408 * Changes to this class. What the people have been up to: Revision 1.37 2007/01/23 15:09:12 bezema
1409 * Changes to this class. What the people have been up to: code formatting
1410 * Changes to this class. What the people have been up to:
1411 * Changes to this class. What the people have been up to: Revision 1.36 2007/01/15 17:01:59 bezema
1412 * Changes to this class. What the people have been up to: Updated the capabilities /configuration
1413 * parsing, and the construction of their beans Changes to this class. What the people have been up
1414 * to: Changes to this class. What the people have been up to: Revision 1.35 2007/01/03 17:29:05
1415 * bezema Changes to this class. What the people have been up to: starting to realise a more
1416 * ogc-conform capabilities (document) Changes to this class. What the people have been up to:
1417 * Changes to this class. What the people have been up to: Revision 1.34 2007/01/03 13:31:30 bezema
1418 * Changes to this class. What the people have been up to: changed from the deegree namespace to ogc
1419 * namespace Changes to this class. What the people have been up to: Changes to this class. What the
1420 * people have been up to: Revision 1.33 2006/12/11 15:20:57 bezema Changes to this class. What the
1421 * people have been up to: added shadows to the terrain and removed warnings Changes to this class.
1422 * What the people have been up to: Changes to this class. What the people have been up to: Revision
1423 * 1.32 2006/12/06 15:34:36 bezema Changes to this class. What the people have been up to: removed
1424 * warnings and unsafe lists Changes to this class. What the people have been up to: Changes to this
1425 * class. What the people have been up to: Revision 1.31 2006/11/27 15:40:32 bezema Changes to this
1426 * class. What the people have been up to: Updated the coordinatesystem handling and the generics
1427 * Changes to this class. What the people have been up to: Revision 1.30 2006/11/27 09:07:53 poth
1428 * JNI integration of proj4 has been removed. The CRS functionality now will be done by native
1429 * deegree code.
1430 *
1431 * Revision 1.29 2006/11/23 11:46:40 bezema The initial version of the new wpvs
1432 *
1433 * Revision 1.28 2006/11/07 16:34:02 poth bug fixes and code formatting
1434 *
1435 * Revision 1.27 2006/08/24 06:42:15 poth File header corrected
1436 *
1437 * Revision 1.26 2006/05/01 20:15:27 poth ** empty log message ***
1438 *
1439 * Revision 1.25 2006/04/06 20:25:25 poth ** empty log message ***
1440 *
1441 * Revision 1.24 2006/03/30 21:20:26 poth ** empty log message ***
1442 *
1443 * Revision 1.23 2006/01/18 08:47:54 taddei bug fixes
1444 *
1445 * Revision 1.22 2005/12/21 11:08:20 mays clean up: remove typos, remove wgs84bboxes from bboxes
1446 * array
1447 *
1448 * Revision 1.21 2005/12/20 13:14:52 mays clean up and addition of minor missing parts
1449 *
1450 * Revision 1.20 2005/12/20 10:08:46 mays remove typo
1451 *
1452 * Revision 1.19 2005/12/20 09:59:41 mays implement ValueRange in getOWSDomainType110 and implement
1453 * SimpleLink in getOWSMetadata
1454 *
1455 * Revision 1.18 2005/12/19 10:05:23 mays changes for call of Operation110 constructor in
1456 * getOperation110
1457 *
1458 * Revision 1.17 2005/12/16 15:29:38 mays necessary changes due to new definition of
1459 * ows:OperationsMetadata
1460 *
1461 * Revision 1.16 2005/12/13 16:53:10 mays change parseOperationsMetadata to 'protected'
1462 *
1463 * Revision 1.15 2005/12/12 10:25:51 mays removed typos
1464 *
1465 * Revision 1.14 2005/12/09 14:07:56 mays add parseOperationsMetadata and clean up
1466 *
1467 * Revision 1.13 2005/12/08 16:46:03 mays change method names to parseSomeThing; move configuration
1468 * specific stuff to WPVSConfigurationDocument and leave only capabilties specifics in here
1469 *
1470 * Revision 1.12 2005/12/07 09:45:14 mays redesign of filterCondition request from String to Map
1471 * form wcs and wms datasources
1472 *
1473 * Revision 1.11 2005/12/06 16:45:21 mays necessary changes for AbstractDataSources: use Query for
1474 * WFSDataSources
1475 *
1476 * Revision 1.10 2005/12/06 12:57:07 mays add create-methods for new subnodes of dataset; remove
1477 * errors in existing methods
1478 *
1479 * Revision 1.9 2005/12/05 09:36:38 mays revision of comments
1480 *
1481 * Revision 1.8 2005/12/02 15:28:55 mays adaptations according to schema specifications, mainly
1482 * concerning the number of item occurences
1483 *
1484 * Revision 1.7 2005/12/01 16:50:40 mays add some more subnodes to dataset (not finished yet), add
1485 * create-methods for new subnodes
1486 *
1487 * Revision 1.6 2005/12/01 10:30:14 mays add standard footer to all java classes in wpvs package
1488 *
1489 **************************************************************************************************/