Search in sources :

Example 1 with ReflectiveConstructorExecutor

use of org.springframework.expression.spel.support.ReflectiveConstructorExecutor 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 ReflectiveConstructorExecutor

use of org.springframework.expression.spel.support.ReflectiveConstructorExecutor in project spring-framework by spring-projects.

the class ConstructorReference method generateCode.

@Override
public void generateCode(MethodVisitor mv, CodeFlow cf) {
    ReflectiveConstructorExecutor executor = ((ReflectiveConstructorExecutor) this.cachedExecutor);
    Constructor<?> constructor = executor.getConstructor();
    String classDesc = constructor.getDeclaringClass().getName().replace('.', '/');
    mv.visitTypeInsn(NEW, classDesc);
    mv.visitInsn(DUP);
    // children[0] is the type of the constructor, don't want to include that in argument processing
    SpelNodeImpl[] arguments = new SpelNodeImpl[children.length - 1];
    System.arraycopy(children, 1, arguments, 0, children.length - 1);
    generateCodeForArguments(mv, cf, constructor, arguments);
    mv.visitMethodInsn(INVOKESPECIAL, classDesc, "<init>", CodeFlow.createSignatureDescriptor(constructor), false);
    cf.pushDescriptor(this.exitTypeDescriptor);
}
Also used : ReflectiveConstructorExecutor(org.springframework.expression.spel.support.ReflectiveConstructorExecutor)

Example 3 with ReflectiveConstructorExecutor

use of org.springframework.expression.spel.support.ReflectiveConstructorExecutor in project spring-framework by spring-projects.

the class ConstructorReference method isCompilable.

@Override
public boolean isCompilable() {
    if (!(this.cachedExecutor instanceof ReflectiveConstructorExecutor) || this.exitTypeDescriptor == null) {
        return false;
    }
    if (getChildCount() > 1) {
        for (int c = 1, max = getChildCount(); c < max; c++) {
            if (!this.children[c].isCompilable()) {
                return false;
            }
        }
    }
    ReflectiveConstructorExecutor executor = (ReflectiveConstructorExecutor) this.cachedExecutor;
    Constructor<?> constructor = executor.getConstructor();
    return (Modifier.isPublic(constructor.getModifiers()) && Modifier.isPublic(constructor.getDeclaringClass().getModifiers()));
}
Also used : ReflectiveConstructorExecutor(org.springframework.expression.spel.support.ReflectiveConstructorExecutor)

Aggregations

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