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 }