tomcat-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From cos...@apache.org
Subject svn commit: r761964 [1/10] - in /tomcat/trunk/modules/tomcat-lite/java: ./ org/ org/apache/ org/apache/tomcat/ org/apache/tomcat/addons/ org/apache/tomcat/integration/ org/apache/tomcat/integration/jmx/ org/apache/tomcat/integration/simple/ org/apache/...
Date Sat, 04 Apr 2009 16:24:36 GMT
Author: costin
Date: Sat Apr  4 16:24:34 2009
New Revision: 761964

URL: http://svn.apache.org/viewvc?rev=761964&view=rev
Log:
First batch, based on sandbox. The main change is adding the ObjectManager to abstract configuration/JMX/integration,
and replace some filters with explicit interfaces, as was suggested. This has dependencies on coyote and 
tomcat-util, and some optional servlets/filters/plugins to provide various features from the spec.


Added:
    tomcat/trunk/modules/tomcat-lite/java/
    tomcat/trunk/modules/tomcat-lite/java/org/
    tomcat/trunk/modules/tomcat-lite/java/org/apache/
    tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/
    tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/addons/
    tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/addons/UserAuthentication.java   (with props)
    tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/addons/UserSessionManager.java   (with props)
    tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/addons/UserTemplateClassMapper.java   (with props)
    tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/integration/
    tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/integration/ObjectManager.java   (with props)
    tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/integration/ObjectManagerSpi.java   (with props)
    tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/integration/jmx/
    tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/integration/jmx/JmxObjectManagerSpi.java   (with props)
    tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/integration/simple/
    tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/integration/simple/SimpleObjectManager.java
    tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/
    tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/CharsetMapperDefault.properties   (with props)
    tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/Connector.java   (with props)
    tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/ContextPreinitListener.java   (with props)
    tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/FilterChainImpl.java   (with props)
    tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/FilterConfigImpl.java   (with props)
    tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/Locale2Charset.java   (with props)
    tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/ParameterMap.java   (with props)
    tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/RequestDispatcherImpl.java   (with props)
    tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/ServletConfigImpl.java   (with props)
    tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/ServletContextConfig.java   (with props)
    tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/ServletContextImpl.java   (with props)
    tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/ServletInputStreamImpl.java   (with props)
    tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/ServletOutputStreamImpl.java   (with props)
    tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/ServletReaderImpl.java   (with props)
    tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/ServletRequestImpl.java   (with props)
    tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/ServletRequestWrapperImpl.java   (with props)
    tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/ServletResponseImpl.java   (with props)
    tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/ServletResponseIncludeWrapper.java   (with props)
    tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/ServletWriterImpl.java   (with props)
    tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/TomcatLite.java   (with props)
    tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/WebappContextMapper.java   (with props)
    tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/WebappFilterMapper.java   (with props)
    tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/WebappServletMapper.java   (with props)
    tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/cli/
    tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/cli/Main.java   (with props)
    tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/config.properties   (with props)
    tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/coyote/
    tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/coyote/ClientAbortException.java   (with props)
    tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/coyote/CoyoteHttp.java   (with props)
    tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/coyote/CoyoteServer.java   (with props)
    tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/coyote/CoyoteUtils.java   (with props)
    tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/coyote/MapperAdapter.java   (with props)
    tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/coyote/MessageReader.java   (with props)
    tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/coyote/MessageWriter.java   (with props)
    tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/webxml/
    tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/webxml/TomcatLiteWebXmlConfig.java   (with props)
    tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/webxml/WebAnnotation.java   (with props)
    tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/webxml/WebResourceCollectionData.java   (with props)
    tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/webxml/WebXml.java   (with props)
    tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/servlets/
    tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/servlets/file/
    tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/servlets/file/CopyUtils.java   (with props)
    tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/servlets/file/DefaultServlet.java   (with props)
    tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/servlets/file/Dir2Html.java   (with props)
    tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/servlets/file/FileCopyUtils.java   (with props)
    tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/servlets/file/MD5Encoder.java   (with props)
    tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/servlets/file/URLEncoder.java   (with props)
    tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/servlets/file/WebdavServlet.java   (with props)
    tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/servlets/file/XMLWriter.java   (with props)
    tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/servlets/jsp/
    tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/servlets/jsp/JasperCompilerTemplateClassMapper.java   (with props)
    tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/servlets/jsp/JspFileTemplateServlet.java   (with props)
    tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/servlets/jsp/PreCompileFilter.java   (with props)
    tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/servlets/jsp/SimpleTemplateClassMapper.java   (with props)
    tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/servlets/jsp/SingleThreadedProxyServlet.java   (with props)
    tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/servlets/jsp/WildcardTemplateServlet.java   (with props)
    tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/servlets/sec/
    tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/servlets/sec/AccessFilter.java   (with props)
    tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/servlets/sec/BasicAuthentication.java   (with props)
    tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/servlets/sec/FormAuthentication.java   (with props)
    tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/servlets/sec/IPFilter.java   (with props)
    tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/servlets/sec/SimpleUserAuthDB.java   (with props)
    tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/servlets/sec/UserDB.java   (with props)
    tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/servlets/session/
    tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/servlets/session/HttpSessionImpl.java   (with props)
    tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/servlets/session/RandomGenerator.java   (with props)
    tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/servlets/session/SimpleSessionManager.java   (with props)
    tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/servlets/util/
    tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/servlets/util/Enumerator.java   (with props)
    tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/servlets/util/LocaleParser.java   (with props)
    tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/servlets/util/Range.java   (with props)
    tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/servlets/util/RequestUtil.java   (with props)
    tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/servlets/util/UrlUtils.java   (with props)

Added: tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/addons/UserAuthentication.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/addons/UserAuthentication.java?rev=761964&view=auto
==============================================================================
--- tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/addons/UserAuthentication.java (added)
+++ tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/addons/UserAuthentication.java Sat Apr  4 16:24:34 2009
@@ -0,0 +1,47 @@
+/*
+ */
+package org.apache.tomcat.addons;
+
+import java.io.IOException;
+import java.security.Principal;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+/**
+ * Plugin for user auth.
+ * 
+ * This interface should support all common forms of auth, 
+ * including Basic, Digest, Form and various other auth 
+ * standards - the plugin has full control over request and
+ * response.  
+ * 
+ * Container will verify the security constraints on URLs and 
+ * call this for all URLs that have constraints. The plugin can
+ * either authenticate and return the principal, or change 
+ * the response - redirect, add headers, send content. 
+ * 
+ * Alternative: a simple Filter can do the same, with some conventions
+ * to support it ( attributes ).
+ * 
+ * @author Costin Manolache
+ */
+public interface UserAuthentication {
+
+    /**
+     * If req has all the info - return the principal.
+     * Otherwise set the challenge in response.
+     * 
+     * @param requestedMethod auth method from web.xml. Spec
+     *  complain plugins must support it. 
+     * @throws IOException 
+     */
+    public Principal authenticate(HttpServletRequest req, 
+                                  HttpServletResponse res, 
+                                  String requestedMethod) throws IOException;
+    
+    
+    public boolean isUserInRole(HttpServletRequest req,
+                                Principal p,
+                                String role);
+}

Propchange: tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/addons/UserAuthentication.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/addons/UserSessionManager.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/addons/UserSessionManager.java?rev=761964&view=auto
==============================================================================
--- tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/addons/UserSessionManager.java (added)
+++ tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/addons/UserSessionManager.java Sat Apr  4 16:24:34 2009
@@ -0,0 +1,45 @@
+/*
+ */
+package org.apache.tomcat.addons;
+
+import java.io.IOException;
+
+import javax.servlet.ServletContext;
+import javax.servlet.http.HttpSession;
+
+/**
+ * Session management plugin. No dependency on tomcat-lite, should
+ * be possible to add this to tomcat-trunk or other containers.
+ * 
+ * The container will:
+ * - extract the session id from request ( via a filter or built-ins )
+ * - call this interface when the user makes the related calls in the 
+ * servlet API.
+ * - provide a context attribute 'context-listeners' with the 
+ * List<EventListener> from web.xml 
+ *
+ * Implementation of this class must provide HttpSession object 
+ * and implement the spec. 
+ * 
+ */
+public interface UserSessionManager {
+
+    
+    
+    HttpSession findSession(String requestedSessionId) throws IOException;
+
+    HttpSession createSession(String requestedSessionId);
+  
+    boolean isValid(HttpSession session);
+
+    void access(HttpSession session);
+  
+    void endAccess(HttpSession session);
+  
+  
+    void setSessionTimeout(int to);
+    
+    void setContext(ServletContext ctx);
+
+
+}

