Class ChainedInvocation

  • All Implemented Interfaces:
    Invokable

    public class ChainedInvocation
    extends Object
    implements Invokable

    A special implementation of the Invokable interface that allows aggregating an arbitrary number of Invokable objects to a kind of script.

    The idea behind this class is that other objects implementing the Invokable interface can be added. They can then be executed en bloc. In addition to that a rudimentary support for variables is available: the result of an invocation can be assigned to a named variable; later this variable can be accessed again using a special Dependency, which can be created by calling the getChainDependency() method.

    The typical life-cycle of an instance of this class is as follows:

    1. An instance is created using the default constructor.
    2. The Invokable objects to be executed are added using the addInvokable() methods. Note that the order of these calls is important; the added objects are invoked in exactly the same order.
    3. After adding all Invokable objects the invoke() method can be called. It triggers all contained objects.
    By making use of different invocation implementations, indeed a kind of scripting can be achieved. For instance new objects can be created, initialized (by invoking methods on them or setting properties), and assigned to other objects. This is quite powerful, but can also become complex and hard to debug.

    This class provides some methods for accessing and manipulating local variables. So it is possible to list all currently existing variables, query their values, and even modify them. However these features are mainly intended for debugging purposes rather than for implementing additional scripting logic.

    Note: This class is not thread-safe. It is intended to be created and initialized by a single thread and then be passed to a complex bean provider with initialization support. After that no more invocations should be added. Because the local variables of a currently executed script are internally stored, it is especially not possible to have multiple concurrent invocations.

    Version:
    $Id: ChainedInvocation.java 207 2012-02-09 07:30:13Z oheger $
    Author:
    Oliver Heger
    • Constructor Detail

      • ChainedInvocation

        public ChainedInvocation()
        Creates a new instance of ChainedInvocation.
    • Method Detail

      • addInvokable

        public void addInvokable​(Invokable inv)
        Adds the specified Invokable object to this object. It will become part of the invocation sequence.
        Parameters:
        inv - the object to be added (must not be null)
        Throws:
        IllegalArgumentException - if the passed in Invokable object is null
      • addInvokable

        public void addInvokable​(Invokable inv,
                                 String result)
        Adds the specified Invokable object to this object and initializes its result variable. It will become part of the invocation sequence. The result of its invocation will be stored in a local variable with the given name.
        Parameters:
        inv - the object to be added (must not be null)
        result - the name of the result variable
        Throws:
        IllegalArgumentException - if the passed in Invokable object is null
      • addInvokable

        public void addInvokable​(Invokable inv,
                                 String result,
                                 String source)
        Adds the specified Invokable object to this object and initializes its result variable and its source object. It will become part of the invocation sequence. The result of its invocation will be stored in a local variable with the given name. The invocation is not performed on the current target object, but on the object stored in the local variable with the given source name. This makes it possible to manipulate other objects than the current main target.
        Parameters:
        inv - the object to be added (must not be null)
        result - the name of the result variable
        source - the name of the variable, which contains the target object for this invocation
        Throws:
        IllegalArgumentException - if the passed in Invokable object is null
      • getInvokables

        public List<Invokable> getInvokables()
        Returns a list with the Invokable objects that have already been added to this chain. Manipulations of this list do not affect this object. It is empty if nothing has been added yet.
        Returns:
        a list with the children of this chain
      • size

        public int size()
        Returns the number of Invokable objects contained in this chain.
        Returns:
        the size of this chain
      • getChainDependency

        public Dependency getChainDependency​(String name)
        Returns a special Dependency for a local variable that is used during the execution of a ChainedInvocation. Local variables are created by specifying result names for Invokables when they are added to the chain: the result of this invocation will then be stored in a variable with this name. If this variable later needs to be used for another invocation (e.g. as the parameter of a method call), it can be accessed using such a dependency.
        Parameters:
        name - the name of the local variable to be accessed (must not be null)
        Returns:
        the dependency for accessing the specified local variable
        Throws:
        IllegalArgumentException - if the name is null
      • getVariableBean

        public BeanProvider getVariableBean​(String name)
        Returns a BeanProvider for the local variable with the given name. Using this method, variables created during script execution can be accessed as beans and thus can act as providers for other tags.
        Parameters:
        name - the name of the local variable to be accessed (must not be null)
        Returns:
        a BeanProvider wrapping this local variable
        Throws:
        IllegalArgumentException - if the name is null
        Since:
        1.1
      • getVariableNames

        public Set<String> getVariableNames()
        Returns a set with the names of the currently defined local variables. These names can be passed to the getVariable() method for querying the current values of these variables.
        Returns:
        a set with the names of the currently existing local variables
      • getVariable

        public Object getVariable​(String name)
        Returns the name of the variable with the given name. If there is no variable with this name, an exception is thrown. (We consider an access to an undefined variable an error in the invocation chain.)
        Parameters:
        name - the name of the variable to be queried
        Returns:
        the value of this variable
        Throws:
        InjectionException - if the variable cannot be found
      • setVariable

        public void setVariable​(String name,
                                Object value)
        Sets the value of the specified variable. If the variable does not exist yet, it is created. A value of null removes the variable.
        Parameters:
        name - the name of the variable (must not be null)
        value - the new value of the variable
        Throws:
        IllegalArgumentException - if the name is null
      • isClearVariables

        public boolean isClearVariables()
        Returns a flag whether all local variables are to be cleared for each new invocation.
        Returns:
        the clear variables flag
      • setClearVariables

        public void setClearVariables​(boolean clearVariables)
        Sets the value of the clear variables flag. If this flag is set to true (which is the default value), the storage for local variables is cleared at the beginning of an invocation. This ensures that values generated by earlier invocations do not affect the current invocation. If variables have been set manually using the setVariable() method, it will be necessary to disable this flag; otherwise these variables will also get lost.
        Parameters:
        clearVariables - the new value of the flag
      • getResultVariableName

        public String getResultVariableName()
        Returns the name of the result variable.
        Returns:
        the name of the result variable
        Since:
        1.1
      • setResultVariableName

        public void setResultVariableName​(String resultVariableName)
        Sets the name of the result variable. If this property is set, the invoke() method will not return the passed in target object, but the object referenced by this variable. This is useful if the script generates a result.
        Parameters:
        resultVariableName - the name of the result variable
        Since:
        1.1
      • getParameterDependencies

        public List<Dependency> getParameterDependencies()
        Returns a list of the dependencies required for this invocation. This implementation creates a union of the dependencies of all contained Invokable objects.
        Specified by:
        getParameterDependencies in interface Invokable
        Returns:
        a list with the dependencies
      • invoke

        public Object invoke​(DependencyProvider depProvider,
                             Object target)
        Performs the invocation represented by this class. This implementation will invoke all contained Invokable objects.
        Specified by:
        invoke in interface Invokable
        Parameters:
        depProvider - the dependency provider
        target - the target object
        Returns:
        the result of the invocation
        Throws:
        InjectionException - if an error occurs
        IllegalArgumentException - if the dependency provider is null or a required target object is undefined
      • toString

        public String toString()
        Returns a string representation for this object. This implementation outputs all contained Invokable objects.
        Overrides:
        toString in class Object
        Returns:
        a string for this object