Search in sources :

Example 1 with ConstructorExecutor

use of org.springframework.expression.ConstructorExecutor 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 ConstructorExecutor

use of org.springframework.expression.ConstructorExecutor 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)

Aggregations

AccessException (org.springframework.expression.AccessException)2 ConstructorExecutor (org.springframework.expression.ConstructorExecutor)2 SpelEvaluationException (org.springframework.expression.spel.SpelEvaluationException)2 ReflectiveConstructorExecutor (org.springframework.expression.spel.support.ReflectiveConstructorExecutor)2 InvocationTargetException (java.lang.reflect.InvocationTargetException)1 ArrayList (java.util.ArrayList)1 TypeDescriptor (org.springframework.core.convert.TypeDescriptor)1 ConstructorResolver (org.springframework.expression.ConstructorResolver)1 EvaluationContext (org.springframework.expression.EvaluationContext)1 TypedValue (org.springframework.expression.TypedValue)1