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/01/20 07:35:26 UTC
cvs commit: jakarta-tomcat/proposals/catalina/src/share/org/apache/tomcat/core StandardContext.java StandardEngine.java StandardHost.java StandardResources.java ValveBase.java
craigmcc 00/01/19 22:35:26
Added: proposals/catalina/src/share/org/apache/tomcat/core
StandardContext.java StandardEngine.java
StandardHost.java StandardResources.java
ValveBase.java
Log:
Check-in #2 of the core component implementations for the
"Catalina" proposal.
Revision Changes Path
1.1 jakarta-tomcat/proposals/catalina/src/share/org/apache/tomcat/core/StandardContext.java
Index: StandardContext.java
===================================================================
/*
* $Header: /home/cvs/jakarta-tomcat/proposals/catalina/src/share/org/apache/tomcat/core/StandardContext.java,v 1.1 2000/01/20 06:35:25 craigmcc Exp $
* $Revision: 1.1 $
* $Date: 2000/01/20 06:35:25 $
*
* ====================================================================
*
* 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 javax.servlet.ServletContext;
import javax.servlet.ServletException;
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.Request;
import org.apache.tomcat.Response;
import org.apache.tomcat.Wrapper;
import org.apache.tomcat.deployment.WebApplicationDescriptor;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
/**
* Standard implementation of the <b>Context</b> interface. Each
* child container must be a Wrapper implementation to process the
* requests directed to a particular servlet.
* <p>
* Lifecycle configuration of this component assumes an XML node
* in the following format:
* <code>
* <Context className="org.apache.tomcat.core.StandardContext"
* path="xxx"/>
* </code>
* where you can adjust the following parameters, with default values
* in square brackets:
* <ul>
* <li><b>path</b> - Context path for URIs that are processed by this
* Context. Per the servlet API specification, you must define a
* Context with a path of "/", which serves as the default Context
* within a particular environment. [/]
* <li><b>FIXME - add other properties supported by Tomcat 3.0</b>.
* </ul>
*
* @author Craig R. McClanahan
* @version $Revision: 1.1 $ $Date: 2000/01/20 06:35:25 $
*/
public final class StandardContext
extends ContainerBase
implements Context, Lifecycle {
// ----------------------------------------------------- Instance Variables
/**
* Has this component been configured?
*/
private boolean configured = false;
/**
* The ServletContext implementation associated with this Context.
*/
private ApplicationContext context = null;
/**
* The web application deployment descriptor associated with this context.
*/
private WebApplicationDescriptor descriptor = null;
/**
* The descriptive information string for this implementation.
*/
private static final String info =
"org.apache.tomcat.core.StandardContext/1.0";
/**
* Has this component been started?
*/
private boolean started = false;
// ------------------------------------------------------------- Properties
/**
* Return the context configuration descriptor for this web application.
*/
public WebApplicationDescriptor getDescriptor() {
return (this.descriptor);
}
/**
* Set the context configuration descriptor for this web application.
*
* @param descriptor The new context configuration descriptor
*/
public void setDescriptor(WebApplicationDescriptor descriptor) {
this.descriptor = descriptor;
}
/**
* Return the context path for this Context.
*/
public String getPath() {
return (getName());
}
/**
* Set the context path for this Context.
* <p>
* <b>IMPLEMENTATION NOTE</b>: The context path is used as the "name" of
* a Context, because it must be unique.
*
* @param path The new context path
*/
public void setPath(String path) {
setName(path);
}
/**
* Return the servlet context for which this Context is a facade.
*/
public ServletContext getServletContext() {
if (context == null)
context = new ApplicationContext(this);
return (context);
}
// --------------------------------------------------------- Public Methods
/**
* Add a child Container, only if the proposed child is an implementation
* of Wrapper.
*
* @param child Child container to be added
*/
public void addChild(Container child) {
if (!(child instanceof Wrapper))
throw new IllegalArgumentException
(sm.getString("standardContext.notWrapper"));
super.addChild(child);
}
/**
* Return descriptive information about this Container implementation and
* the corresponding version number, in the format
* <code><description>/<version></code>.
*/
public String getInfo() {
return (info);
}
/**
* Return the Wrapper associated with the servlet that matches the
* specified context-relative URI, if any; otherwise return
* <code>null</code>.
*
* @param uri Context-relative URI, which must start with a "/"
*/
public Wrapper map(String uri) {
return (null); // FIXME - map() via servlet mappings
}
/**
* Select the appropriate child Wrapper to process this request,
* based on the specified request URI. If no matching Wrapper can
* be found, return an appropriate HTTP error.
*
* @param request Request to be processed
* @param response Response to be produced
*/
public void service(Request request, Response response)
throws IOException, ServletException {
// Select the Wrapper to be used for this Request
String path = request.getRequest().getRequestURI();
Wrapper wrapper = map(path);
if (wrapper == null) {
response.getResponse().sendError
(HttpServletResponse.SC_NOT_FOUND,
sm.getString("standardContext.notFound"));
return;
}
// Ask this Wrapper to process this Request
; // XXX - Tell the request which Wrapper we are using?
; // XXX - Would seem to be necesary to calculate getServletPath
wrapper.invoke(request, response);
}
// ------------------------------------------------------ Lifecycle Methods
/**
* Configure this component, based on the specified configuration
* parameters. This method should be called immediately after the
* component instance is created, and before <code>start()</code>
* is called.
*
* @param parameters Configuration parameters for this component
* (<B>FIXME: What object type should this really be?)
*
* @exception IllegalStateException if this component has already been
* configured and/or started
* @exception LifecycleException if this component detects a fatal error
* in the configuration parameters it was given
*/
public void configure(Node parameters)
throws LifecycleException {
// Validate and update our current component state
if (configured)
throw new LifecycleException
(sm.getString("standardContext.alreadyConfigured"));
configured = true;
if (parameters == null)
return;
// Parse and process our configuration parameters
if (!("Context".equals(parameters.getNodeName())))
return;
NamedNodeMap attributes = parameters.getAttributes();
Node node = null;
String value = null;
node = attributes.getNamedItem("path");
if (node != null) {
value = node.getNodeValue();
if (value != null)
setPath(value);
}
// Parse and process our subordinate components
subconfigure(parameters);
; // XXX - configure servlet definitions in descriptor?
}
/**
* Prepare for the beginning of active use of the public methods of this
* component. This method should be called after <code>configure()</code>,
* and before any of the public methods of the component are utilized.
*
* @exception IllegalStateException if this component has not yet been
* configured (if required for this component)
* @exception IllegalStateException if this component has already been
* started
* @exception LifecycleException if this component detects a fatal error
* that prevents this component from being used
*/
public void start() throws LifecycleException {
// Validate and update our current component state
if (!configured)
throw new LifecycleException
(sm.getString("standardContext.notConfigured"));
if (started)
throw new LifecycleException
(sm.getString("standardContext.alreadyStarted"));
started = true;
// Start our subordinate components
substart();
; // XXX - start servlet definitions in descriptor?
}
/**
* Gracefully terminate the active use of the public methods of this
* component. This method should be the last one called on a given
* instance of this component.
*
* @exception IllegalStateException if this component has not been started
* @exception IllegalStateException if this component has already
* been stopped
* @exception LifecycleException if this component detects a fatal error
* that needs to be reported
*/
public void stop() throws LifecycleException {
// Validate and update our current state
if (!started)
throw new LifecycleException
(sm.getString("standardContext.notStarted"));
// Stop our subordinate components
; // XXX - stop servlet definitions in descriptor?
substop();
}
}
1.1 jakarta-tomcat/proposals/catalina/src/share/org/apache/tomcat/core/StandardEngine.java
Index: StandardEngine.java
===================================================================
/*
* $Header: /home/cvs/jakarta-tomcat/proposals/catalina/src/share/org/apache/tomcat/core/StandardEngine.java,v 1.1 2000/01/20 06:35:26 craigmcc Exp $
* $Revision: 1.1 $
* $Date: 2000/01/20 06:35:26 $
*
* ====================================================================
*
* 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 javax.servlet.ServletException;
import javax.servlet.http.HttpServletResponse;
import org.apache.tomcat.Container;
import org.apache.tomcat.Engine;
import org.apache.tomcat.Host;
import org.apache.tomcat.Lifecycle;
import org.apache.tomcat.LifecycleException;
import org.apache.tomcat.Request;
import org.apache.tomcat.Response;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
/**
* Standard implementation of the <b>Engine</b> interface. Each
* child container must be a Host implementation to process the specific
* fully qualified host name of that virtual host.
* <p>
* Lifecycle configuration of this component assumes an XML node
* in the following format:
* <code>
* <Engine className="org.apache.tomcat.core.StandardEngine"
* defaultHost="www.mycompany.com"
* unknownHost="www.mycompany.com"/>
* </code>
* where you can adjust the following parameters, with default values
* in square brackets:
* <ul>
* <li><b>defaultHost</b> - Default host name to use if none was specified
* in the incoming request (a corresponding <code><Host></code>
* child component must be configured. [none]
* <li><b>unknownHost</b> - Host name to use if an unknown host name was
* specified in the incoming request (a corresponding
* <code><Host></code> child component must be configured. [none]
* </ul>
*
* @author Craig R. McClanahan
* @version $Revision: 1.1 $ $Date: 2000/01/20 06:35:26 $
*/
public final class StandardEngine
extends ContainerBase
implements Engine, Lifecycle {
// ----------------------------------------------------- Instance Variables
/**
* Has this component been configured?
*/
private boolean configured = false;
/**
* Host name to use when no server host is specified in the request.
*/
private String defaultHost = null;
/**
* The descriptive information string for this implementation.
*/
private static final String info =
"org.apache.tomcat.core.StandardEngine/1.0";
/**
* Has this component been started?
*/
private boolean started = false;
/**
* Host name to use when an unknown host name is specified.
*/
private String unknownHost = null;
// ------------------------------------------------------------- Properties
/**
* Return the default host.
*/
public String getDefaultHost() {
return (defaultHost);
}
/**
* Set the default host.
*
* @param host The new default host
*/
public void setDefaultHost(String host) {
defaultHost = host;
}
/**
* Return the unknown host.
*/
public String getUnknownHost() {
return (unknownHost);
}
/**
* Set the unknown host.
*
* @param host The new unknown host
*/
public void setUnknownHost(String host) {
unknownHost = host;
}
// --------------------------------------------------------- Public Methods
/**
* Add a child Container, only if the proposed child is an implementation
* of Host.
*
* @param child Child container to be added
*/
public void addChild(Container child) {
if (!(child instanceof Host))
throw new IllegalArgumentException
(sm.getString("standardEngine.notHost"));
super.addChild(child);
}
/**
* Return descriptive information about this Container implementation and
* the corresponding version number, in the format
* <code><description>/<version></code>.
*/
public String getInfo() {
return (info);
}
/**
* Return the Host that should be used to process this request,
* based on the server name that was included. If no such Host
* can be identified, return <code>null</code> instead.
*
* @param request Request being processed
*/
public Host map(Request request) {
// Extract the requested server name
String server = request.getRequest().getServerName();
if (server == null)
server = defaultHost;
if (server == null)
return (null);
// Find the matching child Host
Host host = (Host) findChild(server);
if ((host == null) && (unknownHost != null))
host = (Host) findChild(unknownHost);
return (host);
}
/**
* Select the appropriate child Host to process this request,
* based on the requested server name. If no matching Host can
* be found, return an appropriate HTTP error.
*
* @param request Request to be processed
* @param response Response to be produced
*/
public void service(Request request, Response response)
throws IOException, ServletException {
// Select the host to be used for this request
Host host = map(request);
if (host == null) {
response.getResponse().sendError
(HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
sm.getString("standardEngine.noHost"));
return;
}
// Ask this Host to process this request
host.invoke(request, response);
}
/**
* Disallow any attempt to set a parent for this Container, since an
* Engine is supposed to be at the top of the Container hierarchy.
*
* @param container Proposed parent Container
*/
public void setParent(Container container) {
throw new IllegalArgumentException
(sm.getString("standardEngine.notParent"));
}
// ------------------------------------------------------ Lifecycle Methods
/**
* Configure this component, based on the specified configuration
* parameters. This method should be called immediately after the
* component instance is created, and before <code>start()</code>
* is called.
*
* @param parameters Configuration parameters for this component
* (<B>FIXME: What object type should this really be?)
*
* @exception IllegalStateException if this component has already been
* configured and/or started
* @exception LifecycleException if this component detects a fatal error
* in the configuration parameters it was given
*/
public void configure(Node parameters)
throws LifecycleException {
// Validate and update our current component state
if (configured)
throw new LifecycleException
(sm.getString("standardEngine.alreadyConfigured"));
configured = true;
if (parameters == null)
return;
// Parse and process our configuration parameters
if (!("Engine".equals(parameters.getNodeName())))
return;
NamedNodeMap attributes = parameters.getAttributes();
Node node = null;
String value = null;
node = attributes.getNamedItem("defaultHost");
if (node != null) {
value = node.getNodeValue();
if (value != null)
setDefaultHost(value);
}
node = attributes.getNamedItem("unknownHost");
if (node != null) {
value = node.getNodeValue();
if (value != null)
setUnknownHost(value);
}
// Parse and process our subordinate components
subconfigure(parameters);
}
/**
* Prepare for the beginning of active use of the public methods of this
* component. This method should be called after <code>configure()</code>,
* and before any of the public methods of the component are utilized.
*
* @exception IllegalStateException if this component has not yet been
* configured (if required for this component)
* @exception IllegalStateException if this component has already been
* started
* @exception LifecycleException if this component detects a fatal error
* that prevents this component from being used
*/
public void start() throws LifecycleException {
// Validate and update our current component state
if (!configured)
throw new LifecycleException
(sm.getString("standardEngine.notConfigured"));
if (started)
throw new LifecycleException
(sm.getString("standardEngine.alreadyStarted"));
started = true;
// Start our subordinate components
substart();
}
/**
* Gracefully terminate the active use of the public methods of this
* component. This method should be the last one called on a given
* instance of this component.
*
* @exception IllegalStateException if this component has not been started
* @exception IllegalStateException if this component has already
* been stopped
* @exception LifecycleException if this component detects a fatal error
* that needs to be reported
*/
public void stop() throws LifecycleException {
// Validate and update our current state
if (!started)
throw new LifecycleException
(sm.getString("standardEngine.notStarted"));
// Stop our subordinate components
substop();
}
}
1.1 jakarta-tomcat/proposals/catalina/src/share/org/apache/tomcat/core/StandardHost.java
Index: StandardHost.java
===================================================================
/*
* $Header: /home/cvs/jakarta-tomcat/proposals/catalina/src/share/org/apache/tomcat/core/StandardHost.java,v 1.1 2000/01/20 06:35:26 craigmcc Exp $
* $Revision: 1.1 $
* $Date: 2000/01/20 06:35:26 $
*
* ====================================================================
*
* 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 javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletResponse;
import org.apache.tomcat.Container;
import org.apache.tomcat.Context;
import org.apache.tomcat.Host;
import org.apache.tomcat.Lifecycle;
import org.apache.tomcat.LifecycleException;
import org.apache.tomcat.Request;
import org.apache.tomcat.Response;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
/**
* Standard implementation of the <b>Host</b> interface. Each
* child container must be a Context implementation to process the
* requests directed to a particular web application.
* <p>
* Lifecycle configuration of this component assumes an XML node
* in the following format:
* <code>
* <Host className="org.apache.tomcat.core.StandardHost"
* name="www.mycompany.com" root="false"/>
* </code>
* where you can adjust the following parameters, with default values
* in square brackets:
* <ul>
* <li><b>name</b> - Fully qualified host name of the virtual host
* represented by this component. [REQUIRED - NO DEFAULT]
* <li><b>root</b> - <code>true</code> if getRootContext() should return
* a valid object, or <code>false</code> if getRootContext()
* should return null (normally the case in secure environments).
* [false]
* </ul>
*
* @author Craig R. McClanahan
* @version $Revision: 1.1 $ $Date: 2000/01/20 06:35:26 $
*/
public final class StandardHost
extends ContainerBase
implements Host, Lifecycle {
// ----------------------------------------------------- Instance Variables
/**
* Has this component been configured?
*/
private boolean configured = false;
/**
* The descriptive information string for this implementation.
*/
private static final String info =
"org.apache.tomcat.core.StandardHost/1.0";
/**
* Should we return a root context?
*/
private boolean root = false;
/**
* The root context for this virtual host.
*/
private ServletContext rootContext = null;
/**
* Has this component been started?
*/
private boolean started = false;
// ------------------------------------------------------------- Properties
/**
* Return the canonical, fully qualified, name of the virtual host
* this Container represents.
*/
public String getName() {
return (name);
}
/**
* Set the canonical, fully qualified, name of the virtual host
* this Container represents.
*
* @param name Virtual host name
*
* @exception IllegalArgumentException if name is null
*/
public void setName(String name) {
if (name == null)
throw new IllegalArgumentException
(sm.getString("standardHost.nullName"));
this.name = name;
}
/**
* Return the root context flag.
*/
public boolean getRoot() {
return (this.root);
}
/**
* Set the root context flag.
*
* @param root The new root context flag
*/
public void setRoot(boolean root) {
this.root = root;
}
/**
* Return a specialized ServletContext instance that wraps the
* resources of the underlying virtual host; or <code>null</code>
* if access to these resources is not supported or not allowed.
* In general, this method will be used when a servlet calls
* <code>ServletContext.getContext("/")</code>.
*/
public ServletContext getRootContext() {
if (!root)
return (null);
// Construct a root context object if necessary
rootContext = null; // XXX - create root context object
return (rootContext);
}
// --------------------------------------------------------- Public Methods
/**
* Add a child Container, only if the proposed child is an implementation
* of Context.
*
* @param child Child container to be added
*/
public void addChild(Container child) {
if (!(child instanceof Context))
throw new IllegalArgumentException
(sm.getString("standardHost.notContext"));
super.addChild(child);
}
/**
* Return descriptive information about this Container implementation and
* the corresponding version number, in the format
* <code><description>/<version></code>.
*/
public String getInfo() {
return (info);
}
/**
* Return the Context that should be used to process this request,
* based on matching the longest possible context path (or selecting
* the default context. If no such Context can be identified,
* return <code>null</code> instead.
*
* @param uri Request URI, which must start with a '/'
*/
public Context map(String uri) {
String path = uri;
Context context = null;
while (path.length() > 1) {
context = (Context) findChild(path);
if (context != null)
break;
path = path.substring(0, path.lastIndexOf("/"));
}
return (context);
}
/**
* Select the appropriate child Context to process this request,
* based on the specified request URI. If no matching Context can
* be found, return an appropriate HTTP error.
*
* @param request Request to be processed
* @param response Response to be produced
*/
public void service(Request request, Response response)
throws IOException, ServletException {
// Select the context to be used for this request
String path = request.getRequest().getRequestURI();
Context context = map(path);
if (context == null) {
response.getResponse().sendError
(HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
sm.getString("standardHost.noContext"));
return;
}
// Ask this Context to process this request
request.setContext(context);
response.setContext(context);
context.invoke(request, response);
}
// ------------------------------------------------------ Lifecycle Methods
/**
* Configure this component, based on the specified configuration
* parameters. This method should be called immediately after the
* component instance is created, and before <code>start()</code>
* is called.
*
* @param parameters Configuration parameters for this component
* (<B>FIXME: What object type should this really be?)
*
* @exception IllegalStateException if this component has already been
* configured and/or started
* @exception LifecycleException if this component detects a fatal error
* in the configuration parameters it was given
*/
public void configure(Node parameters)
throws LifecycleException {
// Validate and update our current component state
if (configured)
throw new LifecycleException
(sm.getString("standardHost.alreadyConfigured"));
configured = true;
if (parameters == null)
return;
// Parse and process our configuration parameters
if (!("Host".equals(parameters.getNodeName())))
return;
NamedNodeMap attributes = parameters.getAttributes();
Node node = null;
String value = null;
node = attributes.getNamedItem("name");
if (node != null) {
value = node.getNodeValue();
if (value != null)
setName(value);
}
node = attributes.getNamedItem("root");
if (node != null) {
value = node.getNodeValue();
if (value != null)
setRoot("true".equals(value.toLowerCase()));
}
// Parse and process our subordinate components
subconfigure(parameters);
}
/**
* Prepare for the beginning of active use of the public methods of this
* component. This method should be called after <code>configure()</code>,
* and before any of the public methods of the component are utilized.
*
* @exception IllegalStateException if this component has not yet been
* configured (if required for this component)
* @exception IllegalStateException if this component has already been
* started
* @exception LifecycleException if this component detects a fatal error
* that prevents this component from being used
*/
public void start() throws LifecycleException {
// Validate and update our current component state
if (!configured)
throw new LifecycleException
(sm.getString("standardHost.notConfigured"));
if (started)
throw new LifecycleException
(sm.getString("standardHost.alreadyStarted"));
started = true;
// Start our subordinate components
substart();
}
/**
* Gracefully terminate the active use of the public methods of this
* component. This method should be the last one called on a given
* instance of this component.
*
* @exception IllegalStateException if this component has not been started
* @exception IllegalStateException if this component has already
* been stopped
* @exception LifecycleException if this component detects a fatal error
* that needs to be reported
*/
public void stop() throws LifecycleException {
// Validate and update our current state
if (!started)
throw new LifecycleException
(sm.getString("standardHost.notStarted"));
// Stop our subordinate components
substop();
}
}
1.1 jakarta-tomcat/proposals/catalina/src/share/org/apache/tomcat/core/StandardResources.java
Index: StandardResources.java
===================================================================
/*
* $Header: /home/cvs/jakarta-tomcat/proposals/catalina/src/share/org/apache/tomcat/core/StandardResources.java,v 1.1 2000/01/20 06:35:26 craigmcc Exp $
* $Revision: 1.1 $
* $Date: 2000/01/20 06:35:26 $
*
* ====================================================================
*
* 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.File;
import java.io.InputStream;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import org.apache.tomcat.Container;
import org.apache.tomcat.Context;
import org.apache.tomcat.Lifecycle;
import org.apache.tomcat.LifecycleException;
import org.apache.tomcat.Resources;
import org.apache.tomcat.util.StringManager;
import org.apache.tomcat.util.URLUtil;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
/**
* Standard implementation of the <b>Resources</b> interface. Resource
* requests are resolved against the document base URL that is configured.
* <p>
* Lifecycle configuration of this component assumes an XML node
* in the following format:
* <code>
* <Resources className="org.apache.tomcat.core.StandardResources"
* docRoot="webpages"/>
* </code>
* where you can adjust the following parameters, with default values
* in square brackets:
* <ul>
* <li><b>docRoot</b> - Directory name, directory path, or base URL from
* which this component can derive URLs of desired resources.
* [webpages]
* </ul>
*
* @author Craig R. McClanahan
* @version $Revision: 1.1 $ $Date: 2000/01/20 06:35:26 $
*/
public final class StandardResources
implements Resources, Lifecycle {
// ----------------------------------------------------------- Constructors
/**
* Construct a new instance of this class with default values.
*/
public StandardResources() {
super();
setDocRoot("webpages");
}
// ----------------------------------------------------- Instance Variables
/**
* Has this component been configured?
*/
private boolean configured = false;
/**
* The Container this component is associated with.
*/
private Container container = null;
/**
* The document root URL for this component.
*/
private String docRoot = null;
/**
* The descriptive information string for this implementation.
*/
private static final String info =
"org.apache.tomcat.core.StandardResources/1.0";
/**
* The string manager for this package.
*/
private StringManager sm = StringManager.getManager(Constants.Package);
/**
* Has this component been started?
*/
private boolean started = false;
// ------------------------------------------------------------- Properties
/**
* Return the Container with which this Resources has been associated.
*/
public Container getContainer() {
return (this.container);
}
/**
* Set the Container with which this Resources has been associated.
*
* @param container The associated Container
*/
public void setContainer(Container container) {
this.container = container;
}
/**
* Return the document root for this component.
*/
public String getDocRoot() {
return (this.docRoot);
}
/**
* Set the document root for this component.
*
* @param docRoot The new document root
*
* @exception IllegalArgumentException if this would create a
* malformed URL
*/
public void setDocRoot(String docRoot) {
URL url = null;
try {
url = URLUtil.resolve(docRoot);
} catch (MalformedURLException e) {
throw new IllegalArgumentException
(sm.getString("standardResources.malformedURL"));
}
this.docRoot = url.toString();
}
/**
* Return descriptive information about this Resources implementation and
* the corresponding version number, in the format
* <code><description>/<version></code>.
*/
public String getInfo() {
return (info);
}
// --------------------------------------------------------- Public Methods
/**
* Return the MIME type of the specified file, or <code>null</code> if
* the MIME type is not known. The MIME type is determined by the
* configuration of the servlet container, and may be specified in a
* web application descriptor. Common MIME types are
* <code>"text/html"</code> and <code>"image/gif"</code>.
*
* @param file Name of the file whose MIME type is to be determined
*/
public String getMimeType(String file) {
return (null); // FIXME - Ask container if it is a Context, else map?
}
/**
* Return the real path for a given virtual path. For example, the
* virtual path <code>"/index.html"</code> has a real path of whatever
* file on the server's filesystem would be served by a request for
* <code>"/index.html"</code>.
* <p>
* The real path returned will be in a form appropriate to the computer
* and operating system on which the servlet container is running,
* including the proper path separators. This method returns
* <code>null</code> if the servlet container cannot translate the
* virtual path to a real path for any reason (such as when the content
* is being made available from a <code>.war</code> archive).
*
* @param path The virtual path to be translated
*/
public String getRealPath(String path) {
if ((path == null) || (!path.startsWith("/")))
return (null);
if (docRoot.startsWith("file://"))
return (docRoot.substring(6) + path); // FIXME: Windows?
else
return (null);
}
/**
* Return a URL to the resource that is mapped to the specified path.
* The path must begin with a "/" and is interpreted as relative to
* the current context root.
* <p>
* This method allows the Container to make a resource available to
* servlets from any source. Resources can be located on a local or
* remote file system, in a database, or in a <code>.war</code> file.
* <p>
* The servlet container must implement the URL handlers and
* <code>URLConnection</code> objects that are necessary to access
* the resource.
* <p>
* This method returns <code>null</code> if no resource is mapped to
* the pathname.
* <p>
* Some Containers may allow writing to the URL returned by this method,
* using the methods of the URL class.
* <p>
* The resource content is returned directly, so be aware that
* requesting a <code>.jsp</code> page returns the JSP source code.
* Use a <code>RequestDispatcher</code> instead to include results
* of an execution.
* <p>
* This method has a different purpose than
* <code>java.lang.Class.getResource()</code>, which looks up resources
* based on a class loader. This method does not use class loaders.
*
* @param path The path to the desired resource
*
* @exception MalformedURLException if the pathname is not given
* in the correct form
*/
public URL getResource(String path) throws MalformedURLException {
if ((path == null) || (!path.startsWith("/")))
throw new MalformedURLException
(sm.getString("standardResources.malformedPath"));
return (new URL(docRoot + path));
}
/**
* Return the resource located at the named path as an
* <code>InputStream</code> object.
* <p>
* The data in the <code>InputStream</code> can be of any type or length.
* The path must be specified according to the rules given in
* <code>getResource()</code>. This method returns <code>null</code>
* if no resource exists at the specified path.
* <p>
* Meta-information such as content length and content type that is
* available via the <code>getResource()</code> method is lost when
* using this method.
* <p>
* The servlet container must implement the URL handlers and
* <code>URLConnection</code> objects that are necessary to access
* the resource.
* <p>
* This method is different from
* <code>java.lang.Class.getResourceAsStream()</code>, which uses a
* class loader. This method allows servlet containers to make a
* resource available to a servlet from any location, without using
* a class loader.
*
* @param path The path to the desired resource
*/
public InputStream getResourceAsStream(String path) {
try {
URL url = getResource(path);
return (url.openStream());
} catch (MalformedURLException e) {
return (null);
} catch (IOException e) {
return (null);
}
}
// ------------------------------------------------------ Lifecycle Methods
/**
* Configure this component, based on the specified configuration
* parameters. This method should be called immediately after the
* component instance is created, and before <code>start()</code>
* is called.
*
* @param parameters Configuration parameters for this component
* (<B>FIXME: What object type should this really be?)
*
* @exception IllegalStateException if this component has already been
* configured and/or started
* @exception LifecycleException if this component detects a fatal error
* in the configuration parameters it was given
*/
public void configure(Node parameters)
throws LifecycleException {
// Validate and update our current component state
if (configured)
throw new LifecycleException
(sm.getString("standardResources.alreadyConfigured"));
configured = true;
if (parameters == null)
return;
// Parse and process our configuration parameters
if (!("Resources".equals(parameters.getNodeName())))
return;
NamedNodeMap attributes = parameters.getAttributes();
Node node = null;
String value = null;
node = attributes.getNamedItem("docRoot");
if (node != null) {
value = node.getNodeValue();
if (value != null)
setDocRoot(value);
}
}
/**
* Prepare for the beginning of active use of the public methods of this
* component. This method should be called after <code>configure()</code>,
* and before any of the public methods of the component are utilized.
*
* @exception IllegalStateException if this component has not yet been
* configured (if required for this component)
* @exception IllegalStateException if this component has already been
* started
* @exception LifecycleException if this component detects a fatal error
* that prevents this component from being used
*/
public void start() throws LifecycleException {
// Validate and update our current component state
if (!configured)
throw new LifecycleException
(sm.getString("standardResources.notConfigured"));
if (started)
throw new LifecycleException
(sm.getString("standardResources.alreadyStarted"));
started = true;
}
/**
* Gracefully terminate the active use of the public methods of this
* component. This method should be the last one called on a given
* instance of this component.
*
* @exception IllegalStateException if this component has not been started
* @exception IllegalStateException if this component has already
* been stopped
* @exception LifecycleException if this component detects a fatal error
* that needs to be reported
*/
public void stop() throws LifecycleException {
// Validate and update our current state
if (!started)
throw new LifecycleException
(sm.getString("standardResources.notStarted"));
}
}
1.1 jakarta-tomcat/proposals/catalina/src/share/org/apache/tomcat/core/ValveBase.java
Index: ValveBase.java
===================================================================
/*
* $Header: /home/cvs/jakarta-tomcat/proposals/catalina/src/share/org/apache/tomcat/core/ValveBase.java,v 1.1 2000/01/20 06:35:26 craigmcc Exp $
* $Revision: 1.1 $
* $Date: 2000/01/20 06:35:26 $
*
* ====================================================================
*
* 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;
import java.io.IOException;
import javax.servlet.ServletException;
import org.apache.tomcat.Container;
import org.apache.tomcat.Request;
import org.apache.tomcat.Response;
import org.apache.tomcat.Valve;
/**
* Convenience base class for implementations of the <b>Valve</b> interface.
* A subclass <strong>MUST</strong> implement an <code>invoke()</code>
* method to provide the required functionality, and <strong>MAY</strong>
* implement the <code>Lifecycle</code> interface to provide configuration
* management and lifecycle support.
*
* @author Craig R. McClanahan
* @version $Revision: 1.1 $ $Date: 2000/01/20 06:35:26 $
*/
public abstract class ValveBase
implements Valve {
//------------------------------------------------------ Instance Variables
/**
* The Container whose pipeline this Valve is a component of.
*/
protected Container container = null;
/**
* Descriptive information about this Valve implementation. This value
* should be overridden by subclasses.
*/
protected static String info =
"org.apache.tomcat.core.ValveBase/1.0";
/**
* Dummy object used for global synchronization of the double linked
* lists that make up each pipeline.
*/
protected static String lock = "";
/**
* The next Valve in the pipeline this Valve is a component of.
*/
protected ValveBase next = null;
/**
* The previous Valve in the pipeline this Valve is a component of.
*/
protected ValveBase previous = null;
//-------------------------------------------------------------- Properties
/**
* Return the Container to which this Valve is connected, if any.
*/
public Container getContainer() {
return (container);
}
/**
* Return descriptive information about this Valve implementation.
*/
public String getInfo() {
return (info);
}
/**
* Return the next Valve in this pipeline, or <code>null</code> if this
* is the last Valve in the pipeline.
*/
public ValveBase getNext() {
return (next);
}
/**
* Set the Valve that follows this one in the pipeline it is part of.
*
* @param valve The new next valve
*/
public void setNext(ValveBase valve) {
this.next = valve;
}
/**
* Return the previous Valve in this pipeline, or <code>null</code> if
* this is the first Valve in the pipeline.
*/
public ValveBase getPrevious() {
return (previous);
}
/**
* Set the Valve that preceeds this one in the pipeline it is part of.
*
* @param valve The previous valve
*/
public void setPrevious(ValveBase valve) {
this.previous = valve;
}
//---------------------------------------------------------- Public Methods
/**
* Insert this Valve after the specified Valve in the pipeline it is a
* part of. The specified Valve will become the value returned by
* the <code>getPrevious()</code> method of this instance.
*
* @param valve The Valve to become the predecessor to this Valve
*/
public void insertAfter(ValveBase valve) {
synchronized (lock) {
previous = valve;
next = valve.getNext();
valve.setNext(this);
}
}
/**
* Insert this Valve before the specified Valve in the pipeline it is a
* part of. The specified Valve will become the value returned by
* the <code>getNext()</code> method of this instance.
*
* @param valve The Valve to become the successor to this Valve
*/
public void insertBefore(ValveBase valve) {
synchronized (lock) {
next = valve;
previous = valve.getPrevious();
valve.setPrevious(this);
}
}
/**
* The implementation-specific logic represented by this Valve. See the
* class description for the normal design patterns for this method.
* <p>
* This method <strong>MUST</strong> be provided by a subclass.
*
* @param request The servlet request to be processed
* @param response The servlet response to be created
*
* @exception IOException if an input/output error occurs
* @exception ServletException if a servlet error occurs
*/
public abstract void invoke(Request request, Response response)
throws IOException, ServletException;
/**
* Method to pass responsibility for processing this request to the next
* Valve in the pipeline (if any). Call this from your
* <code>invoke()</code> method if you have not completely handled this
* request, and want to pass it on for the usual processing.
* <p>
* This method is not normally overridden.
*
* @param request The servlet request to be processed
* @param response The servlet response to be created
*
* @exception IOException if an input/output error occurs
* @exception ServletException if a servlet error occurs
*/
public void invokeNext(Request request, Response response)
throws IOException, ServletException {
if (next == null) {
throw new IllegalStateException("No next 'valve' in the pipeline");
} else {
next.invoke(request, response);
}
}
/**
* Remove this Valve from the pipeline it is a part of. The links of
* the current "previous" and "next" Valves will be adjusted to omit
* this one.
*/
public void remove() {
synchronized (lock) {
if (next != null) {
next.setPrevious(previous);
}
if (previous != null) {
previous.setNext(next);
}
}
}
}