Package org.apache.tomcat.core

Source Code of org.apache.tomcat.core.StandardWrapper

/*
* $Header: /home/cvs/jakarta-tomcat/proposals/catalina/src/share/org/apache/tomcat/core/StandardWrapper.java,v 1.4 2000/02/08 05:43:36 craigmcc Exp $
* $Revision: 1.4 $
* $Date: 2000/02/08 05:43:36 $
*
* ====================================================================
*
* The Apache Software License, Version 1.1
*
* Copyright (c) 1999 The Apache Software Foundation.  All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
*    notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
*    notice, this list of conditions and the following disclaimer in
*    the documentation and/or other materials provided with the
*    distribution.
*
* 3. The end-user documentation included with the redistribution, if
*    any, must include the following acknowlegement: 
*       "This product includes software developed by the
*        Apache Software Foundation (http://www.apache.org/)."
*    Alternately, this acknowlegement may appear in the software itself,
*    if and wherever such third-party acknowlegements normally appear.
*
* 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
*    Foundation" must not be used to endorse or promote products derived
*    from this software without prior written permission. For written
*    permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache"
*    nor may "Apache" appear in their names without prior written
*    permission of the Apache Group.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation.  For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
* [Additional notices, if required by prior licensing conditions]
*
*/


package org.apache.tomcat.core;


import java.io.IOException;
import java.util.Enumeration;
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;


/**
* 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.4 $ $Date: 2000/02/08 05:43:36 $
*/

