use of org.thymeleaf.exceptions.TemplateProcessingException in project thymeleaf by thymeleaf.
the class DivisionExpression method executeDivision.
static Object executeDivision(final IExpressionContext context, final DivisionExpression expression, final StandardExpressionExecutionContext expContext) {
if (logger.isTraceEnabled()) {
logger.trace("[THYMELEAF][{}] Evaluating division expression: \"{}\"", TemplateEngine.threadIndex(), expression.getStringRepresentation());
}
Object leftValue = expression.getLeft().execute(context, expContext);
Object rightValue = expression.getRight().execute(context, expContext);
if (leftValue == null) {
leftValue = "null";
}
if (rightValue == null) {
rightValue = "null";
}
final BigDecimal leftNumberValue = EvaluationUtils.evaluateAsNumber(leftValue);
final BigDecimal rightNumberValue = EvaluationUtils.evaluateAsNumber(rightValue);
if (leftNumberValue != null && rightNumberValue != null) {
try {
return leftNumberValue.divide(rightNumberValue);
} catch (final ArithmeticException ignored) {
// we just use a minimum arbitrary scale (10) and HALF_UP rounding mode
return leftNumberValue.divide(rightNumberValue, Math.max(Math.max(leftNumberValue.scale(), rightNumberValue.scale()), 10), RoundingMode.HALF_UP);
}
}
throw new TemplateProcessingException("Cannot execute division: operands are \"" + LiteralValue.unwrap(leftValue) + "\" and \"" + LiteralValue.unwrap(rightValue) + "\"");
}
use of org.thymeleaf.exceptions.TemplateProcessingException 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.exceptions.TemplateProcessingException in project thymeleaf by thymeleaf.
the class StandardExpressionParser method parseExpression.
static IStandardExpression parseExpression(final IExpressionContext context, final String input, final boolean preprocess) {
final IEngineConfiguration configuration = context.getConfiguration();
final String preprocessedInput = (preprocess ? StandardExpressionPreprocessor.preprocess(context, input) : input);
final IStandardExpression cachedExpression = ExpressionCache.getExpressionFromCache(configuration, preprocessedInput);
if (cachedExpression != null) {
return cachedExpression;
}
final Expression expression = Expression.parse(preprocessedInput.trim());
if (expression == null) {
throw new TemplateProcessingException("Could not parse as expression: \"" + input + "\"");
}
ExpressionCache.putExpressionIntoCache(configuration, preprocessedInput, expression);
return expression;
}
use of org.thymeleaf.exceptions.TemplateProcessingException in project sling by apache.
the class TemplateManager method createTemplateProcessingHandlerChain.
private static ITemplateHandler createTemplateProcessingHandlerChain(final IEngineContext context, final boolean setPreProcessors, final boolean setPostProcessors, final ITemplateHandler handler, final Writer writer) {
final IEngineConfiguration configuration = context.getConfiguration();
/*
* Declare the pair of pointers that will allow us to build the chain of template handlers
*/
ITemplateHandler firstHandler = null;
ITemplateHandler lastHandler = null;
/*
* First type of handlers to be added: pre-processors (if any)
*/
if (setPreProcessors) {
final Set<IPreProcessor> preProcessors = configuration.getPreProcessors(context.getTemplateMode());
if (preProcessors != null && preProcessors.size() > 0) {
for (final IPreProcessor preProcessor : preProcessors) {
final Class<? extends ITemplateHandler> preProcessorClass = preProcessor.getHandlerClass();
final ITemplateHandler preProcessorHandler;
try {
preProcessorHandler = preProcessorClass.newInstance();
} catch (final Exception e) {
// This should never happen - class was already checked during configuration to contain a zero-arg constructor
throw new TemplateProcessingException("An exception happened during the creation of a new instance of pre-processor " + preProcessorClass.getClass().getName(), e);
}
// Initialize the pre-processor
preProcessorHandler.setContext(context);
if (firstHandler == null) {
firstHandler = preProcessorHandler;
lastHandler = preProcessorHandler;
} else {
lastHandler.setNext(preProcessorHandler);
lastHandler = preProcessorHandler;
}
}
}
}
/*
* Initialize and add to the chain te Processor Handler itself, the central piece of the chain
*/
handler.setContext(context);
if (firstHandler == null) {
firstHandler = handler;
lastHandler = handler;
} else {
lastHandler.setNext(handler);
lastHandler = handler;
}
/*
* After the Processor Handler, we now must add the post-processors (if any)
*/
if (setPostProcessors) {
final Set<IPostProcessor> postProcessors = configuration.getPostProcessors(context.getTemplateMode());
if (postProcessors != null && postProcessors.size() > 0) {
for (final IPostProcessor postProcessor : postProcessors) {
final Class<? extends ITemplateHandler> postProcessorClass = postProcessor.getHandlerClass();
final ITemplateHandler postProcessorHandler;
try {
postProcessorHandler = postProcessorClass.newInstance();
} catch (final Exception e) {
// This should never happen - class was already checked during configuration to contain a zero-arg constructor
throw new TemplateProcessingException("An exception happened during the creation of a new instance of post-processor " + postProcessorClass.getClass().getName(), e);
}
// Initialize the pre-processor
postProcessorHandler.setContext(context);
if (firstHandler == null) {
firstHandler = postProcessorHandler;
lastHandler = postProcessorHandler;
} else {
lastHandler.setNext(postProcessorHandler);
lastHandler = postProcessorHandler;
}
}
}
}
/*
* Last step: the OUTPUT HANDLER
*/
if (writer != null) {
final OutputTemplateHandler outputHandler = new OutputTemplateHandler(writer);
outputHandler.setContext(context);
if (firstHandler == null) {
firstHandler = outputHandler;
} else {
lastHandler.setNext(outputHandler);
}
}
return firstHandler;
}
use of org.thymeleaf.exceptions.TemplateProcessingException in project thymeleaf-tests by thymeleaf.
the class AbstractSpring5ReactiveTest method testTemplateSpringView.
private static void testTemplateSpringView(final String template, final Set<String> markupSelectors, final IContext context, final String result, final boolean sse, final int responseMaxChunkSizeBytes) throws Exception {
if (context instanceof ISpringWebFluxContext) {
// we can influence when directly instantiating the ThymeleafReactiveView. So we'll just skip
return;
}
final String dataDriverVariableName = detectDataDriver(context);
final boolean isDataDriven = dataDriverVariableName != null;
final ThymeleafReactiveView thymeleafReactiveView = createThymeleafReactiveView(templateEngine, template, markupSelectors, Locale.US, responseMaxChunkSizeBytes);
final Map<String, Object> model = new HashMap<String, Object>();
for (final String variableName : context.getVariableNames()) {
model.put(variableName, context.getVariable(variableName));
}
final ServerWebExchange serverWebExchange = new TestingServerWebExchange("testing", Collections.emptyMap(), Collections.emptyMap(), Collections.emptyMap());
List<DataBuffer> resultBuffers = null;
try {
final Mono<ServerHttpResponse> responseStream = thymeleafReactiveView.render(model, (sse ? sseMediaType : htmlMediaType), serverWebExchange).then(Mono.just(serverWebExchange.getResponse()));
final ServerHttpResponse response = responseStream.block();
resultBuffers = ((TestingServerHttpResponse) response).getWrittenOutput();
} catch (final Exception e) {
throw new TemplateProcessingException("Error happened while executing reactive test for template " + template + " with markup " + "selectors " + markupSelectors + ", context with variables " + context.getVariableNames() + " and " + "response chunk size of " + responseMaxChunkSizeBytes + " bytes.", e);
}
if (responseMaxChunkSizeBytes != Integer.MAX_VALUE) {
for (final DataBuffer resultBuffer : resultBuffers) {
Assert.assertTrue("Buffer returned by stream is of size larger than " + responseMaxChunkSizeBytes, resultBuffer.readableByteCount() <= responseMaxChunkSizeBytes);
}
} else {
if (!isDataDriven) {
final int bufferCount = resultBuffers.size();
Assert.assertTrue("No limit set on buffer size, and non-data-driven: there should only be one result buffer instead of " + bufferCount, bufferCount == 1);
}
}
final String resultStr = resultBuffers.stream().map((buffer) -> ReactiveTestUtils.bufferAsString(buffer, charset)).map(// Note we NORMALIZE before joining it all
ReactiveTestUtils::normalizeResult).collect(Collectors.joining());
final String expected = ReactiveTestUtils.readExpectedNormalizedResults(result, charset);
Assert.assertEquals(expected, resultStr);
}
Aggregations