com.waveset.workflow
Class Workflow

java.lang.Object
  extended bycom.waveset.workflow.Workflow

public class Workflow
extends java.lang.Object

The Waveset Workflow Engine.

The engine uses a number of objects defined in the com.waveset.object package, including WFProcess, WFCase, and WorkItem. These objects represent the externally visible state of the workflow. The workflow engine logic is implemented here, and mostly in the WorkflowExecutor class which is packaged as a TaskExecutor for background execution.

Now that most of the work is done in the executor, there's not much to do here. We still provide a few helper methods for the management of work items.


Field Summary
static java.lang.String code_id
           
 
Constructor Summary
Workflow(com.waveset.repository.Repository repo, ObjectCache cache, LighthouseContext context, com.waveset.security.authz.AccessPolicy accessPolicy, TaskManager taskman)
           
 
Method Summary
 WSUser checkForwarding(WSUser start)
          Given an administator, check for forwarding.
 WavesetResult checkinWorkItem(WorkItem item, java.lang.String user, boolean execute)
          After checkin of a WorkItem object, we need to cause the workflow task to be resumed.
 void checkinWorkItemOld(WorkItem item, java.lang.String user)
          NOTE: Old unreliable code that tried to use the "requested state" in the TaskInstance.
 void checkinWorkItemPre(WorkItem item)
          Called before checkin of a work item by the CheckinVisitor.
 void deleteTask(TaskInstance task, java.lang.String administrator)
          Delete a workflow task instance, and clean up any associated work items.
 WorkItem[] getWorkItems(Subject subject, java.lang.String owner)
          Return all items that are assigned to a particular owner.
 RepositoryResult listWorkItems(Subject subject, java.lang.String owner)
          Return all items that are assigned to a particular owner.
 void lockAssertively(Type type, java.lang.String id, java.lang.String user)
          Obtain a lock on the object, breaking someone else's if we have to.
 void setCompatibleOrganization(PersistentObject obj, WSUser user)
          Given an object and a user, make sure the object is in an organization controlled by that user.
 
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
Constructor Detail

Workflow

public Workflow(com.waveset.repository.Repository repo,
                ObjectCache cache,
                LighthouseContext context,
                com.waveset.security.authz.AccessPolicy accessPolicy,
                TaskManager taskman)
         throws WavesetException
Method Detail

checkinWorkItemPre

public void checkinWorkItemPre(WorkItem item)
                        throws WavesetException
Called before checkin of a work item by the CheckinVisitor. Check for administrator forwarding before storing this in the repository.

Throws:
WavesetException

setCompatibleOrganization

public void setCompatibleOrganization(PersistentObject obj,
                                      WSUser user)
                               throws WavesetException
Given an object and a user, make sure the object is in an organization controlled by that user. General enough to go somewhere else.

Throws:
WavesetException

checkForwarding

public WSUser checkForwarding(WSUser start)
                       throws WavesetException
Given an administator, check for forwarding. Also make sure the administrator we return has approval rights.

Sigh, some of the logic here is duplciated in NewValidator, but its a little different here since we're allowed to throw exceptions and we don't accumulate statud in a WavesetResult. Note that if we detect cycles, we always return the original user. In releases prior to v4 we would return the previous user in the cycle, but this would cause the owner to keep moving whenever CheckinVisitor was called.

Throws:
WavesetException

checkinWorkItem

public WavesetResult checkinWorkItem(WorkItem item,
                                     java.lang.String user,
                                     boolean execute)
                              throws WavesetException
After checkin of a WorkItem object, we need to cause the workflow task to be resumed. We do this by posting a task event, which the scheduler will eventually process.

It is important that this be done AFTER the WorkItem has been stored.

Added an option that will attempt to execute the workflow synchronously in this thread. Due to scheduler contention it is never guarenteed that we can run the task, but usually we can.

Throws:
WavesetException

checkinWorkItemOld

public void checkinWorkItemOld(WorkItem item,
                               java.lang.String user)
                        throws WavesetException
NOTE: Old unreliable code that tried to use the "requested state" in the TaskInstance. This should be deleted once we verify that the new event based workflow tickler works.

After checkin of a WorkItem object, we need to signal the associated TaskInstance that is runing the workflow case that it has something it needs to do.

It is important that this be done AFTER the WorkItem has been stored.

If the task is currently executing, we set a "request ready" flag so that when its done with its current cycle, it knows to enter a READY state rather than another WAITING state.

This all feels fragile and kludgey, think of a better way to store "events" to the workflow case that can be processed in a more reliable way. Sadly this will probably require periodic polling of the repository.

!! Need a new concept, "TaskEvent" that can be posted in a guarenteed way and checked by the scheduler.

Throws:
WavesetException

getWorkItems

public WorkItem[] getWorkItems(Subject subject,
                               java.lang.String owner)
                        throws WavesetException
Return all items that are assigned to a particular owner.

Note that "subject" is the user requesting the list, and "owner" is the user for whom we want tasks. They may be different. Also note that owner must already be prefixed if you are asking for non-administrator items.

Why do we pass in Subject? This was written when it was thought that work items may be have more complex storage than they do. Since this is just a normal attribute query, there is no requirement to use this method to query work items, its a minor convenience.

Throws:
WavesetException

listWorkItems

public RepositoryResult listWorkItems(Subject subject,
                                      java.lang.String owner)
                               throws WavesetException
Return all items that are assigned to a particular owner.

Note that "subject" is the user requesting the list, and "owner" is the user for whom we want tasks. They may be different.

Why do we pass in Subject? This was written when it was thought that work items may be have more complex storage than they do. Since this is just a normal attribute query, there is no requirement to use this method to query work items, its a minor convenience.

Throws:
WavesetException

deleteTask

public void deleteTask(TaskInstance task,
                       java.lang.String administrator)
                throws WavesetException
Delete a workflow task instance, and clean up any associated work items.

If we can't delete a work item, let the whole thing fail so we can retry this later.

Throws:
WavesetException

lockAssertively

public void lockAssertively(Type type,
                            java.lang.String id,
                            java.lang.String user)
                     throws WavesetException
Obtain a lock on the object, breaking someone else's if we have to.

Throws:
WavesetException