|
|
|
|
@ -44,8 +44,8 @@ import java.util.Map;
|
|
|
|
|
import org.apache.log4j.Logger;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Represents a process instance that is assigned to a particular
|
|
|
|
|
* process that is associated with some object.
|
|
|
|
|
* Represents a process instance that is assigned to a particular process that
|
|
|
|
|
* is associated with some object.
|
|
|
|
|
*
|
|
|
|
|
* @author Khy Huang
|
|
|
|
|
* @author Stefan Deusch
|
|
|
|
|
@ -53,22 +53,19 @@ import org.apache.log4j.Logger;
|
|
|
|
|
* @author Karl Goldstein
|
|
|
|
|
* @version $Id: Workflow.java 1278 2006-07-27 09:09:51Z cgyg9330 $
|
|
|
|
|
*
|
|
|
|
|
**/
|
|
|
|
|
*
|
|
|
|
|
*/
|
|
|
|
|
public class Workflow extends Task {
|
|
|
|
|
|
|
|
|
|
public static final String BASE_DATA_OBJECT_TYPE =
|
|
|
|
|
"com.arsdigita.workflow.simple.Workflow";
|
|
|
|
|
|
|
|
|
|
private static final Logger s_log = Logger.getLogger(Workflow.class);
|
|
|
|
|
|
|
|
|
|
private OID m_ACSObjectOID = null;
|
|
|
|
|
public static final String ACS_OBJECT = "object";
|
|
|
|
|
private static final String PROCESS_STATE = "processState";
|
|
|
|
|
private static final String WF_TASKS = "wfTasks";
|
|
|
|
|
public static final String TASK_WORKFLOW = "taskWf";
|
|
|
|
|
|
|
|
|
|
private static final String PROCESS_DEF_ID = "processDefinitionID";
|
|
|
|
|
|
|
|
|
|
// class variables, enums of constants
|
|
|
|
|
public final static int NONE = -1;
|
|
|
|
|
public final static int STARTED = 0;
|
|
|
|
|
@ -77,39 +74,42 @@ public class Workflow extends Task {
|
|
|
|
|
public final static int INIT = 3;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Creates a new workflow process. The properties of this object
|
|
|
|
|
* are not made persistent until the <code>save</code> method is called.
|
|
|
|
|
* Creates a new workflow process. The properties of this object are not
|
|
|
|
|
* made persistent until the
|
|
|
|
|
* <code>save</code> method is called.
|
|
|
|
|
*
|
|
|
|
|
* @param label the label
|
|
|
|
|
* @param description the description
|
|
|
|
|
**/
|
|
|
|
|
*
|
|
|
|
|
*/
|
|
|
|
|
public Workflow(String label, String description) {
|
|
|
|
|
super(BASE_DATA_OBJECT_TYPE);
|
|
|
|
|
|
|
|
|
|
initAttributes(label,description);
|
|
|
|
|
initAttributes(label, description);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Creates a new workflow process with the properties
|
|
|
|
|
* <code>label</code> and <code>description</code> set to null.
|
|
|
|
|
* Properties of this object are not made persistent until the
|
|
|
|
|
* <code>save</code> method is called. If save() is called
|
|
|
|
|
* without setting these properties, an IllegalArgumentException
|
|
|
|
|
* will be thrown.
|
|
|
|
|
**/
|
|
|
|
|
* <code>label</code> and
|
|
|
|
|
* <code>description</code> set to null. Properties of this object are not
|
|
|
|
|
* made persistent until the
|
|
|
|
|
* <code>save</code> method is called. If save() is called without setting
|
|
|
|
|
* these properties, an IllegalArgumentException will be thrown.
|
|
|
|
|
*
|
|
|
|
|
*/
|
|
|
|
|
public Workflow() {
|
|
|
|
|
super(BASE_DATA_OBJECT_TYPE);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Restores a workflow process from a task data object.
|
|
|
|
|
*
|
|
|
|
|
* @param workflowDataObject
|
|
|
|
|
**/
|
|
|
|
|
*
|
|
|
|
|
*/
|
|
|
|
|
public Workflow(DataObject workflowDataObject) {
|
|
|
|
|
super(workflowDataObject);
|
|
|
|
|
DataObject object = (DataObject)get(ACS_OBJECT);
|
|
|
|
|
DataObject object = (DataObject) get(ACS_OBJECT);
|
|
|
|
|
if (object != null) {
|
|
|
|
|
m_ACSObjectOID = object.getOID();
|
|
|
|
|
}
|
|
|
|
|
@ -120,7 +120,8 @@ public class Workflow extends Task {
|
|
|
|
|
*
|
|
|
|
|
* @param type the object type
|
|
|
|
|
* @see com.arsdigita.persistence.metadata.ObjectType
|
|
|
|
|
**/
|
|
|
|
|
*
|
|
|
|
|
*/
|
|
|
|
|
protected Workflow(ObjectType type) {
|
|
|
|
|
super(type);
|
|
|
|
|
}
|
|
|
|
|
@ -130,7 +131,8 @@ public class Workflow extends Task {
|
|
|
|
|
*
|
|
|
|
|
* @param typeName the type name
|
|
|
|
|
*
|
|
|
|
|
**/
|
|
|
|
|
*
|
|
|
|
|
*/
|
|
|
|
|
protected Workflow(String typeName) {
|
|
|
|
|
super(typeName);
|
|
|
|
|
}
|
|
|
|
|
@ -141,7 +143,8 @@ public class Workflow extends Task {
|
|
|
|
|
* @param oid the OID
|
|
|
|
|
* @see com.arsdigita.persistence.OID
|
|
|
|
|
*
|
|
|
|
|
**/
|
|
|
|
|
*
|
|
|
|
|
*/
|
|
|
|
|
public Workflow(OID oid) throws DataObjectNotFoundException {
|
|
|
|
|
super(oid);
|
|
|
|
|
}
|
|
|
|
|
@ -149,23 +152,25 @@ public class Workflow extends Task {
|
|
|
|
|
/**
|
|
|
|
|
* Restores a workflow process using a BigDecimal ID.
|
|
|
|
|
*
|
|
|
|
|
* @param id the BigDecimal ID of this object. An OID will be
|
|
|
|
|
* created implicitly with the BASE_DATA_OBJECT_TYPE constant
|
|
|
|
|
* specified in this file.
|
|
|
|
|
**/
|
|
|
|
|
* @param id the BigDecimal ID of this object. An OID will be created
|
|
|
|
|
* implicitly with the BASE_DATA_OBJECT_TYPE constant specified in this
|
|
|
|
|
* file.
|
|
|
|
|
*
|
|
|
|
|
*/
|
|
|
|
|
public Workflow(BigDecimal id) throws DataObjectNotFoundException {
|
|
|
|
|
this(new OID(BASE_DATA_OBJECT_TYPE, id));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Initializes the internal state depending on whether
|
|
|
|
|
* this is a new or a restored instance.
|
|
|
|
|
**/
|
|
|
|
|
* Initializes the internal state depending on whether this is a new or a
|
|
|
|
|
* restored instance.
|
|
|
|
|
*
|
|
|
|
|
*/
|
|
|
|
|
protected void initialize() {
|
|
|
|
|
super.initialize();
|
|
|
|
|
|
|
|
|
|
if (!isNew()) {
|
|
|
|
|
DataObject object = (DataObject)get(ACS_OBJECT);
|
|
|
|
|
DataObject object = (DataObject) get(ACS_OBJECT);
|
|
|
|
|
if (object != null) {
|
|
|
|
|
m_ACSObjectOID = object.getOID();
|
|
|
|
|
}
|
|
|
|
|
@ -184,13 +189,13 @@ public class Workflow extends Task {
|
|
|
|
|
return BASE_DATA_OBJECT_TYPE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Adds a task to this process. (persistent operation)
|
|
|
|
|
*
|
|
|
|
|
* @param task the task to add to this process
|
|
|
|
|
* @see Task
|
|
|
|
|
**/
|
|
|
|
|
*
|
|
|
|
|
*/
|
|
|
|
|
public void addTask(Task task) {
|
|
|
|
|
task.setParent(this);
|
|
|
|
|
if (getProcessState() == STARTED) {
|
|
|
|
|
@ -201,20 +206,21 @@ public class Workflow extends Task {
|
|
|
|
|
updateState();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Deletes a task. (perisistent operation).
|
|
|
|
|
*
|
|
|
|
|
* @param task to be removed
|
|
|
|
|
**/
|
|
|
|
|
*
|
|
|
|
|
*/
|
|
|
|
|
public void removeTask(Task task) {
|
|
|
|
|
remove(WF_TASKS,task);
|
|
|
|
|
remove(WF_TASKS, task);
|
|
|
|
|
//task.delete()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Removes all tasks from this workflow. (persistent operation)
|
|
|
|
|
**/
|
|
|
|
|
*
|
|
|
|
|
*/
|
|
|
|
|
public void removeAllTasks() {
|
|
|
|
|
DataAssociation da = getTaskAssociation();
|
|
|
|
|
da.clear();
|
|
|
|
|
@ -230,7 +236,8 @@ public class Workflow extends Task {
|
|
|
|
|
*
|
|
|
|
|
* @param user the user
|
|
|
|
|
*
|
|
|
|
|
**/
|
|
|
|
|
*
|
|
|
|
|
*/
|
|
|
|
|
public void save(User user) throws ProcessException {
|
|
|
|
|
//add logging information
|
|
|
|
|
save();
|
|
|
|
|
@ -240,31 +247,33 @@ public class Workflow extends Task {
|
|
|
|
|
* Returns the number of task in this process.
|
|
|
|
|
*
|
|
|
|
|
* @return the numnber of tasks in the workflow
|
|
|
|
|
**/
|
|
|
|
|
*
|
|
|
|
|
*/
|
|
|
|
|
public int getTaskCount() {
|
|
|
|
|
return (new Long(getTaskAssociation().cursor().size())).intValue();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// ---------------- START: state methods --------------------------
|
|
|
|
|
/**
|
|
|
|
|
* Stops the process. (persistent operation)
|
|
|
|
|
*
|
|
|
|
|
* @param user the user that stopped the process
|
|
|
|
|
*
|
|
|
|
|
**/
|
|
|
|
|
*
|
|
|
|
|
*/
|
|
|
|
|
public void stop(User user) {
|
|
|
|
|
setProcessState(STOPPED);
|
|
|
|
|
save();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Starts the process. This method marks all the tasks as
|
|
|
|
|
* active when called the first time. (persistent operation)
|
|
|
|
|
* Starts the process. This method marks all the tasks as active when called
|
|
|
|
|
* the first time. (persistent operation)
|
|
|
|
|
*
|
|
|
|
|
* @param user the user that starts the process
|
|
|
|
|
*
|
|
|
|
|
**/
|
|
|
|
|
*
|
|
|
|
|
*/
|
|
|
|
|
public void start(User user) {
|
|
|
|
|
|
|
|
|
|
int processState = getProcessState();
|
|
|
|
|
@ -280,11 +289,12 @@ public class Workflow extends Task {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Gets the process spinning. This method also
|
|
|
|
|
* marks all the tasks as active.
|
|
|
|
|
* Gets the process spinning. This method also marks all the tasks as
|
|
|
|
|
* active.
|
|
|
|
|
*
|
|
|
|
|
*
|
|
|
|
|
**/
|
|
|
|
|
*
|
|
|
|
|
*/
|
|
|
|
|
protected void startInternal() {
|
|
|
|
|
|
|
|
|
|
TaskCollection tasks = getTaskCollection();
|
|
|
|
|
@ -324,18 +334,19 @@ public class Workflow extends Task {
|
|
|
|
|
*
|
|
|
|
|
*/
|
|
|
|
|
public int getProcessState() {
|
|
|
|
|
return getProcessStateInt((String)get(PROCESS_STATE));
|
|
|
|
|
return getProcessStateInt((String) get(PROCESS_STATE));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Internal method to
|
|
|
|
|
* set the state from the DB, 'stopped', 'started','deleted', 'init' are allowed
|
|
|
|
|
* Internal method to set the state from the DB, 'stopped',
|
|
|
|
|
* 'started','deleted', 'init' are allowed
|
|
|
|
|
*
|
|
|
|
|
* @param state the process state
|
|
|
|
|
*
|
|
|
|
|
**/
|
|
|
|
|
*
|
|
|
|
|
*/
|
|
|
|
|
private void setProcessState(int state) {
|
|
|
|
|
set(PROCESS_STATE,getProcessStateStr(state));
|
|
|
|
|
set(PROCESS_STATE, getProcessStateStr(state));
|
|
|
|
|
if (!isNew()) {
|
|
|
|
|
save();
|
|
|
|
|
}
|
|
|
|
|
@ -345,7 +356,8 @@ public class Workflow extends Task {
|
|
|
|
|
* Sets the Object that this workflow is applied to.
|
|
|
|
|
*
|
|
|
|
|
* @param o the object to which to apply this workflow.
|
|
|
|
|
**/
|
|
|
|
|
*
|
|
|
|
|
*/
|
|
|
|
|
public void setObject(ACSObject o) {
|
|
|
|
|
m_ACSObjectOID = o.getOID();
|
|
|
|
|
set(ACS_OBJECT, o);
|
|
|
|
|
@ -354,16 +366,15 @@ public class Workflow extends Task {
|
|
|
|
|
/**
|
|
|
|
|
* Set the object id
|
|
|
|
|
*
|
|
|
|
|
**/
|
|
|
|
|
*
|
|
|
|
|
*/
|
|
|
|
|
public void setObjectID(BigDecimal id) {
|
|
|
|
|
m_ACSObjectOID = new OID(ACSObject.BASE_DATA_OBJECT_TYPE,id);
|
|
|
|
|
m_ACSObjectOID = new OID(ACSObject.BASE_DATA_OBJECT_TYPE, id);
|
|
|
|
|
try {
|
|
|
|
|
set(ACS_OBJECT, DomainObjectFactory.newInstance
|
|
|
|
|
(m_ACSObjectOID));
|
|
|
|
|
set(ACS_OBJECT, DomainObjectFactory.newInstance(m_ACSObjectOID));
|
|
|
|
|
} catch (DataObjectNotFoundException e) {
|
|
|
|
|
s_log.error("unable to locate the ID for the workflow");
|
|
|
|
|
throw new UncheckedWrapperException
|
|
|
|
|
("Unable to locate object corresponding to ID " + id, e);
|
|
|
|
|
throw new UncheckedWrapperException("Unable to locate object corresponding to ID " + id, e);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@ -371,7 +382,8 @@ public class Workflow extends Task {
|
|
|
|
|
* Helper method that converts the state string in persistence to
|
|
|
|
|
* WorkflowProcess object state ids
|
|
|
|
|
*
|
|
|
|
|
**/
|
|
|
|
|
*
|
|
|
|
|
*/
|
|
|
|
|
private int getProcessStateInt(String state) {
|
|
|
|
|
if (state.equals("stopped")) {
|
|
|
|
|
return STOPPED;
|
|
|
|
|
@ -386,45 +398,50 @@ public class Workflow extends Task {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Helper method that converts the state ids in WorkflowProcess object
|
|
|
|
|
* to state string in persistence
|
|
|
|
|
* Helper method that converts the state ids in WorkflowProcess object to
|
|
|
|
|
* state string in persistence
|
|
|
|
|
*
|
|
|
|
|
* @return the persistence state string
|
|
|
|
|
*
|
|
|
|
|
**/
|
|
|
|
|
*
|
|
|
|
|
*/
|
|
|
|
|
private String getProcessStateStr(int state) {
|
|
|
|
|
switch (state) {
|
|
|
|
|
case STARTED: return "started";
|
|
|
|
|
case STOPPED: return "stopped";
|
|
|
|
|
case DELETED: return "deleted";
|
|
|
|
|
case INIT: return "init";
|
|
|
|
|
case NONE: return "none";
|
|
|
|
|
case STARTED:
|
|
|
|
|
return "started";
|
|
|
|
|
case STOPPED:
|
|
|
|
|
return "stopped";
|
|
|
|
|
case DELETED:
|
|
|
|
|
return "deleted";
|
|
|
|
|
case INIT:
|
|
|
|
|
return "init";
|
|
|
|
|
case NONE:
|
|
|
|
|
return "none";
|
|
|
|
|
}
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
// ---------------- END: state methods -------------------
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Returns an iterator for the tasks in this process.
|
|
|
|
|
*
|
|
|
|
|
* @return the list of all tasks.
|
|
|
|
|
*
|
|
|
|
|
**/
|
|
|
|
|
*
|
|
|
|
|
*/
|
|
|
|
|
public Iterator getTasks() {
|
|
|
|
|
return new DomainCollectionIterator(getTaskCollection());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* The data association for the tasks in workflow process.
|
|
|
|
|
*
|
|
|
|
|
* @return the data collection
|
|
|
|
|
*
|
|
|
|
|
**/
|
|
|
|
|
*
|
|
|
|
|
*/
|
|
|
|
|
private DataAssociation getTaskAssociation() {
|
|
|
|
|
return (DataAssociation)get(WF_TASKS);
|
|
|
|
|
return (DataAssociation) get(WF_TASKS);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
@ -432,12 +449,13 @@ public class Workflow extends Task {
|
|
|
|
|
*
|
|
|
|
|
* @return an interator over enabled tasks.
|
|
|
|
|
*
|
|
|
|
|
**/
|
|
|
|
|
*
|
|
|
|
|
*/
|
|
|
|
|
public Iterator getEnabledTasks() {
|
|
|
|
|
if (getProcessState() == DELETED || getProcessState() == STOPPED) {
|
|
|
|
|
if ( s_log.isDebugEnabled() ) {
|
|
|
|
|
s_log.debug("No enabled tasks. Process state is " +
|
|
|
|
|
getProcessState());
|
|
|
|
|
if (s_log.isDebugEnabled()) {
|
|
|
|
|
s_log.debug("No enabled tasks. Process state is "
|
|
|
|
|
+ getProcessState());
|
|
|
|
|
}
|
|
|
|
|
return Collections.EMPTY_LIST.iterator();
|
|
|
|
|
}
|
|
|
|
|
@ -448,7 +466,7 @@ public class Workflow extends Task {
|
|
|
|
|
FilterFactory factory = tasks.getFilterFactory();
|
|
|
|
|
CompoundFilter filter = factory.and();
|
|
|
|
|
filter.addFilter(factory.equals(Task.TASK_STATE, Task.getStateString(Task.ENABLED)));
|
|
|
|
|
filter.addFilter(factory.equals(Task.IS_ACTIVE, "1" ));
|
|
|
|
|
filter.addFilter(factory.equals(Task.IS_ACTIVE, "1"));
|
|
|
|
|
tasks.addFilter(filter);
|
|
|
|
|
|
|
|
|
|
LinkedList enabledTasks = new LinkedList();
|
|
|
|
|
@ -468,7 +486,8 @@ public class Workflow extends Task {
|
|
|
|
|
*
|
|
|
|
|
* @return an iterator over finished tasks.
|
|
|
|
|
*
|
|
|
|
|
**/
|
|
|
|
|
*
|
|
|
|
|
*/
|
|
|
|
|
public Iterator getFinishedTasks() {
|
|
|
|
|
TaskCollection tasksCollection = getTaskCollection();
|
|
|
|
|
Filter filter = tasksCollection.addFilter("taskState = :taskState");
|
|
|
|
|
@ -478,13 +497,14 @@ public class Workflow extends Task {
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @return an iterator over all overdue tasks in the process.
|
|
|
|
|
**/
|
|
|
|
|
*
|
|
|
|
|
*/
|
|
|
|
|
public Iterator getOverdueTasks() {
|
|
|
|
|
HashSet tasksSet = new HashSet();
|
|
|
|
|
TaskCollection tasksCollection = getTaskCollection();
|
|
|
|
|
while ( tasksCollection.next() ) {
|
|
|
|
|
while (tasksCollection.next()) {
|
|
|
|
|
Task task = (Task) tasksCollection.getDomainObject();
|
|
|
|
|
if ( task instanceof UserTask && ((UserTask) task).isOverdue() ) {
|
|
|
|
|
if (task instanceof UserTask && ((UserTask) task).isOverdue()) {
|
|
|
|
|
tasksSet.add(task);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
@ -499,14 +519,16 @@ public class Workflow extends Task {
|
|
|
|
|
*
|
|
|
|
|
* @return the ACS object that this process is based on.
|
|
|
|
|
*
|
|
|
|
|
**/
|
|
|
|
|
*
|
|
|
|
|
*/
|
|
|
|
|
public OID getObjectOID() {
|
|
|
|
|
return m_ACSObjectOID;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Get the ACSObject this Workflow is associated with.
|
|
|
|
|
**/
|
|
|
|
|
*
|
|
|
|
|
*/
|
|
|
|
|
public ACSObject getObject() {
|
|
|
|
|
OID objOID = getObjectOID();
|
|
|
|
|
if (objOID == null) {
|
|
|
|
|
@ -516,36 +538,38 @@ public class Workflow extends Task {
|
|
|
|
|
return (ACSObject) DomainObjectFactory.
|
|
|
|
|
newInstance(getObjectOID());
|
|
|
|
|
} catch (DataObjectNotFoundException de) {
|
|
|
|
|
throw new UncheckedWrapperException("Could not load object with OID " +
|
|
|
|
|
getObjectOID(),
|
|
|
|
|
throw new UncheckedWrapperException("Could not load object with OID "
|
|
|
|
|
+ getObjectOID(),
|
|
|
|
|
de);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Removes a task from the underlying
|
|
|
|
|
* workflow process definition.
|
|
|
|
|
* Removes a task from the underlying workflow process definition.
|
|
|
|
|
*
|
|
|
|
|
* @param task the task to be removed
|
|
|
|
|
* @param dependentList the task definitions that are dependent on
|
|
|
|
|
* the passed in task definition
|
|
|
|
|
* @param dependentList the task definitions that are dependent on the
|
|
|
|
|
* passed in task definition
|
|
|
|
|
*
|
|
|
|
|
**/
|
|
|
|
|
*
|
|
|
|
|
*/
|
|
|
|
|
public void removeTask(Task task, Iterator dependentList) {
|
|
|
|
|
Task dependentTask;
|
|
|
|
|
while (dependentList.hasNext()) {
|
|
|
|
|
dependentTask = (Task)dependentList.next();
|
|
|
|
|
dependentTask = (Task) dependentList.next();
|
|
|
|
|
dependentTask.removeFinishedListener(task);
|
|
|
|
|
//dependentTask.updateState();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Override the update method, workflow is finished if all its task are completed
|
|
|
|
|
* Override the update method, workflow is finished if all its task are
|
|
|
|
|
* completed
|
|
|
|
|
*
|
|
|
|
|
*
|
|
|
|
|
**/
|
|
|
|
|
*
|
|
|
|
|
*/
|
|
|
|
|
synchronized void updateState() {
|
|
|
|
|
super.updateState();
|
|
|
|
|
|
|
|
|
|
@ -591,16 +615,14 @@ public class Workflow extends Task {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Performs a deep clone of the workflow. All tasks
|
|
|
|
|
* are cloned as well. The cloned copy is saved to persistent
|
|
|
|
|
* storage before returning.
|
|
|
|
|
* Performs a deep clone of the workflow. All tasks are cloned as well. The
|
|
|
|
|
* cloned copy is saved to persistent storage before returning.
|
|
|
|
|
*
|
|
|
|
|
* @return the cloned workflow process.
|
|
|
|
|
*
|
|
|
|
|
**/
|
|
|
|
|
*
|
|
|
|
|
*/
|
|
|
|
|
public synchronized Object clone() {
|
|
|
|
|
Workflow workflowClone = new Workflow(getLabel(), getDescription());
|
|
|
|
|
//copyAttributes(workflowClone);
|
|
|
|
|
@ -613,7 +635,7 @@ public class Workflow extends Task {
|
|
|
|
|
Map taskToCloneMap = new HashMap();
|
|
|
|
|
Task dependOn, dependOnClone;
|
|
|
|
|
Task task;
|
|
|
|
|
Task taskClone,taskListenerClone, listener;
|
|
|
|
|
Task taskClone, taskListenerClone, listener;
|
|
|
|
|
Iterator dependencies;
|
|
|
|
|
Iterator tasks, finishedListeners;
|
|
|
|
|
|
|
|
|
|
@ -621,10 +643,10 @@ public class Workflow extends Task {
|
|
|
|
|
tasks = getTasks();
|
|
|
|
|
|
|
|
|
|
while (tasks.hasNext()) {
|
|
|
|
|
task = (Task)tasks.next();
|
|
|
|
|
task = (Task) tasks.next();
|
|
|
|
|
taskClone = null;
|
|
|
|
|
try {
|
|
|
|
|
taskClone = (Task)(task.clone());
|
|
|
|
|
taskClone = (Task) (task.clone());
|
|
|
|
|
taskClone.removeAllFinishedListeners();
|
|
|
|
|
taskClone.save();
|
|
|
|
|
taskClone.removeAllDependencies();
|
|
|
|
|
@ -642,16 +664,16 @@ public class Workflow extends Task {
|
|
|
|
|
tasks = getTasks();
|
|
|
|
|
|
|
|
|
|
while (tasks.hasNext()) {
|
|
|
|
|
task = (Task)tasks.next();
|
|
|
|
|
taskClone = (Task)taskToCloneMap.get(task);
|
|
|
|
|
task = (Task) tasks.next();
|
|
|
|
|
taskClone = (Task) taskToCloneMap.get(task);
|
|
|
|
|
|
|
|
|
|
// Clone also copies the references to previous environment,
|
|
|
|
|
// so we remove those
|
|
|
|
|
// Copy dependencies of one task definition to the clone one
|
|
|
|
|
dependencies = task.getDependencies();
|
|
|
|
|
while (dependencies.hasNext()) {
|
|
|
|
|
dependOn = (Task)dependencies.next();
|
|
|
|
|
dependOnClone = (Task)taskToCloneMap.get(dependOn);
|
|
|
|
|
dependOn = (Task) dependencies.next();
|
|
|
|
|
dependOnClone = (Task) taskToCloneMap.get(dependOn);
|
|
|
|
|
taskClone.addDependency(dependOnClone);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@ -659,18 +681,18 @@ public class Workflow extends Task {
|
|
|
|
|
//is not a dependency then clone them.
|
|
|
|
|
finishedListeners = task.getFinishedListeners();
|
|
|
|
|
while (finishedListeners.hasNext()) {
|
|
|
|
|
listener = (Task)finishedListeners.next();
|
|
|
|
|
listener = (Task) finishedListeners.next();
|
|
|
|
|
|
|
|
|
|
// Listeners to exclude are :
|
|
|
|
|
// 1. the containing workflow
|
|
|
|
|
// 2. Task that depend on this task; When we added dependency
|
|
|
|
|
// a listener was already registered.
|
|
|
|
|
if (!listener.equals(this) &&
|
|
|
|
|
!listener.isDependency(task)) {
|
|
|
|
|
if (!listener.equals(this)
|
|
|
|
|
&& !listener.isDependency(task)) {
|
|
|
|
|
|
|
|
|
|
//Clone the listener and add clone task as listener
|
|
|
|
|
try {
|
|
|
|
|
taskListenerClone = (Task)listener.clone();
|
|
|
|
|
taskListenerClone = (Task) listener.clone();
|
|
|
|
|
} catch (CloneNotSupportedException e) {
|
|
|
|
|
e.printStackTrace();
|
|
|
|
|
throw new RuntimeException(e.getMessage());
|
|
|
|
|
@ -688,7 +710,8 @@ public class Workflow extends Task {
|
|
|
|
|
/**
|
|
|
|
|
* Overrides the enable method (since the behavior is a little different).
|
|
|
|
|
*
|
|
|
|
|
**/
|
|
|
|
|
*
|
|
|
|
|
*/
|
|
|
|
|
public void enable() {
|
|
|
|
|
|
|
|
|
|
int taskState = getState();
|
|
|
|
|
@ -720,7 +743,8 @@ public class Workflow extends Task {
|
|
|
|
|
/**
|
|
|
|
|
* On a disable event, stops the workflow.
|
|
|
|
|
*
|
|
|
|
|
**/
|
|
|
|
|
*
|
|
|
|
|
*/
|
|
|
|
|
public void disableEvt() {
|
|
|
|
|
Task tempTask = null;
|
|
|
|
|
stop(null);
|
|
|
|
|
@ -728,7 +752,7 @@ public class Workflow extends Task {
|
|
|
|
|
Iterator itr = getTasks();
|
|
|
|
|
|
|
|
|
|
while (itr.hasNext()) {
|
|
|
|
|
tempTask = (Task)itr.next();
|
|
|
|
|
tempTask = (Task) itr.next();
|
|
|
|
|
tempTask.disable();
|
|
|
|
|
}
|
|
|
|
|
setProcessState(INIT);
|
|
|
|
|
@ -737,7 +761,8 @@ public class Workflow extends Task {
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Set the template from which this Workflow was instantiated.
|
|
|
|
|
**/
|
|
|
|
|
*
|
|
|
|
|
*/
|
|
|
|
|
public void setWorkflowTemplate(WorkflowTemplate template) {
|
|
|
|
|
if (template != null) {
|
|
|
|
|
set(PROCESS_DEF_ID, template.getID());
|
|
|
|
|
@ -748,7 +773,8 @@ public class Workflow extends Task {
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Get the template from which this workflow was instantiated.
|
|
|
|
|
**/
|
|
|
|
|
*
|
|
|
|
|
*/
|
|
|
|
|
public WorkflowTemplate getWorkflowTemplate() {
|
|
|
|
|
BigDecimal templateID = (BigDecimal) get(PROCESS_DEF_ID);
|
|
|
|
|
if (templateID != null) {
|
|
|
|
|
@ -773,28 +799,25 @@ public class Workflow extends Task {
|
|
|
|
|
public static BigDecimal getItemID(BigDecimal workflowId) {
|
|
|
|
|
BigDecimal objectID = null;
|
|
|
|
|
Session session = SessionManager.getSession();
|
|
|
|
|
DataQuery query = session.retrieveQuery
|
|
|
|
|
("com.arsdigita.workflow.simple.getProcesses");
|
|
|
|
|
DataQuery query = session.retrieveQuery("com.arsdigita.workflow.simple.getProcesses");
|
|
|
|
|
query.addEqualsFilter("id", workflowId);
|
|
|
|
|
if (query.next()) {
|
|
|
|
|
objectID = (BigDecimal)query.get("processObjectID");
|
|
|
|
|
objectID = (BigDecimal) query.get("processObjectID");
|
|
|
|
|
query.close();
|
|
|
|
|
}
|
|
|
|
|
return objectID;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* static methods to retrieve the workflow associated with an object */
|
|
|
|
|
|
|
|
|
|
public static BigDecimal getObjectWorkflowID(BigDecimal id) {
|
|
|
|
|
BigDecimal workflowID = null;
|
|
|
|
|
final Session session = SessionManager.getSession();
|
|
|
|
|
final DataQuery query = session.retrieveQuery
|
|
|
|
|
("com.arsdigita.workflow.simple.getProcesses");
|
|
|
|
|
Filter filter= query.addFilter("processObjectID = :object_id");
|
|
|
|
|
final DataQuery query = session.retrieveQuery("com.arsdigita.workflow.simple.getProcesses");
|
|
|
|
|
Filter filter = query.addFilter("processObjectID = :object_id");
|
|
|
|
|
filter.set("object_id", id);
|
|
|
|
|
|
|
|
|
|
if (query.next()) {
|
|
|
|
|
workflowID = (BigDecimal)query.get("processID");
|
|
|
|
|
workflowID = (BigDecimal) query.get("processID");
|
|
|
|
|
query.close();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@ -808,8 +831,7 @@ public class Workflow extends Task {
|
|
|
|
|
public static Workflow getObjectWorkflow(BigDecimal id) {
|
|
|
|
|
final BigDecimal workflowID;
|
|
|
|
|
final Session session = SessionManager.getSession();
|
|
|
|
|
final DataQuery query = session.retrieveQuery
|
|
|
|
|
("com.arsdigita.workflow.simple.getProcesses");
|
|
|
|
|
final DataQuery query = session.retrieveQuery("com.arsdigita.workflow.simple.getProcesses");
|
|
|
|
|
final Filter filter = query.addFilter("processObjectID = :object_id");
|
|
|
|
|
filter.set("object_id", id);
|
|
|
|
|
|
|
|
|
|
|