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