use of org.springframework.expression.spel.SpelEvaluationException 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.expression.spel.SpelEvaluationException 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.expression.spel.SpelEvaluationException in project spring-framework by spring-projects.
the class ConstructorReference method createArray.
/**
* Create an array and return it.
* @param state the expression state within which this expression is being evaluated
* @return the new array
* @throws EvaluationException if there is a problem creating the array
*/
private TypedValue createArray(ExpressionState state) throws EvaluationException {
// First child gives us the array type which will either be a primitive or reference type
Object intendedArrayType = getChild(0).getValue(state);
if (!(intendedArrayType instanceof String)) {
throw new SpelEvaluationException(getChild(0).getStartPosition(), SpelMessage.TYPE_NAME_EXPECTED_FOR_ARRAY_CONSTRUCTION, FormatHelper.formatClassNameForMessage(intendedArrayType.getClass()));
}
String type = (String) intendedArrayType;
Class<?> componentType;
TypeCode arrayTypeCode = TypeCode.forName(type);
if (arrayTypeCode == TypeCode.OBJECT) {
componentType = state.findType(type);
} else {
componentType = arrayTypeCode.getType();
}
Object newArray;
if (!hasInitializer()) {
// Confirm all dimensions were specified (for example [3][][5] is missing the 2nd dimension)
for (SpelNodeImpl dimension : this.dimensions) {
if (dimension == null) {
throw new SpelEvaluationException(getStartPosition(), SpelMessage.MISSING_ARRAY_DIMENSION);
}
}
TypeConverter typeConverter = state.getEvaluationContext().getTypeConverter();
// Shortcut for 1 dimensional
if (this.dimensions.length == 1) {
TypedValue o = this.dimensions[0].getTypedValue(state);
int arraySize = ExpressionUtils.toInt(typeConverter, o);
newArray = Array.newInstance(componentType, arraySize);
} else {
// Multi-dimensional - hold onto your hat!
int[] dims = new int[this.dimensions.length];
for (int d = 0; d < this.dimensions.length; d++) {
TypedValue o = this.dimensions[d].getTypedValue(state);
dims[d] = ExpressionUtils.toInt(typeConverter, o);
}
newArray = Array.newInstance(componentType, dims);
}
} else {
// There is an initializer
if (this.dimensions.length > 1) {
// is not currently supported
throw new SpelEvaluationException(getStartPosition(), SpelMessage.MULTIDIM_ARRAY_INITIALIZER_NOT_SUPPORTED);
}
TypeConverter typeConverter = state.getEvaluationContext().getTypeConverter();
InlineList initializer = (InlineList) getChild(1);
// If a dimension was specified, check it matches the initializer length
if (this.dimensions[0] != null) {
TypedValue dValue = this.dimensions[0].getTypedValue(state);
int i = ExpressionUtils.toInt(typeConverter, dValue);
if (i != initializer.getChildCount()) {
throw new SpelEvaluationException(getStartPosition(), SpelMessage.INITIALIZER_LENGTH_INCORRECT);
}
}
// Build the array and populate it
int arraySize = initializer.getChildCount();
newArray = Array.newInstance(componentType, arraySize);
if (arrayTypeCode == TypeCode.OBJECT) {
populateReferenceTypeArray(state, newArray, typeConverter, initializer, componentType);
} else if (arrayTypeCode == TypeCode.INT) {
populateIntArray(state, newArray, typeConverter, initializer);
} else if (arrayTypeCode == TypeCode.BOOLEAN) {
populateBooleanArray(state, newArray, typeConverter, initializer);
} else if (arrayTypeCode == TypeCode.CHAR) {
populateCharArray(state, newArray, typeConverter, initializer);
} else if (arrayTypeCode == TypeCode.LONG) {
populateLongArray(state, newArray, typeConverter, initializer);
} else if (arrayTypeCode == TypeCode.SHORT) {
populateShortArray(state, newArray, typeConverter, initializer);
} else if (arrayTypeCode == TypeCode.DOUBLE) {
populateDoubleArray(state, newArray, typeConverter, initializer);
} else if (arrayTypeCode == TypeCode.FLOAT) {
populateFloatArray(state, newArray, typeConverter, initializer);
} else if (arrayTypeCode == TypeCode.BYTE) {
populateByteArray(state, newArray, typeConverter, initializer);
} else {
throw new IllegalStateException(arrayTypeCode.name());
}
}
return new TypedValue(newArray);
}
use of org.springframework.expression.spel.SpelEvaluationException in project spring-framework by spring-projects.
the class DefaultSubscriptionRegistry method filterSubscriptions.
private MultiValueMap<String, String> filterSubscriptions(MultiValueMap<String, String> allMatches, Message<?> message) {
if (!this.selectorHeaderInUse) {
return allMatches;
}
EvaluationContext context = null;
MultiValueMap<String, String> result = new LinkedMultiValueMap<>(allMatches.size());
for (String sessionId : allMatches.keySet()) {
for (String subId : allMatches.get(sessionId)) {
SessionSubscriptionInfo info = this.subscriptionRegistry.getSubscriptions(sessionId);
if (info == null) {
continue;
}
Subscription sub = info.getSubscription(subId);
if (sub == null) {
continue;
}
Expression expression = sub.getSelectorExpression();
if (expression == null) {
result.add(sessionId, subId);
continue;
}
if (context == null) {
context = new StandardEvaluationContext(message);
context.getPropertyAccessors().add(new SimpMessageHeaderPropertyAccessor());
}
try {
if (expression.getValue(context, boolean.class)) {
result.add(sessionId, subId);
}
} catch (SpelEvaluationException ex) {
if (logger.isDebugEnabled()) {
logger.debug("Failed to evaluate selector: " + ex.getMessage());
}
} catch (Throwable ex) {
logger.debug("Failed to evaluate selector", ex);
}
}
}
return result;
}
use of org.springframework.expression.spel.SpelEvaluationException in project uPortal by Jasig.
the class SearchPortletController method modifySearchResultLinkTitle.
/**
* Since portlets don't have access to the portlet definition to create a useful search results
* link using something like the portlet definition's title, post-process the link text and for
* those portlets whose type is present in the substitution set, replace the title with the
* portlet definition's title.
*
* @param result Search results object (may be modified)
* @param httpServletRequest HttpServletRequest
* @param portletWindowId Portlet Window ID
*/
protected void modifySearchResultLinkTitle(SearchResult result, final HttpServletRequest httpServletRequest, final IPortletWindowId portletWindowId) {
// evaluation context.
if (result.getType().size() > 0 && result.getTitle().contains("${")) {
final IPortletWindow portletWindow = this.portletWindowRegistry.getPortletWindow(httpServletRequest, portletWindowId);
final IPortletEntity portletEntity = portletWindow.getPortletEntity();
final IPortletDefinition portletDefinition = portletEntity.getPortletDefinition();
final SpELEnvironmentRoot spelEnvironment = new SpELEnvironmentRoot(portletDefinition);
try {
result.setTitle(spELService.getValue(result.getTitle(), spelEnvironment));
} catch (SpelParseException | SpelEvaluationException e) {
result.setTitle("(Invalid portlet title) - see details in log file");
logger.error("Invalid Spring EL expression {} in search result portlet title", result.getTitle(), e);
}
}
}
Aggregations