com.googlecode.sarasvati
Interface Engine

All Known Implementing Classes:
BaseEngine, HibEngine, MemEngine

public interface Engine

An Engine executes a process. A Graph specifies how it should be executed and a GraphProcess tracks the current state of execution. But it is an Engine which creates instances of ArcToken, NodeToken and GraphProcess and which invokes Node.guard(Engine, NodeToken) and Node.execute(Engine, NodeToken).

Unless an Engine implementation states otherwise, Engine instances should not be considered thread-safe. A new Engine instance should be created for each thread that needs one.

Author:
Paul Lorenz

Method Summary
 void addExecutionListener(Class<? extends ExecutionListener> listenerClass, ExecutionEventType... eventTypes)
          Adds a listener of the given type for the given event types for all processes.
 void addExecutionListener(GraphProcess process, Class<? extends ExecutionListener> listenerClass, ExecutionEventType... eventTypes)
          Adds a listener for the given event types for the given process.
 void addGlobalCustomNodeType(String type, Class<? extends CustomNode> nodeClass)
          Adds the type to the GraphFactory for this engine.
 void addNodeType(String type, Class<? extends Node> nodeClass)
          Adds the type to the GraphFactory for this engine.
 void backtrack(NodeToken token)
          Backtracks execution to the point where the given node token was active.
 void cancelProcess(GraphProcess process)
          Cancels the given process.
 void complete(NodeToken token, String arcName)
          Continues execution of a process in a wait state.
 void completeAsynchronous(NodeToken token, String arcName)
          Marks the given node token completed and generates the next set of arc tokens.
 void completeWithNewTokenSet(NodeToken token, String arcName, String tokenSetName, int numberOfTokens, boolean asynchronous, Env initialEnv, Map<String,List<?>> initialMemberEnv)
          Marks the given node token, creates new token set and generates the next set of arc tokens as members of that new token set.
 GuardResult evaluateGuard(NodeToken token, String guard)
          Nodes, by default, will pass off guard evaluation to the Engine.
 void executeQueuedArcTokens(GraphProcess process)
          If this process has any ArcTokens queued for execution, this method will execute them.
 void finalizeCancel(GraphProcess process)
          Called by the engine when a process is cancelled, via cancelProcess(GraphProcess).
 void finalizeComplete(GraphProcess process)
          Called by the engine when the process is detected to be completed.
 EventActions fireEvent(ExecutionEvent event)
          This will send the given event to listeners who have registered for events on all processes and to listeners who have registered for events on the process that originated this event.
 GraphFactory getFactory()
          Returns an appropriate GraphFactory for this Engine.
 GraphLoader<? extends Graph> getLoader()
          Returns an appropriate GraphLoader for this Engine.
 GraphLoader<? extends Graph> getLoader(GraphValidator validator)
          Returns an appropriate GraphLoader for this Engine.
 Engine getParentEngine()
          If this engine was created to execute a nested process, it will remember the engine which created it.
 GraphRepository<? extends Graph> getRepository()
          Returns an appropriate GraphRepository for this Engine.
 Engine newEngine(boolean forNested)
          Since an Engine can have state specific to the currently executing process, there are times we want to create a new engine (such as when executing a nested process).
 JoinLangEnv newJoinLangEnv(ArcToken token)
          Creates a JoinLangEnv to be used to evaluate a JoinLang statement controlling if the given ArcToken satisfies a join.
 RubricEnv newRubricEnv(NodeToken token)
          Creates a RubricEnv to be used to evaluate a Rubric statement defining a guard for the given NodeToken.
 void removeExecutionListener(Class<? extends ExecutionListener> listenerClass, ExecutionEventType... eventTypes)
          Will remove the given listener type from the set of global listeners.
 void removeExecutionListener(GraphProcess process, Class<? extends ExecutionListener> listenerClass, ExecutionEventType... eventTypes)
          Will remove the listener from the given proces.
 void setupScriptEnv(ScriptEnv env, NodeToken token)
          Adds whatever variables of interest to the script environment.
 GraphProcess startProcess(Graph graph)
          Given a Graph, creates a new GraphProcess executing that graph.
 void startProcess(GraphProcess process)
          Sometimes it is desirable to separate process creation from starting execution of the process.
 GraphProcess startProcess(String graphName)
          Starts an instance of the latest graph with the given name.
 

