Author: wglass
Date: Sat Sep 23 20:55:33 2006
New Revision: 449347

URL: http://svn.apache.org/viewvc?view=rev&rev=449347
Log:
Fix to introspection method caching.  Thanks to Alexey Panchenko for the catch, 
fix, and test.  VELOCITY-453.

Added:
    
jakarta/velocity/engine/trunk/src/test/org/apache/velocity/test/IntrospectionCacheDataTestCase.java
   (with props)
Modified:
    
jakarta/velocity/engine/trunk/src/java/org/apache/velocity/runtime/parser/node/ASTMethod.java
    jakarta/velocity/engine/trunk/xdocs/changes.xml

Modified: 
jakarta/velocity/engine/trunk/src/java/org/apache/velocity/runtime/parser/node/ASTMethod.java
URL: 
http://svn.apache.org/viewvc/jakarta/velocity/engine/trunk/src/java/org/apache/velocity/runtime/parser/node/ASTMethod.java?view=diff&rev=449347&r1=449346&r2=449347
==============================================================================
--- 
jakarta/velocity/engine/trunk/src/java/org/apache/velocity/runtime/parser/node/ASTMethod.java
 (original)
+++ 
jakarta/velocity/engine/trunk/src/java/org/apache/velocity/runtime/parser/node/ASTMethod.java
 Sat Sep 23 20:55:33 2006
@@ -18,6 +18,7 @@
 
 import java.lang.reflect.InvocationTargetException;
 
+import org.apache.commons.lang.ArrayUtils;
 import org.apache.velocity.app.event.EventHandlerUtil;
 import org.apache.velocity.context.InternalContextAdapter;
 import org.apache.velocity.exception.MethodInvocationException;
@@ -45,7 +46,7 @@
  */
 public class ASTMethod extends SimpleNode
 {
-    private String methodName = "";
+    protected String methodName = "";
     private int paramCount = 0;
 
     /**
@@ -126,7 +127,7 @@
              * change from visit to visit
              */
 
-            Class[] paramClasses = new Class[paramCount];
+            final Class[] paramClasses = paramCount > 0 ? new 
Class[paramCount] : ArrayUtils.EMPTY_CLASS_ARRAY;
 
             for (int j = 0; j < paramCount; j++)
             {
@@ -325,23 +326,51 @@
             this.params = params;
         }
 
+        private final ASTMethod getASTMethod() 
+        {
+            return ASTMethod.this;
+        }
+        
         /**
          * @see java.lang.Object#equals(java.lang.Object)
          */
         public boolean equals(Object o)
         {
-            return  (o != null) &&
-                    (o instanceof MethodCacheKey) &&
-                    (this.hashCode() == o.hashCode());
+            if (o instanceof MethodCacheKey) 
+            {
+                final MethodCacheKey other = (MethodCacheKey) o;            
+                if (params.length == other.params.length && 
methodName.equals(other.getASTMethod().methodName)) 
+                {              
+                    for (int i = 0; i < params.length; ++i) 
+                    {
+                        if (params[i] != other.params[i]) 
+                        {
+                            return false;
+                        }
+                    }
+                    return true;
+                }
+            }
+            return false;
         }
+        
 
         /**
          * @see java.lang.Object#hashCode()
          */
-        public int hashCode()
+        public int hashCode() 
         {
-            return params.hashCode() * 37 + ASTMethod.this.hashCode();
+            int result = 0;
+            for (int i = 0; i < params.length; ++i) 
+            {
+                final Class param = params[i];
+                if (param != null)
+                {
+                    result ^= param.hashCode();
+                }
+            }
+            return result * 37 + methodName.hashCode();
         }
     }
-
+    
 }

Added: 
jakarta/velocity/engine/trunk/src/test/org/apache/velocity/test/IntrospectionCacheDataTestCase.java
URL: 
http://svn.apache.org/viewvc/jakarta/velocity/engine/trunk/src/test/org/apache/velocity/test/IntrospectionCacheDataTestCase.java?view=auto&rev=449347
==============================================================================
--- 
jakarta/velocity/engine/trunk/src/test/org/apache/velocity/test/IntrospectionCacheDataTestCase.java
 (added)
+++ 
jakarta/velocity/engine/trunk/src/test/org/apache/velocity/test/IntrospectionCacheDataTestCase.java
 Sat Sep 23 20:55:33 2006
@@ -0,0 +1,71 @@
+package org.apache.velocity.test;
+
+/*
+ * Copyright 2000-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.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import java.io.IOException;
+import java.io.StringWriter;
+
+import org.apache.velocity.VelocityContext;
+import org.apache.velocity.app.Velocity;
+import org.apache.velocity.exception.MethodInvocationException;
+import org.apache.velocity.exception.ParseErrorException;
+import org.apache.velocity.exception.ResourceNotFoundException;
+import org.apache.velocity.util.introspection.IntrospectionCacheData;
+
+import junit.framework.TestCase;
+
+/**
+ * Checks that arrays are cached correctly in the Introspector.
+ *
+ * @author <a href="Alexey Pachenko">[EMAIL PROTECTED]</a>
+ * @version $Id$
+ */
+public class IntrospectionCacheDataTestCase extends TestCase 
+{
+
+  private static class CacheHitCountingVelocityContext extends VelocityContext 
+  {
+    public int cacheHit = 0;
+
+    public IntrospectionCacheData icacheGet(Object key) 
+    {
+      final IntrospectionCacheData result = super.icacheGet(key);
+      if (result != null) {
+        ++cacheHit;
+      }
+      return result;
+    }
+
+  }
+
+  public void testCache() throws ParseErrorException, 
MethodInvocationException, 
+  ResourceNotFoundException, IOException 
+  {
+    CacheHitCountingVelocityContext context = new 
CacheHitCountingVelocityContext();
+    context.put("this", this);
+    StringWriter w = new StringWriter();
+    Velocity.evaluate(context, w, "test", "$this.exec('a')$this.exec('b')");
+    assertEquals("[a][b]", w.toString());
+    assertTrue(context.cacheHit > 0);
+  }
+
+  public String exec(String value) 
+  {
+    return "[" + value + "]";
+  }
+
+}

Propchange: 
jakarta/velocity/engine/trunk/src/test/org/apache/velocity/test/IntrospectionCacheDataTestCase.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: 
jakarta/velocity/engine/trunk/src/test/org/apache/velocity/test/IntrospectionCacheDataTestCase.java
------------------------------------------------------------------------------
    svn:keywords = Id Author Date Revision

Modified: jakarta/velocity/engine/trunk/xdocs/changes.xml
URL: 
http://svn.apache.org/viewvc/jakarta/velocity/engine/trunk/xdocs/changes.xml?view=diff&rev=449347&r1=449346&r2=449347
==============================================================================
--- jakarta/velocity/engine/trunk/xdocs/changes.xml (original)
+++ jakarta/velocity/engine/trunk/xdocs/changes.xml Sat Sep 23 20:55:33 2006
@@ -24,6 +24,10 @@
   <body>
     <release version="1.5-dev" date="in Subversion">
 
+      <action type="fix" dev="wglass" issue="VELOCITY-453" due-to="Alexey 
Panchenko">
+                 Method caching now uses consistent keys.
+      </action>
+
       <action type="fix" dev="wglass" issue="VELOCITY-459" due-to="Stephen 
Haberman">
          Change the meaning of localscope for macros to allow access to 
references from 
          calling context.



---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to