    001    // $HeadURL: svn+ssh://mschneider@svn.wald.intevation.org/deegree/base/trunk/src/org/deegree/ogcwebservices/wfs/capabilities/WFSCapabilitiesDocument.java $
    002    /*----------------------------------------------------------------------------
    003     This file is part of deegree, http://deegree.org/
    004     Copyright (C) 2001-2009 by:
    005       Department of Geography, University of Bonn
    006     and
    007       lat/lon GmbH
    008
    009     This library is free software; you can redistribute it and/or modify it under
    010     the terms of the GNU Lesser General Public License as published by the Free
    011     Software Foundation; either version 2.1 of the License, or (at your option)
    012     any later version.
    013     This library is distributed in the hope that it will be useful, but WITHOUT
    014     ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
    015     FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
    016     details.
    017     You should have received a copy of the GNU Lesser General Public License
    018     along with this library; if not, write to the Free Software Foundation, Inc.,
    019     59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
    020
    021     Contact information:
    022
    023     lat/lon GmbH
    024     Aennchenstr. 19, 53177 Bonn
    025     Germany
    026     http://lat-lon.de/
    027
    028     Department of Geography, University of Bonn
    029     Prof. Dr. Klaus Greve
    030     Postfach 1147, 53001 Bonn
    031     Germany
    032     http://www.geographie.uni-bonn.de/deegree/
    033
    034     e-mail: info@deegree.org
    035    ----------------------------------------------------------------------------*/
    036    package org.deegree.ogcwebservices.wfs.capabilities;
    037
    038    import java.io.IOException;
    039    import java.net.MalformedURLException;
    040    import java.net.URI;
    041    import java.net.URISyntaxException;
    042    import java.net.URL;
    043    import java.security.InvalidParameterException;
    044    import java.util.ArrayList;
    045    import java.util.HashMap;
    046    import java.util.List;
    047    import java.util.Map;
    048
    049    import org.deegree.datatypes.Code;
    050    import org.deegree.datatypes.QualifiedName;
    051    import org.deegree.framework.log.ILogger;
    052    import org.deegree.framework.log.LoggerFactory;
    053    import org.deegree.framework.util.StringTools;
    054    import org.deegree.framework.xml.XMLParsingException;
    055    import org.deegree.framework.xml.XMLTools;
    056    import org.deegree.model.filterencoding.capabilities.FilterCapabilities;
    057    import org.deegree.model.filterencoding.capabilities.FilterCapabilities110Fragment;
    058    import org.deegree.model.metadata.iso19115.Keywords;
    059    import org.deegree.model.spatialschema.Envelope;
    060    import org.deegree.ogcbase.CommonNamespaces;
    061    import org.deegree.ogcwebservices.getcapabilities.InvalidCapabilitiesException;
    062    import org.deegree.ogcwebservices.getcapabilities.MetadataURL;
    063    import org.deegree.ogcwebservices.getcapabilities.OGCCapabilities;
    064    import org.deegree.ogcwebservices.getcapabilities.Operation;
    065    import org.deegree.ogcwebservices.getcapabilities.OperationsMetadata;
    066    import org.deegree.ogcwebservices.getcapabilities.ServiceIdentification;
    067    import org.deegree.owscommon.OWSCommonCapabilitiesDocument;
    068    import org.deegree.owscommon.OWSDomainType;
    069    import org.w3c.dom.Document;
    070    import org.w3c.dom.Element;
    071    import org.w3c.dom.Node;
    072    import org.xml.sax.SAXException;
    073
    074    /**
    075     * Represents a capabilities document for an OGC WFS 1.1.0 compliant web service.
    076     *
    077     * @author <a href="mailto:mschneider@lat-lon.de">Markus Schneider </a>
    078     * @author last edited by: $Author: rbezema $
    079     *
    080     * @version $Revision: 11377 $, $Date: 2008-04-23 07:55:34 +0000 (Mi, 23 Apr 2008) $
    081     */
    082    public class WFSCapabilitiesDocument_1_1_0 extends OWSCommonCapabilitiesDocument {
    083
    084        private static final long serialVersionUID = 6664839532969382269L;
    085
    086        private static ILogger LOG = LoggerFactory.getLogger( WFSCapabilitiesDocument_1_1_0.class );
    087
    088        /**
    089         * The "FeatureTypeList" string.
    090         */
    091        public final static String FEATURE_TYPE_LIST_NAME = "FeatureTypeList";
    092
    093        /**
    094         * The "ServesGMLObjectTypeList" string.
    095         */
    096        public final static String SERVES_GML_OBJECT_TYPE_LIST_NAME = "ServesGMLObjectTypeList";
    097
    098        /**
    099         * The "SupportsGMLObjectTypeList" string.
    100         */
    101        public final static String SUPPORTS_GML_OBJECT_TYPE_LIST_NAME = "SupportsGMLObjectTypeList";
    102
    103        /**
    104         * The "FilterCapabilities" string.
    105         */
    106        public final static String FILTER_CAPABILITIES_NAME = "FilterCapabilities";
    107
    108        protected static final URI WFSNS = CommonNamespaces.WFSNS;
    109
    110        private static final String PRE_OWS = CommonNamespaces.OWS_PREFIX + ":";
    111
    112        protected static final URI OGCNS = CommonNamespaces.OGCNS;
    113
    114        protected static final URI DEEGREEWFSNS = CommonNamespaces.DEEGREEWFS;
    115
    116        private static final String XML_TEMPLATE = "WFSCapabilitiesTemplate.xml";
    117
    118        private static final String[] VALID_TYPES = { "TC211", "FGDC", "19115", "19139" };
    119
    120        private static final String[] VALID_FORMATS = { "text/xml", "text/html", "text/sgml", "text/plain" };
    121
    122        /**
    123         * Creates a skeleton capabilities document that contains the mandatory elements only.
    124         *
    125         * @throws IOException
    126         * @throws SAXException
    127         */
    128        public void createEmptyDocument()
    129                                throws IOException, SAXException {
    130            URL url = WFSCapabilitiesDocument_1_1_0.class.getResource( XML_TEMPLATE );
    131            if ( url == null ) {
    132                throw new IOException( "The resource '" + XML_TEMPLATE + " could not be found." );
    133            }
    134            load( url );
    135        }
    136
    137        /**
    138         * Creates an emptyDocument with given version, and an updateSequence of "0" without reading the skeleton document.
    139         *
    140         * @param version
    141         *            if
    142         *
    143         */
    144        public void createEmptyDocument( String version ) {
    145            // set up the root document.
    146            Document doc = XMLTools.create();
    147            Element root = doc.createElementNS( "http://www.opengis.net/wfs", "WFS_Capabilities" );
    148            doc.importNode( root, false );
    149
    150            setRootElement( root );
    151            root.setAttribute( "version", version );
    152            root.setAttribute( "updateSequence", "0" );
    153        }
    154
    155        /**
    156         * Creates a class representation of the document.
    157         *
    158         * @return class representation of the configuration document
    159         */
    160        @Override
    161        public OGCCapabilities parseCapabilities()
    162                                throws InvalidCapabilitiesException {
    163
    164            WFSCapabilities wfsCapabilities = null;
    165            try {
    166
    167                wfsCapabilities = new WFSCapabilities( parseVersion(), parseUpdateSequence(), getServiceIdentification(),
    168                                                       getServiceProvider(), getOperationsMetadata(), getFeatureTypeList(),
    169                                                       getServesGMLObjectTypeList(), getSupportsGMLObjectTypeList(), null,
    170                                                       getFilterCapabilities() );
    171            } catch ( XMLParsingException e ) {
    172                throw new InvalidCapabilitiesException( e.getMessage() + "\n" + StringTools.stackTraceToString( e ) );
    173            }
    174
    175            return wfsCapabilities;
    176        }
    177
    178        /**
    179         * Returns the class representation for the <code>ServiceIdentification</code> section of the document.
    180         * <p>
    181         * NOTE: this method is overridden, because the WFS 1.1.0 requires the OWS 1.0.0 version of the element
    182         *
    183         * @return class representation for the <code>ServiceIdentification</code> section
    184         * @throws XMLParsingException
    185         */
    186        @Override
    187        public ServiceIdentification getServiceIdentification()
    188                                throws XMLParsingException {
    189
    190            // Element element = XMLTools.getRequiredChildElement( "ServiceIdentification", OWSNS,
    191            // getRootElement() );
    192            Element element = XMLTools.getRequiredElement( getRootElement(), PRE_OWS + "ServiceIdentification", nsContext );
    193
    194            // 'ServiceType' element (mandatory)
    195            // Element serviceTypeElement = XMLTools.getRequiredChildElement( "ServiceType", OWSNS,
    196            // element );
    197            Element serviceTypeElement = XMLTools.getRequiredElement( element, PRE_OWS + "ServiceType", nsContext );
    198            Code serviceType = null;
    199            try {
    200                String codeSpace = XMLTools.getAttrValue( serviceTypeElement, OWSNS, "codeSpace", null );
    201                URI uri = codeSpace != null ? new URI( codeSpace ) : null;
    202                serviceType = new Code( XMLTools.getStringValue( serviceTypeElement ), uri );
    203            } catch ( URISyntaxException e ) {
    204                throw new XMLParsingException( "Given value '"
    205                                               + XMLTools.getAttrValue( serviceTypeElement, OWSNS, "codeSpace", null )
    206                                               + "' in attribute 'codeSpace' of element 'ServiceType' " + "(namespace: '"
    207                                               + OWSNS + "') is not a valid URI." );
    208            }
    209
    210            // 'ServiceTypeVersion' elements (mandatory)
    211            String[] serviceTypeVersions = XMLTools.getRequiredNodeAsStrings( element, "ows:ServiceTypeVersion", nsContext,
    212                                                                              ",;" );
    213            if ( serviceTypeVersions.length == 0 ) {
    214                String msg = "No version specified in 'ows:ServiceTypeVersion' element.";
    215                throw new XMLParsingException( msg );
    216            }
    217
    218            // 'Fees' element (optional)
    219            String fees = XMLTools.getStringValue( "Fees", OWSNS, element, null );
    220
    221            // 'AccessConstraints' elements (optional)
    222            String accessConstraints[] = XMLTools.getNodesAsStrings( element, "ows:AccessConstraints", nsContext );
    223
    224            String title = XMLTools.getNodeAsString( element, "ows:Title", nsContext, null );
    225            // 'ows:Name' -- nonstandard, added to support the WFS 1.0.0 Service/Name element
    226            String name = XMLTools.getNodeAsString( element, "ows:Name", nsContext, title );
    227
    228            String abs = XMLTools.getNodeAsString( element, "ows:Abstract", nsContext, null );
    229
    230            Keywords[] kws = getKeywords( XMLTools.getElements( element, "ows:Keywords", nsContext ) );
    231
    232            ServiceIdentification serviceIdentification = new ServiceIdentification( name, serviceType, serviceTypeVersions,
    233                                                                                     title, abs, kws, fees,
    234                                                                                     accessConstraints );
    235            return serviceIdentification;
    236        }
    237
    238        /**
    239         * Creates an object representation of the <code>ows:OperationsMetadata</code> section.
    240         *
    241         * @return object representation of the <code>ows:OperationsMetadata</code> section
    242         * @throws XMLParsingException
    243         */
    244        public OperationsMetadata getOperationsMetadata()
    245                                throws XMLParsingException {
    246
    247            List<Node> operationElementList = XMLTools.getNodes( getRootElement(), "ows:OperationsMetadata/ows:Operation",
    248                                                                 nsContext );
    249
    250            // build HashMap of 'ows:Operation'-elements for easier access
    251            Map<String, Node> operations = new HashMap<String, Node>();
    252            for ( int i = 0; i < operationElementList.size(); i++ ) {
    253                operations.put( XMLTools.getRequiredNodeAsString( operationElementList.get( i ), "@name", nsContext ),
    254                                operationElementList.get( i ) );
    255            }
    256
    257            Operation getCapabilities = getOperation( OperationsMetadata.GET_CAPABILITIES_NAME, true, operations );
    258            Operation describeFeatureType = getOperation( WFSOperationsMetadata.DESCRIBE_FEATURETYPE_NAME, true, operations );
    259            Operation getFeature = getOperation( WFSOperationsMetadata.GET_FEATURE_NAME, false, operations );
    260            Operation getFeatureWithLock = getOperation( WFSOperationsMetadata.GET_FEATURE_WITH_LOCK_NAME, false,
    261                                                         operations );
    262            Operation getGMLObject = getOperation( WFSOperationsMetadata.GET_GML_OBJECT_NAME, false, operations );
    263            Operation lockFeature = getOperation( WFSOperationsMetadata.LOCK_FEATURE_NAME, false, operations );
    264            Operation transaction = getOperation( WFSOperationsMetadata.TRANSACTION_NAME, false, operations );
    265
    266            List<Element> parameterElementList = XMLTools.getElements( getRootElement(),
    267                                                                       "ows:OperationsMetadata/ows:Parameter", nsContext );
    268            OWSDomainType[] parameters = new OWSDomainType[parameterElementList.size()];
    269            for ( int i = 0; i < parameters.length; i++ ) {
    270                parameters[i] = getOWSDomainType( null, parameterElementList.get( i ) );
    271            }
    272
    273            List<Element> constraintElementList = XMLTools.getElements( getRootElement(),
    274                                                                        "ows:OperationsMetadata/ows:Constraint", nsContext );
    275            OWSDomainType[] constraints = new OWSDomainType[constraintElementList.size()];
    276            for ( int i = 0; i < constraints.length; i++ ) {
    277                constraints[i] = getOWSDomainType( null, constraintElementList.get( i ) );
    278            }
    279            WFSOperationsMetadata metadata = new WFSOperationsMetadata( getCapabilities, describeFeatureType, getFeature,
    280                                                                        getFeatureWithLock, getGMLObject, lockFeature,
    281                                                                        transaction, parameters, constraints );
    282
    283            return metadata;
    284        }
    285
    286        /**
    287         * Returns the object representation for the <code>wfs:FeatureTypeList</code>- section.
    288         *
    289         * @return object representation of the <code>wfs:FeatureTypeList</code> section, may be empty (if missing)
    290         * @throws XMLParsingException
    291         */
    292        public FeatureTypeList getFeatureTypeList()
    293                                throws XMLParsingException {
    294
    295            List<WFSFeatureType> wfsFeatureTypes = new ArrayList<WFSFeatureType>();
    296
    297            FeatureTypeList featureTypeList = new FeatureTypeList(
    298                                                                   new org.deegree.ogcwebservices.wfs.capabilities.Operation[0],
    299                                                                   wfsFeatureTypes );
    300
    301            Element element = (Element) XMLTools.getNode( getRootElement(), "wfs:FeatureTypeList", nsContext );
    302            if ( element != null ) {
    303                org.deegree.ogcwebservices.wfs.capabilities.Operation[] globalOperations = null;
    304                Element operationsTypeElement = (Element) XMLTools.getNode( element, "wfs:Operations", nsContext );
    305                if ( operationsTypeElement != null ) {
    306                    globalOperations = getOperationsType( operationsTypeElement );
    307                }
    308                List<Element> featureTypeElementList = XMLTools.getElements( element, "wfs:FeatureType", nsContext );
    309                // TODO Check this.
    310                // if ( featureTypeElementList.getLength() < 1 ) {
    311                // throw new XMLParsingException(
    312                // "A wfs:FeatureTypeListType must contain at least one wfs:FeatureType-element." );
    313                // }
    314                for ( int i = 0; i < featureTypeElementList.size(); i++ ) {
    315                    WFSFeatureType wfsFT = getFeatureTypeType( featureTypeElementList.get( i ) );
    316                    wfsFeatureTypes.add( wfsFT );
    317                }
    318
    319                featureTypeList = new FeatureTypeList( globalOperations, wfsFeatureTypes );
    320            }
    321
    322            return featureTypeList;
    323        }
    324
    325        /**
    326         * Returns the object representation for the <code>wfs:ServesGMLObjectTypeList</code>- section.
    327         *
    328         * @return object representation of the <code>wfs:ServesGMLObjectTypeList</code> section, null if the section does
    329         *         not exist
    330         * @throws XMLParsingException
    331         */
    332        public GMLObject[] getServesGMLObjectTypeList()
    333                                throws XMLParsingException {
    334
    335            GMLObject[] gmlObjectTypes = null;
    336            Element element = (Element) XMLTools.getNode( getRootElement(), "wfs:ServesGMLObjectTypeList", nsContext );
    337            if ( element != null ) {
    338                List<Node> nodeList = XMLTools.getRequiredNodes( element, "wfs:GMLObjectType", nsContext );
    339                gmlObjectTypes = new GMLObject[nodeList.size()];
    340                for ( int i = 0; i < gmlObjectTypes.length; i++ ) {
    341                    gmlObjectTypes[i] = getGMLObjectType( (Element) nodeList.get( i ) );
    342                }
    343            }
    344
    345            return gmlObjectTypes;
    346        }
    347
    348        /**
    349         * Returns the object representation for the <code>wfs:SupportsGMLObjectTypeList</code>- section.
    350         *
    351         * @return object representation of the <code>wfs:SupportsGMLObjectTypeList</code> section, null if the section
    352         *         does not exist
    353         * @throws XMLParsingException
    354         */
    355        public GMLObject[] getSupportsGMLObjectTypeList()
    356                                throws XMLParsingException {
    357
    358            GMLObject[] gmlObjectTypes = null;
    359            Element element = (Element) XMLTools.getNode( getRootElement(), "wfs:SupportsGMLObjectTypeList", nsContext );
    360            if ( element != null ) {
    361                List<Node> nodeList = XMLTools.getRequiredNodes( element, "wfs:GMLObjectType", nsContext );
    362                gmlObjectTypes = new GMLObject[nodeList.size()];
    363                for ( int i = 0; i < gmlObjectTypes.length; i++ ) {
    364                    gmlObjectTypes[i] = getGMLObjectType( (Element) nodeList.get( i ) );
    365                }
    366            }
    367
    368            return gmlObjectTypes;
    369        }
    370
    371        /**
    372         * Returns the object representation for an element of type <code>wfs:GMLObjectType</code>.
    373         *
    374         * @param element
    375         * @return object representation of the element of type <code>wfs:GMLObjectType</code>
    376         * @throws XMLParsingException
    377         */
    378        public GMLObject getGMLObjectType( Element element )
    379                                throws XMLParsingException {
    380            QualifiedName name = parseQualifiedName( XMLTools.getRequiredNode( element, "wfs:Name/text()", nsContext ) );
    381            String title = XMLTools.getNodeAsString( element, "wfs:Title/text()", nsContext, null );
    382            String abstract_ = XMLTools.getNodeAsString( element, "wfs:Abstract/text()", nsContext, null );
    383            Keywords[] keywords = getKeywords( XMLTools.getNodes( element, "ows:Keywords", nsContext ) );
    384            List<Element> formatElementList = XMLTools.getElements( element, "wfs:OutputFormats/wfs:Format", nsContext );
    385            FormatType[] outputFormats = new FormatType[formatElementList.size()];
    386            for ( int i = 0; i < outputFormats.length; i++ ) {
    387                outputFormats[i] = getFormatType( formatElementList.get( i ) );
    388            }
    389            return new GMLObject( name, title, abstract_, keywords, outputFormats );
    390        }
    391
    392        /**
    393         * Returns the object representation for an element of type <code>wfs:FeatureTypeType</code>.
    394         *
    395         * @param element
    396         * @return object representation for the element of type <code>wfs:OperationsType</code>
    397         * @throws XMLParsingException
    398         */
    399        public WFSFeatureType getFeatureTypeType( Element element )
    400                                throws XMLParsingException {
    401
    402            QualifiedName name = parseQualifiedName( XMLTools.getRequiredNode( element, "wfs:Name/text()", nsContext ) );
    403            String title = XMLTools.getRequiredNodeAsString( element, "wfs:Title/text()", nsContext );
    404            String abstract_ = XMLTools.getNodeAsString( element, "wfs:Abstract/text()", nsContext, null );
    405            Keywords[] keywords = getKeywords( XMLTools.getNodes( element, "ows:Keywords", nsContext ) );
    406
    407            URI defaultSrs = null;
    408            URI[] otherSrs = null;
    409            Node noSrsElement = XMLTools.getNode( element, "wfs:NoSRS", nsContext );
    410            if ( noSrsElement == null ) {
    411                defaultSrs = XMLTools.getNodeAsURI( element, "wfs:DefaultSRS/text()", nsContext, null );
    412                if ( defaultSrs == null ) {
    413                    String msg = "A 'wfs:FeatureType' element must always contain a 'wfs:NoSRS' "
    414                                 + "element  or a 'wfs:DefaultSRS' element";
    415                    throw new XMLParsingException( msg );
    416                }
    417                otherSrs = XMLTools.getNodesAsURIs( element, "wfs:OtherSRS/text()", nsContext );
    418            }
    419
    420            org.deegree.ogcwebservices.wfs.capabilities.Operation[] operations = null;
    421            Element operationsTypeElement = (Element) XMLTools.getNode( element, "wfs:Operations", nsContext );
    422            if ( operationsTypeElement != null ) {
    423                operations = getOperationsType( operationsTypeElement );
    424            }
    425            List<Element> formatElementList = XMLTools.getElements( element, "wfs:OutputFormats/wfs:Format", nsContext );
    426            FormatType[] formats = new FormatType[formatElementList.size()];
    427            for ( int i = 0; i < formats.length; i++ ) {
    428                formats[i] = getFormatType( formatElementList.get( i ) );
    429            }
    430            List<Element> wgs84BoundingBoxElements = XMLTools.getElements( element, "ows:WGS84BoundingBox", nsContext );
    431            if ( wgs84BoundingBoxElements.size() < 1 ) {
    432                throw new XMLParsingException( "A 'wfs:FeatureTypeType' must contain at least one "
    433                                               + "'ows:WGS84BoundingBox'-element." );
    434            }
    435            Envelope[] wgs84BoundingBoxes = new Envelope[wgs84BoundingBoxElements.size()];
    436            for ( int i = 0; i < wgs84BoundingBoxes.length; i++ ) {
    437                wgs84BoundingBoxes[i] = getWGS84BoundingBoxType( wgs84BoundingBoxElements.get( i ) );
    438            }
    439            List<Element> metadataURLElementList = XMLTools.getElements( element, "wfs:MetadataURL", nsContext );
    440            MetadataURL[] metadataUrls = new MetadataURL[metadataURLElementList.size()];
    441            for ( int i = 0; i < metadataUrls.length; i++ ) {
    442                metadataUrls[i] = getMetadataURL( metadataURLElementList.get( i ) );
    443            }
    444            WFSFeatureType featureType = new WFSFeatureType( name, title, abstract_, keywords, defaultSrs, otherSrs,
    445                                                             operations, formats, wgs84BoundingBoxes, metadataUrls );
    446
    447            return featureType;
    448        }
    449
    450        /**
    451         * Returns the object representation for an <code>wfs:OutputFormat</code> -element.
    452         *
    453         * @param element
    454         * @return object representation for the element
    455         * @throws XMLParsingException
    456         */
    457        public FormatType getFormatType( Element element )
    458                                throws XMLParsingException {
    459
    460            String[] tmp = new String[3];
    461            URI[] uris = new URI[3];
    462            tmp[0] = XMLTools.getNodeAsString( element, "@deegreewfs:inFilter", nsContext, null );
    463            tmp[1] = XMLTools.getNodeAsString( element, "@deegreewfs:outFilter", nsContext, null );
    464            tmp[2] = XMLTools.getNodeAsString( element, "@deegreewfs:schemaLocation", nsContext, null );
    465            for ( int i = 0; i < tmp.length; i++ ) {
    466                try {
    467                    if ( tmp[i] != null && !"".equals( tmp[i].trim() ) ) {
    468                        if ( !( tmp[i].toLowerCase().startsWith( "file:/" ) ) ) {
    469                            tmp[i] = this.resolve( tmp[i] ).toExternalForm();
    470                            LOG.logDebug( "Found format "
    471                                          + ( ( i == 0 ) ? "inFilter" : ( ( i == 1 ) ? "outFilter" : "schemaLocation" ) )
    472                                          + " at location: " + tmp[i] );
    473                        }
    474                        uris[i] = new URI( tmp[i] );
    475                    }
    476                } catch ( MalformedURLException e ) {
    477                    throw new XMLParsingException( "Could not resolve relative path:" + tmp[i] );
    478                } catch ( URISyntaxException e ) {
    479                    throw new XMLParsingException( "Not a valid URI:" + tmp[i] );
    480                }
    481            }
    482
    483            String value = XMLTools.getRequiredNodeAsString( element, "text()", nsContext );
    484
    485            return new FormatType( uris[0], uris[1], uris[2], value );
    486        }
    487
    488        /**
    489         * Returns the object representation for an element node of type <code>wfs:MetadataURLType</code>.
    490         *
    491         * TODO: Schema says base type is String, not URL!
    492         *
    493         * @param element
    494         * @return object representation for the element of type <code>wfs:MetadataURLType</code>
    495         * @throws XMLParsingException
    496         */
    497        public MetadataURL getMetadataURL( Element element )
    498                                throws XMLParsingException {
    499
    500            String type = XMLTools.getRequiredNodeAsString( element, "@type", nsContext, VALID_TYPES );
    501            String format = XMLTools.getRequiredNodeAsString( element, "@format", nsContext, VALID_FORMATS );
    502            String url = XMLTools.getRequiredNodeAsString( element, "text()", nsContext );
    503            URL onlineResource;
    504            try {
    505                onlineResource = new URL( url );
    506            } catch ( MalformedURLException e ) {
    507                throw new XMLParsingException( "A wfs:MetadataURLType must contain a valid URL: " + e.getMessage() );
    508            }
    509
    510            return new MetadataURL( type, format, onlineResource );
    511        }
    512
    513        /**
    514         * Returns the object representation for an element node of type <code>wfs:OperationsType</code>.
    515         *
    516         * @param element
    517         * @return object representation for the element of type <code>wfs:OperationsType</code>
    518         * @throws XMLParsingException
    519         */
    520        public org.deegree.ogcwebservices.wfs.capabilities.Operation[] getOperationsType( Element element )
    521                                throws XMLParsingException {
    522
    523            String[] operationCodes = XMLTools.getNodesAsStrings( element, "wfs:Operation/text()", nsContext );
    524            org.deegree.ogcwebservices.wfs.capabilities.Operation[] operations = new org.deegree.ogcwebservices.wfs.capabilities.Operation[operationCodes.length];
    525            for ( int i = 0; i < operations.length; i++ ) {
    526                try {
    527                    operations[i] = new org.deegree.ogcwebservices.wfs.capabilities.Operation( operationCodes[i] );
    528                } catch ( InvalidParameterException e ) {
    529                    throw new XMLParsingException( e.getMessage() );
    530                }
    531            }
    532
    533            return operations;
    534        }
    535
    536        /**
    537         * Returns the object representation for the <code>Filter_Capabilities</code> section of the document.
    538         *
    539         * @return class representation for the <code>Filter_Capabilities</code> section
    540         * @throws XMLParsingException
    541         */
    542        public FilterCapabilities getFilterCapabilities()
    543                                throws XMLParsingException {
    544
    545            FilterCapabilities filterCapabilities = null;
    546            Element filterCapabilitiesElement = (Element) XMLTools.getNode( getRootElement(), "ogc:Filter_Capabilities",
    547                                                                            nsContext );
    548            if ( filterCapabilitiesElement != null ) {
    549                filterCapabilities = new FilterCapabilities110Fragment( filterCapabilitiesElement, getSystemId() ).parseFilterCapabilities();
    550            }
    551            return filterCapabilities;
    552        }
    553    }