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));
}
}
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));
}
Aggregations