Propchange: tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/addons/UserSessionManager.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/addons/UserTemplateClassMapper.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/addons/UserTemplateClassMapper.java?rev=761964&view=auto
==============================================================================
--- tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/addons/UserTemplateClassMapper.java (added)
+++ tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/addons/UserTemplateClassMapper.java Sat Apr  4 16:24:34 2009
@@ -0,0 +1,39 @@
+/*
+ */
+package org.apache.tomcat.addons;
+
+import javax.servlet.Servlet;
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletContext;
+import javax.servlet.ServletException;
+
+/** 
+ * Mapps a templating name ( like a jsp file ) to a class name 
+ * generated by the template compiler.
+ * 
+ * This class is needed at runtime to support *.jsp mappings
+ * or <jsp-file> - can be used to support other formats. 
+ * 
+ * The UserTemplateCompiler is only needed to support run-time
+ * compilation - if ahead-of-time compilation is used 
+ * all generated files can be mapped explicitly with  
+ * <servlet><class-name>.
+ * 
+ * @author Costin Manolache
+ */
+public interface UserTemplateClassMapper {
+
+    /**
+     * Generate and load the proxy corresponding to the template file.
+     *  
+     */
+    public Servlet loadProxy(String jspFile, 
+                             ServletContext ctx, 
+                             ServletConfig config) throws ServletException;
+
+    /**
+     * Quick check if the template ( or deps ) has been modified
+     * and the servlet needs to be regenerated;  
+     */
+    public boolean needsReload(String jspFile, Servlet s);
+}

Propchange: tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/addons/UserTemplateClassMapper.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/integration/ObjectManager.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/integration/ObjectManager.java?rev=761964&view=auto
==============================================================================
--- tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/integration/ObjectManager.java (added)
+++ tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/integration/ObjectManager.java Sat Apr  4 16:24:34 2009
@@ -0,0 +1,79 @@
+/*
+ */
+package org.apache.tomcat.integration;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Tomcat is using JMX heavily for monitoring and config - but other 
+ * apps embedding tomcat may have different preferences. There
+ * is interest to use and better integrate with dependency injection
+ * frameworks, OSGI. 
+ * 
+ * Tomcat will make call to this class when it creates contexts,
+ * servlets, connectors - giving a chance to DI frameworks to inject,
+ * and to JMX to expose the objects. 
+ * 
+ * Tomcat will also call this class when it needs a plugin, allowing
+ * DI or frameworks to locate the dependency.
+ * 
+ * @author Costin Manolache
+ */
+public class ObjectManager {
+    
+    /** 
+     * Attribute used to keep a reference to the object manager 
+     * in the context, for the use of servlets. 
+     */
+    public static final String ATTRIBUTE = "ObjectManager";
+
+    /**
+     * Register a named object with the framework. 
+     * 
+     * For example JMX will expose the object as an MBean.
+     * 
+     * The framework may inject properties - if it supports that.
+     */
+    public void bind(String name, Object o) {
+        for (ObjectManagerSpi p : providers) {
+            p.bind(name, o);
+        }
+    }
+
+    /** 
+     * When an object is no longer in use.
+     */
+    public void unbind(String name) {
+        for (ObjectManagerSpi p : providers) {
+            p.unbind(name);
+        }        
+    }
+
+    /**
+     * Create or get a new object with the given name.
+     */
+    public Object get(String key) {
+        for (ObjectManagerSpi p : providers) {
+            Object o = p.get(key);
+            if (o != null) {
+                return o;
+            }
+        }        
+        return null;
+    }
+
+    /**
+     * Helper for typed get.
+     */
+    public Object get(Class c) {
+        return get(c.getName());
+    }
+
+    /**
+     * ObjectManager delegates to providers. You can have multiple
+     * providers - for example JMX, DI and OSGI at the same time.
+     */
+    protected List<ObjectManagerSpi> providers = 
+        new ArrayList<ObjectManagerSpi>(); 
+}

Propchange: tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/integration/ObjectManager.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/integration/ObjectManagerSpi.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/integration/ObjectManagerSpi.java?rev=761964&view=auto
==============================================================================
--- tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/integration/ObjectManagerSpi.java (added)
+++ tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/integration/ObjectManagerSpi.java Sat Apr  4 16:24:34 2009
@@ -0,0 +1,18 @@
+/*
+ */
+package org.apache.tomcat.integration;
+
+/**
+ * Base class for framework-integration plugins.
+ */
+public abstract class ObjectManagerSpi {
+    public abstract void bind(String name, Object o);
+    
+    public abstract void unbind(String name);
+
+    public abstract Object get(String key);
+
+    public void register(ObjectManager om) {
+        om.providers.add(this);
+    }
+}
\ No newline at end of file

Propchange: tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/integration/ObjectManagerSpi.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/integration/jmx/JmxObjectManagerSpi.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/integration/jmx/JmxObjectManagerSpi.java?rev=761964&view=auto
==============================================================================
--- tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/integration/jmx/JmxObjectManagerSpi.java (added)
+++ tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/integration/jmx/JmxObjectManagerSpi.java Sat Apr  4 16:24:34 2009
@@ -0,0 +1,41 @@
+/*
+ */
+package org.apache.tomcat.integration.jmx;
+
+import java.util.logging.Logger;
+
+import org.apache.tomcat.integration.ObjectManagerSpi;
+import org.apache.tomcat.util.modeler.Registry;
+
+/**
+ * Plugin for integration with JMX.
+ * 
+ * All objects of interest are registered automatically.
+ */
+public class JmxObjectManagerSpi extends ObjectManagerSpi {
+    Registry registry;
+    Logger log = Logger.getLogger("JmxObjectManager");
+    
+    public JmxObjectManagerSpi() {
+        registry = Registry.getRegistry(null, null);
+    }
+    
+    public void bind(String name, Object o) {
+        try {
+            registry.registerComponent(o, 
+                    ":name=\"" + name + "\"", null);
+        } catch (Exception e) {
+            log.severe("Error registering" + e);
+        }
+    }
+
+    public void unbind(String name) {
+        registry.unregisterComponent(":name=\"" + name + "\"");
+    }
+
+    @Override
+    public Object get(String key) {
+        return null;
+    }
+
+}

