//$Header: /home/deegree/jail/deegreerepository/deegree/src/org/deegree/ogcwebservices/wpvs/capabilities/WPVSCapabilitiesDocument.java,v 1.31 2006/11/27 15:40:32 bezema Exp $
/*---------------- FILE HEADER ------------------------------------------
This file is part of deegree.
Copyright (C) 2001-2006 by:
EXSE, Department of Geography, University of Bonn
http://www.giub.uni-bonn.de/deegree/
lat/lon GmbH
http://www.lat-lon.de
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Contact:
Andreas Poth
lat/lon GmbH
Aennchenstraße 19
53177 Bonn
Germany
E-Mail: poth@lat-lon.de
Prof. Dr. Klaus Greve
Department of Geography
University of Bonn
Meckenheimer Allee 166
53115 Bonn
Germany
E-Mail: greve@giub.uni-bonn.de
---------------------------------------------------------------------------*/
package org.deegree.ogcwebservices.wpvs.capabilities;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.deegree.datatypes.values.TypedLiteral;
import org.deegree.datatypes.values.ValueRange;
import org.deegree.datatypes.xlink.SimpleLink;
import org.deegree.framework.log.ILogger;
import org.deegree.framework.log.LoggerFactory;
import org.deegree.framework.util.StringTools;
import org.deegree.framework.xml.NamespaceContext;
import org.deegree.framework.xml.XMLParsingException;
import org.deegree.framework.xml.XMLTools;
import org.deegree.model.crs.CRSFactory;
import org.deegree.model.crs.CoordinateSystem;
import org.deegree.model.crs.UnknownCRSException;
import org.deegree.model.metadata.iso19115.Keywords;
import org.deegree.model.spatialschema.Envelope;
import org.deegree.model.spatialschema.GeometryFactory;
import org.deegree.model.spatialschema.Position;
import org.deegree.ogcbase.CommonNamespaces;
import org.deegree.ogcwebservices.InvalidParameterValueException;
import org.deegree.ogcwebservices.MissingParameterValueException;
import org.deegree.ogcwebservices.OGCWebServiceException;
import org.deegree.ogcwebservices.getcapabilities.DCPType;
import org.deegree.ogcwebservices.getcapabilities.InvalidCapabilitiesException;
import org.deegree.ogcwebservices.getcapabilities.OGCCapabilities;
import org.deegree.ogcwebservices.getcapabilities.OperationsMetadata;
import org.deegree.ogcwebservices.getcapabilities.Protocol;
import org.deegree.owscommon.OWSCommonCapabilitiesDocument;
import org.deegree.owscommon.OWSMetadata;
import org.deegree.owscommon.com110.HTTP110;
import org.deegree.owscommon.com110.OWSAllowedValues;
import org.deegree.owscommon.com110.OWSDomainType110;
import org.deegree.owscommon.com110.OWSRequestMethod;
import org.deegree.owscommon.com110.Operation110;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.xml.sax.SAXException;
/**
* This class represents a <code>WPVSCapabilitiesDocument</code> object.
*
* @author <a href="mailto:mays@lat-lon.de">Judit Mays</a>
* @author last edited by: $Author: bezema $
*
* $Revision: 1.31 $, $Date: 2006/11/27 15:40:32 $
*
*/
public class WPVSCapabilitiesDocument extends OWSCommonCapabilitiesDocument {
/**
*
*/
private static final long serialVersionUID = 2633513531080190745L;
private static final ILogger LOG = LoggerFactory.getLogger( WPVSCapabilitiesDocument.class );
private static final String XML_TEMPLATE = "WPVSCapabilitiesTemplate.xml";
private static String PRE_DWPVS = CommonNamespaces.DEEGREEWPVS_PREFIX + ":";
/**
* Creates a skeleton capabilities document that contains the mandatory elements only.
*
* @throws IOException
* @throws SAXException
*/
public void createEmptyDocument()
throws IOException, SAXException {
URL url = WPVSCapabilitiesDocument.class.getResource( XML_TEMPLATE );
if ( url == null ) {
throw new IOException( "The resource '" + XML_TEMPLATE + " could not be found." );
}
load( url );
}
/**
* @see org.deegree.ogcwebservices.getcapabilities.OGCCapabilitiesDocument#parseCapabilities()
*/
@Override
public OGCCapabilities parseCapabilities()
throws InvalidCapabilitiesException {
LOG.entering();
WPVSCapabilities wpvsCapabilities = null;
try {
wpvsCapabilities = new WPVSCapabilities( parseVersion(), parseUpdateSequence(),
getServiceIdentification(),
getServiceProvider(),
parseOperationsMetadata(), null, getDataset() );
} catch ( XMLParsingException e ) {
throw new InvalidCapabilitiesException( e.getMessage() + "\n"
+ StringTools.stackTraceToString( e ) );
} catch ( MissingParameterValueException e ) {
throw new InvalidCapabilitiesException( e.getMessage() + "\n"
+ StringTools.stackTraceToString( e ) );
} catch ( InvalidParameterValueException e ) {
throw new InvalidCapabilitiesException( e.getMessage() + "\n"
+ StringTools.stackTraceToString( e ) );
} catch ( OGCWebServiceException e ) {
throw new InvalidCapabilitiesException( e.getMessage() + "\n"
+ StringTools.stackTraceToString( e ) );
}
LOG.exiting();
return wpvsCapabilities;
}
/**
* Gets the <code>Dataset</code> object from the root element of the WPVSCapabilities element.
*
* @return Returns the Dataset object form root element.
* @throws XMLParsingException
* @throws OGCWebServiceException
* @throws InvalidParameterValueException
* @throws MissingParameterValueException
*/
private Dataset getDataset()
throws XMLParsingException, MissingParameterValueException,
InvalidParameterValueException, OGCWebServiceException {
Element datasetElement = (Element) XMLTools.getRequiredNode( getRootElement(), PRE_DWPVS
+ "Dataset",
nsContext );
Dataset dataset = parseDataset( datasetElement, null );
return dataset;
}
/**
* Creates and returns a new <code>Dataset</code> object from the given <code>Element</code>
* and the parent <code>Dataset</code> object.
*
* @param datasetElement
* @param parent
* may be null
* @return Returns a new Dataset object.
* @throws XMLParsingException
* @throws OGCWebServiceException
* @throws InvalidParameterValueException
* @throws MissingParameterValueException
*/
private Dataset parseDataset( Element datasetElement, Dataset parent )
throws XMLParsingException, MissingParameterValueException,
InvalidParameterValueException, OGCWebServiceException {
LOG.entering();
// attributes
boolean queryable = XMLTools.getNodeAsBoolean( datasetElement, "./@queryable", nsContext,
false );
boolean opaque = XMLTools.getNodeAsBoolean( datasetElement, "./@opaque", nsContext, false );
boolean noSubsets = XMLTools.getNodeAsBoolean( datasetElement, "./@noSubsets", nsContext,
false );
int fixedWidth = XMLTools.getNodeAsInt( datasetElement, "./@fixedWidth", nsContext, 0 );
int fixedHeight = XMLTools.getNodeAsInt( datasetElement, "./@fixedHeight", nsContext, 0 );
// elements
String name = XMLTools.getNodeAsString( datasetElement, PRE_DWPVS + "Name/text()",
nsContext, null );
String title = XMLTools.getRequiredNodeAsString( datasetElement,
PRE_DWPVS + "Title/text()", nsContext );
String abstract_ = XMLTools.getNodeAsString( datasetElement, PRE_DWPVS + "Abstract/text()",
nsContext, null );
Keywords[] keywords = getKeywords( XMLTools.getNodes( datasetElement, "ows:Keywords",
nsContext ) );
String[] crsStrings = XMLTools.getNodesAsStrings( datasetElement, PRE_DWPVS + "CRS/text()",
nsContext );
List<CoordinateSystem> crsList = parseCoordinateSystems( crsStrings );
String[] format = XMLTools.getRequiredNodesAsStrings( datasetElement, PRE_DWPVS
+ "Format/text()",
nsContext );
Envelope wgs84BoundingBox = getBoundingBox( datasetElement, "ows:WGS84BoundingBox" );
Envelope[] boundingBoxes = getBoundingBoxes( datasetElement, parent );
Dimension[] dimensions = parseDimensions( datasetElement );
DataProvider dataProvider = parseDataProvider( datasetElement );
Identifier identifier = parseIdentifier( datasetElement, PRE_DWPVS + "Identifier" );
MetaData[] metaData = parseMetaData( datasetElement );
DatasetReference[] datasetRefs = parseDatasetReferences( datasetElement );
FeatureListReference[] featureListRefs = parseFeatureListReferences( datasetElement );
Style[] style = parseStyles( datasetElement );
double minScaleDenom = XMLTools.getNodeAsDouble(
datasetElement,
PRE_DWPVS
+ "MinimumScaleDenominator/text()",
nsContext, 0 );
double maxScaleDenom = XMLTools.getNodeAsDouble(
datasetElement,
PRE_DWPVS
+ "MaximumScaleDenominator/text()",
nsContext, 9E9 );
if ( minScaleDenom >= maxScaleDenom ) {
throw new InvalidCapabilitiesException( "MinimumScaleDenominator must be "
+ "less than MaximumScaleDenominator!" );
}
ElevationModel elevationModel = parseElevationModel( datasetElement );
// create new root dataset
Dataset dataset = new Dataset( queryable, opaque, noSubsets, fixedWidth, fixedHeight, name,
title, abstract_, keywords, crsList, format,
wgs84BoundingBox, boundingBoxes, dimensions, dataProvider,
identifier, metaData, datasetRefs, featureListRefs, style,
minScaleDenom, maxScaleDenom, null, elevationModel, null,
parent );
// get child datasets
List nl = XMLTools.getNodes( datasetElement, PRE_DWPVS + "Dataset", nsContext );
Dataset[] childDatasets = new Dataset[nl.size()];
for ( int i = 0; i < childDatasets.length; i++ ) {
childDatasets[i] = parseDataset( (Element) nl.get( i ), dataset );
}
// set child datasets
dataset.setDatasets( childDatasets );
LOG.exiting();
return dataset;
}
protected List<CoordinateSystem> parseCoordinateSystems( String[] coordinateStrings ){
if( coordinateStrings == null ) return new ArrayList<CoordinateSystem>( );
ArrayList<CoordinateSystem> crsList = new ArrayList<CoordinateSystem>( coordinateStrings.length );
for ( String tmpCRS : coordinateStrings ) {
try {
CoordinateSystem crs = CRSFactory.create( tmpCRS );
crsList.add( crs );
} catch ( UnknownCRSException e ) {
// fail configuration notify the user
LOG.logError( e.getLocalizedMessage(), e );
}
}
return crsList;
}
/**
* Creates and returns a new <code>ElevationModel</code> object from the given
* <code>Element</code>.
*
* This OGC ElevationModel contains only a String.
*
* @param datasetElement
* @return Returns the ElevationModel object.
* @throws XMLParsingException
*/
private ElevationModel parseElevationModel( Element datasetElement )
throws XMLParsingException {
String name = XMLTools.getRequiredNodeAsString( datasetElement, PRE_DWPVS
+ "ElevationModel/text()",
nsContext );
ElevationModel elevationModel = new ElevationModel( name );
return elevationModel;
}
/**
* Creates and returns a new array of <code>Style</code> objects from the given
* <code>Element</code>.
*
* @param datasetElement
* @return Returns a new array of Style objects.
* @throws XMLParsingException
* @throws InvalidCapabilitiesException
*/
protected Style[] parseStyles( Element datasetElement )
throws XMLParsingException, InvalidCapabilitiesException {
List styleList = XMLTools.getNodes( datasetElement, PRE_DWPVS + "Style", nsContext );
Style[] styles = new Style[styleList.size()];
for ( int i = 0; i < styles.length; i++ ) {
Element styleElement = (Element) styleList.get( i );
String name = XMLTools.getRequiredNodeAsString( styleElement,
PRE_DWPVS + "Name/text()", nsContext );
String title = XMLTools.getRequiredNodeAsString( styleElement, PRE_DWPVS
+ "Title/text()",
nsContext );
String abstract_ = XMLTools.getRequiredNodeAsString( styleElement, PRE_DWPVS
+ "Abstract/text()",
nsContext );
Keywords[] keywords = getKeywords( XMLTools.getNodes( styleElement, "ows:Keywords",
nsContext ) );
Identifier identifier = parseIdentifier( styleElement, PRE_DWPVS + "Identifier" );
LegendURL[] legendURLs = parseLegendURLs( styleElement );
StyleSheetURL styleSheetURL = parseStyleSheetURL( styleElement );
StyleURL styleURL = parseStyleURL( styleElement );
styles[i] = new Style( name, title, abstract_, keywords, identifier, legendURLs,
styleSheetURL, styleURL );
}
return styles;
}
/**
* Creates and returns a new <code>StyleURL</code> object from the given <code>Element</code>.
*
* @param styleElement
* @return Returns a new StyleURL object.
* @throws XMLParsingException
* @throws InvalidCapabilitiesException
*/
private StyleURL parseStyleURL( Element styleElement )
throws XMLParsingException, InvalidCapabilitiesException {
Element StyleURLElement = (Element) XMLTools.getNode( styleElement, PRE_DWPVS + "StyleURL",
nsContext );
String format = XMLTools.getRequiredNodeAsString( StyleURLElement, PRE_DWPVS
+ "Format/text()",
nsContext );
URI onlineResourceURI = XMLTools.getNodeAsURI( StyleURLElement,
PRE_DWPVS + "OnlineResource/@xlink:href",
nsContext, null );
URL onlineResource;
try {
onlineResource = onlineResourceURI.toURL();
} catch ( MalformedURLException e ) {
throw new InvalidCapabilitiesException( onlineResourceURI
+ " does not represent a valid URL: "
+ e.getMessage() );
}
return new StyleURL( format, onlineResource );
}
/**
* Creates and returns a new <code>StyleSheetURL</code> object from the given
* <code>Element</code>.
*
* @param styleElement
* @return Returns a new StyleSheetURL object.
* @throws XMLParsingException
* @throws InvalidCapabilitiesException
*/
private StyleSheetURL parseStyleSheetURL( Element styleElement )
throws XMLParsingException, InvalidCapabilitiesException {
Element StyleSheetURLElement = (Element) XMLTools.getNode( styleElement, PRE_DWPVS
+ "StyleSheetURL",
nsContext );
String format = XMLTools.getRequiredNodeAsString( StyleSheetURLElement, PRE_DWPVS
+ "Format/text()",
nsContext );
URI onlineResourceURI = XMLTools.getNodeAsURI( StyleSheetURLElement,
PRE_DWPVS + "OnlineResource/@xlink:href",
nsContext, null );
URL onlineResource;
try {
onlineResource = onlineResourceURI.toURL();
} catch ( MalformedURLException e ) {
throw new InvalidCapabilitiesException( onlineResourceURI
+ " does not represent a valid URL: "
+ e.getMessage() );
}
return new StyleSheetURL( format, onlineResource );
}
/**
* Creates and returns a new array of <code>LegendURL</code> objects from the given
* <code>Element</code>.
*
* @param styleElement
* @return Returns a new array of LegendURL objects.
* @throws XMLParsingException
* @throws InvalidCapabilitiesException
*/
private LegendURL[] parseLegendURLs( Element styleElement )
throws XMLParsingException, InvalidCapabilitiesException {
List legendList = XMLTools.getNodes( styleElement, PRE_DWPVS + "LegendURL", nsContext );
LegendURL[] legendURLs = new LegendURL[legendList.size()];
for ( int i = 0; i < legendURLs.length; i++ ) {
Element legendURLElement = (Element) legendList.get( i );
int width = XMLTools.getRequiredNodeAsInt( legendURLElement, "./@width", nsContext );
int height = XMLTools.getRequiredNodeAsInt( legendURLElement, "./@height", nsContext );
if ( width < 0 || height < 0 ) {
throw new InvalidCapabilitiesException( "The attributes width and height of '"
+ legendURLElement.getNodeName()
+ "' must be positive!" );
}
String format = XMLTools.getRequiredNodeAsString( legendURLElement, PRE_DWPVS
+ "Format/text()",
nsContext );
URI onlineResourceURI = XMLTools.getNodeAsURI(
legendURLElement,
PRE_DWPVS + "OnlineResource/@xlink:href",
nsContext, null );
URL onlineResource;
try {
onlineResource = onlineResourceURI.toURL();
} catch ( MalformedURLException e ) {
throw new InvalidCapabilitiesException( onlineResourceURI
+ " does not represent a valid URL: "
+ e.getMessage() );
}
legendURLs[i] = new LegendURL( width, height, format, onlineResource );
}
return legendURLs;
}
/**
* Creates and returns a new array of <code>FeatureListReference</code> objects from the given
* <code>Element</code>.
*
* @param datasetElement
* @return Returns a new array of FeatureListReference objects.
* @throws XMLParsingException
* @throws InvalidCapabilitiesException
*/
protected FeatureListReference[] parseFeatureListReferences( Element datasetElement )
throws XMLParsingException, InvalidCapabilitiesException {
List featureList = XMLTools.getNodes( datasetElement, PRE_DWPVS + "FeatureListReference",
nsContext );
FeatureListReference[] featureRefs = new FeatureListReference[featureList.size()];
for ( int i = 0; i < featureRefs.length; i++ ) {
Element featureRefElement = (Element) featureList.get( i );
String format = XMLTools.getRequiredNodeAsString( featureRefElement, PRE_DWPVS
+ "Format/text()",
nsContext );
URI onlineResourceURI = XMLTools.getNodeAsURI(
featureRefElement,
PRE_DWPVS + "OnlineResource/@xlink:href",
nsContext, null );
URL onlineResource;
try {
onlineResource = onlineResourceURI.toURL();
} catch ( MalformedURLException e ) {
throw new InvalidCapabilitiesException( onlineResourceURI
+ " does not represent a valid URL: "
+ e.getMessage() );
}
featureRefs[i] = new FeatureListReference( format, onlineResource );
}
return featureRefs;
}
/**
* Creates and returns a new array of <code>DatasetReference</code> objects from the given
* <code>Element</code>.
*
* @param datasetElement
* @return Returns a new array of DatasetReference objects.
* @throws XMLParsingException
* @throws InvalidCapabilitiesException
*/
protected DatasetReference[] parseDatasetReferences( Element datasetElement )
throws XMLParsingException, InvalidCapabilitiesException {
List datasetRefList = XMLTools.getNodes( datasetElement, PRE_DWPVS + "DatasetReference",
nsContext );
DatasetReference[] datasetRefs = new DatasetReference[datasetRefList.size()];
for ( int i = 0; i < datasetRefs.length; i++ ) {
Element datasetRefElement = (Element) datasetRefList.get( i );
String format = XMLTools.getRequiredNodeAsString( datasetRefElement, PRE_DWPVS
+ "Format/text()",
nsContext );
URI onlineResourceURI = XMLTools.getNodeAsURI(
datasetRefElement,
PRE_DWPVS + "OnlineResource/@xlink:href",
nsContext, null );
URL onlineResource;
try {
onlineResource = onlineResourceURI.toURL();
} catch ( MalformedURLException e ) {
throw new InvalidCapabilitiesException( onlineResourceURI
+ " does not represent a valid URL: "
+ e.getMessage() );
}
datasetRefs[i] = new DatasetReference( format, onlineResource );
}
return datasetRefs;
}
/**
* Creates and returns a new <code>MetaData</code> object from the given <code>Element</code>.
*
* @param datasetElement
* @return Returns a new MetaData object.
* @throws XMLParsingException
* @throws InvalidCapabilitiesException
*/
protected MetaData[] parseMetaData( Element datasetElement )
throws XMLParsingException, InvalidCapabilitiesException {
List metaDataList = XMLTools.getNodes( datasetElement, PRE_DWPVS + "MetaData", nsContext );
MetaData[] metaData = new MetaData[metaDataList.size()];
for ( int i = 0; i < metaData.length; i++ ) {
Element metaDataElement = (Element) metaDataList.get( i );
String type = XMLTools.getRequiredNodeAsString( metaDataElement, "./@type", nsContext );
String format = XMLTools.getRequiredNodeAsString( metaDataElement, PRE_DWPVS
+ "Format/text()",
nsContext );
URI onlineResourceURI = XMLTools.getNodeAsURI(
metaDataElement,
PRE_DWPVS + "OnlineResource/@xlink:href",
nsContext, null );
URL onlineResource;
try {
onlineResource = onlineResourceURI.toURL();
} catch ( MalformedURLException e ) {
throw new InvalidCapabilitiesException( onlineResourceURI
+ " does not represent a valid URL: "
+ e.getMessage() );
}
metaData[i] = new MetaData( type, format, onlineResource );
}
return metaData;
}
/**
* Creates and returns a new <code>Identifier</code> object from the given
* <code>Element</code> and the given <cod>xPathQuery</code>.
*
* @param element
* @param xPathQuery
* @return Returns a new Identifier object.
* @throws XMLParsingException
*/
protected Identifier parseIdentifier( Element element, String xPathQuery )
throws XMLParsingException {
Element identifierElement = (Element) XMLTools.getNode( element, xPathQuery, nsContext );
Identifier id = null;
if ( identifierElement != null ) {
String value = XMLTools.getNodeAsString( identifierElement, "./text()", nsContext, null );
String codeSpace = XMLTools.getNodeAsString( identifierElement, "./@codeSpace",
nsContext, null );
id = new Identifier( value, codeSpace );
}
return id;
}
/**
* Creates and returns a new <code>DataProvider</code> object from the given
* <code>Element</code>.
*
* @param datasetElement
* @return Returns a new DataProvider object.
* @throws XMLParsingException
* @throws InvalidCapabilitiesException
*/
protected DataProvider parseDataProvider( Element datasetElement )
throws XMLParsingException, InvalidCapabilitiesException {
String providerName = null;
URL providerSite = null;
LogoURL logoURL = null;
Element dataProviderElement = (Element) XMLTools.getNode( datasetElement, PRE_DWPVS
+ "DataProvider",
nsContext );
if ( dataProviderElement != null ) {
providerName = XMLTools.getNodeAsString( dataProviderElement, PRE_DWPVS
+ "ProviderName/text()",
nsContext, null );
URI providerSiteURI = XMLTools.getNodeAsURI( dataProviderElement,
PRE_DWPVS + "ProviderSite/@xlink:href",
nsContext, null );
try {
providerSite = providerSiteURI.toURL();
} catch ( MalformedURLException e ) {
throw new InvalidCapabilitiesException( providerSiteURI
+ " does not represent a valid URL: "
+ e.getMessage() );
}
Element logoURLElement = (Element) XMLTools.getNode( dataProviderElement, PRE_DWPVS
+ "LogoURL",
nsContext );
if ( logoURLElement != null ) {
int width = XMLTools.getRequiredNodeAsInt( logoURLElement, "./@width", nsContext );
int height = XMLTools.getRequiredNodeAsInt( logoURLElement, "./@height", nsContext );
if ( width < 0 || height < 0 ) {
throw new InvalidCapabilitiesException( "width and height of '"
+ logoURLElement
+ "' must be positive!" );
}
String format = XMLTools.getRequiredNodeAsString( logoURLElement,
PRE_DWPVS + "Format/text()",
nsContext );
URI onlineResourceURI = XMLTools.getNodeAsURI(
logoURLElement,
PRE_DWPVS
+ "OnlineResource/@xlink:href",
nsContext, null );
URL onlineResource;
try {
onlineResource = onlineResourceURI.toURL();
} catch ( MalformedURLException e ) {
throw new InvalidCapabilitiesException( onlineResourceURI
+ " does not represent a valid URL: "
+ e.getMessage() );
}
logoURL = new LogoURL( width, height, format, onlineResource );
}
}
return new DataProvider( providerName, providerSite, logoURL );
}
/**
* TODO adapted copy from WMSCapabilitiesDocument#parseDimensions(). move to common class ?!
* changed some object types and added more attribs.
*
* @param element
* @return
* @throws XMLParsingException
*/
protected Dimension[] parseDimensions( Element element )
throws XMLParsingException {
LOG.entering();
List nl = XMLTools.getNodes( element, PRE_DWPVS + "Dimension", nsContext );
Dimension[] dimensions = new Dimension[nl.size()];
for ( int i = 0; i < dimensions.length; i++ ) {
String name = XMLTools.getRequiredNodeAsString( (Node) nl.get( i ), "./@name",
nsContext );
String units = XMLTools.getRequiredNodeAsString( (Node) nl.get( i ), "./@units",
nsContext );
String unitSymbol = XMLTools.getNodeAsString( (Node) nl.get( i ), "./@unitSymbol",
nsContext, null );
String default_ = XMLTools.getNodeAsString( (Node) nl.get( i ), "./@default",
nsContext, null );
Boolean multipleValues = Boolean.valueOf( XMLTools.getNodeAsBoolean(
(Node) nl.get( i ),
"./@multipleValues",
nsContext, true ) );
Boolean nearestValues = Boolean.valueOf( XMLTools.getNodeAsBoolean( (Node) nl.get( i ),
"./@nearestValues",
nsContext, true ) );
Boolean current = Boolean.valueOf( XMLTools.getNodeAsBoolean( (Node) nl.get( i ),
"./@current", nsContext,
true ) );
String value = XMLTools.getNodeAsString( (Node) nl.get( i ), ".", nsContext, null );
dimensions[i] = new Dimension( name, units, unitSymbol, default_, multipleValues,
nearestValues, current, value );
}
LOG.exiting();
return dimensions;
}
/**
* Gets an array of <code>boundingBoxes</code> from the given <code>Element</code>. This
* method returns all boundingBoxes together in one array.
*
* @param element
* @param parent
* @return Returns an array of boundingBoxes.
* @throws XMLParsingException
* @throws InvalidParameterValueException
*/
protected Envelope[] getBoundingBoxes( Element element, Dataset parent )
throws XMLParsingException, InvalidParameterValueException {
List boundingBoxList = XMLTools.getNodes( element, "ows:BoundingBox", nsContext );
List bboxesList = new ArrayList( boundingBoxList.size() );
for ( int i = 0; i < boundingBoxList.size(); i++ ) {
bboxesList.add( parseBoundingBox( (Element) boundingBoxList.get( i ) ) );
}
if ( parent != null ) {
Envelope[] boundingBoxes = parent.getBoundingBoxes();
for ( int i = 0; i < boundingBoxes.length; i++ ) {
bboxesList.add( boundingBoxes[i] );
}
}
Envelope[] boxes = (Envelope[]) bboxesList.toArray( new Envelope[bboxesList.size()] );
return boxes;
}
/**
* Gets a single <code>boundingBox</code> from the given <code>Element</code> at the given
* <code>XPathQuery</code>.
*
* @param datasetElement
* @param xPathQuery
* @return Returns a single boundingBox.
* @throws XMLParsingException
* @throws InvalidParameterValueException
*/
protected Envelope getBoundingBox( Element datasetElement, String xPathQuery )
throws XMLParsingException, InvalidParameterValueException {
Envelope boundingBox = null;
Element boundingBoxElement = (Element) XMLTools.getNode( datasetElement, xPathQuery,
nsContext );
if ( boundingBoxElement != null ) {
boundingBox = parseBoundingBox( boundingBoxElement );
}
return boundingBox;
}
/**
* TODO move to a common mehtod/class: method body copied from
* OWSCommonCapabilitiesDocument#getWGS84BoundingBoxType()
*
* Changed name, because it is usable with any BoundingBox. Changed crs from null to given
* attribute value of crs. Added check for min values to be smaler than max values.
*
* Creates an <code>Envelope</code> object from the given element of type
* <code>ows:WGS84BoundingBox</code> or <code>ows:BoundingBox</code>.
*
* @param element
* @return
* @throws XMLParsingException
* @throws InvalidParameterValueException
*/
private Envelope parseBoundingBox( Element element )
throws XMLParsingException, InvalidParameterValueException {
Envelope env = getWGS84BoundingBoxType( element );
Position min = env.getMin();
Position max = env.getMax();
if ( min.getX() >= max.getX() ) {
throw new InvalidParameterValueException( "X value of LowerCorner must be smaler "
+ "than X value of UpperCorner." );
}
if ( min.getY() >= max.getY() ) {
throw new InvalidParameterValueException( "Y value of LowerCorner must be smaler "
+ "than Y value of UpperCorner." );
}
String crsAtt = XMLTools.getAttrValue( element, "crs" );
CoordinateSystem crs;
try {
crs = CRSFactory.create( crsAtt );
} catch ( UnknownCRSException e ) {
throw new InvalidParameterValueException( e.getMessage() );
}
return GeometryFactory.createEnvelope( min.getX(), min.getY(), max.getX(), max.getY(), crs );
}
/**
* Creates and returns a new <code>OperationsMetadata</code> object.
*
* @return Returns a new OperationsMetadata object.
* @throws XMLParsingException
* @throws InvalidCapabilitiesException
*/
protected OperationsMetadata parseOperationsMetadata()
throws XMLParsingException, InvalidCapabilitiesException {
LOG.entering();
Node operationMetadata = XMLTools.getRequiredNode( getRootElement(),
"./ows:OperationsMetadata", nsContext );
List operationElementList = XMLTools.getNodes( operationMetadata, "./ows:Operation",
nsContext );
Map operations = new HashMap();
for ( int i = 0; i < operationElementList.size(); i++ ) {
operations.put( XMLTools.getRequiredNodeAsString( (Node) operationElementList.get( i ),
"./@name", nsContext ),
operationElementList.get( i ) );
}
Operation110 getCapabilities = getOperation110( OperationsMetadata.GET_CAPABILITIES_NAME,
true, operations );
Operation110 getView = getOperation110( WPVSOperationsMetadata.GET_VIEW_NAME, true,
operations );
Operation110 getDescription = getOperation110( WPVSOperationsMetadata.GET_DESCRIPTION_NAME,
false, operations );
Operation110 getLegendGraphics = getOperation110(
WPVSOperationsMetadata.GET_LEGEND_GRAPHIC_NAME,
false, operations );
List parameterElementList = XMLTools.getNodes( operationMetadata, "./ows:Parameter",
nsContext );
OWSDomainType110[] parameters = new OWSDomainType110[parameterElementList.size()];
for ( int i = 0; i < parameters.length; i++ ) {
parameters[i] = getOWSDomainType110( (Element) parameterElementList.get( i ) );
}
List constraintElementList = XMLTools.getNodes( operationMetadata, "./ows:Constraint",
nsContext );
OWSDomainType110[] constraints = new OWSDomainType110[constraintElementList.size()];
for ( int i = 0; i < constraints.length; i++ ) {
constraints[i] = getOWSDomainType110( (Element) constraintElementList.get( i ) );
}
List extendedCapsList = XMLTools.getNodes( operationMetadata, "./ows:ExtendedCapabilities",
nsContext );
Object[] extendedCapabilities = new Object[extendedCapsList.size()];
for ( int i = 0; i < extendedCapabilities.length; i++ ) {
extendedCapabilities[i] = extendedCapsList.get( i );
}
WPVSOperationsMetadata metadata = new WPVSOperationsMetadata( getCapabilities, getView,
getDescription,
getLegendGraphics,
parameters, constraints,
extendedCapabilities );
LOG.exiting();
return metadata;
}
/**
* FIXME needs to be handled, when OWSDomainType110 ceases to exist.
*
* @see org.deegree.owscommon.OWSCommonCapabilitiesDocument#getOperation()
*
* @param name
* @param isMandatory
* @param operations
* @return
* @throws XMLParsingException
* @throws InvalidCapabilitiesException
*/
private Operation110 getOperation110( String name, boolean isMandatory, Map operations )
throws XMLParsingException, InvalidCapabilitiesException {
LOG.entering();
Operation110 operation = null;
Element operationElement = (Element) operations.get( name );
if ( operationElement == null ) {
if ( isMandatory ) {
throw new XMLParsingException( "Mandatory operation '" + name + "' not defined in "
+ "'OperationsMetadata'-section." );
}
} else {
// 'ows:DCP' - elements
DCPType[] dcps = getDCPs( XMLTools.getRequiredNodes( operationElement, "ows:DCP",
nsContext ) );
// 'Parameter' - elements
List parameterList = XMLTools.getNodes( operationElement, "./ows:Parameter", nsContext );
OWSDomainType110[] parameters = new OWSDomainType110[parameterList.size()];
for ( int i = 0; i < parameters.length; i++ ) {
parameters[i] = getOWSDomainType110( (Element) parameterList.get( i ) );
}
// 'Constraint' - elements
List constraintList = XMLTools.getNodes( operationElement, "./ows:Constraint",
nsContext );
OWSDomainType110[] constraints = new OWSDomainType110[constraintList.size()];
for ( int i = 0; i < constraintList.size(); i++ ) {
constraints[i] = getOWSDomainType110( (Element) constraintList.get( i ) );
}
// 'ows:Metadata' - element
List metadataList = XMLTools.getNodes( operationElement, "./ows:Metadata", nsContext );
OWSMetadata[] metadata = new OWSMetadata[metadataList.size()];
for ( int i = 0; i < metadata.length; i++ ) {
metadata[i] = getOWSMetadata( operationElement, "ows:Metadata", nsContext );
}
// return new Operation110 object
operation = new Operation110( name, dcps, parameters, constraints, metadata );
}
LOG.exiting();
return operation;
}
/**
* FIXME there is a similar method in
* org.deegree.owscommon.OWSCommonCapabilitiesDocument#getDCP. overrides that method!
*
* Creates a <code>DCPType</code> object from the passed <code>DCP</code> element.
*
* @param element
* @param namespaceURI
* @return created <code>DCPType</code>
* @throws XMLParsingException
* @see org.deegree.ogcwebservices.getcapabilities.OGCStandardCapabilities
*/
protected DCPType getDCP( Element element )
throws XMLParsingException {
LOG.entering();
DCPType dcpType = null;
Element httpElement = (Element) XMLTools.getRequiredNode( element, "./ows:HTTP", nsContext );
try {
List requestList = XMLTools.getNodes( httpElement, "./ows:Get", nsContext );
OWSRequestMethod[] getRequests = new OWSRequestMethod[requestList.size()];
for ( int i = 0; i < getRequests.length; i++ ) {
List constraintList = XMLTools.getNodes( (Node) requestList.get( i ),
"./ows:Constraint", nsContext );
OWSDomainType110[] constraint = new OWSDomainType110[constraintList.size()];
for ( int j = 0; j < constraint.length; j++ ) {
constraint[j] = getOWSDomainType110( (Element) constraintList.get( i ) );
}
SimpleLink link = parseSimpleLink( (Element) requestList.get( i ) );
getRequests[i] = new OWSRequestMethod( link, constraint );
}
requestList = XMLTools.getNodes( httpElement, "./ows:Post", nsContext );
OWSRequestMethod[] postRequests = new OWSRequestMethod[requestList.size()];
for ( int i = 0; i < postRequests.length; i++ ) {
List constraintList = XMLTools.getNodes( (Node) requestList.get( i ),
"./ows:Constraint", nsContext );
OWSDomainType110[] constraint = new OWSDomainType110[constraintList.size()];
for ( int j = 0; j < constraint.length; j++ ) {
constraint[j] = getOWSDomainType110( (Element) constraintList.get( i ) );
}
SimpleLink link = parseSimpleLink( (Element) requestList.get( i ) );
postRequests[i] = new OWSRequestMethod( link, constraint );
}
Protocol protocol = new HTTP110( getRequests, postRequests );
dcpType = new DCPType( protocol );
} catch ( InvalidCapabilitiesException e ) {
throw new XMLParsingException( "Couldn't parse the OWSDomainType110 within DCPType: "
+ StringTools.stackTraceToString( e ) );
}
LOG.exiting();
return dcpType;
}
/**
* FIXME needs to be handled, when OWSDomainType110 ceases to exist.
*
* @see org.deegree.owscommon.OWSCommonCapabilitiesDocument#getOWSDomainType()
*
* @param element
* @return Returns owsDomainType110 object.
* @throws InvalidCapabilitiesException
*/
private OWSDomainType110 getOWSDomainType110( Element element )
throws XMLParsingException, InvalidCapabilitiesException {
LOG.entering();
// 'name' - attribute
String name = XMLTools.getRequiredNodeAsString( element, "@name", nsContext );
// 'ows:AllowedValues' - element
Element allowedElement = (Element) XMLTools.getNode( element, "./ows:AllowedValues",
nsContext );
OWSAllowedValues allowedValues = null;
if ( allowedElement != null ) {
// 'ows:Value' - elements
String[] values = XMLTools.getNodesAsStrings( allowedElement, "./ows:Value/text()",
nsContext );
TypedLiteral[] literals = null;
if ( values != null ) {
literals = new TypedLiteral[values.length];
for ( int i = 0; i < literals.length; i++ ) {
literals[i] = new TypedLiteral( values[i], null );
}
}
// 'ows:Range' - elements
List rangeList = XMLTools.getNodes( allowedElement, "./ows:Range", nsContext );
ValueRange[] ranges = new ValueRange[rangeList.size()];
for ( int i = 0; i < ranges.length; i++ ) {
String minimum = XMLTools.getNodeAsString( (Node) rangeList.get( i ),
"./ows:MinimumValue", nsContext, null );
String maximum = XMLTools.getNodeAsString( (Node) rangeList.get( i ),
"./ows:MaximumValue", nsContext, null );
String spacing = XMLTools.getNodeAsString( (Node) rangeList.get( i ),
"./ows:Spacing", nsContext, null );
TypedLiteral min = new TypedLiteral( minimum, null );
TypedLiteral max = new TypedLiteral( maximum, null );
TypedLiteral space = new TypedLiteral( spacing, null );
ranges[i] = new ValueRange( min, max, space );
}
if ( values.length < 1 && ranges.length < 1 ) {
throw new XMLParsingException(
"At least one 'ows:Value'-element or one 'ows:Range'-element must be defined "
+ "in each element of type 'ows:AllowedValues'." );
}
allowedValues = new OWSAllowedValues( literals, ranges );
}
// FIXME manage elements: ows:AnyValue, ows:NoValues.
boolean anyValue = false;
boolean noValues = false;
// 'ows:ValuesListReference' - element
OWSMetadata valuesListReference = getOWSMetadata( element, "./ows:ValuesListReference",
nsContext );
// 'ows:DefaulValue' - element
String defaultValue = XMLTools.getNodeAsString( element, "./ows:DefaultValue/text()",
nsContext, null );
// 'ows:Meaning' - element
OWSMetadata meaning = getOWSMetadata( element, "./ows:Meaning", nsContext );
// 'ows:DataType - element
OWSMetadata dataType = getOWSMetadata( element, "./ows:DataType", nsContext );
// choose up to one measurement element
String measurementType = null;
// 'ows:ReferenceSystem' - element
Element referenceElement = (Element) XMLTools.getNode( element, "./ows:ReferenceSystem",
nsContext );
// 'ows:UOM' - element
Element uomElement = (Element) XMLTools.getNode( element, "./ows:UOM", nsContext );
OWSMetadata measurement = null;
if ( referenceElement != null && uomElement != null ) {
throw new InvalidCapabilitiesException( "Within an 'ows:DomainType'-Element only one "
+ "of the following elements is allowed: "
+ "'ows:ReferenceSystem' OR 'ows:UOM'." );
} else if ( referenceElement != null ) {
measurementType = OWSDomainType110.REFERENCE_SYSTEM;
measurement = getOWSMetadata( element, "./ows:ReferenceSystem", nsContext );
} else if ( uomElement != null ) {
measurementType = OWSDomainType110.UOM;
measurement = getOWSMetadata( element, "./ows:UOM", nsContext );
}
// 'ows:Metadata' - elements
List metaList = XMLTools.getNodes( element, "./ows:Metadata", nsContext );
OWSMetadata[] metadata = new OWSMetadata[metaList.size()];
for ( int i = 0; i < metadata.length; i++ ) {
metadata[i] = getOWSMetadata( (Element) metaList.get( i ), "./ows:Metadata", nsContext );
}
// return new OWSDomainType110
OWSDomainType110 domainType110 = null;
if ( allowedValues != null && !anyValue && !noValues && valuesListReference == null ) {
domainType110 = new OWSDomainType110( allowedValues, defaultValue, meaning, dataType,
measurementType, measurement, metadata, name );
} else if ( ( anyValue || noValues ) && allowedValues == null
&& valuesListReference == null ) {
domainType110 = new OWSDomainType110( anyValue, noValues, defaultValue, meaning,
dataType, measurementType, measurement, metadata,
name );
} else if ( valuesListReference != null && allowedValues == null && !anyValue && !noValues ) {
domainType110 = new OWSDomainType110( valuesListReference, defaultValue, meaning,
dataType, measurementType, measurement, metadata,
name );
} else {
throw new InvalidCapabilitiesException(
"Only one of the following elements may be "
+ "contained within an 'ows:DomainType': 'ows:AllowedValues', 'ows:AnyValue', "
+ "'ows:NoValues' or 'ows:ValuesListReference'." );
}
LOG.exiting();
return domainType110;
}
/**
* FIXME check, wether the URIs go to the correct address within OWSMetadata. So far, no example
* was given to check this with.
*
* Creates and returns a new <code>OWSMetadata</code> object (or null) from the given
* <code>Element</code> at the given <code>XPath</code>.
*
* @param element
* @param xPath
* @param nsContext
* @return Returns a new OWSMetadata object (may be null).
* @throws XMLParsingException
*/
private OWSMetadata getOWSMetadata( Element element, String xPath, NamespaceContext nsContext )
throws XMLParsingException {
Element child = (Element) XMLTools.getNode( element, xPath, nsContext );
if ( child == null ) {
return null;
}
// attrib about
URI about = XMLTools.getNodeAsURI( child, "./@about", nsContext, null );
// attribs for SimpleLink
URI href = XMLTools.getNodeAsURI( child, "./@xlink:href", nsContext, null );
URI role = XMLTools.getNodeAsURI( child, "./@xlink:role", nsContext, null );
URI arcrole = XMLTools.getNodeAsURI( child, "./@xlink:arcrole", nsContext, null );
String title = XMLTools.getNodeAsString( child, "./@xlink:title", nsContext, null );
String show = XMLTools.getNodeAsString( child, "./@xlink:show", nsContext, null );
String actuate = XMLTools.getNodeAsString( child, "./@xlink:actuate", nsContext, null );
// ows:name (ows:AbstractMetaData)
String name = XMLTools.getNodeAsString( child, "./text()", nsContext, null );
SimpleLink link = new SimpleLink( href, role, arcrole, title, show, actuate );
return new OWSMetadata( about, link, name );
}
}
/***************************************************************************************************
* Changes to this class. What the people have been up to: $Log: WPVSCapabilitiesDocument.java,v $
* Changes to this class. What the people have been up to: Revision 1.31 2006/11/27 15:40:32 bezema
* Changes to this class. What the people have been up to: Updated the coordinatesystem handling and the generics
* Changes to this class. What the people have been up to:
* Revision 1.30 2006/11/27 09:07:53 poth JNI integration of proj4 has been removed. The CRS
* functionality now will be done by native deegree code.
*
* Revision 1.29 2006/11/23 11:46:40 bezema The initial version of the new wpvs
*
* Revision 1.28 2006/11/07 16:34:02 poth bug fixes and code formatting
*
* Revision 1.27 2006/08/24 06:42:15 poth File header corrected
*
* Revision 1.26 2006/05/01 20:15:27 poth ** empty log message ***
*
* Revision 1.25 2006/04/06 20:25:25 poth ** empty log message ***
*
* Revision 1.24 2006/03/30 21:20:26 poth ** empty log message ***
*
* Revision 1.23 2006/01/18 08:47:54 taddei bug fixes
*
* Revision 1.22 2005/12/21 11:08:20 mays clean up: remove typos, remove wgs84bboxes from bboxes
* array
*
* Revision 1.21 2005/12/20 13:14:52 mays clean up and addition of minor missing parts
*
* Revision 1.20 2005/12/20 10:08:46 mays remove typo
*
* Revision 1.19 2005/12/20 09:59:41 mays implement ValueRange in getOWSDomainType110 and implement
* SimpleLink in getOWSMetadata
*
* Revision 1.18 2005/12/19 10:05:23 mays changes for call of Operation110 constructor in
* getOperation110
*
* Revision 1.17 2005/12/16 15:29:38 mays necessary changes due to new definition of
* ows:OperationsMetadata
*
* Revision 1.16 2005/12/13 16:53:10 mays change parseOperationsMetadata to 'protected'
*
* Revision 1.15 2005/12/12 10:25:51 mays removed typos
*
* Revision 1.14 2005/12/09 14:07:56 mays add parseOperationsMetadata and clean up
*
* Revision 1.13 2005/12/08 16:46:03 mays change method names to parseSomeThing; move configuration
* specific stuff to WPVSConfigurationDocument and leave only capabilties specifics in here
*
* Revision 1.12 2005/12/07 09:45:14 mays redesign of filterCondition request from String to Map
* form wcs and wms datasources
*
* Revision 1.11 2005/12/06 16:45:21 mays necessary changes for AbstractDataSources: use Query for
* WFSDataSources
*
* Revision 1.10 2005/12/06 12:57:07 mays add create-methods for new subnodes of dataset; remove
* errors in existing methods
*
* Revision 1.9 2005/12/05 09:36:38 mays revision of comments
*
* Revision 1.8 2005/12/02 15:28:55 mays adaptations according to schema specifications, mainly
* concerning the number of item occurences
*
* Revision 1.7 2005/12/01 16:50:40 mays add some more subnodes to dataset (not finished yet), add
* create-methods for new subnodes
*
* Revision 1.6 2005/12/01 10:30:14 mays add standard footer to all java classes in wpvs package
*
**************************************************************************************************/