Method Detail

startProcess

GraphProcess startProcess(String graphName)
Starts an instance of the latest graph with the given name. Is the equivalent of doing
  Graph graph = engine.getRepository().getLatestGraph( graphName );
  GraphProcess process = engine.startProcess( graph );
 
If no process definition exists for the given name, a SarasvatiException will be thrown.

Parameters:
graphName - The name of the graph to execute.
Returns:
The new GraphProcess.
Throws:
SarasvatiException - If no process definition is defined for that name.

startProcess

GraphProcess startProcess(Graph graph)
Given a Graph, creates a new GraphProcess executing that graph. A NodeToken will be generated on each start nodes (determined by Graph.getStartNodes()), and these NodeTokens will be executed. If the graph does not contain Nodes which go into a wait state, the GraphProcess returned will be completed.

Parameters:
graph - The Graph to execute.
Returns:
A GraphProcess executing the given Graph.

startProcess

void startProcess(GraphProcess process)
Sometimes it is desirable to separate process creation from starting execution of the process. For example, one may wish to set some variables into the process environment before starting execution. startProcess will generate a new NodeToken on each start node contained in the given process.

Parameters:
process - The process on which to begin execution.

cancelProcess

void cancelProcess(GraphProcess process)
Cancels the given process. The process state is set to ProcessState.PendingCancel.

Parameters:
process - The process to cancel

finalizeComplete

void finalizeComplete(GraphProcess process)
Called by the engine when the process is detected to be completed. It will set the state to ProcessState.Completed and perform whatever cleanup is required.

If an ExecutionListener returns an EventActions object specifying EventActionType.DELAY_PROCESS_FINALIZE_COMPLETE, then this method will *not* be called, and be manually invoked from user logic

If this process is a nested process, at this point the containing token will be completed.

Parameters:
process - The process being completed.

finalizeCancel

void finalizeCancel(GraphProcess process)
Called by the engine when a process is cancelled, via cancelProcess(GraphProcess). It will set the state to ProcessState.Canceled and perform whatever cleanup is required.

If an ExecutionListener returns an EventActions object specifying EventActionType.DELAY_PROCESS_FINALIZE_CANCEL, then this method will *not* be called, and be manually invoked from user logic

Parameters:
process - The process being canceled.

complete

void complete(NodeToken token,
              String arcName)
Continues execution of a process in a wait state. If a call to Node.execute(Engine, NodeToken) does not contain a call to complete(NodeToken, String), then execution of the graph will halt at that point. This is generally referred to as a wait state. It may happen, for example, if the action represented by that node must be done by a human or some external system.
When the external system has determined that the Node has completed its work, it should invoke this method to continue executing the process.
If the token belongs to a process which is _not_ in state ProcessState.Executing this call will return immediately.

Parameters:
token - The NodeToken to resume execution on
arcName - The name of the Arc (or arcs, as more than one Arc can have the same name) to generate ArcTokens on.

completeAsynchronous

void completeAsynchronous(NodeToken token,
                          String arcName)
Marks the given node token completed and generates the next set of arc tokens. However, these arc tokens will not be processed. Execution may be continued later with a call to executeQueuedArcTokens(GraphProcess).

Parameters:
token - The token to mark completed
arcName - The name of the Arc (or arcs, as more than one Arc can have the same name) to generate ArcTokens on.

completeWithNewTokenSet

