use of org.springframework.expression.AccessException in project spring-framework by spring-projects.
the class ReflectiveMethodExecutor method execute.
@Override
public TypedValue execute(EvaluationContext context, Object target, Object... arguments) throws AccessException {
try {
if (arguments != null) {
this.argumentConversionOccurred = ReflectionHelper.convertArguments(context.getTypeConverter(), arguments, this.method, this.varargsPosition);
}
if (this.method.isVarArgs()) {
arguments = ReflectionHelper.setupArgumentsForVarargsInvocation(this.method.getParameterTypes(), arguments);
}
ReflectionUtils.makeAccessible(this.method);
Object value = this.method.invoke(target, arguments);
return new TypedValue(value, new TypeDescriptor(new MethodParameter(this.method, -1)).narrow(value));
} catch (Exception ex) {
throw new AccessException("Problem invoking method: " + this.method, ex);
}
}
use of org.springframework.expression.AccessException in project spring-framework by spring-projects.
the class ReflectivePropertyAccessor method write.
@Override
public void write(EvaluationContext context, Object target, String name, Object newValue) throws AccessException {
if (target == null) {
throw new AccessException("Cannot write property on null target");
}
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.forObject(newValue), typeDescriptor);
} catch (EvaluationException evaluationException) {
throw new AccessException("Type conversion failure", evaluationException);
}
}
PropertyCacheKey cacheKey = new PropertyCacheKey(type, name, target instanceof Class);
Member cachedMember = this.writerCache.get(cacheKey);
if (cachedMember == null || cachedMember instanceof Method) {
Method method = (Method) cachedMember;
if (method == null) {
method = findSetterForProperty(name, type, target);
if (method != null) {
cachedMember = method;
this.writerCache.put(cacheKey, cachedMember);
}
}
if (method != null) {
try {
ReflectionUtils.makeAccessible(method);
method.invoke(target, possiblyConvertedNewValue);
return;
} catch (Exception ex) {
throw new AccessException("Unable to access property '" + name + "' through setter method", ex);
}
}
}
if (cachedMember == null || cachedMember instanceof Field) {
Field field = (Field) cachedMember;
if (field == null) {
field = findField(name, type, target);
if (field != null) {
cachedMember = field;
this.writerCache.put(cacheKey, cachedMember);
}
}
if (field != null) {
try {
ReflectionUtils.makeAccessible(field);
field.set(target, possiblyConvertedNewValue);
return;
} catch (Exception ex) {
throw new AccessException("Unable to access field '" + name + "'", ex);
}
}
}
throw new AccessException("Neither setter method nor field found for property '" + name + "'");
}
use of org.springframework.expression.AccessException in project spring-framework by spring-projects.
the class ReflectivePropertyAccessor method read.
@Override
public TypedValue read(EvaluationContext context, Object target, String name) throws AccessException {
if (target == null) {
throw new AccessException("Cannot read property of null target");
}
Class<?> type = (target instanceof Class ? (Class<?>) target : target.getClass());
if (type.isArray() && name.equals("length")) {
if (target instanceof Class) {
throw new AccessException("Cannot access length on array class itself");
}
return new TypedValue(Array.getLength(target));
}
PropertyCacheKey cacheKey = new PropertyCacheKey(type, name, target instanceof Class);
InvokerPair invoker = this.readerCache.get(cacheKey);
lastReadInvokerPair = invoker;
if (invoker == null || invoker.member instanceof Method) {
Method method = (Method) (invoker != null ? invoker.member : null);
if (method == null) {
method = findGetterForProperty(name, type, target);
if (method != null) {
// TODO remove the duplication here between canRead and read
// Treat it like a property...
// The readerCache will only contain gettable properties (let's not worry about setters for now).
Property property = new Property(type, method, null);
TypeDescriptor typeDescriptor = new TypeDescriptor(property);
invoker = new InvokerPair(method, typeDescriptor);
lastReadInvokerPair = invoker;
this.readerCache.put(cacheKey, invoker);
}
}
if (method != null) {
try {
ReflectionUtils.makeAccessible(method);
Object value = method.invoke(target);
return new TypedValue(value, invoker.typeDescriptor.narrow(value));
} catch (Exception ex) {
throw new AccessException("Unable to access property '" + name + "' through getter method", ex);
}
}
}
if (invoker == null || invoker.member instanceof Field) {
Field field = (Field) (invoker == null ? null : invoker.member);
if (field == null) {
field = findField(name, type, target);
if (field != null) {
invoker = new InvokerPair(field, new TypeDescriptor(field));
lastReadInvokerPair = invoker;
this.readerCache.put(cacheKey, invoker);
}
}
if (field != null) {
try {
ReflectionUtils.makeAccessible(field);
Object value = field.get(target);
return new TypedValue(value, invoker.typeDescriptor.narrow(value));
} catch (Exception ex) {
throw new AccessException("Unable to access field '" + name + "'", ex);
}
}
}
throw new AccessException("Neither getter method nor field found for property '" + name + "'");
}
use of org.springframework.expression.AccessException in project spring-framework by spring-projects.
the class MethodReference method getValueInternal.
private TypedValue getValueInternal(EvaluationContext evaluationContext, Object value, TypeDescriptor targetType, Object[] arguments) {
List<TypeDescriptor> argumentTypes = getArgumentTypes(arguments);
if (value == null) {
throwIfNotNullSafe(argumentTypes);
return TypedValue.NULL;
}
MethodExecutor executorToUse = getCachedExecutor(evaluationContext, value, targetType, argumentTypes);
if (executorToUse != null) {
try {
return executorToUse.execute(evaluationContext, value, arguments);
} catch (AccessException ex) {
// Two reasons this can occur:
// 1. the method invoked actually threw a real exception
// 2. the method invoked was not passed the arguments it expected and
// has become 'stale'
// In the first case we should not retry, in the second case we should see
// if there is a better suited method.
// To determine the situation, the AccessException will contain a cause.
// If the cause is an InvocationTargetException, a user exception was
// thrown inside the method. Otherwise the method could not be invoked.
throwSimpleExceptionIfPossible(value, ex);
// At this point we know it wasn't a user problem so worth a retry if a
// better candidate can be found.
this.cachedExecutor = null;
}
}
// either there was no accessor or it no longer existed
executorToUse = findAccessorForMethod(this.name, argumentTypes, value, evaluationContext);
this.cachedExecutor = new CachedMethodExecutor(executorToUse, (value instanceof Class ? (Class<?>) value : null), targetType, argumentTypes);
try {
return executorToUse.execute(evaluationContext, value, arguments);
} catch (AccessException ex) {
// Same unwrapping exception handling as above in above catch block
throwSimpleExceptionIfPossible(value, ex);
throw new SpelEvaluationException(getStartPosition(), ex, SpelMessage.EXCEPTION_DURING_METHOD_INVOCATION, this.name, value.getClass().getName(), ex.getMessage());
}
}
Aggregations