001    // $HeadURL:
002    // /cvsroot/deegree/src/org/deegree/ogcwebservices/csw/capabilities/CatalogCapabilitiesDocument.java,v
003    // 1.22 2004/08/05 15:40:08 ap Exp $
004    /*----------------    FILE HEADER  ------------------------------------------
005    
006     This file is part of deegree.
007     Copyright (C) 2001-2006 by:
008     EXSE, Department of Geography, University of Bonn
009     http://www.giub.uni-bonn.de/deegree/
010     lat/lon GmbH
011     http://www.lat-lon.de
012    
013     This library is free software; you can redistribute it and/or
014     modify it under the terms of the GNU Lesser General Public
015     License as published by the Free Software Foundation; either
016     version 2.1 of the License, or (at your option) any later version.
017    
018     This library is distributed in the hope that it will be useful,
019     but WITHOUT ANY WARRANTY; without even the implied warranty of
020     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
021     Lesser General Public License for more details.
022    
023     You should have received a copy of the GNU Lesser General Public
024     License along with this library; if not, write to the Free Software
025     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
026    
027     Contact:
028    
029     Andreas Poth
030     lat/lon GmbH
031     Aennchenstr. 19
032     53115 Bonn
033     Germany
034     E-Mail: poth@lat-lon.de
035    
036     Prof. Dr. Klaus Greve
037     Department of Geography
038     University of Bonn
039     Meckenheimer Allee 166
040     53115 Bonn
041     Germany
042     E-Mail: greve@giub.uni-bonn.de
043     
044     ---------------------------------------------------------------------------*/
045    package org.deegree.ogcwebservices.csw.capabilities;
046    
047    import java.io.IOException;
048    import java.net.URI;
049    import java.net.URISyntaxException;
050    import java.net.URL;
051    import java.util.Arrays;
052    import java.util.HashMap;
053    import java.util.List;
054    import java.util.Map;
055    
056    import org.deegree.datatypes.xlink.SimpleLink;
057    import org.deegree.framework.log.ILogger;
058    import org.deegree.framework.log.LoggerFactory;
059    import org.deegree.framework.xml.ElementList;
060    import org.deegree.framework.xml.InvalidConfigurationException;
061    import org.deegree.framework.xml.XMLParsingException;
062    import org.deegree.framework.xml.XMLTools;
063    import org.deegree.i18n.Messages;
064    import org.deegree.model.filterencoding.capabilities.FilterCapabilities;
065    import org.deegree.model.filterencoding.capabilities.FilterCapabilities100Fragment;
066    import org.deegree.ogcbase.CommonNamespaces;
067    import org.deegree.ogcwebservices.getcapabilities.InvalidCapabilitiesException;
068    import org.deegree.ogcwebservices.getcapabilities.OGCCapabilities;
069    import org.deegree.ogcwebservices.getcapabilities.Operation;
070    import org.deegree.ogcwebservices.getcapabilities.OperationsMetadata;
071    import org.deegree.owscommon.OWSCommonCapabilitiesDocument;
072    import org.deegree.owscommon.OWSDomainType;
073    import org.w3c.dom.Element;
074    import org.w3c.dom.Node;
075    import org.xml.sax.SAXException;
076    
077    /**
078     * Represents an XML capabilities document for an OGC CSW 2.0 compliant service.
079     * 
080     * @author <a href="mailto:tfr@users.sourceforge.net">Torsten Friebe </a>
081     * @author <a href="mailto:mschneider@lat-lon.de">Markus Schneider </a>
082     * 
083     * @author last edited by: $Author: rbezema $
084     * 
085     * @version 2.0, $Revision: 7335 $, $Date: 2007-05-29 11:43:53 +0200 (Di, 29 Mai 2007) $
086     * 
087     * @since 2.0
088     * 
089     */
090    public class CatalogueCapabilitiesDocument extends OWSCommonCapabilitiesDocument {
091    
092        private static final ILogger LOG = LoggerFactory.getLogger( CatalogueCapabilitiesDocument.class );
093    
094        public final static String FILTER_CAPABILITIES_NAME = "FilterCapabilities";
095    
096        public final static String EBRIM_CAPABILITIES_NAME = "EBRIMCapabilities";
097    
098        protected static final URI OGCNS = CommonNamespaces.OGCNS;
099    
100        private static final String XML_TEMPLATE = "CatalogueCapabilitiesTemplate.xml";
101    
102        /**
103         * Creates a skeleton capabilities document that contains the mandatory elements only.
104         * 
105         * @throws IOException
106         * @throws SAXException
107         */
108        public void createEmptyDocument() throws IOException,
109                                         SAXException {
110            URL url = CatalogueCapabilitiesDocument.class.getResource( XML_TEMPLATE );
111            if ( url == null ) {
112                throw new IOException( "The resource '" + XML_TEMPLATE + " could not be found." );
113            }
114            load( url );
115        }
116    
117        /**
118         * Creates a class representation of the document.
119         * 
120         * @return class representation of the configuration document
121         */
122        public OGCCapabilities parseCapabilities() throws InvalidCapabilitiesException {
123            try {
124                FilterCapabilities filterCapabilities = null;
125                Element filterCapabilitiesElement = (Element) XMLTools.getNode( getRootElement(),
126                                                                                "ogc:Filter_Capabilities",
127                                                                                nsContext );
128                if ( filterCapabilitiesElement != null ) {
129                    filterCapabilities = new FilterCapabilities100Fragment( filterCapabilitiesElement, getSystemId() ).parseFilterCapabilities();
130                }
131                return new CatalogueCapabilities( parseVersion(),
132                                                  parseUpdateSequence(),
133                                                  getServiceIdentification(),
134                                                  getServiceProvider(),
135                                                  getOperationsMetadata(),
136                                                  null,
137                                                  filterCapabilities );
138            } catch ( Exception e ) {
139                LOG.logError( e.getMessage(), e );
140                throw new InvalidCapabilitiesException( e.getMessage() );
141            }
142        }
143    
144        /**
145         * Creates a class representation of the <code>OperationsMetadata</code>- section.
146         * 
147         * @return
148         * @throws InvalidConfigurationException
149         */
150        public OperationsMetadata getOperationsMetadata() throws XMLParsingException {
151    
152            Node root = this.getRootElement();
153    
154            Node omNode = XMLTools.getRequiredChildElement( "OperationsMetadata", OWSNS, root );
155            ElementList elementList = XMLTools.getChildElements( "Operation", OWSNS, omNode );
156    
157            ElementList parameterElements = XMLTools.getChildElements( "Parameter", OWSNS, omNode );
158            OWSDomainType[] parameters = new OWSDomainType[parameterElements.getLength()];
159    
160            for ( int i = 0; i < parameters.length; i++ ) {
161                parameters[i] = getOWSDomainType( null, parameterElements.item( i ) );
162            }
163    
164            // build HashMap of 'Operation'-elements for easier access
165            HashMap operations = new HashMap();
166            for ( int i = 0; i < elementList.getLength(); i++ ) {
167                operations.put( XMLTools.getRequiredAttrValue( "name", null, elementList.item( i ) ), elementList.item( i ) );
168            }
169    
170            // 'GetCapabilities'-operation
171            Operation getCapabilites = getOperation( OperationsMetadata.GET_CAPABILITIES_NAME, true, operations );
172            // 'DescribeRecord'-operation
173            Operation describeRecord = getOperation( CatalogueOperationsMetadata.DESCRIBE_RECORD_NAME, true, operations );
174            // 'GetDomain'-operation
175            Operation getDomain = getOperation( CatalogueOperationsMetadata.GET_DOMAIN_NAME, false, operations );
176            // 'GetRecords'-operation
177            Operation getRecords = getOperation( CatalogueOperationsMetadata.GET_RECORDS_NAME, true, operations );
178            // 'GetRecordById'-operation
179            Operation getRecordById = getOperation( CatalogueOperationsMetadata.GET_RECORD_BY_ID_NAME, true, operations );
180            // 'Transaction'-operation
181            Operation transaction = getOperation( CatalogueOperationsMetadata.TRANSACTION_NAME, false, operations );
182            // 'Harvest'-operation
183            Operation harvest = getOperation( CatalogueOperationsMetadata.HARVEST_NAME, false, operations );
184    
185            return new CatalogueOperationsMetadata( getCapabilites,
186                                                    describeRecord,
187                                                    getDomain,
188                                                    getRecords,
189                                                    getRecordById,
190                                                    transaction,
191                                                    harvest,
192                                                    parameters,
193                                                    null );
194        }
195    
196        /**
197         * @return a {@link EBRIMCapabilities} element (specified in the ogc-ebrim extension)
198         * @throws XMLParsingException
199         *             if a required node isn't found
200         */
201        protected EBRIMCapabilities parseEBRIMCapabilities() throws XMLParsingException {
202            Element rootElement = getRootElement();
203    
204            String prefix = rootElement.getOwnerDocument().lookupPrefix( CommonNamespaces.WRS_EBRIMNS.toString() );
205    
206            if ( prefix == null || "".equals( prefix.trim() ) ) {
207                return null;
208            }
209    
210            // SeviceFeatures
211            Element serviceFeature = (Element) XMLTools.getRequiredNode( rootElement, "wrs:ServiceFeatures", nsContext );
212            List nl = XMLTools.getNodes( serviceFeature, "wrs:feature", nsContext );
213            Map<URI, CSWFeature> features = new HashMap<URI, CSWFeature>();
214            for ( Object n : nl ) {
215                Node featureElement = (Node) n;
216                URI featureName = XMLTools.getRequiredNodeAsURI( featureElement, "@name", nsContext );
217                LOG.logDebug( "found featurename: " + featureName );
218                if ( features.containsKey( featureName ) ) {
219                    throw new XMLParsingException( Messages.getMessage( "WRS_UNAMBIGUOUS_FEAT_PROP", featureName.toString() ) );
220                }
221                CSWFeature feature = new CSWFeature( parsePropties( featureElement ) );
222                features.put( featureName, feature );
223            }
224    
225            Element serviceProps = (Element) XMLTools.getRequiredNode( rootElement, "wrs:ServiceProperties", nsContext );
226            Map<URI, List<String>> serviceProperties = parsePropties( serviceProps );
227            SimpleLink wsdl_SimpleLink = parseSimpleLink( (Element) XMLTools.getRequiredNode( rootElement,
228                                                                                              "wrs:WSDL-services",
229                                                                                              nsContext ) );
230    
231            return new EBRIMCapabilities( features, serviceProperties, wsdl_SimpleLink );
232        }
233    
234        private Map<URI, List<String>> parsePropties( Node xmlNode ) throws XMLParsingException {
235            List pnl = XMLTools.getNodes( xmlNode, "wrs:property", nsContext );
236            Map<URI, List<String>> properties = new HashMap<URI, List<String>>();
237    
238            for ( Object pn : pnl ) {
239                Node property = (Node) pn;
240                URI propName = XMLTools.getRequiredNodeAsURI( property, "@name", nsContext );
241                List<String> propValues = Arrays.asList( XMLTools.getRequiredNodesAsStrings( property,
242                                                                                             "wrs:value",
243                                                                                             nsContext ) );
244                properties.put( propName, propValues );
245            }
246            return properties;
247        }
248    }