com.waveset.object
Class WFCase

java.lang.Object
  extended bycom.waveset.util.AbstractXmlObject
      extended bycom.waveset.object.VariableScope
          extended bycom.waveset.object.WFCase
All Implemented Interfaces:
Extension, javax.naming.Referenceable, VariableResolver, XmlObject

public class WFCase
extends VariableScope
implements Extension

A class used to represent extended state for TaskInstance objects assocated with workflow processes.

A case can be considered an instance of a Process, it maintains runtime state as the process is executed, and holds results after the process has completed.

The case maintains a list of "steps" which hold the state of one execution of an Activity defined in the process. You can think of a Step as an instance of an Activity. Workflow literature usually refers to these as "Activity Instances" but that turns out to be very awkward to type, so I chose Step. So there.

Earlier implementations called these objects "Tasks" but the name was changed to avoid confusion with the new background task management system.

Each step may contain one or more Result objects which hold the results of the Actions defined in the Activity. If an action used an "iteration", the result may be an aggregate result, which points to other Result objects.

WFCase and its inner classes extend VariableScope to maintain a hierarchy of variable bindings. VariableScope extends AbstractXmlObject so we can also serizlize oursleves.


Nested Class Summary
static class WFCase.Result
          A class used to maintain information about the results of an execution of an Actions within an Activity.
static class WFCase.Step
          A class used to represent the execution state of an Activity from the process definition.
 
Field Summary
static java.lang.String code_id
           
static java.lang.String ELEMENT
          Our XML element.
 
Fields inherited from class com.waveset.util.AbstractXmlObject
_trace
 
Constructor Summary
WFCase()
          No-arg constructor.
WFCase(org.w3c.dom.Element e)
          Construct a case from an XML element.
 
Method Summary
 void addAutoTransition(java.lang.String to)
           
 void addInvalidWorkItem(java.lang.String id)
           
 void addNewWorkItem(WorkItem item)
           
 WFCase.Step addStep(WFProcess.Activity activity)
          Add a new step for a process activity.
 WFCase findCase(java.lang.String name)
          Look for a case with the given name.
 WFCase.Step findJoinStep(WFProcess.Activity activity)
          Given an Activity, find a corresponding Step.
 WSAttribute getAttributeValues(java.lang.String attrName)
          Add any attribute values that this object may have for the specified attribute.
 java.lang.String getElementName()
          Get the XML element name.
 long getEndDate()
           
 int getFirstStep()
          Get the index of the first active step.
 java.util.List getInvalidWorkItems()
           
 WFCase.Result getItemResult(java.lang.String itemId)
          Locate the Result object that tracks the state of a particular work item.
 java.lang.String getName()
          Get the case name.
 java.util.List getNewWorkItems()
           
 java.util.Date getNextTimeout()
          Walk over the case returning the next timeout event.
 java.lang.Object getOwner()
          Get the owning object.
 WFCase.Result getParent()
          Get the parent Result object for subcases.
 VariableScope getParentScope()
          Return the parent scope.
 WFProcess getProcess()
          Get the process definition.
 WFProcess getProcess(LighthouseContext context, ObjectRef ref, boolean raiseError)
          Attempt to fetch an external process given an object reference.
 ObjectRef getProcessRef()
          Get the reference to the external process definition.
 WavesetResult getResult()
           
 WFCase getRootCase()
          Get the root case.
 long getStartDate()
           
 WFCase.Step getStartStep()
          Gets the start step for this case.
 WFCase.Step getStep(int index)
          Get a step given its index.
 int getStepCount()
          Get the number of steps in the process.
 java.util.ArrayList getSteps()
          Get the step list.
 java.lang.String getTitle()
          Get the case title.
 java.util.List getWorkItems()
          Walk over the case returning a list of all WFCase.Result objects contained within that have corresponding WorkItem objects in the repository.
 boolean isAutoTransitioned(java.lang.String name)
          Return true if we've taken an automatic transition to the named activity.
 boolean isComplete()
          Tests the case completion flag.
 boolean isPending()
          Test the pending status of the case.
 boolean isTerminated()
           
 boolean isVariableDefined(java.lang.String name)
          Test to see if the variable is defined in this scope.
 void listQueryableAttributes(java.util.List qattrs)
          Add any defined attributes that this type of PersistentObject may expose as queryable attributes (regardless of whether this object has a value for each).
 void listSummaryAttributes(java.util.List sattrs)
          Add any defined attributes that this type of PersistentObject may expose as summary attributes (regardless of whether this object has a value for each).
 void parseXml(org.w3c.dom.Element e)
          Parse the XML representation of the case.
 void removeNewWorkItem(WorkItem item)
           
 void resolveProcessDefinitions(LighthouseContext context)
          Recursivly walk over the active cases resolving the references to their process definitons.
 void setComplete(boolean b)
          Set the case completion flag.
 void setEndDate()
           
 void setFirstStep(int index)
          Set the index of the first active activity.
 void setInvalidWorkItems(java.util.List items)
           
 void setName(java.lang.String name)
          Set the case name.
 void setNewWorkItems(java.util.List items)
           
 void setOwner(java.lang.Object o)
          Allows the extension to keep a back pointer to its container.
 void setParent(WFCase.Result res)
          Set the parent Result object for subcases.
 void setProcess(WFProcess p)
          Set the process definition.
 void setProcessRef(ObjectRef ref)
          Set the external process definition reference.
 void setResult(WavesetResult r)
           
 void setStartDate()
           
 void setTerminated(boolean b)
           
 void setTitle(java.lang.String s)
           
 void toXml(java.lang.StringBuffer b, int indent)
          Emit the XML representation of the case.
 
