com.googlecode.sarasvati.impl
Class BaseEngine

java.lang.Object
  extended by com.googlecode.sarasvati.impl.BaseEngine
All Implemented Interfaces:
Engine
Direct Known Subclasses:
HibEngine, MemEngine

public abstract class BaseEngine
extends Object
implements Engine

Contains all the engine logic which is not backend specific.

Instances of BaseEngine have local state which is not thread-safe. Create a new Engine instance for each thread that needs one.

Author:
Paul Lorenz

Constructor Summary
BaseEngine(String applicationContext)
          Creates a new Engine with the given application context.
 
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 Engine.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.
 BaseEngine getParentEngine()
          If this engine was created to execute a nested process, it will remember the engine which created it.
 BaseEngine 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.
 
Methods inherited from class java.lang.Object
equals, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 
Methods inherited from interface com.googlecode.sarasvati.Engine
getFactory, getLoader, getLoader, getRepository
 

Constructor Detail

BaseEngine

public BaseEngine(String applicationContext)
Creates a new Engine with the given application context. Each application context has its own set of global listeners. This allows different applications running the same JVM to have different sets of listeners without having to add them at the process level.

Parameters:
applicationContext - The application context
Method Detail

startProcess

public GraphProcess startProcess(String graphName)
Description copied from interface: Engine
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.

Specified by:
startProcess in interface Engine
Parameters:
graphName - The name of the graph to execute.
Returns:
The new GraphProcess.

startProcess

public GraphProcess startProcess(Graph graph)
Description copied from interface: Engine
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.

Specified by:
startProcess in interface Engine
Parameters:
graph - The Graph to execute.
Returns:
A GraphProcess executing the given Graph.

startProcess

public void startProcess(GraphProcess process)
Description copied from interface: Engine
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.

Specified by:
startProcess in interface Engine
Parameters:
process - The process on which to begin execution.

cancelProcess

public void cancelProcess(GraphProcess process)
Description copied from interface: Engine
Cancels the given process. The process state is set to ProcessState.PendingCancel.

Specified by:
cancelProcess in interface Engine
Parameters:
process - The process to cancel

finalizeComplete

public void finalizeComplete(GraphProcess process)
Description copied from interface: Engine
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.

Specified by:
finalizeComplete in interface Engine
Parameters:
process - The process being completed.

finalizeCancel

public void finalizeCancel(GraphProcess process)
Description copied from interface: Engine
Called by the engine when a process is cancelled, via Engine.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

Specified by:
finalizeCancel in interface Engine
Parameters:
process - The process being canceled.

complete

public void complete(NodeToken token,
                     String arcName)
Description copied from interface: Engine
Continues execution of a process in a wait state. If a call to Node.execute(Engine, NodeToken) does not contain a call to Engine.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.

Specified by:
complete in interface Engine
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

public void completeAsynchronous(NodeToken token,
                                 String arcName)
Description copied from interface: Engine
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 Engine.executeQueuedArcTokens(GraphProcess).

Specified by:
completeAsynchronous in interface Engine
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

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

Specified by:
completeWithNewTokenSet in interface Engine
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

public void executeQueuedArcTokens(GraphProcess process)
Description copied from interface: Engine
If this process has any ArcTokens queued for execution, this method will execute them.

Specified by:
executeQueuedArcTokens in interface Engine
Parameters:
process - The process whose queued arc tokens to queue

setupScriptEnv

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

Specified by:
setupScriptEnv in interface Engine
Parameters:
env - The script environment to add variables to
token - The NodeToken which is currently being executed

addNodeType

public void addNodeType(String type,
                        Class<? extends Node> nodeClass)
Description copied from interface: Engine
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.

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

addGlobalCustomNodeType

public void addGlobalCustomNodeType(String type,
                                    Class<? extends CustomNode> nodeClass)
Description copied from interface: Engine
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.

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

backtrack

public void backtrack(NodeToken token)
Description copied from interface: Engine
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.

Specified by:
backtrack in interface Engine
Parameters:
token - The destination token to backtrack to.

newRubricEnv

public RubricEnv newRubricEnv(NodeToken token)
Description copied from interface: Engine
Creates a RubricEnv to be used to evaluate a Rubric statement defining a guard for the given NodeToken.

Specified by:
newRubricEnv in interface Engine
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

public JoinLangEnv newJoinLangEnv(ArcToken token)
Description copied from interface: Engine
Creates a JoinLangEnv to be used to evaluate a JoinLang statement controlling if the given ArcToken satisfies a join.

Specified by:
newJoinLangEnv in interface Engine
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

public GuardResult evaluateGuard(NodeToken token,
                                 String guard)
Description copied from interface: Engine
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.

Specified by:
evaluateGuard in interface Engine
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

public BaseEngine newEngine(boolean forNested)
Description copied from interface: Engine
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.

Specified by:
newEngine in interface Engine
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

public BaseEngine getParentEngine()
Description copied from interface: Engine
If this engine was created to execute a nested process, it will remember the engine which created it.

Specified by:
getParentEngine in interface Engine
Returns:
The parent engine.

addExecutionListener

public void addExecutionListener(Class<? extends ExecutionListener> listenerClass,
                                 ExecutionEventType... eventTypes)
Description copied from interface: Engine
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.

Specified by:
addExecutionListener in interface Engine
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.

removeExecutionListener

public void removeExecutionListener(Class<? extends ExecutionListener> listenerClass,
                                    ExecutionEventType... eventTypes)
Description copied from interface: Engine
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.

Specified by:
removeExecutionListener in interface Engine
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

addExecutionListener

public void addExecutionListener(GraphProcess process,
                                 Class<? extends ExecutionListener> listenerClass,
                                 ExecutionEventType... eventTypes)
Description copied from interface: Engine
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.

Specified by:
addExecutionListener in interface Engine
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

public void removeExecutionListener(GraphProcess process,
                                    Class<? extends ExecutionListener> listenerClass,
                                    ExecutionEventType... eventTypes)
Description copied from interface: Engine
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.

Specified by:
removeExecutionListener in interface Engine
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

fireEvent

public EventActions fireEvent(ExecutionEvent event)
Description copied from interface: Engine
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.

Specified by:
fireEvent in interface Engine
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.