terp - the Codemesh Modular
Template Interpreter v1.3.309

com.codemesh.terp.eval
Class TerpEvaluatorImpl

java.lang.Object
  extended by com.codemesh.terp.eval.TerpRegistrarImpl
      extended by com.codemesh.terp.eval.TerpEvaluatorImpl
All Implemented Interfaces:
TerpConstants, TerpEvaluator, TerpRegistrar

public class TerpEvaluatorImpl
extends TerpRegistrarImpl
implements TerpEvaluator

The default evaluator for terp templates and expressions. While there is nothing that prevents you from creating many instances of this type, it should usually be used in a singleton pattern. You can call the TerpEvaluatorImpl() constructor to create multiple instances, but in most circumstances you really only need one of them. To reuse a single instance over and over, acquire it via the getInstance() method.

Why allow multiple instances while recommending a single instance? The answer lies in the modular structure of terp. terp can be extended by registering operator overloads, new functions, type converters, etc. but this raises the question of whom you should register these extensions with. terp provides the TerpRegistrar interface as the contract for registering additional functionality. The TerpEvaluatorImpl type provides an implementation of this interface. This means that you can instantiate an evaluator and then register your custom code with it and it will be available during the evaluation of terp expressions and expansion of terp templates. Using the singleton pattern provided via getInstance() makes sure that you always deal with the same instance that has your extensions registered.

If you create a new evaluator instance, it won't have your extensions registered and you might get unexpected results. There is of course the possibility that you don't really want your extensions registered with the newly created instance. Maybe you really want different evaluators with different extension sets. While this is a less likely scenario, it is certainly not impossible, and that's why we don't want to enforce the singleton pattern by making the constructor private. By the way, if you want all terp evaluator instances to have access to a set of extensions you can register the extensions with the global registrar available via TerpRegistrarImpl.getGlobalRegistrar(). No matter whether you created the evaluator before or after registering extensions with the global registrar, the extensions will be available to it.

No matter how you acquired your evaluator instance, you will want to use it to evaluate expressions or expand templates. You use the evaluate(TerpParser,TerpContext) and expand(TerpParser,TerpContext) methods for these purposes.


Field Summary
 
Fields inherited from class com.codemesh.terp.eval.TerpRegistrarImpl
GLOBAL_REGISTRAR, instanceConverters, instanceLvalFactories, instanceOps, instanceRvalFactories, instanceSelectors, instanceSorters, instanceTransformers
 
Fields inherited from interface com.codemesh.terp.api.TerpConstants
APPLY, ASSIGN, BITWISE_AND, BITWISE_NOT, BITWISE_OR, CONDITIONAL, DIVIDE, DIVIDE_EQUALS, EMIT, EQUALS, EVAL, EXPAND, EXPORT, GREATER_EQUALS, GREATER_THAN, IMPORT, LESS_EQUALS, LESS_THAN, LOGICAL_AND, LOGICAL_NOT, LOGICAL_OR, MATCHES, METADATA_SUPPRESS, METADATA_TARGET, METADATA_TEMPLATE, MINUS, MINUS_EQUALS, MODULO, MODULO_EQUALS, MULTIPLY, MULTIPLY_EQUALS, NOT_EQUALS, NOT_MATCHES, PLUS, PLUS_EQUALS, POST_DEC, POST_INC, PRE_DEC, PRE_INC, RANGE, SET, SHELL, UNARY_MINUS
 
Constructor Summary
protected TerpEvaluatorImpl()
           
 
Method Summary
protected  boolean calculate_select(java.lang.Object item, java.lang.Object owner, Node selectorNode, TerpContext ctx)
           
protected  java.lang.Object calculate_transform(java.lang.Object item, Node txNode, TerpContext ctx)
           
 java.lang.Object calculate(Node node, TerpContext ctx)
           
protected  void collection(Node node, TerpContext ctx)
          Creates an ArrayList containing all specified elements and pushes it onto the stack.
protected  void embedded(Node node, TerpContext ctx, boolean bRecurse)
           
 java.lang.Object evaluate(TerpParser parser, TerpContext ctx)
          Evaluates a terp expression.
 java.lang.Object executeAssignment(java.lang.String op, java.util.List<java.lang.Object> args, TerpContext ctx)
           
protected  void executeAssignment(java.lang.String op, Node opNode, TerpContext ctx)
          Calculates all operands, invokes an assignment operation.
protected  void executeConditional(java.lang.String op, Node opNode, TerpContext ctx)
           
 java.lang.Object executeGeneric(java.lang.String op, java.util.List<java.lang.Object> args, TerpContext ctx)
           
protected  void executeGeneric(java.lang.String op, Node opNode, TerpContext ctx)
          Calculates all operands, invokes a resolved executor and pushes result on stack.
protected  void executeGeneric(java.lang.String op, Node opNode, TerpContext ctx, boolean bAbortCondition)
          An alternate entry point for some logical operations with special invocation semantics.
 void expand(TerpParser parser, TerpContext ctx)
          Expands a terp template.
 void expand(TerpParser parser, TerpContext ctx, boolean bRecurse)
           
 void expandNoCatch(TerpParser parser, TerpContext ctx)
           
 void expandNoCatch(TerpParser parser, TerpContext ctx, boolean bRecurse)
           
protected  void foreach(Node foreach, TerpContext ctx, boolean bRecurse)
           
protected  void function(Node node, TerpContext ctx)
           
static TerpEvaluator getInstance()
          The factory method that returns a global instance of an evaluator.
protected  void if_(Node ifNode, TerpContext ctx, boolean bRecurse)
           
protected  boolean isBooleanType(Node node)
           
protected  boolean isInteger(Node node, TerpContext ctx)
           
protected  boolean isNonEmptyIterable(java.lang.Object obj)
           
protected  boolean isNumericType(Node node, TerpContext ctx)
           
protected  boolean isScalarTransformer(Node node)
           
protected  boolean isSorter(Node node)
           
protected  boolean isString(Node node, TerpContext ctx)
           
protected  boolean isTransformer(Node node)
           
 java.util.Iterator iterator(java.lang.Object obj)
           
 Converter lookupConverter(java.lang.String name)
          Looks for registered converters in the instance registry followed by the global registry.
 Executor<Lvalue> lookupLvalueResolver(java.lang.String name, java.util.List<java.lang.Object> args)
          Looks for registered resolver in the instance registry followed by the global registry.
 Executor<Rvalue> lookupRvalueResolver(java.lang.String name, java.util.List<java.lang.Object> args)
          Looks for registered resolver in the instance registry followed by the global registry.
 Selector lookupSelector(java.lang.String name)
          Looks for registered selectors in the instance registry followed by the global registry.
 Sorter lookupSorter(java.lang.String name)
          Looks for registered sorter in the instance registry followed by the global registry.
 Transformer lookupTransformer(java.lang.String name)
          Looks for registered transformers in the instance registry followed by the global registry.
protected  void lvalue(Node node, TerpContext ctx)
           
protected  void map(Node node, TerpContext ctx)
          Creates a HashMap containing all contained name/value pairs and pushes it onto the stack.
protected  void property(Node node, TerpContext ctx)
           
protected  void qualifier(Node node, TerpContext ctx)
           
protected  void range(Node node, TerpContext ctx)
          Creates a Range initialized to the lower and upper bounds specified and pushes it onto the stack.
 Executor resolveExecutor(java.lang.String op, java.util.List<java.lang.Object> args)
          Looks for registered executor in the instance registry followed by the global registry.
protected  Lvalue resolveLvalue(Node idNode, TerpContext ctx)
           
protected  Rvalue resolveRvalue(Node idNode, TerpContext ctx)
           
protected  java.lang.Object scalar_transform(java.lang.Object receiver, Node txNode, TerpContext ctx)
           
protected  void scope(java.lang.String id, Node scope, TerpContext ctx, boolean bRecurse)
           
protected  java.lang.Object select(java.lang.Object receiver, Node selectorNode, TerpContext ctx)
           
protected  java.lang.Object sort(java.lang.Object receiver, Node txNode, TerpContext ctx)
           
protected  void statement(Node node, TerpContext ctx, boolean bRecurse)
           
protected  void switch_(Node switchNode, TerpContext ctx, boolean bRecurse)
           
protected  java.lang.Object transform(java.lang.Object receiver, Node txNode, TerpContext ctx)
           
protected  void type(Node node, TerpContext ctx)
          Attempts to execute a type converter/constructor.
 
Methods inherited from class com.codemesh.terp.eval.TerpRegistrarImpl
getGlobalRegistrar, registerConverter, registerExecutor, registerLvalueResolver, registerRvalueResolver, registerSelector, registerSorter, registerTransformer, unregisterConverter, unregisterExecutor, unregisterLvalueResolver, unregisterRvalueResolver, unregisterSelector, unregisterSorter, unregisterTransformer
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 
Methods inherited from interface com.codemesh.terp.api.TerpRegistrar
getGlobalRegistrar, registerConverter, registerExecutor, registerLvalueResolver, registerRvalueResolver, registerSelector, registerSorter, registerTransformer, unregisterConverter, unregisterExecutor, unregisterLvalueResolver, unregisterRvalueResolver, unregisterSelector, unregisterSorter, unregisterTransformer
 

Constructor Detail

TerpEvaluatorImpl

protected TerpEvaluatorImpl()
Method Detail

getInstance

public static TerpEvaluator getInstance()
The factory method that returns a global instance of an evaluator. In most cases, you don't want or need more than one instance of an evaluator. The only times that you want different instances is when you register different extension packages with conflicting declarations.

Returns:
the global instance of an evaluator.

evaluate

public java.lang.Object evaluate(TerpParser parser,
                                 TerpContext ctx)
Evaluates a terp expression. A terp expression is not embedded in the embedded terp delimiters '${' and '}'. An expression can consist simply of a literal like 4 or a variable like pi or a complex expression like ^string((4*pi)/e). See the terp expression reference for more details on syntax and available features.

Specified by:
evaluate in interface TerpEvaluator
Parameters:
parser - the parsed expression. The parser needed to be instantiated with a TokenizerState of TokenizerState.EXPRESSION.
ctx - the evaluation context which defines variables etc.
Returns:
the result of the evaluation.

expand

public void expand(TerpParser parser,
                   TerpContext ctx)
Expands a terp template. A terp template is simply text which may contain embedded terp expressions. As you can see, the expand method does not return the resulting text. The resulting text is accumulated in an Appendable that is maintained by the TerpContext. The appendable object can be a StringBuilder or a StringBuffer or it could be a FileWriter. Any Appendable will do. By default, context instances are created with a StringBuilder as their Appendable. This means that you can accumulate more than one template into a buffer by reusing the context. You can also start over again by resetting the buffer length to 0.

Specified by:
expand in interface TerpEvaluator
Parameters:
parser - the parsed expression. The parser needed to be instantiated with a TokenizerState of TokenizerState.TEXT.
ctx - the evaluation context which defines variables etc.

expand

public void expand(TerpParser parser,
                   TerpContext ctx,
                   boolean bRecurse)
Specified by:
expand in interface TerpEvaluator

expandNoCatch

public void expandNoCatch(TerpParser parser,
                          TerpContext ctx)
Specified by:
expandNoCatch in interface TerpEvaluator

expandNoCatch

public void expandNoCatch(TerpParser parser,
                          TerpContext ctx,
                          boolean bRecurse)
Specified by:
expandNoCatch in interface TerpEvaluator

statement

protected void statement(Node node,
                         TerpContext ctx,
                         boolean bRecurse)

embedded

protected void embedded(Node node,
                        TerpContext ctx,
                        boolean bRecurse)

if_

protected void if_(Node ifNode,
                   TerpContext ctx,
                   boolean bRecurse)

foreach

protected void foreach(Node foreach,
                       TerpContext ctx,
                       boolean bRecurse)

scope