Propchange: tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/integration/jmx/JmxObjectManagerSpi.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/integration/simple/SimpleObjectManager.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/integration/simple/SimpleObjectManager.java?rev=761964&view=auto
==============================================================================
--- tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/integration/simple/SimpleObjectManager.java (added)
+++ tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/integration/simple/SimpleObjectManager.java Sat Apr  4 16:24:34 2009
@@ -0,0 +1,214 @@
+/*
+ */
+package org.apache.tomcat.integration.simple;
+
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Properties;
+import java.util.logging.Logger;
+
+import org.apache.tomcat.integration.ObjectManager;
+import org.apache.tomcat.integration.ObjectManagerSpi;
+import org.apache.tomcat.util.IntrospectionUtils;
+
+/**
+ * This is a very small 'dependency injection'/registry poor-man substitute, 
+ * based on old tomcat IntrospectionUtils ( which is based on ant ).
+ * Alternative would be to just pick one of spring/guice/etc and use it.
+ * This class is a bit smaller and should be enough for simple use.
+ * 
+ * How it works: 
+ *  - when bound, simple properties are injected in the objects using
+ *  the old IntrospectionUtils, same as in original Tomcat server.xml
+ *   
+ *  - object creation using class name - properties injected as well.
+ *  Similar with how server.xml or ant works.
+ *  
+ *  - it is based on a big Properties file, with command line arguments 
+ *  merged in.
+ *  
+ * Tomcat doesn't require any of the features - they are just used to
+ * allow configuration in 'default' mode, when no other framework is 
+ * used.  
+ * 
+ * See the Spring example for an alternative. I believe most POJO frameworks
+ * can be supported. 
+ * 
+ * @author Costin Manolache
+ */
+public class SimpleObjectManager extends ObjectManagerSpi {
+
+    static Logger log = Logger.getLogger(SimpleObjectManager.class.getName());
+    
+    /** 
+     * Saved CLI arguments. Will be added to the properties.
+     */
+    public static String[] args;
+    
+    protected Properties props = new Properties();
+    protected Map<String, Object> objects = new HashMap();
+    ObjectManager om;
+    
+    public SimpleObjectManager() {
+    }
+
+    public SimpleObjectManager(ObjectManager om) {
+        register(om);
+    }
+
+    public void register(ObjectManager om) {
+        this.om = om;
+        if (args != null) {
+            try {
+                processArgs(args, props);
+            } catch (IOException e) {
+                // TODO Auto-generated catch block
+                e.printStackTrace();
+            }
+        }
+        super.register(om);
+    }
+    
+    public ObjectManager getObjectManager() {
+        return om;
+    }
+
+    public void load(InputStream is) {
+        try {
+            props.load(is);
+        } catch (IOException e) {
+            throw new RuntimeException("Error loading default config");
+        }
+    }
+    
+    public void loadResource(String res) {
+        InputStream in = this.getClass().getClassLoader()
+            .getResourceAsStream(res);
+        load(in);
+    }
+    
+    public Properties getProperties() {
+        return props;
+    }
+    
+    @Override
+    public void unbind(String name) {
+    }
+
+    @Override
+    public void bind(String name, Object o) {
+        log.info("Bound: " + name + " " + o);
+
+        // TODO: can I make 'inject' public - Guice seems to 
+        // support this.
+        inject(name, o);
+    }
+
+    @Override
+    public Object get(String key) {
+        // Use same syntax as Spring props.
+        String prop = props.getProperty(key + ".(class)");
+        if (prop != null) {
+            Object res = loadClass(prop);
+            inject(key, res);
+            return res;
+        }
+
+        return null;
+    }
+
+    private void inject(String name, Object o) {
+        // Simple injection of primitive types
+        String pref = name + ".";
+        int prefLen = pref.length();
+
+        for (String k: props.stringPropertyNames()) {
+            if (k.startsWith(pref)) {
+                if (k.endsWith(")")) {
+                    continue; // special 
+                }
+                String value = props.getProperty(k);
+                value = IntrospectionUtils.replaceProperties(value, 
+                        props, null);
+                String p = k.substring(prefLen);
+                int idx = p.indexOf(".");
+                if (idx > 0) {
+                    // ignore suffix - indexed properties
+                    p = p.substring(0, idx);
+                }
+                IntrospectionUtils.setProperty(o, p, value);
+                log.info("Setting: " + name + " " + k + " " + value);
+            }
+        }
+        // We could do cooler things - inject objects, etc.
+    }
+
+    private Object loadClass(String className) {
+        try {
+            Class c = Class.forName(className);
+            Object ext = c.newInstance();
+            return ext;
+        } catch (Throwable e) {
+            e.printStackTrace();
+            return null;
+        }        
+    }
+    
+    /**
+     * Populate properties based on CLI:
+     *  -key value
+     *  --key=value
+     *  
+     *  --config=FILE - load a properties file
+     *  
+     * @param args
+     * @param p
+     * @param meta
+     * @return everything after the first non arg not starting with '-'
+     * @throws IOException 
+     */
+    public static String[] processArgs(String[] args, Properties props) 
+            throws IOException {
+
+        for (int i = 0; i < args.length; i++) {
+            String arg = args[i];
+            if (arg.startsWith("--")) {
+                arg = arg.substring(2);
+            } else if (arg.startsWith("-")) {
+                arg = arg.substring(1);
+            } else {
+                String [] res = new String[args.length - i];
+                System.arraycopy(args, i, res, 0, res.length);
+                return res;
+            }
+            
+            String name = arg; 
+            int eq = arg.indexOf("=");
+            String value = null;
+            if (eq > 0) {
+                name = arg.substring(0, eq);
+                value = arg.substring(eq + 1);
+            } else {
+                i++;
+                if (i >= args.length) {
+                    throw new RuntimeException("Missing param " + arg);
+                }
+                value = args[i];
+            }
+
+            if ("config".equals(arg)) {
+                props.load(new FileInputStream(value));
+            } else {
+                props.put(name, value);
+            }
+        }
+        return new String[] {};
+    }
+
+    public static void setArgs(String[] argv) {
+        SimpleObjectManager.args = argv;
+    }
+}

Added: tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/CharsetMapperDefault.properties
URL: http://svn.apache.org/viewvc/tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/CharsetMapperDefault.properties?rev=761964&view=auto
==============================================================================
--- tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/CharsetMapperDefault.properties (added)
+++ tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/CharsetMapperDefault.properties Sat Apr  4 16:24:34 2009
@@ -0,0 +1,2 @@
+en=ISO-8859-1
+fr=ISO-8859-1

Propchange: tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/CharsetMapperDefault.properties
------------------------------------------------------------------------------
    svn:eol-style = native

Added: tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/Connector.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/Connector.java?rev=761964&view=auto
==============================================================================
--- tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/Connector.java (added)
+++ tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/Connector.java Sat Apr  4 16:24:34 2009
@@ -0,0 +1,42 @@
+/*
+ */
+package org.apache.tomcat.lite;
+
+import java.io.IOException;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.tomcat.integration.ObjectManager;
+
+/**
+ * What we need to plugin a connector.
+ * 
+ * Currently we have lots of deps on coyote Request, but I plan to
+ * change this and allow other HTTP implementations - like MINA, the
+ * experimental async connector, etc. Most important will be 
+ * different support for IO - i.e. a more non-blocking mode.
+ * We'll probably keep MessageBytes as wrappers for request/res
+ * properties. 
+ * 
+ * This interface has no dep on coyote.
+ *  
+ */
+public interface Connector {
+
+    public void setDaemon(boolean b);
+    
+    public void start();
+    
+    public void stop();
+    
+    public void finishResponse(HttpServletResponse res) throws IOException;
+    
+    public void recycle(HttpServletRequest req, HttpServletResponse res);
+
+    void initRequest(HttpServletRequest req, HttpServletResponse res);
+
+    public void setTomcatLite(TomcatLite tomcatLite);
+
+    public void setObjectManager(ObjectManager objectManager);
+}

Propchange: tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/Connector.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/ContextPreinitListener.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/ContextPreinitListener.java?rev=761964&view=auto
==============================================================================
--- tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/ContextPreinitListener.java (added)
+++ tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/ContextPreinitListener.java Sat Apr  4 16:24:34 2009
@@ -0,0 +1,23 @@
+/*
+ */
+package org.apache.tomcat.lite;
+
+import javax.servlet.ServletContext;
+
+/**
+ * Tomcat-lite specific interface ( could be moved to addons ).
+ * This class will be called before initialization - implementations
+ * can add servlets, filters, etc. In particular web.xml parsing
+ * is done implementing this interface. 
+ * 
+ * On a small server you could remove web.xml support to reduce 
+ * footprint, and either hardcode this class or use properties.
+ * Same if you already use a framework and you inject settings
+ * or use framework's registry (OSGI).
+ * 
+ * @author Costin Manolache
+ */
+public interface ContextPreinitListener {
+
+    public void preInit(ServletContext ctx);
+}

