Author: remy.maucherat(a)jboss.com
Date: 2009-01-23 13:17:34 -0500 (Fri, 23 Jan 2009)
New Revision: 911
Modified:
trunk/java/org/apache/catalina/core/ApplicationContext.java
trunk/java/org/apache/catalina/core/LocalStrings.properties
trunk/java/org/apache/catalina/core/StandardContext.java
Log:
- Some of the cookie and session config. I did not like putting it all in the servlet
context.
Modified: trunk/java/org/apache/catalina/core/ApplicationContext.java
===================================================================
--- trunk/java/org/apache/catalina/core/ApplicationContext.java 2009-01-23 18:16:50 UTC
(rev 910)
+++ trunk/java/org/apache/catalina/core/ApplicationContext.java 2009-01-23 18:17:34 UTC
(rev 911)
@@ -24,6 +24,7 @@
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
+import java.util.EnumSet;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.Map;
@@ -33,17 +34,23 @@
import javax.naming.Binding;
import javax.naming.NamingException;
import javax.naming.directory.DirContext;
+import javax.servlet.DispatcherType;
import javax.servlet.RequestDispatcher;
import javax.servlet.Servlet;
import javax.servlet.ServletContext;
import javax.servlet.ServletContextAttributeEvent;
import javax.servlet.ServletContextAttributeListener;
+import javax.servlet.SessionCookieConfig;
+import javax.servlet.SessionTrackingMode;
import org.apache.catalina.Context;
import org.apache.catalina.Globals;
import org.apache.catalina.Host;
import org.apache.catalina.Wrapper;
import org.apache.catalina.deploy.ApplicationParameter;
+import org.apache.catalina.deploy.FilterDef;
+import org.apache.catalina.deploy.FilterMap;
+import org.apache.catalina.deploy.SessionCookie;
import org.apache.catalina.util.Enumerator;
import org.apache.catalina.util.RequestUtil;
import org.apache.catalina.util.ResourceSet;
@@ -145,6 +152,12 @@
new ThreadLocal<DispatchData>();
+ /**
+ * Effective session cookie config.
+ */
+ private SessionCookieConfig sessionCookieConfig = null;
+
+
// --------------------------------------------------------- Public Methods
@@ -801,6 +814,155 @@
}
+ public void addFilter(String filterName, String description,
+ String className, Map<String, String> initParameters,
+ boolean isAsyncSupported) {
+
+ if (context.initialized) {
+ //TODO Spec breaking enhancement to ignore this restriction
+ throw new IllegalStateException(
+ sm.getString("applicationContext.addFilter.ise",
+ getContextPath()));
+ }
+ FilterDef filterDef = new FilterDef();
+ filterDef.setFilterName(filterName);
+ filterDef.setDescription(description);
+ filterDef.setFilterClass(className);
+ filterDef.getParameterMap().putAll(initParameters);
+ context.addFilterDef(filterDef);
+ // TODO SERVLET3 - ASync support
+ }
+
+
+ public void addFilterMappingForServletNames(String filterName,
+ EnumSet<DispatcherType> dispatcherTypes, boolean isMatchAfter,
+ String... servletNames) {
+ if (context.initialized) {
+ //TODO Spec breaking enhancement to ignore this restriction
+ throw new IllegalStateException(sm.getString(
+ "applicationContext.addFilterMapping", getContextPath()));
+ }
+ FilterMap filterMap = new FilterMap();
+ for (String servletName : servletNames) {
+ filterMap.addServletName(servletName);
+ }
+ filterMap.setFilterName(filterName);
+ for (DispatcherType dispatcherType: dispatcherTypes) {
+ filterMap.setDispatcher(dispatcherType.name());
+ }
+ if (isMatchAfter) {
+ context.addFilterMap(filterMap);
+ } else {
+ context.addFilterMapBefore(filterMap);
+ }
+ }
+
+
+ public void addFilterMappingForUrlPatterns(String filterName,
+ EnumSet<DispatcherType> dispatcherTypes, boolean isMatchAfter,
+ String... urlPatterns) {
+
+ if (context.initialized) {
+ //TODO Spec breaking enhancement to ignore this restriction
+ throw new IllegalStateException(sm.getString(
+ "applicationContext.addFilterMapping", getContextPath()));
+ }
+ FilterMap filterMap = new FilterMap();
+ for (String urlPattern : urlPatterns) {
+ filterMap.addURLPattern(urlPattern);
+ }
+ filterMap.setFilterName(filterName);
+ for (DispatcherType dispatcherType: dispatcherTypes) {
+ filterMap.setDispatcher(dispatcherType.name());
+ }
+ if (isMatchAfter) {
+ context.addFilterMap(filterMap);
+ } else {
+ context.addFilterMapBefore(filterMap);
+ }
+ }
+
+
+ public void addServletMapping(String servletName, String[] urlPatterns) {
+ if (context.initialized) {
+ //TODO Spec breaking enhancement to ignore this restriction
+ throw new IllegalStateException(sm.getString(
+ "applicationContext.addServletMapping",
getContextPath()));
+ }
+ for (String urlPattern : urlPatterns) {
+ boolean jspWildCard = ("*.jsp".equals(urlPattern));
+ context.addServletMapping(servletName, urlPattern, jspWildCard);
+ }
+ }
+
+
+ /**
+ * By default {@link SessionTrackingMode#URL} is always supported, {@link
+ * SessionTrackingMode#COOKIE} is supported unless the
<code>cookies</code>
+ * attribute has been set to <code>false</code> for the context and
{@link
+ * SessionTrackingMode#SSL} is supported if at least one of the connectors
+ * used by this context has the attribute <code>secure</code> set to
+ * <code>true</code>.
+ */
+ public EnumSet<SessionTrackingMode> getDefaultSessionTrackingModes() {
+ return context.getDefaultSessionTrackingModes();
+ }
+
+ /**
+ * Return the supplied value if one was previously set, else return the
+ * defaults.
+ */
+ public EnumSet<SessionTrackingMode> getEffectiveSessionTrackingModes() {
+ return context.getSessionTrackingModes();
+ }
+
+
+ public SessionCookieConfig getSessionCookieConfig() {
+ if (sessionCookieConfig != null) {
+ return sessionCookieConfig;
+ }
+ SessionCookie sessionCookie = context.getSessionCookie();
+ sessionCookieConfig = new SessionCookieConfig(sessionCookie.getDomain(),
sessionCookie.getPath(),
+ sessionCookie.getComment(), sessionCookie.isHttpOnly(),
sessionCookie.isSecure());
+ return sessionCookieConfig;
+ }
+
+
+ public void setSessionCookieConfig(SessionCookieConfig sessionCookieConfig) {
+ // FIXME: do something ...
+ this.sessionCookieConfig = sessionCookieConfig;
+ }
+
+
+ /**
+ * @throws IllegalStateException if the context has already been initialised
+ * @throws IllegalArgumentException TODO SERVLET3 Something to do with SSL
+ * but the spec language is not clear
+ * If an unsupported tracking mode is
+ * requested
+ */
+ public void setSessionTrackingModes(EnumSet<SessionTrackingMode>
sessionTrackingModes) {
+
+ if (context.getAvailable()) {
+ throw new IllegalStateException(
+ sm.getString("applicationContext.setSessionTracking.ise",
+ getContextPath()));
+ }
+
+ // Check that only supported tracking modes have been requested
+ for (SessionTrackingMode sessionTrackingMode : sessionTrackingModes) {
+ if (!getDefaultSessionTrackingModes().contains(sessionTrackingMode)) {
+ throw new IllegalArgumentException(sm.getString(
+ "applicationContext.setSessionTracking.iae",
+ sessionTrackingMode.toString(), getContextPath()));
+ }
+ }
+ // TODO SERVLET3 - The SSL test
+
+ context.setSessionTrackingModes(sessionTrackingModes);
+ }
+
+
// -------------------------------------------------------- Package Methods
protected StandardContext getContext() {
return this.context;
Modified: trunk/java/org/apache/catalina/core/LocalStrings.properties
===================================================================
--- trunk/java/org/apache/catalina/core/LocalStrings.properties 2009-01-23 18:16:50 UTC
(rev 910)
+++ trunk/java/org/apache/catalina/core/LocalStrings.properties 2009-01-23 18:17:34 UTC
(rev 911)
@@ -1,3 +1,21 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+#
http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+applicationContext.addFilter.ise=Filters can not be added to context {0} at this time.
See SRV.4.4.
+applicationContext.addFilterMapping.ise=Filter mappings can not be added to context {0}
at this time. See SRV.4.4.
+applicationContext.addServletMapping.ise=Servlet mappings can not be added to context {0}
at this time. See SRV.4.4.
applicationContext.attributeEvent=Exception thrown by attributes event listener
applicationContext.mapping.error=Error during mapping
applicationContext.requestDispatcher.iae=Path {0} does not start with a "/"
character
@@ -3,4 +21,6 @@
applicationContext.resourcePaths.iae=Path {0} does not start with a "/"
character
applicationContext.setAttribute.namenull=Name cannot be null
+applicationContext.setSessionTracking.ise=The session tracking modes for context {0}
cannot be set whilst the context is running
+applicationContext.setSessionTracking.iae=The session tracking mode {0} requested for
context {1} is not supported by that context
applicationDispatcher.allocateException=Allocate exception for servlet {0}
applicationDispatcher.deallocateException=Deallocate exception for servlet {0}
Modified: trunk/java/org/apache/catalina/core/StandardContext.java
===================================================================
--- trunk/java/org/apache/catalina/core/StandardContext.java 2009-01-23 18:16:50 UTC (rev
910)
+++ trunk/java/org/apache/catalina/core/StandardContext.java 2009-01-23 18:17:34 UTC (rev
911)
@@ -29,6 +29,7 @@
import java.io.Serializable;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
+import java.util.EnumSet;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Iterator;
@@ -59,6 +60,7 @@
import javax.servlet.ServletException;
import javax.servlet.ServletRequestAttributeListener;
import javax.servlet.ServletRequestListener;
+import javax.servlet.SessionTrackingMode;
import javax.servlet.http.HttpSessionAttributeListener;
import javax.servlet.http.HttpSessionListener;
@@ -296,12 +298,20 @@
/**
- * Should we attempt to use cookies for session id communication?
+ * Session tracking modes.
*/
- private boolean cookies = true;
+ // FIXME: see about SSL tracking mode
+ private EnumSet<SessionTrackingMode> defaultSessionTrackingModes =
+ EnumSet.of(SessionTrackingMode.URL, SessionTrackingMode.COOKIE /*,
SessionTrackingMode.SSL*/);
+
+ /**
+ * Session tracking modes.
+ */
+ private EnumSet<SessionTrackingMode> sessionTrackingModes =
defaultSessionTrackingModes;
+
- /**
+ /**
* Should we allow the <code>ServletContext.getContext()</code> method
* to access the context of other web applications in this server?
*/
@@ -374,12 +384,26 @@
/**
* The set of filter mappings for this application, in the order
- * they were defined in the deployment descriptor.
+ * they were defined in the deployment descriptor with additional mappings
+ * added via the {@link ServletContext} possibly both before and after those
+ * defined in the deployment descriptor.
*/
private FilterMap filterMaps[] = new FilterMap[0];
/**
+ * Filter mappings added via {@link ServletContext} may have to be inserted
+ * before the mappings in the deploymenmt descriptor but must be inserted in
+ * the order the {@link ServletContext} methods are called. This isn't an
+ * issue for the mappings added after the deployment descriptor - they are
+ * just added to the end - but correctly the adding mappings before the
+ * deployment descriptor mappings requires knowing where the last 'before'
+ * mapping was added.
+ */
+ private int filterMapInsertPoint = 0;
+
+
+ /**
* Ignore annotations.
*/
private boolean ignoreAnnotations = false;
@@ -1130,7 +1154,7 @@
*/
public boolean getCookies() {
- return (this.cookies);
+ return (sessionTrackingModes.contains(SessionTrackingMode.COOKIE));
}
@@ -1142,11 +1166,18 @@
*/
public void setCookies(boolean cookies) {
- boolean oldCookies = this.cookies;
- this.cookies = cookies;
- support.firePropertyChange("cookies",
- new Boolean(oldCookies),
- new Boolean(this.cookies));
+ boolean oldCookies = sessionTrackingModes.contains(SessionTrackingMode.COOKIE);
+ if (oldCookies && !cookies) {
+ defaultSessionTrackingModes.remove(SessionTrackingMode.COOKIE);
+ }
+ if (!oldCookies && cookies) {
+ defaultSessionTrackingModes.add(SessionTrackingMode.COOKIE);
+ }
+ if (oldCookies != cookies) {
+ support.firePropertyChange("cookies",
+ new Boolean(oldCookies),
+ new Boolean(cookies));
+ }
}
@@ -1710,6 +1741,22 @@
}
+ public EnumSet<SessionTrackingMode> getDefaultSessionTrackingModes() {
+ return defaultSessionTrackingModes;
+ }
+
+
+ public EnumSet<SessionTrackingMode> getSessionTrackingModes() {
+ return sessionTrackingModes;
+ }
+
+
+ public void setSessionTrackingModes(
+ EnumSet<SessionTrackingMode> sessionTrackingModes) {
+ this.sessionTrackingModes = sessionTrackingModes;
+ }
+
+
/**
* Return the "replace welcome files" property.
*/
@@ -2237,7 +2284,8 @@
/**
- * Add a filter mapping to this Context.
+ * Add a filter mapping to this Context at the end of the current set
+ * of filter mappings.
*
* @param filterMap The filter mapping to be added
*
@@ -2247,6 +2295,54 @@
*/
public void addFilterMap(FilterMap filterMap) {
+ validateFilterMap(filterMap);
+ // Add this filter mapping to our registered set
+ synchronized (filterMaps) {
+ FilterMap results[] =new FilterMap[filterMaps.length + 1];
+ System.arraycopy(filterMaps, 0, results, 0, filterMaps.length);
+ results[filterMaps.length] = filterMap;
+ filterMaps = results;
+ }
+ fireContainerEvent("addFilterMap", filterMap);
+ }
+
+
+ /**
+ * Add a filter mapping to this Context before the mappings defined in the
+ * deployment descriptor but after any other mappings added via this method.
+ *
+ * @param filterMap The filter mapping to be added
+ *
+ * @exception IllegalArgumentException if the specified filter name
+ * does not match an existing filter definition, or the filter mapping
+ * is malformed
+ */
+ public void addFilterMapBefore(FilterMap filterMap) {
+
+ validateFilterMap(filterMap);
+
+ // Add this filter mapping to our registered set
+ synchronized (filterMaps) {
+ FilterMap results[] = new FilterMap[filterMaps.length + 1];
+ System.arraycopy(filterMaps, 0, results, 0, filterMapInsertPoint);
+ results[filterMapInsertPoint] = filterMap;
+ System.arraycopy(filterMaps, filterMapInsertPoint, results,
+ filterMaps.length - filterMapInsertPoint+1,
+ filterMapInsertPoint);
+
+ filterMapInsertPoint++;
+
+ results[filterMaps.length] = filterMap;
+ filterMaps = results;
+ }
+ fireContainerEvent("addFilterMap", filterMap);
+ }
+
+
+ /**
+ * Validate the supplied FilterMap.
+ */
+ private void validateFilterMap(FilterMap filterMap) {
// Validate the proposed filter mapping
String filterName = filterMap.getFilterName();
String[] servletNames = filterMap.getServletNames();
@@ -2254,9 +2350,10 @@
if (findFilterDef(filterName) == null)
throw new IllegalArgumentException
(sm.getString("standardContext.filterMap.name", filterName));
- if (!filterMap.getMatchAllServletNames()
- && !filterMap.getMatchAllUrlPatterns()
- && (servletNames.length == 0) && (urlPatterns.length ==
0))
+
+ if (!filterMap.getMatchAllServletNames() &&
+ !filterMap.getMatchAllUrlPatterns() &&
+ (servletNames.length == 0) && (urlPatterns.length == 0))
throw new IllegalArgumentException
(sm.getString("standardContext.filterMap.either"));
// FIXME: Older spec revisions may still check this
@@ -2265,8 +2362,6 @@
throw new IllegalArgumentException
(sm.getString("standardContext.filterMap.either"));
*/
- // Because filter-pattern is new in 2.3, no need to adjust
- // for 2.2 backwards compatibility
for (int i = 0; i < urlPatterns.length; i++) {
if (!validateURLPattern(urlPatterns[i])) {
throw new IllegalArgumentException
@@ -2274,16 +2369,6 @@
urlPatterns[i]));
}
}
-
- // Add this filter mapping to our registered set
- synchronized (filterMaps) {
- FilterMap results[] =new FilterMap[filterMaps.length + 1];
- System.arraycopy(filterMaps, 0, results, 0, filterMaps.length);
- results[filterMaps.length] = filterMap;
- filterMaps = results;
- }
- fireContainerEvent("addFilterMap", filterMap);
-
}
@@ -3385,6 +3470,9 @@
System.arraycopy(filterMaps, 0, results, 0, n);
System.arraycopy(filterMaps, n + 1, results, n,
(filterMaps.length - 1) - n);
+ if (n < filterMapInsertPoint) {
+ filterMapInsertPoint--;
+ }
filterMaps = results;
}
@@ -5783,6 +5871,6 @@
}
}
-
-
+
+
}