001 //$HeadURL: http://svn.wald.intevation.org/svn/deegree/base/trunk/src/org/deegree/enterprise/servlet/OGCServletController.java $ 002 // $Id: OGCServletController.java 29966 2011-03-09 14:19:04Z apoth $ 003 /*---------------------------------------------------------------------------- 004 This file is part of deegree, http://deegree.org/ 005 Copyright (C) 2001-2009 by: 006 Department of Geography, University of Bonn 007 and 008 lat/lon GmbH 009 010 This library is free software; you can redistribute it and/or modify it under 011 the terms of the GNU Lesser General Public License as published by the Free 012 Software Foundation; either version 2.1 of the License, or (at your option) 013 any later version. 014 This library is distributed in the hope that it will be useful, but WITHOUT 015 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 016 FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more 017 details. 018 You should have received a copy of the GNU Lesser General Public License 019 along with this library; if not, write to the Free Software Foundation, Inc., 020 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 021 022 Contact information: 023 024 lat/lon GmbH 025 Aennchenstr. 19, 53177 Bonn 026 Germany 027 http://lat-lon.de/ 028 029 Department of Geography, University of Bonn 030 Prof. Dr. Klaus Greve 031 Postfach 1147, 53001 Bonn 032 Germany 033 http://www.geographie.uni-bonn.de/deegree/ 034 035 e-mail: info@deegree.org 036 ----------------------------------------------------------------------------*/ 037 038 package org.deegree.enterprise.servlet; 039 040 import static java.lang.Character.isDigit; 041 import static java.lang.System.getProperty; 042 import static java.lang.System.setProperty; 043 import static org.deegree.enterprise.servlet.ServiceLookup.getInstance; 044 import static org.deegree.framework.log.LoggerFactory.getLogger; 045 import static org.deegree.framework.util.StringTools.arrayToString; 046 047 import java.beans.Introspector; 048 import java.io.IOException; 049 import java.io.OutputStream; 050 import java.io.PrintWriter; 051 import java.lang.reflect.InvocationTargetException; 052 import java.lang.reflect.Method; 053 import java.net.InetAddress; 054 import java.net.URL; 055 import java.nio.charset.Charset; 056 import java.sql.Driver; 057 import java.sql.DriverManager; 058 import java.sql.SQLException; 059 import java.text.MessageFormat; 060 import java.util.Enumeration; 061 import java.util.HashMap; 062 import java.util.Iterator; 063 import java.util.Map; 064 065 import javax.imageio.spi.IIORegistry; 066 import javax.servlet.ServletContext; 067 import javax.servlet.ServletException; 068 import javax.servlet.http.HttpServletRequest; 069 import javax.servlet.http.HttpServletResponse; 070 import javax.xml.parsers.DocumentBuilderFactory; 071 import javax.xml.transform.TransformerFactory; 072 073 import org.apache.commons.logging.LogFactory; 074 import org.apache.log4j.LogManager; 075 import org.deegree.crs.configuration.CRSConfiguration; 076 import org.deegree.enterprise.AbstractOGCServlet; 077 import org.deegree.enterprise.ServiceException; 078 import org.deegree.framework.log.ILogger; 079 import org.deegree.framework.util.CharsetUtils; 080 import org.deegree.framework.util.KVP2Map; 081 import org.deegree.framework.util.StringTools; 082 import org.deegree.framework.util.WebappResourceResolver; 083 import org.deegree.framework.version.Version; 084 import org.deegree.framework.xml.XMLFragment; 085 import org.deegree.ogcwebservices.ExceptionReport; 086 import org.deegree.ogcwebservices.OGCRequestFactory; 087 import org.deegree.ogcwebservices.OGCWebServiceException; 088 import org.deegree.ogcwebservices.OGCWebServiceRequest; 089 import org.deegree.ogcwebservices.wmps.configuration.WMPSConfigurationDocument; 090 import org.deegree.ogcwebservices.wms.configuration.WMSConfigurationDocument; 091 import org.deegree.ogcwebservices.wms.configuration.WMSConfigurationDocument_1_3_0; 092 import org.deegree.owscommon.XMLFactory; 093 import org.xml.sax.SAXException; 094 095 /** 096 * An <code>OGCServletController</code> handles all incoming requests. The controller for all OGC service requests. 097 * Dispatcher to specific handler for WMS, WFS and other. 098 * 099 * @author <a href="mailto:tfr@users.sourceforge.net">Torsten Friebe </a> 100 * @author last edited by: $Author: apoth $ 101 * 102 * @version $Revision: 29966 $, $Date: 22.04.2008 16:23:34$ 103 * @see <a href="http://java.sun.com/blueprints/corej2eepatterns/Patterns/FrontController.html">Front controller </a> 104 */ 105 public class OGCServletController extends AbstractOGCServlet { 106 107 /** 108 * address is the url of the client which requests. 109 */ 110 public static String address = null; 111 112 private static final long serialVersionUID = -4461759017823581221L; 113 114 private static ILogger LOG; 115 116 private static final String SERVICE = "services"; 117 118 private static final String HANDLER_CLASS = ".handler"; 119 120 private static final String HANDLER_CONF = ".config"; 121 122 private static final Map<Class<?>, String> SERVICE_FACTORIES_MAPPINGS = new HashMap<Class<?>, String>(); 123 124 private static final String ERR_MSG = "Can't set configuration for {0}"; 125 126 /** 127 * 128 * 129 * @param request 130 * @param response 131 * @TODO refactor and optimize code for initializing handler 132 */ 133 public void doService( HttpServletRequest request, HttpServletResponse response ) { 134 if ( response.isCommitted() ) { 135 LOG.logWarning( "The response object is already committed!" ); 136 } 137 138 long startTime = System.currentTimeMillis(); 139 address = request.getRequestURL().toString(); 140 141 String service = null; 142 try { 143 OGCWebServiceRequest ogcRequest = OGCRequestFactory.create( request ); 144 145 LOG.logInfo( StringTools.concat( 500, "Handling request '", ogcRequest.getId(), "' from '", 146 request.getRemoteAddr(), "' to service: '", ogcRequest.getServiceName(), 147 "'" ) ); 148 149 // get service from request 150 service = ogcRequest.getServiceName().toUpperCase(); 151 152 // get handler instance 153 ServiceDispatcher handler = ServiceLookup.getInstance().getHandler( service, request.getRemoteAddr() ); 154 // dispatch request to specific handler 155 handler.perform( ogcRequest, response ); 156 } catch ( OGCWebServiceException e ) { 157 LOG.logError( e.getMessage(), e ); 158 sendException( response, e, request, service ); 159 } catch ( ServiceException e ) { 160 if ( e.getNestedException() instanceof OGCWebServiceException ) { 161 sendException( response, (OGCWebServiceException) e.getNestedException(), request, service ); 162 } else { 163 sendException( response, new OGCWebServiceException( this.getClass().getName(), e.getMessage() ), 164 request, service ); 165 } 166 LOG.logError( e.getMessage(), e ); 167 } catch ( Exception e ) { 168 sendException( response, new OGCWebServiceException( this.getClass().getName(), e.getMessage() ), request, 169 service ); 170 LOG.logError( e.getMessage(), e ); 171 } 172 if ( LOG.isDebug() ) { 173 LOG.logDebug( "OGCServletController: request performed in " 174 + Long.toString( System.currentTimeMillis() - startTime ) + " milliseconds." ); 175 } 176 } 177 178 /** 179 * Sends the passed <code>OGCWebServiceException</code> to the calling client. 180 * 181 * @param response 182 * @param e 183 * @param request 184 * @param service 185 * the service name, if known 186 */ 187 private static void sendException( HttpServletResponse response, OGCWebServiceException e, 188 HttpServletRequest request, String service ) { 189 LOG.logInfo( "Sending OGCWebServiceException to client." ); 190 191 Map<?, ?> pmap = request.getParameterMap(); 192 Map<String, String> map = new HashMap<String, String>( pmap.size() ); 193 for ( Object o : pmap.keySet() ) { 194 String[] tmp = (String[]) pmap.get( o ); 195 for ( int i = 0; i < tmp.length; i++ ) { 196 tmp[i] = tmp[i].trim(); 197 } 198 map.put( ( (String) o ).toLowerCase(), arrayToString( tmp, ',' ) ); 199 } 200 201 boolean isWMS130 = false, isCSW = false, isWCTS = false, isWFS = false, isWFS100 = false; 202 203 if ( service == null ) { 204 service = map.get( "service" ); 205 } 206 207 String version = map.get( "version" ); 208 209 if ( service != null ) { 210 if ( "wms".equalsIgnoreCase( service ) ) { 211 isWMS130 = version != null && version.equals( "1.3.0" ); 212 } 213 if ( "wfs".equalsIgnoreCase( service ) ) { 214 isWFS = true; 215 isWFS100 = version != null && version.equals( "1.0.0" ); 216 } 217 218 isCSW = "csw".equalsIgnoreCase( service ); 219 isWCTS = "wcts".equalsIgnoreCase( service ); 220 isWFS = "wfs".equalsIgnoreCase( service ); 221 } else { 222 try { 223 XMLFragment doc = new XMLFragment( request.getReader(), XMLFragment.DEFAULT_URL ); 224 service = OGCRequestFactory.getTargetService( "", "", doc.getRootElement().getOwnerDocument() ); 225 isCSW = "csw".equalsIgnoreCase( service ); 226 isWCTS = "wcts".equalsIgnoreCase( service ); 227 isWFS = "wfs".equalsIgnoreCase( service ); 228 isWFS100 = isWFS && doc.getRootElement().getAttribute( "version" ) != null 229 && doc.getRootElement().getAttribute( "version" ).equals( "1.0.0" ); 230 } catch ( SAXException e1 ) { 231 // ignore 232 } catch ( IOException e1 ) { 233 // ignore 234 } catch ( IllegalStateException e1 ) { 235 // ignore, that happens in some tomcats 236 } 237 } 238 239 try { 240 XMLFragment doc; 241 String contentType = "text/xml"; 242 243 if ( !( isWMS130 || isCSW || isWCTS || isWFS ) ) { 244 // apply the simplest of heuristics... 245 String req = request.getRequestURI().toLowerCase(); 246 if ( req.indexOf( "csw" ) != -1 ) { 247 isCSW = true; 248 } else if ( req.indexOf( "wcts" ) != -1 ) { 249 isWCTS = true; 250 } else if ( req.indexOf( "wfs" ) != -1 ) { 251 isWFS = true; 252 } 253 254 if ( isWFS ) { 255 isWFS100 = req.indexOf( "1.0.0" ) != -1; 256 } 257 258 if ( !( isWMS130 || isCSW || isWCTS || isWFS || isWFS100 ) ) { 259 isWMS130 = version != null && version.equals( "1.3.0" ); 260 } 261 } 262 263 // send exception format INIMAGE etc. for WMS 264 if ( service != null && service.equalsIgnoreCase( "wms" ) ) { 265 ServiceDispatcher handler = getInstance().getHandler( service, request.getRemoteAddr() ); 266 if ( handler instanceof WMSHandler ) { 267 WMSHandler h = (WMSHandler) handler; 268 String format = map.get( "format" ); 269 String eFormat = map.get( "exceptions" ); 270 try { 271 h.determineExceptionFormat( eFormat, format, version, response ); 272 h.writeServiceExceptionReport( e ); 273 return; 274 } catch ( Exception ex ) { 275 LOG.logDebug( "Error while sending the exception in special format." 276 + " Continuing in default mode.", ex ); 277 } 278 } 279 } 280 281 if ( isWMS130 || "wcs".equalsIgnoreCase( e.getLocator() ) ) { 282 doc = XMLFactory.exportNS( new ExceptionReport( new OGCWebServiceException[] { e } ) ); 283 } else if ( isCSW ) { 284 doc = XMLFactory.exportExceptionReport( new ExceptionReport( new OGCWebServiceException[] { e } ) ); 285 } else if ( isWCTS ) { 286 doc = org.deegree.owscommon_1_1_0.XMLFactory.exportException( e ); 287 } else if ( isWFS100 ) { 288 doc = XMLFactory.exportExceptionReportWFS100( e ); 289 } else if ( isWFS ) { 290 doc = XMLFactory.exportExceptionReportWFS( e ); 291 } else { 292 contentType = "application/vnd.ogc.se_xml"; 293 doc = XMLFactory.export( new ExceptionReport( new OGCWebServiceException[] { e } ) ); 294 } 295 296 response.setContentType( contentType ); 297 OutputStream os = response.getOutputStream(); 298 doc.write( os ); 299 os.close(); 300 } catch ( Exception ex ) { 301 LOG.logError( "ERROR: " + ex.getMessage(), ex ); 302 } 303 } 304 305 /** 306 * 307 * @see javax.servlet.http.HttpServlet#doGet(javax.servlet.http.HttpServletRequest, 308 * javax.servlet.http.HttpServletResponse) 309 */ 310 @Override 311 protected void doGet( HttpServletRequest request, HttpServletResponse response ) 312 throws ServletException, IOException { 313 314 LOG.logDebug( "query string ", request.getQueryString() ); 315 if ( request.getParameter( "RELOADDEEGREE" ) != null ) { 316 reloadServices( request, response ); 317 } else { 318 this.doService( request, response ); 319 } 320 } 321 322 /** 323 * 324 * @param request 325 * @param response 326 * @throws ServletException 327 * @throws IOException 328 */ 329 private void reloadServices( HttpServletRequest request, HttpServletResponse response ) 330 throws ServletException, IOException { 331 Map<?, ?> map = KVP2Map.toMap( request ); 332 String user = (String) map.get( "USER" ); 333 String password = (String) map.get( "PASSWORD" ); 334 String message = null; 335 if ( getInitParameter( "USER" ) != null && getInitParameter( "PASSWORD" ) != null 336 && getInitParameter( "USER" ).equals( user ) && getInitParameter( "PASSWORD" ).equals( password ) ) { 337 initServices( getServletContext() ); 338 ctDestroyed(); 339 message = Messages.getString( "OGCServletController.reloadsuccess" ); 340 } else { 341 message = Messages.getString( "OGCServletController.reloadfailed" ); 342 } 343 PrintWriter pw = response.getWriter(); 344 pw.print( message ); 345 pw.flush(); 346 pw.close(); 347 } 348 349 /* 350 * (non-Javadoc) 351 * 352 * @see javax.servlet.http.HttpServlet#doPost(javax.servlet.http.HttpServletRequest, 353 * javax.servlet.http.HttpServletResponse) 354 */ 355 @Override 356 protected void doPost( HttpServletRequest request, HttpServletResponse response ) 357 throws ServletException, IOException { 358 this.doService( request, response ); 359 } 360 361 private static String spaces( int i ) { 362 if ( i <= 0 ) { 363 return ""; 364 } 365 366 StringBuffer sb = new StringBuffer( i ); 367 for ( int j = 0; j < i; ++j ) { 368 sb.append( " " ); 369 } 370 return sb.toString(); 371 } 372 373 private static void logIfThere( String param ) { 374 String val = getProperty( param ); 375 if ( val != null ) { 376 LOG.logInfo( "- " + param + spaces( 15 - param.length() ) + ": " + val ); 377 } 378 } 379 380 /** 381 * @see javax.servlet.GenericServlet#init() 382 */ 383 @Override 384 public void init() 385 throws ServletException { 386 387 synchronized ( OGCServletController.class ) { 388 if ( LOG == null ) { 389 // hack to figure out and set the context path name 390 // for a laugh, see http://marc.info/?l=tomcat-user&m=109215904113904&w=2 and the related thread 391 // http://marc.info/?t=109215871400004&r=1&w=2 392 String path = getServletContext().getRealPath( "" ); 393 String[] ps = path.split( "[/\\\\]" ); 394 path = ps[ps.length - 1]; 395 // heuristics are always a charm (and work best for tomcat in this case) 396 if ( isDigit( path.charAt( 0 ) ) && path.indexOf( "-" ) != -1 ) { 397 path = path.split( "-", 2 )[1]; 398 } 399 // note that setting this changes it on a JVM GLOBAL BASIS, so it WILL GET OVERWRITTEN in subsequent 400 // deegree startups! (However, since the log4j.properties will only be read on startup, this hack is 401 // useful anyway) 402 setProperty( "context.name", path ); 403 404 LOG = getLogger( OGCServletController.class ); 405 } 406 } 407 408 super.init(); 409 LOG.logDebug( "Logger for " + this.getClass().getName() + " initialized." ); 410 411 SERVICE_FACTORIES_MAPPINGS.put( CSWHandler.class, "org.deegree.ogcwebservices.csw.CSWFactory" ); 412 SERVICE_FACTORIES_MAPPINGS.put( WFSHandler.class, "org.deegree.ogcwebservices.wfs.WFServiceFactory" ); 413 SERVICE_FACTORIES_MAPPINGS.put( WCSHandler.class, "org.deegree.ogcwebservices.wcs.WCServiceFactory" ); 414 SERVICE_FACTORIES_MAPPINGS.put( WMSHandler.class, "org.deegree.ogcwebservices.wms.WMServiceFactory" ); 415 SERVICE_FACTORIES_MAPPINGS.put( WPVSHandler.class, "org.deegree.ogcwebservices.wpvs.WPVServiceFactory" ); 416 SERVICE_FACTORIES_MAPPINGS.put( WMPSHandler.class, "org.deegree.ogcwebservices.wmps.WMPServiceFactory" ); 417 SERVICE_FACTORIES_MAPPINGS.put( WPSHandler.class, "org.deegree.ogcwebservices.wps.WPServiceFactory" ); 418 SERVICE_FACTORIES_MAPPINGS.put( WASSHandler.class, "org.deegree.ogcwebservices.wass.common.WASServiceFactory" ); 419 SERVICE_FACTORIES_MAPPINGS.put( WCTSHandler.class, "org.deegree.ogcwebservices.wcts.WCTServiceFactory" ); 420 421 LOG.logInfo( "-------------------------------------------------------------------------------" ); 422 LOG.logInfo( "Starting deegree version " + Version.getVersion() ); 423 LOG.logInfo( "- context : " + this.getServletContext().getServletContextName() ); 424 LOG.logInfo( "- real path : " + this.getServletContext().getRealPath( "/" ) ); 425 LOG.logInfo( "- java version : " + System.getProperty( "java.version" ) + "" ); 426 LOG.logInfo( "- dom builder : " + DocumentBuilderFactory.newInstance().getClass().getName() + "" ); 427 LOG.logInfo( "- xslt builder : " + TransformerFactory.newInstance().getClass().getName() + "" ); 428 LOG.logInfo( "- system charset : " + CharsetUtils.getSystemCharset() ); 429 LOG.logInfo( "- default charset: " + Charset.defaultCharset() ); 430 LOG.logInfo( "- server info : " + this.getServletContext().getServerInfo() ); 431 logIfThere( "proxyHost" ); 432 logIfThere( "proxyPort" ); 433 logIfThere( "noProxyHosts" ); 434 logIfThere( "nonProxyHosts" ); 435 logIfThere( "http.proxyHost" ); 436 logIfThere( "http.proxyPort" ); 437 logIfThere( "http.noProxyHosts" ); 438 logIfThere( "http.nonProxyHosts" ); 439 logIfThere( "ftp.proxyHost" ); 440 logIfThere( "ftp.proxyPort" ); 441 logIfThere( "ftp.noProxyHosts" ); 442 logIfThere( "ftp.nonProxyHosts" ); 443 logIfThere( "https.proxyHost" ); 444 logIfThere( "https.proxyPort" ); 445 logIfThere( "https.noProxyHosts" ); 446 logIfThere( "https.nonProxyHosts" ); 447 try { 448 LOG.logInfo( "- ip : " + InetAddress.getLocalHost().getHostAddress() ); 449 LOG.logInfo( "- host name : " + InetAddress.getLocalHost().getHostName() ); 450 LOG.logInfo( "- domain name : " + InetAddress.getLocalHost().getCanonicalHostName() ); 451 } catch ( Exception e ) { 452 LOG.logError( e.getMessage(), e ); 453 } 454 LOG.logInfo( "-------------------------------------------------------------------------------" ); 455 this.initServices( getServletContext() ); 456 checkServerCompatibility(); 457 LOG.logInfo( "-------------------------------------------------------------------------------" ); 458 String tmpServiceList = this.getServiceList(); 459 if ( tmpServiceList != null && !( "".equals( tmpServiceList.trim() ) ) ) { 460 LOG.logInfo( "Initialized successfully (context '" + this.getServletContext().getServletContextName() 461 + "'):" ); 462 String[] tmpServices = tmpServiceList.split( "," ); 463 for ( String service : tmpServices ) { 464 // Added a check for the alternative service name, because it should not be outputed twice for the csw. 465 if ( !OGCRequestFactory.CSW_SERVICE_NAME_EBRIM.toUpperCase().equals( service ) ) { 466 LOG.logInfo( "- " + service ); 467 } 468 } 469 } else { 470 LOG.logError( "An Error occured while initializing context '" 471 + this.getServletContext().getServletContextName() + "', no services are available." ); 472 } 473 474 LOG.logInfo( "-------------------------------------------------------------------------------" ); 475 // Sets the attributes for tomcat -> application.getAttribute(); in jsp sites 476 this.getServletContext().setAttribute( "deegree_ogc_services", this.getServiceList() ); 477 } 478 479 private void checkServerCompatibility() { 480 String serverInfo = getServletContext().getServerInfo(); 481 if ( "Apache Tomcat/5.5.26".equals( serverInfo ) || "Apache Tomcat/6.0.16".equals( serverInfo ) ) { 482 LOG.logWarning( "*******************************************************************************" ); 483 LOG.logWarning( "YOU ARE RUNNING DEEGREE ON A TOMCAT RELEASE (" + serverInfo 484 + ") THAT IS KNOWN TO HAVE A SERIOUS ISSUE WITH LARGE POST REQUESTS." ); 485 LOG.logWarning( "PLEASE CONSIDER THE CORRESPONDING DEEGREE WIKI PAGE AT https://wiki.deegree.org/deegreeWiki/ApacheTomcat " 486 + "FOR DETAILS AND SWITCH TO A DIFFERENT TOMCAT VERSION." ); 487 LOG.logWarning( "*******************************************************************************" ); 488 } 489 } 490 491 private void initServices( ServletContext context ) 492 throws ServletException { 493 494 // get list of OGC services 495 String serviceList = this.getRequiredInitParameter( SERVICE ); 496 497 String[] serviceNames = StringTools.toArray( serviceList, ",", false ); 498 499 ServiceLookup lookup = ServiceLookup.getInstance(); 500 for ( int i = 0; i < serviceNames.length; i++ ) { 501 LOG.logInfo( StringTools.concat( 100, "---- Initializing ", serviceNames[i].toUpperCase(), " ----" ) ); 502 try { 503 String className = this.getRequiredInitParameter( serviceNames[i] + HANDLER_CLASS ); 504 Class<?> handlerClzz = Class.forName( className ); 505 506 // initialize each service factory 507 String s = this.getRequiredInitParameter( serviceNames[i] + HANDLER_CONF ); 508 URL serviceConfigurationURL = WebappResourceResolver.resolveFileLocation( s, context, LOG ); 509 510 // set configuration 511 LOG.logInfo( StringTools.concat( 300, "Reading configuration for ", serviceNames[i].toUpperCase(), 512 " from URL: '", serviceConfigurationURL, "'." ) ); 513 514 String factoryClassName = SERVICE_FACTORIES_MAPPINGS.get( handlerClzz ); 515 516 Class<?> factory = Class.forName( factoryClassName ); 517 Method method = factory.getMethod( "setConfiguration", new Class[] { URL.class } ); 518 method.invoke( factory, new Object[] { serviceConfigurationURL } ); 519 520 // The csw-ebrim profile adds an alternative service name, it too is registred with the CSW handler. 521 if ( "CSW".equals( serviceNames[i].toUpperCase() ) ) { 522 lookup.addService( OGCRequestFactory.CSW_SERVICE_NAME_EBRIM.toUpperCase(), handlerClzz ); 523 } 524 // put handler to available service list 525 lookup.addService( serviceNames[i].toUpperCase(), handlerClzz ); 526 527 LOG.logInfo( StringTools.concat( 300, serviceNames[i].toUpperCase(), " successfully initialized." ) ); 528 } catch ( ServletException e ) { 529 LOG.logError( e.getMessage(), e ); 530 } catch ( InvocationTargetException e ) { 531 e.getTargetException().printStackTrace(); 532 LOG.logError( this.produceMessage( ERR_MSG, new Object[] { serviceNames[i] } ), e ); 533 } catch ( Exception e ) { 534 LOG.logError( "Can't initialize OGC service:" + serviceNames[i], e ); 535 } 536 } 537 } 538 539 private String getRequiredInitParameter( String name ) 540 throws ServletException { 541 String paramValue = getInitParameter( name ); 542 if ( paramValue == null ) { 543 544 String msg = "Required init parameter '" + name + "' missing in web.xml"; 545 LOG.logError( msg ); 546 throw new ServletException( msg ); 547 } 548 return paramValue; 549 } 550 551 /** 552 * @return the services, separated by "," 553 */ 554 private String getServiceList() { 555 556 StringBuffer buf = new StringBuffer(); 557 ServiceLookup lookup = ServiceLookup.getInstance(); 558 for ( Iterator<?> iter = lookup.getIterator(); iter.hasNext(); ) { 559 String serviceName = (String) iter.next(); 560 buf.append( serviceName ); 561 if ( iter.hasNext() ) { 562 buf.append( ',' ); 563 } 564 } 565 return buf.toString(); 566 } 567 568 /** 569 * Formats the provided string and the args array into a String using MessageFormat. 570 * 571 * @param pattern 572 * @param args 573 * @return the message to present the client. 574 */ 575 private String produceMessage( String pattern, Object[] args ) { 576 return new MessageFormat( pattern ).format( args ); 577 } 578 579 /** 580 * @see javax.servlet.ServletContextListener#contextDestroyed(javax.servlet.ServletContextEvent) 581 */ 582 public void ctDestroyed() { 583 LOG.logInfo( "Stopping context: " ); 584 585 WMSConfigurationDocument.resetCapabilitiesCache(); 586 WMSConfigurationDocument_1_3_0.resetCapabilitiesCache(); 587 WMPSConfigurationDocument.resetCapabilitiesCache(); 588 589 ServiceLookup lookup = ServiceLookup.getInstance(); 590 for ( Iterator<?> iter = lookup.getIterator(); iter.hasNext(); ) { 591 String serviceName = (String) iter.next(); 592 LOG.logInfo( "Stopping service " + serviceName ); 593 594 try { 595 String s = SERVICE_FACTORIES_MAPPINGS.get( lookup.getService( serviceName ) ); 596 Class<?> clzz = Class.forName( s ); 597 // TODO stop and reset all service instances 598 Method[] methods = clzz.getMethods(); 599 for ( int j = 0; j < methods.length; j++ ) { 600 if ( methods[j].getName().equals( "reset" ) ) { 601 Object[] args = new Object[0]; 602 methods[j].invoke( clzz.newInstance(), args ); 603 } 604 } 605 } catch ( Exception e ) { 606 LOG.logError( e.getMessage(), e ); 607 } 608 } 609 } 610 611 @Override 612 public void destroy() { 613 super.destroy(); 614 Enumeration<Driver> e = DriverManager.getDrivers(); 615 while ( e.hasMoreElements() ) { 616 Driver driver = e.nextElement(); 617 try { 618 if ( driver.getClass().getClassLoader() == getClass().getClassLoader() ) 619 DriverManager.deregisterDriver( driver ); 620 } catch ( SQLException e1 ) { 621 LOG.logError( "Cannot unload driver: " + driver ); 622 } 623 } 624 LogFactory.releaseAll(); 625 LogManager.shutdown(); 626 // SLF4JLogFactory.releaseAll(); // should be the same as the LogFactory.releaseAll call 627 Iterator<Class<?>> i = IIORegistry.getDefaultInstance().getCategories(); 628 while ( i.hasNext() ) { 629 Class<?> c = i.next(); 630 Iterator<?> k = IIORegistry.getDefaultInstance().getServiceProviders( c, false ); 631 while ( k.hasNext() ) { 632 Object o = k.next(); 633 if ( o.getClass().getClassLoader() == getClass().getClassLoader() ) { 634 IIORegistry.getDefaultInstance().deregisterServiceProvider( o ); 635 LOG.logDebug( "Deregistering JAI driver ", o.getClass() ); 636 } 637 } 638 } 639 Introspector.flushCaches(); 640 // just clear the configurations for now, it does not hurt 641 CRSConfiguration.DEFINED_CONFIGURATIONS.clear(); 642 } 643 644 }