mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-08-07 17:49:17 +00:00
Checkpoint for workflow features
git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@3518 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
@@ -1,12 +1,24 @@
|
||||
package org.alfresco.web.bean.workflow;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.faces.context.FacesContext;
|
||||
import javax.transaction.UserTransaction;
|
||||
|
||||
import org.alfresco.service.cmr.workflow.WorkflowService;
|
||||
import org.alfresco.service.cmr.workflow.WorkflowTask;
|
||||
import org.alfresco.service.cmr.workflow.WorkflowTaskDefinition;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
import org.alfresco.web.app.Application;
|
||||
import org.alfresco.web.bean.dialog.BaseDialogBean;
|
||||
import org.alfresco.web.bean.repository.Node;
|
||||
import org.alfresco.web.bean.repository.Repository;
|
||||
import org.alfresco.web.bean.repository.TransientNode;
|
||||
import org.alfresco.web.config.DialogsConfigElement.DialogButtonConfig;
|
||||
import org.alfresco.web.ui.common.Utils;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
@@ -17,51 +29,186 @@ import org.apache.commons.logging.LogFactory;
|
||||
*/
|
||||
public class ManageWorkItemDialog extends BaseDialogBean
|
||||
{
|
||||
private static final Log logger = LogFactory.getLog(ManageWorkItemDialog.class);
|
||||
protected WorkflowService workflowService;
|
||||
protected Node workItemNode;
|
||||
protected WorkflowTask workItem;
|
||||
protected String[] transitions;
|
||||
|
||||
protected static final String ID_PREFIX = "transition_";
|
||||
protected static final String CLIENT_ID_PREFIX = "dialog:" + ID_PREFIX;
|
||||
|
||||
private static final Log logger = LogFactory.getLog(ManageWorkItemDialog.class);
|
||||
|
||||
// ------------------------------------------------------------------------------
|
||||
// Dialog implementation
|
||||
|
||||
@Override
|
||||
public void init(Map<String, String> parameters)
|
||||
{
|
||||
super.init(parameters);
|
||||
|
||||
String taskId = this.parameters.get("id");
|
||||
this.workItem = this.workflowService.getTaskById(taskId);
|
||||
|
||||
if (this.workItem != null)
|
||||
{
|
||||
// setup a transient node to represent the work item we're managing
|
||||
WorkflowTaskDefinition taskDef = this.workItem.definition;
|
||||
this.workItemNode = new TransientNode(taskDef.metadata.getName(),
|
||||
"task_" + System.currentTimeMillis(), this.workItem.properties);
|
||||
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("Created node for work item: " + this.workItemNode);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String finishImpl(FacesContext context, String outcome)
|
||||
throws Exception
|
||||
{
|
||||
return null;
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("Saving work item with params: " + this.workItemNode.getProperties());
|
||||
|
||||
// prepare the edited parameters for saving
|
||||
Map<QName, Serializable> params = WorkflowBean.prepareWorkItemParams(this.workItemNode);
|
||||
|
||||
// update the task with the updated parameters
|
||||
this.workflowService.updateTask(this.workItem.id, params, null, null);
|
||||
|
||||
return outcome;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public List<DialogButtonConfig> getAdditionalButtons()
|
||||
{
|
||||
List<DialogButtonConfig> buttons = new ArrayList<DialogButtonConfig>(1);
|
||||
buttons.add(new DialogButtonConfig("reassign-button",
|
||||
"Reassign", null, "#{ManageWorkItemDialog.reassign}", "false", null));
|
||||
List<DialogButtonConfig> buttons = null;
|
||||
|
||||
if (this.workItem != null)
|
||||
{
|
||||
// get the transitions available from this work item and
|
||||
// show them in the dialog as additional buttons
|
||||
this.transitions = this.workItem.path.node.transitions;
|
||||
|
||||
if (this.transitions != null)
|
||||
{
|
||||
buttons = new ArrayList<DialogButtonConfig>(this.transitions.length);
|
||||
|
||||
for (String trans : this.transitions)
|
||||
{
|
||||
// TODO: Tidy this up when the service returns the list of labels
|
||||
String label = trans;
|
||||
if (label.length() == 0)
|
||||
{
|
||||
label = "Done";
|
||||
}
|
||||
|
||||
buttons.add(new DialogButtonConfig(ID_PREFIX + trans, label, null,
|
||||
"#{DialogManager.bean.transition}", "false", null));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return buttons;
|
||||
return buttons;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getFinishButtonLabel()
|
||||
{
|
||||
return Application.getMessage(FacesContext.getCurrentInstance(), "save");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getFinishButtonDisabled()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------
|
||||
// Event handlers
|
||||
|
||||
public void approve()
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public String transition()
|
||||
{
|
||||
logger.info("approve button was pressed");
|
||||
}
|
||||
|
||||
public void reject()
|
||||
{
|
||||
logger.info("reject button was pressed");
|
||||
}
|
||||
|
||||
public void reassign()
|
||||
{
|
||||
logger.info("reassign button was pressed");
|
||||
String outcome = getDefaultFinishOutcome();
|
||||
|
||||
// to find out which transition button was pressed we need
|
||||
// to look for the button's id in the request parameters,
|
||||
// the first non-null result is the button that was pressed.
|
||||
FacesContext context = FacesContext.getCurrentInstance();
|
||||
Map reqParams = context.getExternalContext().getRequestParameterMap();
|
||||
|
||||
String selectedTransition = null;
|
||||
for (String trans : this.transitions)
|
||||
{
|
||||
Object result = reqParams.get(CLIENT_ID_PREFIX + trans);
|
||||
if (result != null)
|
||||
{
|
||||
// this was the button that was pressed
|
||||
selectedTransition = trans;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (selectedTransition != null)
|
||||
{
|
||||
UserTransaction tx = null;
|
||||
|
||||
try
|
||||
{
|
||||
tx = Repository.getUserTransaction(context);
|
||||
tx.begin();
|
||||
|
||||
// prepare the edited parameters for saving
|
||||
Map<QName, Serializable> params = WorkflowBean.prepareWorkItemParams(this.workItemNode);
|
||||
|
||||
// update the task with the updated parameters
|
||||
this.workflowService.updateTask(this.workItem.id, params, null, null);
|
||||
|
||||
// signal the selected transition to the workflow task
|
||||
this.workflowService.endTask(this.workItem.id, selectedTransition);
|
||||
|
||||
// commit the changes
|
||||
tx.commit();
|
||||
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("Ended work item with transition: " + selectedTransition);
|
||||
}
|
||||
catch (Throwable e)
|
||||
{
|
||||
// reset the flag so we can re-attempt the operation
|
||||
isFinished = false;
|
||||
|
||||
// rollback the transaction
|
||||
try { if (tx != null) {tx.rollback();} } catch (Exception ex) {}
|
||||
Utils.addErrorMessage(formatErrorMessage(e));
|
||||
outcome = this.getErrorOutcome(e);
|
||||
}
|
||||
}
|
||||
|
||||
return outcome;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------
|
||||
// Bean Getters and Setters
|
||||
|
||||
public boolean getApproveDisabled()
|
||||
|
||||
/**
|
||||
* Returns the Node representing the work item
|
||||
*
|
||||
* @return The node
|
||||
*/
|
||||
public Node getWorkItemNode()
|
||||
{
|
||||
return true;
|
||||
return this.workItemNode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the workflow service to use
|
||||
*
|
||||
* @param workflowService
|
||||
* WorkflowService instance
|
||||
*/
|
||||
public void setWorkflowService(WorkflowService workflowService)
|
||||
{
|
||||
this.workflowService = workflowService;
|
||||
}
|
||||
}
|
||||
|
@@ -1,6 +1,5 @@
|
||||
package org.alfresco.web.bean.workflow;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
@@ -10,18 +9,14 @@ import java.util.ResourceBundle;
|
||||
import javax.faces.context.FacesContext;
|
||||
import javax.faces.model.SelectItem;
|
||||
|
||||
import org.alfresco.service.cmr.repository.AssociationRef;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.cmr.workflow.WorkflowDefinition;
|
||||
import org.alfresco.service.cmr.workflow.WorkflowPath;
|
||||
import org.alfresco.service.cmr.workflow.WorkflowService;
|
||||
import org.alfresco.service.cmr.workflow.WorkflowTask;
|
||||
import org.alfresco.service.cmr.workflow.WorkflowTaskDefinition;
|
||||
import org.alfresco.service.cmr.workflow.WorkflowTaskState;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
import org.alfresco.web.app.Application;
|
||||
import org.alfresco.web.bean.repository.Node;
|
||||
import org.alfresco.web.bean.repository.Repository;
|
||||
import org.alfresco.web.bean.repository.TransientNode;
|
||||
import org.alfresco.web.bean.wizard.BaseWizardBean;
|
||||
import org.apache.commons.logging.Log;
|
||||
@@ -74,7 +69,8 @@ public class StartWorkflowWizard extends BaseWizardBean
|
||||
logger.debug("Starting workflow with params: " + this.startTaskNode.getProperties());
|
||||
|
||||
// start the workflow to get access to the start task
|
||||
WorkflowPath path = this.workflowService.startWorkflow(this.selectedWorkflow, prepareTaskParams());
|
||||
WorkflowPath path = this.workflowService.startWorkflow(this.selectedWorkflow,
|
||||
WorkflowBean.prepareWorkItemParams(this.startTaskNode));
|
||||
if (path != null)
|
||||
{
|
||||
// extract the start task
|
||||
@@ -239,48 +235,4 @@ public class StartWorkflowWizard extends BaseWizardBean
|
||||
{
|
||||
this.workflowService = workflowService;
|
||||
}
|
||||
|
||||
protected Map<QName, Serializable> prepareTaskParams()
|
||||
{
|
||||
Map<QName, Serializable> params = new HashMap<QName, Serializable>();
|
||||
|
||||
// marshal the properties and associations captured by the property sheet
|
||||
// back into a Map to pass to the workflow service
|
||||
|
||||
// go through all the properties in the transient node and add them to
|
||||
// params map
|
||||
Map<String, Object> props = this.startTaskNode.getProperties();
|
||||
for (String propName : props.keySet())
|
||||
{
|
||||
QName propQName = Repository.resolveToQName(propName);
|
||||
params.put(propQName, (Serializable)props.get(propName));
|
||||
}
|
||||
|
||||
// go through any associations that have been added to the start task
|
||||
// and build a list of NodeRefs representing the targets
|
||||
Map<String, Map<String, AssociationRef>> assocs = this.startTaskNode.getAddedAssociations();
|
||||
for (String assocName : assocs.keySet())
|
||||
{
|
||||
QName assocQName = Repository.resolveToQName(assocName);
|
||||
|
||||
// get the associations added and create list of targets
|
||||
Map<String, AssociationRef> addedAssocs = assocs.get(assocName);
|
||||
List<NodeRef> targets = new ArrayList<NodeRef>(addedAssocs.size());
|
||||
for (AssociationRef assoc : addedAssocs.values())
|
||||
{
|
||||
targets.add(assoc.getTargetRef());
|
||||
}
|
||||
|
||||
// add the targets for this particular association
|
||||
params.put(assocQName, (Serializable)targets);
|
||||
}
|
||||
|
||||
// String reviewer = (String)this.startTaskNode.getProperties().get(
|
||||
// ContentModel.PROP_NAME);
|
||||
// Map<QName, Serializable> params = new HashMap<QName, Serializable>(1);
|
||||
// params.put(QName.createQName(NamespaceService.DEFAULT_URI, "reviewer"), reviewer);
|
||||
|
||||
|
||||
return params;
|
||||
}
|
||||
}
|
||||
|
140
source/java/org/alfresco/web/bean/workflow/WorkflowBean.java
Normal file
140
source/java/org/alfresco/web/bean/workflow/WorkflowBean.java
Normal file
@@ -0,0 +1,140 @@
|
||||
package org.alfresco.web.bean.workflow;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.faces.context.FacesContext;
|
||||
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.service.cmr.repository.AssociationRef;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.cmr.workflow.WorkflowService;
|
||||
import org.alfresco.service.cmr.workflow.WorkflowTask;
|
||||
import org.alfresco.service.cmr.workflow.WorkflowTaskDefinition;
|
||||
import org.alfresco.service.cmr.workflow.WorkflowTaskState;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
import org.alfresco.util.ISO9075;
|
||||
import org.alfresco.web.app.Application;
|
||||
import org.alfresco.web.bean.repository.Node;
|
||||
import org.alfresco.web.bean.repository.Repository;
|
||||
import org.alfresco.web.bean.repository.TransientMapNode;
|
||||
import org.alfresco.web.bean.repository.User;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
/**
|
||||
* Managed bean used for handling workflow related features
|
||||
*
|
||||
* @author gavinc
|
||||
*/
|
||||
public class WorkflowBean
|
||||
{
|
||||
protected WorkflowService workflowService;
|
||||
protected List<Node> workItems;
|
||||
|
||||
private static final Log logger = LogFactory.getLog(WorkflowBean.class);
|
||||
|
||||
// ------------------------------------------------------------------------------
|
||||
// Bean Getters and Setters
|
||||
|
||||
public List<Node> getWorkItemsToDo()
|
||||
{
|
||||
// get the current username
|
||||
FacesContext fc = FacesContext.getCurrentInstance();
|
||||
User user = Application.getCurrentUser(fc);
|
||||
String userName = ISO9075.encode(user.getUserName());
|
||||
|
||||
// get the current in progress tasks for the current user
|
||||
List<WorkflowTask> tasks = this.workflowService.getAssignedTasks(
|
||||
userName, WorkflowTaskState.IN_PROGRESS);
|
||||
|
||||
// create a list of transient nodes to represent
|
||||
this.workItems = new ArrayList<Node>(tasks.size());
|
||||
for (WorkflowTask task : tasks)
|
||||
{
|
||||
createWorkItem(task);
|
||||
}
|
||||
|
||||
return this.workItems;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the workflow service to use
|
||||
*
|
||||
* @param workflowService WorkflowService instance
|
||||
*/
|
||||
public void setWorkflowService(WorkflowService workflowService)
|
||||
{
|
||||
this.workflowService = workflowService;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------
|
||||
// Helper methods
|
||||
|
||||
public static Map<QName, Serializable> prepareWorkItemParams(Node node)
|
||||
{
|
||||
Map<QName, Serializable> params = new HashMap<QName, Serializable>();
|
||||
|
||||
// marshal the properties and associations captured by the property sheet
|
||||
// back into a Map to pass to the workflow service
|
||||
|
||||
// go through all the properties in the transient node and add them to
|
||||
// params map
|
||||
Map<String, Object> props = node.getProperties();
|
||||
for (String propName : props.keySet())
|
||||
{
|
||||
QName propQName = Repository.resolveToQName(propName);
|
||||
params.put(propQName, (Serializable)props.get(propName));
|
||||
}
|
||||
|
||||
// go through any associations that have been added to the start task
|
||||
// and build a list of NodeRefs representing the targets
|
||||
Map<String, Map<String, AssociationRef>> assocs = node.getAddedAssociations();
|
||||
for (String assocName : assocs.keySet())
|
||||
{
|
||||
QName assocQName = Repository.resolveToQName(assocName);
|
||||
|
||||
// get the associations added and create list of targets
|
||||
Map<String, AssociationRef> addedAssocs = assocs.get(assocName);
|
||||
List<NodeRef> targets = new ArrayList<NodeRef>(addedAssocs.size());
|
||||
for (AssociationRef assoc : addedAssocs.values())
|
||||
{
|
||||
targets.add(assoc.getTargetRef());
|
||||
}
|
||||
|
||||
// add the targets for this particular association
|
||||
params.put(assocQName, (Serializable)targets);
|
||||
}
|
||||
|
||||
return params;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates and populates a TransientNode to represent the given
|
||||
* workflow task from the repository workflow engine
|
||||
*
|
||||
* @param task The task to create a representation of
|
||||
*/
|
||||
protected void createWorkItem(WorkflowTask task)
|
||||
{
|
||||
// get the type of the task
|
||||
WorkflowTaskDefinition taskDef = task.definition;
|
||||
|
||||
// create the basic transient node
|
||||
TransientMapNode node = new TransientMapNode(taskDef.metadata.getName(),
|
||||
task.name, task.properties);
|
||||
|
||||
// add properties for the other useful metadata
|
||||
node.getProperties().put(ContentModel.PROP_NAME.toString(), task.name);
|
||||
node.getProperties().put("type", taskDef.metadata.getTitle());
|
||||
node.getProperties().put("id", task.id);
|
||||
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("Created node for work item with id '" + task.id + "' " + node);
|
||||
|
||||
this.workItems.add(node);
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user