You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by cr...@locus.apache.org on 2000/02/07 07:08:58 UTC

cvs commit: jakarta-tomcat/proposals/catalina/src/share/org/apache/tomcat/core LocalStrings.properties StandardWrapper.java

craigmcc    00/02/06 22:08:58

  Modified:    proposals/catalina/src/share/org/apache/tomcat/core
                        LocalStrings.properties StandardWrapper.java
  Log:
  Flesh out the implementation of StandardWrapper.  This component is
  responsible for managing a single servlet definition, as well as the
  lifecycle of the servlet instance that it creates.
  
  The current implementation does not support a pool of SingleThreadModel
  instances, although the Wrapper interface allows for this.  IMHO,
  encouraging people to use STM (by improving the performance of
  simultaneous requests) is not something we should be doing.
  
  Revision  Changes    Path
  1.5       +2 -0      jakarta-tomcat/proposals/catalina/src/share/org/apache/tomcat/core/LocalStrings.properties
  
  Index: LocalStrings.properties
  ===================================================================
  RCS file: /home/cvs/jakarta-tomcat/proposals/catalina/src/share/org/apache/tomcat/core/LocalStrings.properties,v
  retrieving revision 1.4
  retrieving revision 1.5
  diff -u -r1.4 -r1.5
  --- LocalStrings.properties	2000/01/30 06:56:20	1.4
  +++ LocalStrings.properties	2000/02/07 06:08:57	1.5
  @@ -21,3 +21,5 @@
   standardResources.malformedPath=Path must start with '/'
   standardResources.malformedURL=Malformed URL
   standardWrapper.noChild=Wrapper cannot have a child Container
  +standardWrapper.noLoader=Wrapper cannot find the Loader to use
  +standardWrapper.noServlet=No servlet class has been configured
  
  
  
  1.2       +233 -11   jakarta-tomcat/proposals/catalina/src/share/org/apache/tomcat/core/StandardWrapper.java
  
  Index: StandardWrapper.java
  ===================================================================
  RCS file: /home/cvs/jakarta-tomcat/proposals/catalina/src/share/org/apache/tomcat/core/StandardWrapper.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- StandardWrapper.java	2000/01/30 06:56:20	1.1
  +++ StandardWrapper.java	2000/02/07 06:08:57	1.2
  @@ -1,7 +1,7 @@
   /*
  - * $Header: /home/cvs/jakarta-tomcat/proposals/catalina/src/share/org/apache/tomcat/core/StandardWrapper.java,v 1.1 2000/01/30 06:56:20 craigmcc Exp $
  - * $Revision: 1.1 $
  - * $Date: 2000/01/30 06:56:20 $
  + * $Header: /home/cvs/jakarta-tomcat/proposals/catalina/src/share/org/apache/tomcat/core/StandardWrapper.java,v 1.2 2000/02/07 06:08:57 craigmcc Exp $
  + * $Revision: 1.2 $
  + * $Date: 2000/02/07 06:08:57 $
    *
    * ====================================================================
    *
  @@ -70,10 +70,16 @@
   import java.util.Hashtable;
   import java.util.Vector;
   import javax.servlet.Servlet;
  +import javax.servlet.ServletConfig;
  +import javax.servlet.ServletContext;
   import javax.servlet.ServletException;
  +import javax.servlet.SingleThreadModel;
   import javax.servlet.http.HttpServletResponse;
   import org.apache.tomcat.Container;
   import org.apache.tomcat.Context;
  +import org.apache.tomcat.Lifecycle;
  +import org.apache.tomcat.LifecycleException;
  +import org.apache.tomcat.Loader;
   import org.apache.tomcat.Request;
   import org.apache.tomcat.Response;
   import org.apache.tomcat.Wrapper;
  @@ -83,14 +89,19 @@
    * Standard implementation of the <b>Wrapper</b> interface that represents
    * an individual servlet definition.  No child Containers are allowed, and
    * the parent Container must be a Context.
  + * <p>
  + * <b>IMPLEMENTATION NOTE</b>:  This implementation does <i>not</i> support
  + * a pool of instances for servlets that implement SingleThreadModel.  IMHO
  + * developers should not be encouraged to use this technique, so efforts to
  + * make them efficient are counter-productive.
    *
    * @author Craig R. McClanahan
  - * @version $Revision: 1.1 $ $Date: 2000/01/30 06:56:20 $
  + * @version $Revision: 1.2 $ $Date: 2000/02/07 06:08:57 $
    */
   
   public final class StandardWrapper
       extends ContainerBase
  -    implements Wrapper {
  +    implements ServletConfig, Wrapper {
   
   
       // ----------------------------------------------------------- Constructors
  @@ -111,6 +122,12 @@
   
   
       /**
  +     * Has our SingleThreadModel servlet instance been allocated already?
  +     */
  +    private boolean allocated = false;
  +
  +
  +    /**
        * The descriptive information string for this implementation.
        */
       private static final String info =
  @@ -118,6 +135,12 @@
   
   
       /**
  +     * The (single) initialized instance of this servlet.
  +     */
  +    private Servlet instance = null;
  +
  +
  +    /**
        * The context-relative URI of the JSP file for this servlet.
        */
       private String jspFile = null;
  @@ -151,6 +174,12 @@
       private String servletClass = null;
   
   
  +    /**
  +     * Does this servlet implement the SingleThreadModel interface?
  +     */
  +    private boolean singleThreadModel = false;
  +
  +
       // ------------------------------------------------------------- Properties
   
   
  @@ -260,6 +289,37 @@
   
   
   
  +    /**
  +     * Set the name of this servlet.  This is an alias for the normal
  +     * <code>Container.setName()</code> method, and complements the
  +     * <code>getServletName()</code> method required by the
  +     * <code>ServletConfig</code> interface.
  +     *
  +     * @param name The new name of this servlet
  +     */
  +    public void setServletName(String name) {
  +
  +	setName(name);
  +
  +    }
  +
  +
  +    /**
  +     * Return <code>true</code> if the servlet class represented by this
  +     * component implements the <code>SingleThreadModel</code> interface.
  +     */
  +    public boolean isSingleThreadModel() {
  +
  +	try {
  +	    load();
  +	} catch (ServletException e) {
  +	    ;
  +	}
  +	return (singleThreadModel);
  +
  +    }
  +
  +
       // --------------------------------------------------------- Public Methods
   
   
  @@ -320,8 +380,32 @@
        */
       public Servlet allocate() {
   
  -	return (null);	// FIXME - allocate()
  +	// Load and initialize our instance if necessary
  +	if (instance == null) {
  +	    try {
  +		load();
  +	    } catch (Exception e) {
  +		return (null);
  +	    }
  +	}
   
  +	// If not SingleThreadedModel, return the same instance every time
  +	if (!singleThreadModel)
  +	    return (instance);
  +
  +	// Lock and return this instance
  +	synchronized (instance) {
  +	    if (allocated) {
  +		try {
  +		    instance.wait();
  +		} catch (InterruptedException e) {
  +		    ;
  +		}
  +	    }
  +	    allocated = true;
  +	    return (instance);
  +	}
  +
       }
   
   
  @@ -334,7 +418,15 @@
        */
       public void deallocate(Servlet servlet) {
   
  -	;	// FIXME - deallocate()
  +	// If not SingleThreadModel, no action is required
  +	if (!singleThreadModel)
  +	    return;
  +
  +	// Unlock and free this instance
  +	synchronized (instance) {
  +	    allocated = false;
  +	    instance.notify();
  +	}
   
       }
   
  @@ -412,10 +504,37 @@
        * @exception ServletException if thrown by the init() method of the
        *  loaded servlet
        */
  -    public void load() throws ServletException {
  +    public synchronized void load() throws ServletException {
   
  -	;	// FIXME - load()
  +	if (instance != null)
  +	    return;
   
  +	// Complain if no servlet class has been specified
  +	// FIXME - support for JSP file servlets!!!
  +	if (servletClass == null)
  +	    throw new ServletException
  +		(sm.getString("standardWrapper.noServlet"));
  +
  +	// Acquire an instance of the class loader to be used
  +	Loader loader = ((Context) getParent()).getLoader();
  +	if (loader == null)
  +	    throw new ServletException
  +		(sm.getString("standardWrapper.noLoader"));
  +	ClassLoader classLoader = loader.getClassLoader();
  +
  +	// Load and initialize an instance of the specified servlet class
  +	try {
  +	    Class classClass = classLoader.loadClass(servletClass);
  +	    Servlet servlet = (Servlet) classClass.newInstance();
  +	    servlet.init((ServletConfig) this);
  +	    instance = servlet;
  +	} catch (Exception e) {
  +	    throw new ServletException("load: " + e);
  +	}
  +
  +	singleThreadModel = instance instanceof SingleThreadModel;
  +	fireContainerEvent("load", this);
  +
       }
   
   
  @@ -455,15 +574,118 @@
        * for example, prior to shutting down the entire servlet engine, or
        * prior to reloading all of the classes from the Loader associated with
        * our Loader's repository.
  +     */
  +    public synchronized void unload() {
  +
  +	if (instance == null)
  +	    return;
  +	instance.destroy();
  +	instance = null;
  +	fireContainerEvent("unload", this);
  +
  +    }
  +
  +
  +    // -------------------------------------------------- ServletConfig Methods
  +
  +
  +    /**
  +     * Return the initialization parameter value for the specified name,
  +     * if any; otherwise return <code>null</code>.
  +     *
  +     * @param name Name of the initialization parameter to retrieve
  +     */
  +    public String getInitParameter(String name) {
  +
  +	return (findInitParameter(name));
  +
  +    }
  +
  +
  +    /**
  +     * Return the set of initialization parameter names defined for this
  +     * servlet.  If none are defined, an empty Enumeration is returned.
        */
  -    public void unload() {
  +    public Enumeration getInitParameterNames() {
   
  -	;	// FIXME - unload()
  +	Vector results = new Vector();
  +	String names[] = findInitParameterNames();
  +	for (int i = 0; i < names.length; i++)
  +	    results.addElement(names[i]);
  +	return (results.elements());
   
       }
   
   
  +    /**
  +     * Return the servlet context with which this servlet is associated.
  +     */
  +    public ServletContext getServletContext() {
  +
  +	if (parent == null)
  +	    return (null);
  +	else if (!(parent instanceof Context))
  +	    return (null);
  +	else
  +	    return (((Context) parent).getServletContext());
  +
  +    }
  +
  +
  +    /**
  +     * Return the name of this servlet.
  +     */
  +    public String getServletName() {
  +
  +	return (getName());
  +
  +    }
  +
  +
       // -------------------------------------------------------- Private Methods
  +
  +
  +    // ------------------------------------------------------ Lifecycle Methods
  +
  +
  +    /**
  +     * Start this component, pre-loading the servlet if the load-on-startup
  +     * value is set appropriately.
  +     *
  +     * @exception LifecycleException if a fatal error occurs during startup
  +     */
  +    public void start() throws LifecycleException {
  +
  +	// Start up this component
  +	super.start();
  +
  +	// Load and initialize an instance of this servlet if requested
  +	if (loadOnStartup < 0)
  +	    return;
  +        try {
  +	    load();
  +	} catch (ServletException e) {
  +	    throw new LifecycleException("start:  " + e);
  +	}
  +
  +    }
  +
  +
  +    /**
  +     * Stop this component, gracefully shutting down the servlet if it has
  +     * been initialized.
  +     *
  +     * @exception LifecycleException if a fatal error occurs during shutdown
  +     */
  +    public void stop() throws LifecycleException {
  +
  +	// Shut down our servlet instance (if it has been initialized)
  +	unload();
  +
  +	// Shut down this component
  +	super.stop();
  +
  +    }
   
   
   }