All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.thymeleaf.engine.TemplateModel Maven / Gradle / Ivy

Go to download

Modern server-side Java template engine for both web and standalone environments

There is a newer version: 3.1.3.RELEASE
Show newest version
/*
 * =============================================================================
 * 
 *   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 java.io.IOException;
import java.io.Writer;

import org.thymeleaf.IEngineConfiguration;
import org.thymeleaf.exceptions.TemplateProcessingException;
import org.thymeleaf.model.IModel;
import org.thymeleaf.model.IModelVisitor;
import org.thymeleaf.model.ITemplateEvent;
import org.thymeleaf.templatemode.TemplateMode;
import org.thymeleaf.util.FastStringWriter;
import org.thymeleaf.util.Validate;


/**
 *
 * @author Daniel Fernández
 * @since 3.0.0
 *
 */
public final class TemplateModel implements IModel {

    final IEngineConfiguration configuration;
    final TemplateData templateData;
    final IEngineTemplateEvent[] queue; // This is final because this IModel is IMMUTABLE


    // Package-protected constructor, because we don't want anyone creating these objects from outside the engine.
    // If a processor (be it standard or custom-made) wants to create a piece of model, that should be a Model
    // object, not this.
    TemplateModel(
            final IEngineConfiguration configuration, final TemplateData templateData,
            final IEngineTemplateEvent[] queue) {
        
        super();
        
        Validate.notNull(configuration, "Engine Configuration cannot be null");
        Validate.notNull(templateData, "Template Resolution cannot be null");
        Validate.notNull(queue, "Event queue cannot be null");
        Validate.isTrue(queue.length >= 2, "At least TemplateStart/TemplateEnd events must be added to a TemplateModel");
        Validate.isTrue(queue[0] == TemplateStart.TEMPLATE_START_INSTANCE, "First event in queue is not TemplateStart");
        Validate.isTrue(queue[queue.length - 1] == TemplateEnd.TEMPLATE_END_INSTANCE, "Last event in queue is not TemplateEnd");

        this.configuration = configuration;
        this.templateData = templateData;
        this.queue = queue;

    }


    public final TemplateData getTemplateData() {
        return this.templateData;
    }


    public final IEngineConfiguration getConfiguration() {
        return this.configuration;
    }


    public final TemplateMode getTemplateMode() {
        return this.templateData.getTemplateMode();
    }



    public final int size() {
        return this.queue.length;
    }


    public final ITemplateEvent get(final int pos) {
        return this.queue[pos];
    }


    public final void add(final ITemplateEvent event) {
        immutableModelException();
    }


    public final void insert(final int pos, final ITemplateEvent event) {
        immutableModelException();
    }


    public final void replace(final int pos, final ITemplateEvent event) {
        immutableModelException();
    }


    public final void addModel(final IModel model) {
        immutableModelException();
    }


    public final void insertModel(final int pos, final IModel model) {
        immutableModelException();
    }


    public final void remove(final int pos) {
        immutableModelException();
    }


    public final void reset() {
        immutableModelException();
    }




    void process(final ITemplateHandler handler) {
        for (int i = 0; i < this.queue.length; i++) {
            this.queue[i].beHandled(handler);
        }
    }


    int process(final ITemplateHandler handler, final int offset, final TemplateFlowController controller) {

        if (controller == null) {
            process(handler);
            return this.queue.length;
        }

        if (this.queue.length == 0 || offset >= this.queue.length) {
            return 0;
        }

        int processed = 0;

        for (int i = offset; i < this.queue.length && !controller.stopProcessing; i++) {
            this.queue[i].beHandled(handler);
            processed++;
        }

        return processed;

    }




    public final IModel cloneModel() {
        return new Model(this);
    }




    public final void write(final Writer writer) throws IOException {
        for (int i = 0; i < this.queue.length; i++) {
            this.queue[i].write(writer);
        }
    }




    public void accept(final IModelVisitor visitor) {
        for (int i = 0; i < this.queue.length; i++) {
            // We will execute the visitor on the Immutable events, that we need to create during the visit
            this.queue[i].accept(visitor);
        }
    }



    @Override
    public final String toString() {
        try {
            final Writer writer = new FastStringWriter();
            write(writer);
            return writer.toString();
        } catch (final IOException e) {
            throw new TemplateProcessingException(
                    "Error while creating String representation of model");
        }
    }




    private static void immutableModelException() {
        throw new UnsupportedOperationException(
                "Modifications are not allowed on immutable model objects. This model object is an immutable " +
                "implementation of the " + IModel.class.getName() + " interface, and no modifications are allowed in " +
                "order to keep cache consistency and improve performance. To modify model events, convert first your " +
                "immutable model object to a mutable one by means of the " + IModel.class.getName() + "#cloneModel() method");
    }


}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy