Add cache to SelectionTrackingActionListener
Issue: SWF-1614
This commit is contained in:
@@ -16,6 +16,8 @@
|
|||||||
package org.springframework.faces.model;
|
package org.springframework.faces.model;
|
||||||
|
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
import javax.faces.component.UIComponent;
|
import javax.faces.component.UIComponent;
|
||||||
import javax.faces.component.UIData;
|
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.Log;
|
||||||
import org.apache.commons.logging.LogFactory;
|
import org.apache.commons.logging.LogFactory;
|
||||||
import org.springframework.faces.webflow.FlowActionListener;
|
import org.springframework.faces.webflow.FlowActionListener;
|
||||||
|
import org.springframework.util.ClassUtils;
|
||||||
import org.springframework.util.ReflectionUtils;
|
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
|
* 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
|
* current row index is pointing to the desired row as it would need to be to use an expression such as
|
||||||
* #{model.rowData.id}
|
* #{model.rowData.id}
|
||||||
*
|
*
|
||||||
* @author Jeremy Grelle
|
* @author Jeremy Grelle
|
||||||
*/
|
*/
|
||||||
public class SelectionTrackingActionListener implements ActionListener {
|
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 static final Log logger = LogFactory.getLog(FlowActionListener.class);
|
||||||
|
|
||||||
private final ActionListener delegate;
|
private final ActionListener delegate;
|
||||||
|
|
||||||
|
private final Map<Class<?>, Method> valueMethodCache = new ConcurrentHashMap<Class<?>, Method>(256);
|
||||||
|
|
||||||
|
|
||||||
public SelectionTrackingActionListener(ActionListener delegate) {
|
public SelectionTrackingActionListener(ActionListener delegate) {
|
||||||
this.delegate = delegate;
|
this.delegate = delegate;
|
||||||
}
|
}
|
||||||
@@ -60,7 +69,7 @@ public class SelectionTrackingActionListener implements ActionListener {
|
|||||||
UIComponent currentComponent = component;
|
UIComponent currentComponent = component;
|
||||||
while (currentComponent.getParent() != null && !(currentComponent.getParent() instanceof UIViewRoot)) {
|
while (currentComponent.getParent() != null && !(currentComponent.getParent() instanceof UIViewRoot)) {
|
||||||
UIComponent parent = currentComponent.getParent();
|
UIComponent parent = currentComponent.getParent();
|
||||||
Method valueAccessor = ReflectionUtils.findMethod(parent.getClass(), "getValue");
|
Method valueAccessor = getValueMethod(parent.getClass());
|
||||||
if (valueAccessor != null) {
|
if (valueAccessor != null) {
|
||||||
Object value = ReflectionUtils.invokeMethod(valueAccessor, parent);
|
Object value = ReflectionUtils.invokeMethod(valueAccessor, parent);
|
||||||
if (value != null && value instanceof SelectionAware) {
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user