void completeWithNewTokenSet(NodeToken token,
                             String arcName,
                             String tokenSetName,
                             int numberOfTokens,
                             boolean asynchronous,
                             Env initialEnv,
                             Map<String,List<?>> initialMemberEnv)
Marks the given node token, creates new token set and generates the next set of arc tokens as members of that new token set.

Parameters:
token - The node token to complete
arcName - The name of the Arc (or arcs, as more than one Arc can have the same name) to generate ArcTokens on.
tokenSetName - The token set name
numberOfTokens - The number of tokens to generate on each arc
asynchronous - If true, the engine will return after creating the arc tokens. If false, the new arc tokens will be processed immediately.
initialEnv - The initial environment for the new token set. May be null.
initialMemberEnv - The initial environment for the new token set members. May be null.

executeQueuedArcTokens

void executeQueuedArcTokens(GraphProcess process)
If this process has any ArcTokens queued for execution, this method will execute them.

Parameters:
process - The process whose queued arc tokens to queue

getRepository

GraphRepository<? extends Graph> getRepository()
Returns an appropriate GraphRepository for this Engine. Subclasses may override this to provide custom behavior.

Returns:
An appropriate GraphRepository for this Engine

getFactory

GraphFactory getFactory()
Returns an appropriate GraphFactory for this Engine. Subclasses may override this provide customer behavior.

Returns:
A GraphFactory which will generate the appropriate types for this Engine.

getLoader

GraphLoader<? extends Graph> getLoader()
Returns an appropriate GraphLoader for this Engine. Subclasses may override this provide customer behavior.

Equivalent to getLoader( null )

Returns:
A GraphLoader which, by default, will use the factory and repository from this engine.

getLoader

GraphLoader<? extends Graph> getLoader(GraphValidator validator)
Returns an appropriate GraphLoader for this Engine. Subclasses may override this provide customer behavior.

Returns:
A GraphLoader which, by default, will use the factory and repository from this engine.

addNodeType

void addNodeType(String type,
                 Class<? extends Node> nodeClass)
Adds the type to the GraphFactory for this engine. Specifies what class will be used for a given node type, when loading process definitions from XML file.

Parameters:
type - The type identifier, as used in the process definition file
nodeClass - The node class which will be instantiated for this type

addGlobalCustomNodeType

void addGlobalCustomNodeType(String type,
                             Class<? extends CustomNode> nodeClass)
Adds the type to the GraphFactory for this engine. Specifies what class will be used for a given node type, when loading process definitions from XML file.

Adds a class for a custom node type globally, for all GraphFactory instances. Only custom types can have global instances, since they are backend agnostic.

Parameters:
type - The type identifier, as used in the process definition file
nodeClass - The custom node class which will be instantiated for this type

fireEvent

EventActions fireEvent(ExecutionEvent event)
This will send the given event to listeners who have registered for events on all processes and to listeners who have registered for events on the process that originated this event.

Parameters:
event - The event to send to all interested listeners.
Returns:
EventActions Listeners may return EventActions which may influence execution by, for example, delaying further execution.

addExecutionListener

void addExecutionListener(Class<? extends ExecutionListener> listenerClass,
                          ExecutionEventType... eventTypes)
Adds a listener of the given type for the given event types for all processes. It is not added to each process individually, but rather added to a global set of listeners. Global generally means global for the application scope of this engine. The application scope is just a string name, specified in the engine constructor. If the default constructor is used, the default application scope is used, which is the empty string.
ExecutionListener Global execution listeners must be thread safe. Because listeners are specified by type, they must have a default constructor and be instantiatable by a call to listenerClass.newInstance().
Global execution listeners are specified by class for consistency with process level execution listeners, which can be persisted in a database by class name.

Parameters:
listenerClass - The listener type to be added
eventTypes - The event types to be notified for. If no types are specified, the listener is added for all event types.

addExecutionListener

void addExecutionListener(GraphProcess process,
                          Class<? extends ExecutionListener> listenerClass,
                          ExecutionEventType... eventTypes)
