From 0076cb5c535e6873f9fd2be6bf530d8dfd29c39b Mon Sep 17 00:00:00 2001 From: Rossen Stoyanchev Date: Wed, 18 Dec 2013 16:18:08 -0500 Subject: [PATCH] Add cache to SelectionTrackingActionListener Issue: SWF-1614 --- .../SelectionTrackingActionListener.java | 22 +++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/spring-faces/src/main/java/org/springframework/faces/model/SelectionTrackingActionListener.java b/spring-faces/src/main/java/org/springframework/faces/model/SelectionTrackingActionListener.java index 1db971ac..4a119965 100644 --- a/spring-faces/src/main/java/org/springframework/faces/model/SelectionTrackingActionListener.java +++ b/spring-faces/src/main/java/org/springframework/faces/model/SelectionTrackingActionListener.java @@ -16,6 +16,8 @@ package org.springframework.faces.model; import java.lang.reflect.Method; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; import javax.faces.component.UIComponent; import javax.faces.component.UIData; @@ -27,6 +29,7 @@ import javax.faces.event.ActionListener; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.faces.webflow.FlowActionListener; +import org.springframework.util.ClassUtils; import org.springframework.util.ReflectionUtils; /** @@ -37,15 +40,21 @@ import org.springframework.util.ReflectionUtils; * at any time through EL expressions such as #{model.selectedRow.id} without having to rely on the whether or not the * current row index is pointing to the desired row as it would need to be to use an expression such as * #{model.rowData.id} - * + * * @author Jeremy Grelle */ public class SelectionTrackingActionListener implements ActionListener { + private static final Method NO_MATCH = + ClassUtils.getMethodIfAvailable(System.class, "currentTimeMillis", (Class[]) null); + private static final Log logger = LogFactory.getLog(FlowActionListener.class); private final ActionListener delegate; + private final Map, Method> valueMethodCache = new ConcurrentHashMap, Method>(256); + + public SelectionTrackingActionListener(ActionListener delegate) { this.delegate = delegate; } @@ -60,7 +69,7 @@ public class SelectionTrackingActionListener implements ActionListener { UIComponent currentComponent = component; while (currentComponent.getParent() != null && !(currentComponent.getParent() instanceof UIViewRoot)) { UIComponent parent = currentComponent.getParent(); - Method valueAccessor = ReflectionUtils.findMethod(parent.getClass(), "getValue"); + Method valueAccessor = getValueMethod(parent.getClass()); if (valueAccessor != null) { Object value = ReflectionUtils.invokeMethod(valueAccessor, parent); if (value != null && value instanceof SelectionAware) { @@ -75,4 +84,13 @@ public class SelectionTrackingActionListener implements ActionListener { } } + private Method getValueMethod(Class parentClass) { + Method method = this.valueMethodCache.get(parentClass); + if (method == null) { + method = ReflectionUtils.findMethod(parentClass, "getValue"); + this.valueMethodCache.put(parentClass, (method != null) ? method : NO_MATCH); + } + return (method != NO_MATCH) ? method : null; + } + }