Methods inherited from class com.waveset.object.VariableScope
assimilateLocalVariables, clearLocalVariables, expandVariables, getLocalVariable, getLocalVariables, getVariable, getVariables, getVariables, pruneGenericObjects, removeLocalVariable, resolveVariable, setLocalVariable, setLocalVariables, setVariable
 
Methods inherited from class com.waveset.util.AbstractXmlObject
addXmlHeader, cloneObject, dump, dumpFile, getReference, println, setTrace, toIdentityString, toVerboseString, toVerboseString, toXml, toXml, toXml
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

code_id

public static final java.lang.String code_id
See Also:
Constant Field Values

ELEMENT

public static final java.lang.String ELEMENT
Our XML element.

See Also:
Constant Field Values
Constructor Detail

WFCase

public WFCase()
No-arg constructor. This normally shouldn't be used, though XmlObject wants to have one of these.


WFCase

public WFCase(org.w3c.dom.Element e)
       throws WavesetException
Construct a case from an XML element. This is required by XmlObject.

Method Detail

setResult

public void setResult(WavesetResult r)

setTerminated

public void setTerminated(boolean b)

setInvalidWorkItems

public void setInvalidWorkItems(java.util.List items)

addInvalidWorkItem

public void addInvalidWorkItem(java.lang.String id)

setNewWorkItems

public void setNewWorkItems(java.util.List items)

addNewWorkItem

public void addNewWorkItem(WorkItem item)

removeNewWorkItem

public void removeNewWorkItem(WorkItem item)

addAutoTransition

public void addAutoTransition(java.lang.String to)

setOwner

public void setOwner(java.lang.Object o)
Description copied from interface: Extension
Allows the extension to keep a back pointer to its container.

Specified by:
setOwner in interface Extension

listQueryableAttributes

public void listQueryableAttributes(java.util.List qattrs)
Add any defined attributes that this type of PersistentObject may expose as queryable attributes (regardless of whether this object has a value for each).

Specified by:
listQueryableAttributes in interface Extension

listSummaryAttributes

public void listSummaryAttributes(java.util.List sattrs)
Add any defined attributes that this type of PersistentObject may expose as summary attributes (regardless of whether this object has a value for each).

Specified by:
listSummaryAttributes in interface Extension

getAttributeValues

public WSAttribute getAttributeValues(java.lang.String attrName)
Add any attribute values that this object may have for the specified attribute.

Specified by:
getAttributeValues in interface Extension
Returns:
any attribute values that the extension may have for the specified attribute.

getElementName

public java.lang.String getElementName()
Get the XML element name.

Specified by:
getElementName in interface XmlObject
Specified by:
getElementName in class AbstractXmlObject

getOwner

public java.lang.Object getOwner()
Get the owning object.

Specified by:
getOwner in interface Extension

getProcessRef

public ObjectRef getProcessRef()
Get the reference to the external process definition. This will be null if we're associated with a local process.


setProcessRef

public void setProcessRef(ObjectRef ref)
Set the external process definition reference. This should only be called by the WorkflowEngine when it creates a new case.


getProcess

public WFProcess getProcess()
Get the process definition. This is not serialized, it must be set at runtime by the workflow engine.


setProcess

public void setProcess(WFProcess p)
Set the process definition. This should be set by the workflow engine soon after construction in order for the process sensitive accessors to work properly.


getParent

public WFCase.Result getParent()
Get the parent Result object for subcases.


setParent

public void setParent(WFCase.Result res)
Set the parent Result object for subcases.


getName

public java.lang.String getName()
Get the case name. Should we try to derive one if it doesn't exist?


setName

public void setName(java.lang.String name)
Set the case name.


getTitle

public java.lang.String getTitle()
Get the case title.


setTitle

public void setTitle(java.lang.String s)

getRootCase

public WFCase getRootCase()
                   throws InternalError
Get the root case. If we're a nested subcase, walk backward until we find the root.

Throws:
InternalError

isPending

public boolean isPending()
Test the pending status of the case. This is true if no steps have been executed.


isComplete

public boolean isComplete()
Tests the case completion flag.


setComplete

public void setComplete(boolean b)
Set the case completion flag.


isTerminated

public boolean isTerminated()

