001    //$HeadURL: svn+ssh://rbezema@svn.wald.intevation.org/deegree/base/tags/2.1/src/org/deegree/ogcwebservices/wpvs/configuration/WPVSConfigurationDocument.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.configuration;
045    
046    import java.awt.Color;
047    import java.net.MalformedURLException;
048    import java.net.URL;
049    import java.util.ArrayList;
050    import java.util.HashMap;
051    import java.util.Iterator;
052    import java.util.List;
053    import java.util.Map;
054    
055    import org.deegree.datatypes.QualifiedName;
056    import org.deegree.framework.log.ILogger;
057    import org.deegree.framework.log.LoggerFactory;
058    import org.deegree.framework.util.IDGenerator;
059    import org.deegree.framework.util.KVP2Map;
060    import org.deegree.framework.util.StringTools;
061    import org.deegree.framework.xml.InvalidConfigurationException;
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.CoordinateSystem;
066    import org.deegree.model.filterencoding.AbstractFilter;
067    import org.deegree.model.filterencoding.Filter;
068    import org.deegree.model.metadata.iso19115.Keywords;
069    import org.deegree.model.metadata.iso19115.OnlineResource;
070    import org.deegree.model.spatialschema.Envelope;
071    import org.deegree.model.spatialschema.GMLGeometryAdapter;
072    import org.deegree.model.spatialschema.Geometry;
073    import org.deegree.model.spatialschema.GeometryException;
074    import org.deegree.model.spatialschema.GeometryFactory;
075    import org.deegree.model.spatialschema.Surface;
076    import org.deegree.ogcbase.CommonNamespaces;
077    import org.deegree.ogcbase.PropertyPath;
078    import org.deegree.ogcwebservices.InvalidParameterValueException;
079    import org.deegree.ogcwebservices.MissingParameterValueException;
080    import org.deegree.ogcwebservices.OGCWebServiceException;
081    import org.deegree.ogcwebservices.getcapabilities.InvalidCapabilitiesException;
082    import org.deegree.ogcwebservices.wcs.getcoverage.GetCoverage;
083    import org.deegree.ogcwebservices.wms.operation.GetMap;
084    import org.deegree.ogcwebservices.wpvs.capabilities.DataProvider;
085    import org.deegree.ogcwebservices.wpvs.capabilities.Dataset;
086    import org.deegree.ogcwebservices.wpvs.capabilities.DatasetReference;
087    import org.deegree.ogcwebservices.wpvs.capabilities.Dimension;
088    import org.deegree.ogcwebservices.wpvs.capabilities.ElevationModel;
089    import org.deegree.ogcwebservices.wpvs.capabilities.FeatureListReference;
090    import org.deegree.ogcwebservices.wpvs.capabilities.Identifier;
091    import org.deegree.ogcwebservices.wpvs.capabilities.MetaData;
092    import org.deegree.ogcwebservices.wpvs.capabilities.OWSCapabilities;
093    import org.deegree.ogcwebservices.wpvs.capabilities.Style;
094    import org.deegree.ogcwebservices.wpvs.capabilities.WPVSCapabilitiesDocument;
095    import org.w3c.dom.Element;
096    import org.w3c.dom.Node;
097    import org.w3c.dom.Text;
098    
099    /**
100     * Parser for WPVS configuration documents.
101     * 
102     * @author <a href="mailto:mays@lat-lon.de">Judit Mays</a>
103     * @author last edited by: $Author: rbezema $
104     * 
105     * @version $Revision: 7952 $, $Date: 2007-08-09 11:57:34 +0200 (Do, 09 Aug 2007) $
106     */
107    public class WPVSConfigurationDocument extends WPVSCapabilitiesDocument {
108    
109        private static final long serialVersionUID = 1511898601495679163L;
110    
111        private static final ILogger LOG = LoggerFactory.getLogger( WPVSConfigurationDocument.class );
112    
113        private static String PRE_DWPVS = CommonNamespaces.DEEGREEWPVS_PREFIX + ":";
114    
115        private static String PRE_OWS = CommonNamespaces.OWS_PREFIX + ":";
116    
117        // The smallestMinimalScaleDenomiator is needed to calculate the smallest resolutionstripe
118        // possible
119        private double smallestMinimalScaleDenominator = Double.MAX_VALUE;
120    
121        /**
122         * Creates a class representation of the <code>WPVSConfiguration</code> document.
123         * 
124         * @return Returns a WPVSConfiguration object.
125         * @throws InvalidConfigurationException
126         */
127        public WPVSConfiguration parseConfiguration()
128                                throws InvalidConfigurationException {
129            WPVSConfiguration wpvsConfiguration = null;
130            try {
131    
132                // TODO 'contents' field not verified, therefore null! Check spec.
133                Element requestedNode = (Element) XMLTools.getRequiredNode(
134                                                                            getRootElement(),
135                                                                            PRE_DWPVS + "deegreeParams",
136                                                                            nsContext );
137                WPVSDeegreeParams wpvsDeegreeParams = parseDeegreeParams( requestedNode );
138    
139                requestedNode = (Element) XMLTools.getRequiredNode( getRootElement(), PRE_DWPVS
140                                                                                      + "Dataset",
141                                                                    nsContext );
142                Dataset rootDataset = parseDataset( requestedNode, null, null,
143                                                    wpvsDeegreeParams.getMinimalWCS_DGMResolution() );
144    
145                wpvsConfiguration = new WPVSConfiguration(
146                                                           parseVersion(),
147                                                           parseUpdateSequence(),
148                                                           getServiceIdentification(),
149                                                           getServiceProvider(),
150                                                           parseOperationsMetadata(),
151                                                           null,
152                                                           rootDataset,
153                                                           wpvsDeegreeParams,
154                                                           ( Double.isInfinite( smallestMinimalScaleDenominator ) ? 1.0
155                                                                                                                 : smallestMinimalScaleDenominator ) );
156    
157            } catch ( XMLParsingException e ) {
158                throw new InvalidConfigurationException( e.getMessage() + "\n"
159                                                         + StringTools.stackTraceToString( e ) );
160    
161            } catch ( MissingParameterValueException e ) {
162                throw new InvalidConfigurationException( e.getMessage() + "\n"
163                                                         + StringTools.stackTraceToString( e ) );
164    
165            } catch ( InvalidParameterValueException e ) {
166                throw new InvalidConfigurationException( e.getMessage() + "\n"
167                                                         + StringTools.stackTraceToString( e ) );
168    
169            } catch ( OGCWebServiceException e ) {
170                throw new InvalidConfigurationException( e.getMessage() + "\n"
171                                                         + StringTools.stackTraceToString( e ) );
172    
173            } catch ( InvalidConfigurationException e ) {
174                throw new InvalidConfigurationException( e.getMessage() + "\n"
175                                                         + StringTools.stackTraceToString( e ) );
176    
177            }
178            return wpvsConfiguration;
179        }
180    
181        /**
182         * Creates and returns a new <code>WPVSDeegreeParams</code> object from the given
183         * <code>Node</code>.
184         * 
185         * @param deegreeNode
186         * @return Returns a new WPVSDeegreeParams object.
187         * @throws XMLParsingException
188         * @throws InvalidConfigurationException
189         */
190        private WPVSDeegreeParams parseDeegreeParams( Node deegreeNode )
191                                throws XMLParsingException, InvalidConfigurationException {
192    
193            Element deegreeElement = (Element) XMLTools.getRequiredNode(
194                                                                         deegreeNode,
195                                                                         PRE_DWPVS
196                                                                                                 + "DefaultOnlineResource",
197                                                                         nsContext );
198            OnlineResource online = parseOnLineResource( deegreeElement );
199    
200            int cacheSize = XMLTools.getNodeAsInt( deegreeNode, PRE_DWPVS + "CacheSize", nsContext, 100 );
201    
202            int maxLifeTime = XMLTools.getNodeAsInt( deegreeNode, PRE_DWPVS + "MaxLifeTime", nsContext,
203                                                     3600 );
204    
205            int reqTimeLimit = XMLTools.getNodeAsInt( deegreeNode, PRE_DWPVS + "RequestTimeLimit",
206                                                      nsContext, 60 );
207            reqTimeLimit *= 1000;
208    
209            float viewQuality = (float) XMLTools.getNodeAsDouble( deegreeNode, PRE_DWPVS
210                                                                               + "ViewQuality",
211                                                                  nsContext, 0.95f );
212    
213            int maxMapWidth = XMLTools.getNodeAsInt( deegreeNode, PRE_DWPVS + "MaxViewWidth",
214                                                     nsContext, 1000 );
215    
216            int maxMapHeight = XMLTools.getNodeAsInt( deegreeNode, PRE_DWPVS + "MaxViewHeight",
217                                                      nsContext, 1000 );
218    
219            String charSet = XMLTools.getNodeAsString( deegreeNode, PRE_DWPVS + "CharacterSet",
220                                                       nsContext, "UTF-8" );
221    
222            Node copyrightNode = XMLTools.getNode( deegreeNode, PRE_DWPVS + "Copyright", nsContext );
223    
224            Node copyTextNode = XMLTools.getNode( copyrightNode, PRE_DWPVS + "Text", nsContext );
225            Node copyURLNode = XMLTools.getNode( copyrightNode, PRE_DWPVS + "ImageURL/@xlink:href",
226                                                 nsContext );
227    
228            boolean isWatermarked = false;
229    
230            String copyright;
231            if ( copyTextNode != null ) {
232                copyright = XMLTools.getRequiredNodeAsString( copyrightNode, PRE_DWPVS + "Text/text()",
233                                                              nsContext );
234            } else if ( copyURLNode != null ) {
235                copyright = XMLTools.getRequiredNodeAsString( copyrightNode, PRE_DWPVS
236                                                                             + "ImageURL/@xlink:href",
237                                                              nsContext );
238    
239                isWatermarked = XMLTools.getNodeAsBoolean( copyrightNode, PRE_DWPVS
240                                                                          + "ImageURL/@watermark",
241                                                           nsContext, isWatermarked );
242    
243                try {
244                    copyright = resolve( copyright ).toString();
245                } catch ( MalformedURLException e ) {
246                    throw new InvalidConfigurationException( "Copyright/ImageURL '" + copyright
247                                                             + "' doesn't seem to be a valid URL!" );
248                }
249    
250            } else {
251                throw new InvalidConfigurationException( "Copyright must contain either "
252                                                         + "a Text-Element or an ImageURL-Element!" );
253            }
254    
255            Map<String, URL> backgroundMap = new HashMap<String, URL>( 10 );
256            Element backgrounds = (Element) XMLTools.getNode( deegreeNode,
257                                                              PRE_DWPVS + "BackgroundList", nsContext );
258            if ( backgrounds != null ) {
259                List backgroundList = XMLTools.getNodes( backgrounds, PRE_DWPVS + "Background",
260                                                         nsContext );
261                for ( Iterator iter = backgroundList.iterator(); iter.hasNext(); ) {
262                    Element background = (Element) iter.next();
263    
264                    String bgName = background.getAttribute( "name" );
265                    String bgHref = background.getAttribute( "href" );
266    
267                    if ( bgName == null || bgName.length() == 0 || bgHref == null
268                         || bgHref.length() == 0 )
269                        throw new InvalidConfigurationException(
270                                                                 "Background must contain a 'name' and a "
271                                                                                         + " 'href' attribute, both if which must contain non-empty strings." );
272    
273                    try {
274    
275                        backgroundMap.put( bgName, resolve( bgHref ) );
276                    } catch ( MalformedURLException e ) {
277                        throw new InvalidConfigurationException( "Background", e.getMessage() );
278                    }
279                }
280    
281            }
282    
283            boolean quality = XMLTools.getNodeAsBoolean( deegreeNode, PRE_DWPVS
284                                                                      + "RequestQualityPreferred",
285                                                         nsContext, true );
286            double maximumFarClippingPlane = XMLTools.getNodeAsDouble(
287                                                                       deegreeNode,
288                                                                       PRE_DWPVS
289                                                                                               + "RequestsMaximumFarClippingPlane",
290                                                                       nsContext, 15000 );
291            
292            double nearClippingPlane = XMLTools.getNodeAsDouble(
293                                                                      deegreeNode,
294                                                                      PRE_DWPVS
295                                                                                              + "NearClippingPlane",
296                                                                      nsContext, 2 );
297    
298            String defaultSplitter = XMLTools.getNodeAsString( deegreeNode,
299                                                               PRE_DWPVS + "DefaultSplitter",
300                                                               nsContext, "QUAD" ).toUpperCase();
301    
302            double minimalTerrainHeight = XMLTools.getNodeAsDouble( deegreeNode,
303                                                                    PRE_DWPVS + "MinimalTerrainHeight",
304                                                                    nsContext, 0 );
305    
306            double minimalWCS_DGMResolution = XMLTools.getNodeAsDouble(
307                                                                        deegreeNode,
308                                                                        PRE_DWPVS
309                                                                                                + "MinimalWCSElevationModelResolution",
310                                                                        nsContext, 0 );
311    
312            double extendRequestPercentage = XMLTools.getNodeAsDouble(
313                                                                       deegreeNode,
314                                                                       PRE_DWPVS
315                                                                                               + "ExtendRequestPercentage",
316                                                                       nsContext, 0 );
317            if ( extendRequestPercentage > 100 ) {
318                LOG.logWarning( Messages.getMessage( "WPVS_WRONG_EXTEND_REQUEST_PERCENTAGE",
319                                                     Double.valueOf( extendRequestPercentage ),
320                                                     Double.valueOf( 100 ) ) );
321                extendRequestPercentage = 100d;
322            } else if ( extendRequestPercentage < -0.00000001 ) {
323                LOG.logWarning( Messages.getMessage( "WPVS_WRONG_EXTEND_REQUEST_PERCENTAGE",
324                                                     Double.valueOf( extendRequestPercentage ),
325                                                     Double.valueOf( 0 ) ) );
326                extendRequestPercentage = 0d;
327            }
328            WPVSDeegreeParams wpvsDeegreeParams = new WPVSDeegreeParams( online,
329                                                                         cacheSize,
330                                                                         reqTimeLimit,
331                                                                         charSet,
332                                                                         copyright,
333                                                                         isWatermarked,
334                                                                         maxLifeTime,
335                                                                         viewQuality,
336                                                                         backgroundMap,
337                                                                         maxMapWidth,
338                                                                         maxMapHeight,
339                                                                         quality,
340                                                                         maximumFarClippingPlane,
341                                                                         nearClippingPlane,
342                                                                         defaultSplitter,
343                                                                         minimalTerrainHeight,
344                                                                         minimalWCS_DGMResolution,
345                                                                         extendRequestPercentage * 0.01 );
346    
347            return wpvsDeegreeParams;
348        }
349    
350        // /**
351        // * Gets the <code>Dataset</code> object from the <code>WPVSConfiguration</code> element.
352        // *
353        // * @return Returns the Dataset object form root element.
354        // * @throws XMLParsingException
355        // * @throws OGCWebServiceException
356        // * @throws InvalidParameterValueException
357        // * @throws MissingParameterValueException
358        // * @throws InvalidConfigurationException
359        // */
360        // private Dataset getDataset( Deegree)
361        // throws XMLParsingException, MissingParameterValueException,
362        // InvalidParameterValueException, OGCWebServiceException,
363        // InvalidConfigurationException {
364        //
365        // Element datasetElement = (Element) XMLTools.getRequiredNode( getRootElement(), PRE_DWPVS
366        // + "Dataset",
367        // nsContext );
368        // Dataset dataset = parseDataset( datasetElement, null, null );
369        //
370        // return dataset;
371        // }
372    
373        /**
374         * Creates and returns a new <code>Dataset</code> object from the given <code>Element</code>
375         * and the parent <code>Dataset</code> object.
376         * 
377         * @param datasetElement
378         * @param parent
379         *            may be null if root Dataset
380         * @return Returns a new Dataset object.
381         * @throws XMLParsingException
382         * @throws MissingParameterValueException
383         * @throws InvalidParameterValueException
384         * @throws OGCWebServiceException
385         * @throws InvalidConfigurationException
386         */
387        private Dataset parseDataset( Element datasetElement, Dataset parent,
388                                      CoordinateSystem defaultCoordinateSystem,
389                                      double minimalWCS_DGMResolution )
390                                throws XMLParsingException, MissingParameterValueException,
391                                InvalidParameterValueException, OGCWebServiceException,
392                                InvalidConfigurationException {
393            // attributes
394            boolean queryable = XMLTools.getNodeAsBoolean( datasetElement, "@queryable", nsContext,
395                                                           false );
396            boolean opaque = XMLTools.getNodeAsBoolean( datasetElement, "@opaque", nsContext, false );
397            boolean noSubsets = XMLTools.getNodeAsBoolean( datasetElement, "@noSubsets", nsContext,
398                                                           false );
399            int fixedWidth = XMLTools.getNodeAsInt( datasetElement, "@fixedWidth", nsContext, 0 );
400            int fixedHeight = XMLTools.getNodeAsInt( datasetElement, "@fixedHeight", nsContext, 0 );
401    
402            // elements
403            String name = XMLTools.getNodeAsString( datasetElement, PRE_DWPVS + "Name/text()",
404                                                    nsContext, null );
405            String title = XMLTools.getRequiredNodeAsString( datasetElement,
406                                                             PRE_DWPVS + "Title/text()", nsContext );
407            String abstract_ = XMLTools.getNodeAsString( datasetElement, PRE_DWPVS + "Abstract/text()",
408                                                         nsContext, null );
409            Keywords[] keywords = getKeywords( XMLTools.getNodes( datasetElement, PRE_OWS + "Keywords",
410                                                                  nsContext ) );
411            String[] crsStrings = XMLTools.getNodesAsStrings( datasetElement, PRE_DWPVS + "CRS/text()",
412                                                              nsContext );
413            List<CoordinateSystem> crsList = parseCoordinateSystems( crsStrings );
414    
415            if ( parent == null ) { // root dataset
416                if ( crsList.size() == 0 || crsList.get( 0 ) == null ) {
417                    throw new InvalidCapabilitiesException(
418                                                            Messages.getMessage(
419                                                                                 "WPVS_NO_TOPLEVEL_DATASET_CRS",
420                                                                                 title ) );
421                }
422                defaultCoordinateSystem = crsList.get( 0 );
423            }
424    
425            String[] format = XMLTools.getRequiredNodesAsStrings( datasetElement, PRE_DWPVS
426                                                                                  + "Format/text()",
427                                                                  nsContext );
428            // wgs84 == mandatory
429            Element boundingBoxElement = (Element) XMLTools.getRequiredNode(
430                                                                             datasetElement,
431                                                                             PRE_OWS
432                                                                                                     + "WGS84BoundingBox",
433                                                                             nsContext );
434            Envelope wgs84BoundingBox = getWGS84BoundingBoxType( boundingBoxElement );
435    
436            Envelope[] boundingBoxes = getBoundingBoxes( datasetElement, defaultCoordinateSystem );
437            Dimension[] dimensions = parseDimensions( datasetElement );
438            DataProvider dataProvider = parseDataProvider( datasetElement );
439            Identifier identifier = parseDatasetIdentifier( datasetElement, PRE_DWPVS + "Identifier" );
440            MetaData[] metaData = parseMetaData( datasetElement );
441            DatasetReference[] datasetRefs = parseDatasetReferences( datasetElement );
442            FeatureListReference[] featureListRefs = parseFeatureListReferences( datasetElement );
443            Style[] style = parseStyles( datasetElement );
444            double minScaleDenom = XMLTools.getNodeAsDouble(
445                                                             datasetElement,
446                                                             PRE_DWPVS
447                                                                                     + "MinimumScaleDenominator/text()",
448                                                             nsContext, 0 );
449    
450            // update the smallestMinimalScaleDenomiator
451            if ( minScaleDenom < smallestMinimalScaleDenominator )
452                smallestMinimalScaleDenominator = minScaleDenom;
453    
454            double maxScaleDenom = XMLTools.getNodeAsDouble(
455                                                             datasetElement,
456                                                             PRE_DWPVS
457                                                                                     + "MaximumScaleDenominator/text()",
458                                                             nsContext, 9E9 );
459    
460            if ( minScaleDenom >= maxScaleDenom ) {
461                throw new InvalidCapabilitiesException( "MinimumScaleDenominator must be "
462                                                        + "less than MaximumScaleDenominator!" );
463            }
464            CoordinateSystem currentCRS = defaultCoordinateSystem;
465            if ( crsList.size() > 0 && crsList.get( 0 ) != null ) {
466                currentCRS = crsList.get( 0 );
467            }
468            ElevationModel elevationModel = parseElevationModel( datasetElement, name,
469                                                                 minimalWCS_DGMResolution, currentCRS );
470            AbstractDataSource[] dataSources = parseAbstractDatasources( datasetElement, name,
471                                                                         currentCRS );
472    
473            // create new root dataset
474            Dataset dataset = new Dataset( queryable, opaque, noSubsets, fixedWidth, fixedHeight, name,
475                                           title, abstract_, keywords, crsList, format,
476                                           wgs84BoundingBox, boundingBoxes, dimensions, dataProvider,
477                                           identifier, metaData, datasetRefs, featureListRefs, style,
478                                           minScaleDenom, maxScaleDenom, null, elevationModel,
479                                           dataSources, parent );
480    
481            // get child datasets
482            List nl = XMLTools.getNodes( datasetElement, PRE_DWPVS + "Dataset", nsContext );
483            Dataset[] childDatasets = new Dataset[nl.size()];
484            for ( int i = 0; i < childDatasets.length; i++ ) {
485                childDatasets[i] = parseDataset( (Element) nl.get( i ), dataset,
486                                                 defaultCoordinateSystem, minimalWCS_DGMResolution );
487    
488            }
489    
490            // set child datasets
491            dataset.setDatasets( childDatasets );
492    
493            return dataset;
494        }
495    
496        /**
497         * Creates and returns a new <code>ElevationModel</code> object from the given
498         * <code>Element</code> and the parent <code>Dataset</code>.
499         * 
500         * The OGC ElevationModel contains only a String. The Deegree ElevationModel additionaly
501         * contains a complex dataSource.
502         * 
503         * @param datasetElement
504         * @param parent
505         * @return Returns the ElevationModel object.
506         * @throws XMLParsingException
507         * @throws OGCWebServiceException
508         * @throws InvalidParameterValueException
509         * @throws MissingParameterValueException
510         * @throws InvalidConfigurationException
511         */
512        private ElevationModel parseElevationModel( Element datasetElement, String parentName,
513                                                    double minimalWCS_DGMResolution,
514                                                    CoordinateSystem defaultCRS )
515                                throws XMLParsingException, MissingParameterValueException,
516                                InvalidParameterValueException, OGCWebServiceException,
517                                InvalidConfigurationException {
518    
519            Element elevationElement = null;
520            String name = null;
521            ElevationModel elevationModel = null;
522    
523            elevationElement = (Element) XMLTools.getNode( datasetElement,
524                                                           PRE_DWPVS + "ElevationModel", nsContext );
525    
526            AbstractDataSource[] dataSources = null;
527            if ( elevationElement != null ) {
528    
529                name = XMLTools.getRequiredNodeAsString( elevationElement, PRE_DWPVS + "Name/text()",
530                                                         nsContext );
531    
532                dataSources = parseAbstractDatasources( elevationElement, parentName, defaultCRS );
533                if ( dataSources.length < 1 ) {
534                    throw new InvalidCapabilitiesException(
535                                                            "Each '"
536                                                                                    + elevationElement.getNodeName()
537                                                                                    + "' must contain at least one data source!" );
538                }
539                if ( !Double.isNaN( minimalWCS_DGMResolution ) ) {
540                    // little trick to know which dgm datasources have a configured minimal resolution,
541                    // if the minimalWCS_DGMResolution is not set (e.g Double.nan) nothing has to be
542                    // done (a value of 0d is presumed)
543                    for ( AbstractDataSource source : dataSources ) {
544                        if ( source.getServiceType() == AbstractDataSource.LOCAL_WCS
545                             || source.getServiceType() == AbstractDataSource.REMOTE_WCS ) {
546                            ( (LocalWCSDataSource) source ).setConfiguredMinimalDGMResolution( minimalWCS_DGMResolution );
547                        }
548                    }
549                }
550            }
551    
552            elevationModel = new ElevationModel( name, dataSources );
553    
554            return elevationModel;
555        }
556    
557        /**
558         * Creates and returns a new array of <code>AbstractDataSource</code> objects from the given
559         * <code>Element</code>.
560         * 
561         * If the objects are used within an ElevationModel object, they may be of the following types:
562         * LocalWCSDataSource, RemoteWCSDataSource, LocalWFSDataSource, RemoteWFSDataSource. If the
563         * objects are used within a Dataset object, they may additionaly be of the types:
564         * LocalWMSDataSource, RemoteWMSDataSource.
565         * 
566         * @param element
567         * @return Returns a new array of AbstractDataSource objects.
568         * @throws XMLParsingException
569         * @throws OGCWebServiceException
570         * @throws InvalidConfigurationException
571         */
572        private AbstractDataSource[] parseAbstractDatasources( Element element, String parentName,
573                                                               CoordinateSystem defaultCRS )
574                                throws XMLParsingException, OGCWebServiceException,
575                                InvalidConfigurationException {
576    
577            List abstractDataSources = XMLTools.getNodes( element, "*", nsContext );
578            List<AbstractDataSource> tempDataSources = new ArrayList<AbstractDataSource>(
579                                                                                          abstractDataSources.size() );
580    
581            for ( int i = 0; i < abstractDataSources.size(); i++ ) {
582    
583                Element dataSourceElement = (Element) abstractDataSources.get( i );
584    
585                // String nodeName = dataSourceElement.getNodeName();
586                String nodeName = dataSourceElement.getLocalName();
587    
588                if ( nodeName.endsWith( "DataSource" ) ) {
589                    QualifiedName pn = null;
590                    if ( parentName != null ) {
591                        pn = new QualifiedName( PRE_DWPVS, parentName, nsContext.getURI( PRE_DWPVS ) );
592                    }
593                    QualifiedName name = XMLTools.getNodeAsQualifiedName( dataSourceElement,
594                                                                          PRE_DWPVS + "Name/text()",
595                                                                          nsContext, pn );
596    
597                    OWSCapabilities owsCapabilities = parseOWSCapabilities( dataSourceElement );
598    
599                    double minScaleDenom = XMLTools.getNodeAsDouble(
600                                                                     dataSourceElement,
601                                                                     PRE_DWPVS
602                                                                                             + "MinimumScaleDenominator/text()",
603                                                                     nsContext, 0 );
604    
605                    // update the smallestMinimalScaleDenomiator
606                    if ( minScaleDenom < smallestMinimalScaleDenominator )
607                        smallestMinimalScaleDenominator = minScaleDenom;
608    
609                    double maxScaleDenom = XMLTools.getNodeAsDouble(
610                                                                     dataSourceElement,
611                                                                     PRE_DWPVS
612                                                                                             + "MaximumScaleDenominator/text()",
613                                                                     nsContext, 9E9 );
614    
615                    Surface validArea = parseValidArea( dataSourceElement, defaultCRS );
616                    AbstractDataSource dataSource = null;
617    
618                    if ( nodeName.equals( "LocalWCSDataSource" ) ) {
619                        Element filterElement = (Element) XMLTools.getRequiredNode(
620                                                                                    dataSourceElement,
621                                                                                    PRE_DWPVS
622                                                                                                            + "FilterCondition",
623                                                                                    nsContext );
624                        GetCoverage getCoverage = parseWCSFilterCondition( filterElement );
625                        Color[] transparentColors = parseTransparentColors( dataSourceElement );
626    
627                        dataSource = new LocalWCSDataSource( name, owsCapabilities, validArea,
628                                                             minScaleDenom, maxScaleDenom, getCoverage,
629                                                             transparentColors );
630                        LOG.logDebug( "created local wcs with name: " + name );
631    
632                    } else if ( nodeName.equals( "RemoteWCSDataSource" ) ) {
633                        Element filterElement = (Element) XMLTools.getRequiredNode(
634                                                                                    dataSourceElement,
635                                                                                    PRE_DWPVS
636                                                                                                            + "FilterCondition",
637                                                                                    nsContext );
638                        GetCoverage getCoverage = parseWCSFilterCondition( filterElement );
639                        Color[] transparentColors = parseTransparentColors( dataSourceElement );
640    
641                        dataSource = new RemoteWCSDataSource( name, owsCapabilities, validArea,
642                                                              minScaleDenom, maxScaleDenom,
643                                                              getCoverage, transparentColors );
644                        LOG.logDebug( "created remote wcs with name: " + name );
645    
646                    } else if ( nodeName.equals( "LocalWFSDataSource" ) ) {
647                        Text geoPropNode = (Text) XMLTools.getRequiredNode(
648                                                                            dataSourceElement,
649                                                                            PRE_DWPVS
650                                                                                                    + "GeometryProperty/text()",
651                                                                            nsContext );
652                        PropertyPath geometryProperty = parsePropertyPath( geoPropNode );
653    
654                        Element filterElement = (Element) XMLTools.getNode(
655                                                                            dataSourceElement,
656                                                                            PRE_DWPVS
657                                                                                                    + "FilterCondition/ogc:Filter",
658                                                                            nsContext );
659    
660                        Filter filterCondition = null;
661                        if ( filterElement != null ) {
662                            filterCondition = AbstractFilter.buildFromDOM( filterElement, false );
663                        }
664    
665                        // FeatureCollectionAdapter adapter = createFCAdapterFromAdapterClassName(
666                        // dataSourceElement );
667    
668                        dataSource = new LocalWFSDataSource( name, owsCapabilities, validArea,
669                                                             minScaleDenom, maxScaleDenom,
670                                                             geometryProperty, filterCondition/*
671                                                                                                 * ,
672                                                                                                 * adapter
673                                                                                                 */);
674                        LOG.logDebug( "created local wfs with name: " + name );
675    
676                    } else if ( nodeName.equals( "RemoteWFSDataSource" ) ) {
677                        Text geoPropNode = (Text) XMLTools.getRequiredNode(
678                                                                            dataSourceElement,
679                                                                            PRE_DWPVS
680                                                                                                    + "GeometryProperty/text()",
681                                                                            nsContext );
682                        PropertyPath geometryProperty = parsePropertyPath( geoPropNode );
683    
684                        Element filterElement = (Element) XMLTools.getNode(
685                                                                            dataSourceElement,
686                                                                            PRE_DWPVS
687                                                                                                    + "FilterCondition/ogc:Filter",
688                                                                            nsContext );
689    
690                        Filter filterCondition = null;
691                        if ( filterElement != null ) {
692                            filterCondition = AbstractFilter.buildFromDOM( filterElement, false );
693                        }
694    
695                        // FeatureCollectionAdapter adapter = createFCAdapterFromAdapterClassName(
696                        // dataSourceElement );
697    
698                        dataSource = new RemoteWFSDataSource( name, owsCapabilities, validArea,
699                                                              minScaleDenom, maxScaleDenom,
700                                                              geometryProperty, filterCondition
701                        /* ,adapter */);
702                        LOG.logDebug( "created remote wfs with name: " + name );
703    
704                    } else if ( nodeName.equals( "LocalWMSDataSource" ) ) {
705                        if ( element.getNodeName().endsWith( "ElevationModel" ) ) {
706                            throw new InvalidConfigurationException( "An ElevationModel cannot "
707                                                                     + "contain a LocalWMSDataSource!" );
708                        }
709                        Element filterElement = (Element) XMLTools.getRequiredNode(
710                                                                                    dataSourceElement,
711                                                                                    PRE_DWPVS
712                                                                                                            + "FilterCondition",
713                                                                                    nsContext );
714                        GetMap getMap = parseWMSFilterCondition( filterElement );
715    
716                        Color[] transparentColors = parseTransparentColors( dataSourceElement );
717    
718                        dataSource = new LocalWMSDataSource( name, owsCapabilities, validArea,
719                                                             minScaleDenom, maxScaleDenom, getMap,
720                                                             transparentColors );
721                        LOG.logDebug( "created local wms with name: " + name );
722    
723                    } else if ( nodeName.equals( "RemoteWMSDataSource" ) ) {
724                        if ( element.getNodeName().endsWith( "ElevationModel" ) ) {
725                            throw new InvalidConfigurationException( "An ElevationModel cannot "
726                                                                     + "contain a LocalWMSDataSource!" );
727                        }
728                        Element filterElement = (Element) XMLTools.getRequiredNode(
729                                                                                    dataSourceElement,
730                                                                                    PRE_DWPVS
731                                                                                                            + "FilterCondition",
732                                                                                    nsContext );
733                        GetMap getMap = parseWMSFilterCondition( filterElement );
734    
735                        Color[] transparentColors = parseTransparentColors( dataSourceElement );
736    
737                        dataSource = new RemoteWMSDataSource( name, owsCapabilities, validArea,
738                                                              minScaleDenom, maxScaleDenom, getMap,
739                                                              transparentColors );
740                        LOG.logDebug( "created remote wms with name: " + name );
741                    } else {
742                        throw new InvalidCapabilitiesException( "Unknown data source: '" + nodeName
743                                                                + "'" );
744                    }
745    
746                    tempDataSources.add( dataSource );
747                }
748            }
749    
750            AbstractDataSource[] dataSources = tempDataSources.toArray( new AbstractDataSource[tempDataSources.size()] );
751    
752            return dataSources;
753        }
754    
755        /**
756         * FIXME check content of StringBuffer and Map! This is an adapted copy from:
757         * org.deegree.ogcwebservices.wms.configuration#parseWMSFilterCondition(Node)
758         * 
759         * Creates and returns a new <code>GetMap</code> object from the given <code>Element</code>.
760         * 
761         * @param filterElement
762         * @return a partial wms GetMap request instance
763         * @throws XMLParsingException
764         */
765        private GetMap parseWMSFilterCondition( Element filterElement )
766                                throws XMLParsingException {
767    
768            GetMap getMap = null;
769    
770            String wmsRequest = XMLTools.getRequiredNodeAsString( filterElement, PRE_DWPVS
771                                                                                 + "WMSRequest/text()",
772                                                                  nsContext );
773    
774            StringBuffer sd = new StringBuffer( 1000 );
775            sd.append( "REQUEST=GetMap&LAYERS=%default%&STYLES=&SRS=EPSG:4326&" );
776            sd.append( "BBOX=0,0,1,1&WIDTH=1&HEIGHT=1&FORMAT=%default%" );
777    
778            Map<String, String> map1 = KVP2Map.toMap( sd.toString() );
779    
780            Map<String, String> map2 = KVP2Map.toMap( wmsRequest );
781            if ( map2.get( "VERSION" ) == null && map2.get( "WMTVER" ) == null ) {
782                map2.put( "VERSION", "1.1.1" );
783            }
784            // if no service is set use WMS as default
785            if ( map2.get( "SERVICE" ) == null ) {
786                map2.put( "SERVICE", "WMS" );
787            }
788    
789            map1.putAll( map2 );
790    
791            String id = Long.toString( IDGenerator.getInstance().generateUniqueID() );
792            map1.put( "ID", id );
793            try {
794                getMap = GetMap.create( map1 );
795            } catch ( Exception e ) {
796                throw new XMLParsingException( "could not create GetMap from WMS FilterCondition", e );
797            }
798    
799            return getMap;
800        }
801    
802        /**
803         * FIXME check content of StringBuffer ! This is an adapted copy from:
804         * org.deegree.ogcwebservices.wms.configuration#parseWCSFilterCondition(Node)
805         * 
806         * Creates and returns a new <code>GetCoverage</code> object from the given
807         * <code>Element</code>.
808         * 
809         * @param filterElement
810         * @return a partial GetCoverage request
811         * @throws XMLParsingException
812         */
813        private GetCoverage parseWCSFilterCondition( Element filterElement )
814                                throws XMLParsingException {
815    
816            GetCoverage coverage = null;
817    
818            String wcsRequest = XMLTools.getRequiredNodeAsString( filterElement, PRE_DWPVS
819                                                                                 + "WCSRequest/text()",
820                                                                  nsContext );
821    
822            StringBuffer sd = new StringBuffer( 1000 );
823            sd.append( "version=1.0.0&Coverage=%default%&CRS=EPSG:4326&BBOX=0,0,1,1" );
824            sd.append( "&Width=1&Height=1&Format=%default%&" );
825            sd.append( wcsRequest );
826    
827            String id = "" + IDGenerator.getInstance().generateUniqueID();
828    
829            try {
830                coverage = GetCoverage.create( id, sd.toString() );
831            } catch ( Exception e ) {
832                throw new XMLParsingException( "Could not create GetCoverage "
833                                               + "from WPVS FilterCondition", e );
834            }
835    
836            return coverage;
837        }
838    
839        /**
840         * Creates and returns a new <code>OWSCapabilities</code> object from the given
841         * <code>Element</code>.
842         * 
843         * @param element
844         * @return Returns a new OWSCapabilities object.
845         * @throws XMLParsingException
846         * @throws InvalidCapabilitiesException
847         */
848        private OWSCapabilities parseOWSCapabilities( Element element )
849                                throws XMLParsingException, InvalidCapabilitiesException {
850    
851            Element owsCapabilitiesElement = (Element) XMLTools.getRequiredNode(
852                                                                                 element,
853                                                                                 PRE_DWPVS
854                                                                                                         + "OWSCapabilities",
855                                                                                 nsContext );
856    
857            String format = null;
858    
859            // FIXME
860            // schema has onlineResourceType as not optional, so it should be mandatory.
861            // but in other examples onlineResource is never created with this onlineResourceType.
862            // therefore it gets omitted here, too.
863    
864            // String onlineResourceType = XMLTools.getRequiredNodeAsString(
865            // owsCapabilitiesElement, PRE_DWPVS+"OnlineResource/@xlink:type", nsContext );
866    
867            String onlineResourceURI = XMLTools.getRequiredNodeAsString(
868                                                                         owsCapabilitiesElement,
869                                                                         PRE_DWPVS
870                                                                                                 + "OnlineResource/@xlink:href",
871                                                                         nsContext );
872    
873            URL onlineResource;
874            try {
875                onlineResource = resolve( onlineResourceURI );
876            } catch ( MalformedURLException e ) {
877                throw new InvalidCapabilitiesException( onlineResourceURI
878                                                        + " does not represent a valid URL: "
879                                                        + e.getMessage() );
880            }
881            LOG.logDebug( "found following onlineResource: " + onlineResource );
882            return new OWSCapabilities( format, onlineResource );
883    
884            // FIXME
885            // if onlineResourceType is going to be used, the returned new OnlineResource should be
886            // created with different constructor:
887            // return new OWSCapabilities( format, onlineResourceType, onlineResource );
888        }
889    
890        /**
891         * Creates and returns a new <code>Geometry</code> object from the given Element.
892         * 
893         * @param dataSource
894         * @return Returns a new Geometry object.
895         * @throws XMLParsingException
896         * @throws InvalidConfigurationException
897         */
898        private Surface parseValidArea( Element dataSource, CoordinateSystem defaultCRS )
899                                throws XMLParsingException, InvalidConfigurationException {
900            List nl = XMLTools.getNodes( dataSource, PRE_DWPVS + "ValidArea/*", nsContext );
901            if ( nl.size() == 0 ) {
902                return null;
903            }
904    
905            if ( nl.size() > 1 ) {
906                LOG.logWarning( Messages.getMessage( "WPVS_WRONG_NUMBER_OF_VALID_AREAS",
907                                                     GMLNS.toASCIIString(), dataSource.getLocalName() ) );
908                return null;
909            }
910            Surface validArea = null;
911            if ( ( (Node) nl.get( 0 ) ).getNamespaceURI().equals( GMLNS.toASCIIString() ) ) {
912                try {
913                    String srsName = XMLTools.getNodeAsString( (Node) nl.get( 0 ), "@srsName",
914                                                               nsContext, null );
915                    if ( srsName == null ) {
916                        srsName = defaultCRS.getFormattedString();
917                    }
918    
919                    Geometry geom = GMLGeometryAdapter.wrap( (Element) nl.get( 0 ), srsName );
920                    if ( !( geom instanceof Surface ) ) {
921                        throw new InvalidConfigurationException(
922                                                                 Messages.getMessage(
923                                                                                      "WPVS_WRONG_GEOMTERY_VALID_AREA",
924                                                                                      dataSource.getLocalName() ) );
925                    }
926                    validArea = (Surface) geom;
927                } catch ( GeometryException e ) {
928                    throw new InvalidConfigurationException(
929                                                             Messages.getMessage(
930                                                                                  "WPVS_WRONG_GEOMTERY_VALID_AREA",
931                                                                                  dataSource.getLocalName() )
932                                                                                     + "\n"
933                                                                                     + e.getMessage(),
934    
935                                                             e );
936                }
937    
938            } else if ( ( (Node) nl.get( 0 ) ).getNamespaceURI().equals( CommonNamespaces.OWSNS ) ) {
939                try {
940                    Element bbox = (Element) nl.get( 0 );
941                    if ( !"BoundingBox".equals( bbox.getLocalName() ) ) {
942                        throw new InvalidConfigurationException(
943                                                                 Messages.getMessage(
944                                                                                      "WPVS_WRONG_GEOMTERY_VALID_AREA",
945                                                                                      dataSource.getLocalName() ) );
946                    }
947                    Envelope env = parseBoundingBox( (Element) nl.get( 0 ), null );
948                    validArea = GeometryFactory.createSurface( env, env.getCoordinateSystem() );
949                } catch ( GeometryException e ) {
950                    throw new InvalidConfigurationException(
951                                                             Messages.getMessage(
952                                                                                  "WPVS_WRONG_GEOMTERY_VALID_AREA",
953                                                                                  dataSource.getLocalName() )
954                                                                                     + "\n"
955                                                                                     + e.getMessage(),
956                                                             e );
957                } catch ( InvalidParameterValueException e ) {
958                    throw new InvalidConfigurationException(
959                                                             Messages.getMessage(
960                                                                                  "WPVS_WRONG_GEOMTERY_VALID_AREA",
961                                                                                  dataSource.getLocalName() )
962                                                                                     + "\n"
963                                                                                     + e.getMessage(),
964                                                             e );
965                }
966            } else {
967                LOG.logWarning( Messages.getMessage( "WPVS_WRONG_GEOMTERY_VALID_AREA",
968                                                     dataSource.getLocalName() ) );
969                return null;
970            }
971            return validArea;
972        }
973    
974        /**
975         * Creates and returns a new array of <code>Color</code> objects from the given Element.
976         * 
977         * @param dataSourceElement
978         * @return Returns a new array of Color objects.
979         * @throws XMLParsingException
980         * @throws InvalidCapabilitiesException
981         */
982        private Color[] parseTransparentColors( Element dataSourceElement )
983                                throws XMLParsingException {
984    
985            List colorList = XMLTools.getNodes( dataSourceElement, PRE_DWPVS + "TransparentColors/"
986                                                                   + PRE_DWPVS + "Color", nsContext );
987    
988            Color[] transparentColors = null;
989            if ( colorList != null ) {
990                transparentColors = new Color[colorList.size()];
991    
992                for ( int i = 0; i < transparentColors.length; i++ ) {
993    
994                    Element colorElement = (Element) colorList.get( i );
995                    String color = XMLTools.getRequiredNodeAsString( colorElement, "text()", nsContext );
996    
997                    transparentColors[i] = Color.decode( color );
998                }
999            }
1000    
1001            return transparentColors;
1002        }
1003    
1004    }
1005    
1006    /***************************************************************************************************
1007     * <code>
1008     * Changes to this class. What the people have been up to:
1009     * 
1010     * $Log$
1011     * Revision 1.51  2007/03/08 10:16:42  bezema
1012     * added support for the extendRequestPercentage parameter and some small docu/code changes
1013     *
1014     * Revision 1.50  2007/03/06 14:56:55  poth
1015     * bug fix wpvs accessing a dataservices caps
1016     *
1017     * Revision 1.49  2007/03/05 10:19:46  bezema
1018     * removed the usage of an deprectated api
1019     *
1020     * Revision 1.48  2007/01/29 16:44:10  bezema
1021     * removing use of the deprecated api
1022     *
1023     * Revision 1.47  2007/01/29 09:05:16  bezema
1024     * removing use of the deprecated api
1025     *
1026     * Revision 1.46  2007/01/15 17:02:14  bezema
1027     * Updated the capabilities /configuration parsing, and the construction of their beans
1028     *
1029     * Revision 1.45  2006/12/22 13:37:35  poth
1030     * code formatting
1031     *
1032     * Revision 1.44  2006/12/21 11:22:04  bezema
1033     * removed the gabs in a pointbased dgm by interpolation of the nearest boundingbox points and Made the minimalterrainheight configurable.
1034     *
1035     * Revision 1.43  2006/12/20 14:31:50  bezema
1036     * removed syso
1037     *
1038     * Revision 1.42  2006/12/06 12:00:46  poth
1039     * bug fix - reading relative pathes
1040     *
1041     * Revision 1.41  2006/12/06 11:24:33  bezema
1042     * can use the wcs as a localdatasource for textures and dgm, also added support for the wfs features in gml. Still trying to figure out how the eyepoint is set by java3d
1043     *
1044     * Revision 1.40  2006/11/28 18:09:28  mschneider
1045     * Fixed header.
1046     *
1047     * Revision 1.39  2006/11/28 18:08:55  mschneider
1048     * Fixed parsing of GeometryProperty name. Namespace binding was not correctly extracted (null).
1049     *
1050     * Revision 1.38  2006/11/28 16:52:19  bezema Added support for a default splitter
1051     *
1052     * Revision 1.37  2006/11/27 15:41:13  bezema Updated the coordinatesystem handling and the featurecollection adapter
1053     *
1054     * Revision 1.36 2006/11/27 11:44:14 bezema Added a minimalScaleDenomitator check
1055    
1056     * Revision 1.34 2006/11/23 11:46:40 bezema The initial version of the new wpvs
1057     * 
1058     * Revision 1.33 2006/11/07 16:33:49 poth bug fixes and code formatting
1059     * 
1060     * Revision 1.32 2006/08/07 12:14:57 poth never read variable removed
1061     * 
1062     * Revision 1.31 2006/07/20 08:13:05 taddei use of QualiName for geometry property
1063     * 
1064     * Revision 1.30 2006/07/12 16:59:32 poth required adaptions according to renaming of OnLineResource to OnlineResource
1065     * 
1066     * Revision 1.29 2006/07/05 15:58:23 poth bug fix - changed Query to Filter for WFS datasources
1067     * 
1068     * Revision 1.28 2006/06/29 19:06:54 poth ** empty log message ***
1069     * 
1070     * Revision 1.27 2006/06/29 18:50:16 poth bug fix reading optional element TransparentColors
1071     * 
1072     * Revision 1.26 2006/06/20 07:45:21 taddei datasources use quali names now
1073     * 
1074     * Revision 1.25 2006/05/05 12:41:36 taddei fixed bug in max tex size
1075     * 
1076     * Revision 1.24 2006/04/26 12:13:07 taddei max size and tex config parameters
1077     * 
1078     * Revision 1.23 2006/04/06 20:25:24 poth ** empty log message ***
1079     * 
1080     * Revision 1.22 2006/04/05 08:56:21 taddei refactoring: fc adapter
1081     * 
1082     * Revision 1.20 2006/03/07 08:46:26 taddei added pts list factory
1083     * 
1084     * Revision 1.19 2006/02/14 15:14:43 taddei added possibility to choose splitter
1085     * 
1086     * Revision 1.18 2006/02/10 16:05:41 taddei capabilities use now resolve()
1087     * 
1088     * Revision 1.17 2006/01/30 14:56:10 taddei implementation of copyright info
1089     * 
1090     * Revision 1.16 2006/01/26 13:54:59 taddei added code for parsing ElevationModel/Name
1091     * 
1092     * Revision 1.15 2006/01/18 08:47:54 taddei bug fixes
1093     * 
1094     * Revision 1.14 2005/12/23 11:16:50 mays add comments
1095     * 
1096     * Revision 1.13 2005/12/23 10:39:19 mays add imports that where accidentally lost
1097     * 
1098     * Revision 1.12 2005/12/23 10:34:56 mays correction of color and filterConditions
1099     * 
1100     * Revision 1.10 2005/12/13 13:31:49 mays changes in parseElevationModel because of necessary changes in namespace
1101     * 
1102     * Revision 1.9 2005/12/12 13:51:38 mays revision of parseElevationModel, parseDataset, parseDeegreeParams and parseOWSCapabilities.
1103     * 
1104     * Revision 1.8 2005/12/09 14:11:22 mays code clean up
1105     * 
1106     * Revision 1.7 2005/12/08 16:53:10 mays organized imports
1107     * 
1108     * Revision 1.6 2005/12/08 16:49:08 mays move configuration specific stuff from WPVSCapabilitiesDocument to here
1109     * 
1110     * Revision 1.5 2005/12/01 10:30:14 mays add standard footer to all java classes in wpvs package
1111     * </code>
1112     **************************************************************************************************/