Search in sources :

Example 1 with IOpenElementTag

use of org.thymeleaf.model.IOpenElementTag in project thymeleaf-tests by thymeleaf.

the class ModelAttributeTagProcessor method doProcess.

@Override
protected void doProcess(final ITemplateContext context, final IModel model, final AttributeName attributeName, final String attributeValue, final IElementModelStructureHandler structureHandler) {
    final IModelFactory modelFactory = context.getModelFactory();
    final IProcessableElementTag firstEvent = (IProcessableElementTag) model.get(0);
    final Map<String, String> attributes = firstEvent.getAttributeMap();
    final ITemplateEvent lastEvent = model.get(model.size() - 1);
    if (firstEvent == lastEvent) {
        final IStandaloneElementTag newFirstEvent = modelFactory.createStandaloneElementTag("ctx", attributes, AttributeValueQuotes.DOUBLE, false, false);
        model.replace(0, newFirstEvent);
    } else {
        final IOpenElementTag newFirstEvent = modelFactory.createOpenElementTag("ctx", attributes, AttributeValueQuotes.DOUBLE, false);
        final ICloseElementTag newLastEvent = modelFactory.createCloseElementTag("ctx", false, false);
        model.replace(0, newFirstEvent);
        model.replace(model.size() - 1, newLastEvent);
    }
}
Also used : ITemplateEvent(org.thymeleaf.model.ITemplateEvent) IProcessableElementTag(org.thymeleaf.model.IProcessableElementTag) IOpenElementTag(org.thymeleaf.model.IOpenElementTag) IModelFactory(org.thymeleaf.model.IModelFactory) ICloseElementTag(org.thymeleaf.model.ICloseElementTag) IStandaloneElementTag(org.thymeleaf.model.IStandaloneElementTag)

Example 2 with IOpenElementTag

use of org.thymeleaf.model.IOpenElementTag in project thymeleaf by thymeleaf.

the class OpenElementTag method asEngineOpenElementTag.

// Meant to be called only from within the engine
static OpenElementTag asEngineOpenElementTag(final IOpenElementTag openElementTag) {
    if (openElementTag instanceof OpenElementTag) {
        return (OpenElementTag) openElementTag;
    }
    final IAttribute[] originalAttributeArray = openElementTag.getAllAttributes();
    final Attributes attributes;
    if (originalAttributeArray == null || originalAttributeArray.length == 0) {
        attributes = null;
    } else {
        // We will perform a deep cloning of the attributes into objects of the Attribute class, so that
        // we make sure absolutely all Attributes in the new event are under the engine's control
        final Attribute[] newAttributeArray = new Attribute[originalAttributeArray.length];
        for (int i = 0; i < originalAttributeArray.length; i++) {
            final IAttribute originalAttribute = originalAttributeArray[i];
            newAttributeArray[i] = new Attribute(originalAttribute.getAttributeDefinition(), originalAttribute.getAttributeCompleteName(), originalAttribute.getOperator(), originalAttribute.getValue(), originalAttribute.getValueQuotes(), originalAttribute.getTemplateName(), originalAttribute.getLine(), originalAttribute.getCol());
        }
        final String[] newInnerWhiteSpaces;
        if (newAttributeArray.length == 1) {
            newInnerWhiteSpaces = Attributes.DEFAULT_WHITE_SPACE_ARRAY;
        } else {
            newInnerWhiteSpaces = new String[newAttributeArray.length];
            Arrays.fill(newInnerWhiteSpaces, Attributes.DEFAULT_WHITE_SPACE);
        }
        attributes = new Attributes(newAttributeArray, newInnerWhiteSpaces);
    }
    return new OpenElementTag(openElementTag.getTemplateMode(), openElementTag.getElementDefinition(), openElementTag.getElementCompleteName(), attributes, openElementTag.isSynthetic(), openElementTag.getTemplateName(), openElementTag.getLine(), openElementTag.getCol());
}
Also used : IAttribute(org.thymeleaf.model.IAttribute) IAttribute(org.thymeleaf.model.IAttribute) IOpenElementTag(org.thymeleaf.model.IOpenElementTag)

