Search in sources :

Example 6 with TemplateModel

use of org.thymeleaf.engine.TemplateModel in project thymeleaf by thymeleaf.

the class StandardUtextTagProcessor method doProcess.

@Override
protected void doProcess(final ITemplateContext context, final IProcessableElementTag tag, final AttributeName attributeName, final String attributeValue, final IElementTagStructureHandler structureHandler) {
    final IEngineConfiguration configuration = context.getConfiguration();
    final IStandardExpressionParser expressionParser = StandardExpressions.getExpressionParser(configuration);
    final IStandardExpression expression = expressionParser.parseExpression(context, attributeValue);
    final Object expressionResult;
    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 {
        expressionResult = expression.execute(context, StandardExpressionExecutionContext.RESTRICTED);
    }
    // If result is no-op, there's nothing to execute
    if (expressionResult == NoOpToken.VALUE) {
        return;
    }
    /*
         * First of all we should check whether the expression result is a Fragment so that, in such case, we can
         * avoid creating a String in memory for it and just append its model.
         */
    if (expressionResult != null && expressionResult instanceof Fragment) {
        if (expressionResult == Fragment.EMPTY_FRAGMENT) {
            structureHandler.removeBody();
            return;
        }
        structureHandler.setBody(((Fragment) expressionResult).getTemplateModel(), false);
        return;
    }
    final String unescapedTextStr = (expressionResult == null ? "" : expressionResult.toString());
    /*
         * We will check if there are configured post processors or not. The reason we do this is because output
         * inserted as a result of a th:utext attribute, even if it might be markup, will never be considered as
         * 'processable', i.e. no other processors/inliner will ever be able to act on it. The main reason for this
         * is to protect against code injection.
         *
         * So the only other agents that would be able to modify these th:utext results are POST-PROCESSORS. And
         * they will indeed need markup to have been parsed in order to separate text from structures, so that's why
         * we check if there actually are any post-processors and, if not (most common case), simply output the
         * expression result as if it were a mere (unescaped) text node.
         */
    final Set<IPostProcessor> postProcessors = configuration.getPostProcessors(getTemplateMode());
    if (postProcessors.isEmpty()) {
        structureHandler.setBody(unescapedTextStr, false);
        return;
    }
    /*
         * We have post-processors, so from here one we will have to decide whether we need to parse the unescaped
         * text or not...
         */
    if (!mightContainStructures(unescapedTextStr)) {
        // If this text contains no markup structures, there would be no need to parse it or treat it as markup!
        structureHandler.setBody(unescapedTextStr, false);
        return;
    }
    /*
         * We have post-processors AND this text might contain structures, so there is no alternative but parsing
         */
    final TemplateModel parsedFragment = configuration.getTemplateManager().parseString(context.getTemplateData(), unescapedTextStr, // we won't apply offset here because the inserted text does not really come from the template itself
    0, // we won't apply offset here because the inserted text does not really come from the template itself
    0, // No template mode forcing required
    null, // useCache == false because we could potentially pollute the cache with too many entries (th:utext is too variable!)
    false);
    // Setting 'processable' to false avoiding text inliners processing already generated text,
    // which in turn avoids code injection.
    structureHandler.setBody(parsedFragment, false);
}
Also used : IStandardExpression(org.thymeleaf.standard.expression.IStandardExpression) FragmentExpression(org.thymeleaf.standard.expression.FragmentExpression) IEngineConfiguration(org.thymeleaf.IEngineConfiguration) IPostProcessor(org.thymeleaf.postprocessor.IPostProcessor) IStandardExpressionParser(org.thymeleaf.standard.expression.IStandardExpressionParser) TemplateModel(org.thymeleaf.engine.TemplateModel) Fragment(org.thymeleaf.standard.expression.Fragment)

Example 7 with TemplateModel

use of org.thymeleaf.engine.TemplateModel in project thymeleaf by thymeleaf.

the class StandardConditionalCommentProcessor method doProcess.

@Override
protected void doProcess(final ITemplateContext context, final IComment comment, final ICommentStructureHandler structureHandler) {
    final StandardConditionalCommentUtils.ConditionalCommentParsingResult parsingResult = StandardConditionalCommentUtils.parseConditionalComment(comment);
    if (parsingResult == null) {
        // This is NOT a Conditional Comment. Just return
        return;
    }
    final String commentStr = comment.getComment();
    /*
         * Next, we need to get the content of the Conditional Comment and process it as a piece of markup. In fact,
         * we must process it as a template itself (a template fragment) so that all thymeleaf attributes and
         * structures inside this content execute correctly, including references to context variables.
         */
    final TemplateManager templateManager = context.getConfiguration().getTemplateManager();
    final String parsableContent = commentStr.substring(parsingResult.getContentOffset(), parsingResult.getContentOffset() + parsingResult.getContentLen());
    final TemplateModel templateModel = templateManager.parseString(context.getTemplateData(), parsableContent, comment.getLine(), comment.getCol(), // No need to force template mode
    null, true);
    final FastStringWriter writer = new FastStringWriter(200);
    /*
         * Rebuild the conditional comment start expression
         */
    writer.write("[");
    writer.write(commentStr, parsingResult.getStartExpressionOffset(), parsingResult.getStartExpressionLen());
    writer.write("]>");
    /*
         * Process the parsable content
         */
    templateManager.process(templateModel, context, writer);
    /*
         * Rebuild the conditional comment end expression
         */
    writer.write("<![");
    writer.write(commentStr, parsingResult.getEndExpressionOffset(), parsingResult.getEndExpressionLen());
    writer.write("]");
    /*
         * Re-set the comment content, once processed
         */
    structureHandler.setContent(writer.toString());
}
Also used : FastStringWriter(org.thymeleaf.util.FastStringWriter) TemplateManager(org.thymeleaf.engine.TemplateManager) StandardConditionalCommentUtils(org.thymeleaf.standard.util.StandardConditionalCommentUtils) TemplateModel(org.thymeleaf.engine.TemplateModel)

Aggregations

TemplateModel (org.thymeleaf.engine.TemplateModel)7 FastStringWriter (org.thymeleaf.util.FastStringWriter)5 Writer (java.io.Writer)4 TemplateManager (org.thymeleaf.engine.TemplateManager)4 IEngineConfiguration (org.thymeleaf.IEngineConfiguration)3 TemplateInputException (org.thymeleaf.exceptions.TemplateInputException)2 Fragment (org.thymeleaf.standard.expression.Fragment)2 Map (java.util.Map)1 IEngineContext (org.thymeleaf.context.IEngineContext)1 ITemplateContext (org.thymeleaf.context.ITemplateContext)1 TemplateData (org.thymeleaf.engine.TemplateData)1 TemplateProcessingException (org.thymeleaf.exceptions.TemplateProcessingException)1 ICloseElementTag (org.thymeleaf.model.ICloseElementTag)1 IModel (org.thymeleaf.model.IModel)1 IOpenElementTag (org.thymeleaf.model.IOpenElementTag)1 IProcessableElementTag (org.thymeleaf.model.IProcessableElementTag)1 ITemplateEvent (org.thymeleaf.model.ITemplateEvent)1 IPostProcessor (org.thymeleaf.postprocessor.IPostProcessor)1 FragmentExpression (org.thymeleaf.standard.expression.FragmentExpression)1 FragmentSignature (org.thymeleaf.standard.expression.FragmentSignature)1