Propchange: tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/ContextPreinitListener.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/FilterChainImpl.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/FilterChainImpl.java?rev=761964&view=auto
==============================================================================
--- tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/FilterChainImpl.java (added)
+++ tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/FilterChainImpl.java Sat Apr  4 16:24:34 2009
@@ -0,0 +1,168 @@
+/*
+ * Copyright 2009 The Apache Software Foundation.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.tomcat.lite;
+
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.servlet.Filter;
+import javax.servlet.FilterChain;
+import javax.servlet.Servlet;
+import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+
+/**
+ * Wraps the list of filters for the current request. One instance 
+ * associated with each RequestImpl, reused. 
+ * 
+ * Populated by the mapper ( WebappFilterMapper for example ), which
+ * determines the filters for the current request.
+ * 
+ * Not thread safe.
+ */
+public final class FilterChainImpl implements FilterChain {
+    private List<FilterConfigImpl> filters =  new ArrayList<FilterConfigImpl>();
+
+
+    /**
+     * The int which is used to maintain the current position 
+     * in the filter chain.
+     */
+    private int pos = 0;
+
+    /**
+     * The servlet instance to be executed by this chain.
+     */
+    private Servlet servlet = null;
+
+
+    private ServletConfigImpl wrapper;
+
+
+    public FilterChainImpl() {
+        super();
+    }
+
+
+    /**
+     * Invoke the next filter in this chain, passing the specified request
+     * and response.  If there are no more filters in this chain, invoke
+     * the <code>service()</code> method of the servlet itself.
+     *
+     * @param request The servlet request we are processing
+     * @param response The servlet response we are creating
+     *
+     * @exception IOException if an input/output error occurs
+     * @exception ServletException if a servlet exception occurs
+     */
+    public void doFilter(ServletRequest request, ServletResponse response)
+        throws IOException, ServletException {
+
+
+        // Call the next filter if there is one
+        if (pos < filters.size()) {
+            FilterConfigImpl filterConfig = filters.get(pos++);
+            Filter filter = null;
+            try {
+                filter = filterConfig.getFilter();
+                filter.doFilter(request, response, this);
+            } catch (IOException e) {
+                throw e;
+            } catch (ServletException e) {
+                throw e;
+            } catch (RuntimeException e) {
+                throw e;
+            } catch (Throwable e) {
+                e.printStackTrace();
+                throw new ServletException("Throwable", e);
+            }
+            return;
+        }
+
+        // We fell off the end of the chain -- call the servlet instance
+        try {
+            if (servlet != null) 
+                servlet.service(request, response);
+        } catch (IOException e) {
+            throw e;
+        } catch (ServletException e) {
+            throw e;
+        } catch (RuntimeException e) {
+            throw e;
+        } catch (Throwable e) {
+            throw new ServletException("Throwable", e);
+        }
+    }
+
+
+    // -------------------------------------------------------- Package Methods
+
+
+
+    /**
+     * Add a filter to the set of filters that will be executed in this chain.
+     *
+     * @param filterConfig The FilterConfig for the servlet to be executed
+     */
+    public void addFilter(FilterConfigImpl filterConfig) {
+        filters.add(filterConfig);
+    }
+
+
+    /**
+     * Release references to the filters and wrapper executed by this chain.
+     */
+    public void release() {
+        filters.clear();
+        pos = 0;
+        servlet = null;
+    }
+
+
+    /**
+     * Set the servlet that will be executed at the end of this chain.
+     * Set by the mapper filter 
+     */
+    public void setServlet(ServletConfigImpl wrapper, Servlet servlet) {
+        this.wrapper = wrapper;
+        this.servlet = servlet;
+    }
+
+    // ------ Getters for information ------------ 
+    
+    public int getSize() {
+        return filters.size();
+    }
+    
+    public FilterConfigImpl getFilter(int i) {
+        return filters.get(i);
+    }
+    
+    public Servlet getServlet() {
+        return servlet;
+    }
+    
+    public ServletConfigImpl getServletConfig() {
+        return wrapper;
+    }
+    
+    public int getPos() {
+        return pos;
+    }
+}

Propchange: tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/FilterChainImpl.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/FilterConfigImpl.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/FilterConfigImpl.java?rev=761964&view=auto
==============================================================================
--- tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/FilterConfigImpl.java (added)
+++ tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/FilterConfigImpl.java Sat Apr  4 16:24:34 2009
@@ -0,0 +1,143 @@
+/*
+ * Copyright 1999,2004 The Apache Software Foundation.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+package org.apache.tomcat.lite;
+
+
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.Map;
+
+import javax.servlet.Filter;
+import javax.servlet.FilterConfig;
+import javax.servlet.ServletContext;
+import javax.servlet.ServletException;
+
+import org.apache.tomcat.servlets.util.Enumerator;
+
+
+/** 
+ * A Filter is configured in web.xml by:
+ *  - name - used in mappings
+ *  - className - used to instantiate the filter
+ *  - init params
+ *  - other things not used in the servlet container ( icon, descr, etc )
+ *  
+ * Alternatively, in API mode you can pass the actual filter.
+ * 
+ * @see ServletConfigImpl
+ */
+public final class FilterConfigImpl implements FilterConfig {
+
+    public FilterConfigImpl(ServletContextImpl context) {
+        this.context = context;
+    }
+    
+    private ServletContextImpl context = null;
+
+    /**
+     * The application Filter we are configured for.
+     */
+    private transient Filter filter = null;
+
+    private String filterName;
+
+    private String filterClass;
+
+    private Map<String, String> initParams;
+
+    public void setData(String filterName, String filterClass,
+                        Map<String, String> params) {
+        this.filterName = filterName;
+        this.filterClass = filterClass;
+        this.initParams = params;
+    }
+    
+    public void setFilter(Filter f) {
+        filter = f;
+    }
+    
+    public String getFilterName() {
+        return filterName;
+    }
+
+    public String getInitParameter(String name) {
+        if (initParams == null) return null;
+        return initParams.get(name);
+    }
+
+    /**
+     * Return an <code>Enumeration</code> of the names of the initialization
+     * parameters for this Filter.
+     */
+    public Enumeration getInitParameterNames() {
+        if (initParams == null)
+            return (new Enumerator(new ArrayList()));
+        else
+            return (new Enumerator(initParams.keySet()));
+    }
+
+
+    /**
+     * Return the ServletContext of our associated web application.
+     */
+    public ServletContext getServletContext() {
+        return context;
+    }
+
+    /**
+     * Return the application Filter we are configured for.
+     */
+    public Filter getFilter() throws ClassCastException, ClassNotFoundException,
+        IllegalAccessException, InstantiationException, ServletException {
+
+        // Return the existing filter instance, if any
+        if (filter != null)
+            return filter;
+
+        ClassLoader classLoader = context.getClassLoader();
+
+        ClassLoader oldCtxClassLoader =
+            Thread.currentThread().getContextClassLoader();
+        if (classLoader != oldCtxClassLoader) {
+            Thread.currentThread().setContextClassLoader(classLoader);
+        }
+        try {
+            Class clazz = classLoader.loadClass(filterClass);
+            this.filter = (Filter) clazz.newInstance();
+        } finally {        
+            if (classLoader != oldCtxClassLoader) {
+                Thread.currentThread().setContextClassLoader(oldCtxClassLoader);
+            }
+        }
+        
+        filter.init(this);
+        return (this.filter);
+    }
+
+
+    /**
+     * Release the Filter instance associated with this FilterConfig,
+     * if there is one.
+     */
+    public void release() {
+        if (this.filter != null){
+            filter.destroy();
+        }
+        this.filter = null;
+     }
+}

Propchange: tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/FilterConfigImpl.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/Locale2Charset.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/Locale2Charset.java?rev=761964&view=auto
==============================================================================
--- tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/Locale2Charset.java (added)
+++ tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/Locale2Charset.java Sat Apr  4 16:24:34 2009
@@ -0,0 +1,128 @@
+/*
+ * Copyright 1999,2004 The Apache Software Foundation.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.tomcat.lite;
+
+
+import java.io.InputStream;
+import java.util.Locale;
+import java.util.Properties;
+
+
+
+/**
+ * One instance per Context. Holds the 
+ * 
+ * Utility class that attempts to map from a Locale to the corresponding
+ * character set to be used for interpreting input text (or generating
+ * output text) when the Content-Type header does not include one.  You
+ * can customize the behavior of this class by modifying the mapping data
+ * it loads, or by subclassing it (to change the algorithm) and then using
+ * your own version for a particular web application.
+ *
+ * @author Craig R. McClanahan
+ */
+public class Locale2Charset {
+
+
+    // ---------------------------------------------------- Manifest Constants
+
+
+    /**
+     * Default properties resource name.
+     */
+    public static final String DEFAULT_RESOURCE =
+      "/org/apache/tomcat/lite/CharsetMapperDefault.properties";
+
+    
+
+    // ---------------------------------------------------------- Constructors
+
+
+    /**
+     * Construct a new CharsetMapper using the default properties resource.
+     */
+    public Locale2Charset() {
+      String name = DEFAULT_RESOURCE;
+      if (defaultMap == null) { // once !
+        try {
+          defaultMap = new Properties();
+          InputStream stream =
+            this.getClass().getResourceAsStream(name);
+          defaultMap.load(stream);
+          stream.close();
+        } catch (Throwable t) {
+          throw new IllegalArgumentException(t.toString());
+        }
+      }
+      map = defaultMap;
+    }
+
+
+    // ---------------------------------------------------- Instance Variables
+
+
+    private static Properties defaultMap; // shared for all apps
+    
+    /**
+     * The mapping properties that have been initialized from the specified or
+     * default properties resource.
+     */
+    private Properties map;
+
+
+    // ------------------------------------------------------- Public Methods
+
+
+    /**
+     * Calculate the name of a character set to be assumed, given the specified
+     * Locale and the absence of a character set specified as part of the
+     * content type header.
+     *
+     * @param locale The locale for which to calculate a character set
+     */
+    public String getCharset(Locale locale) {
+        // Match full language_country_variant first, then language_country, 
+        // then language only
+        String charset = map.getProperty(locale.toString());
+        if (charset == null) {
+            charset = map.getProperty(locale.getLanguage() + "_" 
+                    + locale.getCountry());
+            if (charset == null) {
+                charset = map.getProperty(locale.getLanguage());
+            }
+        }
+        return (charset);
+    }
+
+    
+    /**
+     * The deployment descriptor can have a
+     * locale-encoding-mapping-list element which describes the
+     * webapp's desired mapping from locale to charset.  This method
+     * gets called when processing the web.xml file for a context
+     *
+     * @param locale The locale for a character set
+     * @param charset The charset to be associated with the locale
+     */
+    public void addCharsetMapping(String locale, String charset) {
+      if (map == defaultMap) { 
+        // new copy, don't modify original
+        map = new Properties(defaultMap);
+      }
+      map.put(locale, charset);
+    }
+}

