001 //$HeadURL: svn+ssh://rbezema@svn.wald.intevation.org/deegree/base/branches/2.2_testing/src/org/deegree/ogcwebservices/csw/CatalogueService.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 Aennchenstr. 19 030 53115 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 ---------------------------------------------------------------------------*/ 044 045 package org.deegree.ogcwebservices.csw; 046 047 import java.net.URL; 048 import java.util.HashMap; 049 import java.util.Map; 050 import java.util.Stack; 051 052 import org.deegree.framework.log.ILogger; 053 import org.deegree.framework.log.LoggerFactory; 054 import org.deegree.framework.trigger.TriggerProvider; 055 import org.deegree.i18n.Messages; 056 import org.deegree.ogcwebservices.MissingParameterValueException; 057 import org.deegree.ogcwebservices.OGCWebService; 058 import org.deegree.ogcwebservices.OGCWebServiceException; 059 import org.deegree.ogcwebservices.OGCWebServiceRequest; 060 import org.deegree.ogcwebservices.csw.capabilities.CatalogueGetCapabilities; 061 import org.deegree.ogcwebservices.csw.capabilities.CatalogueOperationsMetadata; 062 import org.deegree.ogcwebservices.csw.configuration.CatalogueConfiguration; 063 import org.deegree.ogcwebservices.csw.configuration.CatalogueConfigurationDocument; 064 import org.deegree.ogcwebservices.csw.discovery.DescribeRecord; 065 import org.deegree.ogcwebservices.csw.discovery.Discovery; 066 import org.deegree.ogcwebservices.csw.discovery.GetDomain; 067 import org.deegree.ogcwebservices.csw.discovery.GetRecordById; 068 import org.deegree.ogcwebservices.csw.discovery.GetRecords; 069 import org.deegree.ogcwebservices.csw.manager.Harvest; 070 import org.deegree.ogcwebservices.csw.manager.Manager; 071 import org.deegree.ogcwebservices.csw.manager.Transaction; 072 import org.deegree.ogcwebservices.getcapabilities.OGCCapabilities; 073 import org.deegree.ogcwebservices.wfs.RemoteWFService; 074 import org.deegree.ogcwebservices.wfs.WFService; 075 import org.deegree.ogcwebservices.wfs.WFServiceFactory; 076 import org.deegree.ogcwebservices.wfs.XMLFactory; 077 import org.deegree.ogcwebservices.wfs.capabilities.WFSCapabilities; 078 import org.deegree.ogcwebservices.wfs.capabilities.WFSCapabilitiesDocument; 079 import org.deegree.ogcwebservices.wfs.configuration.WFSConfiguration; 080 import org.deegree.ogcwebservices.wfs.configuration.WFSConfigurationDocument; 081 082 /** 083 * The Catalogue Service class provides the foundation for an OGC catalogue service. The Catalogue 084 * Service class directly includes only the serviceTypeID attribute. In most cases, this attribute 085 * will not be directly visible to catalogue clients. 086 * <p> 087 * The catalog service is an implementation of the OpenGIS Catalogue Service Specification 2.0. 088 * </p> 089 * 090 * @author <a href="mailto:tfr@users.sourceforge.net">Torsten Friebe </a> 091 * @author <a href="mailto:mschneider@lat-lon.de">Markus Schneider </a> 092 * 093 * @author last edited by: $Author: apoth $ 094 * 095 * @version $Revision: 9384 $, $Date: 2008-01-03 14:30:39 +0100 (Do, 03 Jan 2008) $ 096 * @see <a href="http://www.opengis.org/specs/">OGC Specification </a> 097 */ 098 099 public class CatalogueService implements OGCWebService { 100 101 private static final ILogger LOG = LoggerFactory.getLogger( CatalogueService.class ); 102 103 private static final TriggerProvider TP = TriggerProvider.create( CatalogueService.class ); 104 105 private Discovery discovery; 106 107 private WFService wfsService; 108 109 private CatalogueConfiguration serviceConfiguration; 110 111 private static Map<URL, OGCWebService> wfsMap = new HashMap<URL, OGCWebService>(); 112 113 private static Stack<Manager> managerPool = new Stack<Manager>(); 114 115 /** 116 * Creates a new <code>CatalogService</code> instance. 117 * 118 * @param config 119 * 120 * @return new <code>CatalogService</code> instance. 121 * @throws OGCWebServiceException 122 */ 123 public static final CatalogueService create( CatalogueConfiguration config ) 124 throws OGCWebServiceException { 125 // get WFS: local or remote 126 OGCWebService wfsResource = null; 127 try { 128 CatalogueConfigurationDocument document = new CatalogueConfigurationDocument(); 129 document.setSystemId( config.getSystemId() ); 130 131 URL wfsCapabilitiesFileURL = document.resolve( config.getDeegreeParams().getWfsResource().getHref().toString() ); 132 if ( wfsMap.get( wfsCapabilitiesFileURL ) == null ) { 133 if ( wfsCapabilitiesFileURL.getProtocol().equals( "http" ) ) { 134 WFSCapabilitiesDocument capaDoc = new WFSCapabilitiesDocument(); 135 capaDoc.load( wfsCapabilitiesFileURL ); 136 WFSCapabilities capabilities = (WFSCapabilities) capaDoc.parseCapabilities(); 137 LOG.logInfo( "Creating remote WFS with capabilities file " + wfsCapabilitiesFileURL ); 138 wfsResource = new RemoteWFService( capabilities ); 139 } else { 140 WFSConfigurationDocument capaDoc = new WFSConfigurationDocument(); 141 capaDoc.load( wfsCapabilitiesFileURL ); 142 WFSConfiguration conf = capaDoc.getConfiguration(); 143 LOG.logInfo( "CS-W service: Creating local WFS with capabilities file " + wfsCapabilitiesFileURL ); 144 wfsResource = WFServiceFactory.createInstance( conf ); 145 if ( LOG.getLevel() == ILogger.LOG_DEBUG ) { 146 LOG.logDebug( "CS-W service: The localwfs was has been successfully created, it's capabilties are: " 147 + XMLFactory.export( (WFSCapabilities) wfsResource.getCapabilities() ).getAsPrettyString() ); 148 } 149 } 150 wfsMap.put( wfsCapabilitiesFileURL, wfsResource ); 151 } else { 152 wfsResource = wfsMap.get( wfsCapabilitiesFileURL ); 153 } 154 } catch ( Exception e ) { 155 LOG.logError( "Error creating WFS for CSW", e ); 156 String msg = Messages.get( "CSW_ERROR_CREATING_WFS", e.getMessage() ); 157 throw new OGCWebServiceException( CatalogueService.class.getName(), msg ); 158 } 159 160 // initialize manager and discovery 161 return new CatalogueService( config, (WFService) wfsResource ); 162 } 163 164 /** 165 * 166 * @param config 167 * @param wfsService 168 */ 169 private CatalogueService( CatalogueConfiguration config, WFService wfsService ) { 170 this.serviceConfiguration = config; 171 this.wfsService = wfsService; 172 this.discovery = new Discovery( wfsService, config ); 173 } 174 175 /** 176 * Returns the OGC-capabilities of the service. 177 * 178 * @return the OGC-capabilities of the service. 179 * @todo analyze incoming request! return only requested sections 180 */ 181 public OGCCapabilities getCapabilities() { 182 return this.serviceConfiguration; 183 } 184 185 /** 186 * Returns the service type (CSW). 187 * 188 * @return the service type (CSW). 189 */ 190 public String getServiceTypeId() { 191 return this.serviceConfiguration.getServiceIdentification().getServiceType().getCode(); 192 } 193 194 /** 195 * @return Version 196 */ 197 public String getVersion() { 198 return this.serviceConfiguration.getVersion(); 199 } 200 201 /** 202 * Method for event based request processing. 203 * 204 * @param request 205 * request object containing the request 206 * @return an Object which may be one of the following 207 * <ul> 208 * <li>DescribeRecordResult</li> 209 * <li>GetRecordResult</li> 210 * <li>GetRecordByIdResult</li> 211 * <li>TransactionResult</li> 212 * <li>EchoRequest</li> 213 * <li>OGCCapabilities</li> 214 * @throws OGCWebServiceException 215 * 216 * @todo validation of requested version against accepted versions 217 * @todo return type 218 */ 219 public Object doService( OGCWebServiceRequest request ) 220 throws OGCWebServiceException { 221 222 request = (OGCWebServiceRequest) TP.doPreTrigger( this, request )[0]; 223 224 Object response = null; 225 226 if ( request instanceof DescribeRecord ) { 227 response = this.getDiscovery().describeRecordType( (DescribeRecord) request ); 228 } else if ( request instanceof GetDomain ) { 229 throw new OGCWebServiceException( getClass().getName(), Messages.get( "CSW_GETDOMAIN_NOT_IMPLEMENTED" ) ); 230 // TODO is not implemented 231 // response = this.getDiscovery().getDomain( (GetDomain) request ); 232 } else if ( request instanceof GetRecords ) { 233 response = this.getDiscovery().query( (GetRecords) request ); 234 } else if ( request instanceof GetRecordById ) { 235 response = this.getDiscovery().query( (GetRecordById) request ); 236 } else if ( request instanceof Transaction ) { 237 Manager manager = this.getManager( request.getVersion() ); 238 response = manager.transaction( (Transaction) request ); 239 managerPool.push( manager ); 240 } else if ( request instanceof Harvest ) { 241 Manager manager = this.getManager( request.getVersion() ); 242 response = manager.harvestRecords( (Harvest) request ); 243 managerPool.push( manager ); 244 } else if ( request instanceof CatalogueGetCapabilities ) { 245 LOG.logDebug( "GetCapabilities for version:" + request.getVersion(), request ); 246 response = this.getCapabilities(); 247 } else { 248 throw new OGCWebServiceException( Messages.get( "CSW_INVALID_REQUEST_TYPE", request.getClass().getName() ) ); 249 } 250 251 return TP.doPostTrigger( this, response )[0]; 252 } 253 254 /** 255 * @return Returns the discovery. 256 * 257 */ 258 public Discovery getDiscovery() { 259 return discovery; 260 } 261 262 /** 263 * @return the manager. 264 * @throws OGCWebServiceException 265 */ 266 public synchronized Manager getManager( String version ) 267 throws OGCWebServiceException { 268 CatalogueOperationsMetadata com = (CatalogueOperationsMetadata) serviceConfiguration.getOperationsMetadata(); 269 Manager manager = null; 270 if ( managerPool.size() == 0 ) { 271 if ( com.getHarvest() != null || com.getTransaction() != null ) { 272 try { 273 String className = CSWPropertiesAccess.getString( "Manager" + version ); 274 if ( className == null ) { 275 String msg = Messages.get( "CSW_UNSUPPORTED_VERSION", version ); 276 throw new OGCWebServiceException( getClass().getName(), msg ); 277 } 278 manager = (Manager) Class.forName( className ).newInstance(); 279 manager.init( wfsService, serviceConfiguration ); 280 managerPool.push( manager ); 281 } catch ( MissingParameterValueException e ) { 282 LOG.logError( e.getMessage(), e ); 283 throw new OGCWebServiceException( getClass().getName(), e.getMessage() ); 284 } catch ( InstantiationException e ) { 285 LOG.logError( e.getMessage(), e ); 286 throw new OGCWebServiceException( getClass().getName(), e.getMessage() ); 287 } catch ( IllegalAccessException e ) { 288 LOG.logError( e.getMessage(), e ); 289 throw new OGCWebServiceException( getClass().getName(), e.getMessage() ); 290 } catch ( ClassNotFoundException e ) { 291 LOG.logError( e.getMessage(), e ); 292 throw new OGCWebServiceException( getClass().getName(), e.getMessage() ); 293 } 294 } else { 295 String msg = Messages.get( "CSW_TRANSCATIONS_ARE_NOT_DEFINED" ); 296 throw new OGCWebServiceException( getClass().getName(), msg ); 297 } 298 } else { 299 manager = managerPool.pop(); 300 } 301 return manager; 302 } 303 304 }