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

org.thymeleaf.Arguments Maven / Gradle / Ivy

/*
 * =============================================================================
 * 
 *   Copyright (c) 2011-2012, 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;

import java.util.HashMap;
import java.util.Map;

import org.thymeleaf.context.IContext;
import org.thymeleaf.context.VariablesMap;
import org.thymeleaf.dom.Document;
import org.thymeleaf.exceptions.TemplateProcessingException;
import org.thymeleaf.expression.ExpressionEvaluatorObjects;
import org.thymeleaf.templateresolver.TemplateResolution;
import org.thymeleaf.util.Validate;

/**
 * 

* Objects of this class contain all the required arguments for template * processing. *

*

* These objects are created internally by the Template Engine in order * to provide processors with all the information * they might need for performing their tasks. *

*

* Arguments include many attributes, among which some should be used internally * only, and never by developers of attribute/element processors. Public * attributes are: *

*
    *
  • The Template Engine configuration ({@link Configuration}): {@link #getConfiguration()}
  • *
  • The template name: {@link #getTemplateName()}
  • *
  • The Context ({@link IContext}): {@link #getContext()}
  • *
  • The current map of ID Counts (used for adding a unique index to repeated id attributes): {@link #getIdCounts()}
  • *
  • The Expression roots: *
      *
    • For normal (non selected) evaluation (${...} in standard dialect): {@link #getExpressionEvaluationRoot()}
    • *
    • For selected evaluation (*{...} in standard dialect): {@link #getExpressionSelectionEvaluationRoot()}
    • *
    *
  • *
  • Information about whether processing non-element nodes is allowed at a specific point of a template * execution or not (default is to process only elements).
  • *
* * @author Daniel Fernández * * @since 1.0 * */ public final class Arguments { public static final String SELECTION_TARGET_LOCAL_VARIABLE_NAME = "%%{SELECTION_TARGET}%%"; private final TemplateProcessingParameters templateProcessingParameters; private final Configuration configuration; private final Document document; private final TemplateResolution templateResolution; private final TemplateRepository templateRepository; private final IContext context; private final HashMap localVariables; private final Map idCounts; private final Object evaluationRoot; private final Object selectionEvaluationRoot; private final boolean processOnlyElementNodes; private final Map baseContextVariables; /** *

* Create a new Arguments instance. *

*

* Mainly for internal use. Should not be called directly except * when processing a template (e.g. a fragment) using the {@link TemplateEngine} * from a element/attribute processor. *

* * @param templateProcessingParameters the template processing parameters * @param templateResolution the template resolution object * @param templateRepository the template repository in use * @param templateParser the template parser * @param context the context */ Arguments( final TemplateProcessingParameters templateProcessingParameters, final TemplateResolution templateResolution, final TemplateRepository templateRepository, final Document document) { super(); Validate.notNull(templateProcessingParameters, "Template processing parameters cannot be null"); Validate.notNull(templateResolution, "Template resolution cannot be null"); Validate.notNull(templateRepository, "Template repository cannot be null"); Validate.notNull(document, "Document cannot be null"); this.templateProcessingParameters = templateProcessingParameters; this.configuration = this.templateProcessingParameters.getConfiguration(); this.templateResolution = templateResolution; this.templateRepository = templateRepository; this.document = document; this.context = this.templateProcessingParameters.getContext(); this.localVariables = null; this.idCounts = new HashMap(); this.evaluationRoot = createEvaluationRoot(); this.selectionEvaluationRoot = createSelectedEvaluationRoot(); this.processOnlyElementNodes = true; this.baseContextVariables = ExpressionEvaluatorObjects.computeEvaluationVariablesForArguments(this); } private Arguments( final TemplateProcessingParameters templateProcessingParameters, final TemplateResolution templateResolution, final TemplateRepository templateRepository, final Document document, final HashMap localVariables, final Map idCounts, final boolean processOnlyElementNodes) { super(); this.templateProcessingParameters = templateProcessingParameters; this.configuration = this.templateProcessingParameters.getConfiguration(); this.templateResolution = templateResolution; this.templateRepository = templateRepository; this.document = document; this.context = this.templateProcessingParameters.getContext(); this.localVariables = localVariables; this.idCounts = idCounts; this.evaluationRoot = createEvaluationRoot(); this.selectionEvaluationRoot = createSelectedEvaluationRoot(); this.processOnlyElementNodes = processOnlyElementNodes; this.baseContextVariables = ExpressionEvaluatorObjects.computeEvaluationVariablesForArguments(this); } private Object createEvaluationRoot() { final Map newEvaluationRoot = new VariablesMap(); newEvaluationRoot.putAll(this.context.getVariables()); if (hasLocalVariables()) { newEvaluationRoot.putAll(this.localVariables); } return newEvaluationRoot; } private Object createSelectedEvaluationRoot() { if (hasSelectionTarget()) { return getSelectionTarget(); } return this.evaluationRoot; } /** *

* Returns the Template Processing Parameters used for resolving * and parsing the template being processed. *

* * @return the template processing parameters */ public TemplateProcessingParameters getTemplateProcessingParameters() { return this.templateProcessingParameters; } /** *

* Returns the Template Engine configuration being used for * processing templates. *

* * @return the configuration */ public Configuration getConfiguration() { return this.configuration; } /** *

* Returns the template resolution object corresponding to the * template currently being processed. *

* * @return the Template Resolution object */ public TemplateResolution getTemplateResolution() { return this.templateResolution; } /** *

* Returns the template repository in use. *

* * @return the Template Repository object */ public TemplateRepository getTemplateRepository() { return this.templateRepository; } /** *

* Returns the parsed Document DOM object. *

* * @return the Document object */ public Document getDocument() { return this.document; } /** *

* Returns the name of the template currently being processed. *

* * @return the template name */ public String getTemplateName() { return this.templateResolution.getTemplateName(); } /** *

* Returns the current context specified for template processing. *

* * @return the current context */ public IContext getContext() { return this.context; } /** *

* Returns whether local variables have currently been specified or not. * (e.g. th:with in standard dialect). *

* * @return true if there are local variables, false if not */ public boolean hasLocalVariables() { return this.localVariables != null && this.localVariables.size() > 0; } /** *

* Returns the value of a local variable. *

* * @param variableName the name of the local variable to be returned * @return the value of the variable, or null if the variable does not exist (or has null value) * */ public Object getLocalVariable(final String variableName) { if (this.localVariables == null) { return null; } return this.localVariables.get(variableName); } /** *

* Returns whether a specific local variable is defined or not. *

* * @return true if the variable is currently defined, false if not. */ public boolean hasLocalVariable(final String variableName) { if (this.localVariables == null) { return false; } return this.localVariables.containsKey(variableName); } /** *

* Returns the real inner map of local variables. This * method should not be called directly. *

* * @return the local variables map, which could be null if no variables are defined */ public HashMap unsafeGetLocalVariables() { return this.localVariables; } /** *

* Returns a safe copy of the map of local variables. *

* * @return the local variables */ public Map getLocalVariables() { final HashMap vars = new HashMap(); if (this.localVariables != null) { vars.putAll(this.localVariables); } return vars; } /** *

* Returns whether only element nodes should be processed (as opposed * to texts, CDATAs, comments, etc.). Default is true. *

* * @return whether only element nodes will be processed */ public boolean getProcessOnlyElementNodes() { return this.processOnlyElementNodes; } /** *

* Returns whether there currently is a selection going on * (e.g. th:object in standard dialect). *

* * @return true if there is a selection currently established, false if not */ public boolean hasSelectionTarget() { return hasLocalVariable(Arguments.SELECTION_TARGET_LOCAL_VARIABLE_NAME); } /** *

* Returns the selection target object, and raises an * exception if there isn't any. *

*

* Meant for internal use. *

* * @return the selection target object */ public Object getSelectionTarget() { if (hasSelectionTarget()) { return getLocalVariable(Arguments.SELECTION_TARGET_LOCAL_VARIABLE_NAME); } throw new IllegalStateException( "Cannot return selection target object, a selection target has not been set."); } /** *

* Returns the map of ID counts. *

*

* These numbers are used to avoid conflicts among elements with the same id * attribute; for example elements being repeated as a part of a th:each iteration. *

* * @return the current map of ID counts */ public Map getIdCounts() { return this.idCounts; } /** *

* Returns the execution attributes. *

* * @return the current map of execution attributes */ public Map getExecutionAttributes() { return this.configuration.getExecutionAttributes(); } /** *

* Returns the execution attribute with the specified name. *

* * @param attributeName the name of the attribute to be retrieved * @return the value of the attribute */ public Object getExecutionAttribute(final String attributeName) { return this.configuration.getExecutionAttributes().get(attributeName); } /** *

* Returns the current evaluation root. This is the object on which expressions * (normal expressions, like those specified in the standard dialect with * ${...}) are executed. *

* * @return the expression evaluation root */ public Object getExpressionEvaluationRoot() { return this.evaluationRoot; } /** *

* Returns the current selection evaluation root. This is the object on which selection expressions * (like those specified in the standard dialect with *{...}) are executed. *

* * @return the selection evaluation root */ public Object getExpressionSelectionEvaluationRoot() { return this.selectionEvaluationRoot; } /** *

* Returns the map of base variables that should be made available to every expression * evaluation operation (whenever variable evaluation is available). *

* * @since 2.0.0 * @return the map of variables (a new object, mutable, safe to use as a context variables base) */ public Map getBaseContextVariables() { final Map variables = new HashMap(); variables.putAll(this.baseContextVariables); return variables; } /** *

* Returns a new index (ID count) for a specific * value of the id attribute, and increments * the count. *

* * @param id the ID for which the count will be computed * @return the new count, ready to be used */ public Integer getAndIncrementIDSeq(final String id) { Validate.notNull(id, "ID cannot be null"); Integer count = this.idCounts.get(id); if (count == null) { count = Integer.valueOf(1); } this.idCounts.put(id, Integer.valueOf(count.intValue() + 1)); return count; } /** *

* Returns the index (ID count) for a specific * value of the id attribute without incrementing * the count. *

* * @param id the ID for which the count will be retrieved * @return the current count */ public Integer getNextIDSeq(final String id) { Validate.notNull(id, "ID cannot be null"); Integer count = this.idCounts.get(id); if (count == null) { count = Integer.valueOf(1); } return count; } /** *

* Returns the last index (ID count) returned for a specific * value of the id attribute (without incrementing * the count). *

* * @param id the ID for which the last count will be retrieved * @return the count */ public Integer getPreviousIDSeq(final String id) { Validate.notNull(id, "ID cannot be null"); Integer count = this.idCounts.get(id); if (count == null) { throw new TemplateProcessingException( "Cannot obtain previous ID count for ID \"" + id + "\""); } return Integer.valueOf(count.intValue() - 1); } /** *

* Creates a new Arguments object by adding some new local variables * to the existing map (the rest of the attributes are copied verbatim). *

* * @param newVariables the new variables * @return the new Arguments object */ public Arguments addLocalVariables(final Map newVariables) { if (newVariables == null || newVariables.isEmpty()) { return this; } final int localVariablesSize = (this.localVariables != null? this.localVariables.size() : 0); final HashMap cloneLocalVariables = new HashMap(localVariablesSize + newVariables.size() + 1, 1.0f); if (this.localVariables != null) { cloneLocalVariables.putAll(this.localVariables); } cloneLocalVariables.putAll(newVariables); final Arguments arguments = new Arguments(this.templateProcessingParameters, this.templateResolution, this.templateRepository, this.document, cloneLocalVariables, this.idCounts, this.processOnlyElementNodes); return arguments; } /** *

* Creates a new Arguments object by setting a new value for the processOnlyElementNodes flag. *

* * @param shouldProcessOnlyElementNodes whether only element nodes should be processed from this moment in template execution * @return the new Arguments object */ public Arguments setProcessOnlyElementNodes(final boolean shouldProcessOnlyElementNodes) { final Arguments arguments = new Arguments(this.templateProcessingParameters, this.templateResolution, this.templateRepository, this.document, this.localVariables, this.idCounts, shouldProcessOnlyElementNodes); return arguments; } /** *

* Creates a new Arguments object by setting new local variables and a new value for the processOnlyElementNodes flag. *

* * @param newVariables the new local variables * @param shouldProcessOnlyElementNodes whether only element nodes should be processed from this moment in template execution * @return the new Arguments object */ public Arguments addLocalVariablesAndProcessOnlyElementNodes(final Map newVariables, final boolean shouldProcessOnlyElementNodes) { if (newVariables == null || newVariables.isEmpty()) { return this; } final int localVariablesSize = (this.localVariables != null? this.localVariables.size() : 0); final HashMap cloneLocalVariables = new HashMap(localVariablesSize + newVariables.size() + 1, 1.0f); if (this.localVariables != null) { cloneLocalVariables.putAll(this.localVariables); } cloneLocalVariables.putAll(newVariables); final Arguments arguments = new Arguments(this.templateProcessingParameters, this.templateResolution, this.templateRepository, this.document, cloneLocalVariables, this.idCounts, shouldProcessOnlyElementNodes); return arguments; } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy