use of org.thymeleaf.standard.expression.IStandardExpression in project thymeleaf by thymeleaf.
the class EngineEventUtils method computeAttributeExpression.
/*
* The idea behind this method is to cache in the Attribute object itself the IStandardExpression object corresponding
* with the expression to be executed, so that we don't have to hit the expression cache at all
*/
public static IStandardExpression computeAttributeExpression(final ITemplateContext context, final IProcessableElementTag tag, final AttributeName attributeName, final String attributeValue) {
if (!(tag instanceof AbstractProcessableElementTag)) {
return parseAttributeExpression(context, attributeValue);
}
final AbstractProcessableElementTag processableElementTag = (AbstractProcessableElementTag) tag;
final Attribute attribute = (Attribute) processableElementTag.getAttribute(attributeName);
IStandardExpression expression = attribute.getCachedStandardExpression();
if (expression != null) {
return expression;
}
expression = parseAttributeExpression(context, attributeValue);
// If the expression has been correctly parsed AND it does not contain preprocessing marks (_), nor it is a FragmentExpression, cache it!
if (expression != null && !(expression instanceof FragmentExpression) && attributeValue.indexOf('_') < 0) {
attribute.setCachedStandardExpression(expression);
}
return expression;
}
use of org.thymeleaf.standard.expression.IStandardExpression in project thymeleaf by thymeleaf.
the class AbstractStandardAssertionTagProcessor method doProcess.
@Override
protected final void doProcess(final ITemplateContext context, final IProcessableElementTag tag, final AttributeName attributeName, final String attributeValue, final IElementTagStructureHandler structureHandler) {
if (StringUtils.isEmptyOrWhitespace(attributeValue)) {
return;
}
final ExpressionSequence expressionSequence = ExpressionSequenceUtils.parseExpressionSequence(context, attributeValue);
final List<IStandardExpression> expressions = expressionSequence.getExpressions();
for (final IStandardExpression expression : expressions) {
final Object expressionResult = expression.execute(context);
final boolean expressionBooleanResult = EvaluationUtils.evaluateAsBoolean(expressionResult);
if (!expressionBooleanResult) {
throw new TemplateAssertionException(expression.getStringRepresentation(), tag.getTemplateName(), tag.getAttribute(attributeName).getLine(), tag.getAttribute(attributeName).getCol());
}
}
}
use of org.thymeleaf.standard.expression.IStandardExpression in project thymeleaf by thymeleaf.
the class AbstractStandardExpressionAttributeTagProcessor method doProcess.
@Override
protected final void doProcess(final ITemplateContext context, final IProcessableElementTag tag, final AttributeName attributeName, final String attributeValue, final IElementTagStructureHandler structureHandler) {
final Object expressionResult;
if (attributeValue != null) {
final IStandardExpression expression = EngineEventUtils.computeAttributeExpression(context, tag, attributeName, attributeValue);
if (expression != null && expression instanceof FragmentExpression) {
// This is merely a FragmentExpression (not complex, not combined with anything), so we can apply a shortcut
// so that we don't require a "null" result for this expression if the template does not exist. That will
// save a call to resource.exists() which might be costly.
final FragmentExpression.ExecutedFragmentExpression executedFragmentExpression = FragmentExpression.createExecutedFragmentExpression(context, (FragmentExpression) expression);
expressionResult = FragmentExpression.resolveExecutedFragmentExpression(context, executedFragmentExpression, true);
} else {
/*
* Some attributes will require the execution of the expressions contained in them in RESTRICTED
* mode, so that e.g. access to request parameters is forbidden.
*/
final StandardExpressionExecutionContext expCtx = (this.restrictedExpressionExecution ? StandardExpressionExecutionContext.RESTRICTED : StandardExpressionExecutionContext.NORMAL);
expressionResult = expression.execute(context, expCtx);
}
} else {
expressionResult = null;
}
// If the result of this expression is NO-OP, there is nothing to execute
if (expressionResult == NoOpToken.VALUE) {
if (this.removeIfNoop) {
structureHandler.removeAttribute(attributeName);
}
return;
}
doProcess(context, tag, attributeName, attributeValue, expressionResult, structureHandler);
}
use of org.thymeleaf.standard.expression.IStandardExpression in project thymeleaf by thymeleaf.
the class AbstractStandardFragmentInsertionTagProcessor method computeFragment.
/*
* This can return a Fragment, NoOpToken (if nothing should be done) or null
*/
private static Object computeFragment(final ITemplateContext context, final String input) {
final IStandardExpressionParser expressionParser = StandardExpressions.getExpressionParser(context.getConfiguration());
final String trimmedInput = input.trim();
if (shouldBeWrappedAsFragmentExpression(trimmedInput)) {
// We do not know for sure that this is a complete standard expression, so we will consider it the
// content of a FragmentExpression for legacy compatibility reasons.
// We will only reach this point if the expression does not contain any Fragment Expressions expressed
// as ~{...} (excluding parameters), nor the "::" fragment selector separator.
// NOTE we are using the generic parseExpression() and not directly calling a parse method in the
// FragmentExpression class because we want to take advantage of the expression cache.
final FragmentExpression fragmentExpression = (FragmentExpression) expressionParser.parseExpression(context, "~{" + trimmedInput + "}");
final FragmentExpression.ExecutedFragmentExpression executedFragmentExpression = FragmentExpression.createExecutedFragmentExpression(context, fragmentExpression);
if (executedFragmentExpression.getFragmentSelectorExpressionResult() == null && executedFragmentExpression.getFragmentParameters() == null) {
// We might be in the scenario that what we thought was a template name in fact was instead an expression
// returning a Fragment itself, so we should simply return it
final Object templateNameExpressionResult = executedFragmentExpression.getTemplateNameExpressionResult();
if (templateNameExpressionResult != null) {
if (templateNameExpressionResult instanceof Fragment) {
return templateNameExpressionResult;
}
if (templateNameExpressionResult == NoOpToken.VALUE) {
return NoOpToken.VALUE;
}
}
}
// have to execute a (potentially costly) resource.exists() call on the resolved resource.
return FragmentExpression.resolveExecutedFragmentExpression(context, executedFragmentExpression, true);
}
// If we reached this point, we know for sure this is a complete fragment expression, so we just parse it
// as such and execute it
final IStandardExpression fragmentExpression = expressionParser.parseExpression(context, trimmedInput);
final Object fragmentExpressionResult;
if (fragmentExpression != null && fragmentExpression instanceof FragmentExpression) {
// This is not a complex expression but merely a FragmentExpression, so we can apply a shortcut
// so that we don't require a "null" result for this expression if the template does not exist. That will
// save a call to resource.exists() which might be costly.
final FragmentExpression.ExecutedFragmentExpression executedFragmentExpression = FragmentExpression.createExecutedFragmentExpression(context, (FragmentExpression) fragmentExpression);
fragmentExpressionResult = FragmentExpression.resolveExecutedFragmentExpression(context, executedFragmentExpression, true);
} else {
fragmentExpressionResult = fragmentExpression.execute(context);
}
if (fragmentExpressionResult == null || fragmentExpressionResult == NoOpToken.VALUE) {
return fragmentExpressionResult;
}
if (!(fragmentExpressionResult instanceof Fragment)) {
throw new TemplateProcessingException("Invalid fragment specification: \"" + input + "\": " + "expression does not return a Fragment object");
}
return fragmentExpressionResult;
}
use of org.thymeleaf.standard.expression.IStandardExpression in project thymeleaf by thymeleaf.
the class AbstractStandardTargetSelectionTagProcessor method doProcess.
@Override
protected final void doProcess(final ITemplateContext context, final IProcessableElementTag tag, final AttributeName attributeName, final String attributeValue, final IElementTagStructureHandler structureHandler) {
final IStandardExpressionParser expressionParser = StandardExpressions.getExpressionParser(context.getConfiguration());
final IStandardExpression expression = expressionParser.parseExpression(context, attributeValue);
validateSelectionValue(context, tag, attributeName, attributeValue, expression);
final Object newSelectionTarget = expression.execute(context);
final Map<String, Object> additionalLocalVariables = computeAdditionalLocalVariables(context, tag, attributeName, attributeValue, expression);
if (additionalLocalVariables != null && additionalLocalVariables.size() > 0) {
for (final Map.Entry<String, Object> variableEntry : additionalLocalVariables.entrySet()) {
structureHandler.setLocalVariable(variableEntry.getKey(), variableEntry.getValue());
}
}
structureHandler.setSelectionTarget(newSelectionTarget);
}
Aggregations