getResult

public WavesetResult getResult()

getInvalidWorkItems

public java.util.List getInvalidWorkItems()

getNewWorkItems

public java.util.List getNewWorkItems()

findCase

public WFCase findCase(java.lang.String name)
Look for a case with the given name. Intended primarily for use in testing to locate expected subcases within a complex case. Note that this will return completed cases, we do them in reverse order to ensure that active cases have priority.


isAutoTransitioned

public boolean isAutoTransitioned(java.lang.String name)
Return true if we've taken an automatic transition to the named activity.


resolveProcessDefinitions

public void resolveProcessDefinitions(LighthouseContext context)
                               throws WavesetException
Recursivly walk over the active cases resolving the references to their process definitons. This must be done early in the execution cycle as most things assume they are able to get WFProcess objects from their WFCase counterparts. This is used both by the WorkflowExecutor at workflow runtime, and by ReportFormatter when generating reports from the current case state.

Throws:
WavesetException

getProcess

public WFProcess getProcess(LighthouseContext context,
                            ObjectRef ref,
                            boolean raiseError)
                     throws WavesetException
Attempt to fetch an external process given an object reference. Since we may just be probing, don't throw an exception. Return the name of the Configuration or TaskDefinition object in the name of the WFProcess. In theory these could be different but its confusing if you do that, and the Config editor will force them to be the same. Here it provides a convenient way to return a refreshed name in case the definition was renamed.

Throws:
WavesetException

getParentScope

public VariableScope getParentScope()
Return the parent scope.

Specified by:
getParentScope in class VariableScope

isVariableDefined

public boolean isVariableDefined(java.lang.String name)
                          throws WavesetException
Test to see if the variable is defined in this scope.

Specified by:
isVariableDefined in class VariableScope
Throws:
WavesetException

getSteps

public java.util.ArrayList getSteps()
Get the step list. Should be used only for iteration, don't modify this. Would be better to expose an iterator object.


getFirstStep

public int getFirstStep()
Get the index of the first active step. This is just stored here as a convenience for the executor, it is a transient runtime field.


setFirstStep

public void setFirstStep(int index)
Set the index of the first active activity. This is set by the WorkflowExecutor as it changes step states.


getStepCount

public int getStepCount()
Get the number of steps in the process.


getStep

public WFCase.Step getStep(int index)
Get a step given its index. Convenience method that avoids casts using ArrayList.


getStartStep

public WFCase.Step getStartStep()
                         throws WavesetException
Gets the start step for this case. UPDATE: With the introduction of auto-start, we may no longer have a step whose activity is named "start" and we don't want to repeat the calcuation here. It is safe to assume that the first step in any case is the start step.

Throws:
WavesetException

addStep

public WFCase.Step addStep(WFProcess.Activity activity)
                    throws WavesetException
Add a new step for a process activity. We'll trust the executor that the given activity is in fact one from the Process referenced in the _process field.

Throws:
WavesetException

getItemResult

public WFCase.Result getItemResult(java.lang.String itemId)
Locate the Result object that tracks the state of a particular work item.

This got a lot more complicated now that we support subprocesses. Lacking any nice search structure, we have to traverse the whole damn thing looking for Result objects that have a reference to the repository ID of this work item. For small cases this shouldn't be that expensive, but we obviously should consider a faster way of storing this association.


findJoinStep

public WFCase.Step findJoinStep(WFProcess.Activity activity)
Given an Activity, find a corresponding Step. This should only be used to locate steps with AND-Joins since we may have already allocated one of these at the time we transition from one of the feeds.

We just do a linear search from the base of the active step list. This isn't terribly effecient, but the join step should trickle down toward the bottom of the list.

Here is is the crux of the "case thread" problem. We could support multiple threads through the process by dynamically allocating tasks as we do now, keeping a thread counter on the task, and "spawning" another thread every time we take an AND SPLIT. Each Join task would then have to be referenced by both activity index and thread counter.

Need to study the WfmC spec on case threads.


getWorkItems

public java.util.List getWorkItems()
Walk over the case returning a list of all WFCase.Result objects contained within that have corresponding WorkItem objects in the repository.

Added for the report generator, may have other uses.


getNextTimeout

public java.util.Date getNextTimeout()
Walk over the case returning the next timeout event. Be careful to check completion status, we can prematurely terminate a thread by setting the completion status, but we don't always traverse the step history clearing out old timeouts.


setStartDate

public void setStartDate()

getStartDate

public long getStartDate()

setEndDate

public void setEndDate()

getEndDate

public long getEndDate()

toXml

public void toXml(java.lang.StringBuffer b,
                  int indent)
Emit the XML representation of the case. This is the signature required by XmlObject.

Specified by:
toXml in interface XmlObject
Specified by:
toXml in class AbstractXmlObject

parseXml

public void parseXml(org.w3c.dom.Element e)
              throws WavesetException
Parse the XML representation of the case.

Throws:
WavesetException