mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-07-24 17:32:48 +00:00
Workflow:
1) Support for localisation of all Workflow definitions 2) Consolidate on id, title & description fields for all Workflow API objects 3) Add WorkflowTransition object to Workflow APIs 4) Fix up damage of above changes (web client etc) git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@3528 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
@@ -96,7 +96,7 @@ public interface TaskComponent
|
||||
* @param transition the task transition to take on completion (or null, for the default transition)
|
||||
* @return the updated task
|
||||
*/
|
||||
public WorkflowTask endTask(String taskId, String transition);
|
||||
public WorkflowTask endTask(String taskId, String transitionId);
|
||||
|
||||
}
|
||||
|
||||
|
@@ -133,7 +133,7 @@ public interface WorkflowComponent
|
||||
* @param transition the transition to follow (or null, for the default transition)
|
||||
* @return the updated workflow path
|
||||
*/
|
||||
public WorkflowPath signal(String pathId, String transition);
|
||||
public WorkflowPath signal(String pathId, String transitionId);
|
||||
|
||||
/**
|
||||
* Gets all Tasks associated with the specified path
|
||||
|
@@ -157,7 +157,7 @@ public class WorkflowDeployer implements ApplicationListener
|
||||
WorkflowDefinition def = workflowService.deployDefinition(engineId, workflowResource.getInputStream(), mimetype);
|
||||
if (logger.isInfoEnabled())
|
||||
{
|
||||
logger.info("Workflow deployer: Deployed process definition '" + def.name + "' (version " + def.version + ") from '" + location + "'");
|
||||
logger.info("Workflow deployer: Deployed process definition '" + def.title + "' (version " + def.version + ") from '" + location + "'");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -28,6 +28,7 @@ import java.util.Set;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.zip.ZipInputStream;
|
||||
|
||||
import org.alfresco.i18n.I18NUtil;
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.repo.content.MimetypeMap;
|
||||
import org.alfresco.repo.security.authentication.AuthenticationUtil;
|
||||
@@ -52,6 +53,7 @@ import org.alfresco.service.cmr.workflow.WorkflowPath;
|
||||
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.cmr.workflow.WorkflowTransition;
|
||||
import org.alfresco.service.namespace.NamespaceService;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
import org.hibernate.Query;
|
||||
@@ -68,6 +70,7 @@ import org.jbpm.graph.exe.ProcessInstance;
|
||||
import org.jbpm.graph.exe.Token;
|
||||
import org.jbpm.taskmgmt.def.Task;
|
||||
import org.jbpm.taskmgmt.exe.TaskInstance;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springmodules.workflow.jbpm31.JbpmCallback;
|
||||
import org.springmodules.workflow.jbpm31.JbpmTemplate;
|
||||
|
||||
@@ -101,6 +104,11 @@ public class JBPMEngine extends BPMEngine
|
||||
"and ti.isOpen = false " +
|
||||
"and ti.end is not null";
|
||||
|
||||
// I18N labels
|
||||
private final static String TITLE_LABEL = "title";
|
||||
private final static String DESC_LABEL = "description";
|
||||
private final static String DEFAULT_TRANSITION_LABEL = "bpm_businessprocessmodel.transition";
|
||||
|
||||
|
||||
/**
|
||||
* Sets the JBPM Template used for accessing JBoss JBPM in the correct context
|
||||
@@ -1196,6 +1204,22 @@ public class JBPMEngine extends BPMEngine
|
||||
return authorities;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an I18N Label for a workflow item
|
||||
*
|
||||
* @param displayId message resource id lookup
|
||||
* @param labelKey label to lookup (title or description)
|
||||
* @param defaultLabel default value if not found in message resource bundle
|
||||
* @return the label
|
||||
*/
|
||||
private String getLabel(String displayId, String labelKey, String defaultLabel)
|
||||
{
|
||||
String key = StringUtils.replace(displayId, ":", "_");
|
||||
key += "." + labelKey;
|
||||
String label = I18NUtil.getMessage(key);
|
||||
return (label == null) ? defaultLabel : label;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Workflow Data Object Creation...
|
||||
@@ -1226,8 +1250,11 @@ public class JBPMEngine extends BPMEngine
|
||||
@SuppressWarnings("unchecked")
|
||||
protected WorkflowNode createWorkflowNode(Node node)
|
||||
{
|
||||
String name = node.getName();
|
||||
String processName = node.getProcessDefinition().getName();
|
||||
WorkflowNode workflowNode = new WorkflowNode();
|
||||
workflowNode.name = node.getName();
|
||||
workflowNode.title = getLabel(processName + ".node." + name, TITLE_LABEL, name);
|
||||
workflowNode.description = getLabel(processName + ".node." + name, DESC_LABEL, workflowNode.title);
|
||||
if (node instanceof HibernateProxy)
|
||||
{
|
||||
Node realNode = (Node)((HibernateProxy)node).getHibernateLazyInitializer().getImplementation();
|
||||
@@ -1240,18 +1267,45 @@ public class JBPMEngine extends BPMEngine
|
||||
// TODO: Is there a formal way of determing if task node?
|
||||
workflowNode.isTaskNode = workflowNode.type.equals("TaskNode");
|
||||
List transitions = node.getLeavingTransitions();
|
||||
workflowNode.transitions = new String[(transitions == null) ? 0 : transitions.size()];
|
||||
workflowNode.transitions = new WorkflowTransition[(transitions == null) ? 0 : transitions.size()];
|
||||
if (transitions != null)
|
||||
{
|
||||
int i = 0;
|
||||
for (Transition transition : (List<Transition>)transitions)
|
||||
{
|
||||
workflowNode.transitions[i++] = transition.getName();
|
||||
workflowNode.transitions[i++] = createWorkflowTransition(transition);
|
||||
}
|
||||
}
|
||||
return workflowNode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a Workflow Transition
|
||||
*
|
||||
* @param transition JBoss JBPM Transition
|
||||
* @return Workflow Transition
|
||||
*/
|
||||
protected WorkflowTransition createWorkflowTransition(Transition transition)
|
||||
{
|
||||
WorkflowTransition workflowTransition = new WorkflowTransition();
|
||||
workflowTransition.id = transition.getName();
|
||||
Node node = transition.getFrom();
|
||||
workflowTransition.isDefault = node.getDefaultLeavingTransition().equals(transition);
|
||||
if (workflowTransition.id.length() == 0)
|
||||
{
|
||||
workflowTransition.title = getLabel(DEFAULT_TRANSITION_LABEL, TITLE_LABEL, workflowTransition.id);
|
||||
workflowTransition.description = getLabel(DEFAULT_TRANSITION_LABEL, DESC_LABEL, workflowTransition.title);
|
||||
}
|
||||
else
|
||||
{
|
||||
String nodeName = node.getName();
|
||||
String processName = node.getProcessDefinition().getName();
|
||||
workflowTransition.title = getLabel(processName + ".node." + nodeName + ".transition." + workflowTransition.id, TITLE_LABEL, workflowTransition.id);
|
||||
workflowTransition.description = getLabel(processName + ".node." + nodeName + ".transition." + workflowTransition.id, DESC_LABEL, workflowTransition.title);
|
||||
}
|
||||
return workflowTransition;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a Workflow Instance
|
||||
*
|
||||
@@ -1276,15 +1330,16 @@ public class JBPMEngine extends BPMEngine
|
||||
protected WorkflowDefinition createWorkflowDefinition(ProcessDefinition definition)
|
||||
{
|
||||
WorkflowDefinition workflowDef = new WorkflowDefinition();
|
||||
String name = definition.getName();
|
||||
workflowDef.title = getLabel(name + ".workflow", TITLE_LABEL, name);
|
||||
workflowDef.description = getLabel(name + ".workflow", DESC_LABEL, workflowDef.title);
|
||||
workflowDef.id = createGlobalId(new Long(definition.getId()).toString());
|
||||
workflowDef.version = new Integer(definition.getVersion()).toString();
|
||||
workflowDef.name = definition.getName();
|
||||
Task startTask = definition.getTaskMgmtDefinition().getStartTask();
|
||||
if (startTask != null)
|
||||
{
|
||||
workflowDef.startTaskDefinition = createWorkflowTaskDefinition(startTask);
|
||||
}
|
||||
|
||||
return workflowDef;
|
||||
}
|
||||
|
||||
@@ -1298,11 +1353,27 @@ public class JBPMEngine extends BPMEngine
|
||||
{
|
||||
WorkflowTask workflowTask = new WorkflowTask();
|
||||
workflowTask.id = createGlobalId(new Long(task.getId()).toString());
|
||||
workflowTask.name = task.getName();
|
||||
workflowTask.path = createWorkflowPath(task.getToken());
|
||||
workflowTask.state = getWorkflowTaskState(task);
|
||||
workflowTask.definition = createWorkflowTaskDefinition(task.getTask());
|
||||
workflowTask.properties = getTaskProperties(task);
|
||||
String name = task.getName();
|
||||
String processName = task.getTask().getProcessDefinition().getName();
|
||||
workflowTask.title = getLabel(processName + ".node." + name, TITLE_LABEL, name);
|
||||
if (workflowTask.title == null)
|
||||
{
|
||||
workflowTask.title = workflowTask.definition.metadata.getTitle();
|
||||
if (workflowTask.title == null)
|
||||
{
|
||||
workflowTask.title = name;
|
||||
}
|
||||
}
|
||||
workflowTask.description = getLabel(processName + ".node." + name, DESC_LABEL, workflowTask.title);
|
||||
if (workflowTask.description == null)
|
||||
{
|
||||
String description = workflowTask.definition.metadata.getDescription();
|
||||
workflowTask.description = (description == null) ? workflowTask.title : description;
|
||||
}
|
||||
return workflowTask;
|
||||
}
|
||||
|
||||
|
@@ -23,6 +23,7 @@ import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.alfresco.i18n.I18NUtil;
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.repo.content.MimetypeMap;
|
||||
import org.alfresco.repo.workflow.BPMEngineRegistry;
|
||||
@@ -58,19 +59,22 @@ public class JBPMEngineTest extends BaseSpringTest
|
||||
NodeRef testNodeRef;
|
||||
|
||||
|
||||
//@Override
|
||||
@Override
|
||||
protected void onSetUpInTransaction() throws Exception
|
||||
{
|
||||
BPMEngineRegistry registry = (BPMEngineRegistry)applicationContext.getBean("bpm_engineRegistry");
|
||||
workflowComponent = registry.getWorkflowComponent("jbpm");
|
||||
taskComponent = registry.getTaskComponent("jbpm");
|
||||
|
||||
// deploy test process messages
|
||||
I18NUtil.registerResourceBundle("org/alfresco/repo/workflow/jbpm/test-messages");
|
||||
|
||||
// deploy test process definition
|
||||
ClassPathResource processDef = new ClassPathResource("org/alfresco/repo/workflow/jbpm/test_processdefinition.xml");
|
||||
assertFalse(workflowComponent.isDefinitionDeployed(processDef.getInputStream(), MimetypeMap.MIMETYPE_XML));
|
||||
testWorkflowDef = workflowComponent.deployDefinition(processDef.getInputStream(), MimetypeMap.MIMETYPE_XML);
|
||||
assertNotNull(testWorkflowDef);
|
||||
assertEquals("Test", testWorkflowDef.name);
|
||||
assertEquals("Test", testWorkflowDef.title);
|
||||
assertEquals("1", testWorkflowDef.version);
|
||||
assertTrue(workflowComponent.isDefinitionDeployed(processDef.getInputStream(), MimetypeMap.MIMETYPE_XML));
|
||||
|
||||
@@ -93,7 +97,7 @@ public class JBPMEngineTest extends BaseSpringTest
|
||||
ClassPathResource processDef = new ClassPathResource("org/alfresco/repo/workflow/jbpm/test_processdefinition.xml");
|
||||
testWorkflowDef = workflowComponent.deployDefinition(processDef.getInputStream(), MimetypeMap.MIMETYPE_XML);
|
||||
assertNotNull(testWorkflowDef);
|
||||
assertEquals("Test", testWorkflowDef.name);
|
||||
assertEquals("Test", testWorkflowDef.title);
|
||||
assertEquals("2", testWorkflowDef.version);
|
||||
}
|
||||
|
||||
@@ -295,7 +299,7 @@ public class JBPMEngineTest extends BaseSpringTest
|
||||
WorkflowDefinition workflowDef = getTestDefinition();
|
||||
WorkflowPath path = workflowComponent.startWorkflow(workflowDef.id, null);
|
||||
assertNotNull(path);
|
||||
WorkflowPath updatedPath = workflowComponent.signal(path.id, path.node.transitions[1]);
|
||||
WorkflowPath updatedPath = workflowComponent.signal(path.id, path.node.transitions[1].id);
|
||||
assertNotNull(updatedPath);
|
||||
}
|
||||
|
||||
@@ -312,15 +316,17 @@ public class JBPMEngineTest extends BaseSpringTest
|
||||
List<WorkflowTask> tasks = workflowComponent.getTasksForWorkflowPath(path.id);
|
||||
assertNotNull(tasks);
|
||||
assertEquals(1, tasks.size());
|
||||
WorkflowTask updatedTask = taskComponent.endTask(tasks.get(0).id, path.node.transitions[0]);
|
||||
WorkflowTask updatedTask = taskComponent.endTask(tasks.get(0).id, path.node.transitions[0].id);
|
||||
assertNotNull(updatedTask);
|
||||
List<WorkflowTask> completedTasks = taskComponent.getAssignedTasks("admin", WorkflowTaskState.COMPLETED);
|
||||
List<WorkflowTask> completedTasks = taskComponent.getAssignedTasks("System", WorkflowTaskState.COMPLETED);
|
||||
assertNotNull(completedTasks);
|
||||
assertEquals(0, completedTasks.size());
|
||||
completedTasks = filterTasksByWorkflowInstance(completedTasks, path.instance.id);
|
||||
assertEquals(1, completedTasks.size());
|
||||
List<WorkflowTask> assignedTasks = taskComponent.getAssignedTasks("admin", WorkflowTaskState.IN_PROGRESS);
|
||||
assertNotNull(assignedTasks);
|
||||
assignedTasks = filterTasksByWorkflowInstance(assignedTasks, path.instance.id);
|
||||
assertEquals(1, assignedTasks.size());
|
||||
assertEquals("Review", assignedTasks.get(0).name);
|
||||
assertEquals("Review", assignedTasks.get(0).title);
|
||||
}
|
||||
|
||||
|
||||
@@ -342,6 +348,7 @@ public class JBPMEngineTest extends BaseSpringTest
|
||||
assertEquals(WorkflowTaskState.COMPLETED, updatedTask.state);
|
||||
List<WorkflowTask> completedTasks = taskComponent.getAssignedTasks("System", WorkflowTaskState.COMPLETED);
|
||||
assertNotNull(completedTasks);
|
||||
completedTasks = filterTasksByWorkflowInstance(completedTasks, path.instance.id);
|
||||
assertEquals(1, completedTasks.size());
|
||||
assertEquals(WorkflowTaskState.COMPLETED, completedTasks.get(0).state);
|
||||
}
|
||||
@@ -361,7 +368,7 @@ public class JBPMEngineTest extends BaseSpringTest
|
||||
assertEquals(1, tasks1.size());
|
||||
WorkflowTask getTask = taskComponent.getTaskById(tasks1.get(0).id);
|
||||
assertNotNull(getTask);
|
||||
assertEquals(getTask.name, tasks1.get(0).name);
|
||||
assertEquals(getTask.title, tasks1.get(0).title);
|
||||
}
|
||||
|
||||
|
||||
@@ -394,7 +401,7 @@ public class JBPMEngineTest extends BaseSpringTest
|
||||
List<WorkflowTask> tasks1 = workflowComponent.getTasksForWorkflowPath(path.id);
|
||||
assertNotNull(tasks1);
|
||||
assertEquals(1, tasks1.size());
|
||||
WorkflowTask updatedTask = taskComponent.endTask(tasks1.get(0).id, path.node.transitions[0]);
|
||||
WorkflowTask updatedTask = taskComponent.endTask(tasks1.get(0).id, path.node.transitions[0].id);
|
||||
assertNotNull(updatedTask);
|
||||
}
|
||||
|
||||
@@ -409,4 +416,25 @@ public class JBPMEngineTest extends BaseSpringTest
|
||||
return testWorkflowDef;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Filter task list by workflow instance
|
||||
*
|
||||
* @param tasks
|
||||
* @param processInstanceId
|
||||
* @return
|
||||
*/
|
||||
private List<WorkflowTask> filterTasksByWorkflowInstance(List<WorkflowTask> tasks, String workflowInstanceId)
|
||||
{
|
||||
List<WorkflowTask> filteredTasks = new ArrayList<WorkflowTask>();
|
||||
for (WorkflowTask task : tasks)
|
||||
{
|
||||
if (task.path.instance.id.equals(workflowInstanceId))
|
||||
{
|
||||
filteredTasks.add(task);
|
||||
}
|
||||
}
|
||||
return filteredTasks;
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<process-definition xmlns="urn:jbpm.org:jpdl-3.1" name="Review and Approve">
|
||||
<process-definition xmlns="urn:jbpm.org:jpdl-3.1" name="wf:review">
|
||||
<swimlane name="Initiator"></swimlane>
|
||||
<start-state name="start">
|
||||
<task name="wf:submitReviewTask" swimlane="Initiator" blocking="true">
|
||||
@@ -14,7 +14,7 @@
|
||||
<swimlane name="Reviewer">
|
||||
<assignment actor-id="#{reviewer}"></assignment>
|
||||
</swimlane>
|
||||
<task-node name="Review">
|
||||
<task-node name="review">
|
||||
<task name="Review" duedate="1 business day" blocking="true" swimlane="Reviewer">
|
||||
<controller>
|
||||
<variable name="comment" access="read,write,required"></variable>
|
||||
|
@@ -0,0 +1,14 @@
|
||||
test.workflow.title=Test
|
||||
test.workflow.description=Workflow for testing purposes
|
||||
|
||||
test.node.start.title=Start
|
||||
test.node.start.description=The Start
|
||||
test.node.review.title=Review
|
||||
test.node.review.description=The Review
|
||||
test.node.end.title=End
|
||||
test.node.end.description=The End
|
||||
|
||||
test.node.start.transition.review=Review
|
||||
|
||||
test.task.submit.title=Submit Review Title
|
||||
test.task.submit.description=Submit Review Description
|
@@ -1,15 +1,16 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<process-definition xmlns="urn:jbpm.org:jpdl-3.1" name="Test">
|
||||
<swimlane name="Initiator"></swimlane>
|
||||
<process-definition xmlns="urn:jbpm.org:jpdl-3.1" name="test">
|
||||
<swimlane name="initiator"></swimlane>
|
||||
|
||||
<start-state name="start">
|
||||
<task name="Submit" swimlane="Initiator">
|
||||
<task name="submit" swimlane="initiator">
|
||||
<controller>
|
||||
<variable name="reviewer" access="write,required" />
|
||||
<variable name="testNode" access="write,required" />
|
||||
</controller>
|
||||
</task>
|
||||
<transition name="" to="Review">
|
||||
<transition name="" to="review">
|
||||
<action class="org.alfresco.repo.workflow.jbpm.AlfrescoJavaScript">
|
||||
<script>
|
||||
<expression>
|
||||
@@ -23,13 +24,14 @@
|
||||
</script>
|
||||
</action>
|
||||
</transition>
|
||||
<transition name="end" to="end">
|
||||
</transition>
|
||||
<transition name="end" to="end"/>
|
||||
</start-state>
|
||||
<swimlane name="Reviewer">
|
||||
|
||||
<swimlane name="reviewer">
|
||||
<assignment actor-id="#{reviewer}"></assignment>
|
||||
</swimlane>
|
||||
<task-node name="Review">
|
||||
|
||||
<task-node name="review">
|
||||
<event type="node-enter">
|
||||
<script>
|
||||
System.out.println("the reviewer is " + reviewer);
|
||||
@@ -37,12 +39,14 @@
|
||||
System.out.println("scriptResult = " + scriptResult);
|
||||
</script>
|
||||
</event>
|
||||
<task name="Review" duedate="1 business day" blocking="true" swimlane="Reviewer">
|
||||
<task name="review" duedate="1 business day" blocking="true" swimlane="reviewer">
|
||||
<controller>
|
||||
<variable name="comment" access="read,write,required"></variable>
|
||||
</controller>
|
||||
</task>
|
||||
<transition name="" to="end"></transition>
|
||||
</task-node>
|
||||
|
||||
<end-state name="end"></end-state>
|
||||
|
||||
</process-definition>
|
Reference in New Issue
Block a user