use of org.thymeleaf.expression.IExpressionObjects in project thymeleaf by thymeleaf.
the class OGNLVariableExpressionEvaluator method evaluate.
private static Object evaluate(final IExpressionContext context, final IStandardVariableExpression expression, final StandardExpressionExecutionContext expContext, final boolean applyOGNLShortcuts) {
try {
if (logger.isTraceEnabled()) {
logger.trace("[THYMELEAF][{}] OGNL expression: evaluating expression \"{}\" on target", TemplateEngine.threadIndex(), expression.getExpression());
}
final IEngineConfiguration configuration = context.getConfiguration();
final String exp = expression.getExpression();
final boolean useSelectionAsRoot = expression.getUseSelectionAsRoot();
if (exp == null) {
throw new TemplateProcessingException("Expression content is null, which is not allowed");
}
final ComputedOGNLExpression parsedExpression = obtainComputedOGNLExpression(configuration, expression, exp, applyOGNLShortcuts);
final Map<String, Object> contextVariablesMap;
if (parsedExpression.mightNeedExpressionObjects) {
// The IExpressionObjects implementation returned by processing contexts that include the Standard
// Dialects will be lazy in the creation of expression objects (i.e. they won't be created until really
// needed). And in order for this behaviour to be accepted by OGNL, we will be wrapping this object
// inside an implementation of Map<String,Object>, which will afterwards be fed to the constructor
// of an OgnlContext object.
// Note this will never happen with shortcut expressions, as the '#' character with which all
// expression object names start is not allowed by the OGNLShortcutExpression parser.
final IExpressionObjects expressionObjects = context.getExpressionObjects();
contextVariablesMap = new OGNLExpressionObjectsWrapper(expressionObjects, expContext.getRestrictVariableAccess());
// can later lookup during evaluation.
if (expContext.getRestrictVariableAccess()) {
contextVariablesMap.put(OGNLContextPropertyAccessor.RESTRICT_REQUEST_PARAMETERS, OGNLContextPropertyAccessor.RESTRICT_REQUEST_PARAMETERS);
} else {
contextVariablesMap.remove(OGNLContextPropertyAccessor.RESTRICT_REQUEST_PARAMETERS);
}
} else {
if (expContext.getRestrictVariableAccess()) {
contextVariablesMap = CONTEXT_VARIABLES_MAP_NOEXPOBJECTS_RESTRICTIONS;
} else {
contextVariablesMap = Collections.EMPTY_MAP;
}
}
// The root object on which we will evaluate expressions will depend on whether a selection target is
// active or not...
final ITemplateContext templateContext = (context instanceof ITemplateContext ? (ITemplateContext) context : null);
final Object evaluationRoot = (useSelectionAsRoot && templateContext != null && templateContext.hasSelectionTarget() ? templateContext.getSelectionTarget() : templateContext);
// Execute the expression!
final Object result;
try {
result = executeExpression(configuration, parsedExpression.expression, contextVariablesMap, evaluationRoot);
} catch (final OGNLShortcutExpression.OGNLShortcutExpressionNotApplicableException notApplicable) {
// We tried to apply shortcuts, but it is not possible for this expression even if it parsed OK,
// so we need to empty the cache and try again disabling shortcuts. Once processed for the first time,
// an OGNL (non-shortcut) parsed expression will already be cached and this exception will not be
// thrown again
invalidateComputedOGNLExpression(configuration, expression, exp);
return evaluate(context, expression, expContext, false);
}
if (!expContext.getPerformTypeConversion()) {
return result;
}
final IStandardConversionService conversionService = StandardExpressions.getConversionService(configuration);
return conversionService.convert(context, result, String.class);
} catch (final Exception e) {
throw new TemplateProcessingException("Exception evaluating OGNL expression: \"" + expression.getExpression() + "\"", e);
}
}
Aggregations