Search in sources :

Example 11 with AccessException

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);
    }
}
Also used : AccessException(org.springframework.expression.AccessException) TypeDescriptor(org.springframework.core.convert.TypeDescriptor) MethodParameter(org.springframework.core.MethodParameter) AccessException(org.springframework.expression.AccessException) TypedValue(org.springframework.expression.TypedValue)

Example 12 with AccessException

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 + "'");
}
Also used : Field(java.lang.reflect.Field) AccessException(org.springframework.expression.AccessException) TypeDescriptor(org.springframework.core.convert.TypeDescriptor) EvaluationException(org.springframework.expression.EvaluationException) Method(java.lang.reflect.Method) Member(java.lang.reflect.Member) EvaluationException(org.springframework.expression.EvaluationException) AccessException(org.springframework.expression.AccessException)

Example 13 with AccessException

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 + "'");
}
Also used : Field(java.lang.reflect.Field) AccessException(org.springframework.expression.AccessException) TypeDescriptor(org.springframework.core.convert.TypeDescriptor) Method(java.lang.reflect.Method) Property(org.springframework.core.convert.Property) EvaluationException(org.springframework.expression.EvaluationException) AccessException(org.springframework.expression.AccessException) TypedValue(org.springframework.expression.TypedValue)

Example 14 with AccessException

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());
    }
}
Also used : SpelEvaluationException(org.springframework.expression.spel.SpelEvaluationException) AccessException(org.springframework.expression.AccessException) TypeDescriptor(org.springframework.core.convert.TypeDescriptor) ReflectiveMethodExecutor(org.springframework.expression.spel.support.ReflectiveMethodExecutor) MethodExecutor(org.springframework.expression.MethodExecutor)

Aggregations

AccessException (org.springframework.expression.AccessException)14 TypeDescriptor (org.springframework.core.convert.TypeDescriptor)9 EvaluationException (org.springframework.expression.EvaluationException)6 SpelEvaluationException (org.springframework.expression.spel.SpelEvaluationException)5 Method (java.lang.reflect.Method)4 Test (org.junit.Test)4 MethodParameter (org.springframework.core.MethodParameter)4 EvaluationContext (org.springframework.expression.EvaluationContext)4 TypedValue (org.springframework.expression.TypedValue)4 StandardEvaluationContext (org.springframework.expression.spel.support.StandardEvaluationContext)4 ArrayList (java.util.ArrayList)3 Expression (org.springframework.expression.Expression)3 SpelExpression (org.springframework.expression.spel.standard.SpelExpression)3 Field (java.lang.reflect.Field)2 InvocationTargetException (java.lang.reflect.InvocationTargetException)2 ConstructorExecutor (org.springframework.expression.ConstructorExecutor)2 MethodExecutor (org.springframework.expression.MethodExecutor)2 PropertyAccessor (org.springframework.expression.PropertyAccessor)2 TypeConverter (org.springframework.expression.TypeConverter)2 SpelExpressionParser (org.springframework.expression.spel.standard.SpelExpressionParser)2