Example 3 with IOpenElementTag

use of org.thymeleaf.model.IOpenElementTag in project thymeleaf-tests by thymeleaf.

the class OpenElementTagTest method testXmlOpenElementAttrManagement.

@Test
public void testXmlOpenElementAttrManagement() {
    IOpenElementTag tag;
    tag = computeXmlTag("<input></input>");
    Assert.assertEquals("<input>", tag.toString());
    tag = computeXmlTag("<input type=\"text\"></input>");
    Assert.assertEquals("<input type=\"text\">", tag.toString());
    tag = computeXmlTag("<input type=\"text\"   value='hello!!!'></input>");
    Assert.assertEquals("<input type=\"text\"   value='hello!!!'>", tag.toString());
    tag.getAttributes().removeAttribute("type");
    Assert.assertEquals("<input value='hello!!!'>", tag.toString());
    tag.getAttributes().removeAttribute("value");
    Assert.assertEquals("<input>", tag.toString());
    tag = computeXmlTag("<input type=\"text\"   value='hello!!!'    ></input>");
    Assert.assertEquals("<input type=\"text\"   value='hello!!!'    >", tag.toString());
    tag.getAttributes().removeAttribute(null, "type");
    Assert.assertEquals("<input value='hello!!!'    >", tag.toString());
    tag.getAttributes().removeAttribute(null, "value");
    Assert.assertEquals("<input    >", tag.toString());
    tag = computeXmlTag("<input th:type=\"text\"   th:value='hello!!!'    ></input>");
    Assert.assertEquals("<input th:type=\"text\"   th:value='hello!!!'    >", tag.toString());
    tag.getAttributes().removeAttribute("th", "type");
    Assert.assertEquals("<input th:value='hello!!!'    >", tag.toString());
    tag.getAttributes().removeAttribute("th", "value");
    Assert.assertEquals("<input    >", tag.toString());
    tag = computeXmlTag("<input type=\"text\"   value='hello!!!'    ba='' ></input>");
    Assert.assertEquals("<input type=\"text\"   value='hello!!!'    ba='' >", tag.toString());
    tag.getAttributes().setAttribute("value", "bye! :(");
    Assert.assertEquals("<input type=\"text\"   value='bye! :('    ba='' >", tag.toString());
    tag.getAttributes().setAttribute("type", "one");
    Assert.assertEquals("<input type=\"one\"   value='bye! :('    ba='' >", tag.toString());
    tag.getAttributes().setAttribute("ba", "two");
    Assert.assertEquals("<input type=\"one\"   value='bye! :('    ba='two' >", tag.toString());
    tag.getAttributes().setAttribute("ba", "three", ElementAttributes.ValueQuotes.SINGLE);
    Assert.assertEquals("<input type=\"one\"   value='bye! :('    ba='three' >", tag.toString());
    try {
        tag.getAttributes().setAttribute("ba", "four", ElementAttributes.ValueQuotes.NONE);
        Assert.assertTrue(false);
    } catch (final IllegalArgumentException e) {
        Assert.assertTrue(true);
    }
    try {
        tag.getAttributes().setAttribute("ba", null, ElementAttributes.ValueQuotes.NONE);
        Assert.assertTrue(false);
    } catch (final IllegalArgumentException e) {
        Assert.assertTrue(true);
    }
    try {
        tag.getAttributes().setAttribute("ba", null);
        Assert.assertTrue(false);
    } catch (final IllegalArgumentException e) {
        Assert.assertTrue(true);
    }
    tag.getAttributes().setAttribute("ba", "five");
    Assert.assertEquals("<input type=\"one\"   value='bye! :('    ba='five' >", tag.toString());
    tag.getAttributes().setAttribute("ba", "six");
    Assert.assertEquals("<input type=\"one\"   value='bye! :('    ba='six' >", tag.toString());
    tag = computeXmlTag("<div type=\"text\"   value='hello!!!'    ba='twenty' ><p id='one'></p></div>");
    Assert.assertEquals("<p id='one'>", tag.toString());
}
Also used : IOpenElementTag(org.thymeleaf.model.IOpenElementTag) Test(org.junit.Test)