protected void scope(java.lang.String id,
                     Node scope,
                     TerpContext ctx,
                     boolean bRecurse)

switch_

protected void switch_(Node switchNode,
                       TerpContext ctx,
                       boolean bRecurse)

calculate

public java.lang.Object calculate(Node node,
                                  TerpContext ctx)
Specified by:
calculate in interface TerpEvaluator

collection

protected void collection(Node node,
                          TerpContext ctx)
Creates an ArrayList containing all specified elements and pushes it onto the stack.

Parameters:
node - the collection node.
ctx - the evaluation context.

map

protected void map(Node node,
                   TerpContext ctx)
Creates a HashMap containing all contained name/value pairs and pushes it onto the stack.

Parameters:
node - the map node.
ctx - the evaluation context.

range

protected void range(Node node,
                     TerpContext ctx)
Creates a Range initialized to the lower and upper bounds specified and pushes it onto the stack.

Parameters:
node - the range node.
ctx - the evaluation context.

type

protected void type(Node node,
                    TerpContext ctx)
Attempts to execute a type converter/constructor.

Parameters:
node - the type node.
ctx - the evaluation context.

lvalue

protected void lvalue(Node node,
                      TerpContext ctx)

property

protected void property(Node node,
                        TerpContext ctx)

qualifier

protected void qualifier(Node node,
                         TerpContext ctx)

select

protected java.lang.Object select(java.lang.Object receiver,
                                  Node selectorNode,
                                  TerpContext ctx)

sort

protected java.lang.Object sort(java.lang.Object receiver,
                                Node txNode,
                                TerpContext ctx)

transform

protected java.lang.Object transform(java.lang.Object receiver,
                                     Node txNode,
                                     TerpContext ctx)

scalar_transform

protected java.lang.Object scalar_transform(java.lang.Object receiver,
                                            Node txNode,
                                            TerpContext ctx)

calculate_select

protected boolean calculate_select(java.lang.Object item,
                                   java.lang.Object owner,
                                   Node selectorNode,
                                   TerpContext ctx)

calculate_transform

protected java.lang.Object calculate_transform(java.lang.Object item,
                                               Node txNode,
                                               TerpContext ctx)

function

protected void function(Node node,
                        TerpContext ctx)

executeAssignment

protected void executeAssignment(java.lang.String op,
                                 Node opNode,
                                 TerpContext ctx)
Calculates all operands, invokes an assignment operation.

Parameters:
op - the operation's identifier string. Use this string value to register additional executors or to override already registered ones.
opNode - the operation's node with operands as children.
ctx - the evaluation context.

executeAssignment

public java.lang.Object executeAssignment(java.lang.String op,
                                          java.util.List<java.lang.Object> args,
                                          TerpContext ctx)

executeGeneric

protected void executeGeneric(java.lang.String op,
                              Node opNode,
                              TerpContext ctx)
Calculates all operands, invokes a resolved executor and pushes result on stack.

Parameters:
op - the operation's identifier string. Use this string value to register additional executors or to override already registered ones.
opNode - the operation's node with operands as children.
ctx - the evaluation context.

executeGeneric

public java.lang.Object executeGeneric(java.lang.String op,
                                       java.util.List<java.lang.Object> args,
                                       TerpContext ctx)
Specified by:
executeGeneric in interface TerpEvaluator

executeGeneric

protected void executeGeneric(java.lang.String op,
                              Node opNode,
                              TerpContext ctx,
                              boolean bAbortCondition)
An alternate entry point for some logical operations with special invocation semantics. Logical AND or OR operations have special semantics that abort the evaluation of arguments when the result of the operation is known after evaluating some operands. For example, an AND operation requires all operands to be true. When the first false operand is encountered, evaluation of all following operands must be aborted because the first false condition might have been a guard preventing evaluation of subsequent terms. Example:
if( f != null && f.exists() ) {...}
The second term must not be evaluated because it would result in a NullPointerException after the first one returned false.

This situation is further complicated by potential operator overrides. The implementation therefore also pays attention to the operand types. The operand evaluation abort feature only kicks in when all preceding operands were of Boolean type.

