001    //$HeadURL: https://svn.wald.intevation.org/svn/deegree/base/branches/2.3_testing/src/org/deegree/owscommon_new/OWSCommonCapabilitiesDocument.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.owscommon_new;
037    
038    import java.net.URI;
039    import java.net.URISyntaxException;
040    import java.util.ArrayList;
041    import java.util.Arrays;
042    import java.util.Date;
043    import java.util.List;
044    import java.util.Map;
045    
046    import org.deegree.datatypes.Code;
047    import org.deegree.datatypes.QualifiedName;
048    import org.deegree.datatypes.values.TypedLiteral;
049    import org.deegree.datatypes.xlink.SimpleLink;
050    import org.deegree.framework.xml.XMLFragment;
051    import org.deegree.framework.xml.XMLParsingException;
052    import org.deegree.framework.xml.XMLTools;
053    import org.deegree.model.metadata.iso19115.CitedResponsibleParty;
054    import org.deegree.model.metadata.iso19115.Constraints;
055    import org.deegree.model.metadata.iso19115.ISO19115Document;
056    import org.deegree.model.metadata.iso19115.Keywords;
057    import org.deegree.model.metadata.iso19115.OnlineResource;
058    import org.deegree.ogcbase.CommonNamespaces;
059    import org.w3c.dom.Element;
060    
061    /**
062     * <code>OWSCommonCapabilitiesDocument</code> is the parser class for the
063     * <code>OWSCommonCapabilities</code> data class.
064     *
065     * @author <a href="mailto:schmitz@lat-lon.de">Andreas Schmitz</a>
066     * @author last edited by: $Author: mschneider $
067     *
068     * @version 2.0, $Revision: 18195 $, $Date: 2009-06-18 17:55:39 +0200 (Do, 18. Jun 2009) $
069     *
070     * @since 2.0
071     */
072    
073    public class OWSCommonCapabilitiesDocument extends XMLFragment {
074    
075        private static final long serialVersionUID = 5069379023892304513L;
076    
077        private static final String POWS = CommonNamespaces.OWS_PREFIX + ":";
078    
079        private ISO19115Document iso = new ISO19115Document();
080    
081        /**
082         * @param contents
083         *            the service specific contents
084         * @return the data object containing all parsed information.
085         * @throws XMLParsingException
086         */
087        public OWSCommonCapabilities parseCapabilities( Map<String, Content> contents )
088                                throws XMLParsingException {
089            Element root = getRootElement();
090    
091            String version = XMLTools.getRequiredNodeAsString( root, "@version", nsContext );
092            String updateSequence = XMLTools.getNodeAsString( root, "@updateSequence", nsContext, null );
093    
094            Element elem = (Element) XMLTools.getNode( root, POWS + "ServiceIdentification", nsContext );
095            ServiceIdentification serviceIdentification = null;
096            if ( elem != null )
097                serviceIdentification = parseServiceIdentification( elem );
098    
099            elem = (Element) XMLTools.getNode( root, POWS + "ServiceProvider", nsContext );
100            ServiceProvider serviceProvider = null;
101            if ( elem != null )
102                serviceProvider = parseServiceProvider( elem );
103    
104            OperationsMetadata operationsMetadata = null;
105            elem = (Element) XMLTools.getNode( root, POWS + "OperationsMetadata", nsContext );
106            if ( elem != null )
107                operationsMetadata = parseOperationsMetadata( elem );
108    
109            OWSCommonCapabilities capabilities = new OWSCommonCapabilities( version, updateSequence, serviceIdentification,
110                                                                            serviceProvider, operationsMetadata, contents );
111            return capabilities;
112        }
113    
114        private OperationsMetadata parseOperationsMetadata( Element root )
115                                throws XMLParsingException {
116            List<Element> operationElements = XMLTools.getRequiredElements( root, POWS + "Operation", nsContext );
117            if ( operationElements.size() < 2 ) {
118                throw new XMLParsingException( "Too few operations defined in the Operations" + "Metadata element." );
119            }
120    
121            List<Operation> operations = new ArrayList<Operation>();
122            for ( Element element : operationElements ) {
123                operations.add( parseOperation( element ) );
124            }
125    
126            List<Element> parameterElements = XMLTools.getElements( root, POWS + "Parameter", nsContext );
127            List<Parameter> parameters = new ArrayList<Parameter>();
128    
129            for ( Element parameter : parameterElements ) {
130                parameters.add( parseDomainType( parameter, true, true, false, false ) );
131            }
132    
133            List<Element> constraintElements = XMLTools.getElements( root, POWS + "Constraint", nsContext );
134            List<DomainType> constraints = new ArrayList<DomainType>();
135    
136            for ( Element constraint : constraintElements ) {
137                constraints.add( parseDomainType( constraint, true, true, false, false ) );
138            }
139    
140            // extended capabilities are ignored for now
141    
142            OperationsMetadata result = new OperationsMetadata( parameters, constraints, operations, null );
143            return result;
144        }
145    
146        private Operation parseOperation( Element root )
147                                throws XMLParsingException {
148            QualifiedName name = XMLTools.getRequiredNodeAsQualifiedName( root, "@name", nsContext );
149    
150            List<DCP> dcps = parseDCPs( root );
151    
152            List<Element> parameterElements = XMLTools.getElements( root, POWS + "Parameter", nsContext );
153            List<Parameter> parameters = new ArrayList<Parameter>();
154    
155            for ( Element parameter : parameterElements )
156                parameters.add( parseDomainType( parameter, true, true, false, false ) );
157    
158            List<Element> constraintElements = XMLTools.getElements( root, POWS + "Constraint", nsContext );
159            List<DomainType> constraints = new ArrayList<DomainType>();
160    
161            for ( Element constraint : constraintElements )
162                constraints.add( parseDomainType( constraint, true, true, false, false ) );
163    
164            List<Element> metadataElements = XMLTools.getElements( root, POWS + "Metadata", nsContext );
165            List<Metadata> metadatas = new ArrayList<Metadata>();
166    
167            for ( Element metadata : metadataElements )
168                metadatas.add( parseMetadata( metadata ) );
169    
170            Operation result = new Operation( name, dcps, parameters, constraints, metadatas, "n/a" );
171            return result;
172        }
173    
174        // parameter should be the element containing the DCP element
175        private List<DCP> parseDCPs( Element root )
176                                throws XMLParsingException {
177            List<DCP> result = new ArrayList<DCP>();
178            List<Element> dcps = XMLTools.getElements( root, POWS + "DCP", nsContext );
179    
180            for ( Element dcp : dcps )
181                result.add( parseHTTP( dcp ) );
182    
183            return result;
184        }
185    
186        private HTTP parseHTTP( Element root )
187                                throws XMLParsingException {
188    
189            List<Element> get = XMLTools.getElements( root, POWS + "HTTP/" + POWS + "Get", nsContext );
190            List<Element> post = XMLTools.getElements( root, POWS + "HTTP/" + POWS + "Post", nsContext );
191    
192            if ( ( get.size() + post.size() ) == 0 )
193                throw new XMLParsingException( "At least one of Get or Post " + "must be specified under DCP/HTTP." );
194    
195            List<HTTP.Type> types = new ArrayList<HTTP.Type>();
196            List<OnlineResource> links = new ArrayList<OnlineResource>();
197            List<List<DomainType>> constraints = new ArrayList<List<DomainType>>();
198    
199            for ( Element elem : get ) {
200                OnlineResource link = iso.parseOnlineResource( elem );
201                List<Element> constraintElements = XMLTools.getElements( elem, POWS + "Constraint", nsContext );
202                List<DomainType> myConstr = new ArrayList<DomainType>();
203                for ( Element constraint : constraintElements )
204                    myConstr.add( parseDomainType( constraint, true, true, false, false ) );
205    
206                types.add( HTTP.Type.Get );
207                constraints.add( myConstr );
208                links.add( link );
209            }
210    
211            for ( Element elem : post ) {
212                OnlineResource link = iso.parseOnlineResource( elem );
213                List<Element> constraintElements = XMLTools.getElements( elem, POWS + "Constraint", nsContext );
214                List<DomainType> myConstr = new ArrayList<DomainType>();
215                for ( Element constraint : constraintElements )
216                    myConstr.add( parseDomainType( constraint, true, true, false, false ) );
217    
218                types.add( HTTP.Type.Post );
219                constraints.add( myConstr );
220                links.add( link );
221            }
222    
223            return new HTTP( links, constraints, types );
224        }
225    
226        private Metadata parseMetadata( Element root )
227                                throws XMLParsingException {
228            SimpleLink link = parseSimpleLink( root );
229            URI about = XMLTools.getNodeAsURI( root, "@about", nsContext, null );
230            return new Metadata( link, about, null );
231        }
232    
233        private DomainType parseDomainType( Element root, boolean optional, boolean repeatable, boolean noValuesAllowed,
234                                            boolean anyValueAllowed )
235                                throws XMLParsingException {
236            String[] valueArray = XMLTools.getRequiredNodesAsStrings( root, POWS + "Value", nsContext );
237            List<TypedLiteral> values = new ArrayList<TypedLiteral>();
238            URI stringURI = null;
239            try {
240                stringURI = new URI( null, "String", null );
241            } catch ( URISyntaxException e ) {
242                // cannot happen, why do I have to catch this?
243            }
244            for ( String value : valueArray )
245                values.add( new TypedLiteral( value, stringURI ) );
246    
247            List<Element> metadataElements = XMLTools.getElements( root, POWS + "Metadata", nsContext );
248            List<Metadata> metadata = new ArrayList<Metadata>();
249    
250            for ( Element element : metadataElements )
251                metadata.add( parseMetadata( element ) );
252    
253            QualifiedName name = XMLTools.getRequiredNodeAsQualifiedName( root, "@name", nsContext );
254    
255            DomainType result = new DomainType( optional, repeatable, "n/a", 0, name, values, null, null, anyValueAllowed,
256                                                null, noValuesAllowed, null, null, null, metadata );
257            return result;
258        }
259    
260        private ServiceProvider parseServiceProvider( Element root )
261                                throws XMLParsingException {
262            String providerName = XMLTools.getRequiredNodeAsString( root, POWS + "ProviderName", nsContext );
263    
264            OnlineResource providerSite = null;
265            Element siteElement = (Element) XMLTools.getNode( root, POWS + "ProviderSite", nsContext );
266            if ( siteElement != null )
267                providerSite = iso.parseOnlineResource( siteElement );
268    
269            Element partyElement = (Element) XMLTools.getRequiredNode( root, POWS + "ServiceContact", nsContext );
270            CitedResponsibleParty party = iso.parseCitedResponsibleParty( partyElement );
271    
272            ServiceProvider result = new ServiceProvider( providerName, providerSite, party );
273            return result;
274        }
275    
276        private ServiceIdentification parseServiceIdentification( Element root )
277                                throws XMLParsingException {
278            Element elem = (Element) XMLTools.getRequiredNode( root, POWS + "ServiceType", nsContext );
279            Code serviceType = iso.parseCode( elem );
280    
281            List<String> versions = Arrays.asList( XMLTools.getRequiredNodesAsStrings( root, POWS + "ServiceTypeVersion",
282                                                                                       nsContext ) );
283    
284            String fee = XMLTools.getNodeAsString( root, POWS + "Fees", nsContext, null );
285    
286            List<Element> constraintElements = XMLTools.getElements( root, POWS + "AccessConstraints", nsContext );
287            List<Constraints> constraints = new ArrayList<Constraints>();
288    
289            for ( Element constraint : constraintElements )
290                constraints.add( iso.parseConstraint( constraint, fee ) );
291    
292            String title = XMLTools.getNodeAsString( root, POWS + "Title", nsContext, null );
293            String abstractString = XMLTools.getNodeAsString( root, POWS + "Abstract", nsContext, null );
294    
295            List<Element> keywordsElements = XMLTools.getElements( root, POWS + "Keywords", nsContext );
296            List<Keywords> keywords = new ArrayList<Keywords>();
297            for ( Element keyword : keywordsElements )
298                keywords.add( iso.parseKeywords( keyword ) );
299    
300            // the next one is an extension
301            List<String> alternativeTitles = Arrays.asList( XMLTools.getNodesAsStrings( root, POWS + "AlternateTitle",
302                                                                                        nsContext ) );
303    
304            Date date = new Date( System.currentTimeMillis() );
305    
306            String identification = title;
307    
308            ServiceIdentification result = new ServiceIdentification( serviceType, versions, title, alternativeTitles,
309                                                                      date, identification, abstractString, keywords,
310                                                                      constraints );
311            return result;
312        }
313    
314    }