Example 4 with IOpenElementTag

use of org.thymeleaf.model.IOpenElementTag in project thymeleaf-tests by thymeleaf.

the class OpenElementTagTest method testHtmlOpenElementAttrManagement.

@Test
public void testHtmlOpenElementAttrManagement() {
    IOpenElementTag tag;
    tag = computeHtmlTag("<div>");
    Assert.assertEquals("<div>", tag.toString());
    tag = computeHtmlTag("<div type=\"text\">");
    Assert.assertEquals("<div type=\"text\">", tag.toString());
    tag = computeHtmlTag("<div type=\"text\"   value='hello!!!'>");
    Assert.assertEquals("<div type=\"text\"   value='hello!!!'>", tag.toString());
    tag.getAttributes().removeAttribute("type");
    Assert.assertEquals("<div value='hello!!!'>", tag.toString());
    tag.getAttributes().removeAttribute("value");
    Assert.assertEquals("<div>", tag.toString());
    tag = computeHtmlTag("<div type=\"text\"   value='hello!!!'    >");
    Assert.assertEquals("<div type=\"text\"   value='hello!!!'    >", tag.toString());
    tag.getAttributes().removeAttribute(null, "type");
    Assert.assertEquals("<div value='hello!!!'    >", tag.toString());
    tag.getAttributes().removeAttribute(null, "value");
    Assert.assertEquals("<div    >", tag.toString());
    tag = computeHtmlTag("<div type=\"text\"   value='hello!!!'    ba >");
    Assert.assertEquals("<div type=\"text\"   value='hello!!!'    ba >", tag.toString());
    tag.getAttributes().setAttribute("value", "bye! :(");
    Assert.assertEquals("<div type=\"text\"   value='bye! :('    ba >", tag.toString());
    tag.getAttributes().setAttribute("type", "one");
    Assert.assertEquals("<div type=\"one\"   value='bye! :('    ba >", tag.toString());
    tag.getAttributes().setAttribute("ba", "two");
    Assert.assertEquals("<div type=\"one\"   value='bye! :('    ba=\"two\" >", tag.toString());
    tag.getAttributes().setAttribute("ba", "three", ElementAttributes.ValueQuotes.SINGLE);
    Assert.assertEquals("<div type=\"one\"   value='bye! :('    ba='three' >", tag.toString());
    tag.getAttributes().setAttribute("ba", "four", ElementAttributes.ValueQuotes.NONE);
    Assert.assertEquals("<div type=\"one\"   value='bye! :('    ba=four >", tag.toString());
    tag.getAttributes().setAttribute("ba", "five");
    Assert.assertEquals("<div type=\"one\"   value='bye! :('    ba=five >", tag.toString());
    tag.getAttributes().setAttribute("ba", null);
    Assert.assertEquals("<div type=\"one\"   value='bye! :('    ba >", tag.toString());
    tag.getAttributes().setAttribute("ba", "six");
    Assert.assertEquals("<div type=\"one\"   value='bye! :('    ba=six >", tag.toString());
    tag = computeHtmlTag("<div type=\"text\"   value='hello!!!'    ba=twenty >");
    tag.getAttributes().setAttribute("ba", "thirty");
    Assert.assertEquals("<div type=\"text\"   value='hello!!!'    ba=thirty >", tag.toString());
    tag = computeHtmlTag("<div type=\"text\"   value='hello!!!'    ba=twenty ><p id='one'>");
    Assert.assertEquals("<p id='one'>", tag.toString());
}
Also used : IOpenElementTag(org.thymeleaf.model.IOpenElementTag) Test(org.junit.Test)