Propchange: tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/Locale2Charset.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/ParameterMap.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/ParameterMap.java?rev=761964&view=auto
==============================================================================
--- tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/ParameterMap.java (added)
+++ tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/ParameterMap.java Sat Apr  4 16:24:34 2009
@@ -0,0 +1,204 @@
+/*
+ * Copyright 1999,2004 The Apache Software Foundation.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+package org.apache.tomcat.lite;
+
+
+import java.util.HashMap;
+import java.util.Map;
+
+
+/**
+ * Extended implementation of <strong>HashMap</strong> that includes a
+ * <code>locked</code> property.  This class can be used to safely expose
+ * Catalina internal parameter map objects to user classes without having
+ * to clone them in order to avoid modifications.  When first created, a
+ * <code>ParmaeterMap</code> instance is not locked.
+ *
+ * @author Craig R. McClanahan
+ * @version $Revision: 302726 $ $Date: 2004-02-27 06:59:07 -0800 (Fri, 27 Feb 2004) $
+ */
+
+public final class ParameterMap extends HashMap {
+
+
+    // ----------------------------------------------------------- Constructors
+
+
+    /**
+     * Construct a new, empty map with the default initial capacity and
+     * load factor.
+     */
+    public ParameterMap() {
+
+        super();
+
+    }
+
+
+    /**
+     * Construct a new, empty map with the specified initial capacity and
+     * default load factor.
+     *
+     * @param initialCapacity The initial capacity of this map
+     */
+    public ParameterMap(int initialCapacity) {
+
+        super(initialCapacity);
+
+    }
+
+
+    /**
+     * Construct a new, empty map with the specified initial capacity and
+     * load factor.
+     *
+     * @param initialCapacity The initial capacity of this map
+     * @param loadFactor The load factor of this map
+     */
+    public ParameterMap(int initialCapacity, float loadFactor) {
+
+        super(initialCapacity, loadFactor);
+
+    }
+
+
+    /**
+     * Construct a new map with the same mappings as the given map.
+     *
+     * @param map Map whose contents are dupliated in the new map
+     */
+    public ParameterMap(Map map) {
+
+        super(map);
+
+    }
+
+
+    // ------------------------------------------------------------- Properties
+
+
+    /**
+     * The current lock state of this parameter map.
+     */
+    private boolean locked = false;
+
+
+    /**
+     * Return the locked state of this parameter map.
+     */
+    public boolean isLocked() {
+
+        return (this.locked);
+
+    }
+
+
+    /**
+     * Set the locked state of this parameter map.
+     *
+     * @param locked The new locked state
+     */
+    public void setLocked(boolean locked) {
+
+        this.locked = locked;
+
+    }
+
+
+    // --------------------------------------------------------- Public Methods
+
+
+
+    /**
+     * Remove all mappings from this map.
+     *
+     * @exception IllegalStateException if this map is currently locked
+     */
+    public void clear() {
+
+        if (locked)
+            throw new IllegalStateException
+                ("parameterMap.locked");
+        super.clear();
+
+    }
+
+
+    /**
+     * Associate the specified value with the specified key in this map.  If
+     * the map previously contained a mapping for this key, the old value is
+     * replaced.
+     *
+     * @param key Key with which the specified value is to be associated
+     * @param value Value to be associated with the specified key
+     *
+     * @return The previous value associated with the specified key, or
+     *  <code>null</code> if there was no mapping for key
+     *
+     * @exception IllegalStateException if this map is currently locked
+     */
+    public Object put(Object key, Object value) {
+
+        if (locked)
+            throw new IllegalStateException
+                ("parameterMap.locked");
+        return (super.put(key, value));
+
+    }
+
+
+    /**
+     * Copy all of the mappings from the specified map to this one.  These
+     * mappings replace any mappings that this map had for any of the keys
+     * currently in the specified Map.
+     *
+     * @param map Mappings to be stored into this map
+     *
+     * @exception IllegalStateException if this map is currently locked
+     */
+    public void putAll(Map map) {
+
+        if (locked)
+            throw new IllegalStateException
+                ("parameterMap.locked");
+        super.putAll(map);
+
+    }
+
+
+    /**
+     * Remove the mapping for this key from the map if present.
+     *
+     * @param key Key whose mapping is to be removed from the map
+     *
+     * @return The previous value associated with the specified key, or
+     *  <code>null</code> if there was no mapping for that key
+     *
+     * @exception IllegalStateException if this map is currently locked
+     */
+    public Object remove(Object key) {
+
+        if (locked)
+            throw new IllegalStateException
+                ("parameterMap.locked");
+        return (super.remove(key));
+
+    }
+
+
+}

