design change - no longer surfacing typeDescriptor through property accessor. conversion done internally in property write() code
This commit is contained in:
@@ -16,7 +16,6 @@
|
||||
|
||||
package org.springframework.expression;
|
||||
|
||||
import org.springframework.core.convert.TypeDescriptor;
|
||||
|
||||
/**
|
||||
* A property accessor is able to read (and possibly write) to object properties. The interface places no restrictions
|
||||
@@ -43,15 +42,6 @@ public interface PropertyAccessor {
|
||||
* @return an array of classes that this resolver is suitable for (or null if a general resolver)
|
||||
*/
|
||||
Class[] getSpecificTargetClasses();
|
||||
|
||||
/**
|
||||
* Called to retrieve a type descriptor that describes the type of the property.
|
||||
* @param context the evaluation context in which the access is being attempted
|
||||
* @param target the target object upon which the property is being accessed
|
||||
* @param name the name of the property being accessed
|
||||
* @return a type descriptor that describes the type of this property.
|
||||
*/
|
||||
TypeDescriptor getTypeDescriptor(EvaluationContext context, Object target, String name);
|
||||
|
||||
/**
|
||||
* Called to determine if a resolver instance is able to access a specified property on a specified target object.
|
||||
|
||||
@@ -20,10 +20,8 @@ import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.antlr.runtime.Token;
|
||||
import org.springframework.core.convert.TypeDescriptor;
|
||||
import org.springframework.expression.AccessException;
|
||||
import org.springframework.expression.EvaluationContext;
|
||||
import org.springframework.expression.EvaluationException;
|
||||
import org.springframework.expression.PropertyAccessor;
|
||||
import org.springframework.expression.spel.ExpressionState;
|
||||
import org.springframework.expression.spel.SpelException;
|
||||
@@ -44,9 +42,6 @@ public class PropertyOrFieldReference extends SpelNodeImpl {
|
||||
|
||||
private volatile PropertyAccessor cachedWriteAccessor;
|
||||
|
||||
private volatile TypeDescriptor cachedTypeDescriptor;
|
||||
|
||||
|
||||
public PropertyOrFieldReference(Token payload) {
|
||||
super(payload);
|
||||
this.name = payload.getText();
|
||||
@@ -126,19 +121,7 @@ public class PropertyOrFieldReference extends SpelNodeImpl {
|
||||
PropertyAccessor accessorToUse = this.cachedWriteAccessor;
|
||||
if (accessorToUse != null) {
|
||||
try {
|
||||
Object possiblyConvertedValue = newValue;
|
||||
if (cachedTypeDescriptor == null) {
|
||||
cachedTypeDescriptor=accessorToUse.getTypeDescriptor(eContext, contextObject, name);
|
||||
}
|
||||
if (cachedTypeDescriptor != null) {
|
||||
try {
|
||||
possiblyConvertedValue = state.convertValue(newValue, cachedTypeDescriptor.getType());
|
||||
} catch (EvaluationException evaluationException) {
|
||||
throw new SpelException(getCharPositionInLine(), evaluationException, SpelMessages.TYPE_CONVERSION_ERROR,
|
||||
newValue.getClass(), cachedTypeDescriptor.getType());
|
||||
}
|
||||
}
|
||||
accessorToUse.write(state.getEvaluationContext(), contextObject, name, possiblyConvertedValue);
|
||||
accessorToUse.write(state.getEvaluationContext(), contextObject, name, newValue);
|
||||
return;
|
||||
}
|
||||
catch (AccessException ae) {
|
||||
@@ -156,19 +139,7 @@ public class PropertyOrFieldReference extends SpelNodeImpl {
|
||||
for (PropertyAccessor accessor : accessorsToTry) {
|
||||
if (accessor.canWrite(eContext, contextObject, name)) {
|
||||
this.cachedWriteAccessor = accessor;
|
||||
Object possiblyConvertedValue = newValue;
|
||||
if (cachedTypeDescriptor == null) {
|
||||
cachedTypeDescriptor=accessor.getTypeDescriptor(eContext, contextObject, name);
|
||||
}
|
||||
if (cachedTypeDescriptor != null) {
|
||||
try {
|
||||
possiblyConvertedValue = state.convertValue(newValue, cachedTypeDescriptor);
|
||||
} catch (EvaluationException evaluationException) {
|
||||
throw new SpelException(getCharPositionInLine(), evaluationException, SpelMessages.TYPE_CONVERSION_ERROR,
|
||||
newValue.getClass(), cachedTypeDescriptor.getType());
|
||||
}
|
||||
}
|
||||
accessor.write(eContext, contextObject, name, possiblyConvertedValue);
|
||||
accessor.write(eContext, contextObject, name, newValue);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,6 +28,7 @@ import org.springframework.core.MethodParameter;
|
||||
import org.springframework.core.convert.TypeDescriptor;
|
||||
import org.springframework.expression.AccessException;
|
||||
import org.springframework.expression.EvaluationContext;
|
||||
import org.springframework.expression.EvaluationException;
|
||||
import org.springframework.expression.PropertyAccessor;
|
||||
import org.springframework.util.ReflectionUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
@@ -175,6 +176,16 @@ public class ReflectivePropertyResolver implements PropertyAccessor {
|
||||
}
|
||||
Class<?> type = (target instanceof Class ? (Class<?>) target : target.getClass());
|
||||
|
||||
Object possiblyConvertedNewValue = newValue;
|
||||
TypeDescriptor typeDescriptor = getTypeDescriptor(context, target, name);
|
||||
if (typeDescriptor != null) {
|
||||
try {
|
||||
possiblyConvertedNewValue = context.getTypeConverter().convertValue(newValue, typeDescriptor);
|
||||
} catch (EvaluationException evaluationException) {
|
||||
throw new AccessException("Type conversion failure",evaluationException);
|
||||
}
|
||||
}
|
||||
|
||||
CacheKey cacheKey = new CacheKey(type, name);
|
||||
Member cachedMember = this.writerCache.get(cacheKey);
|
||||
|
||||
@@ -190,7 +201,7 @@ public class ReflectivePropertyResolver implements PropertyAccessor {
|
||||
if (method != null) {
|
||||
try {
|
||||
ReflectionUtils.makeAccessible(method);
|
||||
method.invoke(target, newValue);
|
||||
method.invoke(target, possiblyConvertedNewValue);
|
||||
return;
|
||||
}
|
||||
catch (Exception ex) {
|
||||
@@ -211,7 +222,7 @@ public class ReflectivePropertyResolver implements PropertyAccessor {
|
||||
if (field != null) {
|
||||
try {
|
||||
ReflectionUtils.makeAccessible(field);
|
||||
field.set(target, newValue);
|
||||
field.set(target, possiblyConvertedNewValue);
|
||||
return;
|
||||
}
|
||||
catch (Exception ex) {
|
||||
@@ -223,7 +234,7 @@ public class ReflectivePropertyResolver implements PropertyAccessor {
|
||||
throw new AccessException("Neither setter nor field found for property '" + name + "'");
|
||||
}
|
||||
|
||||
public TypeDescriptor getTypeDescriptor(EvaluationContext context, Object target, String name) {
|
||||
private TypeDescriptor getTypeDescriptor(EvaluationContext context, Object target, String name) {
|
||||
if (target == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user