Example 5 with IOpenElementTag

use of org.thymeleaf.model.IOpenElementTag in project thymeleaf by thymeleaf.

the class ProcessorTemplateHandler method handleOpenElement.

@Override
public void handleOpenElement(final IOpenElementTag iopenElementTag) {
    /*
         * If processing is stopped, we should queue this for later handling
         * In theory, given the origin of events (parser or cache) should get stopped immediately, this should
         * only happen if a pre-processor is producing additional events.
         */
    if (this.throttleEngine && this.flowController.stopProcessing) {
        queueEvent(iopenElementTag);
        return;
    }
    /*
         * CHECK WHETHER WE ARE GATHERING AN ELEMENT's MODEL
         */
    if (!this.modelController.shouldProcessOpenElement(iopenElementTag)) {
        return;
    }
    /*
         * CAST TO ENGINE-SPECIFIC IMPLEMENTATION, which will ease the handling of the structure during processing
         */
    OpenElementTag openElementTag = OpenElementTag.asEngineOpenElementTag(iopenElementTag);
    /*
         * OBTAIN THE CURRENT SYNTHETIC MODEL (if any). This is needed in case this event was previously being handled,
         * then a gathering process started (as a consequence of the execution of one of its processors), and then
         * once the model was gathered the process started again by handling the first event, which was the one
         * suspended. By obtaining the current gathering model here we can reinitialize all the handling variables and
         * flags to their original state before being suspended.
         */
    final IGatheringModelProcessable currentGatheringModel = obtainCurrentGatheringModel();
    /*
         * If we are resuming an execution after suspending it, we want to retire the register of the element tag
         * that was added by the controller. The reason we want this is that the current tag was already registered
         * by the controller when the execution was suspended, and we don't want it duplicated (nor altered).
         */
    if (currentGatheringModel != null && this.engineContext != null) {
        this.engineContext.setElementTag(null);
    }
    /*
         * FAIL FAST in case this tag has no associated processors and we have no reason to pay attention to it
         * anyway (because of having been suspended).
         */
    if (currentGatheringModel == null && !openElementTag.hasAssociatedProcessors()) {
        this.next.handleOpenElement(openElementTag);
        return;
    }
    /*
         * DECLARE THE STATE VARS NEEDED FOR PROCESSOR EXECUTION. If we are executing the first event of a gathered
         * model, we will just re-initialize to the original variables, the ones we had before suspending.
         */
    final ProcessorExecutionVars vars = (currentGatheringModel == null ? new ProcessorExecutionVars() : currentGatheringModel.initializeProcessorExecutionVars());
    /*
         * GET THE STRUCTURE HANDLERS INTO LOCAL VARS
         */
    final ElementTagStructureHandler tagStructureHandler = this.elementTagStructureHandler;
    final ElementModelStructureHandler modelStructureHandler = this.elementModelStructureHandler;
    /*
         * EXECUTE PROCESSORS
         */
    IElementProcessor processor;
    while (!vars.discardEvent && (processor = vars.processorIterator.next(openElementTag)) != null) {
        tagStructureHandler.reset();
        modelStructureHandler.reset();
        if (processor instanceof IElementTagProcessor) {
            final IElementTagProcessor elementProcessor = ((IElementTagProcessor) processor);
            elementProcessor.process(this.context, openElementTag, tagStructureHandler);
            // Apply any context modifications made by the processor (local vars, inlining, etc.)
            tagStructureHandler.applyContextModifications(this.engineContext);
            // Apply any modifications to the tag itself: new/removed/replace attributes, etc. Note this
            // creates a new tag object because tag objects are immutable.
            openElementTag = tagStructureHandler.applyAttributes(this.attributeDefinitions, openElementTag);
            if (tagStructureHandler.iterateElement) {
                // Initialize the gathering model
                this.modelController.startGatheringIteratedModel(openElementTag, vars, tagStructureHandler.iterVariableName, tagStructureHandler.iterStatusVariableName, tagStructureHandler.iteratedObject);
                // Nothing else to be done by this handler... let's just queue the rest of the events to be iterated
                return;
            } else if (tagStructureHandler.setBodyText) {
                // Reset model, we need it clean
                vars.modelAfter = resetModel(vars.modelAfter, true);
                // If processable, events will be executed by the ProcessorTemplateHandler. If not, by this.next
                vars.modelAfterProcessable = tagStructureHandler.setBodyTextProcessable;
                // Add the new Text to the queue
                vars.modelAfter.add(new Text(tagStructureHandler.setBodyTextValue));
                // All the body of the original open tag should be skipped (has just been replaced)
                vars.skipBody = SkipBody.SKIP_ALL;
            } else if (tagStructureHandler.setBodyModel) {
                // Reset model, we need it clean
                vars.modelAfter = resetModel(vars.modelAfter, true);
                // If processable, events will be executed by the ProcessorTemplateHandler. If not, by this.next
                vars.modelAfterProcessable = tagStructureHandler.setBodyModelProcessable;
                // Add the new body model to the queue
                vars.modelAfter.addModel(tagStructureHandler.setBodyModelValue);
                // All the body of the original open tag should be skipped (has just been replaced)
                vars.skipBody = SkipBody.SKIP_ALL;
            } else if (tagStructureHandler.insertBeforeModel) {
                // Reset BEFORE model, we need it clean
                vars.modelBefore = resetModel(vars.modelBefore, true);
                // Add model to be passed to this.next BEFORE delegating the event. Note this cannot be processable.
                vars.modelBefore.addModel(tagStructureHandler.insertBeforeModelValue);
            } else if (tagStructureHandler.insertImmediatelyAfterModel) {
                // will not be resetting it because we will be inserting our model at the very beginning of it.
                if (vars.modelAfter == null) {
                    vars.modelAfter = resetModel(vars.modelAfter, true);
                }
                // If processable, events will be executed by the ProcessorTemplateHandler. If not, by this.next
                vars.modelAfterProcessable = tagStructureHandler.insertImmediatelyAfterModelProcessable;
                // Insert the new model
                vars.modelAfter.insertModel(0, tagStructureHandler.insertImmediatelyAfterModelValue);
            // No intervention on the body flags - we will not be removing the body, just inserting before it
            } else if (tagStructureHandler.replaceWithText) {
                // Reset model, we need it clean
                vars.modelAfter = resetModel(vars.modelAfter, true);
                // If processable, events will be executed by the ProcessorTemplateHandler. If not, by this.next
                vars.modelAfterProcessable = tagStructureHandler.replaceWithTextProcessable;
                // Create the new replacement Text event and add it to the model
                vars.modelAfter.add(new Text(tagStructureHandler.replaceWithTextValue));
                // This tag, its body and its corresponding close tag have to be replaced.
                vars.discardEvent = true;
                vars.skipBody = SkipBody.SKIP_ALL;
                vars.skipCloseTag = true;
            } else if (tagStructureHandler.replaceWithModel) {
                // Reset model, we need it clean
                vars.modelAfter = resetModel(vars.modelAfter, true);
                // If processable, events will be executed by the ProcessorTemplateHandler. If not, by this.next
                vars.modelAfterProcessable = tagStructureHandler.replaceWithModelProcessable;
                // Add the new replacement model
                vars.modelAfter.addModel(tagStructureHandler.replaceWithModelValue);
                // This tag, its body and its corresponding close tag have to be replaced.
                vars.discardEvent = true;
                vars.skipBody = SkipBody.SKIP_ALL;
                vars.skipCloseTag = true;
            } else if (tagStructureHandler.removeElement) {
                // Reset model, but only if it already exists
                vars.modelAfter = resetModel(vars.modelAfter, false);
                // We are removing the element (complete with body + close tag). No further processing will be allowed
                vars.discardEvent = true;
                vars.skipBody = SkipBody.SKIP_ALL;
                vars.skipCloseTag = true;
            } else if (tagStructureHandler.removeTags) {
                // No modifications to the queue - it's just the tag that will be removed, not its possible body
                vars.discardEvent = true;
                vars.skipCloseTag = true;
            } else if (tagStructureHandler.removeBody) {
                // Reset model, but only if it already exists
                vars.modelAfter = resetModel(vars.modelAfter, false);
                // We will be only removing the body contents, not the tag itself
                vars.skipBody = SkipBody.SKIP_ALL;
            } else if (tagStructureHandler.removeAllButFirstChild) {
                // Reset model, but only if it already exists
                vars.modelAfter = resetModel(vars.modelAfter, false);
                // This special SkipBody value will allow the first child element (open-body-close or standalone)
                // to be processed, but only that. Once it has been processed, the eventModelController will change
                // this value to SkipBody.SKIP_ELEMENTS.
                // 
                // Note that all non-element child events before and after the first element child event will be
                // processed normally.
                vars.skipBody = SkipBody.PROCESS_ONE_ELEMENT;
            }
        } else if (processor instanceof IElementModelProcessor) {
            if (!vars.processorIterator.lastWasRepeated()) {
                if ((vars.modelBefore != null && vars.modelBefore.size() > 0) || (vars.modelAfter != null && vars.modelAfter.size() > 0)) {
                    throw new TemplateProcessingException("Cannot execute model processor " + processor.getClass().getName() + " as the body " + "of the target element has already been modified by a previously executed processor " + "on the same tag. Model processors cannot execute on already-modified bodies as these " + "might contain unprocessable events (e.g. as a result of a 'th:text' or similar)", openElementTag.getTemplateName(), openElementTag.getLine(), openElementTag.getCol());
                }
                // Set the processor to be executed again, because this time we will just set the "model gathering" mechanism
                vars.processorIterator.setLastToBeRepeated(openElementTag);
                // Initialize the gathering model. This will be concluded (and the gathering model set for
                // processing) at the corresponding close tag.
                this.modelController.startGatheringDelayedModel(openElementTag, vars);
                // Nothing else to be done by this handler... let's just queue the rest of the events in this element
                return;
            }
            /*
                 * This is not the first time we try to execute this processor, which means the model gathering
                 * process has already taken place.
                 */
            // Create the actual Model instance (a clone) that will be passed to the processor to execute on
            final Model gatheredModel = currentGatheringModel.getInnerModel();
            final Model processedModel = new Model(gatheredModel);
            // Execute the processor on the just-created Model
            ((IElementModelProcessor) processor).process(this.context, processedModel, modelStructureHandler);
            // Apply any context modifications made by the processor (local vars, inlining, etc.)
            modelStructureHandler.applyContextModifications(this.engineContext);
            // Reset the skipbody flags so that the processed model can be executed in the same conditions as the original
            currentGatheringModel.resetGatheredSkipFlags();
            /*
                 * Before making any changes and queue the new model for execution, check that it actually is
                 * a "new" model (the processor might have been no-op on the tag and changes might have been
                 * only on the local variables, for example.)
                 */
            if (!gatheredModel.sameAs(processedModel)) {
                /*
                     * Now we will do the exact equivalent to what is performed for an Element Tag processor, when this
                     * returns a result of type "replaceWithModel".
                     */
                // Reset the model
                vars.modelAfter = resetModel(vars.modelAfter, true);
                // Set the model to be executed, and set it to be processable (that is a MUST in this case)
                vars.modelAfter.addModel(processedModel);
                vars.modelAfterProcessable = true;
                // Given we are going to execute the modified model instead of the gathered one, we will set all body
                // skipping flags just as if we had just executed a "replaceWithModel" operation.
                vars.discardEvent = true;
                vars.skipBody = SkipBody.SKIP_ALL;
                vars.skipCloseTag = true;
            }
        } else {
            throw new IllegalStateException("An element has been found with an associated processor of type " + processor.getClass().getName() + " which is neither a Tag Element Processor nor a Model Element Processor.");
        }
    }
    /*
         * QUEUE MODEL HANDLING (IF WE ARE THROTTLING)
         */
    if (this.throttleEngine && ((vars.modelAfter != null && vars.modelAfter.size() > 0) || (vars.modelBefore != null && vars.modelBefore.size() > 0))) {
        queueProcessable(new OpenElementTagModelProcessable(openElementTag, vars, this.modelController, this.flowController, this, this.next));
        return;
    }
    /*
         * PROCESS THE QUEUE BEFORE DELEGATING, if specified to do so
         */
    if (vars.modelBefore != null) {
        // This is never processable
        vars.modelBefore.process(this.next);
    }
    /*
         * PROCESS THE REST OF THE HANDLER CHAIN and INCREASE THE MODEL LEVEL RIGHT AFTERWARDS
         */
    if (!vars.discardEvent) {
        this.next.handleOpenElement(openElementTag);
    }
    /*
         * PROCESS THE QUEUE, launching all the queued events. Note executing the queue after increasing the model
         * level makes sense even if what the queue contains is a replacement for the complete element (including open
         * and close tags), because that way whatever comes in the queue will be encapsulated in a different model level
         * and its internal open/close tags should not affect the correct delimitation of this block.
         */
    if (vars.modelAfter != null) {
        vars.modelAfter.process(vars.modelAfterProcessable ? this : this.next);
    }
    /*
         * SET BODY TO BE SKIPPED, if required. Importantly, this has to be done AFTER executing the queue
         */
    this.modelController.skip(vars.skipBody, vars.skipCloseTag);
}
Also used : IElementTagProcessor(org.thymeleaf.processor.element.IElementTagProcessor) IText(org.thymeleaf.model.IText) IOpenElementTag(org.thymeleaf.model.IOpenElementTag) IElementProcessor(org.thymeleaf.processor.element.IElementProcessor) IElementModelProcessor(org.thymeleaf.processor.element.IElementModelProcessor) TemplateProcessingException(org.thymeleaf.exceptions.TemplateProcessingException)

