001 //$HeadURL: https://svn.wald.intevation.org/svn/deegree/base/branches/2.3_testing/src/org/deegree/enterprise/servlet/CSWHandler.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.enterprise.servlet;
037
038 import java.io.IOException;
039 import java.io.OutputStream;
040 import java.io.PrintWriter;
041 import java.lang.reflect.Method;
042
043 import javax.servlet.http.HttpServletResponse;
044 import javax.xml.transform.TransformerException;
045
046 import org.deegree.enterprise.ServiceException;
047 import org.deegree.framework.log.ILogger;
048 import org.deegree.framework.log.LoggerFactory;
049 import org.deegree.framework.util.CharsetUtils;
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.ogcbase.CommonNamespaces;
054 import org.deegree.ogcbase.ExceptionCode;
055 import org.deegree.ogcwebservices.EchoRequest;
056 import org.deegree.ogcwebservices.InvalidParameterValueException;
057 import org.deegree.ogcwebservices.OGCWebServiceException;
058 import org.deegree.ogcwebservices.OGCWebServiceRequest;
059 import org.deegree.ogcwebservices.csw.CSWExceptionCode;
060 import org.deegree.ogcwebservices.csw.CSWFactory;
061 import org.deegree.ogcwebservices.csw.CSWPropertiesAccess;
062 import org.deegree.ogcwebservices.csw.CatalogueService;
063 import org.deegree.ogcwebservices.csw.capabilities.CatalogueCapabilities;
064 import org.deegree.ogcwebservices.csw.capabilities.CatalogueGetCapabilities;
065 import org.deegree.ogcwebservices.csw.discovery.DescribeRecordResult;
066 import org.deegree.ogcwebservices.csw.discovery.GetRecordByIdResult;
067 import org.deegree.ogcwebservices.csw.discovery.GetRecordsResult;
068 import org.deegree.ogcwebservices.csw.discovery.GetRepositoryItem;
069 import org.deegree.ogcwebservices.csw.discovery.GetRepositoryItemResponse;
070 import org.deegree.ogcwebservices.csw.manager.HarvestResult;
071 import org.deegree.ogcwebservices.csw.manager.TransactionResult;
072 import org.w3c.dom.Document;
073 import org.w3c.dom.Element;
074
075 /**
076 * Web servlet client for CSW.
077 *
078 * @author <a href="mailto:tfr@users.sourceforge.net">Torsten Friebe </A>
079 * @author last edited by: $Author: mschneider $
080 *
081 * @version $Revision: 18195 $, $Date: 2009-06-18 17:55:39 +0200 (Do, 18. Jun 2009) $
082 *
083 * @see <a href="http://www.dofactory.com/patterns/PatternChain.aspx">Chain of Responsibility Design Pattern </a>
084 */
085
086 public class CSWHandler extends AbstractOWServiceHandler {
087
088 private static final ILogger LOG = LoggerFactory.getLogger( CSWHandler.class );
089
090 /**
091 * @param request
092 * @param httpResponse
093 * @throws ServiceException
094 * @throws OGCWebServiceException
095 * @see "org.deegree.enterprise.servlet.ServiceDispatcher#perform(org.deegree.services.AbstractOGCWebServiceRequest,javax.servlet.http.HttpServletResponse)"
096 */
097 public void perform( OGCWebServiceRequest request, HttpServletResponse httpResponse )
098 throws ServiceException, OGCWebServiceException {
099
100 LOG.logDebug( "Performing request: " + request.toString() );
101
102 try {
103 CatalogueService service = CSWFactory.getService();
104 Object response = service.doService( request );
105 if ( response instanceof OGCWebServiceException ) {
106 if ( request instanceof GetRepositoryItem ) {
107 sendOWSException( httpResponse, (OGCWebServiceException) response );
108 } else {
109 sendExceptionReport( httpResponse, (OGCWebServiceException) response );
110 }
111 } else if ( response instanceof Exception ) {
112 sendExceptionReport( httpResponse, (Exception) response );
113 } else if ( response instanceof CatalogueCapabilities ) {
114 sendCapabilities( httpResponse, (CatalogueGetCapabilities) request, (CatalogueCapabilities) response );
115 } else if ( response instanceof GetRecordsResult ) {
116 sendGetRecord( httpResponse, (GetRecordsResult) response );
117 } else if ( response instanceof GetRecordByIdResult ) {
118 sendGetRecordById( httpResponse, (GetRecordByIdResult) response );
119 } else if ( response instanceof DescribeRecordResult ) {
120 sendDescribeRecord( httpResponse, (DescribeRecordResult) response );
121 } else if ( response instanceof TransactionResult ) {
122 sendTransactionResult( httpResponse, (TransactionResult) response );
123 } else if ( response instanceof HarvestResult ) {
124 sendHarvestResult( httpResponse, (HarvestResult) response );
125 } else if ( response instanceof EchoRequest ) {
126 sendHarvestResult( httpResponse );
127 } else if ( response instanceof GetRepositoryItemResponse ) {
128 sendGetRepositoryItem( httpResponse, (GetRepositoryItemResponse) response );
129 } else {
130 OGCWebServiceException e = new OGCWebServiceException(
131 this.getClass().getName(),
132 "Unknown response class: "
133 + ( response == null ? "null response object"
134 : response.getClass().getName() )
135 + "." );
136 sendExceptionReport( httpResponse, e );
137 }
138 } catch ( IOException ex ) {
139 throw new ServiceException( "Error while sending response: " + ex.getMessage(), ex );
140 } catch ( OGCWebServiceException ogc ) {
141 if ( request instanceof GetRepositoryItem ) {
142 sendOWSException( httpResponse, ogc );
143 } else {
144 sendExceptionReport( httpResponse, ogc );
145 }
146 }
147
148 }
149
150 /**
151 * @param httpResponse
152 * @param response
153 * @throws IOException
154 * @throws ServiceException
155 */
156 private void sendGetRepositoryItem( HttpServletResponse httpResponse, GetRepositoryItemResponse response )
157 throws IOException, ServiceException {
158 httpResponse.setContentType( "text/xml; charset=" + CharsetUtils.getSystemCharset() );
159 PrintWriter pw = httpResponse.getWriter();
160 try {
161 response.getRepositoryItem().prettyPrint( pw );
162 pw.flush();
163 } catch ( TransformerException e ) {
164 LOG.logError( e.getLocalizedMessage(), e );
165 throw new ServiceException( e.getLocalizedMessage(), e );
166 }
167 }
168
169 /**
170 * Sends the passed <tt>OGCWebServiceException</tt> to the calling client and flushes/closes the writer.
171 *
172 * @param responseWriter
173 * to write the message of the exception to
174 * @param e
175 * the exception to 'send' e.g. write to the stream.
176 * @throws ServiceException
177 * if a writer could not be created from the response.
178 */
179 private void sendOWSException( HttpServletResponse httpResponse, OGCWebServiceException e )
180 throws ServiceException {
181
182 if ( LOG.getLevel() == ILogger.LOG_DEBUG ) {
183 Thread.dumpStack();
184 }
185 httpResponse.setContentType( "application/xml" );
186 LOG.logDebug( "Sending OGCWebServiceException to client with message: " + e.getMessage() );
187 Document doc = XMLTools.create();
188
189 XMLFragment frag = new XMLFragment( doc.createElementNS( CommonNamespaces.OWSNS.toString(),
190 "ows:ExceptionReport" ) );
191 Element message = null;
192 ExceptionCode code = e.getCode();
193 if ( code == null ) {
194 code = CSWExceptionCode.WRS_INVALIDREQUEST;
195 }
196 if ( code == CSWExceptionCode.WRS_INVALIDREQUEST ) {
197 message = XMLTools.appendElement( frag.getRootElement(), CommonNamespaces.WRS_EBRIMNS, code.value );
198 } else {
199 message = XMLTools.appendElement( frag.getRootElement(), CommonNamespaces.WRS_EBRIMNS,
200 CSWExceptionCode.WRS_NOTFOUND.value );
201 }
202 XMLTools.setNodeValue( message, e.getMessage() );
203
204 try {
205 PrintWriter writer = httpResponse.getWriter();
206 writer.write( frag.getAsPrettyString() );
207 writer.flush();
208 } catch ( IOException e1 ) {
209 throw new ServiceException( e1 );
210 }
211
212 // writer.close();
213
214 }
215
216 /**
217 * Sends the passed <tt>HarvestResult</tt> to the http client.
218 *
219 * @param httpResponse
220 * http connection to the client
221 * @param result
222 * object to send
223 * @throws IOException
224 */
225 private void sendHarvestResult( HttpServletResponse httpResponse, HarvestResult result )
226 throws IOException {
227 XMLFragment doc = null;
228 try {
229 doc = org.deegree.ogcwebservices.csw.manager.XMLFactory.export( result );
230 } catch ( XMLParsingException e ) {
231 throw new IOException( "could not export TransactionResult as XML: " + e.getMessage() );
232 }
233 httpResponse.setContentType( "text/xml; charset=" + CharsetUtils.getSystemCharset() );
234 OutputStream os = httpResponse.getOutputStream();
235 doc.write( os );
236 os.close();
237 }
238
239 /**
240 *
241 * @param httpResponse
242 * @throws IOException
243 */
244 private void sendHarvestResult( HttpServletResponse httpResponse )
245 throws IOException {
246
247 httpResponse.setContentType( "text/xml; charset=" + CharsetUtils.getSystemCharset() );
248 PrintWriter pw = httpResponse.getWriter();
249 pw.write( "<HarvestResponse>Harvest request has been received " );
250 pw.write( "and will be performed</HarvestResponse>" );
251 pw.close();
252 }
253
254 /**
255 * Sends the passed <tt>TransactionResult</tt> to the http client.
256 *
257 * @param httpResponse
258 * http connection to the client
259 * @param result
260 * object to send
261 */
262 private void sendTransactionResult( HttpServletResponse httpResponse, TransactionResult result )
263 throws IOException {
264 XMLFragment doc = null;
265 try {
266 doc = org.deegree.ogcwebservices.csw.manager.XMLFactory.export( result );
267 } catch ( XMLParsingException e ) {
268 throw new IOException( "could not export TransactionResult as XML: " + e.getMessage() );
269 }
270 httpResponse.setContentType( "text/xml; charset=" + CharsetUtils.getSystemCharset() );
271 OutputStream os = httpResponse.getOutputStream();
272 doc.write( os );
273 os.close();
274 }
275
276 /**
277 * Sends the passed <tt>CatalogCapabilities</tt> to the http client.
278 *
279 * @param response
280 * http connection to the client
281 * @param capabilities
282 * object to send
283 */
284 private void sendCapabilities( HttpServletResponse response, CatalogueGetCapabilities getCapabilities,
285 CatalogueCapabilities capabilities )
286 throws IOException {
287
288 boolean xmlOk = false;
289 String[] formats = getCapabilities.getAcceptFormats();
290 if ( formats == null || formats.length == 0 ) {
291 xmlOk = true;
292 } else {
293 for ( int i = 0; i < formats.length; i++ ) {
294 if ( formats[i].equals( "text/xml" ) ) {
295 xmlOk = true;
296 break;
297 }
298 }
299 }
300 if ( !xmlOk ) {
301 ExceptionCode code = ExceptionCode.INVALIDPARAMETERVALUE;
302 InvalidParameterValueException e = new InvalidParameterValueException( this.getClass().getName(),
303 "OutputFormat must be 'text/xml'.",
304 code );
305 sendExceptionReport( response, e );
306 } else {
307 String version = getCapabilities.getVersion();
308 String className = CSWPropertiesAccess.getString( "XMLFactory" + version );
309 XMLFragment doc = null;
310 try {
311 Class<?> clzz = Class.forName( className );
312 Class<?>[] parameterTypes = new Class<?>[] { CatalogueCapabilities.class, String[].class };
313 Object[] parameters = new Object[] { capabilities, getCapabilities.getSections() };
314 Method method = clzz.getMethod( "export", parameterTypes );
315 doc = (XMLFragment) method.invoke( null, parameters );
316 } catch ( Exception e ) {
317 e.printStackTrace();
318 }
319
320 response.setContentType( "text/xml; charset=" + CharsetUtils.getSystemCharset() );
321 OutputStream os = response.getOutputStream();
322 doc.write( os );
323 os.close();
324 }
325 }
326
327 /**
328 *
329 * @param response
330 * @param getRecordResponse
331 * @throws IOException
332 */
333 private void sendGetRecord( HttpServletResponse response, GetRecordsResult getRecordResponse )
334 throws IOException {
335 XMLFragment doc = org.deegree.ogcwebservices.csw.discovery.XMLFactory.export( getRecordResponse );
336 if ( LOG.isDebug() ) {
337 LOG.logDebug( "GetRecord response", doc.getAsPrettyString() );
338 }
339 response.setContentType( "text/xml; charset=" + CharsetUtils.getSystemCharset() );
340 OutputStream os = response.getOutputStream();
341 doc.write( os );
342 os.close();
343 }
344
345 /**
346 *
347 * @param response
348 * @param getRecordByIdResponse
349 * @throws IOException
350 */
351 private void sendGetRecordById( HttpServletResponse response, GetRecordByIdResult getRecordByIdResponse )
352 throws IOException {
353 XMLFragment doc = org.deegree.ogcwebservices.csw.discovery.XMLFactory.export( getRecordByIdResponse );
354 if ( LOG.isDebug() ) {
355 LOG.logDebug( "GetRecordById response", doc.getAsPrettyString() );
356 }
357 response.setContentType( "text/xml" );
358 OutputStream os = response.getOutputStream();
359 doc.write( os );
360 os.close();
361 }
362
363 /**
364 *
365 * @param response
366 * @param describeRecordResponse
367 * @throws IOException
368 */
369 private void sendDescribeRecord( HttpServletResponse response, DescribeRecordResult describeRecordResponse )
370 throws IOException {
371 XMLFragment doc = org.deegree.ogcwebservices.csw.discovery.XMLFactory.export( describeRecordResponse );
372 if ( LOG.isDebug() ) {
373 LOG.logDebug( "DescribeRecord response", doc.getAsPrettyString() );
374 }
375 response.setContentType( "text/xml; charset=" + CharsetUtils.getSystemCharset() );
376 OutputStream os = response.getOutputStream();
377 doc.write( os );
378 os.close();
379 }
380 }