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]