    001    //$HeadURL: https://svn.wald.intevation.org/svn/deegree/base/branches/2.4_testing/src/org/deegree/ogcwebservices/wfs/configuration/WFSConfigurationDocument.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.configuration;
    037
    038    import static org.deegree.framework.xml.XMLTools.getNodeAsBoolean;
    039    import static org.deegree.framework.xml.XMLTools.getRequiredElement;
    040
    041    import java.io.File;
    042    import java.net.URI;
    043    import java.net.URL;
    044    import java.util.HashMap;
    045    import java.util.List;
    046    import java.util.Map;
    047
    048    import org.deegree.datatypes.QualifiedName;
    049    import org.deegree.framework.log.ILogger;
    050    import org.deegree.framework.log.LoggerFactory;
    051    import org.deegree.framework.util.CharsetUtils;
    052    import org.deegree.framework.util.StringTools;
    053    import org.deegree.framework.xml.InvalidConfigurationException;
    054    import org.deegree.framework.xml.XMLParsingException;
    055    import org.deegree.framework.xml.XMLTools;
    056    import org.deegree.model.metadata.iso19115.Keywords;
    057    import org.deegree.model.metadata.iso19115.OnlineResource;
    058    import org.deegree.model.spatialschema.Envelope;
    059    import org.deegree.ogcwebservices.getcapabilities.DCPType;
    060    import org.deegree.ogcwebservices.getcapabilities.HTTP;
    061    import org.deegree.ogcwebservices.getcapabilities.MetadataURL;
    062    import org.deegree.ogcwebservices.getcapabilities.Operation;
    063    import org.deegree.ogcwebservices.getcapabilities.OperationsMetadata;
    064    import org.deegree.ogcwebservices.getcapabilities.Protocol;
    065    import org.deegree.ogcwebservices.wfs.capabilities.FormatType;
    066    import org.deegree.ogcwebservices.wfs.capabilities.WFSCapabilitiesDocument;
    067    import org.deegree.ogcwebservices.wfs.capabilities.WFSFeatureType;
    068    import org.deegree.ogcwebservices.wfs.capabilities.WFSOperationsMetadata;
    069    import org.deegree.owscommon.OWSDomainType;
    070    import org.w3c.dom.Element;
    071    import org.w3c.dom.Node;
    072
    073    /**
    074     * Represents an XML configuration document for a deegree WFS instance, i.e. it consists of all sections common to an
    075     * OGC WFS 1.1 capabilities document plus some deegree specific elements.
    076     *
    077     * @author <a href="mailto:mschneider@lat-lon.de">Markus Schneider </a>
    078     * @author last edited by: $Author: mschneider $
    079     *
    080     * @version $Revision: 18195 $, $Date: 2009-06-18 17:55:39 +0200 (Do, 18. Jun 2009) $
    081     */
    082    public class WFSConfigurationDocument extends WFSCapabilitiesDocument {
    083
    084        private static final long serialVersionUID = -6415476866015999971L;
    085
    086        protected static final ILogger LOG = LoggerFactory.getLogger( WFSConfigurationDocument.class );
    087
    088        /**
    089         * Creates an object representation of the document.
    090         *
    091         * @return class representation of the configuration document
    092         * @throws InvalidConfigurationException
    093         */
    094        public WFSConfiguration getConfiguration()
    095                                throws InvalidConfigurationException {
    096
    097            WFSConfiguration config = null;
    098
    099            try {
    100                WFSDeegreeParams deegreeParams = getDeegreeParams();
    101
    102                // get default Urls (used when DCP element is ommitted in Operation-elements)
    103                OnlineResource defaultOnlineResource = deegreeParams.getDefaultOnlineResource();
    104                String defaultUrl = defaultOnlineResource.getLinkage().getHref().toString();
    105                if ( defaultUrl.endsWith( "?" ) ) {
    106                    defaultUrl = defaultUrl.substring( 0, defaultUrl.length() - 1 );
    107                }
    108                URL defaultUrlGet = new URL( defaultUrl + '?' );
    109                URL defaultUrlPost = new URL( defaultUrl );
    110
    111                OperationsMetadata opMetadata = getOperationsMetadata( defaultUrlGet, defaultUrlPost );
    112                config = new WFSConfiguration( parseVersion(), parseUpdateSequence(), getServiceIdentification(),
    113                                               getServiceProvider(), opMetadata, getFeatureTypeList(),
    114                                               getServesGMLObjectTypeList(), getSupportsGMLObjectTypeList(), null,
    115                                               getFilterCapabilities(), deegreeParams );
    116            } catch ( Exception e ) {
    117                throw new InvalidConfigurationException( e.getMessage() + "\n" + StringTools.stackTraceToString( e ) );
    118            }
    119            return config;
    120        }
    121
    122        /**
    123         * Creates an object representation of the <code>deegreeParams</code>- section.
    124         *
    125         * @return class representation of the <code>deegreeParams</code>- section
    126         * @throws InvalidConfigurationException
    127         */
    128        public WFSDeegreeParams getDeegreeParams()
    129                                throws InvalidConfigurationException {
    130
    131            WFSDeegreeParams deegreeParams = null;
    132
    133            try {
    134                Element element = (Element) XMLTools.getRequiredNode( getRootElement(), "deegreewfs:deegreeParams",
    135                                                                      nsContext );
    136                OnlineResource defaultOnlineResource = parseOnLineResource( getRequiredElement(
    137                                                                                                element,
    138                                                                                                "deegreewfs:DefaultOnlineResource",
    139                                                                                                nsContext ) );
    140                int cacheSize = XMLTools.getNodeAsInt( element, "deegreewfs:CacheSize/text()", nsContext, 100 );
    141                int requestTimeLimit = XMLTools.getNodeAsInt( element, "deegreewfs:RequestTimeLimit/text()", nsContext, 10 );
    142
    143                boolean checkUTMZones = getNodeAsBoolean( element, "deegreewfs:CheckUTMZones", nsContext, false );
    144                boolean switchAxes = getNodeAsBoolean( element, "deegreewfs:SwitchAxesForEPSG4326", nsContext, false );
    145                boolean printGeomIds = getNodeAsBoolean( element, "deegreewfs:PrintGeometryGmlIds", nsContext, false );
    146
    147                String characterSet = XMLTools.getNodeAsString( element, "deegreewfs:Encoding/text()", nsContext,
    148                                                                CharsetUtils.getSystemCharset() );
    149                String[] dataDirectories = XMLTools.getNodesAsStrings(
    150                                                                       element,
    151                                                                       "deegreewfs:DataDirectoryList/deegreewfs:DataDirectory/text()",
    152                                                                       nsContext );
    153                if ( dataDirectories.length == 0 ) {
    154                    LOG.logInfo( "No data directory specified. Using configuration document directory." );
    155                    dataDirectories = new String[] { "." };
    156                }
    157                for ( int i = 0; i < dataDirectories.length; i++ ) {
    158                    try {
    159                        dataDirectories[i] = resolve( dataDirectories[i] ).toURI().getPath();
    160                    } catch ( Exception e ) {
    161                        String msg = "DataDirectory '" + dataDirectories[i] + "' cannot be resolved as a directory: "
    162                                     + e.getMessage();
    163                        throw new InvalidConfigurationException( msg );
    164                    }
    165                }
    166
    167                String lockManagerString = XMLTools.getNodeAsString( element, "deegreewfs:LockManagerDirectory/text()",
    168                                                                     nsContext, null );
    169                File lockManagerDir = null;
    170                if ( lockManagerString != null ) {
    171                    try {
    172                        lockManagerDir = new File( this.resolve( lockManagerString ).toURI().toURL().getFile() );
    173                    } catch ( Exception e ) {
    174                        String msg = "Specified value (" + lockManagerDir
    175                                     + ") for 'deegreewfs:LockManagerDirectory' is invalid.";
    176                        throw new InvalidConfigurationException( msg, e );
    177                    }
    178                }
    179                deegreeParams = new WFSDeegreeParams( defaultOnlineResource, cacheSize, requestTimeLimit, characterSet,
    180                                                      dataDirectories, lockManagerDir, checkUTMZones, switchAxes,
    181                                                      printGeomIds );
    182            } catch ( XMLParsingException e ) {
    183                throw new InvalidConfigurationException( "Error parsing the deegreeParams "
    184                                                         + "section of the WFS configuration: \n" + e.getMessage()
    185                                                         + StringTools.stackTraceToString( e ) );
    186            }
    187            return deegreeParams;
    188        }
    189
    190        /**
    191         * Creates an object representation of the <code>ows:OperationsMetadata</code> section.
    192         *
    193         * @param defaultUrlGet
    194         * @param defaultUrlPost
    195         * @return object representation of the <code>ows:OperationsMetadata</code> section
    196         * @throws XMLParsingException
    197         */
    198        public OperationsMetadata getOperationsMetadata( URL defaultUrlGet, URL defaultUrlPost )
    199                                throws XMLParsingException {
    200
    201            List<Node> operationElementList = XMLTools.getNodes( getRootElement(), "ows:OperationsMetadata/ows:Operation",
    202                                                                 nsContext );
    203
    204            // build HashMap of 'ows:Operation'-elements for easier access
    205            Map<String, Element> operations = new HashMap<String, Element>();
    206            for ( int i = 0; i < operationElementList.size(); i++ ) {
    207                operations.put( XMLTools.getRequiredNodeAsString( operationElementList.get( i ), "@name", nsContext ),
    208                                (Element) operationElementList.get( i ) );
    209            }
    210
    211            Operation getCapabilities = getOperation( OperationsMetadata.GET_CAPABILITIES_NAME, true, operations,
    212                                                      defaultUrlGet, defaultUrlPost );
    213            Operation describeFeatureType = getOperation( WFSOperationsMetadata.DESCRIBE_FEATURETYPE_NAME, true,
    214                                                          operations, defaultUrlGet, defaultUrlPost );
    215            Operation getFeature = getOperation( WFSOperationsMetadata.GET_FEATURE_NAME, false, operations, defaultUrlGet,
    216                                                 defaultUrlPost );
    217            Operation getFeatureWithLock = getOperation( WFSOperationsMetadata.GET_FEATURE_WITH_LOCK_NAME, false,
    218                                                         operations, defaultUrlGet, defaultUrlPost );
    219            Operation getGMLObject = getOperation( WFSOperationsMetadata.GET_GML_OBJECT_NAME, false, operations,
    220                                                   defaultUrlGet, defaultUrlPost );
    221            Operation lockFeature = getOperation( WFSOperationsMetadata.LOCK_FEATURE_NAME, false, operations,
    222                                                  defaultUrlGet, defaultUrlPost );
    223            Operation transaction = getOperation( WFSOperationsMetadata.TRANSACTION_NAME, false, operations, defaultUrlGet,
    224                                                  defaultUrlPost );
    225
    226            List<Element> parameterElementList = XMLTools.getElements( getRootElement(),
    227                                                                       "ows:OperationsMetadata/ows:Parameter", nsContext );
    228            OWSDomainType[] parameters = new OWSDomainType[parameterElementList.size()];
    229            for ( int i = 0; i < parameters.length; i++ ) {
    230                parameters[i] = getOWSDomainType( null, parameterElementList.get( i ) );
    231            }
    232
    233            List<Element> constraintElementList = XMLTools.getElements( getRootElement(),
    234                                                                        "ows:OperationsMetadata/ows:Constraint", nsContext );
    235            OWSDomainType[] constraints = new OWSDomainType[constraintElementList.size()];
    236            for ( int i = 0; i < constraints.length; i++ ) {
    237                constraints[i] = getOWSDomainType( null, constraintElementList.get( i ) );
    238            }
    239            WFSOperationsMetadata metadata = new WFSOperationsMetadata( getCapabilities, describeFeatureType, getFeature,
    240                                                                        getFeatureWithLock, getGMLObject, lockFeature,
    241                                                                        transaction, parameters, constraints );
    242
    243            return metadata;
    244        }
    245
    246        /**
    247         * Creates an object representation of an <code>ows:Operation</code>- element.
    248         *
    249         * @param name
    250         * @param isMandatory
    251         * @param operations
    252         * @param defaultUrlGet
    253         * @param defaultUrlPost
    254         * @return object representation of <code>ows:Operation</code>- element
    255         * @throws XMLParsingException
    256         */
    257        protected Operation getOperation( String name, boolean isMandatory, Map<String, Element> operations,
    258                                          URL defaultUrlGet, URL defaultUrlPost )
    259                                throws XMLParsingException {
    260
    261            Operation operation = null;
    262            Element operationElement = operations.get( name );
    263            if ( operationElement == null ) {
    264                if ( isMandatory ) {
    265                    throw new XMLParsingException( "Mandatory operation '" + name + "' not defined in "
    266                                                   + "'OperationsMetadata'-section." );
    267                }
    268            } else {
    269                // "ows:Parameter"-elements
    270                List<Element> parameterElements = XMLTools.getElements( operationElement, "ows:Parameter", nsContext );
    271                OWSDomainType[] parameters = new OWSDomainType[parameterElements.size()];
    272                for ( int i = 0; i < parameters.length; i++ ) {
    273                    parameters[i] = getOWSDomainType( name, parameterElements.get( i ) );
    274                }
    275
    276                DCPType[] dcps = null;
    277                List<Element> nl = XMLTools.getElements( operationElement, "ows:DCP", nsContext );
    278                if ( nl.size() > 0 ) {
    279                    dcps = getDCPs( nl );
    280                } else {
    281                    // add default URLs
    282                    dcps = new DCPType[1];
    283                    Protocol protocol = new HTTP( new URL[] { defaultUrlGet }, new URL[] { defaultUrlPost } );
    284                    dcps[0] = new DCPType( protocol );
    285                }
    286                operation = new Operation( name, dcps, parameters );
    287            }
    288            return operation;
    289        }
    290
    291        /**
    292         * Returns the object representation for an element of type <code>wfs:FeatureTypeType</code>.
    293         *
    294         * @param element
    295         * @return object representation for the element of type <code>wfs:OperationsType</code>
    296         * @throws XMLParsingException
    297         */
    298        @Override
    299        public WFSFeatureType getFeatureTypeType( Element element )
    300                                throws XMLParsingException {
    301
    302            QualifiedName name = parseQualifiedName( XMLTools.getRequiredNode( element, "wfs:Name/text()", nsContext ) );
    303            String title = XMLTools.getRequiredNodeAsString( element, "wfs:Title/text()", nsContext );
    304            String abstract_ = XMLTools.getNodeAsString( element, "wfs:Abstract/text()", nsContext, null );
    305            Keywords[] keywords = getKeywords( XMLTools.getNodes( element, "ows:Keywords", nsContext ) );
    306
    307            URI defaultSrs = null;
    308            URI[] otherSrs = null;
    309            Node noSrsElement = XMLTools.getNode( element, "wfs:NoSRS", nsContext );
    310            if ( noSrsElement == null ) {
    311                defaultSrs = XMLTools.getNodeAsURI( element, "wfs:DefaultSRS/text()", nsContext, null );
    312                otherSrs = XMLTools.getNodesAsURIs( element, "wfs:OtherSRS/text()", nsContext );
    313            }
    314
    315            org.deegree.ogcwebservices.wfs.capabilities.Operation[] operations = null;
    316            Element operationsTypeElement = (Element) XMLTools.getNode( element, "wfs:Operations", nsContext );
    317            if ( operationsTypeElement != null ) {
    318                operations = getOperationsType( operationsTypeElement );
    319            }
    320            List<Element> formatElementList = XMLTools.getElements( element, "wfs:OutputFormats/wfs:Format", nsContext );
    321            FormatType[] formats = new FormatType[formatElementList.size()];
    322            for ( int i = 0; i < formats.length; i++ ) {
    323                formats[i] = getFormatType( formatElementList.get( i ) );
    324            }
    325            List<Element> wgs84BoundingBoxElements = XMLTools.getElements( element, "ows:WGS84BoundingBox", nsContext );
    326            if ( wgs84BoundingBoxElements.size() < 1 ) {
    327                throw new XMLParsingException( "A 'wfs:FeatureTypeType' must contain at least one "
    328                                               + "'ows:WGS84BoundingBox'-element." );
    329            }
    330            Envelope[] wgs84BoundingBoxes = new Envelope[wgs84BoundingBoxElements.size()];
    331            for ( int i = 0; i < wgs84BoundingBoxes.length; i++ ) {
    332                wgs84BoundingBoxes[i] = getWGS84BoundingBoxType( wgs84BoundingBoxElements.get( i ) );
    333            }
    334            List<Element> metadataURLElementList = XMLTools.getElements( element, "wfs:MetadataURL", nsContext );
    335            MetadataURL[] metadataUrls = new MetadataURL[metadataURLElementList.size()];
    336            for ( int i = 0; i < metadataUrls.length; i++ ) {
    337                metadataUrls[i] = getMetadataURL( metadataURLElementList.get( i ) );
    338            }
    339            WFSFeatureType featureType = new WFSFeatureType( name, title, abstract_, keywords, defaultSrs, otherSrs,
    340                                                             operations, formats, wgs84BoundingBoxes, metadataUrls );
    341
    342            return featureType;
    343        }
    344    }