vgritsenko 2003/02/11 19:03:10 Modified: src/java/org/apache/cocoon/servlet Tag: cocoon_2_0_3_branch CocoonServlet.java Log: Port recent changes from the HEAD. Includes exception handling fixes. Revision Changes Path No revision No revision 1.19.2.16 +161 -156 xml-cocoon2/src/java/org/apache/cocoon/servlet/CocoonServlet.java Index: CocoonServlet.java =================================================================== RCS file: /home/cvs/xml-cocoon2/src/java/org/apache/cocoon/servlet/CocoonServlet.java,v retrieving revision 1.19.2.15 retrieving revision 1.19.2.16 diff -u -r1.19.2.15 -r1.19.2.16 --- CocoonServlet.java 7 Feb 2003 07:23:03 -0000 1.19.2.15 +++ CocoonServlet.java 12 Feb 2003 03:03:09 -0000 1.19.2.16 @@ -61,7 +61,6 @@ import org.apache.avalon.framework.logger.Loggable; import org.apache.cocoon.Constants; import org.apache.cocoon.components.notification.Notifying; -import org.apache.cocoon.components.notification.SimpleNotifyingBean; import org.apache.cocoon.components.notification.DefaultNotifyingBuilder; import org.apache.cocoon.components.notification.Notifier; import org.apache.cocoon.components.request.RequestFactory; @@ -89,15 +88,15 @@ import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.File; +import java.io.FileInputStream; import java.io.InputStream; import java.io.IOException; import java.io.OutputStream; import java.io.FileOutputStream; -import java.io.StringWriter; -import java.io.PrintWriter; import java.lang.reflect.Constructor; import java.net.URL; import java.net.URLDecoder; +import java.net.MalformedURLException; import java.util.Arrays; import java.util.HashMap; import java.util.StringTokenizer; @@ -239,7 +238,6 @@ this.servletContext = conf.getServletContext(); this.appContext.put(Constants.CONTEXT_ENVIRONMENT_CONTEXT, new HttpContext(this.servletContext)); - this.servletContextPath = this.servletContext.getRealPath("/"); // first init the work-directory for the logger. @@ -275,7 +273,7 @@ // Try to figure out the path of the root from that of WEB-INF try { path = this.servletContext.getResource("/WEB-INF").toString(); - } catch (java.net.MalformedURLException me) { + } catch (MalformedURLException me) { throw new ServletException("Unable to get resource 'WEB-INF'.", me); } if (log.isDebugEnabled()) { @@ -293,13 +291,13 @@ } else { this.servletContextURL = new File(path).toURL(); } - } catch (java.net.MalformedURLException me) { + } catch (MalformedURLException me) { // VG: Novell has absolute file names starting with the // volume name which is easily more then one letter. // Examples: sys:/apache/cocoon or sys:\apache\cocoon try { this.servletContextURL = new File(path).toURL(); - } catch (java.net.MalformedURLException ignored) { + } catch (MalformedURLException ignored) { throw new ServletException("Unable to determine servlet context URL.", me); } } @@ -490,15 +488,13 @@ */ public void destroy() { - if (this.initClassLoader) - { + if (this.initClassLoader) { try { Thread.currentThread().setContextClassLoader(this.classLoader); } catch (Exception e){} } - if (this.cocoon != null) - { + if (this.cocoon != null) { if (log.isDebugEnabled()) { log.debug("Servlet destroyed - disposing Cocoon"); } @@ -564,7 +560,7 @@ try { classDirURL = this.servletContext.getResource("/WEB-INF/classes"); - } catch (java.net.MalformedURLException me) { + } catch (MalformedURLException me) { if (log.isWarnEnabled()) { this.log.warn("Unable to add WEB-INF/classes to the classpath", me); } @@ -572,7 +568,7 @@ try { libDirURL = this.servletContext.getResource("/WEB-INF/lib"); - } catch (java.net.MalformedURLException me) { + } catch (MalformedURLException me) { if (log.isWarnEnabled()) { this.log.warn("Unable to add WEB-INF/lib to the classpath", me); } @@ -598,7 +594,7 @@ File[] libraries = root.listFiles(); Arrays.sort(libraries); for (int i = 0; i < libraries.length; i++) { - String fullName = IOUtils.getFullFilename(libraries[i]); + String fullName = IOUtils.getFullFilename(libraries[i]); buildClassPath.append(File.pathSeparatorChar).append(fullName); addClassLoaderDirectory(fullName); @@ -638,7 +634,7 @@ root.mkdirs(); File[] oldLibs = root.listFiles(); - for (int i=0; i<oldLibs.length; i++) { + for (int i = 0; i < oldLibs.length; i++) { String oldLib = oldLibs[i].getName(); if (!libList.contains(oldLib)) { this.log.debug("Removing old library " + oldLibs[i]); @@ -807,7 +803,8 @@ logkitConfig = "/WEB-INF/logkit.xconf"; } - final InputStream is = this.servletContext.getResourceAsStream(logkitConfig); + InputStream is = this.servletContext.getResourceAsStream(logkitConfig); + if (is == null) is = new FileInputStream(logkitConfig); final DefaultConfigurationBuilder builder = new DefaultConfigurationBuilder(); final Configuration conf = builder.build(is); logKitManager.configure(conf); @@ -857,6 +854,17 @@ } if (result == null) { + File resultFile = new File(usedFileName); + if (resultFile.isFile()) try { + result = resultFile.getCanonicalFile().toURL(); + } catch (Exception e) { + String msg = "Init parameter 'configurations' is invalid : " + usedFileName; + log.error(msg, e); + throw new ServletException(msg, e); + } + } + + if (result == null) { String msg = "Init parameter 'configuration' doesn't name an existing resource : " + usedFileName; log.error(msg); throw new ServletException(msg); @@ -960,30 +968,16 @@ this.silentlyRename, this.maxUploadSize); - this.cocoon = getCocoon(request.getPathInfo(), request.getParameter(Constants.RELOAD_PARAM)); + getCocoon(request.getPathInfo(), request.getParameter(Constants.RELOAD_PARAM)); // Check if cocoon was initialized if (this.cocoon == null) { - if(manageExceptions){ - res.reset(); - - SimpleNotifyingBean n = new SimpleNotifyingBean(this); - n.setType("fatal"); - n.setTitle("Internal servlet error"); - n.setSource("Cocoon servlet"); - n.setMessage("Cocoon was not initialized."); - n.setDescription("Cocoon was not initialized. Cannot process request."); - n.addExtraDescription("request-uri", request.getRequestURI()); - - res.setContentType("text/html"); - res.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); - Notifier.notify(n, res.getOutputStream(), "text/html"); - } else { - res.sendError - (HttpServletResponse.SC_INTERNAL_SERVER_ERROR, - "The Cocoon engine said it failed to process the request for an unknown reason." ); - res.flushBuffer(); - } + manageException(request, res, null, null, + HttpServletResponse.SC_INTERNAL_SERVER_ERROR, + "Internal servlet error", + null /* "Cocoon was not initialized" */, + null /* "Cocoon was not initialized, cannot process request" */, + this.exception); return; } @@ -1010,7 +1004,6 @@ else process URI normally */ String prefix = request.getRequestURI(); - if (prefix == null) { prefix = ""; } @@ -1021,15 +1014,27 @@ String contentType = null; ContextMap ctxMap = null; + + Environment env; + try{ + if (uri.charAt(0) == '/') { + uri = uri.substring(1); + } + env = getEnvironment(URLDecoder.decode(uri), request, res); + } catch (Exception e) { + if (log.isErrorEnabled()) { + log.error("Problem with Cocoon servlet", e); + } + + manageException(request, res, null, uri, + HttpServletResponse.SC_INTERNAL_SERVER_ERROR, + "Problem in creating the Environment", null, null, e); + return; + } + try { try { - if (uri.charAt(0) == '/') { - uri = uri.substring(1); - } - - Environment env = getEnvironment(URLDecoder.decode(uri), request, res); - - // Initialize a fresh log context containing the object model : it + // Initialize a fresh log context containing the object model: it // will be used by the CocoonLogFormatter ctxMap = ContextMap.getCurrentContext(); // Add thread name (default content for empty context) @@ -1043,62 +1048,28 @@ if (this.cocoon.process(env)) { contentType = env.getContentType(); } else { - //NKB Should not get here? + // NKB Should not get here? log.fatalError("The Cocoon engine said it failed to process the request for an unknown reason."); - - if(manageExceptions){ - res.reset(); - - SimpleNotifyingBean n = new SimpleNotifyingBean(this); - n.setType("error"); - n.setTitle("Cocoon confusion"); - n.setSource("Cocoon servlet"); - n.setMessage("Cocoon engine failed in process."); - n.setDescription("The Cocoon engine said it failed to process the request for an unknown reason."); - n.addExtraDescription("request-uri", request.getRequestURI()); - n.addExtraDescription("path-info", uri); - - res.setContentType("text/html"); - res.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); - Notifier.notify(n, res.getOutputStream(), "text/html"); - } else { - res.sendError - (HttpServletResponse.SC_INTERNAL_SERVER_ERROR, - "The Cocoon engine said it failed to process the request for an unknown reason." ); - res.flushBuffer(); - } + manageException(request, res, env, uri, + HttpServletResponse.SC_INTERNAL_SERVER_ERROR, + "Cocoon confusion", + "Cocoon engine failed in process.", + "The Cocoon engine said it failed to process the request for an unknown reason.", + null); return; - } } catch (ResourceNotFoundException rse) { if (log.isWarnEnabled()) { log.warn("The resource was not found", rse); } - if(manageExceptions){ - res.reset(); - - SimpleNotifyingBean n = new SimpleNotifyingBean(this); - n.setType("resource-not-found"); - n.setTitle("Resource not found"); - n.setSource("Cocoon servlet"); - n.setMessage("Resource not found"); - n.setDescription("The requested URI \"" - + request.getRequestURI() - + "\" was not found."); - n.addExtraDescription("request-uri", request.getRequestURI()); - n.addExtraDescription("path-info", uri); - - res.setContentType("text/html"); - res.setStatus(HttpServletResponse.SC_NOT_FOUND); - Notifier.notify(n, res.getOutputStream(), "text/html"); - } else { - res.sendError - (HttpServletResponse.SC_NOT_FOUND, "Resource not found." ); - res.flushBuffer(); - } + manageException(request, res, env, uri, + HttpServletResponse.SC_NOT_FOUND, + "Resource not found", + "Resource not found", + "The requested URI \"" + request.getRequestURI() + "\" was not found", + rse); return; - } catch (ConnectionResetException cre) { if (log.isDebugEnabled()) { log.debug("The connection was reset", cre); @@ -1111,28 +1082,9 @@ log.error("Problem with Cocoon servlet", e); } - if(manageExceptions){ - res.reset(); - - HashMap extraDescriptions = new HashMap(3); - extraDescriptions.put("request-uri", request.getRequestURI()); - extraDescriptions.put("path-info", uri); - StringWriter writer = new StringWriter(); - e.printStackTrace(new PrintWriter(writer)); - extraDescriptions.put("stack-trace",writer.toString()); - - Notifying n=new DefaultNotifyingBuilder().build( - this, e, "fatal","Internal server error","Cocoon servlet",null,null,extraDescriptions); - - res.setContentType("text/html"); - res.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); - Notifier.notify(n, res.getOutputStream(), "text/html"); - } else { - res.sendError - (HttpServletResponse.SC_INTERNAL_SERVER_ERROR, - "Internal server error."); - res.flushBuffer(); - } + manageException(request, res, env, uri, + HttpServletResponse.SC_INTERNAL_SERVER_ERROR, + "Internal server error", null, null, e); return; } @@ -1161,16 +1113,72 @@ } } finally { if (ctxMap != null) ctxMap.clear(); - try{ - ServletOutputStream out = res.getOutputStream(); - out.flush(); - out.close(); + try { + ServletOutputStream out = res.getOutputStream(); + out.flush(); + out.close(); } catch(Exception e) { - log.error("Cocoon servlet threw an Exception while trying to close stream.", e); + log.error("Cocoon servlet got an Exception while trying to close stream.", e); } } } + protected void manageException(HttpServletRequest req, HttpServletResponse res, Environment env, + String uri, int errorStatus, + String title, String message, String description, + Exception e) + throws IOException { + if (this.manageExceptions) { + if (env != null) { + env.tryResetResponse(); + } else { + res.reset(); + } + + HashMap extraDescriptions = new HashMap(3); + extraDescriptions.put(Notifying.EXTRA_REQUESTURI, req.getRequestURI()); + if (uri != null) { + extraDescriptions.put("path-info", uri); + } + + String type = Notifying.FATAL_NOTIFICATION; + if (errorStatus == HttpServletResponse.SC_NOT_FOUND) { + type = "resource-not-found"; + + // VG: Do not show exception trace on NotFound error, add only exception message. + if (e != null) { + extraDescriptions.put(Notifying.EXTRA_CAUSE, + DefaultNotifyingBuilder.getRootCause(e).getMessage()); + e = null; + } + } + + // Do not show exception stack trace when log level is WARN or above. Show only message. + if (!log.isInfoEnabled()) { + extraDescriptions.put(Notifying.EXTRA_CAUSE, + DefaultNotifyingBuilder.getRootCause(e).getMessage()); + e = null; + } + + Notifying n = new DefaultNotifyingBuilder().build(this, + e, + type, + title, + "Cocoon servlet", + message, + description, + extraDescriptions); + + res.setContentType("text/html"); + res.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); + Notifier.notify(n, res.getOutputStream(), "text/html"); + } else { + res.sendError(errorStatus, title); + res.flushBuffer(); + } + } + + /** * Create the environment for the request */ @@ -1189,7 +1197,7 @@ req, res, this.servletContext, - (HttpContext)this.appContext.get(Constants.CONTEXT_ENVIRONMENT_CONTEXT), + (HttpContext) this.appContext.get(Constants.CONTEXT_ENVIRONMENT_CONTEXT), this.containerEncoding, formEncoding, this.requestFactory); @@ -1212,8 +1220,8 @@ String initParam = null; int dividerPos = parentComponentManagerClass.indexOf('/'); if (dividerPos != -1) { - initParam = parentComponentManagerClass.substring (dividerPos + 1); - parentComponentManagerClass = parentComponentManagerClass.substring (0, dividerPos); + initParam = parentComponentManagerClass.substring(dividerPos + 1); + parentComponentManagerClass = parentComponentManagerClass.substring(0, dividerPos); } Class pcm = ClassUtils.loadClass(parentComponentManagerClass); @@ -1221,7 +1229,7 @@ parentComponentManager = (ComponentManager) pcmc.newInstance(new Object[]{initParam}); if (parentComponentManager instanceof Loggable) { - ((Loggable) parentComponentManager).setLogger(log); + ((Loggable) parentComponentManager).setLogger(log); } if (parentComponentManager instanceof Contextualizable) { ((Contextualizable) parentComponentManager).contextualize(this.appContext); @@ -1254,9 +1262,9 @@ } catch (Exception e){} } - this.updateEnvironment(); - this.forceLoad(); - this.forceProperty(); + updateEnvironment(); + forceLoad(); + forceProperty(); try { URL configFile = (URL) this.appContext.get(Constants.CONTEXT_CONFIG_URL); @@ -1271,21 +1279,19 @@ c.setLogger(log); } c.contextualize(this.appContext); - c.compose(getParentComponentManager ()); + c.compose(getParentComponentManager()); c.setLogKitManager(this.logKitManager); c.initialize(); this.creationTime = System.currentTimeMillis(); - this.disposeCocoon(); - + disposeCocoon(); this.cocoon = c; } catch (Exception e) { if (log.isErrorEnabled()) { log.error("Exception reloading", e); } this.exception = e; - - this.disposeCocoon(); + disposeCocoon(); } } @@ -1299,7 +1305,7 @@ protected void updateEnvironment() throws ServletException { this.appContext.put(Constants.CONTEXT_CLASS_LOADER, classLoader); this.appContext.put(Constants.CONTEXT_CLASSPATH, getClassPath()); - } + } private String processTime(long time) { StringBuffer out = new StringBuffer(PROCESSED_BY); @@ -1322,37 +1328,36 @@ /** * Gets the current cocoon object. Reload cocoon if configuration * changed or we are reloading. - * - * @return Cocoon */ - private Cocoon getCocoon(final String pathInfo, final String reloadParam) + private void getCocoon(final String pathInfo, final String reloadParam) throws ServletException { - if (this.cocoon != null && this.allowReload) { - if (this.cocoon.modifiedSince(this.creationTime)) { - if (log.isInfoEnabled()) { - log.info("Configuration changed reload attempt"); + if (this.allowReload) { + boolean reload = false; + + if (this.cocoon != null) { + if (this.cocoon.modifiedSince(this.creationTime)) { + if (log.isInfoEnabled()) { + log.info("Configuration changed reload attempt"); + } + reload = true; + } else if (pathInfo == null && reloadParam != null) { + if (log.isInfoEnabled()) { + log.info("Forced reload attempt"); + } + reload = true; } - this.initLogger(); - this.createCocoon(); - return this.cocoon; - } else if ((pathInfo == null) && (reloadParam != null)) { + } else if (pathInfo == null && reloadParam != null) { if (log.isInfoEnabled()) { - log.info("Forced reload attempt"); + log.info("Invalid configurations reload"); } - this.initLogger(); - this.createCocoon(); - return this.cocoon; + reload = true; } - } else if ((pathInfo == null) && this.allowReload && (reloadParam != null)) { - if (log.isInfoEnabled()) { - log.info("Invalid configurations reload"); + + if (reload) { + initLogger(); + createCocoon(); } - this.initLogger(); - this.createCocoon(); - return this.cocoon; } - - return this.cocoon; } /**
---------------------------------------------------------------------- In case of troubles, e-mail: [EMAIL PROTECTED] To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]