public final class StandardWrapper
    extends ContainerBase
    implements ServletConfig, Wrapper {


    // ----------------------------------------------------------- Constructors


    /**
     * Create a new StandardWrapper component with the default basic Valve.
     */
    public StandardWrapper() {

  super();
  setBasic(new StandardWrapperValve());

    }


    // ----------------------------------------------------- Instance Variables


    /**
     * Has our SingleThreadModel servlet instance been allocated already?
     */
    private boolean allocated = false;


    /**
     * The descriptive information string for this implementation.
     */
    private static final String info =
  "org.apache.tomcat.core.StandardWrapper/1.0";


    /**
     * 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;


    /**
     * The load-on-startup order value (negative value means load on
     * first call) for this servlet.
     */
    private int loadOnStartup = -1;


    /**
     * The initialization parameters for this servlet, keyed by
     * parameter name.
     */
    private Hashtable parameters = new Hashtable();


    /**
     * The security role references for this servlet, keyed by role name
     * used in the servlet.  The corresponding value is the role name of
     * the web application itself.
     */
    private Hashtable references = new Hashtable();


    /**
     * The fully qualified servlet class name for this servlet.
     */
    private String servletClass = null;


    /**
     * Does this servlet implement the SingleThreadModel interface?
     */
    private boolean singleThreadModel = false;


    // ------------------------------------------------------------- Properties


    /**
     * Return descriptive information about this Container implementation and
     * the corresponding version number, in the format
     * <code>&lt;description&gt;/&lt;version&gt;</code>.
     */
    public String getInfo() {

  return (info);

    }


    /**
     * Return the context-relative URI of the JSP file for this servlet.
     */
    public String getJspFile() {

  return (this.jspFile);

    }


    /**
     * Set the context-relative URI of the JSP file for this servlet.
     *
     * @param jspFile JSP file URI
     */
    public void setJspFile(String jspFile) {

  String oldJspFile = this.jspFile;
  this.jspFile = jspFile;
  support.firePropertyChange("jspFile", oldJspFile, this.jspFile);

    }


    /**
     * Return the load-on-startup order value (negative value means
     * load on first call).
     */
    public int getLoadOnStartup() {

  return (this.loadOnStartup);

    }


    /**
     * Set the load-on-startup order value (negative value means
     * load on first call).
     *
     * @param value New load-on-startup value
     */
    public void setLoadOnStartup(int value) {

  int oldLoadOnStartup = this.loadOnStartup;
  this.loadOnStartup = value;
  support.firePropertyChange("loadOnStartup",
           new Integer(oldLoadOnStartup),
           new Integer(this.loadOnStartup));

    }



    /**
     * Set the parent Container of this Wrapper, but only if it is a Context.
     *
     * @param container Proposed parent Container
     */
    public void setParent(Container container) {

  if (!(container instanceof Context))
      throw new IllegalArgumentException
    (sm.getString("standardWrapper.notContext"));
  super.setParent(container);

    }


    /**
     * Return the fully qualified servlet class name for this servlet.
     */
    public String getServletClass() {

  return (this.servletClass);

    }


    /**
     * Set the fully qualified servlet class name for this servlet.
     *
     * @param servletClass Servlet class name
     */
    public void setServletClass(String servletClass) {

  String oldServletClass = this.servletClass;
  this.servletClass = servletClass;
  support.firePropertyChange("servletClass", oldServletClass,
           this.servletClass);

    }



    /**
     * 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


    /**
     * Refuse to add a child Container, because Wrappers are the lowest level
     * of the Container hierarchy.
     *
     * @param child Child container to be added
     */
    public void addChild(Container child) {

  throw new IllegalStateException
      (sm.getString("standardWrapper.noChild"));

    }


    /**
     * Add a new servlet initialization parameter for this servlet.
     *
     * @param name Name of this initialization parameter to add
     * @param value Value of this initialization parameter to add
     */
    public void addInitParameter(String name, String value) {

  parameters.put(name, value);
  fireContainerEvent("addInitParameter", name);

    }


    /**
     * Add a new security role reference record to the set of records for
     * this servlet.
     *
     * @param name Role name used within this servlet
     * @param link Role name used within the web application
     */
    public void addSecurityReference(String name, String link) {

  references.put(name, link);
  fireContainerEvent("addSecurityReference", name);

    }



    /**
     * Allocate an initialized instance of this Servlet that is ready to have
     * its <code>service()</code> method called.  If the servlet class does
     * not implement <code>SingleThreadModel</code>, the (only) initialized
     * instance may be returned immediately.  If the servlet class implements
     * <code>SingleThreadModel</code>, the Wrapper implementation must ensure
     * that this instance is not allocated again until it is deallocated by a
     * call to <code>deallocate()</code>.
     * <p>
     * <b>FIXME:  Provide a way to avoid waiting forever.</b>
     */
    public Servlet 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);
  }

    }


    /**
     * Return this previously allocated servlet to the pool of available
     * instances.  If this servlet class does not implement SingleThreadModel,
     * no action is actually required.
     *
     * @param servlet The servlet to be returned
     */
    public void deallocate(Servlet servlet) {

  // If not SingleThreadModel, no action is required
  if (!singleThreadModel)
      return;

  // Unlock and free this instance
  synchronized (instance) {
      allocated = false;
      instance.notify();
  }

    }


    /**
     * Return the value for the specified initialization parameter name,
     * if any; otherwise return <code>null</code>.
     *
     * @param name Name of the requested initialization parameter
     */
    public String findInitParameter(String name) {

  return ((String) parameters.get(name));

    }


    /**
     * Return the names of all defined initialization parameters for this
     * servlet.
     */
    public String[] findInitParameters() {

  synchronized (parameters) {
      String results[] = new String[parameters.size()];
      int n = 0;
      Enumeration names = parameters.keys();
      while (names.hasMoreElements()) {
    results[n++] = (String) names.nextElement();
      }
      return (results);
  }

    }


    /**
     * Return the security role link for the specified security role
     * reference name, if any; otherwise return <code>null</code>.
     *
     * @param name Security role reference used within this servlet
     */
    public String findSecurityReference(String name) {

  return ((String) references.get(name));

    }


    /**
     * Return the set of security role reference names associated with
     * this servlet, if any; otherwise return a zero-length array.
     */
    public String[] findSecurityReferences() {

  synchronized (references) {
      String results[] = new String[references.size()];
      int n = 0;
      Enumeration names = references.keys();
      while (names.hasMoreElements()) {
    results[n++] = (String) names.nextElement();
      }
      return (results);
  }

    }


    /**
     * Load and initialize an instance of this servlet, if there is not already
     * at least one initialized instance.  This can be used, for example, to
     * load servlets that are marked in the deployment descriptor to be loaded
     * at server startup time.
     *
     * @exception ServletException if thrown by the init() method of the
     *  loaded servlet
     */
    public synchronized void load() throws ServletException {

  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);

    }


    /**
     * Remove the specified initialization parameter from this servlet.
     *
     * @param name Name of the initialization parameter to remove
     */
    public void removeInitParameter(String name) {

  if (parameters.get(name) != null) {
      parameters.remove(name);
      fireContainerEvent("removeInitParameter", name);
  }

    }


    /**
     * Remove any security role reference for the specified role name.
     *
     * @param name Security role used within this servlet to be removed
     */
    public void removeSecurityReference(String name) {

  if (references.get(name) != null) {
      references.remove(name);
      fireContainerEvent("removeSecurityReference", name);
  }

    }


    /**
     * Unload all initialized instances of this servlet, after calling the
     * <code>destroy()</code> method for each instance.  This can be used,
     * 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 Enumeration getInitParameterNames() {

  Vector results = new Vector();
  String names[] = findInitParameters();
  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();

    }


}
TOP

Related Classes of org.apache.tomcat.core.StandardWrapper

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.