use of org.springframework.core.convert.TypeDescriptor in project spring-framework by spring-projects.
the class Indexer method getValueRef.
@Override
protected ValueRef getValueRef(ExpressionState state) throws EvaluationException {
TypedValue context = state.getActiveContextObject();
Object targetObject = context.getValue();
TypeDescriptor targetDescriptor = context.getTypeDescriptor();
TypedValue indexValue = null;
Object index = null;
// the property (SPR-5847)
if (targetObject instanceof Map && (this.children[0] instanceof PropertyOrFieldReference)) {
PropertyOrFieldReference reference = (PropertyOrFieldReference) this.children[0];
index = reference.getName();
indexValue = new TypedValue(index);
} else {
// the root object so temporarily push that on whilst evaluating the key
try {
state.pushActiveContextObject(state.getRootContextObject());
indexValue = this.children[0].getValueInternal(state);
index = indexValue.getValue();
} finally {
state.popActiveContextObject();
}
}
// Indexing into a Map
if (targetObject instanceof Map) {
Object key = index;
if (targetDescriptor.getMapKeyTypeDescriptor() != null) {
key = state.convertValue(key, targetDescriptor.getMapKeyTypeDescriptor());
}
this.indexedType = IndexedType.MAP;
return new MapIndexingValueRef(state.getTypeConverter(), (Map<?, ?>) targetObject, key, targetDescriptor);
}
if (targetObject == null) {
throw new SpelEvaluationException(getStartPosition(), SpelMessage.CANNOT_INDEX_INTO_NULL_VALUE);
}
// attempt to treat the index value as a number
if (targetObject.getClass().isArray() || targetObject instanceof Collection || targetObject instanceof String) {
int idx = (Integer) state.convertValue(index, TypeDescriptor.valueOf(Integer.class));
if (targetObject.getClass().isArray()) {
this.indexedType = IndexedType.ARRAY;
return new ArrayIndexingValueRef(state.getTypeConverter(), targetObject, idx, targetDescriptor);
} else if (targetObject instanceof Collection) {
if (targetObject instanceof List) {
this.indexedType = IndexedType.LIST;
}
return new CollectionIndexingValueRef((Collection<?>) targetObject, idx, targetDescriptor, state.getTypeConverter(), state.getConfiguration().isAutoGrowCollections(), state.getConfiguration().getMaximumAutoGrowSize());
} else {
this.indexedType = IndexedType.STRING;
return new StringIndexingLValue((String) targetObject, idx, targetDescriptor);
}
}
// TODO could call the conversion service to convert the value to a String
if (String.class == indexValue.getTypeDescriptor().getType()) {
this.indexedType = IndexedType.OBJECT;
return new PropertyIndexingValueRef(targetObject, (String) indexValue.getValue(), state.getEvaluationContext(), targetDescriptor);
}
throw new SpelEvaluationException(getStartPosition(), SpelMessage.INDEXING_NOT_SUPPORTED_FOR_TYPE, targetDescriptor.toString());
}
use of org.springframework.core.convert.TypeDescriptor 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());
}
}
use of org.springframework.core.convert.TypeDescriptor in project spring-framework by spring-projects.
the class MethodReference method getValueInternal.
@Override
public TypedValue getValueInternal(ExpressionState state) throws EvaluationException {
EvaluationContext evaluationContext = state.getEvaluationContext();
Object value = state.getActiveContextObject().getValue();
TypeDescriptor targetType = state.getActiveContextObject().getTypeDescriptor();
Object[] arguments = getArguments(state);
TypedValue result = getValueInternal(evaluationContext, value, targetType, arguments);
updateExitTypeDescriptor();
return result;
}
use of org.springframework.core.convert.TypeDescriptor in project spring-framework by spring-projects.
the class ConstructorReference method populateReferenceTypeArray.
private void populateReferenceTypeArray(ExpressionState state, Object newArray, TypeConverter typeConverter, InlineList initializer, Class<?> componentType) {
TypeDescriptor toTypeDescriptor = TypeDescriptor.valueOf(componentType);
Object[] newObjectArray = (Object[]) newArray;
for (int i = 0; i < newObjectArray.length; i++) {
SpelNode elementNode = initializer.getChild(i);
Object arrayEntry = elementNode.getValue(state);
newObjectArray[i] = typeConverter.convertValue(arrayEntry, TypeDescriptor.forObject(arrayEntry), toTypeDescriptor);
}
}
use of org.springframework.core.convert.TypeDescriptor in project spring-framework by spring-projects.
the class FormatHelper method formatMethodForMessage.
/**
* Produce a readable representation for a given method name with specified arguments.
* @param name the name of the method
* @param argumentTypes the types of the arguments to the method
* @return a nicely formatted representation, e.g. {@code foo(String,int)}
*/
public static String formatMethodForMessage(String name, List<TypeDescriptor> argumentTypes) {
StringBuilder sb = new StringBuilder(name);
sb.append("(");
for (int i = 0; i < argumentTypes.size(); i++) {
if (i > 0) {
sb.append(",");
}
TypeDescriptor typeDescriptor = argumentTypes.get(i);
if (typeDescriptor != null) {
sb.append(formatClassNameForMessage(typeDescriptor.getType()));
} else {
sb.append(formatClassNameForMessage(null));
}
}
sb.append(")");
return sb.toString();
}
Aggregations