001    //$HeadURL: svn+ssh://rbezema@svn.wald.intevation.org/deegree/base/branches/2.2_testing/src/org/deegree/ogcwebservices/wfs/configuration/WFSConfigurationDocument.java $
002    /*----------------    FILE HEADER  ------------------------------------------
003    
004     This file is part of deegree.
005     Copyright (C) 2001-2008 by:
006     EXSE, Department of Geography, University of Bonn
007     http://www.giub.uni-bonn.de/deegree/
008     lat/lon GmbH
009     http://www.lat-lon.de
010    
011     This library is free software; you can redistribute it and/or
012     modify it under the terms of the GNU Lesser General Public
013     License as published by the Free Software Foundation; either
014     version 2.1 of the License, or (at your option) any later version.
015    
016     This library is distributed in the hope that it will be useful,
017     but WITHOUT ANY WARRANTY; without even the implied warranty of
018     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
019     Lesser General Public License for more details.
020    
021     You should have received a copy of the GNU Lesser General Public
022     License along with this library; if not, write to the Free Software
023     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
024    
025     Contact:
026    
027     Andreas Poth
028     lat/lon GmbH
029     Aennchenstraße 19
030     53177 Bonn
031     Germany
032     E-Mail: poth@lat-lon.de
033    
034     Prof. Dr. Klaus Greve
035     Department of Geography
036     University of Bonn
037     Meckenheimer Allee 166
038     53115 Bonn
039     Germany
040     E-Mail: greve@giub.uni-bonn.de
041     
042     ---------------------------------------------------------------------------*/
043    package org.deegree.ogcwebservices.wfs.configuration;
044    
045    import java.io.File;
046    import java.net.URL;
047    import java.util.HashMap;
048    import java.util.List;
049    import java.util.Map;
050    
051    import org.deegree.framework.log.ILogger;
052    import org.deegree.framework.log.LoggerFactory;
053    import org.deegree.framework.util.CharsetUtils;
054    import org.deegree.framework.util.StringTools;
055    import org.deegree.framework.xml.InvalidConfigurationException;
056    import org.deegree.framework.xml.XMLParsingException;
057    import org.deegree.framework.xml.XMLTools;
058    import org.deegree.model.metadata.iso19115.OnlineResource;
059    import org.deegree.ogcwebservices.getcapabilities.DCPType;
060    import org.deegree.ogcwebservices.getcapabilities.HTTP;
061    import org.deegree.ogcwebservices.getcapabilities.Operation;
062    import org.deegree.ogcwebservices.getcapabilities.OperationsMetadata;
063    import org.deegree.ogcwebservices.getcapabilities.Protocol;
064    import org.deegree.ogcwebservices.wfs.capabilities.WFSCapabilitiesDocument;
065    import org.deegree.ogcwebservices.wfs.capabilities.WFSOperationsMetadata;
066    import org.deegree.owscommon.OWSDomainType;
067    import org.w3c.dom.Element;
068    import org.w3c.dom.Node;
069    
070    /**
071     * Represents an XML configuration document for a deegree WFS instance, i.e. it consists of all
072     * sections common to an OGC WFS 1.1 capabilities document plus some deegree specific elements.
073     * 
074     * @author <a href="mailto:mschneider@lat-lon.de">Markus Schneider </a>
075     * @author last edited by: $Author: apoth $
076     * 
077     * @version $Revision: 9348 $, $Date: 2007-12-27 17:59:14 +0100 (Do, 27 Dez 2007) $
078     */
079    public class WFSConfigurationDocument extends WFSCapabilitiesDocument {
080    
081        private static final long serialVersionUID = -6415476866015999971L;
082    
083        protected static final ILogger LOG = LoggerFactory.getLogger( WFSConfigurationDocument.class );
084    
085        /**
086         * Creates an object representation of the document.
087         * 
088         * @return class representation of the configuration document
089         * @throws InvalidConfigurationException
090         */
091        public WFSConfiguration getConfiguration()
092                                throws InvalidConfigurationException {
093    
094            WFSConfiguration config = null;
095    
096            try {
097                WFSDeegreeParams deegreeParams = getDeegreeParams();
098    
099                // get default Urls (used when DCP element is ommitted in Operation-elements)
100                OnlineResource defaultOnlineResource = deegreeParams.getDefaultOnlineResource();
101                String defaultUrl = defaultOnlineResource.getLinkage().getHref().toString();
102                if ( defaultUrl.endsWith( "?" ) ) {
103                    defaultUrl = defaultUrl.substring( 0, defaultUrl.length() - 1 );
104                }
105                URL defaultUrlGet = new URL( defaultUrl + '?' );
106                URL defaultUrlPost = new URL( defaultUrl );
107    
108                OperationsMetadata opMetadata = getOperationsMetadata( defaultUrlGet, defaultUrlPost );
109                config = new WFSConfiguration( parseVersion(), parseUpdateSequence(), getServiceIdentification(),
110                                               getServiceProvider(), opMetadata, getFeatureTypeList(),
111                                               getServesGMLObjectTypeList(), getSupportsGMLObjectTypeList(), null,
112                                               getFilterCapabilities(), deegreeParams );
113            } catch ( Exception e ) {
114                throw new InvalidConfigurationException( e.getMessage() + "\n" + StringTools.stackTraceToString( e ) );
115            }
116            return config;
117        }
118    
119        /**
120         * Creates an object representation of the <code>deegreeParams</code>- section.
121         * 
122         * @return class representation of the <code>deegreeParams</code>- section
123         * @throws InvalidConfigurationException
124         */
125        public WFSDeegreeParams getDeegreeParams()
126                                throws InvalidConfigurationException {
127    
128            WFSDeegreeParams deegreeParams = null;
129    
130            try {
131                Element element = (Element) XMLTools.getRequiredNode( getRootElement(), "deegreewfs:deegreeParams",
132                                                                      nsContext );
133                OnlineResource defaultOnlineResource = parseOnLineResource( (Element) XMLTools.getRequiredNode(
134                                                                                                                element,
135                                                                                                                "deegreewfs:DefaultOnlineResource",
136                                                                                                                nsContext ) );
137                int cacheSize = XMLTools.getNodeAsInt( element, "deegreewfs:CacheSize/text()", nsContext, 100 );
138                int requestTimeLimit = XMLTools.getNodeAsInt( element, "deegreewfs:RequestTimeLimit/text()", nsContext, 10 );
139                String characterSet = XMLTools.getNodeAsString( element, "deegreewfs:Encoding/text()", nsContext,
140                                                                CharsetUtils.getSystemCharset() );
141                String[] dataDirectories = XMLTools.getNodesAsStrings(
142                                                                       element,
143                                                                       "deegreewfs:DataDirectoryList/deegreewfs:DataDirectory/text()",
144                                                                       nsContext );
145                if ( dataDirectories.length == 0 ) {
146                    LOG.logInfo( "No data directory specified. Using configuration document directory." );
147                    dataDirectories = new String[] { "." };
148                }
149                for ( int i = 0; i < dataDirectories.length; i++ ) {
150                    try {
151                        dataDirectories[i] = resolve( dataDirectories[i] ).toURI().getPath();
152                    } catch ( Exception e ) {
153                        String msg = "DataDirectory '" + dataDirectories[i] + "' cannot be resolved as a directory: "
154                                     + e.getMessage();
155                        throw new InvalidConfigurationException( msg );
156                    }
157                }
158    
159                String lockManagerString = XMLTools.getNodeAsString( element, "deegreewfs:LockManagerDirectory/text()",
160                                                                     nsContext, null );
161                File lockManagerDir = null;
162                if ( lockManagerString != null ) {
163                    try {
164                        lockManagerDir = new File( this.resolve( lockManagerString ).toURI().toURL().getFile() );
165                    } catch ( Exception e ) {
166                        String msg = "Specified value (" + lockManagerDir
167                                     + ") for 'deegreewfs:LockManagerDirectory' is invalid.";
168                        throw new InvalidConfigurationException( msg, e );
169                    }
170                }
171                deegreeParams = new WFSDeegreeParams( defaultOnlineResource, cacheSize, requestTimeLimit, characterSet,
172                                                      dataDirectories, lockManagerDir );
173            } catch ( XMLParsingException e ) {
174                throw new InvalidConfigurationException( "Error parsing the deegreeParams "
175                                                         + "section of the WFS configuration: \n" + e.getMessage()
176                                                         + StringTools.stackTraceToString( e ) );
177            }
178            return deegreeParams;
179        }
180    
181        /**
182         * Creates an object representation of the <code>ows:OperationsMetadata</code> section.
183         * 
184         * @param defaultUrlGet
185         * @param defaultUrlPost
186         * @return object representation of the <code>ows:OperationsMetadata</code> section
187         * @throws XMLParsingException
188         */
189        public OperationsMetadata getOperationsMetadata( URL defaultUrlGet, URL defaultUrlPost )
190                                throws XMLParsingException {
191    
192            List operationElementList = XMLTools.getNodes( getRootElement(), "ows:OperationsMetadata/ows:Operation",
193                                                           nsContext );
194    
195            // build HashMap of 'ows:Operation'-elements for easier access
196            Map<String, Element> operations = new HashMap<String, Element>();
197            for ( int i = 0; i < operationElementList.size(); i++ ) {
198                operations.put(
199                                XMLTools.getRequiredNodeAsString( (Node) operationElementList.get( i ), "@name", nsContext ),
200                                (Element) operationElementList.get( i ) );
201            }
202    
203            Operation getCapabilities = getOperation( OperationsMetadata.GET_CAPABILITIES_NAME, true, operations,
204                                                      defaultUrlGet, defaultUrlPost );
205            Operation describeFeatureType = getOperation( WFSOperationsMetadata.DESCRIBE_FEATURETYPE_NAME, true,
206                                                          operations, defaultUrlGet, defaultUrlPost );
207            Operation getFeature = getOperation( WFSOperationsMetadata.GET_FEATURE_NAME, false, operations, defaultUrlGet,
208                                                 defaultUrlPost );
209            Operation getFeatureWithLock = getOperation( WFSOperationsMetadata.GET_FEATURE_WITH_LOCK_NAME, false,
210                                                         operations, defaultUrlGet, defaultUrlPost );
211            Operation getGMLObject = getOperation( WFSOperationsMetadata.GET_GML_OBJECT_NAME, false, operations,
212                                                   defaultUrlGet, defaultUrlPost );
213            Operation lockFeature = getOperation( WFSOperationsMetadata.LOCK_FEATURE_NAME, false, operations,
214                                                  defaultUrlGet, defaultUrlPost );
215            Operation transaction = getOperation( WFSOperationsMetadata.TRANSACTION_NAME, false, operations, defaultUrlGet,
216                                                  defaultUrlPost );
217    
218            List parameterElementList = XMLTools.getNodes( getRootElement(), "ows:OperationsMetadata/ows:Parameter",
219                                                           nsContext );
220            OWSDomainType[] parameters = new OWSDomainType[parameterElementList.size()];
221            for ( int i = 0; i < parameters.length; i++ ) {
222                parameters[i] = getOWSDomainType( null, (Element) parameterElementList.get( i ) );
223            }
224    
225            List constraintElementList = XMLTools.getNodes( getRootElement(), "ows:OperationsMetadata/ows:Constraint",
226                                                            nsContext );
227            OWSDomainType[] constraints = new OWSDomainType[constraintElementList.size()];
228            for ( int i = 0; i < constraints.length; i++ ) {
229                constraints[i] = getOWSDomainType( null, (Element) constraintElementList.get( i ) );
230            }
231            WFSOperationsMetadata metadata = new WFSOperationsMetadata( getCapabilities, describeFeatureType, getFeature,
232                                                                        getFeatureWithLock, getGMLObject, lockFeature,
233                                                                        transaction, parameters, constraints );
234            
235            return metadata;
236        }
237    
238        /**
239         * Creates an object representation of an <code>ows:Operation</code>- element.
240         * 
241         * @param name
242         * @param isMandatory
243         * @param operations
244         * @param defaultUrlGet
245         * @param defaultUrlPost
246         * @return object representation of <code>ows:Operation</code>- element
247         * @throws XMLParsingException
248         */
249        protected Operation getOperation( String name, boolean isMandatory, Map<String, Element> operations,
250                                          URL defaultUrlGet, URL defaultUrlPost )
251                                throws XMLParsingException {
252    
253            Operation operation = null;
254            Element operationElement = operations.get( name );
255            if ( operationElement == null ) {
256                if ( isMandatory ) {
257                    throw new XMLParsingException( "Mandatory operation '" + name + "' not defined in "
258                                                   + "'OperationsMetadata'-section." );
259                }
260            } else {
261                // "ows:Parameter"-elements
262                List parameterElements = XMLTools.getNodes( operationElement, "ows:Parameter", nsContext );
263                OWSDomainType[] parameters = new OWSDomainType[parameterElements.size()];
264                for ( int i = 0; i < parameters.length; i++ ) {
265                    parameters[i] = getOWSDomainType( name, (Element) parameterElements.get( i ) );
266                }
267    
268                DCPType[] dcps = null;
269                List nl = XMLTools.getNodes( operationElement, "ows:DCP", nsContext );
270                if ( nl.size() > 0 ) {
271                    dcps = getDCPs( nl );
272                } else {
273                    // add default URLs
274                    dcps = new DCPType[1];
275                    Protocol protocol = new HTTP( new URL[] { defaultUrlGet }, new URL[] { defaultUrlPost } );
276                    dcps[0] = new DCPType( protocol );
277                }
278                operation = new Operation( name, dcps, parameters );
279            }
280            return operation;
281        }
282    }