Author: henning Date: Mon Oct 9 14:16:16 2006 New Revision: 454515 URL: http://svn.apache.org/viewvc?view=rev&rev=454515 Log: Add Get and Set Executors that are smart about Maps. This should be a significant speedup if you have context objects that are maps and use get() and put() extensively. Makes VELOCITY-449 ready to be closed.
Added: jakarta/velocity/engine/trunk/src/java/org/apache/velocity/runtime/parser/node/MapGetExecutor.java (with props) jakarta/velocity/engine/trunk/src/java/org/apache/velocity/runtime/parser/node/MapSetExecutor.java (with props) Modified: jakarta/velocity/engine/trunk/src/java/org/apache/velocity/util/introspection/UberspectImpl.java jakarta/velocity/engine/trunk/xdocs/changes.xml Added: jakarta/velocity/engine/trunk/src/java/org/apache/velocity/runtime/parser/node/MapGetExecutor.java URL: http://svn.apache.org/viewvc/jakarta/velocity/engine/trunk/src/java/org/apache/velocity/runtime/parser/node/MapGetExecutor.java?view=auto&rev=454515 ============================================================================== --- jakarta/velocity/engine/trunk/src/java/org/apache/velocity/runtime/parser/node/MapGetExecutor.java (added) +++ jakarta/velocity/engine/trunk/src/java/org/apache/velocity/runtime/parser/node/MapGetExecutor.java Mon Oct 9 14:16:16 2006 @@ -0,0 +1,76 @@ +package org.apache.velocity.runtime.parser.node; + +/* + * Copyright 2000-2006 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.util.Map; + +import org.apache.velocity.runtime.log.Log; + +/** + * GetExecutor that is smart about Maps. If it detects one, it does not + * use Reflection but a cast to access the getter. + * + * @author <a href="mailto:[EMAIL PROTECTED]">Henning P. Schmiedehausen</a> + * @version $Id$ + */ +public class MapGetExecutor + extends AbstractExecutor +{ + private final String property; + + public MapGetExecutor(final Log log, final Class clazz, final String property) + { + this.log = log; + this.property = property; + discover(clazz); + } + + protected void discover (final Class clazz) + { + Class [] interfaces = clazz.getInterfaces(); + for (int i = 0 ; i < interfaces.length; i++) + { + if (interfaces[i].equals(Map.class)) + { + try + { + if (property != null) + { + setMethod(Map.class.getMethod("get", new Class [] { Object.class })); + } + } + /** + * pass through application level runtime exceptions + */ + catch( RuntimeException e ) + { + throw e; + } + catch(Exception e) + { + log.error("While looking for get('" + property + "') method:", e); + } + break; + } + } + } + + public Object execute(final Object o) + { + return ((Map) o).get(property); + } +} Propchange: jakarta/velocity/engine/trunk/src/java/org/apache/velocity/runtime/parser/node/MapGetExecutor.java ------------------------------------------------------------------------------ svn:eol-style = native Propchange: jakarta/velocity/engine/trunk/src/java/org/apache/velocity/runtime/parser/node/MapGetExecutor.java ------------------------------------------------------------------------------ svn:keywords = Id Author Date Revision Added: jakarta/velocity/engine/trunk/src/java/org/apache/velocity/runtime/parser/node/MapSetExecutor.java URL: http://svn.apache.org/viewvc/jakarta/velocity/engine/trunk/src/java/org/apache/velocity/runtime/parser/node/MapSetExecutor.java?view=auto&rev=454515 ============================================================================== --- jakarta/velocity/engine/trunk/src/java/org/apache/velocity/runtime/parser/node/MapSetExecutor.java (added) +++ jakarta/velocity/engine/trunk/src/java/org/apache/velocity/runtime/parser/node/MapSetExecutor.java Mon Oct 9 14:16:16 2006 @@ -0,0 +1,76 @@ +package org.apache.velocity.runtime.parser.node; + +/* + * Copyright 2000-2006 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.util.Map; + +import org.apache.velocity.runtime.log.Log; + +/** + * SetExecutor that is smart about Maps. If it detects one, it does not + * use Reflection but a cast to access the setter. + * + * @author <a href="mailto:[EMAIL PROTECTED]">Henning P. Schmiedehausen</a> + * @version $Id$ + */ +public class MapSetExecutor + extends SetExecutor +{ + private final String property; + + public MapSetExecutor(final Log log, final Class clazz, final String property) + { + this.log = log; + this.property = property; + discover(clazz); + } + + protected void discover (final Class clazz) + { + Class [] interfaces = clazz.getInterfaces(); + for (int i = 0 ; i < interfaces.length; i++) + { + if (interfaces[i].equals(Map.class)) + { + try + { + if (property != null) + { + setMethod(Map.class.getMethod("put", new Class [] { Object.class, Object.class })); + } + } + /** + * pass through application level runtime exceptions + */ + catch( RuntimeException e ) + { + throw e; + } + catch(Exception e) + { + log.error("While looking for get('" + property + "') method:", e); + } + break; + } + } + } + + public Object execute(final Object o, final Object arg) + { + return ((Map) o).put(property, arg); + } +} Propchange: jakarta/velocity/engine/trunk/src/java/org/apache/velocity/runtime/parser/node/MapSetExecutor.java ------------------------------------------------------------------------------ svn:eol-style = native Propchange: jakarta/velocity/engine/trunk/src/java/org/apache/velocity/runtime/parser/node/MapSetExecutor.java ------------------------------------------------------------------------------ svn:keywords = Id Author Date Revision Modified: jakarta/velocity/engine/trunk/src/java/org/apache/velocity/util/introspection/UberspectImpl.java URL: http://svn.apache.org/viewvc/jakarta/velocity/engine/trunk/src/java/org/apache/velocity/util/introspection/UberspectImpl.java?view=diff&rev=454515&r1=454514&r2=454515 ============================================================================== --- jakarta/velocity/engine/trunk/src/java/org/apache/velocity/util/introspection/UberspectImpl.java (original) +++ jakarta/velocity/engine/trunk/src/java/org/apache/velocity/util/introspection/UberspectImpl.java Mon Oct 9 14:16:16 2006 @@ -28,6 +28,8 @@ import org.apache.velocity.runtime.parser.node.AbstractExecutor; import org.apache.velocity.runtime.parser.node.BooleanPropertyExecutor; import org.apache.velocity.runtime.parser.node.GetExecutor; +import org.apache.velocity.runtime.parser.node.MapGetExecutor; +import org.apache.velocity.runtime.parser.node.MapSetExecutor; import org.apache.velocity.runtime.parser.node.PropertyExecutor; import org.apache.velocity.runtime.parser.node.PutExecutor; import org.apache.velocity.runtime.parser.node.SetExecutor; @@ -187,6 +189,14 @@ AbstractExecutor executor = new PropertyExecutor(log, introspector, claz, identifier); /* + * Let's see if we are a map... + */ + if (!executor.isAlive()) + { + executor = new MapGetExecutor(log, claz, identifier); + } + + /* * if that didn't work, look for get("foo") */ @@ -233,6 +243,13 @@ * (also setfoo() ) */ SetExecutor executor = new SetPropertyExecutor(log, introspector, claz, identifier, arg); + + /* + * Let's see if we are a map... + */ + if (!executor.isAlive()) { + executor = new MapSetExecutor(log, claz, identifier); + } /* * if that didn't work, look for put("foo", arg) Modified: jakarta/velocity/engine/trunk/xdocs/changes.xml URL: http://svn.apache.org/viewvc/jakarta/velocity/engine/trunk/xdocs/changes.xml?view=diff&rev=454515&r1=454514&r2=454515 ============================================================================== --- jakarta/velocity/engine/trunk/xdocs/changes.xml (original) +++ jakarta/velocity/engine/trunk/xdocs/changes.xml Mon Oct 9 14:16:16 2006 @@ -24,6 +24,10 @@ <body> <release version="1.5-dev" date="in Subversion"> + <action type="fix" dev="wglass" issue="VELOCITY-449" due-to="Alexey Panchenko"> + Add an additional pair of Executors that are smart about Map. + </action> + <action type="fix" dev="wglass" issue="VELOCITY-453" due-to="Alexey Panchenko"> Method caching now uses consistent keys. </action> --------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]