use of org.thymeleaf.standard.expression.IStandardExpression in project thymeleaf by thymeleaf.
the class AbstractStandardMultipleAttributeModifierTagProcessor method doProcess.
@Override
protected final void doProcess(final ITemplateContext context, final IProcessableElementTag tag, final AttributeName attributeName, final String attributeValue, final IElementTagStructureHandler structureHandler) {
final AssignationSequence assignations = AssignationUtils.parseAssignationSequence(context, attributeValue, false);
if (assignations == null) {
throw new TemplateProcessingException("Could not parse value as attribute assignations: \"" + attributeValue + "\"");
}
// Compute the required execution context depending on whether execution should be restricted or not
final StandardExpressionExecutionContext expCtx = (this.restrictedExpressionExecution ? StandardExpressionExecutionContext.RESTRICTED : StandardExpressionExecutionContext.NORMAL);
final List<Assignation> assignationValues = assignations.getAssignations();
final int assignationValuesLen = assignationValues.size();
for (int i = 0; i < assignationValuesLen; i++) {
final Assignation assignation = assignationValues.get(i);
final IStandardExpression leftExpr = assignation.getLeft();
final Object leftValue = leftExpr.execute(context, expCtx);
final IStandardExpression rightExpr = assignation.getRight();
final Object rightValue = rightExpr.execute(context, expCtx);
if (rightValue == NoOpToken.VALUE) {
// No changes to be done for this attribute
continue;
}
final String newAttributeName = (leftValue == null ? null : leftValue.toString());
if (StringUtils.isEmptyOrWhitespace(newAttributeName)) {
throw new TemplateProcessingException("Attribute name expression evaluated as null or empty: \"" + leftExpr + "\"");
}
if (getTemplateMode() == TemplateMode.HTML && this.modificationType == ModificationType.SUBSTITUTION && ArrayUtils.contains(StandardConditionalFixedValueTagProcessor.ATTR_NAMES, newAttributeName)) {
if (EvaluationUtils.evaluateAsBoolean(rightValue)) {
structureHandler.setAttribute(newAttributeName, newAttributeName);
} else {
structureHandler.removeAttribute(newAttributeName);
}
} else {
// Attribute is a "normal" attribute, not a fixed-value conditional one - or we are not just replacing
final String newAttributeValue = EscapedAttributeUtils.escapeAttribute(getTemplateMode(), rightValue == null ? null : rightValue.toString());
if (newAttributeValue == null || newAttributeValue.length() == 0) {
if (this.modificationType == ModificationType.SUBSTITUTION) {
// Substituting by a no-value will be equivalent to simply removing
structureHandler.removeAttribute(newAttributeName);
}
// Prepend and append simply ignored in this case
} else {
if (this.modificationType == ModificationType.SUBSTITUTION || !tag.hasAttribute(newAttributeName) || tag.getAttributeValue(newAttributeName).length() == 0) {
// Normal value replace
structureHandler.setAttribute(newAttributeName, newAttributeValue);
} else {
String currentValue = tag.getAttributeValue(newAttributeName);
if (this.modificationType == ModificationType.APPEND) {
structureHandler.setAttribute(newAttributeName, currentValue + newAttributeValue);
} else if (this.modificationType == ModificationType.APPEND_WITH_SPACE) {
structureHandler.setAttribute(newAttributeName, currentValue + ' ' + newAttributeValue);
} else if (this.modificationType == ModificationType.PREPEND) {
structureHandler.setAttribute(newAttributeName, newAttributeValue + currentValue);
} else {
// modification type is PREPEND_WITH_SPACE
structureHandler.setAttribute(newAttributeName, newAttributeValue + ' ' + currentValue);
}
}
}
}
}
}
use of org.thymeleaf.standard.expression.IStandardExpression in project thymeleaf by thymeleaf.
the class StandardCaseTagProcessor method isVisible.
@Override
protected boolean isVisible(final ITemplateContext context, final IProcessableElementTag tag, final AttributeName attributeName, final String attributeValue) {
/*
* Note the th:case processors must admit the concept of SHORTCUT inside the enclosing th:switch, which means
* that once one th:case has evaluated to true, no other th:case should be evaluated at all. It is because
* of this that this class should not extend from any other that evaluates the attributeValue before calling
* this code.
*/
final StandardSwitchTagProcessor.SwitchStructure switchStructure = (StandardSwitchTagProcessor.SwitchStructure) context.getVariable(StandardSwitchTagProcessor.SWITCH_VARIABLE_NAME);
if (switchStructure == null) {
throw new TemplateProcessingException("Cannot specify a \"" + attributeName + "\" attribute in an environment where no " + "switch operator has been defined before.");
}
if (switchStructure.isExecuted()) {
return false;
}
if (attributeValue != null && attributeValue.trim().equals(CASE_DEFAULT_ATTRIBUTE_VALUE)) {
if (this.logger.isTraceEnabled()) {
this.logger.trace("[THYMELEAF][{}][{}] Case expression \"{}\" in attribute \"{}\" has been evaluated as: \"{}\"", new Object[] { TemplateEngine.threadIndex(), LoggingUtils.loggifyTemplateName(context.getTemplateData().getTemplate()), attributeValue, attributeName, attributeValue, Boolean.TRUE });
}
switchStructure.setExecuted(true);
return true;
}
final IStandardExpressionParser expressionParser = StandardExpressions.getExpressionParser(context.getConfiguration());
final IStandardExpression caseExpression = expressionParser.parseExpression(context, attributeValue);
final EqualsExpression equalsExpression = new EqualsExpression(switchStructure.getExpression(), caseExpression);
final Object value = equalsExpression.execute(context);
final boolean visible = EvaluationUtils.evaluateAsBoolean(value);
if (this.logger.isTraceEnabled()) {
this.logger.trace("[THYMELEAF][{}][{}] Case expression \"{}\" in attribute \"{}\" has been evaluated as: \"{}\"", new Object[] { TemplateEngine.threadIndex(), LoggingUtils.loggifyTemplateName(context.getTemplateData().getTemplate()), attributeValue, attributeName, attributeValue, Boolean.valueOf(visible) });
}
if (visible) {
switchStructure.setExecuted(true);
}
return visible;
}
use of org.thymeleaf.standard.expression.IStandardExpression in project thymeleaf by thymeleaf.
the class StandardWithTagProcessor method doProcess.
@Override
protected void doProcess(final ITemplateContext context, final IProcessableElementTag tag, final AttributeName attributeName, final String attributeValue, final IElementTagStructureHandler structureHandler) {
final AssignationSequence assignations = AssignationUtils.parseAssignationSequence(context, attributeValue, false);
if (assignations == null) {
throw new TemplateProcessingException("Could not parse value as attribute assignations: \"" + attributeValue + "\"");
}
// Normally we would just allow the structure handler to be in charge of declaring the local variables
// by using structureHandler.setLocalVariable(...) but in this case we want each variable defined at an
// expression to be available for the next expressions, and that forces us to cast our ITemplateContext into
// a more specific interface --which shouldn't be used directly except in this specific, special case-- and
// put the local variables directly into it.
IEngineContext engineContext = null;
if (context instanceof IEngineContext) {
// NOTE this interface is internal and should not be used in users' code
engineContext = (IEngineContext) context;
}
final List<Assignation> assignationValues = assignations.getAssignations();
final int assignationValuesLen = assignationValues.size();
for (int i = 0; i < assignationValuesLen; i++) {
final Assignation assignation = assignationValues.get(i);
final IStandardExpression leftExpr = assignation.getLeft();
final Object leftValue = leftExpr.execute(context);
final IStandardExpression rightExpr = assignation.getRight();
final Object rightValue = rightExpr.execute(context);
final String newVariableName = (leftValue == null ? null : leftValue.toString());
if (StringUtils.isEmptyOrWhitespace(newVariableName)) {
throw new TemplateProcessingException("Variable name expression evaluated as null or empty: \"" + leftExpr + "\"");
}
if (engineContext != null) {
// The advantage of this vs. using the structure handler is that we will be able to
// use this newly created value in other expressions in the same 'th:with'
engineContext.setVariable(newVariableName, rightValue);
} else {
// The problem is, these won't be available until we execute the next processor
structureHandler.setLocalVariable(newVariableName, rightValue);
}
}
}
use of org.thymeleaf.standard.expression.IStandardExpression in project thymeleaf by thymeleaf.
the class StandardEachTagProcessor method doProcess.
@Override
protected void doProcess(final ITemplateContext context, final IProcessableElementTag tag, final AttributeName attributeName, final String attributeValue, final IElementTagStructureHandler structureHandler) {
final Each each = EachUtils.parseEach(context, attributeValue);
final IStandardExpression iterVarExpr = each.getIterVar();
final Object iterVarValue = iterVarExpr.execute(context);
final IStandardExpression statusVarExpr = each.getStatusVar();
final Object statusVarValue;
if (statusVarExpr != null) {
statusVarValue = statusVarExpr.execute(context);
} else {
// Will provoke the default behaviour: iterVarValue + 'Stat'
statusVarValue = null;
}
final IStandardExpression iterableExpr = each.getIterable();
final Object iteratedValue = iterableExpr.execute(context);
final String iterVarName = (iterVarValue == null ? null : iterVarValue.toString());
if (StringUtils.isEmptyOrWhitespace(iterVarName)) {
throw new TemplateProcessingException("Iteration variable name expression evaluated as null: \"" + iterVarExpr + "\"");
}
final String statusVarName = (statusVarValue == null ? null : statusVarValue.toString());
if (statusVarExpr != null && StringUtils.isEmptyOrWhitespace(statusVarName)) {
throw new TemplateProcessingException("Status variable name expression evaluated as null or empty: \"" + statusVarExpr + "\"");
}
structureHandler.iterateElement(iterVarName, statusVarName, iteratedValue);
}
use of org.thymeleaf.standard.expression.IStandardExpression in project sling by apache.
the class SlingIncludeAttributeTagProcessor method doProcess.
@Override
protected void doProcess(final ITemplateContext templateContext, final IProcessableElementTag processableElementTag, final AttributeName attributeName, final String attributeValue, final IElementTagStructureHandler elementTagStructureHandler) {
try {
final SlingHttpServletRequest slingHttpServletRequest = (SlingHttpServletRequest) templateContext.getVariable(SlingBindings.REQUEST);
final SlingHttpServletResponse slingHttpServletResponse = (SlingHttpServletResponse) templateContext.getVariable(SlingBindings.RESPONSE);
final IEngineConfiguration configuration = templateContext.getConfiguration();
final IStandardExpressionParser expressionParser = StandardExpressions.getExpressionParser(configuration);
final IStandardExpression expression = expressionParser.parseExpression(templateContext, attributeValue);
final Object include = expression.execute(templateContext);
String path = null;
if (include instanceof String) {
path = (String) include;
}
Resource resource = null;
if (include instanceof Resource) {
resource = (Resource) include;
}
// request dispatcher options
final RequestDispatcherOptions requestDispatcherOptions = prepareRequestDispatcherOptions(expressionParser, templateContext, processableElementTag, elementTagStructureHandler);
// dispatch
final String content = dispatch(resource, path, slingHttpServletRequest, slingHttpServletResponse, requestDispatcherOptions);
// add output
final Boolean unwrap = (Boolean) parseAttribute(expressionParser, templateContext, processableElementTag, elementTagStructureHandler, UNWRAP_ATTRIBUTE_NAME);
if (unwrap != null && unwrap) {
elementTagStructureHandler.replaceWith(content, false);
} else {
elementTagStructureHandler.setBody(content, false);
}
} catch (Exception e) {
throw new RuntimeException("unable to process include attribute", e);
}
}
Aggregations