import org.apache.tomcat.integration.ObjectManager;
import org.apache.tomcat.util.IntrospectionUtils;
-import org.apache.tools.ant.taskdefs.LoadResource;
/**
- * This is a very small 'dependency injection'/registry poor-man substitute,
+ * 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:
+ *
+ * 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
+ *
+ * - 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.
- *
+ * 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.
- *
+ * can be supported.
+ *
* @author Costin Manolache
*/
public class SimpleObjectManager extends ObjectManager {
static Logger log = Logger.getLogger(SimpleObjectManager.class.getName());
-
+
protected Properties props = new Properties();
protected Map<String, Object> objects = new HashMap();
ObjectManager om;
-
+
public SimpleObjectManager() {
// Register PropertiesSpi
}
this();
bind("Main.args", args);
}
-
+
public void loadResource(String res) {
InputStream in = this.getClass().getClassLoader()
.getResourceAsStream(res);
load(in);
}
-
+
public void register(ObjectManager om) {
this.om = om;
super.register(om);
}
-
+
public ObjectManager getObjectManager() {
return om;
}
throw new RuntimeException("Error loading default config");
}
}
-
+
public Properties getProperties() {
return props;
}
-
+
@Override
public void unbind(String name) {
}
throw new RuntimeException(e);
}
}
-
- // TODO: can I make 'inject' public - Guice seems to
+
+ // TODO: can I make 'inject' public - Guice seems to
// support this.
inject(name, o);
}
for (String k: props.stringPropertyNames()) {
if (k.startsWith(pref)) {
if (k.endsWith(")")) {
- continue; // special
+ continue; // special
}
String value = props.getProperty(k);
- value = IntrospectionUtils.replaceProperties(value,
+ value = IntrospectionUtils.replaceProperties(value,
props, null);
String p = k.substring(prefLen);
int idx = p.indexOf(".");
} 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
+ * @throws IOException
*/
- public String[] processArgs(String[] args, Properties props)
+ public String[] processArgs(String[] args, Properties props)
throws IOException {
for (int i = 0; i < args.length; i++) {
System.arraycopy(args, i, res, 0, res.length);
return res;
}
-
- String name = arg;
+
+ String name = arg;
int eq = arg.indexOf("=");
String value = null;
if (eq > 0) {
if ("config".equals(arg)) {
if (new File(value).exists()) {
- load(new FileInputStream(value));
+ load(new FileInputStream(value));
} else {
loadResource(value);
}
}
}
return new String[] {};
- }
+ }
}
import org.apache.tomcat.util.buf.CharChunk;
/**
- * Implement buffering and character translation acording to the
- * servlet spec.
- *
+ * Implement buffering and character translation acording to the
+ * servlet spec.
+ *
* This class handles both chars and bytes.
- *
+ *
* It is tightly integrated with servlet response, sending headers
* and updating the commit state.
- *
- * TODO: add 'extension' interface that allows direct access to
- * the async connector non-copy non-blocking queue. Same for the
- * OutputStream. Maybe switch the buffer to the brigade.
- *
+ *
+ * TODO: add 'extension' interface that allows direct access to
+ * the async connector non-copy non-blocking queue. Same for the
+ * OutputStream. Maybe switch the buffer to the brigade.
+ *
* @author Costin Manolache
*/
public class BodyWriter extends Writer {
protected static final int WRITER_NOTE = 3;
- private ByteChunk.ByteOutputChannel byteFlusher =
+ private ByteChunk.ByteOutputChannel byteFlusher =
new ByteChunk.ByteOutputChannel() {
@Override
}
};
- private CharChunk.CharOutputChannel charFlusher =
+ private CharChunk.CharOutputChannel charFlusher =
new CharChunk.CharOutputChannel() {
@Override
public void realWriteChars(char[] cbuf, int off, int len)
BodyWriter.this.realWriteChars(cbuf, off, len);
}
};
-
- public static final String DEFAULT_ENCODING =
+
+ public static final String DEFAULT_ENCODING =
org.apache.coyote.Constants.DEFAULT_CHARACTER_ENCODING;
public static final int DEFAULT_BUFFER_SIZE = 8*1024;
/**
- * Encoding to use.
+ * Encoding to use.
* TODO: isn't it redundant ? enc, gotEnc, conv plus the enc in the bb
*/
protected String enc;
/**
- * List of encoders. The writer is reused - the encoder mapping
+ * List of encoders. The writer is reused - the encoder mapping
* avoids creating expensive objects. In future it'll contain nio.Charsets
*/
protected HashMap encoders = new HashMap();
/**
* Alternate constructor which allows specifying the initial buffer size.
- *
+ *
* @param size Buffer size to use
*/
public BodyWriter(int size) {
cb.setLimit(size);
}
-
+
public void setConnector(Connector c, ServletResponseImpl res) {
this.res = res;
this.connector = c;
/**
* Is the response output suspended ?
- *
+ *
* @return suspended flag value
*/
public boolean isSuspended() {
/**
* Set the suspended flag.
- *
+ *
* @param suspended New suspended flag value
*/
public void setSuspended(boolean suspended) {
* Recycle the output buffer.
*/
public void recycle() {
-
+
state = BYTE_STATE;
headersSent = false;
bytesWritten = 0;
charsWritten = 0;
-
+
cb.recycle();
- bb.recycle();
+ bb.recycle();
closed = false;
suspended = false;
-
+
if (conv!= null) {
conv.recycle();
}
-
+
gotEnc = false;
enc = null;
-
+
}
/**
- * Close the output buffer. This tries to calculate the response size if
+ * Close the output buffer. This tries to calculate the response size if
* the response has not been committed yet.
- *
+ *
* @throws IOException An underlying IOException occurred
*/
public void close()
/**
* Flush bytes or chars contained in the buffer.
- *
+ *
* @throws IOException An underlying IOException occurred
*/
public void flush()
/**
* Flush bytes or chars contained in the buffer.
- *
+ *
* @throws IOException An underlying IOException occurred
*/
protected void doFlush(boolean realFlush)
if (state == CHAR_STATE) {
cb.flushBuffer();
state = BYTE_STATE;
- }
+ }
if (state == BYTE_STATE) {
bb.flushBuffer();
- }
+ }
doFlush = false;
if (realFlush) {
// ------------------------------------------------- Bytes Handling Methods
- /**
+ /**
* Sends the buffer data to the client output, checking the
* state of Response and calling the right interceptors.
- *
+ *
* @param buf Byte buffer to be written to the response
* @param off Offset
* @param cnt Length
- *
+ *
* @throws IOException An underlying IOException occurred
*/
private void realWriteBytes(byte buf[], int off, int cnt)
}
- private void writeBytes(byte b[], int off, int len)
+ private void writeBytes(byte b[], int off, int len)
throws IOException {
if (closed)
}
- public void write(StringBuffer sb)
+ public void write(StringBuilder sb)
throws IOException {
if (suspended)
s="null";
write(s, 0, s.length());
- }
+ }
public void println() throws IOException {
write("\n");
}
- private void realWriteChars(char c[], int off, int len)
+ private void realWriteChars(char c[], int off, int len)
throws IOException {
if (!gotEnc)
}
- public void checkConverter()
+ public void checkConverter()
throws IOException {
if (!gotEnc)
}
- protected void setConverter()
+ protected void setConverter()
throws IOException {
enc = res.getCharacterEncoding();
enc = DEFAULT_ENCODING;
conv = (C2BConverter) encoders.get(enc);
if (conv == null) {
-
+
if (System.getSecurityManager() != null){
try{
conv = (C2BConverter)AccessController.doPrivileged(
}
}
- );
+ );
}catch(PrivilegedActionException ex){
Exception e = ex.getException();
if (e instanceof IOException)
- throw (IOException)e;
+ throw (IOException)e;
}
} else {
conv = new C2BConverter(bb, enc);
}
-
+
encoders.put(enc, conv);
}
}
-
+
// -------------------- BufferedOutputStream compatibility
}
- /**
+ /**
* True if this buffer hasn't been used ( since recycle() ) -
- * i.e. no chars or bytes have been added to the buffer.
+ * i.e. no chars or bytes have been added to the buffer.
*/
public boolean isNew() {
return (bytesWritten == 0) && (charsWritten == 0);
// public abstract void recycle();
// public abstract void setSuspended(boolean suspended);
// public abstract boolean isSuspended();
-//
+//
// public abstract void reset();
// public abstract int getBufferSize();
// public abstract void setBufferSize(int n);
// }
// public abstract void write(byte[] b, int off, int len) throws IOException;
// public abstract void writeByte(int b) throws IOException;
-//
+//
//}
\ No newline at end of file
/*
* 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.
import java.util.ArrayList;
+import java.util.Collection;
import java.util.EnumSet;
import java.util.Enumeration;
import java.util.HashSet;
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, FilterRegistration {
DynamicFilterRegistration dynamic = new DynamicFilterRegistration();
-
+
public FilterConfigImpl(ServletContextImpl context) {
this.ctx = context;
}
-
+
boolean asyncSupported;
-
+
private ServletContextImpl ctx = null;
/**
* The application Filter we are configured for.
*/
private transient Filter filter = null;
-
+
String descryption;
-
+
private String filterName;
private String filterClassName;
this.filterClassName = filterClass;
this.initParams = params;
}
-
+
public void setFilter(Filter f) {
filter = f;
}
-
+
public String getFilterName() {
return filterName;
}
public void setFilterClass(Class<? extends Filter> filterClass2) {
this.filterClass = filterClass2;
}
-
+
public String getInitParameter(String name) {
if (initParams == null) return null;
filterClass = (Class<? extends Filter>) classLoader.loadClass(filterClassName);
}
this.filter = (Filter) filterClass.newInstance();
- } finally {
+ } finally {
if (classLoader != oldCtxClassLoader) {
Thread.currentThread().setContextClassLoader(oldCtxClassLoader);
}
}
-
+
// TODO: resource injection
-
+
return filter;
}
-
+
public Filter getFilter() throws ClassCastException, ClassNotFoundException, IllegalAccessException, InstantiationException, ServletException {
Filter filter = createFilter();
filter.init(this);
this.filter = null;
}
- @Override
+
+ @Override
public void addMappingForServletNames(EnumSet<DispatcherType> dispatcherTypes,
boolean isMatchAfter,
String... servletNames) {
if (ctx.startDone) {
- // Use the context method instead of the servlet API to
+ // Use the context method instead of the servlet API to
// add mappings after context init.
throw new IllegalStateException();
}
}
}
- @Override
+
+ @Override
public void addMappingForUrlPatterns(EnumSet<DispatcherType> dispatcherTypes,
boolean isMatchAfter,
String... urlPatterns) {
if (ctx.startDone) {
- // Use the context method instead of the servlet API to
+ // Use the context method instead of the servlet API to
// add mappings after context init.
throw new IllegalStateException();
}
}
}
- @Override
+
+ @Override
public boolean setInitParameter(String name, String value)
throws IllegalArgumentException, IllegalStateException {
- return ServletContextImpl.setInitParameter(ctx, initParams,
+ return ServletContextImpl.setInitParameter(ctx, initParams,
name, value);
}
- @Override
+
+ @Override
public Set<String> setInitParameters(Map<String, String> initParameters)
throws IllegalArgumentException, IllegalStateException {
- return ServletContextImpl.setInitParameters(ctx, initParams,
+ return ServletContextImpl.setInitParameters(ctx, initParams,
initParameters);
}
-
+
public Dynamic getDynamic() {
return dynamic;
}
-
+
public class DynamicFilterRegistration implements Dynamic {
- @Override
+
+ @Override
public void addMappingForServletNames(EnumSet<DispatcherType> dispatcherTypes,
boolean isMatchAfter,
String... servletNames) {
FilterConfigImpl.this.addMappingForServletNames(dispatcherTypes, isMatchAfter, servletNames);
}
- @Override
+
+ @Override
public void addMappingForUrlPatterns(EnumSet<DispatcherType> dispatcherTypes,
boolean isMatchAfter,
String... urlPatterns) {
FilterConfigImpl.this.addMappingForUrlPatterns(dispatcherTypes, isMatchAfter, urlPatterns);
}
- @Override
+
+ @Override
public boolean setInitParameter(String name, String value)
throws IllegalArgumentException, IllegalStateException {
- return ServletContextImpl.setInitParameter(ctx, initParams,
+ return ServletContextImpl.setInitParameter(ctx, initParams,
name, value);
}
- @Override
+
+ @Override
public Set<String> setInitParameters(Map<String, String> initParameters)
throws IllegalArgumentException, IllegalStateException {
- return ServletContextImpl.setInitParameters(ctx, initParams,
+ return ServletContextImpl.setInitParameters(ctx, initParams,
initParameters);
}
- @Override
+
+ @Override
public void setAsyncSupported(boolean isAsyncSupported)
throws IllegalStateException {
asyncSupported = isAsyncSupported;
}
- @Override
+
public void setDescription(String description)
throws IllegalStateException {
FilterConfigImpl.this.descryption = description;
}
+
+ @Override
+ public Collection<String> getUrlPatternMappings() {
+ // implement me
+ return null;
+ }
+
+ @Override
+ public Collection<String> getServletNameMappings() {
+ // implement me
+ return null;
+ }
+
+ @Override
+ public Map<String, String> getInitParameters() {
+ // implement me
+ return null;
+ }
+
+ @Override
+ public String getInitParameter(String name) {
+ if (initParams == null) return null;
+ return initParams.get(name);
+ }
+
+ @Override
+ public String getClassName() {
+ // implement me
+ return null;
+ }
+
+ @Override
+ public String getName() {
+ // implement me
+ return null;
+ }
+ }
+
+ @Override
+ public Collection<String> getUrlPatternMappings() {
+ // implement me
+ return null;
+ }
+
+ @Override
+ public Collection<String> getServletNameMappings() {
+ // implement me
+ return null;
+ }
+
+ @Override
+ public Map<String, String> getInitParameters() {
+ // implement me
+ return null;
+ }
+
+ @Override
+ public String getClassName() {
+ // implement me
+ return null;
+ }
+
+ @Override
+ public String getName() {
+ // implement me
+ return null;
}
-
}
/*
* Copyright 1999-2002,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.
import java.io.PrintStream;
import java.lang.reflect.Method;
+import java.util.Collection;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.HashSet;
import java.util.logging.Level;
import java.util.logging.Logger;
+
+import javax.servlet.MultipartConfigElement;
import javax.servlet.Servlet;
import javax.servlet.ServletConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRegistration;
+import javax.servlet.ServletSecurityElement;
import javax.servlet.SingleThreadModel;
import javax.servlet.UnavailableException;
/**
* Based on Wrapper.
- *
+ *
* Standard implementation of the <b>Wrapper</b> interface that represents
* an individual servlet definition. No child Containers are allowed, and
* the parent Container must be a Context.
*/
@SuppressWarnings("deprecation")
public class ServletConfigImpl implements ServletConfig, ServletRegistration {
-
+
ServletDynamicRegistration dynamic = new ServletDynamicRegistration();
-
+
protected boolean asyncSupported;
-
+
private static Logger log=
Logger.getLogger(ServletConfigImpl.class.getName());
protected int loadOnStartup = -1;
protected String runAs;
protected Map securityRoleRef = new HashMap(); // roleName -> [roleLink]
-
+
/**
* The date and time at which this servlet will become available (in
* milliseconds since the epoch), or zero if the servlet is available.
* servlet is considered permanent.
*/
private transient long available = 0L;
-
+
private ServletContextImpl ctx;
/**
* The (single) initialized instance of this servlet.
*/
private transient Servlet instance = null;
-
+
/**
* Are we unloading our servlet instance at the moment?
*/
*/
private transient Stack instancePool = null;
-
+
// Statistics
private transient long loadTime=0;
private transient int classLoadTime=0;
// ------------------------------------------------------------- Properties
- public ServletConfigImpl(ServletContextImpl ctx, String name,
+ public ServletConfigImpl(ServletContextImpl ctx, String name,
String classname) {
this.servletName = name;
this.servletClassName = classname;
public void setJspFile(String s) {
this.jspFile = s;
}
-
+
/**
* Return the load-on-startup order value (negative value means
* load on first call).
HashSet allow = new HashSet();
allow.add("TRACE");
allow.add("OPTIONS");
-
+
Method[] methods = getAllDeclaredMethods(servletClazz);
for (int i=0; methods != null && i<methods.length; i++) {
Method m = methods[i];
-
+
if (m.getName().equals("doGet")) {
allow.add("GET");
allow.add("HEAD");
/**
* Extract the root cause from a servlet exception.
- *
+ *
* @param e The servlet exception
*/
public static Throwable getRootCause(ServletException e) {
/**
* MUST be called before service()
- * This method should be called to get the servlet. After
+ * This method should be called to get the servlet. After
* service(), dealocate should be called. This deals with STM and
* update use counters.
- *
+ *
* Normally called from RequestDispatcher and TomcatLite.
*/
public Servlet allocate() throws ServletException {
// If we are currently unloading this servlet, throw an exception
- if (unloading)
+ if (unloading)
throw new ServletException
("allocate() while unloading " + getServletName());
countAllocated++;
return (instance);
}
-
+
// Simpler policy for ST: unbound number of servlets ( can grow to
// one per thread )
-
+
synchronized (instancePool) {
if (instancePool.isEmpty()) {
try {
}
countAllocated++;
Servlet newServlet = loadServlet();
- log.fine("New STM servet " + newServlet + " " +
+ log.fine("New STM servet " + newServlet + " " +
countAllocated);
return newServlet;
} catch (ServletException e) {
countAllocated);
Servlet s = (Servlet) instancePool.pop();
countAllocated++;
- log.fine("After get " + instancePool.size() + " " + s +
+ log.fine("After get " + instancePool.size() + " " + s +
" " + countAllocated);
return s;
}
synchronized (instancePool) {
countAllocated--;
if (instancePool.contains(servlet)) {
- System.err.println("Aleady in pool " + servlet + " "
+ System.err.println("Aleady in pool " + servlet + " "
+ instancePool.size()+ " " + countAllocated);
return;
}
- System.err.println("return pool " + servlet + " " +
+ System.err.println("return pool " + servlet + " " +
instancePool.size() + " " + countAllocated);
instancePool.push(servlet);
}
if (actualClass == null) {
// No explicit name. Try to use the framework
if (jspFile != null) {
-
+
// Named JSPs can be handled by a servlet or by the mapper.
Servlet res = (Servlet) ctx.getObjectManager().get("filetemplate-servlet");
if (res != null) {
initParams.put("jsp-file", jspFile);
return res;
} else {
- UserTemplateClassMapper mapper =
+ UserTemplateClassMapper mapper =
(UserTemplateClassMapper) ctx.getObjectManager().get(
UserTemplateClassMapper.class);
if (mapper != null) {
//ctx.getObjectManager().getObject(c);
//ctx.getObjectManager().getObject(servletName);
}
-
-
+
+
if (servletClass == null) {
// set classClass
loadClass(actualClass);
}
-
- // jsp-file case. Load the JspProxyServlet instead, with the
- // right params. Note the JspProxyServlet is _not_ jasper,
- // nor 'jsp' servlet - it is just a proxy with no special
+
+ // jsp-file case. Load the JspProxyServlet instead, with the
+ // right params. Note the JspProxyServlet is _not_ jasper,
+ // nor 'jsp' servlet - it is just a proxy with no special
// params. It calls the jsp servlet and jasper to generate the
// real class.
-
+
// this is quite different from catalina, where an ugly kludge was
// used to use the same jsp servlet in 2 roles
-
+
// the jsp proxy is replaced by the web.xml processor
-
+
if (servletClass == null) {
unavailable(null);
throw new UnavailableException("ClassNotFound: " + actualClass);
}
-
+
// Instantiate and initialize an instance of the servlet class itself
try {
return (Servlet) servletClass.newInstance();
} catch (ClassCastException e) {
unavailable(null);
- throw new UnavailableException("ClassCast: (Servlet)" +
+ throw new UnavailableException("ClassCast: (Servlet)" +
actualClass);
} catch (Throwable e) {
unavailable(null);
// Added extra log statement for Bugzilla 36630:
// http://issues.apache.org/bugzilla/show_bug.cgi?id=36630
if(log.isLoggable(Level.FINE)) {
- log.log(Level.FINE, "newInstance() error: servlet-name: " +
+ log.log(Level.FINE, "newInstance() error: servlet-name: " +
getServletName() +
" servlet-class: " + actualClass, e);
}
// Restore the context ClassLoader
- throw new ServletException("newInstance() error " + getServletName() +
+ throw new ServletException("newInstance() error " + getServletName() +
" " + actualClass, e);
}
}
// Nothing to do if we already have an instance or an instance pool
if (!singleThreadModel && (instance != null))
return instance;
-
+
long t1=System.currentTimeMillis();
Servlet servlet = newInstance();
-
+
classLoadTime=(int) (System.currentTimeMillis() -t1);
-
+
// Call the initialization method of this servlet
try {
servlet.init(this);
instancePool = new Stack();
}
loadTime=System.currentTimeMillis() -t1;
-
+
return servlet;
}
// Complain if no servlet class has been specified
if (actualClass == null) {
unavailable(null);
- throw new ServletException("servlet-class missing " +
+ throw new ServletException("servlet-class missing " +
getServletName());
}
-
- ClassLoader classLoader = ctx.getClassLoader();
- if (classLoader == null )
+
+ ClassLoader classLoader = ctx.getClassLoader();
+ if (classLoader == null )
classLoader = this.getClass().getClassLoader();
-
+
// Load the specified servlet class from the appropriate class loader
try {
servletClass = classLoader.loadClass(actualClass);
* destroy() method
*/
public synchronized void unload() throws ServletException {
- setAvailable(Long.MAX_VALUE);
+ setAvailable(Long.MAX_VALUE);
// Nothing to do if we have never loaded the instance
if (!singleThreadModel && (instance == null))
long delay = ctx.getUnloadDelay() / 20;
while ((nRetries < 21) && (countAllocated > 0)) {
if ((nRetries % 10) == 0) {
- log.info("Servlet.unload() timeout " +
+ log.info("Servlet.unload() timeout " +
countAllocated);
}
try {
Thread.currentThread().getContextClassLoader();
if (instance != null) {
ClassLoader classLoader = instance.getClass().getClassLoader();
-
+
PrintStream out = System.out;
// Call the servlet destroy() method
try {
instance = null;
//instancePool = null;
unloading = false;
- throw new ServletException("Servlet.destroy() " +
+ throw new ServletException("Servlet.destroy() " +
getServletName(), t);
} finally {
// restore the context ClassLoader
Thread.currentThread().setContextClassLoader(oldCtxClassLoader);
}
-
+
// Deregister the destroyed instance
instance = null;
}
unloading = false;
}
-
-
+
+
/**
* Return the initialization parameter value for the specified name,
* if any; otherwise return <code>null</code>.
if ((parentMethods != null) && (parentMethods.length > 0)) {
Method[] allMethods =
new Method[parentMethods.length + thisMethods.length];
- System.arraycopy(parentMethods, 0, allMethods, 0,
+ System.arraycopy(parentMethods, 0, allMethods, 0,
parentMethods.length);
- System.arraycopy(thisMethods, 0, allMethods, parentMethods.length,
+ System.arraycopy(thisMethods, 0, allMethods, parentMethods.length,
thisMethods.length);
- thisMethods = allMethods;
- }
+ thisMethods = allMethods;
+ }
- return thisMethods;
+ return thisMethods;
}
/** Specify the instance. Avoids the class lookup, disables unloading.
* Use for embedded case, or to control the allocation.
- *
+ *
* @param servlet
*/
public void setServlet(Servlet servlet) {
instance = servlet;
ctx.getObjectManager().bind("Servlet:" +
- ctx.getContextPath() + ":" + getServletName(),
+ ctx.getContextPath() + ":" + getServletName(),
this);
}
public String getSecurityRoleRef(String role) {
return (String)securityRoleRef.get(role);
}
-
+
public void setSecurityRoleRef(Map securityRoles) {
this.securityRoleRef = securityRoles;
}
this.loadOnStartup = loadOnStartup;
}
- @Override
+ @Override
public Set<String> addMapping(String... urlPatterns) {
if (ctx.startDone) {
- // Use the context method instead of the servlet API to
+ // Use the context method instead of the servlet API to
// add mappings after context init.
throw new IllegalStateException();
}
return failed;
}
- @Override
+
+ @Override
public boolean setInitParameter(String name, String value)
throws IllegalArgumentException, IllegalStateException {
- return ServletContextImpl.setInitParameter(ctx, initParams,
+ return ServletContextImpl.setInitParameter(ctx, initParams,
name, value);
}
- @Override
+
+ @Override
public Set<String> setInitParameters(Map<String, String> initParameters)
throws IllegalArgumentException, IllegalStateException {
- return ServletContextImpl.setInitParameters(ctx, initParams,
+ return ServletContextImpl.setInitParameters(ctx, initParams,
initParameters);
}
public Dynamic getDynamic() {
return dynamic;
}
-
+
class ServletDynamicRegistration implements Dynamic {
+
@Override
public void setAsyncSupported(boolean isAsyncSupported)
throws IllegalStateException {
asyncSupported = isAsyncSupported;
}
- @Override
+
public void setDescription(String description)
throws IllegalStateException {
ServletConfigImpl.this.description = description;
}
-
+
+ @Override
+ public Set<String> setServletSecurity(ServletSecurityElement constraint) {
+ //implement me
+ return null;
+ }
+
+ @Override
+ public void setLoadOnStartup(int loadOnStartup) {
+ //implement me - here to compile
+ }
+
+ @Override
+ public void setMultipartConfig(MultipartConfigElement multipartConfig) {
+ //implement me - here to compile
+ }
+
+ @Override
+ public void setRunAsRole(String roleName) {
+ //implement me - here to compile
+ }
+
+ @Override
+ public String getRunAsRole() {
+ //implement me - here to compile
+ return null;
+ }
+
+ @Override
+ public Collection<String> getMappings() {
+ //implement me
+ return null;
+ }
+
+ @Override
+ public Set<String> addMapping(String... urlPatterns) {
+ //implement me
+ return null;
+ }
+
+ @Override
+ public Map<String, String> getInitParameters() {
+ // implement me
+ return null;
+ }
+
+ @Override
+ public Set<String> setInitParameters(Map<String, String> initParameters)
+ throws IllegalArgumentException, IllegalStateException {
+ // implement me
+ return null;
+ }
+
+ @Override
+ public String getClassName() {
+ // implement me
+ return null;
+ }
+
+ @Override
+ public String getName() {
+ // implement me
+ return null;
+ }
+
+ @Override
+ public String getInitParameter(String name) {
+ // implement me
+ return null;
+ }
+
+ @Override
+ public boolean setInitParameter(String name, String value)
+ throws IllegalArgumentException, IllegalStateException {
+ // implement me
+ return false;
+ }
+
+ }
+
+ @Override
+ public Collection<String> getMappings() {
+ //implement me
+ return null;
}
public void setServletClass(Class<? extends Servlet> servletClass2) {
servletClass = servletClass2;
}
+
+
+ @Override
+ public String getRunAsRole() {
+ //implement me
+ return null;
+ }
+
+
+ @Override
+ public Map<String, String> getInitParameters() {
+ // implement me
+ return null;
+ }
+
+ @Override
+ public String getClassName() {
+ // implement me
+ return null;
+ }
+
+ @Override
+ public String getName() {
+ // implement me
+ return null;
+ }
+
}
* 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.
import java.net.URL;
import java.net.URLClassLoader;
import java.util.ArrayList;
+import java.util.Collection;
import java.util.EnumSet;
import java.util.Enumeration;
import java.util.EventListener;
import javax.servlet.SessionCookieConfig;
import javax.servlet.SessionTrackingMode;
import javax.servlet.FilterRegistration.Dynamic;
+import javax.servlet.descriptor.JspConfigDescriptor;
import org.apache.tomcat.addons.UserSessionManager;
import org.apache.tomcat.integration.ObjectManager;
/**
* Context - initialized from web.xml or using APIs.
- *
+ *
* Initialization order:
- *
+ *
* - add all listeners
* - add all filters
* - add all servlets
- *
+ *
* - session parameters
- * -
+ * -
*
* @author Craig R. McClanahan
* @author Remy Maucherat
*/
public class ServletContextImpl implements ServletContext {
-
+
/**
* Empty collection to serve as the basis for empty enumerations.
*/
private transient static final ArrayList empty = new ArrayList();
-
+
transient Logger log;
-
+
/**
* Base path - the directory root of the webapp
*/
protected transient ArrayList<EventListener> lifecycleListeners = new ArrayList();
protected UserSessionManager manager;
-
+
HashMap<String, FilterConfigImpl> filters = new HashMap<String, FilterConfigImpl>();
HashMap<String, ServletConfigImpl> servlets = new HashMap<String, ServletConfigImpl>();
/** Mapper for filters.
*/
protected WebappFilterMapper webappFilterMapper;
-
- /** Internal mapper for request dispatcher, must have all
- * context mappings.
- */
+
+ /** Internal mapper for request dispatcher, must have all
+ * context mappings.
+ */
protected WebappServletMapper mapper;
-
+
transient Locale2Charset charsetMapper = new Locale2Charset();
transient TomcatLite facade;
-
+
ObjectManager om;
private String hostname;
boolean initDone = false;
boolean startDone = false;
-
+
// ------------------------------------------------- ServletContext Methods
public ServletContextImpl() {
}
public void setTomcat(TomcatLite facade) {
this.facade = facade;
}
-
+
/**
* Registry/framework interface associated with the context.
* Also available as a context attribute.
}
return om;
}
-
+
public void setObjectManager(ObjectManager om) {
this.om = om;
}
-
+
public Locale2Charset getCharsetMapper() {
return charsetMapper;
}
this.contextPath = path;
log = Logger.getLogger("webapp" + path.replace('/', '.'));
}
-
+
public void setHostname(String hostname) {
this.hostname = hostname;
}
-
+
public String getHostname() {
return hostname;
}
-
+
/** The directory where this app is based. May be null.
- *
+ *
* @param basePath
*/
public void setBasePath(String basePath) {
- this.basePath = basePath;
+ this.basePath = basePath;
}
public ServletContextConfig getContextConfig() {
return contextConfig;
}
-
+
/** The directory where this app is based.
- *
+ *
* @param basePath
*/
public String getBasePath() {
public List<EventListener> getListeners() {
return lifecycleListeners;
}
-
- public void addListener(EventListener listener) {
- lifecycleListeners.add(listener);
+
+ public void addListener(Class <? extends EventListener> listenerClass) {
+ // implement me
+ }
+
+ public void addListener(String className) {
+ // implement me
+ }
+
+ public <T extends EventListener> void addListener(T t) {
+ lifecycleListeners.add(t);
}
+
public void removeListener(EventListener listener) {
lifecycleListeners.remove(listener);
}
public ServletConfigImpl getServletConfig(String jsp_servlet_name) {
return (ServletConfigImpl)servlets.get(jsp_servlet_name);
}
-
+
public Map getServletConfigs() {
return servlets;
}
/**
* Add a servlet to the context.
* Called from processWebAppData()
- *
+ *
* @param servletConfig
*/
public void addServletConfig(ServletConfigImpl servletConfig) {
servlets.put(servletConfig.getServletName(), servletConfig);
}
-
+
public boolean getPrivileged() {
return false;
}
-
+
public Map getFilters() {
return filters;
}
-
+
protected boolean getCrossContext() {
return true;
}
-
+
public void addMimeType(String ext, String type) {
contentTypes.addContentType(ext, type);
}
return mapper;
}
-
+
public WebappFilterMapper getFilterMapper() {
if (webappFilterMapper == null) {
Object customMapper = getObjectManager().get(WebappFilterMapper.class);
return webappFilterMapper ;
}
-
+
public FilterConfigImpl getFilter(String name) {
return (FilterConfigImpl)filters.get(name);
}
public void addSecurityRole(String role) {
securityRoles.add(role);
}
-
+
public List getSecurityRoles() {
return securityRoles;
}
}
}
-
+
/**
* Return the main path associated with this context.
*/
public String getContextPath() {
return contextPath;
}
-
+
/**
* Return the value of the specified initialization parameter, or
*/
public RequestDispatcher getNamedDispatcher(String name) {
if (name == null) return null;
- ServletConfigImpl wrapper =
+ ServletConfigImpl wrapper =
(ServletConfigImpl) this.getServletConfig(name);
if (wrapper == null) return null;
-
+
return new RequestDispatcherImpl(wrapper, name);
}
*/
public RequestDispatcher getRequestDispatcher(String path) {
if (path == null) return null;
-
+
if (!path.startsWith("/"))
throw new IllegalArgumentException(path);
path = UrlUtils.normalize(path);
if (path == null) return (null);
-
+
return new RequestDispatcherImpl(this, path);
}
- public RequestDispatcher getRequestDispatcher(String path,
+ public RequestDispatcher getRequestDispatcher(String path,
int type,
String dispatcherPath) {
RequestDispatcher dispatcher = getRequestDispatcher(path);
ThreadLocal requestDispatcherStack = new ThreadLocal();
protected ClassLoader classLoader;
-
+
// protected RequestDispatcherImpl getRequestDispatcher() {
-// ArrayList/*<RequestDispatcherImpl>*/ list =
+// ArrayList/*<RequestDispatcherImpl>*/ list =
// (ArrayList)requestDispatcherStack.get();
// if (list == null) {
// list = new ArrayList();
// requestDispatcherStack.set(list);
// }
-//
-//
+//
+//
// return null;
// }
public void resetDispatcherStack() {
-
+
}
-
+
/**
* 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
if (path == null || !path.startsWith("/")) {
throw new MalformedURLException("getResource() " + path);
}
-
+
path = UrlUtils.normalize(path);
if (path == null)
return (null);
return (null);
File resFile = new File(basePath + path);
- if (!resFile.exists())
+ if (!resFile.exists())
return null;
-
+
try {
return new FileInputStream(resFile);
} catch (FileNotFoundException e) {
if (!path.endsWith("/")) {
path = path + "/";
}
-
+
HashSet result = new HashSet();
for (int i=0; i < files.length; i++) {
if (files[i].isDirectory() ) {
event =
new ServletContextAttributeEvent(this.getServletContext(),
name, value);
-
+
}
if (replaced) {
listener.attributeReplaced(event);
removeAttribute(key);
}
}
-
+
public void initFilters() throws ServletException {
Iterator fI = getFilters().values().iterator();
while (fI.hasNext()) {
try {
fc.getFilter(); // will triger init()
} catch (Throwable e) {
- log.log(Level.WARNING, getContextPath() + " Filter.init() " +
+ log.log(Level.WARNING, getContextPath() + " Filter.init() " +
fc.getFilterName(), e);
- }
-
+ }
+
}
}
-
+
public void initServlets() throws ServletException {
Iterator fI = getServletConfigs().values().iterator();
- Map/*<Integer, List<ServletConfigImpl>>*/ onStartup =
+ Map/*<Integer, List<ServletConfigImpl>>*/ onStartup =
new TreeMap/*<Integer, List<ServletConfigImpl>>*/();
while (fI.hasNext()) {
ServletConfigImpl fc = (ServletConfigImpl)fI.next();
Iterator keys = onStartup.keySet().iterator();
while (keys.hasNext()) {
Integer key = (Integer)keys.next();
- List/*<ServletConfigImpl>*/ servlets = (List)onStartup.get(key);
+ List/*<ServletConfigImpl>*/ servlets = (List)onStartup.get(key);
Iterator servletsI = servlets.iterator();
while (servletsI.hasNext()) {
ServletConfigImpl fc = (ServletConfigImpl) servletsI.next();
try {
- fc.loadServlet();
+ fc.loadServlet();
} catch (Throwable e) {
log.log(Level.WARNING, "Error initializing " + fc.getServletName(), e);
- }
+ }
}
}
}
while (fI.hasNext()) {
String listenerClass = (String)fI.next();
try {
- Object l =
+ Object l =
getClassLoader().loadClass(listenerClass).newInstance();
lifecycleListeners.add((EventListener) l);
} catch (Throwable e) {
log.log(Level.WARNING, "Error initializing listener " + listenerClass, e);
- }
+ }
}
}
public ClassLoader getClassLoader() {
return classLoader;
}
-
+
public void addMapping(String path, String name) {
ServletConfigImpl wrapper = getServletConfig(name);
addMapping(path, wrapper);
public void addMapping(String path, ServletConfig wrapper) {
getMapper().addWrapper(getMapper().contextMapElement, path, wrapper);
}
-
-
-
+
+
+
public void setWelcomeFiles(String[] name) {
getMapper().contextMapElement.welcomeResources = name;
}
}
public void setSessionTimeout(int to) {
- getManager().setSessionTimeout(to);
+ getManager().setSessionTimeout(to);
}
-
+
/**
* Initialize the context from the parsed config.
- *
+ *
* Note that WebAppData is serializable.
*/
public void processWebAppData(ServletContextConfig d) throws ServletException {
this.contextConfig = d;
-
+
for (String k: d.mimeMapping.keySet()) {
- addMimeType(k, d.mimeMapping.get(k));
+ addMimeType(k, d.mimeMapping.get(k));
}
-
+
String[] wFiles = (String[])d.welcomeFileList.toArray(new String[0]);
if (wFiles.length == 0) {
wFiles = new String[] {"index.html" };
getMapper().contextMapElement.resources = new File(getBasePath());
}
setWelcomeFiles(wFiles);
-
+
Iterator i2 = d.filters.values().iterator();
while (i2.hasNext()) {
FilterData fd = (FilterData)i2.next();
addFilter(fd.filterName, fd.filterClass, fd.initParams);
}
-
+
Iterator i3 = d.servlets.values().iterator();
while (i3.hasNext()) {
ServletData sd = (ServletData) i3.next();
- // jsp-file
+ // jsp-file
if (sd.servletClass == null) {
if (sd.jspFile == null) {
log.log(Level.WARNING, "Missing servlet class for " + sd.servletName);
continue;
}
}
-
- ServletConfigImpl sw =
+
+ ServletConfigImpl sw =
new ServletConfigImpl(this, sd.servletName, sd.servletClass);
sw.setConfig(sd.initParams);
sw.setJspFile(sd.jspFile);
sw.setLoadOnStartup(sd.loadOnStartup);
//sw.setRunAs(sd.runAs);
sw.setSecurityRoleRef(sd.securityRoleRef);
-
+
addServletConfig(sw);
}
-
+
for (String k: d.servletMapping.keySet()) {
- addMapping(k, d.servletMapping.get(k));
+ addMapping(k, d.servletMapping.get(k));
}
-
+
Iterator i5 = d.filterMappings.iterator();
while (i5.hasNext()) {
- FilterMappingData k = (FilterMappingData) i5.next();
+ FilterMappingData k = (FilterMappingData) i5.next();
String[] disp = new String[k.dispatcher.size()];
if (k.urlPattern != null) {
- addFilterMapping(k.urlPattern,
- k.filterName,
+ addFilterMapping(k.urlPattern,
+ k.filterName,
(String[])k.dispatcher.toArray(disp));
}
if (k.servletName != null) {
- addFilterServletMapping(k.servletName,
- k.filterName,
+ addFilterServletMapping(k.servletName,
+ k.filterName,
(String[])k.dispatcher.toArray(disp));
}
}
-
+
for (String n: d.localeEncodingMapping.keySet()) {
- getCharsetMapper().addCharsetMapping(n,
+ getCharsetMapper().addCharsetMapping(n,
d.localeEncodingMapping.get(n));
}
}
-
- public void addServlet(String servletName, String servletClass,
+
+ public void addServlet(String servletName, String servletClass,
String jspFile, Map params) {
- ServletConfigImpl sc = new ServletConfigImpl(this, servletName,
+ ServletConfigImpl sc = new ServletConfigImpl(this, servletName,
servletClass);
sc.setJspFile(jspFile);
sc.setConfig(params);
}
@Override
- public javax.servlet.Registration.Dynamic addServlet(String servletName, Servlet servlet) {
+ public javax.servlet.ServletRegistration.Dynamic addServlet(String servletName, Servlet servlet) {
ServletConfigImpl sc = new ServletConfigImpl(this, servletName, null);
sc.setServlet(servlet);
addServletConfig(sc);
return sc.getDynamic();
}
-
+
public void addServletSec(String serlvetName, String runAs, Map roles) {
// TODO
}
-
-
-
- public void addFilterMapping(String path, String filterName,
+
+
+
+ public void addFilterMapping(String path, String filterName,
String[] dispatcher) {
- getFilterMapper().addMapping(filterName,
+ getFilterMapper().addMapping(filterName,
path, null, dispatcher, true);
-
+
}
- public void addFilterServletMapping(String servlet,
- String filterName,
+ public void addFilterServletMapping(String servlet,
+ String filterName,
String[] dispatcher) {
- getFilterMapper().addMapping(filterName,
- null, servlet,
- dispatcher, true);
+ getFilterMapper().addMapping(filterName,
+ null, servlet,
+ dispatcher, true);
}
-
+
/**
* Called from TomcatLite.init(), required before start.
- *
- * Will initialize defaults and load web.xml unless webAppData is
+ *
+ * Will initialize defaults and load web.xml unless webAppData is
* already set and recent. No other processing is done except reading
* the config - you can add or alter it before start() is called.
- *
+ *
* @throws ServletException
*/
public void init() throws ServletException {
initDone = true;
// Load global init params from the facade
initEngineDefaults();
-
+
initTempDir();
-
+
// Merge in web.xml - or other config source ( programmatic, etc )
- ContextPreinitListener cfg =
- (ContextPreinitListener) getObjectManager().get(
+ ContextPreinitListener cfg =
+ (ContextPreinitListener) getObjectManager().get(
ContextPreinitListener.class);
if (cfg != null) {
cfg.preInit(this);
}
processWebAppData(contextConfig);
-
+
// if not defined yet:
addDefaultServlets();
}
-
-
+
+
protected void initTempDir() throws ServletException {
- // We need a base path - at least for temp files, req. by spec
+ // We need a base path - at least for temp files, req. by spec
if (basePath == null) {
basePath = ("/".equals(contextPath)) ?
facade.getWork().getAbsolutePath() + "/ROOT" :
facade.getWork().getAbsolutePath() + contextPath;
}
-
+
File f = new File(basePath + "/WEB-INF/tmp");
f.mkdirs();
setAttribute("javax.servlet.context.tempdir", f);
}
-
+
/**
* Static file handler ( default )
* *.jsp support
- *
+ *
*/
protected void addDefaultServlets() throws ServletException {
if (servlets.get("default") == null) {
- ServletConfigImpl fileS = new ServletConfigImpl(this,
- "default", null);
+ ServletConfigImpl fileS = new ServletConfigImpl(this,
+ "default", null);
addServletConfig(fileS);
addMapping("/", fileS);
}
-
+
// *.jsp support
if (servlets.get("jspwildcard") == null) {
ServletConfigImpl fileS = new ServletConfigImpl(this,
addMapping("*.jsp", fileS);
}
}
-
+
protected void initEngineDefaults() throws ServletException {
-
+
// TODO: make this customizable, avoid loading it on startup
// Set the class name as default in the addon support
for (String sname: facade.ctxDefaultInitParam.keySet()) {
ServletConfigImpl fileS = new ServletConfigImpl(this, sname, sclass);
addServletConfig(fileS);
}
-
+
for (String sname: facade.preloadMappings.keySet()) {
String path = facade.preloadMappings.get(sname);
ServletConfigImpl servletConfig = getServletConfig(sname);
}
}
-
+
public ArrayList getClasspath(File directory, File classesDir) {
ArrayList res = new ArrayList();
if (classesDir.isDirectory() && classesDir.exists() &&
|| !directory.canRead()) {
return res;
}
-
+
File[] jars = directory.listFiles(new FilenameFilter() {
public boolean accept(File dir, String name) {
return name.endsWith(".jar");
}
});
-
+
for (int j = 0; j < jars.length; j++) {
try {
URL url = jars[j].toURL();
return;
}
String base = getBasePath();
-
+
ArrayList urls = getClasspath(new File(base + "/WEB-INF/lib"),
new File(base + "/WEB-INF/classes"));
URL[] urlsA = new URL[urls.size()];
urls.toArray(urlsA);
- URLClassLoader parentLoader =
+ URLClassLoader parentLoader =
getEngine().getContextParentLoader();
// create a class loader.
ctxRepo.addURL(urlsA);
repository = ctxRepo;
*/
-
+
classLoader = new URLClassLoader(urlsA, parentLoader);
-
+
// JMX should know about us ( TODO: is it too early ? )
facade.notifyAdd(this);
initListeners();
-
+
List listeners = this.getListeners();
ServletContextEvent event = null;
for (int i = 0; i < listeners.size(); i++) {
}
}
-
+
initFilters();
initServlets();
-
+
startDone = true;
}
}
- // TODO: configurable ? init-params
+ // TODO: configurable ? init-params
public String getSessionCookieName() {
return "JSESSIONID";
}
-
-
+
+
public void destroy() throws ServletException {
// destroy filters
Iterator fI = filters.values().iterator();
public TomcatLite getEngine() {
return facade;
}
-
+
public String findStatusPage(int status) {
if (contextConfig.errorPageCode.size() == 0) {
return null;
return (String) contextConfig.errorPageCode.get(Integer.toString(status));
}
- public void handleStatusPage(ServletRequestImpl req,
- ServletResponseImpl res,
- int status,
+ public void handleStatusPage(ServletRequestImpl req,
+ ServletResponseImpl res,
+ int status,
String statusPage) {
String message = RequestUtil.filter(res.getMessage());
if (message == null)
protected void setErrorAttributes(ServletRequestImpl req,
int status,
String message) {
- req.setAttribute("javax.servlet.error.status_code",
+ req.setAttribute("javax.servlet.error.status_code",
new Integer(status));
if (req.getWrapper() != null) {
- req.setAttribute("javax.servlet.error.servlet_name",
+ req.setAttribute("javax.servlet.error.servlet_name",
req.getWrapper().servletName);
}
- req.setAttribute("javax.servlet.error.request_uri",
+ req.setAttribute("javax.servlet.error.request_uri",
req.getRequestURI());
- req.setAttribute("javax.servlet.error.message",
+ req.setAttribute("javax.servlet.error.message",
message);
}
-
- public void handleError(ServletRequestImpl req,
+
+ public void handleError(ServletRequestImpl req,
ServletResponseImpl res,
Throwable t) {
Throwable realError = t;
dispatchError(req, res, errorPage);
} else {
log("Unhandled error", t);
- if (t instanceof ServletException &&
+ if (t instanceof ServletException &&
((ServletException)t).getRootCause() != null) {
log("RootCause:", ((ServletException)t).getRootCause());
}
}
}
- protected void dispatchError(ServletRequestImpl req,
- ServletResponseImpl res,
+ protected void dispatchError(ServletRequestImpl req,
+ ServletResponseImpl res,
String errorPage) {
RequestDispatcher rd =
getRequestDispatcher(errorPage);
try {
- // will clean up the buffer
+ // will clean up the buffer
rd.forward(req, res);
return; // handled
} catch (ServletException e) {
// TODO
}
}
-
+
protected String findErrorPage(Throwable exception) {
if (contextConfig.errorPageException.size() == 0) {
return null;
}
+
@Override
public EnumSet<SessionTrackingMode> getDefaultSessionTrackingModes() {
return null;
}
+
@Override
public EnumSet<SessionTrackingMode> getEffectiveSessionTrackingModes() {
return null;
}
+
@Override
public SessionCookieConfig getSessionCookieConfig() {
return null;
}
+
@Override
public void setSessionTrackingModes(EnumSet<SessionTrackingMode> sessionTrackingModes) {
}
- public void addFilter(String filterName, String filterClass,
+
+ public void addFilter(String filterName, String filterClass,
Map params) {
FilterConfigImpl fc = new FilterConfigImpl(this);
fc.setData(filterName, filterClass, params);
filters.put(filterName, fc);
}
-
+
+
@Override
public Dynamic addFilter(String filterName, String className) {
FilterConfigImpl fc = new FilterConfigImpl(this);
return fc.getDynamic();
}
+
@Override
public Dynamic addFilter(String filterName, Filter filter) {
FilterConfigImpl fc = new FilterConfigImpl(this);
return fc.getDynamic();
}
+
@Override
public Dynamic addFilter(String filterName, Class<? extends Filter> filterClass) {
FilterConfigImpl fc = new FilterConfigImpl(this);
return fc.getDynamic();
}
+
@Override
- public javax.servlet.Registration.Dynamic addServlet(String servletName,
+ public javax.servlet.ServletRegistration.Dynamic addServlet(String servletName,
String className) {
ServletConfigImpl sc = new ServletConfigImpl(this, servletName, className);
addServletConfig(sc);
return sc.getDynamic();
}
+
@Override
- public javax.servlet.Registration.Dynamic addServlet(String servletName,
+ public javax.servlet.ServletRegistration.Dynamic addServlet(String servletName,
Class<? extends Servlet> servletClass) {
ServletConfigImpl sc = new ServletConfigImpl(this, servletName, servletClass.getName());
sc.setServletClass(servletClass);
return sc.getDynamic();
}
- // That's tricky - this filter will have no name. We need to generate one
+ // That's tricky - this filter will have no name. We need to generate one
// because our code relies on names.
AtomicInteger autoName = new AtomicInteger();
-
+
+
@Override
public <T extends Filter> T createFilter(Class<T> c) throws ServletException {
FilterConfigImpl fc = new FilterConfigImpl(this);
}
}
+
@Override
public <T extends Servlet> T createServlet(Class<T> c) throws ServletException {
String filterName = "_tomcat_auto_servlet_" + autoName.incrementAndGet();
}
}
- @Override
+
public FilterRegistration findFilterRegistration(String filterName) {
return filters.get(filterName);
}
- @Override
+
public ServletRegistration findServletRegistration(String servletName) {
return servlets.get(servletName);
}
-
+
+
@Override
public boolean setInitParameter(String name, String value) {
HashMap<String, String> params = contextConfig.contextParam;
return setInitParameter(this, params, name, value);
}
-
- static Set<String> setInitParameters(ServletContextImpl ctx,
+
+
+ static Set<String> setInitParameters(ServletContextImpl ctx,
Map<String, String> params,
Map<String, String> initParameters)
throws IllegalArgumentException, IllegalStateException {
}
}
return result;
- }
+ }
/**
* true if the context initialization parameter with the given name and value was set successfully on this ServletContext, and false if it was not set because this ServletContext already contains a context initialization parameter with a matching name
* Throws:
* java.lang.IllegalStateException - if this ServletContext has already been initialized
*/
- static boolean setInitParameter(ServletContextImpl ctx, Map<String, String> params,
+ static boolean setInitParameter(ServletContextImpl ctx, Map<String, String> params,
String name, String value) {
if (name == null || value == null) {
throw new IllegalArgumentException();
return true;
}
}
+
+ public JspConfigDescriptor getJspConfigDescriptor() {
+ // fix me - just here to compile
+ return null;
+ }
+
+
+
+ public void declareRoles(String... roleNames) {
+ // implement me
+ }
+
+ public <T extends EventListener> T createListener(Class<T> c) throws ServletException {
+ // implement me
+ return null;
+ }
+
+ public Collection<String> getMappings() {
+ // implement me
+ return null;
+ }
+
+ public Map<String, ? extends FilterRegistration> getFilterRegistrations() {
+ // implement me
+ return null;
+ }
+
+ public FilterRegistration getFilterRegistration(String filterName) {
+ // implement me
+ return null;
+ }
+
+ public Map<String, ? extends ServletRegistration> getServletRegistrations() {
+ // implement me
+ return null;
+ }
+
+ public ServletRegistration getServletRegistration(String servletName) {
+ // implement me
+ return null;
+ }
+
+ public int getEffectiveMinorVersion() {
+ // implement me
+ return -1;
+ }
+
+ public int getEffectiveMajorVersion() {
+ // implement me
+ return -1;
+ }
+
}
/*
* 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.
import java.security.Principal;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
+import java.util.Collection;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Iterator;
/**
- *
+ *
* Wrapper object for the Coyote request.
*
* @author Remy Maucherat
/**
* Request dispatcher state.
*/
- public static final String DISPATCHER_TYPE_ATTR =
+ public static final String DISPATCHER_TYPE_ATTR =
"org.apache.catalina.core.DISPATCHER_TYPE";
/**
* Request dispatcher path.
*/
- public static final String DISPATCHER_REQUEST_PATH_ATTR =
+ public static final String DISPATCHER_REQUEST_PATH_ATTR =
"org.apache.catalina.core.DISPATCHER_REQUEST_PATH";
/**
public static final String SERVLET_NAME_ATTR =
"javax.servlet.error.servlet_name";
-
+
/**
* The name of the cookie used to pass the session identifier back
* and forth with the client.
public static final String SUBJECT_ATTR =
"javax.security.auth.subject";
-
+
/**
* The servlet context attribute under which we store a temporary
* working directory (as an object of type File) for use by servlets
* The match string for identifying a session ID parameter.
*/
private static final String match = ";" + SESSION_PARAMETER_NAME + "=";
-
+
/**
* The set of cookies associated with this Request.
*/
* declare formats[] as a static variable.
*/
protected SimpleDateFormat formats[] = null;
-
+
/**
* The attributes associated with this Request, keyed by attribute name.
/**
* ServletInputStream.
*/
- protected ServletInputStreamImpl inputStream;
+ protected ServletInputStreamImpl inputStream;
/**
* Reader.
*/
protected BufferedReader reader;
-
+
/**
* Using stream flag.
* Filter chain associated with the request.
*/
protected FilterChainImpl filterChain = new FilterChainImpl();
-
+
/**
* Mapping data.
*/
* The response with which this request is associated.
*/
protected ServletResponseImpl response = new ServletResponseImpl();
-
+
/**
* URI byte to char converter (not recycled).
*/
* Post data buffer.
*/
public final static int CACHED_POST_LEN = 8192;
-
+
public byte[] postData = null;
-
+
private HttpRequest httpRequest;
-
- /** New IO/buffer model
+
+ /** New IO/buffer model
*/
//protected Http11Connection con;
public void setConnector(Connector c) {
connector = c;
}
-
+
public Connector getConnector() {
return connector;
}
*
* @exception IOException if an input/output error occurs
*/
- public ServletInputStream createInputStream()
+ public ServletInputStream createInputStream()
throws IOException {
return inputStream;
}
public Object getAttribute(String name) {
if (name.equals(ServletRequestImpl.DISPATCHER_TYPE_ATTR)) {
- return (dispatcherType == null)
+ return (dispatcherType == null)
? REQUEST_INTEGER
: dispatcherType;
} else if (name.equals(ServletRequestImpl.DISPATCHER_REQUEST_PATH_ATTR)) {
- return (requestDispatcherPath == null)
+ return (requestDispatcherPath == null)
? getRequestPathMB().toString()
: requestDispatcherPath.toString();
}
// if(attr != null)
// return attr;
// if( isSSLAttribute(name) ) {
-// reqB.action(ActionCode.ACTION_REQ_SSL_ATTRIBUTE,
+// reqB.action(ActionCode.ACTION_REQ_SSL_ATTRIBUTE,
// reqB);
// attr = reqB.getAttribute(ServletRequestImpl.CERTIFICATES_ATTR);
// if( attr != null) {
/**
* Get the context path.
- *
+ *
* @return the context path
*/
public MessageBytes getContextPathMB() {
formats[1].setTimeZone(GMT_ZONE);
formats[2].setTimeZone(GMT_ZONE);
}
-
+
// Attempt to convert the date header in a variety of formats
long result = FastHttpDateFormat.parseDate(value, formats);
if (result != (-1L)) {
/**
* Get the decoded request URI.
- *
+ *
* @return the URL decoded request URI
*/
public String getDecodedRequestURI() {
/**
* Get the decoded request URI.
- *
+ *
* @return the URL decoded request URI
*/
public MessageBytes getDecodedRequestURIMB() {
public String getHeader(String name) {
return httpRequest.getHeader(name);
}
-
+
/**
* Return the names of all headers received with this request.
*/
/**
* Returns the Internet Protocol (IP) address of the interface on
* which the request was received.
- */
+ */
public String getLocalAddr(){
return httpRequest.localAddr().toString();
}
/**
* Get the path info.
- *
+ *
* @return the path info
*/
public MessageBytes getPathInfoMB() {
}
}
-
+
/**
* Return the principal that has been authenticated for this Request.
*/
public Principal getPrincipal() {
return (userPrincipal);
}
-
+
/**
* Return the protocol and version used to make this Request.
*/
/**
* Converter for the encoding associated with the request.
* If encoding is changed - a different encoder will be returned.
- *
+ *
* Encoders are cached ( per request ) - at least 8K per charset
*/
public B2CConverter getB2C() throws IOException {
if (enc == null) {
enc = DEFAULT_CHARACTER_ENCODING;
}
- B2CConverter conv =
+ B2CConverter conv =
(B2CConverter) encoders.get(enc);
if (conv == null) {
conv = new B2CConverter(enc);
}
return conv;
}
-
+
/**
* Return the real path of the specified virtual path.
*
/**
* Returns the Internet Protocol (IP) source port of the client
* or last proxy that sent the request.
- */
+ */
public int getRemotePort(){
return httpRequest.getRemotePort();
}
public HttpServletRequest getRequest() {
return this;
}
-
+
public HttpRequest getHttpRequest() {
return httpRequest;
}
-
+
public void setHttpRequest(HttpRequest req, BodyReader in) {
this.httpRequest = req;
inputBuffer = in;
/**
* Get the request path.
- *
+ *
* @return the request path
*/
public MessageBytes getRequestPathMB() {
public String getRequestURI() {
return httpRequest.requestURI().toString();
}
-
+
/**
*/
public void setRequestURI(String uri) {
httpRequest.decodedURI().setString(uri);
try {
- UriNormalizer.decodeRequest(httpRequest.decodedURI(),
+ UriNormalizer.decodeRequest(httpRequest.decodedURI(),
httpRequest.requestURI(), httpRequest.getURLDecoder());
} catch(IOException ioe) {
ioe.printStackTrace();
/**
* Get the servlet path.
- *
+ *
* @return the servlet path
*/
public MessageBytes getServletPathMB() {
public boolean isSecure() {
return (secure);
}
-
-
+
+
/**
* Return <code>true</code> if the authenticated user principal
* possesses the specified role name.
if (role.equals(userPrincipal.getName())) {
return true;
}
-
+
// TODO: check !!!!
// Check for a role defined directly as a <security-role>
return false;
(ServletRequestAttributeListener) listeners.get(i);
try {
if (event == null) {
- event =
+ event =
new ServletRequestAttributeEvent(context.getServletContext(),
getRequest(), name, value);
}
* @param value The associated value
*/
public void setAttribute(String name, Object value) {
-
+
// Name cannot be null
if (name == null)
throw new IllegalArgumentException
// if (name.startsWith("org.apache.tomcat.")) {
// reqB.setAttribute(name, value);
// }
-//
+//
// Notify interested application event listeners
List listeners = context.getListeners();
if (listeners.size() == 0)
/**
* Set the decoded request URI.
- *
+ *
* @param uri The decoded request URI
*/
public void setDecodedRequestURI(String uri) {
if (System.getSecurityManager() != null){
HttpSession session = getSession(false);
- if ( (subject != null) &&
+ if ( (subject != null) &&
(!subject.getPrincipals().contains(principal)) ){
- subject.getPrincipals().add(principal);
+ subject.getPrincipals().add(principal);
} else if (session != null &&
session.getAttribute(ServletRequestImpl.SUBJECT_ATTR) == null) {
subject = new Subject();
- subject.getPrincipals().add(principal);
+ subject.getPrincipals().add(principal);
}
if (session != null){
session.setAttribute(ServletRequestImpl.SUBJECT_ATTR, subject);
}
- }
+ }
this.userPrincipal = principal;
}
protected void configureSessionCookie(Cookie cookie) {
cookie.setMaxAge(-1);
String contextPath = null;
- if (//!connector.getEmptySessionPath() &&
+ if (//!connector.getEmptySessionPath() &&
(getContext() != null)) {
contextPath = getContext().getEncodedPath();
}
manager = context.getManager();
if (manager == null)
return (null); // Sessions are not supported
-
+
// Return the current session if it exists and is valid
if ((session != null) && !manager.isValid(session))
session = null;
if (session != null)
return (session);
-
-
+
+
if (requestedSessionId != null) {
try {
session = manager.findSession(requestedSessionId);
*/
protected void parseSessionCookiesId() {
String sessionCookieName = context.getSessionCookieName();
-
+
// Parse session id from cookies
Cookies serverCookies = httpRequest.getCookies();
int count = serverCookies.getCookieCount();
if (!isRequestedSessionIdFromCookie()) {
// Accept only the first session id cookie
//scookie.getValue().convertToAscii();
-
+
setRequestedSessionId
(scookie.getValue().toString());
setRequestedSessionCookie(true);
int semicolon2 = uriBC.indexOf(';', sessionIdStart);
if (semicolon2 >= 0) {
request.setRequestedSessionId
- (new String(uriBC.getBuffer(), start + sessionIdStart,
+ (new String(uriBC.getBuffer(), start + sessionIdStart,
semicolon2 - sessionIdStart));
// Extract session ID from request URI
byte[] buf = uriBC.getBuffer();
for (int i = 0; i < end - start - semicolon2; i++) {
- buf[start + semicolon + i]
+ buf[start + semicolon + i]
= buf[start + i + semicolon2];
}
uriBC.setBytes(buf, start, end - start - semicolon2 + semicolon);
} else {
request.setRequestedSessionId
- (new String(uriBC.getBuffer(), start + sessionIdStart,
+ (new String(uriBC.getBuffer(), start + sessionIdStart,
(end - start) - sessionIdStart));
uriBC.setEnd(start + semicolon);
}
}
- @Override
public void addAsyncListener(AsyncListener listener) {
}
- @Override
+
public void addAsyncListener(AsyncListener listener,
ServletRequest servletRequest,
ServletResponse servletResponse) {
}
+
@Override
public AsyncContext getAsyncContext() {
return null;
}
+
@Override
public ServletContext getServletContext() {
return null;
}
+
@Override
public boolean isAsyncStarted() {
return false;
}
+
@Override
public boolean isAsyncSupported() {
return false;
}
- @Override
public void setAsyncTimeout(long timeout) {
}
- @Override
+
+ @Override
public AsyncContext startAsync() throws IllegalStateException {
return null;
}
- @Override
+ @Override
public AsyncContext startAsync(ServletRequest servletRequest,
ServletResponse servletResponse)
throws IllegalStateException {
}
- @Override
+
+ @Override
public boolean authenticate(HttpServletResponse response)
throws IOException, ServletException {
return false;
}
- @Override
+
+ @Override
public Part getPart(String name) {
return null;
}
- @Override
- public Iterable<Part> getParts() {
- return null;
- }
-
- @Override
+ @Override
public void login(String username, String password) throws ServletException {
}
- @Override
+
+ @Override
public void logout() throws ServletException {
}
- @Override
+
public long getAsyncTimeout() {
return 0;
}
- @Override
+
+ @Override
public DispatcherType getDispatcherType() {
return null;
}
+ @Override
+ public Collection<Part> getParts() throws IOException, ServletException {
+ return null;
+ }
+
+
}
* 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.
import java.net.URL;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
+import java.util.Collection;
import java.util.Enumeration;
import java.util.Locale;
import java.util.TimeZone;
public class ServletResponseImpl
implements HttpServletResponse {
- /**
+ /**
* Format for http response header date field
* From DateTool
*/
"EEE, dd MMM yyyy HH:mm:ss zzz";
// ----------------------------------------------------------- Constructors
-
-
+
+
ServletResponseImpl() {
urlEncoder.addSafeCharacter('/');
}
*/
protected boolean included = false;
-
+
/**
* The characterEncoding flag
*/
private boolean isCharacterEncodingSet = false;
-
+
/**
* The error flag.
*/
private HttpResponse resB;
-
-
+
+
// Cached/derived information - reflected in headers
protected static Locale DEFAULT_LOCALE = Locale.getDefault();
-
+
public static final String DEFAULT_CHARACTER_ENCODING="ISO-8859-1";
protected Locale locale = DEFAULT_LOCALE;
- // XXX
+ // XXX
protected boolean commited = false;
protected String contentType = null;
-
+
/**
* Has the charset been explicitly set.
*/
included = false;
error = false;
isCharacterEncodingSet = false;
-
+
cookies.clear();
outputBuffer.recycle();
-
+
resB.recycle();
}
/**
* Set the application commit flag.
- *
+ *
* @param appCommitted The new application committed flag value
*/
public void setAppCommitted(boolean appCommitted) {
*/
public boolean isAppCommitted() {
return (this.appCommitted || isCommitted() || isSuspended()
- || ((getHttpResponse().getContentLength() > 0)
+ || ((getHttpResponse().getContentLength() > 0)
&& (getContentCount() >= getHttpResponse().getContentLength())));
}
/**
* Set the suspended flag.
- *
+ *
* @param suspended The new suspended flag value
*/
public void setSuspended(boolean suspended) throws IOException {
*
* @exception IOException if an input/output error occurs
*/
- public ServletOutputStream createOutputStream()
+ public ServletOutputStream createOutputStream()
throws IOException {
// Probably useless
return outputStream;
public String getContentType() {
String ret = contentType;
- if (ret != null
+ if (ret != null
&& characterEncoding != null
&& charsetSet) {
ret = ret + ";charset=" + characterEncoding;
*
* @exception IOException if an input/output error occurs
*/
- public void flushBuffer()
+ public void flushBuffer()
throws IOException {
outputBuffer.flush();
}
* already been called for this response
* @exception IOException if an input/output error occurs
*/
- public ServletOutputStream getOutputStream()
+ public ServletOutputStream getOutputStream()
throws IOException {
if (usingWriter)
* already been called for this response
* @exception IOException if an input/output error occurs
*/
- public PrintWriter getWriter()
+ public PrintWriter getWriter()
throws IOException {
if (usingOutputStream)
if (isCommitted())
throw new IllegalStateException("isCommitted");
-
+
resB.recycle(); // reset headers, status code, message
req.getConnector().reset(this);
contentType = null;
locale = DEFAULT_LOCALE;
characterEncoding = DEFAULT_CHARACTER_ENCODING;
charsetSet = false;
-
+
outputBuffer.reset();
}
/**
* Set the content length (in bytes) for this Response.
- * Ignored for writers if non-ISO-8859-1 encoding ( we could add more
+ * Ignored for writers if non-ISO-8859-1 encoding ( we could add more
* encodings that are constant.
*/
public void setContentLength(int length) {
// Ignore any call from an included servlet
if (included)
return;
-
- // writers can use variable-length encoding.
+
+ // writers can use variable-length encoding.
if (usingWriter && !"ISO-8859-1".equals(getCharacterEncoding())) {
return;
}
if (isCommitted())
return;
-
+
// Ignore any call from an included servlet
if (included)
- return;
-
+ return;
+
// Ignore any call made after the getWriter has been invoked
// The default should be used
if (usingWriter)
isCharacterEncodingSet = true;
}
-
-
+
+
/**
* Set the Locale that is appropriate for this response, including
* setting the appropriate character encoding.
String contentLanguage = locale.getLanguage();
if ((contentLanguage != null) && (contentLanguage.length() > 0)) {
String country = locale.getCountry();
- StringBuilder value = new StringBuilder(contentLanguage);
+ StringBuffer value = new StringBuffer(contentLanguage);
if ((country != null) && (country.length() > 0)) {
value.append('-');
value.append(country);
* Return an array of all the header names set for this response, or
* a zero-length array if no headers have been set.
*/
- public Iterable<String> getHeaderNames() {
+ public Collection<String> getHeaderNames() {
MimeHeaders headers = getHttpResponse().getMimeHeaders();
int n = headers.size();
cookies.add(cookie);
- final StringBuilder sb = new StringBuilder();
+ final StringBuffer sb = new StringBuffer();
ServerCookie.appendCookieValue
(sb, cookie.getVersion(), cookie.getName(), cookie.getValue(),
- cookie.getPath(), cookie.getDomain(), cookie.getComment(),
+ cookie.getPath(), cookie.getDomain(), cookie.getComment(),
cookie.getMaxAge(), cookie.getSecure(), false);
// the header name is Set-Cookie for both "old" and v.1 ( RFC2109 )
* @param url URL to be encoded
*/
public String encodeURL(String url) {
-
+
String absolute = toAbsolute(url);
if (isEncodeable(absolute)) {
- // W3c spec clearly said
+ // W3c spec clearly said
if (url.equalsIgnoreCase("")){
url = absolute;
}
/**
* Send an acknowledgment of a request.
- *
+ *
* @exception IOException if an input/output error occurs
*/
public void sendAcknowledgement()
// Ignore any call from an included servlet
if (included)
- return;
+ return;
req.getConnector().acknowledge(this);
}
* already been committed
* @exception IOException if an input/output error occurs
*/
- public void sendError(int status)
+ public void sendError(int status)
throws IOException {
sendError(status, null);
}
* already been committed
* @exception IOException if an input/output error occurs
*/
- public void sendError(int status, String message)
+ public void sendError(int status, String message)
throws IOException {
if (isCommitted())
// Ignore any call from an included servlet
if (included)
- return;
+ return;
setError();
// TODO: maybe other mechanism to customize default.
defaultStatusPage(status, message);
}
- setSuspended(true);
+ setSuspended(true);
}
- /**
+ /**
* Default handler for status code != 200
*/
void defaultStatusPage(int status, String message)
setContentType("text/html");
if (status > 400 && status < 600) {
if (getOutputBuffer().getBytesWritten() == 0) {
- getOutputBuffer().write("<html><body><h1>Status: " +
- status + "</h1><h1>Message: " + message +
+ getOutputBuffer().write("<html><body><h1>Status: " +
+ status + "</h1><h1>Message: " + message +
"</h1></body></html>");
getOutputBuffer().flush();
}
}
}
-
+
/**
* Send a temporary redirect to the specified redirect location URL.
* already been committed
* @exception IOException if an input/output error occurs
*/
- public void sendRedirect(String location)
+ public void sendRedirect(String location)
throws IOException {
if (isCommitted())
// Ignore any call from an included servlet
if (included)
- return;
+ return;
// Clear any data content that has been buffered
resetBuffer();
return (false);
if (hreq.isRequestedSessionIdFromCookie())
return (false);
-
+
// Is this a valid absolute URL?
URL url = null;
try {
String relativePath = req.getDecodedRequestURI();
int pos = relativePath.lastIndexOf('/');
relativePath = relativePath.substring(0, pos);
-
+
String encodedURI = null;
encodedURI = urlEncoder.encodeURL(relativePath);
redirectURLCC.append(encodedURI, 0, encodedURI.length());
c == '+' || c == '-' || c == '.';
}
-
+
/**
* Return the specified URL with the specified session identifier
* suitably encoded.
anchor = path.substring(pound);
path = path.substring(0, pound);
}
- StringBuilder sb = new StringBuilder(path);
+ StringBuffer sb = new StringBuffer(path);
if( sb.length() > 0 ) { // jsessionid can't be first.
sb.append(";jsessionid=");
sb.append(sessionId);
public BodyWriter getOutputBuffer() {
return outputBuffer;
}
-
+
public void setWriter(BodyWriter ob) {
outputBuffer = ob;
outputStream = new ServletOutputStreamImpl(outputBuffer);
}
- @Override
- public Iterable<String> getHeaders(String name) {
+
+ @Override
+ public Collection<String> getHeaders(String name) {
return null;
}
public void acknowledge(HttpServletResponse res) throws IOException {
Response cres = (Response) ((ServletResponseImpl) res).getHttpResponse().nativeResponse;
- cres.acknowledge();
+ cres.acknowledge();
}
public void reset(HttpServletResponse res) {
Response cres = (Response) ((ServletResponseImpl) res).getHttpResponse().nativeResponse;
- cres.reset();
+ cres.reset();
}
-
+
public void recycle(HttpServletRequest req, HttpServletResponse res) {
-
+
}
-
+
public static HttpResponse getResponse(final Response cres) {
HttpResponse hres = new HttpResponse() {
public int getStatus() {
cres.setCommitted(b);
}
};
-
+
hres.setMimeHeaders(cres.getMimeHeaders());
hres.nativeResponse = cres;
-
+
return hres;
}
-
+
public static HttpRequest getRequest(Request req) {
-
+
HttpRequest httpReq = new HttpRequest(req.scheme(),
- req.method(),
+ req.method(),
req.unparsedURI(),
req.protocol(),
req.getMimeHeaders(),
req.requestURI(),
req.decodedURI(),
req.query(), req.getParameters(),
- req.serverName(),
+ req.serverName(),
req.getCookies()) {
-
+
};
httpReq.nativeRequest = req;
-
+
// TODO: anything else computed in coyote ?
-
+
return httpReq;
}
@Override
public void initRequest(HttpServletRequest hreq, HttpServletResponse hres) {
ServletRequestImpl req = (ServletRequestImpl) hreq;
- ServletResponseImpl res = (ServletResponseImpl) hres;
+ ServletResponseImpl res = (ServletResponseImpl) hres;
req.setConnector(this);
-
+
Request creq = new Request();
Response cres = new Response();
HttpResponse nRes = getResponse(cres);
BodyWriter out = new BodyWriter(4096);
out.setConnector(this, res);
-
+
res.setHttpResponse(nRes, out);
-
+
cres.setRequest(creq);
cres.setHook(new ActionHook() {
- public void action(ActionCode actionCode,
+ public void action(ActionCode actionCode,
Object param) {
}
});
-
+
BodyReader in = new BodyReader();
in.setConnector(this, req);
HttpRequest nReq = getRequest(creq);
req.setHttpRequest(nReq, in);
-
+
}
-
+
// ---- Coyote Adapter interface ---
-
+
@Override
public void service(Request creq, Response cres) throws Exception {
long t0 = System.currentTimeMillis();
// compute decodedURI - not done by connector
UriNormalizer.decodeRequest(creq.decodedURI(), creq.requestURI(), creq.getURLDecoder());
-
+
// find the facades
ServletRequestImpl req = (ServletRequestImpl) creq.getNote(ADAPTER_REQ_NOTE);
ServletResponseImpl res = (ServletResponseImpl) cres.getNote(ADAPTER_RES_NOTE);
-
+
if (req == null) {
req = new ServletRequestImpl();
res = req.getResponse();
-
+
BodyReader in = new BodyReader();
in.setConnector(this, req);
HttpRequest nReq = getRequest(creq);
nReq.setServerPort(creq.getServerPort());
HttpResponse nRes = getResponse(cres);
-
+
req.setHttpRequest(nReq, in);
BodyWriter out = new BodyWriter(4096);
out.setConnector(this, res);
-
+
res.setHttpResponse(nRes, out);
-
+
creq.setNote(ADAPTER_REQ_NOTE, req);
cres.setNote(ADAPTER_RES_NOTE, res);
-
+
}
req.setConnector(this);
-
+
try {
lite.service(req, res);
} catch(IOException ex) {
t.printStackTrace();
} finally {
long t1 = System.currentTimeMillis();
-
-// log.info("<<<<<<<< DONE: " + creq.method() + " " +
-// creq.decodedURI() + " " +
-// res.getStatus() + " " +
+
+// log.info("<<<<<<<< DONE: " + creq.method() + " " +
+// creq.decodedURI() + " " +
+// res.getStatus() + " " +
// (t1 - t0));
-
+
// Final processing
- // TODO: only if not commet, this doesn't work with the
+ // TODO: only if not commet, this doesn't work with the
// other connectors since we don't have the info
// TODO: add this note in the nio/apr connectors
// TODO: play nice with TomcatLite, other adapters that flush/close
cres.sendHeaders();
}
res.getOutputBuffer().flush();
-
+
BodyWriter mw = res.getBodyWriter();
//MessageWriter.getWriter(creq, cres, 0);
mw.flush();
BodyReader reader = req.getBodyReader();
//getReader(creq);
reader.recycle();
-
+
cres.finish();
creq.recycle();
}
}
}
-
+
@Override
public boolean event(Request req, Response res, SocketStatus status)
throws Exception {
public String getRemoteHost(HttpServletRequest hreq) {
ServletRequestImpl req = (ServletRequestImpl) hreq;
-
+
Request creq = (Request) req.getHttpRequest().nativeRequest;
creq.action(ActionCode.ACTION_REQ_HOST_ATTRIBUTE, creq);
return creq.remoteHost().toString();
public String getRemoteAddr(HttpServletRequest hreq) {
ServletRequestImpl req = (ServletRequestImpl) hreq;
-
+
Request creq = (Request) req.getHttpRequest().nativeRequest;
creq.action(ActionCode.ACTION_REQ_HOST_ADDR_ATTRIBUTE, creq);
return creq.remoteAddr().toString();
@Override
public void beforeClose(HttpServletResponse res, int len) throws IOException {
Response cres = (Response) ((ServletResponseImpl) res).getHttpResponse().nativeResponse;
-
- if ((!cres.isCommitted())
+
+ if ((!cres.isCommitted())
&& (cres.getContentLengthLong() == -1)) {
// Flushing the char buffer
// If this didn't cause a commit of the response, the final content
public int doRead(ServletRequestImpl hreq, ByteChunk bb) throws IOException {
ServletRequestImpl req = (ServletRequestImpl) hreq;
-
+
Request creq = (Request) req.getHttpRequest().nativeRequest;
return creq.doRead(bb);
}
@Override
public void realFlush(HttpServletResponse res) throws IOException {
Response cres = (Response) ((ServletResponseImpl) res).getHttpResponse().nativeResponse;
- cres.action(ActionCode.ACTION_CLIENT_FLUSH,
+ cres.action(ActionCode.ACTION_CLIENT_FLUSH,
cres);
// If some exception occurred earlier, or if some IOE occurred
// here, notify the servlet with an IOE
@Override
public void sendHeaders(HttpServletResponse res) throws IOException {
Response cres = (Response) ((ServletResponseImpl) res).getHttpResponse().nativeResponse;
-
+
// This should happen before 'prepareResponse' is called !!
// Now update coyote response based on response
// don't set charset/locale - they're computed in lite
protected boolean daemon = false;
/**
- * Note indicating the response is COMET.
+ * Note indicating the response is COMET.
*/
public static final int COMET_RES_NOTE = 2;
public static final int COMET_REQ_NOTE = 2;
-
- public static final int ADAPTER_RES_NOTE = 1;
- public static final int ADAPTER_REQ_NOTE = 1;
-
+
+ public static final int ADAPTER_RES_NOTE = 1;
+ public static final int ADAPTER_REQ_NOTE = 1;
+
protected ProtocolHandler proto;
//protected Adapter adapter = new MapperAdapter();
protected int maxThreads = 20;
boolean started = false;
boolean async = false; // use old nio connector
-
+
protected ObjectManager om;
-
-
+
+
public void setObjectManager(ObjectManager om) {
this.om = om;
}
-
- /**
+
+ /**
* Add an adapter. If more than the 'default' adapter is
* added, a MapperAdapter will be inserted.
- *
+ *
* @param path Use "/" for the default.
* @param adapter
*/
// public void addAdapter(String path, Adapter added) {
// if ("/".equals(path)) {
-// ((MapperAdapter) adapter).setDefaultAdapter(added);
+// ((MapperAdapter) adapter).setDefaultAdapter(added);
// } else {
// ((MapperAdapter) adapter).getMapper().addWrapper(path, added);
// }
// }
-
+
/**
*/
public void run() {
public void setDaemon(boolean b) {
daemon = b;
}
-
+
protected void initAdapters() {
if (proto == null) {
addProtocolHandler(port, daemon);
proto.destroy();
started = false;
}
-
+
// /**
// * Simple CLI support - arg is a path:className pair.
// */
// e.printStackTrace();
// }
// }
-
+
public void setConnector(ProtocolHandler h) {
this.proto = h;
h.setAttribute("port", Integer.toString(port));
om.bind("ProtocolHandler:" + "ep-" + port, proto);
}
-
+
public void addProtocolHandler(int port, boolean daemon) {
Http11NioProtocol proto = new Http11NioProtocol();
proto.setCompression("on");
setPort(port);
setDaemon(daemon);
}
-
- public void addProtocolHandler(ProtocolHandler proto,
+
+ public void addProtocolHandler(ProtocolHandler proto,
int port, boolean daemon) {
setConnector(proto);
setPort(port);
setDaemon(daemon);
}
-
+
public void setPort(int port) {
if (proto != null) {
proto.setAttribute("port", Integer.toString(port));
}
this.port = port;
}
-
-
+
+
public void init() {
//JdkLoggerConfig.loadCustom();
- om.bind("CoyoteConnector:" + "CoyoteConnector-" + port,
+ om.bind("CoyoteConnector:" + "CoyoteConnector-" + port,
this);
}
-
+
public void start() throws IOException {
try {
if (started) {
// not required - should run fine without a connector.
if (proto != null) {
proto.setAdapter(this);
-
+
proto.init();
proto.start();
}
-
+
started = true;
} catch (Throwable e) {
e.printStackTrace();
throw new RuntimeException(e);
}
}
-
+
public boolean getStarted() {
return started;
- }
-
+ }
+
+ public boolean asyncDispatch(Request req,Response res, SocketStatus status) throws Exception {
+ // implement me
+ return false;
+ }
+
}