Changed so that existing getters/setters are used before direct field access is attempted
This commit is contained in:
parent
17c88107d3
commit
8740b702f9
|
|
@ -12,19 +12,33 @@ public class ReflectionPropertyReaderExecutor implements PropertyReaderExecutor
|
|||
|
||||
private Method methodToAccessProperty;
|
||||
private Field fieldToAccessProperty;
|
||||
private String propertyName;
|
||||
private final String propertyName;
|
||||
|
||||
public ReflectionPropertyReaderExecutor(String propertyName, Method method) {
|
||||
this.propertyName = propertyName;
|
||||
this.methodToAccessProperty = method;
|
||||
methodToAccessProperty = method;
|
||||
}
|
||||
|
||||
public ReflectionPropertyReaderExecutor(String propertyName, Field field) {
|
||||
this.propertyName = propertyName;
|
||||
this.fieldToAccessProperty = field;
|
||||
fieldToAccessProperty = field;
|
||||
}
|
||||
|
||||
public Object execute(EvaluationContext context, Object target) throws AccessException {
|
||||
if (methodToAccessProperty != null) {
|
||||
try {
|
||||
if (!methodToAccessProperty.isAccessible()) {
|
||||
methodToAccessProperty.setAccessible(true);
|
||||
}
|
||||
return methodToAccessProperty.invoke(target);
|
||||
} catch (IllegalArgumentException e) {
|
||||
throw new AccessException("Unable to access property '" + propertyName + "' through getter", e);
|
||||
} catch (IllegalAccessException e) {
|
||||
throw new AccessException("Unable to access property '" + propertyName + "' through getter", e);
|
||||
} catch (InvocationTargetException e) {
|
||||
throw new AccessException("Unable to access property '" + propertyName + "' through getter", e);
|
||||
}
|
||||
}
|
||||
if (fieldToAccessProperty != null) {
|
||||
try {
|
||||
if (!fieldToAccessProperty.isAccessible()) {
|
||||
|
|
@ -37,19 +51,6 @@ public class ReflectionPropertyReaderExecutor implements PropertyReaderExecutor
|
|||
throw new AccessException("Unable to access field: " + propertyName, e);
|
||||
}
|
||||
}
|
||||
if (methodToAccessProperty != null) {
|
||||
try {
|
||||
if (!methodToAccessProperty.isAccessible())
|
||||
methodToAccessProperty.setAccessible(true);
|
||||
return methodToAccessProperty.invoke(target);
|
||||
} catch (IllegalArgumentException e) {
|
||||
throw new AccessException("Unable to access property '" + propertyName + "' through getter", e);
|
||||
} catch (IllegalAccessException e) {
|
||||
throw new AccessException("Unable to access property '" + propertyName + "' through getter", e);
|
||||
} catch (InvocationTargetException e) {
|
||||
throw new AccessException("Unable to access property '" + propertyName + "' through getter", e);
|
||||
}
|
||||
}
|
||||
throw new AccessException("No method or field accessor found for property '" + propertyName + "'");
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -63,14 +63,14 @@ public class ReflectionPropertyResolver extends CacheablePropertyAccessor {
|
|||
if (relevantClass.isArray() && propertyName.equals("length")) {
|
||||
return new ReflectionPropertyReaderExecutorForArrayLength();
|
||||
}
|
||||
Field field = ReflectionUtils.findField(propertyName, relevantClass);
|
||||
if (field != null) {
|
||||
return new ReflectionPropertyReaderExecutor(propertyName, field);
|
||||
}
|
||||
Method m = ReflectionUtils.findGetterForProperty(propertyName, relevantClass);
|
||||
Method m = ReflectionUtils.findGetterForProperty(propertyName, relevantClass, target instanceof Class);
|
||||
if (m != null) {
|
||||
return new ReflectionPropertyReaderExecutor(propertyName, m);
|
||||
}
|
||||
Field field = ReflectionUtils.findField(propertyName, relevantClass, target instanceof Class);
|
||||
if (field != null) {
|
||||
return new ReflectionPropertyReaderExecutor(propertyName, field);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
|
@ -93,14 +93,14 @@ public class ReflectionPropertyResolver extends CacheablePropertyAccessor {
|
|||
// A property not found exception will occur if the reflection finder was supposed to find it
|
||||
return null;
|
||||
}
|
||||
Field field = ReflectionUtils.findField((String) name, relevantClass);
|
||||
if (field != null) {
|
||||
return new ReflectionPropertyWriterExecutor((String) name, field);
|
||||
}
|
||||
Method m = ReflectionUtils.findSetterForProperty((String) name, relevantClass);
|
||||
Method m = ReflectionUtils.findSetterForProperty((String) name, relevantClass, target instanceof Class);
|
||||
if (m != null) {
|
||||
return new ReflectionPropertyWriterExecutor((String) name, m);
|
||||
}
|
||||
Field field = ReflectionUtils.findField((String) name, relevantClass, target instanceof Class);
|
||||
if (field != null) {
|
||||
return new ReflectionPropertyWriterExecutor((String) name, field);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -12,33 +12,20 @@ public class ReflectionPropertyWriterExecutor implements PropertyWriterExecutor
|
|||
|
||||
private Method methodToAccessProperty;
|
||||
private Field fieldToAccessProperty;
|
||||
private String propertyName;
|
||||
private final String propertyName;
|
||||
|
||||
public ReflectionPropertyWriterExecutor(String propertyName, Method method) {
|
||||
this.propertyName = propertyName;
|
||||
this.methodToAccessProperty = method;
|
||||
methodToAccessProperty = method;
|
||||
}
|
||||
|
||||
public ReflectionPropertyWriterExecutor(String propertyName, Field field) {
|
||||
this.propertyName = propertyName;
|
||||
this.fieldToAccessProperty = field;
|
||||
fieldToAccessProperty = field;
|
||||
}
|
||||
|
||||
// public Object execute(EvaluationContext context, Object target) throws AccessException {
|
||||
public void execute(EvaluationContext evaluationContext, Object target, Object newValue) throws AccessException {
|
||||
if (fieldToAccessProperty != null) {
|
||||
try {
|
||||
if (!fieldToAccessProperty.isAccessible()) {
|
||||
fieldToAccessProperty.setAccessible(true);
|
||||
}
|
||||
fieldToAccessProperty.set(target, newValue);
|
||||
return;
|
||||
} catch (IllegalArgumentException e) {
|
||||
throw new AccessException("Unable to access field: " + propertyName, e);
|
||||
} catch (IllegalAccessException e) {
|
||||
throw new AccessException("Unable to access field: " + propertyName, e);
|
||||
}
|
||||
}
|
||||
if (methodToAccessProperty != null) {
|
||||
try {
|
||||
if (!methodToAccessProperty.isAccessible())
|
||||
|
|
@ -53,6 +40,19 @@ public class ReflectionPropertyWriterExecutor implements PropertyWriterExecutor
|
|||
throw new AccessException("Unable to access property '" + propertyName + "' through setter", e);
|
||||
}
|
||||
}
|
||||
if (fieldToAccessProperty != null) {
|
||||
try {
|
||||
if (!fieldToAccessProperty.isAccessible()) {
|
||||
fieldToAccessProperty.setAccessible(true);
|
||||
}
|
||||
fieldToAccessProperty.set(target, newValue);
|
||||
return;
|
||||
} catch (IllegalArgumentException e) {
|
||||
throw new AccessException("Unable to access field: " + propertyName, e);
|
||||
} catch (IllegalAccessException e) {
|
||||
throw new AccessException("Unable to access field: " + propertyName, e);
|
||||
}
|
||||
}
|
||||
throw new AccessException("No method or field accessor found for property '" + propertyName + "'");
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ import java.lang.reflect.Array;
|
|||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
|
|
@ -347,11 +348,11 @@ public class ReflectionUtils {
|
|||
/**
|
||||
* Find a field of a certain name on a specified class
|
||||
*/
|
||||
public final static Field findField(String name, Class<?> clazz) {
|
||||
Field[] fields = clazz.getFields(); // TODO what about inherited fields? try getFields() too?
|
||||
public final static Field findField(String name, Class<?> clazz, boolean mustBeStatic) {
|
||||
Field[] fields = clazz.getFields(); // TODO use getDeclaredFields() and search up hierarchy?
|
||||
for (int i = 0; i < fields.length; i++) {
|
||||
Field field = fields[i];
|
||||
if (field.getName().equals(name)) {
|
||||
if (field.getName().equals(name) && (mustBeStatic ? Modifier.isStatic(field.getModifiers()) : true)) {
|
||||
return field;
|
||||
}
|
||||
}
|
||||
|
|
@ -362,14 +363,16 @@ public class ReflectionUtils {
|
|||
* Find a getter method for the specified property. A getter is defined as a method whose name start with the prefix
|
||||
* 'get' and the rest of the name is the same as the property name (with the first character uppercased).
|
||||
*/
|
||||
public static Method findGetterForProperty(String propertyName, Class<?> clazz) {
|
||||
Method[] ms = clazz.getMethods();
|
||||
public static Method findGetterForProperty(String propertyName, Class<?> clazz, boolean mustBeStatic) {
|
||||
Method[] ms = clazz.getMethods();// TODO use getDeclaredMethods() and search up hierarchy?
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("get").append(propertyName.substring(0, 1).toUpperCase()).append(propertyName.substring(1));
|
||||
String expectedGetterName = sb.toString();
|
||||
for (int i = 0; i < ms.length; i++) {
|
||||
Method method = ms[i];
|
||||
if (method.getParameterTypes().length == 0 && method.getName().equals(expectedGetterName)) {
|
||||
if (method.getParameterTypes().length == 0
|
||||
&& (mustBeStatic ? Modifier.isStatic(method.getModifiers()) : true)
|
||||
&& method.getName().equals(expectedGetterName)) {
|
||||
return method;
|
||||
}
|
||||
}
|
||||
|
|
@ -379,14 +382,16 @@ public class ReflectionUtils {
|
|||
/**
|
||||
* Find a setter method for the specified property
|
||||
*/
|
||||
public static Method findSetterForProperty(String propertyName, Class<?> clazz) {
|
||||
Method[] ms = clazz.getMethods();
|
||||
public static Method findSetterForProperty(String propertyName, Class<?> clazz, boolean mustBeStatic) {
|
||||
Method[] ms = clazz.getMethods(); // TODO use getDeclaredMethods() and search up hierarchy?
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("set").append(propertyName.substring(0, 1).toUpperCase()).append(propertyName.substring(1));
|
||||
String setterName = sb.toString();
|
||||
for (int i = 0; i < ms.length; i++) {
|
||||
Method method = ms[i];
|
||||
if (method.getParameterTypes().length == 1 && method.getName().equals(setterName)) {
|
||||
if (method.getParameterTypes().length == 1
|
||||
&& (mustBeStatic ? Modifier.isStatic(method.getModifiers()) : true)
|
||||
&& method.getName().equals(setterName)) {
|
||||
return method;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue