Author: remm
Date: Tue Apr 4 15:34:09 2006
New Revision: 391432
URL: http://svn.apache.org/viewcvs?rev=391432&view=rev
Log:
- Add support for multiple servlet and filter mappings.
- Fix a bug I found by accident where application listeners are not
reinitialized when reloading.
- That's all folks, all the useful Servlet 2.5 features are done. Now the
annotations ... (sigh)
- Reuse the ignoreAnnotations field name from the patch submitted by Fabien
Carrion.
Modified:
tomcat/tc6.0.x/trunk/java/org/apache/catalina/Context.java
tomcat/tc6.0.x/trunk/java/org/apache/catalina/core/ApplicationFilterFactory.java
tomcat/tc6.0.x/trunk/java/org/apache/catalina/core/StandardContext.java
tomcat/tc6.0.x/trunk/java/org/apache/catalina/deploy/FilterMap.java
tomcat/tc6.0.x/trunk/java/org/apache/catalina/startup/WebRuleSet.java
tomcat/tc6.0.x/trunk/java/org/apache/tomcat/util/digester/CallMethodRule.java
Modified: tomcat/tc6.0.x/trunk/java/org/apache/catalina/Context.java
URL:
http://svn.apache.org/viewcvs/tomcat/tc6.0.x/trunk/java/org/apache/catalina/Context.java?rev=391432&r1=391431&r2=391432&view=diff
==============================================================================
--- tomcat/tc6.0.x/trunk/java/org/apache/catalina/Context.java (original)
+++ tomcat/tc6.0.x/trunk/java/org/apache/catalina/Context.java Tue Apr 4
15:34:09 2006
@@ -259,6 +259,21 @@
/**
+ * Return the boolean on the annotations parsing.
+ */
+ public boolean getIgnoreAnnotations();
+
+
+ /**
+ * Set the boolean on the annotations parsing for this web
+ * application.
+ *
+ * @param ignoreAnnotations The boolean on the annotations parsing
+ */
+ public void setIgnoreAnnotations(boolean ignoreAnnotations);
+
+
+ /**
* Return the login configuration descriptor for this web application.
*/
public LoginConfig getLoginConfig();
Modified:
tomcat/tc6.0.x/trunk/java/org/apache/catalina/core/ApplicationFilterFactory.java
URL:
http://svn.apache.org/viewcvs/tomcat/tc6.0.x/trunk/java/org/apache/catalina/core/ApplicationFilterFactory.java?rev=391432&r1=391431&r2=391432&view=diff
==============================================================================
---
tomcat/tc6.0.x/trunk/java/org/apache/catalina/core/ApplicationFilterFactory.java
(original)
+++
tomcat/tc6.0.x/trunk/java/org/apache/catalina/core/ApplicationFilterFactory.java
Tue Apr 4 15:34:09 2006
@@ -212,7 +212,30 @@
return (false);
// Match on context relative request path
- String testPath = filterMap.getURLPattern();
+ String[] testPaths = filterMap.getURLPatterns();
+
+ for (int i = 0; i < testPaths.length; i++) {
+ if (matchFiltersURL(testPaths[i], requestPath)) {
+ return (true);
+ }
+ }
+
+ // No match
+ return (false);
+
+ }
+
+
+ /**
+ * Return <code>true</code> if the context-relative request path
+ * matches the requirements of the specified filter mapping;
+ * otherwise, return <code>false</code>.
+ *
+ * @param testPath URL mapping being checked
+ * @param requestPath Context-relative request path of this request
+ */
+ private boolean matchFiltersURL(String testPath, String requestPath) {
+
if (testPath == null)
return (false);
@@ -268,11 +291,13 @@
if (servletName == null) {
return (false);
} else {
- if (servletName.equals(filterMap.getServletName())) {
- return (true);
- } else {
- return false;
+ String[] servletNames = filterMap.getServletNames();
+ for (int i = 0; i < servletNames.length; i++) {
+ if (servletName.equals(servletNames[i])) {
+ return (true);
+ }
}
+ return false;
}
}
Modified:
tomcat/tc6.0.x/trunk/java/org/apache/catalina/core/StandardContext.java
URL:
http://svn.apache.org/viewcvs/tomcat/tc6.0.x/trunk/java/org/apache/catalina/core/StandardContext.java?rev=391432&r1=391431&r2=391432&view=diff
==============================================================================
--- tomcat/tc6.0.x/trunk/java/org/apache/catalina/core/StandardContext.java
(original)
+++ tomcat/tc6.0.x/trunk/java/org/apache/catalina/core/StandardContext.java Tue
Apr 4 15:34:09 2006
@@ -301,7 +301,7 @@
private boolean delegate = false;
- /**
+ /**
* The display name of this web application.
*/
private String displayName = null;
@@ -360,6 +360,12 @@
/**
+ * Ignore annotations.
+ */
+ private boolean ignoreAnnotations = false;
+
+
+ /**
* The set of classnames of InstanceListeners that will be added
* to each newly created Wrapper by <code>createWrapper()</code>.
*/
@@ -1301,6 +1307,28 @@
/**
+ * Return the boolean on the annotations parsing.
+ */
+ public boolean getIgnoreAnnotations() {
+ return this.ignoreAnnotations;
+ }
+
+
+ /**
+ * Set the boolean on the annotations parsing for this web
+ * application.
+ *
+ * @param ignoreAnnotations The boolean on the annotations parsing
+ */
+ public void setIgnoreAnnotations(boolean ignoreAnnotations) {
+ boolean oldIgnoreAnnotations = this.ignoreAnnotations;
+ this.ignoreAnnotations = ignoreAnnotations;
+ support.firePropertyChange("ignoreAnnotations",
Boolean.valueOf(oldIgnoreAnnotations),
+ Boolean.valueOf(this.ignoreAnnotations));
+ }
+
+
+ /**
* Return the login configuration descriptor for this web application.
*/
public LoginConfig getLoginConfig() {
@@ -2061,23 +2089,29 @@
// Validate the proposed filter mapping
String filterName = filterMap.getFilterName();
- String servletName = filterMap.getServletName();
- String urlPattern = filterMap.getURLPattern();
+ String[] servletNames = filterMap.getServletNames();
+ String[] urlPatterns = filterMap.getURLPatterns();
if (findFilterDef(filterName) == null)
throw new IllegalArgumentException
(sm.getString("standardContext.filterMap.name", filterName));
- if ((servletName == null) && (urlPattern == null))
+ if ((servletNames.length == 0) && (urlPatterns.length == 0))
throw new IllegalArgumentException
(sm.getString("standardContext.filterMap.either"));
- if ((servletName != null) && (urlPattern != null))
+ // FIXME: Older spec revisions may still check this
+ /*
+ if ((servletNames.length != 0) && (urlPatterns.length != 0))
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
- if ((urlPattern != null) && !validateURLPattern(urlPattern))
- throw new IllegalArgumentException
- (sm.getString("standardContext.filterMap.pattern",
- urlPattern));
+ for (int i = 0; i < urlPatterns.length; i++) {
+ if (!validateURLPattern(urlPatterns[i])) {
+ throw new IllegalArgumentException
+ (sm.getString("standardContext.filterMap.pattern",
+ urlPatterns[i]));
+ }
+ }
// Add this filter mapping to our registered set
synchronized (filterMaps) {
@@ -4446,7 +4480,7 @@
lifecycle.fireLifecycleEvent(DESTROY_EVENT, null);
instanceListeners = new String[0];
- applicationListeners = new String[0];
+
}
private void resetContext() throws Exception, MBeanRegistrationException {
@@ -4460,6 +4494,10 @@
// Bugzilla 32867
distributable = false;
+ applicationListeners = new String[0];
+ applicationEventListenersObjects = new Object[0];
+ applicationLifecycleListenersObjects = new Object[0];
+
if(log.isDebugEnabled())
log.debug("resetContext " + oname + " " + mserver);
}
Modified: tomcat/tc6.0.x/trunk/java/org/apache/catalina/deploy/FilterMap.java
URL:
http://svn.apache.org/viewcvs/tomcat/tc6.0.x/trunk/java/org/apache/catalina/deploy/FilterMap.java?rev=391432&r1=391431&r2=391432&view=diff
==============================================================================
--- tomcat/tc6.0.x/trunk/java/org/apache/catalina/deploy/FilterMap.java
(original)
+++ tomcat/tc6.0.x/trunk/java/org/apache/catalina/deploy/FilterMap.java Tue Apr
4 15:34:09 2006
@@ -79,14 +79,17 @@
/**
* The servlet name this mapping matches.
*/
- private String servletName = null;
+ private String[] servletNames = new String[0];
- public String getServletName() {
- return (this.servletName);
+ public String[] getServletNames() {
+ return (this.servletNames);
}
- public void setServletName(String servletName) {
- this.servletName = servletName;
+ public void addServletName(String servletName) {
+ String[] results = new String[servletNames.length + 1];
+ System.arraycopy(servletNames, 0, results, 0, servletNames.length);
+ results[servletNames.length] = servletName;
+ servletNames = results;
}
@@ -103,17 +106,20 @@
/**
* The URL pattern this mapping matches.
*/
- private String urlPattern = null;
+ private String[] urlPatterns = new String[0];
- public String getURLPattern() {
- return (this.urlPattern);
+ public String[] getURLPatterns() {
+ return (this.urlPatterns);
}
- public void setURLPattern(String urlPattern) {
+ public void addURLPattern(String urlPattern) {
if ("*".equals(urlPattern)) {
this.allMatch = true;
} else {
- this.urlPattern = RequestUtil.URLDecode(urlPattern);
+ String[] results = new String[urlPatterns.length + 1];
+ System.arraycopy(urlPatterns, 0, results, 0, urlPatterns.length);
+ results[urlPatterns.length] = RequestUtil.URLDecode(urlPattern);
+ urlPatterns = results;
}
}
@@ -211,13 +217,13 @@
StringBuffer sb = new StringBuffer("FilterMap[");
sb.append("filterName=");
sb.append(this.filterName);
- if (servletName != null) {
+ for (int i = 0; i < servletNames.length; i++) {
sb.append(", servletName=");
- sb.append(servletName);
+ sb.append(servletNames[i]);
}
- if (urlPattern != null) {
+ for (int i = 0; i < urlPatterns.length; i++) {
sb.append(", urlPattern=");
- sb.append(urlPattern);
+ sb.append(urlPatterns[i]);
}
sb.append("]");
return (sb.toString());
Modified: tomcat/tc6.0.x/trunk/java/org/apache/catalina/startup/WebRuleSet.java
URL:
http://svn.apache.org/viewcvs/tomcat/tc6.0.x/trunk/java/org/apache/catalina/startup/WebRuleSet.java?rev=391432&r1=391431&r2=391432&view=diff
==============================================================================
--- tomcat/tc6.0.x/trunk/java/org/apache/catalina/startup/WebRuleSet.java
(original)
+++ tomcat/tc6.0.x/trunk/java/org/apache/catalina/startup/WebRuleSet.java Tue
Apr 4 15:34:09 2006
@@ -19,9 +19,14 @@
import java.lang.reflect.Method;
+import java.util.ArrayList;
+
import org.apache.catalina.Context;
import org.apache.catalina.Wrapper;
import org.apache.catalina.deploy.SecurityConstraint;
+import org.apache.tomcat.util.IntrospectionUtils;
+import org.apache.tomcat.util.digester.CallMethodRule;
+import org.apache.tomcat.util.digester.CallParamRule;
import org.apache.tomcat.util.digester.Digester;
import org.apache.tomcat.util.digester.Rule;
import org.apache.tomcat.util.digester.RuleSetBase;
@@ -115,6 +120,8 @@
digester.addRule(prefix + "web-app",
new SetPublicIdRule("setPublicId"));
+ digester.addRule(prefix + "web-app",
+ new IgnoreAnnotationsRule());
digester.addCallMethod(prefix + "web-app/context-param",
"addParameter", 2);
@@ -222,15 +229,15 @@
digester.addObjectCreate(prefix + "web-app/filter-mapping",
"org.apache.catalina.deploy.FilterMap");
digester.addSetNext(prefix + "web-app/filter-mapping",
- "addFilterMap",
- "org.apache.catalina.deploy.FilterMap");
+ "addFilterMap",
+ "org.apache.catalina.deploy.FilterMap");
digester.addCallMethod(prefix + "web-app/filter-mapping/filter-name",
"setFilterName", 0);
digester.addCallMethod(prefix + "web-app/filter-mapping/servlet-name",
- "setServletName", 0);
+ "addServletName", 0);
digester.addCallMethod(prefix + "web-app/filter-mapping/url-pattern",
- "setURLPattern", 0);
+ "addURLPattern", 0);
digester.addCallMethod(prefix + "web-app/filter-mapping/dispatcher",
"setDispatcher", 0);
@@ -392,10 +399,10 @@
digester.addCallMethod(prefix + "web-app/servlet/servlet-name",
"setName", 0);
- digester.addCallMethod(prefix + "web-app/servlet-mapping",
- "addServletMapping", 2);
+ digester.addRule(prefix + "web-app/servlet-mapping",
+ new CallMethodMultiRule("addServletMapping", 2,
0));
digester.addCallParam(prefix + "web-app/servlet-mapping/servlet-name",
1);
- digester.addCallParam(prefix + "web-app/servlet-mapping/url-pattern",
0);
+ digester.addRule(prefix + "web-app/servlet-mapping/url-pattern", new
CallParamMultiRule(0));
digester.addRule(prefix + "web-app/session-config",
sessionConfig);
@@ -611,6 +618,142 @@
Wrapper wrapper = (Wrapper) digester.pop();
if (digester.getLogger().isDebugEnabled())
digester.getLogger().debug("pop " + wrapper.getClass().getName());
+ }
+
+}
+
+
+/**
+ * A Rule that can be used to call multiple times a method as many times as
needed
+ * (used for addServletMapping).
+ */
+final class CallParamMultiRule extends CallParamRule {
+
+ public CallParamMultiRule(int paramIndex) {
+ super(paramIndex);
+ }
+
+ public void end(String namespace, String name) {
+ if (bodyTextStack != null && !bodyTextStack.empty()) {
+ // what we do now is push one parameter onto the top set of
parameters
+ Object parameters[] = (Object[]) digester.peekParams();
+ ArrayList params = (ArrayList) parameters[paramIndex];
+ if (params == null) {
+ params = new ArrayList();
+ parameters[paramIndex] = params;
+ }
+ params.add(bodyTextStack.pop());
+ }
+ }
+
+}
+
+
+/**
+ * A Rule that can be used to call multiple times a method as many times as
needed
+ * (used for addServletMapping).
+ */
+final class CallMethodMultiRule extends CallMethodRule {
+
+ protected int multiParamIndex = 0;
+
+ public CallMethodMultiRule(String methodName, int paramCount, int
multiParamIndex) {
+ super(methodName, paramCount);
+ this.multiParamIndex = multiParamIndex;
+ }
+
+ public void end() throws Exception {
+
+ // Retrieve or construct the parameter values array
+ Object parameters[] = null;
+ if (paramCount > 0) {
+ parameters = (Object[]) digester.popParams();
+ } else {
+ super.end();
+ }
+
+ ArrayList multiParams = (ArrayList) parameters[multiParamIndex];
+
+ // Construct the parameter values array we will need
+ // We only do the conversion if the param value is a String and
+ // the specified paramType is not String.
+ Object paramValues[] = new Object[paramTypes.length];
+ for (int i = 0; i < paramTypes.length; i++) {
+ if (i != multiParamIndex) {
+ // convert nulls and convert stringy parameters
+ // for non-stringy param types
+ if(parameters[i] == null || (parameters[i] instanceof String
+ && !String.class.isAssignableFrom(paramTypes[i]))) {
+ paramValues[i] =
+ IntrospectionUtils.convert((String) parameters[i],
paramTypes[i]);
+ } else {
+ paramValues[i] = parameters[i];
+ }
+ }
+ }
+
+ // Determine the target object for the method call
+ Object target;
+ if (targetOffset >= 0) {
+ target = digester.peek(targetOffset);
+ } else {
+ target = digester.peek(digester.getCount() + targetOffset);
+ }
+
+ if (target == null) {
+ StringBuffer sb = new StringBuffer();
+ sb.append("[CallMethodRule]{");
+ sb.append("");
+ sb.append("} Call target is null (");
+ sb.append("targetOffset=");
+ sb.append(targetOffset);
+ sb.append(",stackdepth=");
+ sb.append(digester.getCount());
+ sb.append(")");
+ throw new org.xml.sax.SAXException(sb.toString());
+ }
+
+ for (int j = 0; j < multiParams.size(); j++) {
+ Object param = multiParams.get(j);
+ if(param == null || (param instanceof String
+ &&
!String.class.isAssignableFrom(paramTypes[multiParamIndex]))) {
+ paramValues[multiParamIndex] =
+ IntrospectionUtils.convert((String) param,
paramTypes[multiParamIndex]);
+ } else {
+ paramValues[multiParamIndex] = param;
+ }
+ Object result = IntrospectionUtils.callMethodN(target, methodName,
+ paramValues, paramTypes);
+ }
+
+ }
+
+}
+
+
+
+/**
+ * A Rule that check if the annotations have to be loaded.
+ *
+ */
+
+final class IgnoreAnnotationsRule extends Rule {
+
+ public IgnoreAnnotationsRule() {
+ }
+
+ public void begin(String namespace, String name, Attributes attributes)
+ throws Exception {
+ Context context = (Context) digester.peek(digester.getCount() - 1);
+ String value = attributes.getValue("metadata-complete");
+ if ("true".equals(value)) {
+ context.setIgnoreAnnotations(true);
+ }
+ if (digester.getLogger().isDebugEnabled()) {
+ digester.getLogger().debug
+ (context.getClass().getName() + ".setIgnoreAnnotations( " +
+ context.getIgnoreAnnotations() + ")");
+ }
}
}
Modified:
tomcat/tc6.0.x/trunk/java/org/apache/tomcat/util/digester/CallMethodRule.java
URL:
http://svn.apache.org/viewcvs/tomcat/tc6.0.x/trunk/java/org/apache/tomcat/util/digester/CallMethodRule.java?rev=391432&r1=391431&r2=391432&view=diff
==============================================================================
---
tomcat/tc6.0.x/trunk/java/org/apache/tomcat/util/digester/CallMethodRule.java
(original)
+++
tomcat/tc6.0.x/trunk/java/org/apache/tomcat/util/digester/CallMethodRule.java
Tue Apr 4 15:34:09 2006
@@ -355,7 +355,7 @@
* top of the digester object stack. The default value of zero
* means the target object is the one on top of the stack.
*/
- private int targetOffset = 0;
+ protected int targetOffset = 0;
/**
* The method name to call on the parent object.
@@ -380,7 +380,7 @@
* The names of the classes of the parameters to be collected.
* This attribute allows creation of the classes to be postponed until the
digester is set.
*/
- private String paramClassNames[] = null;
+ protected String paramClassNames[] = null;
/**
* Should <code>MethodUtils.invokeExactMethod</code> be used for
reflection.
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]