You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by co...@apache.org on 2006/05/20 04:12:52 UTC

svn commit: r407939 [5/8] - in /tomcat/sandbox/java/org/apache/coyote/servlet: ./ util/

Added: tomcat/sandbox/java/org/apache/coyote/servlet/ServletContextImpl.java
URL: http://svn.apache.org/viewvc/tomcat/sandbox/java/org/apache/coyote/servlet/ServletContextImpl.java?rev=407939&view=auto
==============================================================================
--- tomcat/sandbox/java/org/apache/coyote/servlet/ServletContextImpl.java (added)
+++ tomcat/sandbox/java/org/apache/coyote/servlet/ServletContextImpl.java Fri May 19 19:12:51 2006
@@ -0,0 +1,1111 @@
+/*
+ * 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.coyote.servlet;
+
+
+import java.io.File;
+import java.io.InputStream;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Set;
+
+//import javax.naming.Binding;
+//import javax.naming.NamingException;
+//import javax.naming.directory.DirContext;
+import javax.servlet.RequestDispatcher;
+import javax.servlet.Servlet;
+import javax.servlet.ServletContext;
+import javax.servlet.ServletContextAttributeEvent;
+import javax.servlet.ServletContextAttributeListener;
+
+import org.apache.commons.logging.Log;
+import org.apache.coyote.servlet.util.CharsetMapper;
+import org.apache.coyote.servlet.util.Enumerator;
+
+//import org.apache.naming.resources.DirContextURLStreamHandler;
+//import org.apache.naming.resources.Resource;
+
+import org.apache.tomcat.util.buf.CharChunk;
+import org.apache.tomcat.util.buf.MessageBytes;
+import org.apache.tomcat.util.http.mapper.MappingData;
+import org.apache.tomcat.util.res.StringManager;
+
+
+/**
+ * Standard implementation of <code>ServletContext</code> that represents
+ * a web application's execution environment.  An instance of this class is
+ * associated with each instance of <code>StandardContext</code>.
+ *
+ * @author Craig R. McClanahan
+ * @author Remy Maucherat
+ * @version $Revision: 377994 $ $Date: 2006-02-15 04:37:28 -0800 (Wed, 15 Feb 2006) $
+ */
+
+public class ServletContextImpl
+    implements ServletContext {
+
+    // ----------------------------------------------------------- Constructors
+
+    public ServletContextImpl(String basePath) {
+        this.basePath = basePath;
+    }
+
+
+    // ----------------------------------------------------- Instance Variables
+
+
+    /**
+     * The context attributes for this context.
+     */
+    private HashMap attributes = new HashMap();
+
+
+    /**
+     * List of read only attributes for this context.
+     */
+    private HashMap readOnlyAttributes = new HashMap();
+
+
+    /**
+     * The Context instance with which we are associated.
+     */
+    private ServletContextImpl context = this;
+
+    /** Internal mapper - it may be better to use only one per server.
+     */ 
+    private org.apache.tomcat.util.http.mapper.Mapper mapper = 
+        new org.apache.tomcat.util.http.mapper.Mapper();
+
+
+    /**
+     * Empty collection to serve as the basis for empty enumerations.
+     * <strong>DO NOT ADD ANY ELEMENTS TO THIS COLLECTION!</strong>
+     */
+    private static final ArrayList empty = new ArrayList();
+
+
+//    /**
+//     * The facade around this object.
+//     */
+//    private ServletContext facade = new ApplicationContextFacade(this);
+
+
+    /**
+     * The merged context initialization parameters for this Context.
+     */
+    private HashMap parameters = null;
+
+
+    /**
+     * The string manager for this package.
+     */
+    private static final StringManager sm =
+      StringManager.getManager("org.apache.coyote.servlet");
+
+
+    /**
+     * Base path.
+     */
+    private String basePath = null;
+
+
+    /**
+     * Thread local mapping data.
+     */
+    private ThreadLocal localMappingData = new ThreadLocal();
+
+
+    /**
+     * Thread local URI message bytes.
+     */
+    private ThreadLocal localUriMB = new ThreadLocal();
+
+
+    private String contextName = "";
+    
+    private Host host;
+
+    private SessionManager manager = new SessionManager();
+
+    // --------------------------------------------------------- Public Methods
+
+
+    /**
+     * Return the resources object that is mapped to a specified path.
+     * The path must begin with a "/" and is interpreted as relative to the
+     * current context root.
+     */
+//    public DirContext getResources() {
+//
+//        return context.getResources();
+//
+//    }
+
+
+    // ------------------------------------------------- ServletContext Methods
+
+
+    /**
+     * Return the value of the specified context attribute, if any;
+     * otherwise return <code>null</code>.
+     *
+     * @param name Name of the context attribute to return
+     */
+    public Object getAttribute(String name) {
+
+        synchronized (attributes) {
+            return (attributes.get(name));
+        }
+
+    }
+
+
+    /**
+     * Return an enumeration of the names of the context attributes
+     * associated with this context.
+     */
+    public Enumeration getAttributeNames() {
+
+        synchronized (attributes) {
+            return new Enumerator(attributes.keySet(), true);
+        }
+
+    }
+
+
+    /**
+     * Return a <code>ServletContext</code> object that corresponds to a
+     * specified URI on the server.  This method allows servlets to gain
+     * access to the context for various parts of the server, and as needed
+     * obtain <code>RequestDispatcher</code> objects or resources from the
+     * context.  The given path must be absolute (beginning with a "/"),
+     * and is interpreted based on our virtual host's document root.
+     *
+     * @param uri Absolute URI of a resource on the server
+     */
+    public ServletContext getContext(String uri) {
+
+        // Validate the format of the specified argument
+        if ((uri == null) || (!uri.startsWith("/")))
+            return (null);
+
+        ServletContextImpl child = null;
+        try {
+            Host host = (Host) context.getParent();
+            String mapuri = uri;
+            while (true) {
+                child = (ServletContextImpl) host.findChild(mapuri);
+                if (child != null)
+                    break;
+                int slash = mapuri.lastIndexOf('/');
+                if (slash < 0)
+                    break;
+                mapuri = mapuri.substring(0, slash);
+            }
+        } catch (Throwable t) {
+            return (null);
+        }
+
+        if (child == null)
+            return (null);
+
+        if (context.getCrossContext()) {
+            // If crossContext is enabled, can always return the context
+            return child.getServletContext();
+        } else if (child == context) {
+            // Can still return the current context
+            return context.getServletContext();
+        } else {
+            // Nothing to return
+            return (null);
+        }
+    }
+
+    
+    /**
+     * Return the main path associated with this context.
+     */
+    public String getContextPath() {
+        return context.getPath();
+    }
+    
+
+    /**
+     * Return the value of the specified initialization parameter, or
+     * <code>null</code> if this parameter does not exist.
+     *
+     * @param name Name of the initialization parameter to retrieve
+     */
+    public String getInitParameter(final String name) {
+
+        mergeParameters();
+        synchronized (parameters) {
+            return ((String) parameters.get(name));
+        }
+    }
+
+
+    /**
+     * Return the names of the context's initialization parameters, or an
+     * empty enumeration if the context has no initialization parameters.
+     */
+    public Enumeration getInitParameterNames() {
+
+        mergeParameters();
+        synchronized (parameters) {
+           return (new Enumerator(parameters.keySet()));
+        }
+
+    }
+
+
+    /**
+     * Return the major version of the Java Servlet API that we implement.
+     */
+    public int getMajorVersion() {
+
+        return 3;
+
+    }
+
+
+    /**
+     * Return the minor version of the Java Servlet API that we implement.
+     */
+    public int getMinorVersion() {
+
+        return 4;
+
+    }
+
+
+    /**
+     * Return the MIME type of the specified file, or <code>null</code> if
+     * the MIME type cannot be determined.
+     *
+     * @param file Filename for which to identify a MIME type
+     */
+    public String getMimeType(String file) {
+
+        if (file == null)
+            return (null);
+        int period = file.lastIndexOf(".");
+        if (period < 0)
+            return (null);
+        String extension = file.substring(period + 1);
+        if (extension.length() < 1)
+            return (null);
+        return (context.findMimeMapping(extension));
+
+    }
+
+
+    /**
+     * Return a <code>RequestDispatcher</code> object that acts as a
+     * wrapper for the named servlet.
+     *
+     * @param name Name of the servlet for which a dispatcher is requested
+     */
+    public RequestDispatcher getNamedDispatcher(String name) {
+
+        // Validate the name argument
+        if (name == null)
+            return (null);
+
+        // Create and return a corresponding request dispatcher
+        ServletConfigImpl wrapper = (ServletConfigImpl) context.findChild(name);
+        if (wrapper == null)
+            return (null);
+        
+        return new RequestDispatcherImpl(wrapper, null, null, null, null, name);
+
+    }
+
+
+    /**
+     * Return the real path for a given virtual path, if possible; otherwise
+     * return <code>null</code>.
+     *
+     * @param path The path to the desired resource
+     */
+    public String getRealPath(String path) {
+
+        if (!context.isFilesystemBased())
+            return null;
+
+        if (path == null) {
+            return null;
+        }
+
+        File file = new File(basePath, path);
+        return (file.getAbsolutePath());
+
+    }
+
+
+
+    /**
+     * Return a <code>RequestDispatcher</code> instance that acts as a
+     * wrapper for the resource at the given path.  The path must begin
+     * with a "/" and is interpreted as relative to the current context root.
+     *
+     * @param path The path to the desired resource.
+     */
+    public RequestDispatcher getRequestDispatcher(String path) {
+
+        // Validate the path argument
+        if (path == null)
+            return (null);
+        if (!path.startsWith("/"))
+            throw new IllegalArgumentException
+                (sm.getString
+                 ("applicationContext.requestDispatcher.iae", path));
+        path = normalize(path);
+        if (path == null)
+            return (null);
+
+        // Retrieve the thread local URI
+        MessageBytes uriMB = (MessageBytes) localUriMB.get();
+        if (uriMB == null) {
+            uriMB = MessageBytes.newInstance();
+            CharChunk uriCC = uriMB.getCharChunk();
+            uriCC.setLimit(-1);
+            localUriMB.set(uriMB);
+        } else {
+            uriMB.recycle();
+        }
+
+        // Get query string
+        String queryString = null;
+        int pos = path.indexOf('?');
+        if (pos >= 0) {
+            queryString = path.substring(pos + 1);
+        } else {
+            pos = path.length();
+        }
+ 
+        // Retrieve the thread local mapping data
+        MappingData mappingData = (MappingData) localMappingData.get();
+        if (mappingData == null) {
+            mappingData = new MappingData();
+            localMappingData.set(mappingData);
+        }
+
+        // Map the URI
+        CharChunk uriCC = uriMB.getCharChunk();
+        try {
+            uriCC.append(context.getPath(), 0, context.getPath().length());
+            /*
+             * Ignore any trailing path params (separated by ';') for mapping
+             * purposes
+             */
+            int semicolon = path.indexOf(';');
+            if (pos >= 0 && semicolon > pos) {
+                semicolon = -1;
+            }
+            uriCC.append(path, 0, semicolon > 0 ? semicolon : pos);
+            context.getMapper().map(uriMB, mappingData);
+            if (mappingData.wrapper == null) {
+                return (null);
+            }
+            /*
+             * 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) {
+                uriCC.append(path, semicolon, pos - semicolon);
+            }
+        } catch (Exception e) {
+            // Should never happen
+            log(sm.getString("applicationContext.mapping.error"), e);
+            return (null);
+        }
+
+        ServletConfigImpl wrapper = (ServletConfigImpl) mappingData.wrapper;
+        String wrapperPath = mappingData.wrapperPath.toString();
+        String pathInfo = mappingData.pathInfo.toString();
+
+        mappingData.recycle();
+        
+        // Construct a RequestDispatcher to process this request
+        return new RequestDispatcherImpl
+            (wrapper, uriCC.toString(), wrapperPath, pathInfo, 
+             queryString, null);
+
+    }
+
+
+
+    /**
+     * Return the URL to the resource that is mapped to a specified path.
+     * The path must begin with a "/" and is interpreted as relative to the
+     * current context root.
+     *
+     * @param path The path to the desired resource
+     *
+     * @exception MalformedURLException if the path is not given
+     *  in the correct form
+     */
+    public URL getResource(String path)
+        throws MalformedURLException {
+
+        if (path == null || !path.startsWith("/")) {
+            throw new MalformedURLException(sm.getString("applicationContext.requestDispatcher.iae", path));
+        }
+        
+        path = normalize(path);
+        if (path == null)
+            return (null);
+
+        String libPath = "/WEB-INF/lib/";
+        if ((path.startsWith(libPath)) && (path.endsWith(".jar"))) {
+            File jarFile = null;
+            if (context.isFilesystemBased()) {
+                jarFile = new File(basePath, path);
+            } else {
+                jarFile = new File(context.getWorkPath(), path);
+            }
+            if (jarFile.exists()) {
+                return jarFile.toURL();
+            } else {
+                return null;
+            }
+        } else {
+
+            // TODO(costin): File based resources !!
+            
+//            DirContext resources = context.getResources();
+//            if (resources != null) {
+//                String fullPath = context.getName() + path;
+//                String hostName = context.getParent().getName();
+//                try {
+//                    resources.lookup(path);
+//                    return new URL
+//                        ("jndi", "", 0, getJNDIUri(hostName, fullPath),
+//                         new DirContextURLStreamHandler(resources));
+//                } catch (Exception e) {
+//                    // Ignore
+//                }
+//            }
+        }
+
+        return (null);
+
+    }
+
+
+    Host getParent() {
+        return host;
+    }
+
+    void setParent(Host host) {
+        this.host = host;
+    }
+
+    String getName() {
+        return null;
+    }
+
+
+    private String getWorkPath() {
+        return null;
+    }
+
+
+    /**
+     * Return the requested resource as an <code>InputStream</code>.  The
+     * path must be specified according to the rules described under
+     * <code>getResource</code>.  If no such resource can be identified,
+     * return <code>null</code>.
+     *
+     * @param path The path to the desired resource.
+     */
+    public InputStream getResourceAsStream(String path) {
+
+        path = normalize(path);
+        if (path == null)
+            return (null);
+
+        // TODO(costin): file based resources
+//        DirContext resources = context.getResources();
+//        if (resources != null) {
+//            try {
+//                Object resource = resources.lookup(path);
+//                if (resource instanceof Resource)
+//                    return (((Resource) resource).streamContent());
+//            } catch (Exception e) {
+//            }
+//        }
+        return (null);
+
+    }
+
+
+    /**
+     * Return a Set containing the resource paths of resources member of the
+     * specified collection. Each path will be a String starting with
+     * a "/" character. The returned set is immutable.
+     *
+     * @param path Collection path
+     */
+    public Set getResourcePaths(String path) {
+
+        // Validate the path argument
+        if (path == null) {
+            return null;
+        }
+        if (!path.startsWith("/")) {
+            throw new IllegalArgumentException
+                (sm.getString("applicationContext.resourcePaths.iae", path));
+        }
+
+        path = normalize(path);
+        if (path == null)
+            return (null);
+
+        // TODO(costin): file based resources
+//        DirContext resources = context.getResources();
+//        if (resources != null) {
+//            return (getResourcePathsInternal(resources, path));
+//        }
+        return (null);
+
+    }
+
+
+    /**
+     * Internal implementation of getResourcesPath() logic.
+     *
+     * @param resources Directory context to search
+     * @param path Collection path
+     */
+//    private Set getResourcePathsInternal(DirContext resources, String path) {
+//
+//        HashSet set = new HashSet();
+//        try {
+//            listCollectionPaths(set, resources, path);
+//        } catch (NamingException e) {
+//            return (null);
+//        }
+//        //set.setLocked(true);
+//        return (set);
+//
+//    }
+
+
+    /**
+     * Return the name and version of the servlet container.
+     */
+    public String getServerInfo() {
+
+        return "Apache Tomcat";
+
+    }
+
+
+    /**
+     * @deprecated As of Java Servlet API 2.1, with no direct replacement.
+     */
+    public Servlet getServlet(String name) {
+
+        return (null);
+
+    }
+
+
+    /**
+     * Return the display name of this web application.
+     */
+    public String getServletContextName() {
+
+        return contextName ;
+
+    }
+
+
+    /**
+     * @deprecated As of Java Servlet API 2.1, with no direct replacement.
+     */
+    public Enumeration getServletNames() {
+        return (new Enumerator(empty));
+    }
+
+
+    /**
+     * @deprecated As of Java Servlet API 2.1, with no direct replacement.
+     */
+    public Enumeration getServlets() {
+        return (new Enumerator(empty));
+    }
+
+
+    /**
+     * Writes the specified message to a servlet log file.
+     *
+     * @param message Message to be written
+     */
+    public void log(String message) {
+
+        context.getLogger().info(message);
+
+    }
+
+
+    /**
+     * Writes the specified exception and message to a servlet log file.
+     *
+     * @param exception Exception to be reported
+     * @param message Message to be written
+     *
+     * @deprecated As of Java Servlet API 2.1, use
+     *  <code>log(String, Throwable)</code> instead
+     */
+    public void log(Exception exception, String message) {
+        
+        context.getLogger().error(message, exception);
+
+    }
+
+
+    /**
+     * Writes the specified message and exception to a servlet log file.
+     *
+     * @param message Message to be written
+     * @param throwable Exception to be reported
+     */
+    public void log(String message, Throwable throwable) {
+        
+        context.getLogger().error(message, throwable);
+
+    }
+
+
+    /**
+     * Remove the context attribute with the specified name, if any.
+     *
+     * @param name Name of the context attribute to be removed
+     */
+    public void removeAttribute(String name) {
+
+        Object value = null;
+        boolean found = false;
+
+        // Remove the specified attribute
+        synchronized (attributes) {
+            // Check for read only attribute
+           if (readOnlyAttributes.containsKey(name))
+                return;
+            found = attributes.containsKey(name);
+            if (found) {
+                value = attributes.get(name);
+                attributes.remove(name);
+            } else {
+                return;
+            }
+        }
+
+        // Notify interested application event listeners
+        Object listeners[] = context.getApplicationEventListeners();
+        if ((listeners == null) || (listeners.length == 0))
+            return;
+        ServletContextAttributeEvent event =
+          new ServletContextAttributeEvent(context.getServletContext(),
+                                            name, value);
+        for (int i = 0; i < listeners.length; i++) {
+            if (!(listeners[i] instanceof ServletContextAttributeListener))
+                continue;
+            ServletContextAttributeListener listener =
+                (ServletContextAttributeListener) listeners[i];
+            try {
+//                context.fireContainerEvent("beforeContextAttributeRemoved",
+//                                           listener);
+                listener.attributeRemoved(event);
+//                context.fireContainerEvent("afterContextAttributeRemoved",
+//                                           listener);
+            } catch (Throwable t) {
+//                context.fireContainerEvent("afterContextAttributeRemoved",
+//                                           listener);
+                // FIXME - should we do anything besides log these?
+                log(sm.getString("applicationContext.attributeEvent"), t);
+            }
+        }
+
+    }
+
+
+    /**
+     * Bind the specified value with the specified context attribute name,
+     * replacing any existing value for that name.
+     *
+     * @param name Attribute name to be bound
+     * @param value New attribute value to be bound
+     */
+    public void setAttribute(String name, Object value) {
+
+        // Name cannot be null
+        if (name == null)
+            throw new IllegalArgumentException
+                (sm.getString("applicationContext.setAttribute.namenull"));
+
+        // Null value is the same as removeAttribute()
+        if (value == null) {
+            removeAttribute(name);
+            return;
+        }
+
+        Object oldValue = null;
+        boolean replaced = false;
+
+        // Add or replace the specified attribute
+        synchronized (attributes) {
+            // Check for read only attribute
+            if (readOnlyAttributes.containsKey(name))
+                return;
+            oldValue = attributes.get(name);
+            if (oldValue != null)
+                replaced = true;
+            attributes.put(name, value);
+        }
+
+        // Notify interested application event listeners
+        Object listeners[] = context.getApplicationEventListeners();
+        if ((listeners == null) || (listeners.length == 0))
+            return;
+        ServletContextAttributeEvent event = null;
+        if (replaced)
+            event =
+                new ServletContextAttributeEvent(context.getServletContext(),
+                                                 name, oldValue);
+        else
+            event =
+                new ServletContextAttributeEvent(context.getServletContext(),
+                                                 name, value);
+
+        for (int i = 0; i < listeners.length; i++) {
+            if (!(listeners[i] instanceof ServletContextAttributeListener))
+                continue;
+            ServletContextAttributeListener listener =
+                (ServletContextAttributeListener) listeners[i];
+            try {
+                if (replaced) {
+//                    context.fireContainerEvent
+//                        ("beforeContextAttributeReplaced", listener);
+                    listener.attributeReplaced(event);
+//                    context.fireContainerEvent("afterContextAttributeReplaced",
+//                                               listener);
+                } else {
+//                    context.fireContainerEvent("beforeContextAttributeAdded",
+//                                               listener);
+                    listener.attributeAdded(event);
+//                    context.fireContainerEvent("afterContextAttributeAdded",
+//                                               listener);
+                }
+            } catch (Throwable t) {
+//                if (replaced)
+//                    context.fireContainerEvent("afterContextAttributeReplaced",
+//                                               listener);
+//                else
+//                    context.fireContainerEvent("afterContextAttributeAdded",
+//                                               listener);
+                // FIXME - should we do anything besides log these?
+                log(sm.getString("applicationContext.attributeEvent"), t);
+            }
+        }
+
+    }
+
+
+    // -------------------------------------------------------- Package Methods
+
+
+    /**
+     * Clear all application-created attributes.
+     */
+    void clearAttributes() {
+
+        // Create list of attributes to be removed
+        ArrayList list = new ArrayList();
+        synchronized (attributes) {
+            Iterator iter = attributes.keySet().iterator();
+            while (iter.hasNext()) {
+                list.add(iter.next());
+            }
+        }
+
+        // Remove application originated attributes
+        // (read only attributes will be left in place)
+        Iterator keys = list.iterator();
+        while (keys.hasNext()) {
+            String key = (String) keys.next();
+            removeAttribute(key);
+        }
+        
+    }
+    
+    
+//    /**
+//     * Return the facade associated with this ApplicationContext.
+//     */
+//    protected ServletContext getFacade() {
+//
+//        return (this.facade);
+//
+//    }
+
+
+    /**
+     * Set an attribute as read only.
+     */
+    void setAttributeReadOnly(String name) {
+
+        synchronized (attributes) {
+            if (attributes.containsKey(name))
+                readOnlyAttributes.put(name, name);
+        }
+
+    }
+
+
+    // -------------------------------------------------------- Private Methods
+
+
+    /**
+     * Return a context-relative path, beginning with a "/", that represents
+     * the canonical version of the specified path after ".." and "." elements
+     * are resolved out.  If the specified path attempts to go outside the
+     * boundaries of the current context (i.e. too many ".." path elements
+     * are present), return <code>null</code> instead.
+     *
+     * @param path Path to be normalized
+     */
+    private String normalize(String path) {
+
+        if (path == null) {
+            return null;
+        }
+
+        String normalized = path;
+
+        // Normalize the slashes and add leading slash if necessary
+        if (normalized.indexOf('\\') >= 0)
+            normalized = normalized.replace('\\', '/');
+
+        // Resolve occurrences of "/../" in the normalized path
+        while (true) {
+            int index = normalized.indexOf("/../");
+            if (index < 0)
+                break;
+            if (index == 0)
+                return (null);  // Trying to go outside our context
+            int index2 = normalized.lastIndexOf('/', index - 1);
+            normalized = normalized.substring(0, index2) +
+                normalized.substring(index + 3);
+        }
+
+        // Return the normalized path that we have completed
+        return (normalized);
+
+    }
+
+
+    /**
+     * Merge the context initialization parameters specified in the application
+     * deployment descriptor with the application parameters described in the
+     * server configuration, respecting the <code>override</code> property of
+     * the application parameters appropriately.
+     */
+    private void mergeParameters() {
+
+        if (parameters != null)
+            return;
+//        HashMap results = new HashMap();
+//        String names[] = context.findParameters();
+//        for (int i = 0; i < names.length; i++)
+//            results.put(names[i], context.findParameter(names[i]));
+//        ApplicationParameter params[] =
+//            context.findApplicationParameters();
+//        for (int i = 0; i < params.length; i++) {
+//            if (params[i].getOverride()) {
+//                if (results.get(params[i].getName()) == null)
+//                    results.put(params[i].getName(), params[i].getValue());
+//            } else {
+//                results.put(params[i].getName(), params[i].getValue());
+//            }
+//        }
+//        parameters = results;
+
+    }
+
+
+    /**
+     * List resource paths (recursively), and store all of them in the given
+     * Set.
+     */
+//    private static void listCollectionPaths
+//        (Set set, DirContext resources, String path)
+//        throws NamingException {
+//
+//        Enumeration childPaths = resources.listBindings(path);
+//        while (childPaths.hasMoreElements()) {
+//            Binding binding = (Binding) childPaths.nextElement();
+//            String name = binding.getName();
+//            StringBuffer childPath = new StringBuffer(path);
+//            if (!"/".equals(path) && !path.endsWith("/"))
+//                childPath.append("/");
+//            childPath.append(name);
+//            Object object = binding.getObject();
+//            if (object instanceof DirContext) {
+//                childPath.append("/");
+//            }
+//            set.add(childPath.toString());
+//        }
+//
+//    }
+
+
+    /**
+     * Get full path, based on the host name and the context path.
+     */
+//    private static String getJNDIUri(String hostName, String path) {
+//        if (!path.startsWith("/"))
+//            return "/" + hostName + "/" + path;
+//        else
+//            return "/" + hostName + path;
+//    }
+
+    CharsetMapper charsetMapper = new CharsetMapper();
+    String path;
+    
+    public CharsetMapper getCharsetMapper() {
+        return charsetMapper;
+    }
+
+
+    public String getPath() {
+        return path;
+    }
+
+    void setPath(String path) {
+        this.path = path;
+    }
+
+    public SessionManager getManager() {
+        return manager;
+    }
+
+
+    public ApplicationAuthorization getRealm() {
+        return null;
+    }
+
+
+    public String getEncodedPath() {
+        return null;
+    }
+
+
+    public boolean getCookies() {
+        return false;
+    }
+
+
+    public ServletContext getServletContext() {
+        return this;
+    }
+
+
+    public Object[] getApplicationEventListeners() {
+        return null;
+    }
+
+
+    public Log getLogger() {
+        return null;
+    }
+
+
+    public boolean getSwallowOutput() {
+        return false;
+    }
+
+
+    public long getUnloadDelay() {
+        return 0;
+    }
+
+
+    public ServletConfigImpl findChild(String jsp_servlet_name) {
+        return null;
+    }
+
+
+    public boolean getPrivileged() {
+        return false;
+    }
+
+    private boolean getCrossContext() {
+        return true;
+    }
+
+    private boolean isFilesystemBased() {
+        return true;
+    }
+
+
+    private String findMimeMapping(String extension) {
+        return null;
+    }
+
+
+    public void destroy() {
+    }
+
+    public org.apache.tomcat.util.http.mapper.Mapper getMapper() {
+        return (mapper);
+    }
+
+
+    public FilterMap[] findFilterMaps() {
+        return null;
+    }
+
+
+    public FilterConfigImpl findFilterConfig(String filterName) {
+        return null;
+    }
+
+
+    public ClassLoader getClassLoader() {
+        return this.getClass().getClassLoader();
+    }
+
+
+    public Object[] getApplicationLifecycleListeners() {
+        return null;
+    }
+
+    void setContextParameters(HashMap params) {
+        this.parameters = params;
+    }
+}

Added: tomcat/sandbox/java/org/apache/coyote/servlet/ServletInputStreamImpl.java
URL: http://svn.apache.org/viewvc/tomcat/sandbox/java/org/apache/coyote/servlet/ServletInputStreamImpl.java?rev=407939&view=auto
==============================================================================
--- tomcat/sandbox/java/org/apache/coyote/servlet/ServletInputStreamImpl.java (added)
+++ tomcat/sandbox/java/org/apache/coyote/servlet/ServletInputStreamImpl.java Fri May 19 19:12:51 2006
@@ -0,0 +1,111 @@
+/*
+ * 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.coyote.servlet;
+
+import java.io.IOException;
+
+import javax.servlet.ServletInputStream;
+
+import org.apache.coyote.standalone.MessageReader;
+
+/**
+ * This class handles reading bytes.
+ * 
+ * @author Remy Maucherat
+ * @author Jean-Francois Arcand
+ */
+public class ServletInputStreamImpl
+    extends ServletInputStream {
+
+
+    // ----------------------------------------------------- Instance Variables
+
+
+    protected MessageReader ib;
+
+
+    // ----------------------------------------------------------- Constructors
+
+
+    protected ServletInputStreamImpl(MessageReader ib) {
+        this.ib = ib;
+    }
+
+
+    // -------------------------------------------------------- Package Methods
+
+
+    /**
+     * Clear facade.
+     */
+    void clear() {
+        ib = null;
+    }
+
+
+    // --------------------------------------------------------- Public Methods
+
+
+    /**
+     * Prevent cloning the facade.
+     */
+    protected Object clone()
+        throws CloneNotSupportedException {
+        throw new CloneNotSupportedException();
+    }
+
+
+    // --------------------------------------------- ServletInputStream Methods
+
+
+    public int read()
+        throws IOException {    
+        return ib.readByte();
+    }
+
+    public int available() throws IOException {
+        return ib.available();
+    }
+
+    public int read(final byte[] b) throws IOException {
+        return ib.read(b, 0, b.length);
+    }
+
+
+    public int read(final byte[] b, final int off, final int len)
+        throws IOException {
+            
+        return ib.read(b, off, len);
+    }
+
+
+    public int readLine(byte[] b, int off, int len) throws IOException {
+        return super.readLine(b, off, len);
+    }
+
+
+    /** 
+     * Close the stream
+     * Since we re-cycle, we can't allow the call to super.close()
+     * which would permantely disable us.
+     */
+    public void close() throws IOException {
+        ib.close();
+    }
+
+}

Added: tomcat/sandbox/java/org/apache/coyote/servlet/ServletOutputStreamImpl.java
URL: http://svn.apache.org/viewvc/tomcat/sandbox/java/org/apache/coyote/servlet/ServletOutputStreamImpl.java?rev=407939&view=auto
==============================================================================
--- tomcat/sandbox/java/org/apache/coyote/servlet/ServletOutputStreamImpl.java (added)
+++ tomcat/sandbox/java/org/apache/coyote/servlet/ServletOutputStreamImpl.java Fri May 19 19:12:51 2006
@@ -0,0 +1,119 @@
+/*
+ * 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.coyote.servlet;
+
+import java.io.IOException;
+
+import javax.servlet.ServletOutputStream;
+
+import org.apache.coyote.standalone.MessageWriter;
+
+/**
+ * Coyote implementation of the servlet output stream.
+ * 
+ * @author Costin Manolache
+ * @author Remy Maucherat
+ */
+public class ServletOutputStreamImpl 
+    extends ServletOutputStream {
+
+
+    // ----------------------------------------------------- Instance Variables
+
+
+    protected MessageWriter ob;
+
+
+    // ----------------------------------------------------------- Constructors
+
+
+    protected ServletOutputStreamImpl(MessageWriter ob) {
+        this.ob = ob;
+    }
+
+
+    // --------------------------------------------------------- Public Methods
+
+
+    /**
+     * Prevent cloning the facade.
+     */
+    protected Object clone()
+        throws CloneNotSupportedException {
+        throw new CloneNotSupportedException();
+    }
+
+
+    // -------------------------------------------------------- Package Methods
+
+
+    /**
+     * Clear facade.
+     */
+    void clear() {
+        ob = null;
+    }
+
+
+    // --------------------------------------------------- OutputStream Methods
+
+
+    public void write(int i)
+        throws IOException {
+        ob.writeByte(i);
+    }
+
+
+    public void write(byte[] b)
+        throws IOException {
+        write(b, 0, b.length);
+    }
+
+
+    public void write(byte[] b, int off, int len)
+        throws IOException {
+        ob.write(b, off, len);
+    }
+
+
+    /**
+     * Will send the buffer to the client.
+     */
+    public void flush()
+        throws IOException {
+        ob.flush();
+    }
+
+
+    public void close()
+        throws IOException {
+        ob.close();
+    }
+
+
+    // -------------------------------------------- ServletOutputStream Methods
+
+
+    public void print(String s)
+        throws IOException {
+        ob.write(s);
+    }
+
+
+}
+

Added: tomcat/sandbox/java/org/apache/coyote/servlet/ServletReaderImpl.java
URL: http://svn.apache.org/viewvc/tomcat/sandbox/java/org/apache/coyote/servlet/ServletReaderImpl.java?rev=407939&view=auto
==============================================================================
--- tomcat/sandbox/java/org/apache/coyote/servlet/ServletReaderImpl.java (added)
+++ tomcat/sandbox/java/org/apache/coyote/servlet/ServletReaderImpl.java Fri May 19 19:12:51 2006
@@ -0,0 +1,209 @@
+/*
+ * 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.coyote.servlet;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+
+import org.apache.coyote.standalone.MessageReader;
+
+
+/**
+ * Coyote implementation of the buffred reader.
+ * 
+ * @author Remy Maucherat
+ */
+public class ServletReaderImpl
+    extends BufferedReader {
+
+
+    // -------------------------------------------------------------- Constants
+
+
+    private static final char[] LINE_SEP = { '\r', '\n' };
+    private static final int MAX_LINE_LENGTH = 4096;
+
+
+    // ----------------------------------------------------- Instance Variables
+
+
+    protected MessageReader ib;
+
+
+    protected char[] lineBuffer = null;
+
+
+    // ----------------------------------------------------------- Constructors
+
+
+    public ServletReaderImpl(MessageReader ib) {
+        super(ib, 1);
+        this.ib = ib;
+    }
+
+
+    // --------------------------------------------------------- Public Methods
+
+
+    /**
+     * Prevent cloning the facade.
+     */
+    protected Object clone()
+        throws CloneNotSupportedException {
+        throw new CloneNotSupportedException();
+    }
+
+
+    // -------------------------------------------------------- Package Methods
+
+
+    /**
+     * Clear facade.
+     */
+    void clear() {
+        ib = null;
+    }
+
+
+    // --------------------------------------------------------- Reader Methods
+
+
+    public void close()
+        throws IOException {
+        ib.close();
+    }
+
+
+    public int read()
+        throws IOException {
+        return ib.read();
+    }
+
+
+    public int read(char[] cbuf)
+        throws IOException {
+        return ib.read(cbuf, 0, cbuf.length);
+    }
+
+
+    public int read(char[] cbuf, int off, int len)
+        throws IOException {
+        return ib.read(cbuf, off, len);
+    }
+
+
+    public long skip(long n)
+        throws IOException {
+        return ib.skip(n);
+    }
+
+
+    public boolean ready()
+        throws IOException {
+        return ib.ready();
+    }
+
+
+    public boolean markSupported() {
+        return true;
+    }
+
+
+    public void mark(int readAheadLimit)
+        throws IOException {
+        ib.mark(readAheadLimit);
+    }
+
+
+    public void reset()
+        throws IOException {
+        ib.reset();
+    }
+
+
+    public String readLine()
+        throws IOException {
+
+        if (lineBuffer == null) {
+            lineBuffer = new char[MAX_LINE_LENGTH];
+       }
+
+        String result = null;
+
+        int pos = 0;
+        int end = -1;
+        int skip = -1;
+        StringBuffer aggregator = null;
+        while (end < 0) {
+            mark(MAX_LINE_LENGTH);
+            while ((pos < MAX_LINE_LENGTH) && (end < 0)) {
+                int nRead = read(lineBuffer, pos, MAX_LINE_LENGTH - pos);
+                if (nRead < 0) {
+                    if (pos == 0) {
+                        return null;
+                    }
+                    end = pos;
+                    skip = pos;
+                }
+                for (int i = pos; (i < (pos + nRead)) && (end < 0); i++) {
+                    if (lineBuffer[i] == LINE_SEP[0]) {
+                        end = i;
+                        skip = i + 1;
+                        char nextchar;
+                        if (i == (pos + nRead - 1)) {
+                            nextchar = (char) read();
+                        } else {
+                            nextchar = lineBuffer[i+1];
+                        }
+                        if (nextchar == LINE_SEP[1]) {
+                            skip++;
+                        }
+                    } else if (lineBuffer[i] == LINE_SEP[1]) {
+                        end = i;
+                        skip = i + 1;
+                    }
+                }
+                if (nRead > 0) {
+                    pos += nRead;
+                }
+            }
+            if (end < 0) {
+                if (aggregator == null) {
+                    aggregator = new StringBuffer();
+                }
+                aggregator.append(lineBuffer);
+                pos = 0;
+            } else {
+                reset();
+                skip(skip);
+            }
+        }
+
+        if (aggregator == null) {
+            result = new String(lineBuffer, 0, end);
+        } else {
+            aggregator.append(lineBuffer, 0, end);
+            result = aggregator.toString();
+        }
+
+        return result;
+
+    }
+
+
+}



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