[DIGESTER-164] RulesBase performance optimization - patch provided by Frank David Martinez

git-svn-id: https://svn.apache.org/repos/asf/commons/proper/digester/trunk@1328103 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/annotations-processor/src/main/java/org/apache/commons/digester3/annotations/processor/DigesterAnnotationsProcessor.java b/annotations-processor/src/main/java/org/apache/commons/digester3/annotations/processor/DigesterAnnotationsProcessor.java
index 748dcb7..fa3c2fb 100644
--- a/annotations-processor/src/main/java/org/apache/commons/digester3/annotations/processor/DigesterAnnotationsProcessor.java
+++ b/annotations-processor/src/main/java/org/apache/commons/digester3/annotations/processor/DigesterAnnotationsProcessor.java
@@ -94,6 +94,7 @@
         // processingEnv is a predefined member in AbstractProcessor class
         // Messager allows the processor to output messages to the environment
         final FormattingMessager messager = new FormattingMessager( processingEnv.getMessager() );
+        final DigesterElementVisitor elementVisitor = new DigesterElementVisitor( messager );
 
         // TODO get these values from -A parameters
         String packageName = getClass().getPackage().getName();
@@ -118,15 +119,20 @@
             configureMethod.annotate( Override.class );
             final JBlock configureMethodBody = configureMethod.body();
 
+            for ( Element element : environment.getRootElements() )
+            {
+                element.accept( elementVisitor, null );
+            }
+
             // Loop through the annotations that we are going to process
-            for ( TypeElement annotation : annotations )
+            /* for ( TypeElement annotation : annotations )
             {
                 // Get the members
                 for ( Element element : environment.getElementsAnnotatedWith( annotation ) )
                 {
                     messager.error( "Processing @%s %s", annotation, element );
                 }
-            }
+            } */
 
             codeModel.build( new FilerCodeWriter( processingEnv.getFiler() ) );
 
diff --git a/annotations-processor/src/main/java/org/apache/commons/digester3/annotations/processor/DigesterElementVisitor.java b/annotations-processor/src/main/java/org/apache/commons/digester3/annotations/processor/DigesterElementVisitor.java
index d49ca9f..9aa7df6 100644
--- a/annotations-processor/src/main/java/org/apache/commons/digester3/annotations/processor/DigesterElementVisitor.java
+++ b/annotations-processor/src/main/java/org/apache/commons/digester3/annotations/processor/DigesterElementVisitor.java
@@ -69,6 +69,7 @@
     @Override
     public Void visitType( TypeElement clazz, TypeElement annotation )
     {
+        System.out.println( ">>>>>>>>>" + clazz.getAnnotationMirrors() );
         messager.note( "visiting @%s on class %s", annotation, clazz );
         return null;
     }
diff --git a/core/src/main/java/org/apache/commons/digester3/RulesBase.java b/core/src/main/java/org/apache/commons/digester3/RulesBase.java
index 4615318..0828a10 100644
--- a/core/src/main/java/org/apache/commons/digester3/RulesBase.java
+++ b/core/src/main/java/org/apache/commons/digester3/RulesBase.java
@@ -21,6 +21,7 @@
 
 import java.util.ArrayList;
 import java.util.HashMap;
+import java.util.LinkedList;
 import java.util.List;
 
 import org.xml.sax.Attributes;
@@ -61,6 +62,11 @@
     protected HashMap<String, List<Rule>> cache = new HashMap<String, List<Rule>>();
 
     /**
+     * The subset of registered Rule instances with wildcard pattern.
+     */
+    protected List<String> wildcardCache = new LinkedList<String>();
+
+    /**
      * The set of registered Rule instances, in the order that they were originally registered.
      */
     protected ArrayList<Rule> rules = new ArrayList<Rule>();
@@ -99,6 +105,10 @@
         if ( list == null )
         {
             list = new ArrayList<Rule>();
+            if ( pattern.startsWith( "*/" ) )
+            {
+                wildcardCache.add( pattern.substring( 1 ) );
+            }
             cache.put( pattern, list );
         }
         list.add( rule );
@@ -110,6 +120,7 @@
      */
     public void clear()
     {
+        wildcardCache.clear();
         cache.clear();
         rules.clear();
     }
@@ -125,17 +136,18 @@
         {
             // Find the longest key, ie more discriminant
             String longKey = "";
-            for ( String key : cache.keySet() )
+            for ( String key : wildcardCache )
             {
-                if ( key.startsWith( "*/" )
-                                && ( pattern.equals( key.substring( 2 ) ) || pattern.endsWith( key.substring( 1 ) )
-                                && key.length() > longKey.length() ) )
+                if ( ( pattern.equals( key.substring( 1 ) ) || pattern.endsWith( key ) )
+                    && key.length() > longKey.length() )
                 {
-                    // rulesList = (List) this.cache.get(key);
-                    rulesList = lookup( namespaceURI, key );
                     longKey = key;
                 }
             }
+            if ( longKey.length() > 0 )
+            {
+                rulesList = lookup( namespaceURI, "*" + longKey );
+            }
         }
         if ( rulesList == null )
         {
diff --git a/src/changes/changes.xml b/src/changes/changes.xml
index ecb9cff..7ef0659 100644
--- a/src/changes/changes.xml
+++ b/src/changes/changes.xml
@@ -23,6 +23,9 @@
   </properties>
   <body>
   <release version="3.3" date="201?-??-??" description="Maintenance release.">
+    <action dev="simonetripodi" type="fix" issue="DIGESTER-164" due-to="Frank David Martinez">
+      RulesBase performance optimization.
+    </action>
     <action dev="simonetripodi" type="fix" issue="DIGESTER-163" due-to="Torsten Krah">
       ConcurrentModificationException creating a new Digester via loaderInstance.newDigester()
     </action>