Propchange: tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/ParameterMap.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/RequestDispatcherImpl.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/RequestDispatcherImpl.java?rev=761964&view=auto
==============================================================================
--- tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/RequestDispatcherImpl.java (added)
+++ tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/RequestDispatcherImpl.java Sat Apr  4 16:24:34 2009
@@ -0,0 +1,853 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.tomcat.lite;
+
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import javax.servlet.RequestDispatcher;
+import javax.servlet.Servlet;
+import javax.servlet.ServletException;
+import javax.servlet.ServletOutputStream;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletRequestWrapper;
+import javax.servlet.ServletResponse;
+import javax.servlet.ServletResponseWrapper;
+import javax.servlet.UnavailableException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.tomcat.util.buf.CharChunk;
+import org.apache.tomcat.util.buf.MessageBytes;
+import org.apache.tomcat.util.http.mapper.MappingData;
+
+/**
+ *
+ */
+public final class RequestDispatcherImpl implements RequestDispatcher {
+    /**
+     * The request attribute under which the original servlet path is stored
+     * on an forwarded dispatcher request.
+     */
+    public static final String FORWARD_SERVLET_PATH_ATTR =
+        "javax.servlet.forward.servlet_path";
+
+
+    /**
+     * The request attribute under which the original query string is stored
+     * on an forwarded dispatcher request.
+     */
+    public static final String FORWARD_QUERY_STRING_ATTR =
+        "javax.servlet.forward.query_string";
+
+    /**
+     * The request attribute under which the original request URI is stored
+     * on an forwarded dispatcher request.
+     */
+    public static final String FORWARD_REQUEST_URI_ATTR =
+        "javax.servlet.forward.request_uri";
+    
+    
+    /**
+     * The request attribute under which the original context path is stored
+     * on an forwarded dispatcher request.
+     */
+    public static final String FORWARD_CONTEXT_PATH_ATTR =
+        "javax.servlet.forward.context_path";
+
+
+    /**
+     * The request attribute under which the original path info is stored
+     * on an forwarded dispatcher request.
+     */
+    public static final String FORWARD_PATH_INFO_ATTR =
+        "javax.servlet.forward.path_info";
+
+    /**
+     * The request attribute under which we store the servlet name on a
+     * named dispatcher request.
+     */
+    public static final String NAMED_DISPATCHER_ATTR =
+        "org.apache.catalina.NAMED";
+
+    /**
+     * The request attribute under which the request URI of the included
+     * servlet is stored on an included dispatcher request.
+     */
+    public static final String INCLUDE_REQUEST_URI_ATTR =
+        "javax.servlet.include.request_uri";
+
+
+    /**
+     * The request attribute under which the context path of the included
+     * servlet is stored on an included dispatcher request.
+     */
+    public static final String INCLUDE_CONTEXT_PATH_ATTR =
+        "javax.servlet.include.context_path";
+
+
+    /**
+     * The request attribute under which the path info of the included
+     * servlet is stored on an included dispatcher request.
+     */
+    public static final String INCLUDE_PATH_INFO_ATTR =
+        "javax.servlet.include.path_info";
+
+
+    /**
+     * The request attribute under which the servlet path of the included
+     * servlet is stored on an included dispatcher request.
+     */
+    public static final String INCLUDE_SERVLET_PATH_ATTR =
+        "javax.servlet.include.servlet_path";
+
+
+    /**
+     * The request attribute under which the query string of the included
+     * servlet is stored on an included dispatcher request.
+     */
+    public static final String INCLUDE_QUERY_STRING_ATTR =
+        "javax.servlet.include.query_string";
+
+    /**
+     * The request attribute under which we expose the value of the
+     * <code>&lt;jsp-file&gt;</code> value associated with this servlet,
+     * if any.
+     */
+    public static final String JSP_FILE_ATTR =
+        "org.apache.catalina.jsp_file";
+
+
+    // ----------------------------------------------------- Instance Variables
+
+    private static Logger log = Logger.getLogger(RequestDispatcherImpl.class.getName());
+
+    private ServletContextImpl ctx = null;
+
+    /**
+     * The servlet name for a named dispatcher.
+     */
+    private String name = null;
+
+    // Path for a path dispatcher
+    private String path;
+
+    /**
+     * MappingData object - per thread for buffering.
+     */
+    private transient ThreadLocal localMappingData = new ThreadLocal();
+
+    /*
+      OrigRequest(ServletRequestImpl) -> include/forward * -> this include
+      
+      On the path: user-defined RequestWrapper or our ServletRequestWrapper
+
+      include() is called with a RequestWrapper(->...->origRequest) or origRequest
+      
+      Based on params, etc -> we wrap the req / response in ServletRequestWrapper,
+       call filters+servlet. Inside, the req can be wrapped again in 
+       userReqWrapper, and other include called. 
+       
+      
+     */
+    
+    /**
+     * The outermost request that will be passed on to the invoked servlet.
+     */
+    private ServletRequest outerRequest = null;
+
+    /**
+     * The outermost response that will be passed on to the invoked servlet.
+     */
+    private ServletResponse outerResponse = null;
+
+    /**
+     * The request wrapper we have created and installed (if any).
+     */
+    private ServletRequest wrapRequest = null;
+
+    /**
+     * The response wrapper we have created and installed (if any).
+     */
+    private ServletResponse wrapResponse = null;
+
+    // Parameters used when constructing the dispatcvher 
+    /**
+     * The extra path information for this RequestDispatcher.
+     */
+    private String pathInfo = null;
+    /**
+     * The query string parameters for this RequestDispatcher.
+     */
+    private String queryString = null;
+    /**
+     * The request URI for this RequestDispatcher.
+     */
+    private String requestURI = null;
+    /**
+     * The servlet path for this RequestDispatcher.
+     */
+    private String servletPath = null;
+
+    //
+    private String origServletPath = null;
+    
+    /**
+     * The Wrapper associated with the resource that will be forwarded to
+     * or included.
+     */
+    private ServletConfigImpl wrapper = null;
+    
+    private Servlet servlet; 
+
+    /** Named dispatcher 
+     */
+    public RequestDispatcherImpl(ServletConfigImpl wrapper, String name) {
+        this.wrapper = wrapper;
+        this.name = name;
+        this.ctx = (ServletContextImpl) wrapper.getServletContext();
+
+    }
+    
+    public RequestDispatcherImpl(ServletContextImpl ctx, String path) {
+        this.path = path;
+        this.ctx = ctx;
+    }
+   
+
+
+    /**
+     * Forward this request and response to another resource for processing.
+     * Any runtime exception, IOException, or ServletException thrown by the
+     * called servlet will be propogated to the caller.
+     *
+     * @param request The servlet request to be forwarded
+     * @param response The servlet response to be forwarded
+     *
+     * @exception IOException if an input/output error occurs
+     * @exception ServletException if a servlet exception occurs
+     */
+    public void forward(ServletRequest request, ServletResponse response)
+        throws ServletException, IOException
+    {
+        // Reset any output that has been buffered, but keep headers/cookies
+        if (response.isCommitted()) {
+            throw new IllegalStateException("forward(): response.isComitted()");
+        }
+        
+        try {
+            response.resetBuffer();
+        } catch (IllegalStateException e) {
+            throw e;
+        }
+
+        // Set up to handle the specified request and response
+        setup(request, response, false);
+
+        // Identify the HTTP-specific request and response objects (if any)
+        HttpServletRequest hrequest = (HttpServletRequest) request;
+
+        ServletRequestWrapperImpl wrequest =
+            (ServletRequestWrapperImpl) wrapRequest();
+
+        
+        if (name != null) {
+            wrequest.setRequestURI(hrequest.getRequestURI());
+            wrequest.setContextPath(hrequest.getContextPath());
+            wrequest.setServletPath(hrequest.getServletPath());
+            wrequest.setPathInfo(hrequest.getPathInfo());
+            wrequest.setQueryString(hrequest.getQueryString());
+
+            
+        } else { // path based
+            mapPath();
+            if (wrapper == null) {
+                throw new ServletException("Forward not found " + 
+                        path);
+            }
+            String contextPath = ctx.getContextPath();
+            if (hrequest.getAttribute(FORWARD_REQUEST_URI_ATTR) == null) {
+                wrequest.setAttribute(FORWARD_REQUEST_URI_ATTR,
+                                      hrequest.getRequestURI());
+                wrequest.setAttribute(FORWARD_CONTEXT_PATH_ATTR,
+                                      hrequest.getContextPath());
+                wrequest.setAttribute(FORWARD_SERVLET_PATH_ATTR,
+                                      hrequest.getServletPath());
+                wrequest.setAttribute(FORWARD_PATH_INFO_ATTR,
+                                      hrequest.getPathInfo());
+                wrequest.setAttribute(FORWARD_QUERY_STRING_ATTR,
+                                      hrequest.getQueryString());
+            }
+ 
+            wrequest.setContextPath(contextPath);
+            wrequest.setRequestURI(requestURI);
+            wrequest.setServletPath(servletPath);
+            wrequest.setPathInfo(pathInfo);
+            if (queryString != null) {
+                wrequest.setQueryString(queryString);
+                wrequest.setQueryParams(queryString);
+            }
+        }
+        processRequest(outerRequest, outerResponse);
+
+        wrequest.recycle();
+        unwrapRequest();
+
+        // This is not a real close in order to support error processing
+//        if ( log.isDebugEnabled() )
+//            log.debug(" Disabling the response for futher output");
+
+        if  (response instanceof ServletResponseImpl) {
+            ((ServletResponseImpl) response).flushBuffer();
+            ((ServletResponseImpl) response).setSuspended(true);
+        } else {
+            // Servlet SRV.6.2.2. The Resquest/Response may have been wrapped
+            // and may no longer be instance of RequestFacade 
+            if (log.isLoggable(Level.FINE)){
+                log.fine( " The Response is vehiculed using a wrapper: " 
+                           + response.getClass().getName() );
+            }
+
+            // Close anyway
+            try {
+                PrintWriter writer = response.getWriter();
+                writer.close();
+            } catch (IllegalStateException e) {
+                try {
+                    ServletOutputStream stream = response.getOutputStream();
+                    stream.close();
+                } catch (IllegalStateException f) {
+                    ;
+                } catch (IOException f) {
+                    ;
+                }
+            } catch (IOException e) {
+                ;
+            }
+        }
+    }
+
+    
+    
+    /**
+     * Include the response from another resource in the current response.
+     * Any runtime exception, IOException, or ServletException thrown by the
+     * called servlet will be propogated to the caller.
+     *
+     * @param request The servlet request that is including this one
+     * @param response The servlet response to be appended to
+     *
+     * @exception IOException if an input/output error occurs
+     * @exception ServletException if a servlet exception occurs
+     */
+    public void include(ServletRequest request, ServletResponse response)
+        throws ServletException, IOException
+    {
+
+        // Set up to handle the specified request and response
+        setup(request, response, true);
+
+        // Create a wrapped response to use for this request
+        // this actually gets inserted somewhere in the chain - it's not 
+        // the last one, but first non-user response
+        wrapResponse();
+        ServletRequestWrapperImpl wrequest =
+            (ServletRequestWrapperImpl) wrapRequest();
+
+
+        // Handle an HTTP named dispatcher include
+        if (name != null) {
+            wrequest.setAttribute(NAMED_DISPATCHER_ATTR, name);
+            if (servletPath != null) wrequest.setServletPath(servletPath);
+            wrequest.setAttribute(WebappFilterMapper.DISPATCHER_TYPE_ATTR,
+                                  new Integer(WebappFilterMapper.INCLUDE));
+            wrequest.setAttribute(WebappFilterMapper.DISPATCHER_REQUEST_PATH_ATTR, 
+                                  origServletPath);
+        } else {
+            mapPath();
+            String contextPath = ctx.getContextPath();
+            if (requestURI != null)
+                wrequest.setAttribute(INCLUDE_REQUEST_URI_ATTR,
+                                      requestURI);
+            if (contextPath != null)
+                wrequest.setAttribute(INCLUDE_CONTEXT_PATH_ATTR,
+                                      contextPath);
+            if (servletPath != null)
+                wrequest.setAttribute(INCLUDE_SERVLET_PATH_ATTR,
+                                      servletPath);
+            if (pathInfo != null)
+                wrequest.setAttribute(INCLUDE_PATH_INFO_ATTR,
+                                      pathInfo);
+            if (queryString != null) {
+                wrequest.setAttribute(INCLUDE_QUERY_STRING_ATTR,
+                                      queryString);
+                wrequest.setQueryParams(queryString);
+            }
+            
+            wrequest.setAttribute(WebappFilterMapper.DISPATCHER_TYPE_ATTR,
+                                  new Integer(WebappFilterMapper.INCLUDE));
+            wrequest.setAttribute(WebappFilterMapper.DISPATCHER_REQUEST_PATH_ATTR, 
+                                  origServletPath);
+        }
+
+        invoke(outerRequest, outerResponse);
+
+        wrequest.recycle();
+        unwrapRequest();
+        unwrapResponse();
+    }
+
+
+    // -------------------------------------------------------- Private Methods
+
+    public void mapPath() {
+        if (path == null || servletPath != null) return;
+        
+        // Retrieve the thread local URI, used for mapping
+        // TODO: recycle RequestDispatcher stack and associated objects
+        // instead of this object
+        
+        // Retrieve the thread local mapping data
+        MappingData mappingData = (MappingData) localMappingData.get();
+        if (mappingData == null) {
+            mappingData = new MappingData();
+            localMappingData.set(mappingData);
+        }
+
+        // Get query string
+        int pos = path.indexOf('?');
+        if (pos >= 0) {
+            queryString = path.substring(pos + 1);
+        } else {
+            pos = path.length();
+        }
+ 
+        // Map the URI
+        MessageBytes uriMB = MessageBytes.newInstance();
+        CharChunk charBuffer = new CharChunk();
+        //mappingData.localURIBytes;
+        uriMB.recycle();
+        //CharChunk uriCC = uriMB.getCharChunk();
+        try {
+            /*
+             * Ignore any trailing path params (separated by ';') for mapping
+             * purposes.
+             * This is sometimes broken - path params can be on any path 
+             * component, not just last.
+             */
+            int semicolon = path.indexOf(';');
+            if (pos >= 0 && semicolon > pos) {
+                semicolon = -1;
+            }
+            if (ctx.getContextPath().length() > 1 ) {
+                charBuffer.append(ctx.getContextPath());
+            }
+            charBuffer.append(path, 0, 
+                semicolon > 0 ? semicolon : pos);
+
+            // Wrap the buffer 
+            uriMB.setChars(charBuffer.getBuffer(),
+                    charBuffer.getOffset(),
+                    charBuffer.getLength());
+
+            // TODO: make charBuffer part of request or something
+            ctx.getMapper().map(uriMB, mappingData);
+            
+            // at least default wrapper must be returned
+            
+            /*
+             * Append any trailing path params (separated by ';') that were
+             * ignored for mapping purposes, so that they're reflected in the
+             * RequestDispatcher's requestURI
+             */
+            if (semicolon > 0) {
+                // I don't think this will be used in future
+                charBuffer.append(path, 
+                    semicolon, pos - semicolon);
+            }
+        } catch (Exception e) {
+            log.log(Level.SEVERE, "getRequestDispatcher()", e);
+        }
+
+        wrapper = (ServletConfigImpl) mappingData.wrapper;
+        servletPath = mappingData.wrapperPath.toString();
+        pathInfo = mappingData.pathInfo.toString();
+
+        mappingData.recycle();
+
+    }
+    
+
+    /**
+     * Prepare the request based on the filter configuration.
+     * @param request The servlet request we are processing
+     * @param response The servlet response we are creating
+     *
+     * @exception IOException if an input/output error occurs
+     * @exception ServletException if a servlet error occurs
+     */
+    private void processRequest(ServletRequest request, 
+                                ServletResponse response)
+            throws IOException, ServletException {
+        Integer disInt = 
+            (Integer) request.getAttribute(WebappFilterMapper.DISPATCHER_TYPE_ATTR);
+        if (disInt != null) {
+            if (disInt.intValue() != WebappFilterMapper.ERROR) {
+                outerRequest.setAttribute
+                    (WebappFilterMapper.DISPATCHER_REQUEST_PATH_ATTR,
+                     origServletPath);
+                outerRequest.setAttribute
+                    (WebappFilterMapper.DISPATCHER_TYPE_ATTR,
+                     new Integer(WebappFilterMapper.FORWARD));
+            }
+            invoke(outerRequest, response);
+        }
+
+    }
+    
+    
+    
+
+    /**
+     * Ask the resource represented by this RequestDispatcher to process
+     * the associated request, and create (or append to) the associated
+     * response.
+     * <p>
+     * <strong>IMPLEMENTATION NOTE</strong>: This implementation assumes
+     * that no filters are applied to a forwarded or included resource,
+     * because they were already done for the original request.
+     *
+     * @param request The servlet request we are processing
+     * @param response The servlet response we are creating
+     *
+     * @exception IOException if an input/output error occurs
+     * @exception ServletException if a servlet error occurs
+     */
+    private void invoke(ServletRequest request, ServletResponse response)
+            throws IOException, ServletException {
+
+        // Checking to see if the context classloader is the current context
+        // classloader. If it's not, we're saving it, and setting the context
+        // classloader to the Context classloader
+        ClassLoader oldCCL = Thread.currentThread().getContextClassLoader();
+        ClassLoader contextClassLoader = ctx.getClassLoader();
+
+        if (oldCCL != contextClassLoader) {
+            Thread.currentThread().setContextClassLoader(contextClassLoader);
+        } else {
+            oldCCL = null;
+        }
+
+        // Initialize local variables we may need
+        HttpServletResponse hresponse = (HttpServletResponse) response;
+        IOException ioException = null;
+        ServletException servletException = null;
+        RuntimeException runtimeException = null;
+        
+        servletException = allocateServlet(hresponse, servletException);
+                
+        // Get the FilterChain Here
+        WebappFilterMapper factory = 
+            ((ServletContextImpl)wrapper.getServletContext()).getFilterMapper();
+        
+        FilterChainImpl filterChain = factory.createFilterChain(request,
+                                                                wrapper,
+                                                                servlet);
+
+        // Call the service() method for the allocated servlet instance
+        try {
+            String jspFile = wrapper.getJspFile();
+            if (jspFile != null)
+                request.setAttribute(JSP_FILE_ATTR, jspFile);
+            else
+                request.removeAttribute(JSP_FILE_ATTR);
+            // for includes/forwards
+            if ((servlet != null) && (filterChain != null)) {
+               filterChain.doFilter(request, response);
+             }
+        } catch (IOException e) {
+            ctx.getLogger().log(Level.WARNING, "RequestDispatcherImpl error " + 
+                    wrapper.getServletName(), e);
+            ioException = e;
+        } catch (UnavailableException e) {
+            ctx.getLogger().log(Level.WARNING, "RequestDispatcherImpl error " + 
+                    wrapper.getServletName(), e);
+            servletException = e;
+            wrapper.unavailable(e);
+        } catch (ServletException e) {
+            servletException = e;
+        } catch (RuntimeException e) {
+            ctx.getLogger().log(Level.WARNING, "RequestDispatcherImpl error " + 
+                    wrapper.getServletName(), e);
+            runtimeException = e;
+        }
+        request.removeAttribute(JSP_FILE_ATTR);
+
+        // Release the filter chain (if any) for this request
+        if (filterChain != null)
+            filterChain.release();
+
+        servletException = servletDealocate(servletException);
+
+        // Reset the old context class loader
+        if (oldCCL != null)
+            Thread.currentThread().setContextClassLoader(oldCCL);
+        
+        // Unwrap request/response if needed
+        unwrapRequest();
+        unwrapResponse();
+
+        // Rethrow an exception if one was thrown by the invoked servlet
+        if (ioException != null)
+            throw ioException;
+        if (servletException != null)
+            throw servletException;
+        if (runtimeException != null)
+            throw runtimeException;
+
+    }
+
+    private ServletException servletDealocate(ServletException servletException)
+    {
+        if (servlet != null) {
+            wrapper.deallocate(servlet);
+        }
+        return servletException;
+    }
+
+    private ServletException allocateServlet(HttpServletResponse hresponse,
+                                             ServletException servletException)
+        throws IOException
+    {
+        boolean unavailable = false;
+
+        // Check for the servlet being marked unavailable
+        if (wrapper.isUnavailable()) {
+            ctx.getLogger().log(Level.WARNING, "isUnavailable() " + wrapper.getServletName());
+            long available = wrapper.getAvailable();
+            if ((available > 0L) && (available < Long.MAX_VALUE))
+                hresponse.setDateHeader("Retry-After", available);
+            hresponse.sendError(HttpServletResponse.SC_SERVICE_UNAVAILABLE, 
+                    "Unavailable"); // No need to include internal info: wrapper.getServletName();
+            unavailable = true;
+        }
+
+        // Allocate a servlet instance to process this request
+        try {
+            if (!unavailable) {
+                servlet = wrapper.allocate();
+            }
+        } catch (ServletException e) {
+            ctx.getLogger().log(Level.WARNING, "RequestDispatcher: allocate " + 
+                             wrapper.toString());
+            servletException = e;
+            servlet = null;
+        } catch (Throwable e) {
+            ctx.getLogger().log(Level.WARNING, "allocate() error " + wrapper.getServletName(), e);
+            servletException = new ServletException
+                ("Allocate error " + wrapper.getServletName(), e);
+            servlet = null;
+        }
+        return servletException;
+    }
+
+
+    /**
+     * Set up to handle the specified request and response
+     *
+     * @param request The servlet request specified by the caller
+     * @param response The servlet response specified by the caller
+     * @param including Are we performing an include() as opposed to
+     *  a forward()?
+     */
+    private void setup(ServletRequest request, ServletResponse response,
+                       boolean including) {
+
+        this.outerRequest = request;
+        this.outerResponse = response;
+    }
+
+
+    /**
+     * Unwrap the request if we have wrapped it. Not sure how it could end
+     * up in the middle. 
+     */
+    private void unwrapRequest() {
+        if (wrapRequest == null)
+            return;
+
+        ServletRequest previous = null;
+        ServletRequest current = outerRequest;
+        while (current != null) {
+            // If we run into the container request we are done
+            if (current instanceof ServletRequestImpl)
+                break;
+
+            // Remove the current request if it is our wrapper
+            if (current == wrapRequest) {
+                ServletRequest next =
+                  ((ServletRequestWrapper) current).getRequest();
+                if (previous == null)
+                    outerRequest = next;
+                else
+                    ((ServletRequestWrapper) previous).setRequest(next);
+                break;
+            }
+
+            // Advance to the next request in the chain
+            previous = current;
+            current = ((ServletRequestWrapper) current).getRequest();
+        }
+    }
+
+
+    /**
+     * Unwrap the response if we have wrapped it.
+     */
+    private void unwrapResponse() {
+        if (wrapResponse == null)
+            return;
+
+        ServletResponse previous = null;
+        ServletResponse current = outerResponse;
+        while (current != null) {
+            // If we run into the container response we are done
+            if (current instanceof ServletResponseImpl)
+                break;
+
+            // Remove the current response if it is our wrapper
+            if (current == wrapResponse) {
+                ServletResponse next =
+                  ((ServletResponseWrapper) current).getResponse();
+                if (previous == null)
+                    outerResponse = next;
+                else
+                    ((ServletResponseWrapper) previous).setResponse(next);
+                break;
+            }
+            // Advance to the next response in the chain
+            previous = current;
+            current = ((ServletResponseWrapper) current).getResponse();
+        }
+    }
+
+
+    /**
+     * Create and return a request wrapper that has been inserted in the
+     * appropriate spot in the request chain.
+     */
+    private ServletRequest wrapRequest() {
+        // Locate the request we should insert in front of
+        ServletRequest previous = null;
+        ServletRequest current = outerRequest;
+        while (current != null) {
+            if (!(current instanceof ServletRequestWrapper))
+                break;
+            if (current instanceof ServletRequestWrapperImpl)
+                break;
+            if (current instanceof ServletRequestImpl)
+                break;
+            // user-specified
+            previous = current;
+            current = ((ServletRequestWrapper) current).getRequest();
+        }
+        // now previous will be a user-specified wrapper, 
+        // and current one of our own wrappers ( deeper in stack )
+        // ... current USER_previous USER USER
+        // previous is null if the top request is ours.
+
+        // Instantiate a new wrapper at this point and insert it in the chain
+        ServletRequest wrapper = null;
+        
+        // Compute a crossContext flag
+        boolean crossContext = isCrossContext();
+        wrapper = 
+            new ServletRequestWrapperImpl((HttpServletRequest) current, 
+                                          ctx, crossContext);
+
+        if (previous == null) {
+            // outer becomes the wrapper, includes orig wrapper inside
+            outerRequest = wrapper;
+        } else {
+            // outer remains user-specified sersvlet, delegating to 
+            // our wrapper, which delegates to real request or our wrapper.
+            ((ServletRequestWrapper) previous).setRequest(wrapper);
+        }
+        wrapRequest = wrapper;
+        return (wrapper);
+    }
+
+    private boolean isCrossContext() {
+        boolean crossContext = false;
+        if ((outerRequest instanceof ServletRequestWrapperImpl) ||
+                (outerRequest instanceof ServletRequestImpl) ||
+                (outerRequest instanceof HttpServletRequest)) {
+            HttpServletRequest houterRequest = 
+                (HttpServletRequest) outerRequest;
+            Object contextPath = 
+                houterRequest.getAttribute(INCLUDE_CONTEXT_PATH_ATTR);
+            if (contextPath == null) {
+                // Forward
+                contextPath = houterRequest.getContextPath();
+            }
+            crossContext = !(ctx.getContextPath().equals(contextPath));
+        }
+        return crossContext;
+    }
+
+
+    /**
+     * Create and return a response wrapper that has been inserted in the
+     * appropriate spot in the response chain.
+     * 
+     * Side effect: updates outerResponse, wrapResponse.
+     * The chain is updated with a wrapper below lowest user wrapper
+     */
+    private ServletResponse wrapResponse() {
+        // Locate the response we should insert in front of
+        ServletResponse previous = null;
+        ServletResponse current = outerResponse;
+        while (current != null) {
+            if (!(current instanceof ServletResponseWrapper))
+                break;
+            if (current instanceof ServletResponseImpl)
+                break;
+            previous = current;
+            current = ((ServletResponseWrapper) current).getResponse();
+        }
+
+        // Instantiate a new wrapper at this point and insert it in the chain
+        ServletResponse wrapper = 
+             new ServletResponseIncludeWrapper(current);
+            
+        if (previous == null) {
+            // outer is ours, we can wrap on top
+            outerResponse = wrapper;
+        } else {
+            // outer is user-specified, leave it alone. 
+            // we insert ourself below the lowest user-specified response
+            ((ServletResponseWrapper) previous).setResponse(wrapper);
+        }
+        wrapResponse = wrapper;
+        return (wrapper);
+
+    }
+
+
+}

Propchange: tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/RequestDispatcherImpl.java
------------------------------------------------------------------------------
    svn:eol-style = native



---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org


Mime
View raw message