001    //$HeadURL: svn+ssh://rbezema@svn.wald.intevation.org/deegree/base/branches/2.2_testing/src/org/deegree/ogcwebservices/csw/discovery/DescribeRecord.java $
002    /*----------------    FILE HEADER  ------------------------------------------
003     This file is part of deegree.
004     Copyright (C) 2001-2008 by:
005     Department of Geography, University of Bonn
006     http://www.giub.uni-bonn.de/deegree/
007     lat/lon GmbH
008     http://www.lat-lon.de
009     
010     This library is free software; you can redistribute it and/or
011     modify it under the terms of the GNU Lesser General Public
012     License as published by the Free Software Foundation; either
013     version 2.1 of the License, or (at your option) any later version.
014     
015     This library is distributed in the hope that it will be useful,
016     but WITHOUT ANY WARRANTY; without even the implied warranty of
017     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
018     Lesser General Public License for more details.
019     
020     You should have received a copy of the GNU Lesser General Public
021     License along with this library; if not, write to the Free Software
022     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
023     
024     Contact:
025     
026     Andreas Poth
027     lat/lon GmbH
028     Aennchenstraße 19
029     53177 Bonn
030     Germany
031     E-Mail: poth@lat-lon.de
032     
033     Prof. Dr. Klaus Greve
034     Department of Geography
035     University of Bonn
036     Meckenheimer Allee 166
037     53115 Bonn
038     Germany
039     E-Mail: greve@giub.uni-bonn.de
040     
041     ---------------------------------------------------------------------------*/
042    
043    package org.deegree.ogcwebservices.csw.discovery;
044    
045    import java.net.URI;
046    import java.net.URISyntaxException;
047    import java.util.HashMap;
048    import java.util.Map;
049    
050    import org.deegree.framework.log.ILogger;
051    import org.deegree.framework.log.LoggerFactory;
052    import org.deegree.framework.xml.NamespaceContext;
053    import org.deegree.framework.xml.XMLParsingException;
054    import org.deegree.framework.xml.XMLTools;
055    import org.deegree.ogcbase.CommonNamespaces;
056    import org.deegree.ogcwebservices.InvalidParameterValueException;
057    import org.deegree.ogcwebservices.MissingParameterValueException;
058    import org.deegree.ogcwebservices.OGCWebServiceException;
059    import org.deegree.ogcwebservices.csw.AbstractCSWRequest;
060    import org.deegree.ogcwebservices.csw.CSWPropertiesAccess;
061    import org.w3c.dom.Element;
062    
063    /**
064     * The mandatory DescribeRecord operation allows a client to discover elements of the information
065     * model supported by the target catalogue service. The operation allows some or all of the
066     * information model to be described.
067     * 
068     * @author <a href="mailto:poth@lat-lon.de">Andreas Poth </a>
069     * @author <a href="mailto:tfr@users.sourceforge.net">Torsten Friebe </a>
070     * @author <a href="mailto:mschneider@lat-lon.de">Markus Schneider </a>
071     * 
072     * @author last edited by: $Author: apoth $
073     * 
074     * @version $Revision: 9348 $, $Date: 2007-12-27 17:59:14 +0100 (Do, 27 Dez 2007) $
075     */
076    public class DescribeRecord extends AbstractCSWRequest {
077    
078        private static final long serialVersionUID = 6554937884331546780L;
079    
080        private static final ILogger LOG = LoggerFactory.getLogger( DescribeRecord.class );
081    
082        private static NamespaceContext nsContext = CommonNamespaces.getNamespaceContext();
083    
084        private Map namespaceMappings;
085    
086        private String[] typeNames;
087    
088        private String outputFormat;
089    
090        private URI schemaLanguage;
091    
092        /**
093         * creates a GetRecords request from the XML fragment passed. The passed element must be valid
094         * against the OGC CSW 2.0 GetRecords schema.
095         * 
096         * @param id
097         *            unique ID of the request
098         * @param root
099         *            root element of the GetRecors request
100         * @return
101         */
102        public static DescribeRecord create( String id, Element root )
103                                throws MissingParameterValueException, InvalidParameterValueException,
104                                OGCWebServiceException {
105    
106            String version = null;
107            try {
108                // first try to read verdsion attribute which is optional for CSW 2.0.0 and 2.0.1
109                version = XMLTools.getNodeAsString( root, "./@version", nsContext, null );
110            } catch ( XMLParsingException e ) {
111    
112            }
113            if ( version == null ) {
114                // if no version attribute has been set try mapping namespace URI to a version;
115                // this is not well defined for 2.0.0 and 2.0.1 which uses the same namespace.
116                // in this case 2.0.0 will be returned!
117                version = CSWPropertiesAccess.getString( root.getNamespaceURI() );
118            }
119    
120            // read class for version depenging parsing of DescribeRecord request from properties
121            String className = CSWPropertiesAccess.getString( "DescribeRecord" + version );
122            Class clzz = null;
123            try {
124                clzz = Class.forName( className );
125            } catch ( ClassNotFoundException e ) {
126                LOG.logError( e.getMessage(), e );
127                throw new InvalidParameterValueException( e.getMessage(), e );
128            }
129            DescribeRecordDocument document = null;
130            try {
131                document = (DescribeRecordDocument) clzz.newInstance();
132            } catch ( InstantiationException e ) {
133                LOG.logError( e.getMessage(), e );
134                throw new InvalidParameterValueException( e.getMessage(), e );
135            } catch ( IllegalAccessException e ) {
136                LOG.logError( e.getMessage(), e );
137                throw new InvalidParameterValueException( e.getMessage(), e );
138            }
139    
140            document.setRootElement( root );
141            return document.parse( id );
142    
143        }
144    
145        /**
146         * Creates a new <code>DecribeRecord</code> instance from the values stored in the submitted
147         * Map. Keys (parameter names) in the Map must be uppercase.
148         * 
149         * @TODO evaluate vendorSpecificParameter
150         * 
151         * @param kvp
152         *            Map containing the parameters
153         * @exception InvalidParameterValueException
154         * @throws MissingParameterValueException
155         */
156        public static DescribeRecord create( Map<String, String> kvp )
157                                throws InvalidParameterValueException, MissingParameterValueException {
158            
159    
160            String id;
161            String version;
162            Map<String, String> vendorSpecificParameter = new HashMap<String, String>();
163            Map namespaceMappings;
164            String[] typeNames = new String[0];
165            String outputFormat;
166            URI schemaLanguage;
167    
168            // 'ID'-attribute (optional)
169            id = getParam( "ID", kvp, "" );
170    
171            // 'VERSION'-attribute (mandatory)
172            version = getRequiredParam( "VERSION", kvp );
173    
174            // 'NAMESPACE'-attribute (optional)
175            namespaceMappings = getNSMappings( getParam( "NAMESPACE", kvp, null ) );
176    
177            // 'TYPENAME'-attribute (optional)
178            String typeNamesString = getParam( "TYPENAME", kvp, null );
179            if ( typeNamesString != null ) {
180                typeNames = typeNamesString.split( "," );
181            }
182    
183            // 'OUTPUTFORMAT'-attribute (optional)
184            if ( "2.0.2".equals( version  )) {
185                outputFormat = getParam( "OUTPUTFORMAT", kvp, "application/xml" );
186            } else {
187                outputFormat = getParam( "OUTPUTFORMAT", kvp, "text/xml" );
188            }
189    
190            // 'SCHEMALANGUAGE'-attribute (optional)
191            String schemaLanguageString = getParam( "SCHEMALANGUAGE", kvp, "XMLSCHEMA" );
192            try {
193                schemaLanguage = new URI( schemaLanguageString );
194            } catch ( URISyntaxException e ) {
195                String msg = "Value '" + schemaLanguageString
196                             + "' for parameter 'SCHEMALANGUAGE' is invalid. Must denote a valid URI.";
197                throw new InvalidParameterValueException( msg );
198            }
199    
200            
201            return new DescribeRecord( id, version, vendorSpecificParameter, namespaceMappings, typeNames, outputFormat,
202                                       schemaLanguage );
203        }
204    
205        /**
206         * Creates a new <code>DescribeRecord</code> instance.
207         * 
208         * @param id
209         * @param version
210         * @param vendorSpecificParameter
211         */
212        DescribeRecord( String id, String version, Map<String, String> vendorSpecificParameter ) {
213            super( version, id, vendorSpecificParameter );
214        }
215    
216        /**
217         * Creates a new <code>DescribeRecord</code> instance.
218         * 
219         * @param id
220         * @param version
221         * @param vendorSpecificParameter
222         * @param namespaceMappings
223         * @param typeNames
224         * @param outputFormat
225         * @param schemaLanguage
226         */
227        DescribeRecord( String id, String version, Map<String, String> vendorSpecificParameter, Map namespaceMappings,
228                        String[] typeNames, String outputFormat, URI schemaLanguage ) {
229            this( id, version, vendorSpecificParameter );
230            this.namespaceMappings = namespaceMappings;
231            this.typeNames = typeNames;
232            this.outputFormat = outputFormat;
233            this.schemaLanguage = schemaLanguage;
234        }
235    
236        /**
237         * Used to specify namespace(s) and their prefix(es). Format is [prefix:]uri. If prefix is not
238         * specified, then this is the default namespace.
239         * <p>
240         * Zero or one (Optional). Include value for each namespace used by a TypeName. If not included,
241         * all qualified names are in the default namespace
242         */
243        public Map getNamespaces() {
244            return this.namespaceMappings;
245        }
246    
247        /**
248         * One or more qualified type names to be described.
249         * <p>
250         * Zero or one (Optional). Default action is to describe all types known to server.
251         * 
252         */
253        public String[] getTypeNames() {
254            return this.typeNames;
255        }
256    
257        /**
258         * A MIME type indicating the format that the output document should have.
259         * <p>
260         * Zero or one (Optional). Default value is text/xml
261         * 
262         */
263        public String getOutputFormat() {
264            return this.outputFormat;
265        }
266    
267        /**
268         * Default value is 'XMLSCHEMA'.
269         * 
270         */
271        public URI getSchemaLanguage() {
272            return this.schemaLanguage;
273        }
274    }