//$Header: /home/deegree/jail/deegreerepository/deegree/src/org/deegree/ogcwebservices/csw/discovery/Discovery.java,v 1.85 2006/10/18 17:00:55 poth Exp $ /*---------------- FILE HEADER ------------------------------------------ This file is part of deegree. Copyright (C) 2001-2006 by: EXSE, Department of Geography, University of Bonn http://www.giub.uni-bonn.de/deegree/ lat/lon GmbH http://www.lat-lon.de This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Contact: Andreas Poth lat/lon GmbH Aennchenstr. 19 53115 Bonn Germany E-Mail: poth@lat-lon.de Prof. Dr. Klaus Greve Department of Geography University of Bonn Meckenheimer Allee 166 53115 Bonn Germany E-Mail: greve@giub.uni-bonn.de ---------------------------------------------------------------------------*/ package org.deegree.ogcwebservices.csw.discovery; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.StringWriter; import java.net.URI; import java.net.URISyntaxException; import java.net.URL; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import javax.xml.transform.TransformerException; import org.deegree.enterprise.servlet.OGCServletController; import org.deegree.framework.log.ILogger; import org.deegree.framework.log.LoggerFactory; import org.deegree.framework.util.FileUtils; import org.deegree.framework.util.StringTools; import org.deegree.framework.util.TimeTools; import org.deegree.framework.xml.XMLFragment; import org.deegree.framework.xml.XSLTDocument; import org.deegree.framework.xml.schema.XSDocument; import org.deegree.model.feature.FeatureCollection; import org.deegree.model.feature.GMLFeatureAdapter; import org.deegree.ogcbase.ExceptionCode; import org.deegree.ogcwebservices.InvalidParameterValueException; import org.deegree.ogcwebservices.OGCWebServiceException; import org.deegree.ogcwebservices.csw.capabilities.CatalogueOperationsMetadata; import org.deegree.ogcwebservices.csw.configuration.CatalogueConfiguration; import org.deegree.ogcwebservices.csw.configuration.CatalogueConfigurationDocument; import org.deegree.ogcwebservices.csw.configuration.CatalogueOutputSchemaParameter; import org.deegree.ogcwebservices.csw.configuration.CatalogueOutputSchemaValue; import org.deegree.ogcwebservices.csw.configuration.CatalogueTypeNameSchemaParameter; import org.deegree.ogcwebservices.csw.configuration.CatalogueTypeNameSchemaValue; import org.deegree.ogcwebservices.csw.discovery.GetRecords.RESULT_TYPE; import org.deegree.ogcwebservices.wfs.WFService; import org.deegree.ogcwebservices.wfs.capabilities.WFSCapabilities; import org.deegree.ogcwebservices.wfs.operation.FeatureResult; import org.deegree.ogcwebservices.wfs.operation.GetFeature; /** * The Discovery class allows clients to discover resources registered in a catalogue, by providing * four operations named <code>query</code>,<code>present</code>, * <code>describeRecordType</code>, and <code>getDomain</code>. This class has a required * association from the Catalogue Service class, and is thus always implemented by all Catalogue * Service implementations. The Session class can be included with the Discovery class, in * associations with the Catalogue Service class. The "e;query"e; and "e;present"e; * operations may be executed in a session or stateful context. If a session context exists, the * dynamic model uses internal states of the session and the allowed transitions between states. * When the "e;query"e; and "e;present"e; state does not include a session between a * server and a client, any memory or shared information between the client and the server may be * based on private understandings or features available in the protocol binding. The * describeRecordType and getDomain operations do not require a session context. * * @author <a href="mailto:poth@lat-lon.de">Andreas Poth </a> * @author <a href="mailto:tfr@users.sourceforge.net">Torsten Friebe </a> * * @author last edited by: $Author: poth $ * * @version 2.0, $Revision: 1.85 $, $Date: 2006/10/18 17:00:55 $ * * @since 2.0 */ public class Discovery { private static final ILogger LOG = LoggerFactory.getLogger( Discovery.class ); // Keys are Strings, values are XSLDocuments private static final Map<String, XSLTDocument> IN_XSL = new HashMap<String, XSLTDocument>(); // Keys are Strings, values are XSLDocuments private static final Map<String, XSLTDocument> OUT_XSL = new HashMap<String, XSLTDocument>(); // Keys are Strings, values are URLs private static final Map<String, URL> SCHEMA_URLS = new HashMap<String, URL>(); // Keys are Strings, values are XMLFragments private static final Map<String, XSDocument> SCHEMA_DOCS = new HashMap<String, XSDocument>(); private static final String DEFAULT_SCHEMA = "DublinCore"; private static final String OGC_CORE_SCHEMA = "OGCCORE"; private CatalogueConfiguration cswConfiguration = null; /** * The complete data access of a catalog service is managed by one instances of WFService. */ private WFService wfsResource; // single instance only for this CSW public Discovery( WFService wfsService, CatalogueConfiguration cswConfiguration ) { this.wfsResource = wfsService; this.cswConfiguration = cswConfiguration; try { CatalogueOperationsMetadata catalogMetadata = (CatalogueOperationsMetadata) cswConfiguration.getOperationsMetadata(); CatalogueOutputSchemaParameter outputSchemaParameter = (CatalogueOutputSchemaParameter) catalogMetadata.getGetRecords().getParameter( "outputSchema" ); CatalogueConfigurationDocument document = new CatalogueConfigurationDocument(); document.setSystemId( cswConfiguration.getSystemId() ); CatalogueOutputSchemaValue[] values = outputSchemaParameter.getSpecializedValues(); for ( int i = 0; i < values.length; i++ ) { CatalogueOutputSchemaValue value = values[i]; String schemaName = value.getValue().toUpperCase(); URL fileURL = document.resolve( value.getInXsl() ); LOG.logInfo( StringTools.concat( 300, "Input schema '", schemaName, "' is processed using XSLT-sheet from URL '", fileURL, "'" ) ); XSLTDocument inXSLSheet = new XSLTDocument(); inXSLSheet.load( fileURL ); IN_XSL.put( schemaName, inXSLSheet ); fileURL = document.resolve( value.getOutXsl() ); LOG.logInfo( StringTools.concat( 300, "Output schema '", schemaName, "' is processed using XSLT-sheet from URL '", fileURL, "'" ) ); XSLTDocument outXSLSheet = new XSLTDocument(); outXSLSheet.load( fileURL ); OUT_XSL.put( schemaName, outXSLSheet ); } // read and store schema definitions // each type(Name) provided by a CS-W is assigned to one schema CatalogueTypeNameSchemaParameter outputTypeNameParameter = (CatalogueTypeNameSchemaParameter) catalogMetadata.getGetRecords().getParameter( "typeName" ); CatalogueTypeNameSchemaValue[] tn_values = outputTypeNameParameter.getSpecializedValues(); for ( int i = 0; i < tn_values.length; i++ ) { CatalogueTypeNameSchemaValue value = tn_values[i]; URL fileURL = document.resolve( value.getSchema() ); XSDocument schemaDoc = new XSDocument(); schemaDoc.load( fileURL ); String typeName = value.getValue().toUpperCase(); LOG.logInfo( StringTools.concat( 300, "Schema for type '", typeName, "' is defined in XSD-file at URL '", fileURL, "'" ) ); SCHEMA_URLS.put( typeName, fileURL ); SCHEMA_DOCS.put( typeName, schemaDoc ); } } catch ( Exception e ) { e.printStackTrace(); LOG.logError( "Error while creating CSW Discovery: " + e.getMessage(), e ); } WFSCapabilities capa = (WFSCapabilities) wfsResource.getCapabilities(); LOG.logInfo( "CSW Discovery initialized with WFS resource " + capa.getServiceIdentification().getTitle() ); } public void finalize() throws Throwable { super.finalize(); } /** * Performs the submitted <code>DescribeRecord</code> -request. * * TODO: Check output schema & Co. * * @param request */ public DescribeRecordResult describeRecordType( DescribeRecord request ) throws OGCWebServiceException { // requested output format must be 'text/xml' if ( !( "text/xml".equals( request.getOutputFormat() ) ) ) { throw new OGCWebServiceException( "Discovery", "Requested output format '" + request.getOutputFormat() + "' is not " + "supported. The only supported format " + "is 'text/xml'.", ExceptionCode.INVALID_FORMAT ); } // requested schema language must be 'XMLSCHEMA' if ( !( "XMLSCHEMA".equals( request.getSchemaLanguage().toString() ) ) ) { throw new InvalidParameterValueException( "Requested schema language '" + request.getSchemaLanguage().toString() + "' is not supported. The only " + "supported schema language is 'XMLSCHEMA'." ); } // if no type names are specified, describe all known types String[] typeNames = request.getTypeNames(); if ( typeNames == null || typeNames.length == 0 ) { typeNames = SCHEMA_DOCS.keySet().toArray( new String[SCHEMA_DOCS.keySet().size()] ); } SchemaComponent[] schemaComponents = new SchemaComponent[typeNames.length]; for ( int i = 0; i < typeNames.length; i++ ) { XSDocument doc = SCHEMA_DOCS.get( typeNames[i].toUpperCase() ); if ( doc == null ) { String msg = "Type '" + typeNames[i] + " is not known to this Catalogue Service."; throw new OGCWebServiceException( this.getClass().getName(), msg ); } try { schemaComponents[i] = new SchemaComponent( doc, new URI( "http://www.deegree.org/csw" ), null, new URI( "XMLSCHEMA" ) ); } catch ( URISyntaxException e ) { throw new OGCWebServiceException( this.getClass().getName(), e.getMessage() ); } } return new DescribeRecordResult( request, "2.0.0", schemaComponents ); } /** * @param request * @todo not implemented, yet */ public DomainValues getDomain( GetDomain request ) { return new DomainValues(); } private String normalizeOutputSchema( String outputSchema ) throws InvalidParameterValueException { if ( outputSchema == null ) { outputSchema = DEFAULT_SCHEMA; } else if ( outputSchema.equalsIgnoreCase( OGC_CORE_SCHEMA ) ) { outputSchema = DEFAULT_SCHEMA; } outputSchema = outputSchema.toUpperCase(); if ( IN_XSL.get( outputSchema ) == null ) { String msg = "Unsupported output schema '" + outputSchema + "' requested. Supported schemas are: "; Iterator it = IN_XSL.keySet().iterator(); while ( it.hasNext() ) { msg += (String) it.next(); if ( it.hasNext() ) { msg += ", "; } else { msg += "."; } } throw new InvalidParameterValueException( msg ); } return outputSchema; } /** * Performs a <code>GetRecords</code> request. * <p> * This involves the following steps: * <ul> * <li><code>GetRecords</code>-><code>GetRecordsDocument</code></li> * <li><code>GetRecordsDocument</code>-><code>GetFeatureDocument</code> using XSLT</li> * <li><code>GetFeatureDocument</code>-><code>GetFeature</code></li> * <li><code>GetFeature</code> request is performed against the underlying WFS</li> * <li>WFS answers with a <code>FeatureResult</code> object (which contains a * <code>FeatureCollection</code>)</li> * <li><code>FeatureCollection</code>-> GMLFeatureCollectionDocument (as a String)</li> * <li>GMLFeatureCollectionDocument</code>-><code>GetRecordsResultDocument</code> using * XSLT</li> * <li><code>GetRecordsResultDocument</code>-><code>GetRecordsResult</code></li> * </ul> * </p> * * @param getRecords * @return GetRecordsResult * @throws OGCWebServiceException */ public GetRecordsResult query( GetRecords getRecords ) throws OGCWebServiceException { LOG.entering(); GetFeature getFeature = null; XMLFragment getFeatureDocument = null; Object wfsResponse = null; GetRecordsResult cswResponse = null; String outputSchema = normalizeOutputSchema( getRecords.getOutputSchema() ); // TODO remove this (only necessary because determineRecordsMatched changes the resultType) String resultType = getRecords.getResultTypeAsString(); XMLFragment getRecordsDocument = new XMLFragment( XMLFactory.export( getRecords ).getRootElement() ); LOG.logDebug( "Input GetRecords request:\n" + getRecordsDocument ); try { // incoming GetRecord request must be transformed to a GetFeature // request because the underlying 'data engine' of the CSW is a WFS XSLTDocument xslSheet = IN_XSL.get( outputSchema ); getFeatureDocument = xslSheet.transform( getRecordsDocument ); LOG.logDebug( "Generated WFS GetFeature request:\n" + getFeatureDocument ); } catch ( TransformerException e ) { e.printStackTrace(); String msg = "Can't transform GetRecord request to WFS GetFeature request: " + e.getMessage(); LOG.logError( msg, e ); throw new OGCWebServiceException( msg ); } if ( LOG.getLevel() == ILogger.LOG_DEBUG ) { StringWriter sw = new StringWriter( 5000 ); try { getFeatureDocument.prettyPrint( sw ); } catch ( TransformerException e ) { getFeatureDocument.write( sw ); } LOG.logDebug( sw.getBuffer().toString() ); } try { getFeature = GetFeature.create( getRecords.getId(), getFeatureDocument.getRootElement() ); } catch ( Exception e ) { String msg = "Cannot generate object representation for GetFeature request: " + e.getMessage(); LOG.logError( msg, e ); throw new OGCWebServiceException( msg ); } try { wfsResponse = wfsResource.doService( getFeature ); } catch ( OGCWebServiceException e ) { String msg = "Generated WFS GetFeature request failed: " + e.getMessage(); LOG.logError( msg, e ); throw new OGCWebServiceException( msg ); } // theoretical it is possible the result of a GetFeature request is not // an instance of FeatureResult; but this never should happen if ( !( wfsResponse instanceof FeatureResult ) ) { String msg = "Unexpected result type '" + wfsResponse.getClass().getName() + "' from WFS (must be FeatureResult)." + " Maybe a FeatureType is not correctly registered!?"; LOG.logError( msg ); throw new OGCWebServiceException( msg ); } FeatureResult featureResult = (FeatureResult) wfsResponse; // this never should happen too - but it is possible if ( !( featureResult.getResponse() instanceof FeatureCollection ) ) { String msg = "Unexpected reponse type: '" + featureResult.getResponse().getClass().getName() + " " + featureResult.getResponse().getClass() + "' in FeatureResult of WFS (must be a FeatureCollection)."; LOG.logError( msg ); throw new OGCWebServiceException( msg ); } FeatureCollection featureCollection = (FeatureCollection) featureResult.getResponse(); try { int numberOfRecordsReturned = featureCollection.size(); int numberOfMatchedRecords = 0; if ( getRecords.getResultType().equals( RESULT_TYPE.HITS ) ) { numberOfMatchedRecords = Integer.parseInt( featureCollection.getAttribute( "numberOfFeatures" ) ); } else { // if result type does not equal 'HITS', a separate request must // be created and performed to determine how many records match // the query numberOfMatchedRecords = determineRecordsMatched( getRecords ); } int startPosition = getRecords.getStartPosition(); if ( startPosition < 1 ) startPosition = 1; int nextRecord = startPosition + featureCollection.size(); HashMap<String, String> params = new HashMap<String, String>(); params.put( "REQUEST_ID", getRecords.getId() ); if ( numberOfRecordsReturned != 0 ) { params.put( "SEARCH_STATUS", "complete" ); } else { params.put( "SEARCH_STATUS", "none" ); } params.put( "TIMESTAMP", TimeTools.getISOFormattedTime() ); String[] typenames = getRecords.getQueries()[0].getTypeNames(); // this is a bit critical because // a) not the complete result can be validated but just single records // b) it is possible that several different record types are part // of a response that must be validated against different schemas String s = StringTools.concat( 300, OGCServletController.address, "?service=CSW&version=2.0.0&", "request=DescribeRecord&typeName=", typenames[0] ); params.put( "RECORD_SCHEMA", s ); params.put( "RECORDS_MATCHED", "" + numberOfMatchedRecords ); params.put( "RECORDS_RETURNED", "" + numberOfRecordsReturned ); params.put( "NEXT_RECORD", "" + nextRecord ); String elementSet = getRecords.getQueries()[0].getElementSetName(); if ( elementSet == null ) { elementSet = "CUSTOM"; } params.put( "ELEMENT_SET", elementSet ); params.put( "RESULT_TYPE", resultType ); params.put( "REQUEST_NAME", "GetRecords" ); ByteArrayOutputStream bos = new ByteArrayOutputStream( 50000 ); GMLFeatureAdapter ada = new GMLFeatureAdapter( true ); ada.export( featureCollection, bos ); if ( LOG.getLevel() == ILogger.LOG_DEBUG ) { s = new String( bos.toByteArray() ); LOG.logDebug( s ); FileUtils.writeToFile( "CSW_GetRecord_FC.xml", s ); } // vice versa to request transforming the feature collection being result // to the GetFeature request must be transformed into a GetRecords result ByteArrayInputStream bis = new ByteArrayInputStream( bos.toByteArray() ); XSLTDocument xslSheet = OUT_XSL.get( outputSchema ); XMLFragment resultDocument = xslSheet.transform( bis, null, null, params ); GetRecordsResultDocument cswResponseDocument = new GetRecordsResultDocument(); cswResponseDocument.setRootElement( resultDocument.getRootElement() ); cswResponse = cswResponseDocument.parseGetRecordsResponse( getRecords ); } catch ( Exception e ) { String msg = "Can't transform WFS response (FeatureCollection) to CSW response: " + e.getMessage(); LOG.logError( msg, e ); throw new OGCWebServiceException( msg ); } LOG.exiting(); return cswResponse; } /** * Returns the number of records matching a GetRecords request. * * @param getRecords * @return the number of records matching a GetRecords request * @throws OGCWebServiceException */ private int determineRecordsMatched( GetRecords getRecords ) throws OGCWebServiceException { getRecords.setResultType( GetRecords.RESULT_TYPE.HITS ); GetFeature getFeature = null; XMLFragment getFeatureDocument = null; Object wfsResponse = null; String outputSchema = normalizeOutputSchema( getRecords.getOutputSchema() ); XMLFragment getRecordsDocument = new XMLFragment( XMLFactory.export( getRecords ).getRootElement() ); try { XSLTDocument xslSheet = IN_XSL.get( outputSchema ); getFeatureDocument = xslSheet.transform( getRecordsDocument ); LOG.logDebug( "Generated WFS GetFeature request (HITS):\n" + getFeatureDocument ); } catch ( TransformerException e ) { e.printStackTrace(); String msg = "Can't transform GetRecord request to WFS GetFeature request: " + e.getMessage(); LOG.logError( msg, e ); throw new OGCWebServiceException( msg ); } try { getFeature = GetFeature.create( getRecords.getId(), getFeatureDocument.getRootElement() ); } catch ( Exception e ) { String msg = "Cannot generate object representation for GetFeature request: " + e.getMessage(); LOG.logError( msg, e ); throw new OGCWebServiceException( msg ); } try { wfsResponse = wfsResource.doService( getFeature ); } catch ( OGCWebServiceException e ) { String msg = "Generated WFS GetFeature request failed: " + e.getMessage(); LOG.logError( msg, e ); throw new OGCWebServiceException( msg ); } if ( !( wfsResponse instanceof FeatureResult ) ) { String msg = "Unexpected result type '" + wfsResponse.getClass().getName() + "' from WFS (must be FeatureResult)." + " Maybe a FeatureType is not correctly registered!?"; LOG.logError( msg ); throw new OGCWebServiceException( msg ); } FeatureResult featureResult = (FeatureResult) wfsResponse; if ( !( featureResult.getResponse() instanceof FeatureCollection ) ) { String msg = "Unexpected reponse type: '" + featureResult.getResponse().getClass().getName() + " " + featureResult.getResponse().getClass() + "' in FeatureResult of WFS (must be a FeatureCollection)."; LOG.logError( msg ); throw new OGCWebServiceException( msg ); } FeatureCollection featureCollection = (FeatureCollection) featureResult.getResponse(); return Integer.parseInt( featureCollection.getAttribute( "numberOfFeatures" ) ); } /** * Performs a <code>GetRecordById</code> request. * <p> * This involves the following steps: * <ul> * <li><code>GetRecordById</code>-><code>GetRecordByIdDocument</code></li> * <li><code>GetRecordByIdDocument</code>-><code>GetFeatureDocument</code> using XSLT</li> * <li><code>GetFeatureDocument</code>-><code>GetFeature</code></li> * <li><code>GetFeature</code> request is performed against the underlying WFS</li> * <li>WFS answers with a <code>FeatureResult</code> object (which contains a * <code>FeatureCollection</code>)</li> * <li><code>FeatureCollection</code>-> GMLFeatureCollectionDocument (as a String)</li> * <li>GMLFeatureCollectionDocument</code>-><code>GetRecordsResultDocument</code> using * XSLT</li> * <li><code>GetRecordsResultDocument</code>-><code>GetRecordsResult</code></li> * </ul> * </p> * @param getRecordById * @return * @throws OGCWebServiceException */ public GetRecordByIdResult query( GetRecordById getRecordById ) throws OGCWebServiceException { GetFeature getFeature = null; XMLFragment getFeatureDocument = null; Object wfsResponse = null; GetRecordByIdResult cswResponse = null; String outputSchema = cswConfiguration.getDeegreeParams().getDefaultOutputSchema(); XMLFragment getRecordsDocument = new XMLFragment( XMLFactory.export( getRecordById ).getRootElement() ); try { XSLTDocument xslSheet = IN_XSL.get( outputSchema.toUpperCase() ); getFeatureDocument = xslSheet.transform( getRecordsDocument ); LOG.logDebug( "Generated WFS GetFeature request:\n" + getFeatureDocument ); } catch ( TransformerException e ) { String msg = "Can't transform GetRecordById request to WFS GetFeature request: " + e.getMessage(); LOG.logError( msg, e ); throw new OGCWebServiceException( msg ); } if ( LOG.getLevel() == ILogger.LOG_DEBUG ) { StringWriter sw = new StringWriter( 5000 ); getFeatureDocument.write( sw ); LOG.logDebug( sw.getBuffer().toString() ); } try { getFeature = GetFeature.create( getRecordById.getId(), getFeatureDocument.getRootElement() ); } catch ( Exception e ) { String msg = "Cannot generate object representation for GetFeature request: " + e.getMessage(); LOG.logError( msg, e ); throw new OGCWebServiceException( msg ); } try { wfsResponse = wfsResource.doService( getFeature ); } catch ( OGCWebServiceException e ) { String msg = "Generated WFS GetFeature request failed: " + e.getMessage(); LOG.logError( msg, e ); throw new OGCWebServiceException( msg ); } if ( !( wfsResponse instanceof FeatureResult ) ) { String msg = "Unexpected result type '" + wfsResponse.getClass().getName() + "' from WFS (must be FeatureResult)." + " Maybe a FeatureType is not correctly registered!?"; LOG.logError( msg ); throw new OGCWebServiceException( msg ); } FeatureResult featureResult = (FeatureResult) wfsResponse; if ( !( featureResult.getResponse() instanceof FeatureCollection ) ) { String msg = "Unexpected reponse type: '" + featureResult.getResponse().getClass().getName() + " " + featureResult.getResponse().getClass() + "' in FeatureResult of WFS (must be a FeatureCollection)."; LOG.logError( msg ); throw new OGCWebServiceException( msg ); } FeatureCollection featureCollection = (FeatureCollection) featureResult.getResponse(); try { int numberOfMatchedRecords = featureCollection == null ? 0 : featureCollection.size(); int startPosition = 1; long maxRecords = Integer.MAX_VALUE; long numberOfRecordsReturned = startPosition + maxRecords < numberOfMatchedRecords ? maxRecords : numberOfMatchedRecords - startPosition + 1; long nextRecord = numberOfRecordsReturned + startPosition > numberOfMatchedRecords ? 0 : numberOfRecordsReturned + startPosition; HashMap<String, String> params = new HashMap<String, String>(); params.put( "REQUEST_ID", getRecordById.getId() ); if ( numberOfRecordsReturned != 0 ) { params.put( "SEARCH_STATUS", "complete" ); } else { params.put( "SEARCH_STATUS", "none" ); } params.put( "TIMESTAMP", TimeTools.getISOFormattedTime() ); String s = OGCServletController.address + "?service=CSW&version=2.0.0&request=DescribeRecord"; params.put( "RECORD_SCHEMA", s ); params.put( "RECORDS_MATCHED", "" + numberOfMatchedRecords ); params.put( "RECORDS_RETURNED", "" + numberOfRecordsReturned ); params.put( "NEXT_RECORD", "" + nextRecord ); params.put( "ELEMENT_SET", "full" ); params.put( "REQUEST_NAME", "GetRecordById" ); featureCollection.setAttribute( "byID", "true" ); ByteArrayOutputStream bos = new ByteArrayOutputStream( 50000 ); GMLFeatureAdapter ada = new GMLFeatureAdapter( true ); ada.export( featureCollection, bos ); if ( LOG.getLevel() == ILogger.LOG_DEBUG ) { LOG.logDebug( new String( bos.toByteArray() ) ); } ByteArrayInputStream bis = new ByteArrayInputStream( bos.toByteArray() ); XSLTDocument xslSheet = OUT_XSL.get( outputSchema.toUpperCase() ); XMLFragment resultDocument = xslSheet.transform( bis, null, null, params ); GetRecordByIdResultDocument cswResponseDocument = new GetRecordByIdResultDocument(); cswResponseDocument.setRootElement( resultDocument.getRootElement() ); cswResponse = cswResponseDocument.parseGetRecordByIdResponse( getRecordById ); } catch ( Exception e ) { e.printStackTrace(); String msg = "Can't transform WFS response (FeatureCollection) " + "to CSW response: " + e.getMessage(); LOG.logError( msg, e ); throw new OGCWebServiceException( msg ); } return cswResponse; } } /* ******************************************************************** Changes to this class. What the people have been up to: $Log: Discovery.java,v $ Revision 1.85 2006/10/18 17:00:55 poth made DefaultOGCWebServiceResponse base type for all webservice responses Revision 1.84 2006/10/17 20:31:20 poth *** empty log message *** Revision 1.83 2006/10/10 15:53:26 mschneider Improved debug output. Revision 1.82 2006/10/09 20:03:53 poth bug fixes Revision 1.81 2006/08/02 14:17:13 poth comments added Revision 1.80 2006/07/11 06:39:05 poth code formatting Revision 1.79 2006/07/10 20:56:37 mschneider Added XSLT parameter RESULT_TYPE. Revision 1.78 2006/07/09 20:53:08 mschneider Improved type handling. Added generics. Revision 1.77 2006/06/29 12:00:11 poth caused by some ambigous parts of the CSW spec resultType in GetRecords requests now wil be treated not case-sensitive Revision 1.76 2006/06/29 10:27:17 mschneider Changed resultType of GetRecords to enum. Revision 1.75 2006/06/21 17:11:24 mschneider Added handling for null ELEMENT_SET parameter. Revision 1.74 2006/05/20 15:57:34 poth code formating Revision 1.73 2006/04/26 15:09:37 poth *** empty log message *** Revision 1.72 2006/04/18 18:22:55 poth *** empty log message *** Revision 1.71 2006/04/15 15:30:20 poth *** empty log message *** Revision 1.70 2006/04/06 20:25:25 poth *** empty log message *** Revision 1.69 2006/04/04 20:39:41 poth *** empty log message *** Revision 1.68 2006/03/30 21:20:25 poth *** empty log message *** Revision 1.67 2006/03/30 17:26:49 poth *** empty log message *** Revision 1.66 2006/03/29 20:32:31 poth *** empty log message *** Revision 1.65 2006/03/21 13:23:56 poth *** empty log message *** Revision 1.64 2006/03/20 12:17:50 poth *** empty log message *** Revision 1.63 2006/03/17 15:21:48 poth *** empty log message *** Revision 1.62 2006/03/17 14:55:31 poth *** empty log message *** Revision 1.61 2006/03/17 07:56:21 poth *** empty log message *** Revision 1.60 2006/03/16 17:02:11 poth *** empty log message *** Revision 1.59 2006/03/16 16:47:45 poth *** empty log message *** Revision 1.58 2006/03/13 10:39:08 poth *** empty log message *** Revision 1.57 2006/03/01 14:11:04 poth *** empty log message *** Revision 1.56 2006/02/26 21:30:42 poth *** empty log message *** Revision 1.55 2006/02/23 11:46:13 mays bugfix -> using OutputStream instead of PrintWriter for exporting FeatureCollection Revision 1.54 2006/02/20 12:40:02 poth *** empty log message *** ********************************************************************** */