Adds a listener for the given event types for the given process.
ExecutionListener Execution listeners must be thread safe. Because listeners are specified by type, they must have a default constructor and be instantiatable by a call to listenerClass.newInstance().
Process level execution listeners are specified by class because they may be stored in the database as class names. This is so they can be reinstantiated after a JVM restart.

Parameters:
process - The process to add the listener for, or null for all processes
listenerClass - The listener type to be added.
eventTypes - The event types to be notified for. If no listener types are specified, the listener is added for all event types.

removeExecutionListener

void removeExecutionListener(Class<? extends ExecutionListener> listenerClass,
                             ExecutionEventType... eventTypes)
Will remove the given listener type from the set of global listeners. If no event types are specified, the listener will be removed for all event types. Otherwise it will be removed for only the specified event types.

Parameters:
listenerClass - The type of listener to remove
eventTypes - The set of event types to remove the listener for, or none to remove for all

removeExecutionListener

void removeExecutionListener(GraphProcess process,
                             Class<? extends ExecutionListener> listenerClass,
                             ExecutionEventType... eventTypes)
Will remove the listener from the given proces. If no event types are specified, the listener will be removed for all event types. Otherwise it will be removed for only the specified event types.
The listener doesn't need to match exactly. All listeners of this type will be matched. What matches types is determined by the implementation, but usually it means same class.

Parameters:
process - The process to remove the listener from, or null to remove from the global listener set
listenerClass - The type of listener to remove
eventTypes - The set of event types to remove the listener for, or none to remove for all

setupScriptEnv

void setupScriptEnv(ScriptEnv env,
                    NodeToken token)
Adds whatever variables of interest to the script environment. May be overridden by subclasses. By default this will setup two variables:

Parameters:
env - The script environment to add variables to
token - The NodeToken which is currently being executed

newRubricEnv

RubricEnv newRubricEnv(NodeToken token)
Creates a RubricEnv to be used to evaluate a Rubric statement defining a guard for the given NodeToken.

Parameters:
token - The token which will provide some of the state for the RubricEnv
Returns:
A RubricEnv for this engine and the given NodeToken.

newJoinLangEnv

JoinLangEnv newJoinLangEnv(ArcToken token)
Creates a JoinLangEnv to be used to evaluate a JoinLang statement controlling if the given ArcToken satisfies a join.

Parameters:
token - The token which will provide some of the state for the JoinLangEnv
Returns:
A JoinLangEnv for this engine and the given ArcToken.

evaluateGuard

GuardResult evaluateGuard(NodeToken token,
                          String guard)
Nodes, by default, will pass off guard evaluation to the Engine. This allows engine subclasses to easily override the default behavior and use a rules engine or scripting language for guards.

Parameters:
token - The NodeToken for which the guard is being evaluated.
guard - The guard statement to be evaluated. Maybe blank or null, which by convention should cause AcceptTokenGuardResult to be returned.
Returns:
The response based on the guard.

newEngine

Engine newEngine(boolean forNested)
Since an Engine can have state specific to the currently executing process, there are times we want to create a new engine (such as when executing a nested process). If this engine is being created to execute a nested process, the forNested flag should be set to true, so that we track the current engine as the parent.

Parameters:
forNested - Indicates whether this new engine is being created to track execution of a nested process.
Returns:
A copy of the current engine which can be used to execute a nested process

getParentEngine

Engine getParentEngine()
If this engine was created to execute a nested process, it will remember the engine which created it.

Returns:
The parent engine.

backtrack

void backtrack(NodeToken token)
Backtracks execution to the point where the given node token was active. The token must be complete and must not have been backtracked before. If it's not complete, there isn't any point in backtracking to it. If it has already been backtracked, the execution has either returned to a point previous to that token, or there is a newer, non-backtracked token at that node now.

Parameters:
token - The destination token to backtrack to.