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]

Reply via email to