Parameters:
op - the operation's identifier string. Use this string value to register additional executors or to override already registered ones.
opNode - the operation's node with operands as children.
ctx - the evaluation context.
bAbortCondition - the boolean value an operand must have to abort further operand evaluations.

executeConditional

protected void executeConditional(java.lang.String op,
                                  Node opNode,
                                  TerpContext ctx)

resolveRvalue

protected Rvalue resolveRvalue(Node idNode,
                               TerpContext ctx)

resolveLvalue

protected Lvalue resolveLvalue(Node idNode,
                               TerpContext ctx)

resolveExecutor

public Executor resolveExecutor(java.lang.String op,
                                java.util.List<java.lang.Object> args)
Looks for registered executor in the instance registry followed by the global registry.

Specified by:
resolveExecutor in interface TerpRegistrar
Overrides:
resolveExecutor in class TerpRegistrarImpl
Parameters:
op - the lookup name.
args - the arguments passed to the operation.
Returns:
the resolver or null.

lookupLvalueResolver

public Executor<Lvalue> lookupLvalueResolver(java.lang.String name,
                                             java.util.List<java.lang.Object> args)
Looks for registered resolver in the instance registry followed by the global registry.

Specified by:
lookupLvalueResolver in interface TerpRegistrar
Overrides:
lookupLvalueResolver in class TerpRegistrarImpl
Parameters:
name - the lookup name.
args - the arguments passed to the operation.
Returns:
the resolver or null.

lookupRvalueResolver

public Executor<Rvalue> lookupRvalueResolver(java.lang.String name,
                                             java.util.List<java.lang.Object> args)
Looks for registered resolver in the instance registry followed by the global registry.

Specified by:
lookupRvalueResolver in interface TerpRegistrar
Overrides:
lookupRvalueResolver in class TerpRegistrarImpl
Parameters:
name - the lookup name.
args - the arguments passed to the operation.
Returns:
the resolver or null.

lookupConverter

public Converter lookupConverter(java.lang.String name)
Looks for registered converters in the instance registry followed by the global registry.

Specified by:
lookupConverter in interface TerpRegistrar
Overrides:
lookupConverter in class TerpRegistrarImpl
Parameters:
name - the lookup name.
Returns:
the converter or null.

lookupSelector

public Selector lookupSelector(java.lang.String name)
Looks for registered selectors in the instance registry followed by the global registry.

Specified by:
lookupSelector in interface TerpRegistrar
Overrides:
lookupSelector in class TerpRegistrarImpl
Parameters:
name - the lookup name.
Returns:
the selector or null.

lookupSorter

public Sorter lookupSorter(java.lang.String name)
Looks for registered sorter in the instance registry followed by the global registry.

Specified by:
lookupSorter in interface TerpRegistrar
Overrides:
lookupSorter in class TerpRegistrarImpl
Parameters:
name - the lookup name.
Returns:
the sorter or null.

lookupTransformer

public Transformer lookupTransformer(java.lang.String name)
Looks for registered transformers in the instance registry followed by the global registry.

Specified by:
lookupTransformer in interface TerpRegistrar
Overrides:
lookupTransformer in class TerpRegistrarImpl
Parameters:
name - the lookup name.
Returns:
the transformer or null.

iterator

public java.util.Iterator iterator(java.lang.Object obj)

isString

protected boolean isString(Node node,
                           TerpContext ctx)

isInteger

protected boolean isInteger(Node node,
                            TerpContext ctx)

isSorter

protected boolean isSorter(Node node)

isTransformer

protected boolean isTransformer(Node node)

isScalarTransformer

protected boolean isScalarTransformer(Node node)

isBooleanType

protected boolean isBooleanType(Node node)

isNumericType

protected boolean isNumericType(Node node,
                                TerpContext ctx)

isNonEmptyIterable

protected boolean isNonEmptyIterable(java.lang.Object obj)

terp - the Codemesh Modular
Template Interpreter v1.3.309

Copyright © 2008-2012 by Codemesh, Inc. All Rights Reserved.