sylvain     2003/06/03 06:25:43

  Modified:    src/java/org/apache/cocoon/servlet BootstrapServlet.java
                        CocoonServlet.java ParanoidClassLoader.java
                        ParanoidCocoonServlet.java
  Log:
  ParanoidCocoonServlet is now really paranoid
  
  Revision  Changes    Path
  1.2       +53 -139   
cocoon-2.1/src/java/org/apache/cocoon/servlet/BootstrapServlet.java
  
  Index: BootstrapServlet.java
  ===================================================================
  RCS file: 
/home/cvs/cocoon-2.1/src/java/org/apache/cocoon/servlet/BootstrapServlet.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- BootstrapServlet.java     9 Mar 2003 00:09:37 -0000       1.1
  +++ BootstrapServlet.java     3 Jun 2003 13:25:42 -0000       1.2
  @@ -50,19 +50,19 @@
   */
   package org.apache.cocoon.servlet;
   
  -import javax.servlet.*;
  -import javax.servlet.http.HttpServlet;
  -
   import java.io.File;
  -import java.io.IOException;
   import java.io.InputStream;
   import java.net.MalformedURLException;
   import java.net.URL;
  -import java.util.ArrayList;
   import java.util.Enumeration;
  -import java.util.List;
   import java.util.Set;
   
  +import javax.servlet.RequestDispatcher;
  +import javax.servlet.Servlet;
  +import javax.servlet.ServletConfig;
  +import javax.servlet.ServletContext;
  +import javax.servlet.ServletException;
  +
   /**
    * A bootstrap servlet to allow Cocoon to run in servlet engines that aren't fully
    * compliant with the servlet 2.2 spec.
  @@ -81,141 +81,55 @@
    * @version CVS $Id$
    */
   
  -public class BootstrapServlet extends HttpServlet {
  -    
  -    /**
  -     * The name of the actual servlet class.
  -     */
  -    public static final String SERVLET_CLASS = 
"org.apache.cocoon.servlet.CocoonServlet";
  +public class BootstrapServlet extends ParanoidCocoonServlet {
       
  -    protected Servlet servlet;
  +    private File contextDir;
       
  -    protected ClassLoader classloader;
  -    
  -    protected ServletContext context;
  -    
  -    public void init(ServletConfig config) throws ServletException {
  -        this.context = config.getServletContext();
  -        
  -        this.context.log("getRealPath(\"/\") = " + context.getRealPath("/"));
  -
  -        String contextDirParam = config.getInitParameter("context-directory");
  -        if (contextDirParam == null) {
  -            // Check old form, not consistent with other parameter names
  -            contextDirParam = config.getInitParameter("context-dir");
  -            if (contextDirParam == null) {
  -                String msg = "The 'context-directory' parameter must be set to the 
root of the servlet context";
  -                this.context.log(msg);
  -                throw new ServletException(msg);
  -            } else {
  -                this.context.log("Parameter 'context-dir' is deprecated - use 
'context-directory'");
  -            }
  -        }
  -        
  -        // Ensure context dir doesn't end with a "/" (servlet spec says that paths 
for
  -        // getResource() should start by a "/")
  -        if (contextDirParam.endsWith("/")) {
  -            contextDirParam = contextDirParam.substring(0, contextDirParam.length() 
- 1);
  -        }
  -        
  -        // Ensure context dir exists and is a directory
  -        File contextDir = new File(contextDirParam);
  -        if (!contextDir.exists()) {
  -            String msg = "Context dir '" + contextDir + "' doesn't exist";
  -            this.context.log(msg);
  -            throw new ServletException(msg);
  -        }
  +     protected File getContextDir() throws ServletException {
  +             
  +             ServletContext context = getServletContext();
  +             ServletConfig config = getServletConfig();
  +             
  +             log("getRealPath(\"/\") = " + context.getRealPath("/"));
  +
  +             String contextDirParam = config.getInitParameter("context-directory");
  +             
  +             if (contextDirParam == null) {
  +                             throw new ServletException("The 'context-directory' 
parameter must be set to the root of the servlet context");
  +             }
  +        
  +             // Ensure context dir doesn't end with a "/" (servlet spec says that 
paths for
  +             // getResource() should start by a "/")
  +             if (contextDirParam.endsWith("/")) {
  +                     contextDirParam = contextDirParam.substring(0, 
contextDirParam.length() - 1);
  +             }
  +        
  +             // Ensure context dir exists and is a directory
  +             this.contextDir = new File(contextDirParam);
  +             if (!this.contextDir.exists()) {
  +                     String msg = "Context dir '" + this.contextDir + "' doesn't 
exist";
  +                     log(msg);
  +                     throw new ServletException(msg);
  +             }
  +
  +             if (!this.contextDir.isDirectory()) {
  +                     String msg = "Context dir '" + this.contextDir + "' should be 
a directory";
  +                     log(msg);
  +                     throw new ServletException(msg);
  +             }
  +        
  +             context.log("Context dir set to " + this.contextDir);
  +             
  +             return this.contextDir;
  +     }
   
  -        if (!contextDir.isDirectory()) {
  -            String msg = "Context dir '" + contextDir + "' should be a directory";
  -            this.context.log(msg);
  -            throw new ServletException(msg);
  -        }
  -        
  -        context.log("Context dir set to " + contextDir);
   
  -        this.classloader = getClassLoader(contextDirParam);
  -        
  -        try {
  -            Class servletClass = this.classloader.loadClass(SERVLET_CLASS);
  -            
  -            this.servlet = (Servlet)servletClass.newInstance();
  -        } catch(Exception e) {
  -            context.log("Cannot load servlet", e);
  -            throw new ServletException(e);
  -        }
  -        
  -        // Always set the context classloader. JAXP uses it to find a ParserFactory,
  -        // and thus fails if it's not set to the webapp classloader.
  -        Thread.currentThread().setContextClassLoader(this.classloader);
  -        
  -        ServletContext newContext = new ContextWrapper(context, contextDirParam);
  -        ServletConfig newConfig = new ConfigWrapper(config, newContext);
  +    protected void initServlet(Servlet servlet) throws ServletException {
           
  -        super.init(newConfig);
  +        ServletContext newContext = new ContextWrapper(getServletContext(), 
this.contextDir);
  +        ServletConfig newConfig = new ConfigWrapper(getServletConfig(), newContext);
           
  -        // Inlitialize the actual servlet
  -        this.servlet.init(newConfig);
  -        
  -    }
  -    
  -    /**
  -     * Get the classloader that will be used to create the actual servlet.
  -     */
  -    protected ClassLoader getClassLoader(String contextDirParam) throws 
ServletException {
  -        List urlList = new ArrayList();
  -        
  -        try {
  -            File classDir = new File(contextDirParam + "/WEB-INF/classes");
  -            if (classDir.exists()) {
  -                if (!classDir.isDirectory()) {
  -                    String msg = classDir + " exists but is not a directory";
  -                    this.context.log(msg);
  -                    throw new ServletException(msg);
  -                }
  -            
  -                URL classURL = classDir.toURL();
  -                context.log("Adding class directory " + classURL);
  -                urlList.add(classURL);
  -                
  -            }
  -            
  -            File libDir = new File(contextDirParam + "/WEB-INF/lib");
  -            File[] libraries = libDir.listFiles();
  -
  -            for (int i = 0; i < libraries.length; i++) {
  -                URL lib = libraries[i].toURL();
  -                context.log("Adding class library " + lib);
  -                urlList.add(lib);
  -            }
  -        } catch (MalformedURLException mue) {
  -            context.log("Malformed url", mue);
  -            throw new ServletException(mue);
  -        }
  -        
  -        URL[] urls = (URL[])urlList.toArray(new URL[urlList.size()]);
  -        
  -        return ParanoidClassLoader.newInstance(urls, 
this.getClass().getClassLoader());
  -    }
  -    
  -    /**
  -     * Service the request by delegating the call to the real servlet
  -     */
  -    public void service(ServletRequest request, ServletResponse response)
  -      throws ServletException, IOException {
  -
  -        Thread.currentThread().setContextClassLoader(this.classloader);
  -        this.servlet.service(request, response);
  -    }
  -    
  -    /**
  -     * Destroy the actual servlet
  -     */
  -    public void destroy() {
  -
  -        super.destroy();
  -        Thread.currentThread().setContextClassLoader(this.classloader);
  -        this.servlet.destroy();
  +        servlet.init(newConfig);        
       }
   
       //-------------------------------------------------------------------------
  @@ -260,13 +174,13 @@
        */
       public static class ContextWrapper implements ServletContext {
           ServletContext context;
  -        String contextRoot;
  +        File contextRoot;
           
           /**
            * Builds a wrapper around an existing context, and handle all
            * resource resolution relatively to <code>contextRoot</code>
            */
  -        public ContextWrapper(ServletContext context, String contextRoot) {
  +        public ContextWrapper(ServletContext context, File contextRoot) {
               this.context = context;
               this.contextRoot = contextRoot;
           }
  @@ -293,7 +207,7 @@
            * returned.
            */
           public URL getResource(String path) throws MalformedURLException {
  -            File file = new File(this.contextRoot + path);
  +            File file = new File(this.contextRoot, path);
               if (file.exists()) {
                   URL result = file.toURL();
                   //this.context.log("getResource(" + path + ") = " + result);
  
  
  
  1.8       +83 -100   cocoon-2.1/src/java/org/apache/cocoon/servlet/CocoonServlet.java
  
  Index: CocoonServlet.java
  ===================================================================
  RCS file: 
/home/cvs/cocoon-2.1/src/java/org/apache/cocoon/servlet/CocoonServlet.java,v
  retrieving revision 1.7
  retrieving revision 1.8
  diff -u -r1.7 -r1.8
  --- CocoonServlet.java        20 May 2003 12:38:27 -0000      1.7
  +++ CocoonServlet.java        3 Jun 2003 13:25:42 -0000       1.8
  @@ -269,9 +269,12 @@
   
           super.init(conf);
   
  -        final String initClassLoaderParam = 
conf.getInitParameter("init-classloader");
  -        this.initClassLoader = "true".equalsIgnoreCase(initClassLoaderParam) ||
  -                               "yes".equalsIgnoreCase(initClassLoaderParam);
  +             // Check the init-classloader parameter only if it's not already true.
  +             // This is useful for subclasses of this servlet that override the 
value
  +             // initially set by this class (i.e. false).
  +             if (!this.initClassLoader) {
  +                     this.initClassLoader = 
getInitParameterAsBoolean("init-classloader", false);
  +             }
   
           if (this.initClassLoader) {
               // Force context classloader so that JAXP can work correctly
  @@ -298,8 +301,8 @@
   
           // first init the work-directory for the logger.
           // this is required if we are running inside a war file!
  -        final String workDirParam = conf.getInitParameter("work-directory");
  -        if ((workDirParam != null) && (!workDirParam.trim().equals(""))) {
  +        final String workDirParam = getInitParameter("work-directory");
  +        if (workDirParam != null) {
               if (this.servletContextPath == null) {
                   // No context path : consider work-directory as absolute
                   this.workDir = new File(workDirParam);
  @@ -361,17 +364,12 @@
               log.debug("URL for Root: " + this.servletContextURL);
           }
   
  -        this.forceLoadParameter = conf.getInitParameter("load-class");
  -        if (conf.getInitParameter("load-class") == null) {
  -            if (log.isDebugEnabled()) {
  -                log.debug("load-class was not set - defaulting to false?");
  -            }
  -        }
  +        this.forceLoadParameter = getInitParameter("load-class", null);
   
  -        this.forceSystemProperty = conf.getInitParameter("force-property");
  +        this.forceSystemProperty = getInitParameter("force-property", null);
   
           // add work directory
  -        if ((workDirParam != null) && (!workDirParam.trim().equals(""))) {
  +        if (workDirParam != null) {
               if (log.isDebugEnabled()) {
                   log.debug("Using work-directory " + this.workDir);
               }
  @@ -383,7 +381,7 @@
           this.appContext.put(Constants.CONTEXT_WORK_DIR, workDir);
   
           final String uploadDirParam = conf.getInitParameter("upload-directory");
  -        if ((uploadDirParam != null) && (!uploadDirParam.trim().equals(""))) {
  +        if (uploadDirParam != null) {
               if (this.servletContextPath == null) {
                   this.uploadDir = new File(uploadDirParam);
               } else {
  @@ -409,33 +407,12 @@
           this.uploadDir.mkdirs();
           this.appContext.put(Constants.CONTEXT_UPLOAD_DIR, this.uploadDir);
   
  -        value = conf.getInitParameter("enable-uploads");
  -        if (value != null) {
  -            this.enableUploads = ("yes".equalsIgnoreCase(value) || 
"true".equalsIgnoreCase(value));
  -        } else {
  -            this.enableUploads = ENABLE_UPLOADS;
  -            if (log.isDebugEnabled()) {
  -               log.debug("enable-uploads was not set - defaulting to " + 
this.enableUploads);
  -            }
  -        }
  +        this.enableUploads = getInitParameterAsBoolean("enable-uploads", 
ENABLE_UPLOADS);
           
  -        value = conf.getInitParameter("autosave-uploads");
  -        if (value != null) {
  -            this.autoSaveUploads = ("yes".equalsIgnoreCase(value) || 
"true".equalsIgnoreCase(value));
  -        } else {
  -            this.autoSaveUploads = SAVE_UPLOADS_TO_DISK;
  -            if (log.isDebugEnabled()) {
  -               log.debug("autosave-uploads was not set - defaulting to " + 
this.autoSaveUploads);
  -            }
  -        }
  +        this.autoSaveUploads = getInitParameterAsBoolean("autosave-uploads", 
SAVE_UPLOADS_TO_DISK);
   
  -        String overwriteParam = conf.getInitParameter("overwrite-uploads");
  +        String overwriteParam = getInitParameter("overwrite-uploads", "rename");
           // accepted values are deny|allow|rename - rename is default.
  -        if (overwriteParam == null) {
  -            if (log.isDebugEnabled()) {
  -               log.debug("overwrite-uploads was not set - defaulting to rename");
  -            }
  -        }
           if ("deny".equalsIgnoreCase(overwriteParam)) {
               this.allowOverwrite = false;
               this.silentlyRename = false;
  @@ -448,14 +425,10 @@
              this.silentlyRename = true;
           }
   
  -        this.maxUploadSize = MAX_UPLOAD_SIZE;
  -        String maxSizeParam = conf.getInitParameter("upload-max-size");
  -        if ((maxSizeParam != null) && (!maxSizeParam.trim().equals(""))) {
  -            this.maxUploadSize = Integer.parseInt(maxSizeParam);
  -        }
  +        this.maxUploadSize = getInitParameterAsInteger("upload-max-size", 
MAX_UPLOAD_SIZE);
   
           String cacheDirParam = conf.getInitParameter("cache-directory");
  -        if ((cacheDirParam != null) && (!cacheDirParam.trim().equals(""))) {
  +        if (cacheDirParam != null) {
               if (this.servletContextPath == null) {
                   this.cacheDir = new File(cacheDirParam);
               } else {
  @@ -490,15 +463,7 @@
           }
   
           // get allow reload parameter, default is true
  -        value = conf.getInitParameter("allow-reload");
  -        if (value != null) {
  -            this.allowReload = value.equalsIgnoreCase("yes") || 
value.equalsIgnoreCase("true");
  -        } else {
  -            this.allowReload = ALLOW_RELOAD;
  -            if (log.isDebugEnabled()) {
  -                log.debug("allow-reload was not set - defaulting to " + 
ALLOW_RELOAD);
  -            }
  -        }
  +             this.allowReload = getInitParameterAsBoolean("allow-reload", 
ALLOW_RELOAD);
   
           value = conf.getInitParameter("show-time");
           this.showTime = "yes".equalsIgnoreCase(value) || 
"true".equalsIgnoreCase(value)
  @@ -509,12 +474,8 @@
               }
           }
   
  -        parentComponentManagerClass = 
conf.getInitParameter("parent-component-manager");
  -        if (parentComponentManagerClass == null) {
  -            if (log.isDebugEnabled()) {
  -                log.debug("parent-component-manager was not set - defaulting to 
null.");
  -            }
  -        } else {
  +        parentComponentManagerClass = getInitParameter("parent-component-manager", 
null);
  +        if (parentComponentManagerClass != null) {
               int dividerPos = parentComponentManagerClass.indexOf('/');
               if (dividerPos != -1) {
                   parentComponentManagerInitParam = 
parentComponentManagerClass.substring(dividerPos + 1);
  @@ -522,38 +483,12 @@
               }
           }
   
  -        this.containerEncoding = conf.getInitParameter("container-encoding");
  -        if (containerEncoding == null) {
  -            this.containerEncoding = "ISO-8859-1";
  -            if (log.isDebugEnabled()) {
  -                log.debug("container-encoding was not set - defaulting to 
ISO-8859-1.");
  -            }
  -        }
  -
  -        this.defaultFormEncoding = conf.getInitParameter("form-encoding");
  -        if (defaultFormEncoding == null) {
  -            this.defaultFormEncoding = "ISO-8859-1";
  -            if (log.isDebugEnabled()) {
  -                log.debug("form-encoding was not set - defaulting to ISO-8859-1.");
  -            }
  -        }
  +        this.containerEncoding = getInitParameter("container-encoding", 
"ISO-8859-1");
  +        this.defaultFormEncoding = getInitParameter("form-encoding","ISO-8859-1");
   
  -        value = conf.getInitParameter("manage-exceptions");
  -        this.manageExceptions = (value == null || value.equalsIgnoreCase("yes") || 
value.equalsIgnoreCase("true"));
  -        if (value == null) {
  -            if (log.isDebugEnabled()) {
  -                log.debug("Parameter manageExceptions was not set - defaulting to 
true.");
  -            }
  -        }
  +             this.manageExceptions = getInitParameterAsBoolean("manage-exceptions", 
true);
   
  -        value = conf.getInitParameter("enable-instrumentation");
  -        this.enableInstrumentation =
  -            "yes".equalsIgnoreCase(value) || "true".equalsIgnoreCase(value);
  -        if (value == null) {
  -            if (log.isDebugEnabled()) {
  -                log.debug("enable-instrumentation was not set - defaulting to 
false.");
  -            }
  -        }
  +             this.enableInstrumentation = 
getInitParameterAsBoolean("enable-instrumentation", false);
   
           this.requestFactory = new RequestFactory(this.autoSaveUploads,
                                                    this.uploadDir,
  @@ -790,7 +725,7 @@
        protected String getExtraClassPath()
        throws ServletException {
            String extraClassPath = this.getInitParameter("extra-classpath");
  -         if ((extraClassPath != null) && !extraClassPath.trim().equals("")) {
  +         if (extraClassPath != null) {
                StringBuffer sb = new StringBuffer();
                StringTokenizer st = new StringTokenizer(extraClassPath, 
System.getProperty("path.separator"), false);
                int i = 0;
  @@ -849,14 +784,11 @@
        * file.
        */
       private void initLogger() {
  -        String logLevel = getInitParameter("log-level");
  -        if (logLevel == null) {
  -            logLevel = "INFO";
  -        }
  +        String logLevel = getInitParameter("log-level", "INFO");
   
           final String accesslogger = getInitParameter("servlet-logger");
   
  -        final Priority logPriority = Priority.getPriorityForName(logLevel.trim());
  +        final Priority logPriority = Priority.getPriorityForName(logLevel);
   
           final ServletOutputLogTarget servTarget = new 
ServletOutputLogTarget(this.servletContext);
   
  @@ -888,10 +820,7 @@
               this.logKitManager = logKitManager;
   
               //Configure the logkit management
  -            String logkitConfig = getInitParameter("logkit-config");
  -            if (logkitConfig == null) {
  -                logkitConfig = "/WEB-INF/logkit.xconf";
  -            }
  +            String logkitConfig = getInitParameter("logkit-config", 
"/WEB-INF/logkit.xconf");
   
               InputStream is = this.servletContext.getResourceAsStream(logkitConfig);
               if (is == null) is = new FileInputStream(logkitConfig);
  @@ -1511,5 +1440,59 @@
               this.cocoon.dispose();
               this.cocoon = null;
           }
  +    }
  +    
  +    /**
  +     * Get an initialisation parameter. The value is trimmed, and null is returned 
if the trimmed value 
  +     * is empty.
  +     */
  +    public String getInitParameter(String name) {
  +     String result = super.getInitParameter(name);
  +     if (result != null) {
  +             result = result.trim();
  +             if (result.length() == 0) {
  +                     result = null;
  +             }
  +     }
  +     
  +     return result;
  +    }
  +    
  +    /** Convenience method to access servlet parameters */
  +    protected String getInitParameter(String name, String defaultValue) {
  +     String result = getInitParameter(name);
  +     if (result == null) {
  +             if (log != null && log.isDebugEnabled()) {
  +                     log.debug(name + " was not set - defaulting to '" + 
defaultValue + "'");
  +             }
  +             return defaultValue;
  +     } else {
  +             return result;
  +     }
  +    }
  +    
  +    /** Convenience method to access boolean servlet parameters */
  +    protected boolean getInitParameterAsBoolean(String name, boolean defaultValue) {
  +     String value = getInitParameter(name);
  +     if (value == null) {
  +                     if (log != null && log.isDebugEnabled()) {
  +                             log.debug(name + " was not set - defaulting to '" + 
defaultValue + "'");
  +                     }
  +             return defaultValue;
  +     } else {
  +             return value.equalsIgnoreCase("true") || value.equalsIgnoreCase("yes");
  +     }
  +    }
  +    
  +    protected int getInitParameterAsInteger(String name, int defaultValue) {
  +     String value = getInitParameter(name);
  +     if (value == null) {
  +                     if (log != null && log.isDebugEnabled()) {
  +                             log.debug(name + " was not set - defaulting to '" + 
defaultValue + "'");
  +                     }
  +                     return defaultValue;
  +     } else {
  +             return Integer.parseInt(value);
  +     }
       }
   }
  
  
  
  1.2       +12 -3     
cocoon-2.1/src/java/org/apache/cocoon/servlet/ParanoidClassLoader.java
  
  Index: ParanoidClassLoader.java
  ===================================================================
  RCS file: 
/home/cvs/cocoon-2.1/src/java/org/apache/cocoon/servlet/ParanoidClassLoader.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- ParanoidClassLoader.java  9 Mar 2003 00:09:37 -0000       1.1
  +++ ParanoidClassLoader.java  3 Jun 2003 13:25:42 -0000       1.2
  @@ -64,7 +64,7 @@
    * classes.  It checks this classloader before it checks its parent.
    *
    * @author <a href="mailto:[EMAIL PROTECTED]">Berin Loritsch</a>
  - * @author <a href="mailto:[EMAIL PROTECTED]">Sylvain Wallez</a>
  + * @author <a href="http://www.apache.org/~sylvain/";>Sylvain Wallez</a>
    * @version CVS $Id$
    */
   
  @@ -85,7 +85,7 @@
        * Alternate constructor to define a parent.
        */
       public ParanoidClassLoader(final ClassLoader parent) {
  -        this(null, parent, null);
  +        this(new URL[0], parent, null);
       }
   
       /**
  @@ -151,6 +151,7 @@
               
               try {
                   clazz = findClass(name);
  +                //System.err.println("Paranoid load : " + name);
               } catch (ClassNotFoundException cnfe) {
                   if (this.parent != null) {
                        // Ask to parent ClassLoader (can also throw a CNFE).
  @@ -201,5 +202,13 @@
           } catch (MalformedURLException mue) {
               throw new CascadingIOException("Could not add repository", mue);
           }
  +    }
  +    
  +    /**
  +     * Adds a new URL
  +     */
  +    
  +    public void addURL(URL url) {
  +     super.addURL(url);
       }
   }
  
  
  
  1.2       +138 -100  
cocoon-2.1/src/java/org/apache/cocoon/servlet/ParanoidCocoonServlet.java
  
  Index: ParanoidCocoonServlet.java
  ===================================================================
  RCS file: 
/home/cvs/cocoon-2.1/src/java/org/apache/cocoon/servlet/ParanoidCocoonServlet.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- ParanoidCocoonServlet.java        9 Mar 2003 00:09:37 -0000       1.1
  +++ ParanoidCocoonServlet.java        3 Jun 2003 13:25:42 -0000       1.2
  @@ -50,12 +50,20 @@
   */
   package org.apache.cocoon.servlet;
   
  -import org.apache.cocoon.components.classloader.RepositoryClassLoader;
  -import org.apache.cocoon.util.IOUtils;
  -
  -import javax.servlet.ServletException;
   import java.io.File;
  +import java.io.FilenameFilter;
  +import java.io.IOException;
  +import java.net.MalformedURLException;
   import java.net.URL;
  +import java.util.ArrayList;
  +import java.util.List;
  +
  +import javax.servlet.Servlet;
  +import javax.servlet.ServletConfig;
  +import javax.servlet.ServletException;
  +import javax.servlet.ServletRequest;
  +import javax.servlet.ServletResponse;
  +import javax.servlet.http.HttpServlet;
   
   /**
    * This is the entry point for Cocoon execution as an HTTP Servlet.
  @@ -66,105 +74,135 @@
    * of it.
    *
    * @author <a href="mailto:[EMAIL PROTECTED]">Berin Loritsch</a>
  + * @author <a href="http://www.apache.org/~sylvain/";>Sylvain Wallez</a>
    * @version CVS $Id$
    */
   
  -public class ParanoidCocoonServlet extends CocoonServlet {
  +public class ParanoidCocoonServlet extends HttpServlet {
   
  -    protected RepositoryClassLoader repositoryLoader;
  +     /**
  +      * The name of the actual servlet class.
  +      */
  +     public static final String SERVLET_CLASS = 
"org.apache.cocoon.servlet.CocoonServlet";
  +    
  +     private Servlet servlet;
  +    
  +     private ClassLoader classloader;
       
  -    public ParanoidCocoonServlet() {
  -        super();
  -        // Override the parent class classloader
  -        this.repositoryLoader = new RepositoryClassLoader(new URL[] {}, 
this.getClass().getClassLoader());
  -        super.classLoader = this.repositoryLoader;
  -    }
  -
  -    /**
  -     * This builds the important ClassPath used by this Servlet.  It
  -     * does so in a Servlet Engine neutral way.  It uses the
  -     * <code>ServletContext</code>'s <code>getRealPath</code> method
  -     * to get the Servlet 2.2 identified classes and lib directories.
  -     * It iterates through every file in the lib directory and adds
  -     * it to the classpath.
  -     *
  -     * Also, we add the files to the ClassLoader for the Cocoon system.
  -     * In order to protect ourselves from skitzofrantic classloaders,
  -     * we need to work with a known one.
  -     *
  -     * @param context  The ServletContext to perform the lookup.
  -     *
  -     * @throws ServletException
  -     */
  -     protected String getClassPath()
  -     throws ServletException {
  -
  -        StringBuffer buildClassPath = new StringBuffer();
  -        String classDirPath = getInitParameter("class-dir");
  -        String libDirPath = getInitParameter("lib-dir");
  -        String classDir;
  -        File root;
  -
  -        if ((classDirPath != null) && !classDirPath.trim().equals("")) {
  -            classDir = classDirPath;
  -        } else {
  -            classDir = this.servletContext.getRealPath("/WEB-INF/classes");
  -        }
  -
  -        if ((libDirPath != null) && !libDirPath.trim().equals("")) {
  -            root = new File(libDirPath);
  -        } else {
  -            root = new File(this.servletContext.getRealPath("/WEB-INF/lib"));
  -        }
  -
  -        addClassLoaderDirectory(classDir);
  -
  -        buildClassPath.append(classDir);
  -
  -        if (root.isDirectory()) {
  -            File[] libraries = root.listFiles();
  -
  -            for (int i = 0; i < libraries.length; i++) {
  -             String fullName = IOUtils.getFullFilename(libraries[i]);
  -                buildClassPath.append(File.pathSeparatorChar).append(fullName);
  -
  -                addClassLoaderDirectory(fullName);
  -            }
  -        }
  -
  -        buildClassPath.append(File.pathSeparatorChar)
  -                      .append(System.getProperty("java.class.path"));
  -
  -        buildClassPath.append(File.pathSeparatorChar)
  -                      .append(getExtraClassPath());
  -
  -        return buildClassPath.toString();
  -     }
  -
  -    /**
  -     * Adds an URL to the classloader.
  -     */
  -    protected void addClassLoaderURL(URL url) {
  -        try {
  -            this.repositoryLoader.addURL(url);
  -        } catch (Exception e) {
  -            if (log.isDebugEnabled()) {
  -                log.debug("Could not add URL" + url, e);
  -            }
  -        }
  -    }
  -
  -    /**
  -     * Adds a directory to the classloader.
  -     */
  -    protected void addClassLoaderDirectory(String dir) {
  -        try {
  -            this.repositoryLoader.addDirectory(new File(dir));
  -        } catch (Exception e) {
  -            if (log.isDebugEnabled()) {
  -                log.debug("Could not add directory" + dir, e);
  -            }
  -        }
  -    }
  +     public void init(ServletConfig config) throws ServletException {
  +             
  +             super.init(config);
  +
  +             // Create the classloader in which we will load the servlet
  +             this.classloader = getClassLoader(this.getContextDir());
  +        
  +        // Create the servlet
  +             try {
  +                     Class servletClass = this.classloader.loadClass(SERVLET_CLASS);
  +            
  +                     this.servlet = (Servlet)servletClass.newInstance();
  +
  +             } catch(Exception e) {
  +                     throw new ServletException("Cannot load servlet " + 
SERVLET_CLASS, e);
  +             }
  +        
  +             // Always set the context classloader. JAXP uses it to find a 
ParserFactory,
  +             // and thus fails if it's not set to the webapp classloader.
  +             Thread.currentThread().setContextClassLoader(this.classloader);
  +        
  +             // Inlitialize the actual servlet
  +             initServlet(servlet);
  +        
  +     }
  +     
  +     /**
  +      * Initialize the wrapped servlet. Subclasses (see [EMAIL PROTECTED] 
BootstrapServlet} change the
  +      * <code>ServletConfig</code> given to the servlet.
  +      * 
  +      * @param servlet the servlet to initialize
  +      * @throws ServletException
  +      */
  +     protected void initServlet(Servlet servlet) throws ServletException {
  +             this.servlet.init(getServletConfig());
  +     }
  +     
  +     /**
  +      * Get the web application context directory.
  +      * 
  +      * @return the context dir
  +      * @throws ServletException
  +      */
  +     protected File getContextDir() throws ServletException {
  +             String result = getServletContext().getRealPath("/");
  +             if (result == null) {
  +                     throw new ServletException(this.getClass().getName() + " 
cannot run in an undeployed WAR file");
  +             }
  +             return new File(result);
  +     }
  +    
  +     /**
  +      * Get the classloader that will be used to create the actual servlet. Its 
classpath is defined
  +      * by the WEB-INF/classes and WEB-INF/lib directories in the context dir.
  +      */
  +     private ClassLoader getClassLoader(File contextDir) throws ServletException {
  +             List urlList = new ArrayList();
  +        
  +             try {
  +                     File classDir = new File(contextDir + "/WEB-INF/classes");
  +                     if (classDir.exists()) {
  +                             if (!classDir.isDirectory()) {
  +                                     throw new ServletException(classDir + " exists 
but is not a directory");
  +                             }
  +            
  +                             URL classURL = classDir.toURL();
  +                             log("Adding class directory " + classURL);
  +                             urlList.add(classURL);
  +                
  +                     }
  +            
  +            // List all .jar and .zip
  +                     File libDir = new File(contextDir + "/WEB-INF/lib");
  +                     File[] libraries = libDir.listFiles(
  +                             new FilenameFilter() {
  +                     public boolean accept(File dir, String name) {
  +                         return name.endsWith(".zip") || name.endsWith(".jar");
  +                     }
  +                             }
  +                     );
  +
  +                     for (int i = 0; i < libraries.length; i++) {
  +                             URL lib = libraries[i].toURL();
  +                             log("Adding class library " + lib);
  +                             urlList.add(lib);
  +                     }
  +             } catch (MalformedURLException mue) {
  +                     throw new ServletException(mue);
  +             }
  +        
  +             URL[] urls = (URL[])urlList.toArray(new URL[urlList.size()]);
  +        
  +             return ParanoidClassLoader.newInstance(urls, 
this.getClass().getClassLoader());
  +     }
  +    
  +     /**
  +      * Service the request by delegating the call to the real servlet
  +      */
  +     public void service(ServletRequest request, ServletResponse response)
  +       throws ServletException, IOException {
  +
  +             Thread.currentThread().setContextClassLoader(this.classloader);
  +             this.servlet.service(request, response);
  +     }
  +    
  +     /**
  +      * Destroy the actual servlet
  +      */
  +     public void destroy() {
  +
  +             Thread.currentThread().setContextClassLoader(this.classloader);
  +             this.servlet.destroy();
  +
  +             super.destroy();
  +     }
   }
   
  
  
  

Reply via email to