bloritsch    00/12/06 15:52:43

  Modified:    src/org/apache/cocoon/servlet Tag: xml-cocoon2
                        CocoonServlet.java
               webapp/WEB-INF Tag: xml-cocoon2 web.xml
  Log:
  Added "log-level" support for CocoonServlet and restructured CocoonServlet 
for maintenance reasons. (Does not alter the public interface at all)
  
  Revision  Changes    Path
  No                   revision
  
  
  No                   revision
  
  
  1.1.4.36  +197 -100  
xml-cocoon/src/org/apache/cocoon/servlet/Attic/CocoonServlet.java
  
  Index: CocoonServlet.java
  ===================================================================
  RCS file: 
/home/cvs/xml-cocoon/src/org/apache/cocoon/servlet/Attic/CocoonServlet.java,v
  retrieving revision 1.1.4.35
  retrieving revision 1.1.4.36
  diff -u -r1.1.4.35 -r1.1.4.36
  --- CocoonServlet.java        2000/12/06 19:19:58     1.1.4.35
  +++ CocoonServlet.java        2000/12/06 23:52:41     1.1.4.36
  @@ -51,12 +51,13 @@
    *         (Apache Software Foundation, Exoffice Technologies)
    * @author <a href="mailto:[EMAIL PROTECTED]">Stefano Mazzocchi</a>
    * @author <a href="mailto:[EMAIL PROTECTED]">Nicola Ken Barozzi</a> Aisa
  - * @version CVS $Revision: 1.1.4.35 $ $Date: 2000/12/06 19:19:58 $
  + * @author <a href="mailto:[EMAIL PROTECTED]">Berin Loritsch</a>
  + * @version CVS $Revision: 1.1.4.36 $ $Date: 2000/12/06 23:52:41 $
    */
   
   public class CocoonServlet extends HttpServlet {
   
  -    private Logger log = null;
  +    private Logger log;
   
       final long second = 1000;
       final long minute = 60 * second;
  @@ -71,106 +72,196 @@
       private String workDir;
   
       /**
  -     * Initialize this <code>CocoonServlet</code> instance.
  +     * Initialize this <code>CocoonServlet</code> instance.  You will
  +     * notice that I have broken the init into sub methods to make it
  +     * easier to maintain (BL).  The context is passed to a couple of
  +     * the subroutines.  This is also because it is better to explicitly
  +     * pass variables than implicitely.  It is both more maintainable,
  +     * and more elegant.
  +     *
  +     * @param conf The ServletConfig object from the servlet engine.
  +     *
  +     * @throws ServletException
        */
  -    public void init(ServletConfig conf) throws ServletException {
  +    public void init(ServletConfig conf)
  +    throws ServletException {
   
           super.init(conf);
   
           this.context = conf.getServletContext();
   
  +        this.initLogger(conf.getInitParameter("log-level"), this.context);
  +
  +        this.setClassPath(conf.getInitParameter("classpath-attribute"), 
this.context);
  +
  +        this.forceLoad(conf.getInitParameter("force-load"));
  +
  +        this.setWorkDir((File) 
this.context.getAttribute("javax.servlet.context.tempdir"));
  +
  +        this.setConfigFile(conf.getInitParameter("configurations"), 
this.context);
  +
  +        this.createCocoon();
  +    }
  +
  +    /**
  +     * WARNING (SM): the lines below BREAKS the Servlet API portability of
  +     * web applications.
  +     *
  +     * This is a hack to go around java compiler design problems that
  +     * do not allow applications to force their own classloader to the
  +     * compiler during compilation.
  +     *
  +     * We look for a specific Tomcat attribute so we are bound to Tomcat
  +     * this means Cocoon won't be able to compile things if the necessary
  +     * classes are not already present in the *SYSTEM* classpath, any other
  +     * container classloading will break it on other servlet containers.
  +     * To fix this, Javac must be redesigned and rewritten or we have to
  +     * write our own compiler.
  +     *
  +     * So, for now, the cocoon.war file with included libraries can work
  +     * only in Tomcat or in containers that simulate this context attribute
  +     * (I don't know if any do) or, for other servlet containers, you have
  +     * to extract all the libraries and place them in the system classpath
  +     * or the compilation of sitemaps and XSP will fail.
  +     * I know this sucks, but I don't have the energy to write a java
  +     * compiler to fix this :(
  +     *
  +     * This solution is to allow you to specify the servlet ClassPath
  +     * attribute so that Cocoon can use it.  If your files are in the
  +     * system classpath, then we are still ok.  For these popular
  +     * servlet containers, we will provide you with the attribute name:
  +     *
  +     * Catalina (Tomcat 4.x) = "org.apache.catalina.jsp_classpath"
  +     * Tomcat (3.x)          = "org.apache.tomcat.jsp_classpath"
  +     * Resin                 = "caucho.class.path"
  +     * WebSphere (3.5 sp2)   = 
"com.ibm.websphere.servlet.application.classpath"
  +     *
  +     * For other servlet containers, please consult your manuals or
  +     * put Cocoon in the System Classpath.
  +     *
  +     * @param classpathAttribute The classpath attribute to lookup.
  +     * @param context            The ServletContext to perform the lookup.
  +     *
  +     * @throws ServletException
  +     */
  +     private void setClassPath(final String classpathAttribute, final 
ServletContext context)
  +     throws ServletException {
  +        if (classpathAttribute != null) {
  +            this.classpath = (String) 
context.getAttribute(classpathAttribute.trim());
  +        } else {
  +            this.classpath = System.getProperty("java.class.path");
  +        }
  +     }
  +
  +    /**
  +     * Set up the log level and path.  The default log level is
  +     * Priority.DEBUG, although it can be overwritten by the parameter
  +     * "log-level".  The log system goes to both a file and the Servlet
  +     * container's log system.  Only messages that are Priority.ERROR
  +     * and above go to the servlet context.  The log messages can
  +     * be as restrictive (Priority.FATAL_ERROR and above) or as liberal
  +     * (Priority.DEBUG and above) as you want that get routed to the
  +     * file.
  +     *
  +     * @param logLevel The minimum log message handling priority.
  +     * @param context  The ServletContext for the real path.
  +     *
  +     * @throws ServletException
  +     */
  +    private void initLogger(final String logLevel, final ServletContext 
context)
  +    throws ServletException {
  +        final Priority.Enum logPriority;
  +
  +        if (logLevel != null) {
  +            logPriority = LogKit.getPriorityForName(logLevel);
  +        } else {
  +            logPriority = Priority.DEBUG;
  +        }
  +
           try {
  -            String path = this.context.getRealPath("/") +
  +            final String path = context.getRealPath("/") +
                             "/WEB-INF/logs/cocoon.log";
   
  -            Category cocoonCategory = LogKit.createCategory("cocoon", 
Priority.DEBUG);
  +            final Category cocoonCategory = LogKit.createCategory("cocoon", 
logPriority);
               log = LogKit.createLogger(cocoonCategory, new LogTarget[] {
                       new FileOutputLogTarget(path),
  -                    new ServletLogTarget(this.context, Priority.ERROR)
  +                    new ServletLogTarget(context, Priority.ERROR)
                   });
           } catch (Exception e) {
               LogKit.log("Could not set up Cocoon Logger, will use screen 
instead", e);
           }
   
  -        LogKit.setGlobalPriority(Priority.DEBUG);
  +        LogKit.setGlobalPriority(logPriority);
  +    }
   
  -        /* WARNING (SM): the lines below BREAKS the Servlet API portability 
of
  -         * web applications.
  -         *
  -         * This is a hack to go around java compiler design problems that
  -         * do not allow applications to force their own classloader to the
  -         * compiler during compilation.
  -         *
  -         * We look for a specific Tomcat attribute so we are bound to Tomcat
  -         * this means Cocoon won't be able to compile things if the necessary
  -         * classes are not already present in the *SYSTEM* classpath, any 
other
  -         * container classloading will break it on other servlet containers.
  -         * To fix this, Javac must be redesigned and rewritten or we have to
  -         * write our own compiler.
  -         *
  -         * So, for now, the cocoon.war file with included libraries can work
  -         * only in Tomcat or in containers that simulate this context 
attribute
  -         * (I don't know if any do) or, for other servlet containers, you 
have
  -         * to extract all the libraries and place them in the system 
classpath
  -         * or the compilation of sitemaps and XSP will fail.
  -         * I know this sucks, but I don't have the energy to write a java
  -         * compiler to fix this :(
  -         *
  -         * This solution is to allow you to specify the servlet ClassPath
  -         * attribute so that Cocoon can use it.  If your files are in the
  -         * system classpath, then we are still ok.  For these popular
  -         * servlet containers, we will provide you with the attribute name:
  -         *
  -         * Catalina (Tomcat 4.x) = "org.apache.catalina.jsp_classpath"
  -         * Tomcat (3.x)          = "org.apache.tomcat.jsp_classpath"
  -         * Resin                 = "caucho.class.path"
  -         * WebSphere (3.5 sp2)   = 
"com.ibm.websphere.servlet.application.classpath"
  -         *
  -         * For other servlet containers, please consult your manuals or
  -         * put Cocoon in the System Classpath.
  -         */
  -        String servletClassPath = 
conf.getInitParameter("classpath-attribute");
  -        if (servletClassPath != null) {
  -            this.classpath = (String) context.getAttribute(servletClassPath);
  +    /**
  +     * Set the ConfigFile for the Cocoon object.
  +     *
  +     * @param configFileName The file location for the cocoon.xconf
  +     * @param context        The servlet context to get the file handle
  +     *
  +     * @throws ServletException
  +     */
  +    private void setConfigFile(final String configFileName, final 
ServletContext context)
  +    throws ServletException {
  +        if (configFileName == null) {
  +            throw new ServletException("Servlet initialization argument 
'configurations' not specified");
           }
   
  -        this.workDir = ((File) 
this.context.getAttribute("javax.servlet.context.tempdir")).toString();
  +        log.info("Using configuration file: " + configFileName);
   
  -        String forceLoading = conf.getInitParameter("force-load");
  +        try {
  +            this.configFile = new 
File(context.getResource(configFileName).getFile());
  +        } catch (Exception mue) {
  +            log.error("Servlet initialization argument 'configurations' not 
found at " + configFileName, mue);
  +            throw new ServletException("Servlet initialization argument 
'configurations' not found at " + configFileName);
  +        }
  +    }
  +
  +    /**
  +     *  Set up the Work Directory (where things get compiled).
  +     *
  +     * @param workDir the File handle for the work directory
  +     *
  +     * @throws ServletException
  +     */
  +    private void setWorkDir(final File workDir)
  +    throws ServletException {
  +        this.workDir = workDir.toString();
  +    }
  +
  +    /**
  +     * Handle the "force-load" parameter.  This overcomes limits in
  +     * many classpath issues.  One of the more notorious ones is a
  +     * bug in WebSphere that does not load the URL handler for the
  +     * "classloader://" protocol.  In order to overcome that bug,
  +     * set "force-load" to "com.ibm.servlet.classloader.Handler".
  +     *
  +     * If you need to force more than one class to load, then
  +     * separate each entry with a comma.  Cocoon will strip any
  +     * whitespace from the entry.
  +     *
  +     * @param forceLoading The array of fully qualified classes to force 
loading.
  +     *
  +     * @throws ServletException
  +     */
  +    private void forceLoad(final String forceLoading)
  +    throws ServletException {
           if (forceLoading != null) {
               StringTokenizer fqcnTokenizer = new 
StringTokenizer(forceLoading, ",", false);
   
               while (fqcnTokenizer.hasMoreTokens()) {
  -                String fqcn = fqcnTokenizer.nextToken();
  +                final String fqcn = fqcnTokenizer.nextToken().trim();
   
                   try {
                       Class.forName(fqcn);
                   } catch (Exception e) {
                       log.error("Could not force-load class: " + fqcn, e);
  -                    this.context.log("Could not force-load  class: " + fqcn, 
e);
                       throw new ServletException("Could not force-load the 
required class: " +
                                 fqcn + "\n" + e.getMessage(), e);
                   }
               }
           }
  -
  -        String configFileName = conf.getInitParameter("configurations");
  -        if (configFileName == null) {
  -            throw new ServletException("Servlet initialization argument 
'configurations' not specified");
  -        } else {
  -            log.info("Using configuration file: " + configFileName);
  -            this.context.log("Using configuration file: " + configFileName);
  -        }
  -
  -        try {
  -            this.configFile = new 
File(this.context.getResource(configFileName).getFile());
  -        } catch (Exception mue) {
  -            this.context.log("Servlet initialization argument 
'configurations' not found at " + configFileName, mue);
  -            log.error("Servlet initialization argument 'configurations' not 
found at " + configFileName, mue);
  -            throw new ServletException("Servlet initialization argument 
'configurations' not found at " + configFileName);
  -        }
  -
  -        this.cocoon = this.create();
       }
   
       /**
  @@ -178,33 +269,12 @@
        * on the specified <code>HttpServletResponse</code>.
        */
       public void service(HttpServletRequest req, HttpServletResponse res)
  -            throws ServletException, IOException {
  +    throws ServletException, IOException {
   
  -        long start = System.currentTimeMillis();
  +        // This is more scalable
  +        long start = new Date().getTime();
   
  -        // Reload cocoon if configuration changed or we are reloading
  -        boolean reloaded = false;
  -
  -        synchronized (this) {
  -            if (this.cocoon != null) {
  -                if (this.cocoon.modifiedSince(this.creationTime)) {
  -                    log.info("Configuration changed reload attempt");
  -                    this.context.log("Configuration changed reload attempt");
  -                    this.cocoon = this.create();
  -                    reloaded    = true;
  -                } else if ((req.getPathInfo() == null) && 
(req.getParameter(Cocoon.RELOAD_PARAM) != null)) {
  -                    log.info("Forced reload attempt");
  -                    this.context.log("Forced reload attempt");
  -                    this.cocoon = this.create();
  -                    reloaded    = true;
  -                }
  -            } else if ((req.getPathInfo() == null) && 
(req.getParameter(Cocoon.RELOAD_PARAM) != null)) {
  -                log.info("Invalid configurations reload");
  -                this.context.log("Invalid configurations reload");
  -                this.cocoon = this.create();
  -                reloaded    = true;
  -            }
  -        }
  +        Cocoon cocoon = getCocoon(req.getPathInfo(), 
req.getParameter(Cocoon.RELOAD_PARAM));
   
           // Check if cocoon was initialized
           if (this.cocoon == null) {
  @@ -248,7 +318,7 @@
                   uri = uri.substring(1);
               }
   
  -            HttpEnvironment env = new HttpEnvironment(uri, req, res, 
context);
  +            HttpEnvironment env = new HttpEnvironment(uri, req, res, 
this.context);
   
               if (!this.cocoon.process(env)) {
   
  @@ -299,18 +369,19 @@
           out.flush();
       }
   
  -    private Cocoon create() {
  +    /**
  +     * Creates the Cocoon object and handles exception handling.
  +     */
  +    private void createCocoon() {
           try {
               log.info("Reloading from: " + this.configFile);
  -            this.context.log("Reloading from: " + this.configFile);
               Cocoon c = new Cocoon(this.configFile, this.classpath, 
this.workDir);
  -            this.creationTime = System.currentTimeMillis();
  -            return c;
  +            this.creationTime = new Date().getTime();
  +            this.cocoon = c;
           } catch (Exception e) {
               log.error("Exception reloading", e);
  -            this.context.log("Exception reloading: " + e.getMessage());
               this.exception = e;
  -            return null;
  +            this.cocoon = null;
           }
       }
   
  @@ -335,6 +406,32 @@
           }
   
           return out.toString();
  +    }
  +
  +    /**
  +     * Gets the current cocoon object.  Reload cocoon if configuration
  +     * changed or we are reloading.
  +     *
  +     * @returns Cocoon
  +     */
  +    private synchronized Cocoon getCocoon(final String pathInfo, final 
String reloadParam) {
  +        if (this.cocoon != null) {
  +            if (this.cocoon.modifiedSince(this.creationTime)) {
  +                log.info("Configuration changed reload attempt");
  +                this.createCocoon();
  +                return this.cocoon;
  +            } else if ((pathInfo == null) && (reloadParam != null)) {
  +                log.info("Forced reload attempt");
  +                this.createCocoon();
  +                return this.cocoon;
  +            }
  +        } else if ((pathInfo == null) && (reloadParam != null)) {
  +            log.info("Invalid configurations reload");
  +            this.createCocoon();
  +            return this.cocoon;
  +        }
  +
  +        return this.cocoon;
       }
   }
   
  
  
  
  No                   revision
  
  
  No                   revision
  
  
  1.1.2.4   +4 -0      xml-cocoon/webapp/WEB-INF/Attic/web.xml
  
  Index: web.xml
  ===================================================================
  RCS file: /home/cvs/xml-cocoon/webapp/WEB-INF/Attic/web.xml,v
  retrieving revision 1.1.2.3
  retrieving revision 1.1.2.4
  diff -u -r1.1.2.3 -r1.1.2.4
  --- web.xml   2000/12/06 20:46:09     1.1.2.3
  +++ web.xml   2000/12/06 23:52:42     1.1.2.4
  @@ -30,6 +30,10 @@
           IBM:      com.ibm.websphere.servlet.application.classpath
      -->
     </init-param>
  +  <init-param>
  +   <param-name>log-level</param-name>
  +   <param-value>DEBUG</param-value>
  +  </init-param>
    </servlet>
    <servlet-mapping>
     <servlet-name>Cocoon2</servlet-name>
  
  
  

Reply via email to