Search in sources :

Example 1 with AccessException

use of org.springframework.expression.AccessException in project spring-framework by spring-projects.

the class ConstructorReference method createNewInstance.

/**
	 * Create a new ordinary object and return it.
	 * @param state the expression state within which this expression is being evaluated
	 * @return the new object
	 * @throws EvaluationException if there is a problem creating the object
	 */
private TypedValue createNewInstance(ExpressionState state) throws EvaluationException {
    Object[] arguments = new Object[getChildCount() - 1];
    List<TypeDescriptor> argumentTypes = new ArrayList<>(getChildCount() - 1);
    for (int i = 0; i < arguments.length; i++) {
        TypedValue childValue = this.children[i + 1].getValueInternal(state);
        Object value = childValue.getValue();
        arguments[i] = value;
        argumentTypes.add(TypeDescriptor.forObject(value));
    }
    ConstructorExecutor executorToUse = this.cachedExecutor;
    if (executorToUse != null) {
        try {
            return executorToUse.execute(state.getEvaluationContext(), arguments);
        } catch (AccessException ex) {
            // Otherwise the constructor could not be invoked.
            if (ex.getCause() instanceof InvocationTargetException) {
                // User exception was the root cause - exit now
                Throwable rootCause = ex.getCause().getCause();
                if (rootCause instanceof RuntimeException) {
                    throw (RuntimeException) rootCause;
                } else {
                    String typeName = (String) this.children[0].getValueInternal(state).getValue();
                    throw new SpelEvaluationException(getStartPosition(), rootCause, SpelMessage.CONSTRUCTOR_INVOCATION_PROBLEM, typeName, FormatHelper.formatMethodForMessage("", argumentTypes));
                }
            }
            // 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 exists
    String typeName = (String) this.children[0].getValueInternal(state).getValue();
    executorToUse = findExecutorForConstructor(typeName, argumentTypes, state);
    try {
        this.cachedExecutor = executorToUse;
        if (this.cachedExecutor instanceof ReflectiveConstructorExecutor) {
            this.exitTypeDescriptor = CodeFlow.toDescriptor(((ReflectiveConstructorExecutor) this.cachedExecutor).getConstructor().getDeclaringClass());
        }
        return executorToUse.execute(state.getEvaluationContext(), arguments);
    } catch (AccessException ex) {
        throw new SpelEvaluationException(getStartPosition(), ex, SpelMessage.CONSTRUCTOR_INVOCATION_PROBLEM, typeName, FormatHelper.formatMethodForMessage("", argumentTypes));
    }
}
Also used : SpelEvaluationException(org.springframework.expression.spel.SpelEvaluationException) ReflectiveConstructorExecutor(org.springframework.expression.spel.support.ReflectiveConstructorExecutor) ArrayList(java.util.ArrayList) InvocationTargetException(java.lang.reflect.InvocationTargetException) AccessException(org.springframework.expression.AccessException) TypeDescriptor(org.springframework.core.convert.TypeDescriptor) ReflectiveConstructorExecutor(org.springframework.expression.spel.support.ReflectiveConstructorExecutor) ConstructorExecutor(org.springframework.expression.ConstructorExecutor) TypedValue(org.springframework.expression.TypedValue)

Example 2 with AccessException

use of org.springframework.expression.AccessException in project spring-framework by spring-projects.

the class ConstructorReference method findExecutorForConstructor.

/**
	 * Go through the list of registered constructor resolvers and see if any can find a
	 * constructor that takes the specified set of arguments.
	 * @param typeName the type trying to be constructed
	 * @param argumentTypes the types of the arguments supplied that the constructor must take
	 * @param state the current state of the expression
	 * @return a reusable ConstructorExecutor that can be invoked to run the constructor or null
	 * @throws SpelEvaluationException if there is a problem locating the constructor
	 */
private ConstructorExecutor findExecutorForConstructor(String typeName, List<TypeDescriptor> argumentTypes, ExpressionState state) throws SpelEvaluationException {
    EvaluationContext evalContext = state.getEvaluationContext();
    List<ConstructorResolver> ctorResolvers = evalContext.getConstructorResolvers();
    if (ctorResolvers != null) {
        for (ConstructorResolver ctorResolver : ctorResolvers) {
            try {
                ConstructorExecutor ce = ctorResolver.resolve(state.getEvaluationContext(), typeName, argumentTypes);
                if (ce != null) {
                    return ce;
                }
            } catch (AccessException ex) {
                throw new SpelEvaluationException(getStartPosition(), ex, SpelMessage.CONSTRUCTOR_INVOCATION_PROBLEM, typeName, FormatHelper.formatMethodForMessage("", argumentTypes));
            }
        }
    }
    throw new SpelEvaluationException(getStartPosition(), SpelMessage.CONSTRUCTOR_NOT_FOUND, typeName, FormatHelper.formatMethodForMessage("", argumentTypes));
}
Also used : SpelEvaluationException(org.springframework.expression.spel.SpelEvaluationException) AccessException(org.springframework.expression.AccessException) ConstructorResolver(org.springframework.expression.ConstructorResolver) ReflectiveConstructorExecutor(org.springframework.expression.spel.support.ReflectiveConstructorExecutor) ConstructorExecutor(org.springframework.expression.ConstructorExecutor) EvaluationContext(org.springframework.expression.EvaluationContext)

Example 3 with AccessException

use of org.springframework.expression.AccessException in project spring-framework by spring-projects.

the class ReflectivePropertyAccessor method getTypeDescriptor.

private TypeDescriptor getTypeDescriptor(EvaluationContext context, Object target, String name) {
    if (target == null) {
        return null;
    }
    Class<?> type = (target instanceof Class ? (Class<?>) target : target.getClass());
    if (type.isArray() && name.equals("length")) {
        return TypeDescriptor.valueOf(Integer.TYPE);
    }
    PropertyCacheKey cacheKey = new PropertyCacheKey(type, name, target instanceof Class);
    TypeDescriptor typeDescriptor = this.typeDescriptorCache.get(cacheKey);
    if (typeDescriptor == null) {
        // attempt to populate the cache entry
        try {
            if (canRead(context, target, name)) {
                typeDescriptor = this.typeDescriptorCache.get(cacheKey);
            } else if (canWrite(context, target, name)) {
                typeDescriptor = this.typeDescriptorCache.get(cacheKey);
            }
        } catch (AccessException ex) {
        // continue with null type descriptor
        }
    }
    return typeDescriptor;
}
Also used : AccessException(org.springframework.expression.AccessException) TypeDescriptor(org.springframework.core.convert.TypeDescriptor)

Example 4 with AccessException

use of org.springframework.expression.AccessException in project spring-framework by spring-projects.

the class PropertyOrFieldReference method writeProperty.

private void writeProperty(TypedValue contextObject, EvaluationContext evalContext, String name, Object newValue) throws EvaluationException {
    if (contextObject.getValue() == null && this.nullSafe) {
        return;
    }
    PropertyAccessor accessorToUse = this.cachedWriteAccessor;
    if (accessorToUse != null) {
        try {
            accessorToUse.write(evalContext, contextObject.getValue(), name, newValue);
            return;
        } catch (Exception ex) {
            // This is OK - it may have gone stale due to a class change,
            // let's try to get a new one and call it before giving up...
            this.cachedWriteAccessor = null;
        }
    }
    List<PropertyAccessor> accessorsToTry = getPropertyAccessorsToTry(contextObject.getValue(), evalContext.getPropertyAccessors());
    if (accessorsToTry != null) {
        try {
            for (PropertyAccessor accessor : accessorsToTry) {
                if (accessor.canWrite(evalContext, contextObject.getValue(), name)) {
                    this.cachedWriteAccessor = accessor;
                    accessor.write(evalContext, contextObject.getValue(), name, newValue);
                    return;
                }
            }
        } catch (AccessException ex) {
            throw new SpelEvaluationException(getStartPosition(), ex, SpelMessage.EXCEPTION_DURING_PROPERTY_WRITE, name, ex.getMessage());
        }
    }
    if (contextObject.getValue() == null) {
        throw new SpelEvaluationException(getStartPosition(), SpelMessage.PROPERTY_OR_FIELD_NOT_WRITABLE_ON_NULL, name);
    } else {
        throw new SpelEvaluationException(getStartPosition(), SpelMessage.PROPERTY_OR_FIELD_NOT_WRITABLE, name, FormatHelper.formatClassNameForMessage(getObjectClass(contextObject.getValue())));
    }
}
Also used : SpelEvaluationException(org.springframework.expression.spel.SpelEvaluationException) ReflectivePropertyAccessor(org.springframework.expression.spel.support.ReflectivePropertyAccessor) PropertyAccessor(org.springframework.expression.PropertyAccessor) CompilablePropertyAccessor(org.springframework.expression.spel.CompilablePropertyAccessor) AccessException(org.springframework.expression.AccessException) SpelEvaluationException(org.springframework.expression.spel.SpelEvaluationException) EvaluationException(org.springframework.expression.EvaluationException) AccessException(org.springframework.expression.AccessException) InvocationTargetException(java.lang.reflect.InvocationTargetException)

Example 5 with AccessException

use of org.springframework.expression.AccessException in project spring-framework by spring-projects.

the class ReflectiveConstructorResolver method resolve.

/**
	 * Locate a constructor on the type. There are three kinds of match that might occur:
	 * <ol>
	 * <li>An exact match where the types of the arguments match the types of the constructor
	 * <li>An in-exact match where the types we are looking for are subtypes of those defined on the constructor
	 * <li>A match where we are able to convert the arguments into those expected by the constructor, according to the
	 * registered type converter.
	 * </ol>
	 */
@Override
public ConstructorExecutor resolve(EvaluationContext context, String typeName, List<TypeDescriptor> argumentTypes) throws AccessException {
    try {
        TypeConverter typeConverter = context.getTypeConverter();
        Class<?> type = context.getTypeLocator().findType(typeName);
        Constructor<?>[] ctors = type.getConstructors();
        Arrays.sort(ctors, new Comparator<Constructor<?>>() {

            @Override
            public int compare(Constructor<?> c1, Constructor<?> c2) {
                int c1pl = c1.getParameterCount();
                int c2pl = c2.getParameterCount();
                return (c1pl < c2pl ? -1 : (c1pl > c2pl ? 1 : 0));
            }
        });
        Constructor<?> closeMatch = null;
        Constructor<?> matchRequiringConversion = null;
        for (Constructor<?> ctor : ctors) {
            Class<?>[] paramTypes = ctor.getParameterTypes();
            List<TypeDescriptor> paramDescriptors = new ArrayList<>(paramTypes.length);
            for (int i = 0; i < paramTypes.length; i++) {
                paramDescriptors.add(new TypeDescriptor(new MethodParameter(ctor, i)));
            }
            ReflectionHelper.ArgumentsMatchInfo matchInfo = null;
            if (ctor.isVarArgs() && argumentTypes.size() >= paramTypes.length - 1) {
                // *sigh* complicated
                // Basically.. we have to have all parameters match up until the varargs one, then the rest of what is
                // being provided should be
                // the same type whilst the final argument to the method must be an array of that (oh, how easy...not) -
                // or the final parameter
                // we are supplied does match exactly (it is an array already).
                matchInfo = ReflectionHelper.compareArgumentsVarargs(paramDescriptors, argumentTypes, typeConverter);
            } else if (paramTypes.length == argumentTypes.size()) {
                // worth a closer look
                matchInfo = ReflectionHelper.compareArguments(paramDescriptors, argumentTypes, typeConverter);
            }
            if (matchInfo != null) {
                if (matchInfo.isExactMatch()) {
                    return new ReflectiveConstructorExecutor(ctor);
                } else if (matchInfo.isCloseMatch()) {
                    closeMatch = ctor;
                } else if (matchInfo.isMatchRequiringConversion()) {
                    matchRequiringConversion = ctor;
                }
            }
        }
        if (closeMatch != null) {
            return new ReflectiveConstructorExecutor(closeMatch);
        } else if (matchRequiringConversion != null) {
            return new ReflectiveConstructorExecutor(matchRequiringConversion);
        } else {
            return null;
        }
    } catch (EvaluationException ex) {
        throw new AccessException("Failed to resolve constructor", ex);
    }
}
Also used : Constructor(java.lang.reflect.Constructor) ArrayList(java.util.ArrayList) EvaluationException(org.springframework.expression.EvaluationException) TypeConverter(org.springframework.expression.TypeConverter) AccessException(org.springframework.expression.AccessException) TypeDescriptor(org.springframework.core.convert.TypeDescriptor) MethodParameter(org.springframework.core.MethodParameter)

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