Aggregations

IOpenElementTag (org.thymeleaf.model.IOpenElementTag)6 Test (org.junit.Test)2 TemplateProcessingException (org.thymeleaf.exceptions.TemplateProcessingException)2 ICloseElementTag (org.thymeleaf.model.ICloseElementTag)2 IProcessableElementTag (org.thymeleaf.model.IProcessableElementTag)2 ITemplateEvent (org.thymeleaf.model.ITemplateEvent)2 Writer (java.io.Writer)1 Map (java.util.Map)1 IEngineConfiguration (org.thymeleaf.IEngineConfiguration)1 IEngineContext (org.thymeleaf.context.IEngineContext)1 ITemplateContext (org.thymeleaf.context.ITemplateContext)1 TemplateData (org.thymeleaf.engine.TemplateData)1 TemplateModel (org.thymeleaf.engine.TemplateModel)1 TemplateInputException (org.thymeleaf.exceptions.TemplateInputException)1 IAttribute (org.thymeleaf.model.IAttribute)1 IModel (org.thymeleaf.model.IModel)1 IModelFactory (org.thymeleaf.model.IModelFactory)1 IStandaloneElementTag (org.thymeleaf.model.IStandaloneElementTag)1 IText (org.thymeleaf.model.IText)1 IElementModelProcessor (org.thymeleaf.processor.element.IElementModelProcessor)1