org.thymeleaf.engine.AbstractGatheringModelProcessable Maven / Gradle / Ivy
/*
* =============================================================================
*
* Copyright (c) 2011-2016, The THYMELEAF team (http://www.thymeleaf.org)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* =============================================================================
*/
package org.thymeleaf.engine;
import org.thymeleaf.IEngineConfiguration;
import org.thymeleaf.context.IEngineContext;
import org.thymeleaf.context.ITemplateContext;
import org.thymeleaf.engine.TemplateModelController.SkipBody;
import org.thymeleaf.exceptions.TemplateProcessingException;
import org.thymeleaf.model.ICDATASection;
import org.thymeleaf.model.ICloseElementTag;
import org.thymeleaf.model.IComment;
import org.thymeleaf.model.IDocType;
import org.thymeleaf.model.IOpenElementTag;
import org.thymeleaf.model.IProcessingInstruction;
import org.thymeleaf.model.IStandaloneElementTag;
import org.thymeleaf.model.IText;
import org.thymeleaf.model.IXMLDeclaration;
/*
*
* @author Daniel Fernandez
* @since 3.0.0
*
*/
abstract class AbstractGatheringModelProcessable implements IGatheringModelProcessable {
private final ProcessorTemplateHandler processorTemplateHandler;
private final IEngineContext context;
private final Model syntheticModel;
private final TemplateModelController modelController;
private final TemplateFlowController flowController;
private final SkipBody buildTimeSkipBody;
private final boolean buildTimeSkipCloseTag;
private final ProcessorExecutionVars processorExecutionVars;
private boolean gatheringFinished = false;
private int modelLevel;
AbstractGatheringModelProcessable(
final IEngineConfiguration configuration, final ProcessorTemplateHandler processorTemplateHandler, final IEngineContext context,
final TemplateModelController modelController, final TemplateFlowController flowController,
final SkipBody buildTimeSkipBody, final boolean buildTimeSkipCloseTag,
final ProcessorExecutionVars processorExecutionVars) {
super();
this.processorTemplateHandler = processorTemplateHandler;
this.context = context;
this.modelController = modelController;
this.flowController = flowController;
this.buildTimeSkipBody = buildTimeSkipBody;
this.buildTimeSkipCloseTag = buildTimeSkipCloseTag;
if (this.context == null) {
throw new TemplateProcessingException(
"Neither iteration nor model gathering are supported because local variable support is DISABLED. " +
"This is due to the use of an implementation of the " + ITemplateContext.class.getName() + " interface " +
"that does not provide local-variable support. In order to have local-variable support, the context " +
"implementation should also implement the " + IEngineContext.class.getName() +
" interface");
}
this.syntheticModel = new Model(configuration, context.getTemplateMode());
this.processorExecutionVars = processorExecutionVars.cloneVars();
this.gatheringFinished = false;
this.modelLevel = 0;
}
public final void resetGatheredSkipFlagsAfterNoIterations() {
if (this.buildTimeSkipBody == SkipBody.PROCESS_ONE_ELEMENT) {
this.modelController.skip(SkipBody.SKIP_ELEMENTS, this.buildTimeSkipCloseTag);
} else {
this.modelController.skip(this.buildTimeSkipBody, this.buildTimeSkipCloseTag);
}
}
public final void resetGatheredSkipFlags() {
this.modelController.skip(this.buildTimeSkipBody, this.buildTimeSkipCloseTag);
}
protected final void prepareProcessing() {
this.processorTemplateHandler.setCurrentGatheringModel(this);
resetGatheredSkipFlags();
}
protected final ProcessorTemplateHandler getProcessorTemplateHandler() {
return this.processorTemplateHandler;
}
protected final TemplateFlowController getFlowController() {
return this.flowController;
}
public final boolean isGatheringFinished() {
return this.gatheringFinished;
}
protected final IEngineContext getContext() {
return this.context;
}
public ProcessorExecutionVars initializeProcessorExecutionVars() {
// This was cloned during construction
return this.processorExecutionVars;
}
public final Model getInnerModel() {
return this.syntheticModel;
}
public final void gatherText(final IText text) {
if (this.gatheringFinished) {
throw new TemplateProcessingException("Gathering is finished already! We cannot gather more events");
}
this.syntheticModel.add(text);
}
public final void gatherComment(final IComment comment) {
if (this.gatheringFinished) {
throw new TemplateProcessingException("Gathering is finished already! We cannot gather more events");
}
this.syntheticModel.add(comment);
}
public final void gatherCDATASection(final ICDATASection cdataSection) {
if (this.gatheringFinished) {
throw new TemplateProcessingException("Gathering is finished already! We cannot gather more events");
}
this.syntheticModel.add(cdataSection);
}
public final void gatherStandaloneElement(final IStandaloneElementTag standaloneElementTag) {
if (this.gatheringFinished) {
throw new TemplateProcessingException("Gathering is finished already! We cannot gather more events");
}
this.syntheticModel.add(standaloneElementTag);
if (this.modelLevel == 0) {
this.gatheringFinished = true;
}
}
public final void gatherOpenElement(final IOpenElementTag openElementTag) {
if (this.gatheringFinished) {
throw new TemplateProcessingException("Gathering is finished already! We cannot gather more events");
}
this.syntheticModel.add(openElementTag);
this.modelLevel++;
}
public final void gatherCloseElement(final ICloseElementTag closeElementTag) {
if (closeElementTag.isUnmatched()) {
gatherUnmatchedCloseElement(closeElementTag);
return;
}
if (this.gatheringFinished) {
throw new TemplateProcessingException("Gathering is finished already! We cannot gather more events");
}
this.modelLevel--;
this.syntheticModel.add(closeElementTag);
if (this.modelLevel == 0) {
// OK, we are finished gathering, this close tag ends the process
this.gatheringFinished = true;
}
}
public final void gatherUnmatchedCloseElement(final ICloseElementTag closeElementTag) {
if (this.gatheringFinished) {
throw new TemplateProcessingException("Gathering is finished already! We cannot gather more events");
}
this.syntheticModel.add(closeElementTag);
}
public final void gatherDocType(final IDocType docType) {
if (this.gatheringFinished) {
throw new TemplateProcessingException("Gathering is finished already! We cannot gather more events");
}
this.syntheticModel.add(docType);
}
public final void gatherXMLDeclaration(final IXMLDeclaration xmlDeclaration) {
if (this.gatheringFinished) {
throw new TemplateProcessingException("Gathering is finished already! We cannot gather more events");
}
this.syntheticModel.add(xmlDeclaration);
}
public final void gatherProcessingInstruction(final IProcessingInstruction processingInstruction) {
if (this.gatheringFinished) {
throw new TemplateProcessingException("Gathering is finished already! We cannot gather more events");
}
this.syntheticModel.add(processingInstruction);
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy