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: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]