Geändert

 * Query für die Tskliste im CC auf gestartete Workflows beschränkt
 * Automatisches Starten eines Workflows beim Resetten verhindert, würde es eh' für den Publisher starten, nicht für die Autoren
 * Link zum Starten des Workflows wird nun auch im Zustand INIT angezeigt

Wenn das Löschen des Workflows beim Publizieren per Config-Parameter com.arsdigita.cms.delete_workflow_after_publication abgeschalted wurde, sollte das Verhalten nun dem erwarteten entsprechen.

Fehlt

 * Publizieren ist noch nicht vom WF abhängig

git-svn-id: https://svn.libreccm.org/ccm/trunk@2296 8810af33-2d31-482b-a856-94f89814c4df
master
quasi 2013-08-07 06:01:37 +00:00
parent 6a06a18e8c
commit 066d19a137
5 changed files with 182 additions and 155 deletions

View File

@ -74,6 +74,7 @@ query getEnabledUserTasks {
cw_tasks cw_tasks_proc cw_tasks cw_tasks_proc
where cw_tasks.task_id = cw_user_tasks.task_id where cw_tasks.task_id = cw_user_tasks.task_id
and cw_user_tasks.task_id = cms_tasks.task_id and cw_user_tasks.task_id = cms_tasks.task_id
and cw_processes.process_state = 'started'
and cms_tasks.task_type_id = cms_task_types.task_type_id and cms_tasks.task_type_id = cms_task_types.task_type_id
and cw_tasks.task_state = 'enabled' and cw_tasks.task_state = 'enabled'
and cw_tasks.parent_task_id = cw_processes.process_id and cw_tasks.parent_task_id = cw_processes.process_id

View File

@ -74,6 +74,7 @@ query getEnabledUserTasks {
cw_tasks cw_tasks_proc cw_tasks cw_tasks_proc
where cw_tasks.task_id = cw_user_tasks.task_id where cw_tasks.task_id = cw_user_tasks.task_id
and cw_user_tasks.task_id = cms_tasks.task_id and cw_user_tasks.task_id = cms_tasks.task_id
and cw_processes.process_state = 'started'
and cms_tasks.task_type_id = cms_task_types.task_type_id and cms_tasks.task_type_id = cms_task_types.task_type_id
and cw_tasks.task_state = 'enabled' and cw_tasks.task_state = 'enabled'
and cw_tasks.parent_task_id = cw_processes.process_id and cw_tasks.parent_task_id = cw_processes.process_id

View File

@ -835,7 +835,9 @@ class ItemLifecycleSelectForm extends BaseForm {
workflow.delete(); workflow.delete();
workflow = t.instantiateNewWorkflow(); workflow = t.instantiateNewWorkflow();
workflow.setObject(item); workflow.setObject(item);
workflow.start(user); /* Startring the workflow will probably do the wrong thing, because most of the time
* the current user would be a publisher, not an author */
// workflow.start(user);
workflow.save(); workflow.save();
} }
} }

View File

@ -109,7 +109,8 @@ final class ItemWorkflowItemPane extends BaseWorkflowItemPane {
public final boolean isVisible(final PageState state) { public final boolean isVisible(final PageState state) {
final Workflow workflow = m_workflow.getWorkflow(state); final Workflow workflow = m_workflow.getWorkflow(state);
return workflow.getProcessState() == Workflow.STOPPED; // Start link should be visible if the workflow state is stopped or init
return (workflow.getProcessState() == Workflow.STOPPED || workflow.getProcessState() == Workflow.INIT);
} }
private class Listener implements ActionListener { private class Listener implements ActionListener {

View File

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