Workflow:

1) Fix bug in task property conversion for associations where association was single-ended, but list passed in (was causing exception in start workflow ui)
2) Tidy up Review & Approve Process definition (assign appropriate names, set review task due date, priority etc)
3) Provide resource bundles for basic BPM model and Review & Approve workflow
4) Fix bug in I18N resolution of workflow task title & description

git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@3556 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
David Caruana 2006-08-21 20:29:21 +00:00
parent a0462aee48
commit e4872ca8a5
10 changed files with 127 additions and 109 deletions

View File

@ -1,11 +1,42 @@
# Display labels for out-of-the-box Content-oriented Workflows # Display labels for out-of-the-box Content-oriented Workflows
# TODO: DC - Complete this for v1.4... #
# Review & Approve Workflow
#
wf_review.workflow.title=Review & Approve wf_review.workflow.title=Review & Approve
wf_review.workflow.description=Send documents for approval wf_review.workflow.description=Review & approval of content
# Review & Approve Task Definitions
wf_workflowmodel.type.wf_submitReviewTask.title=Submit Review
wf_workflowmodel.type.wf_submitReviewTask.description=Submit documents for review & approval
wf_workflowmodel.property.wf_reviewDueDate.title=Review Due Date
wf_workflowmodel.property.wf_reviewDueDate.description=Review Due Date
wf_workflowmodel.property.wf_priority.title=Review Priority
wf_workflowmodel.property.wf_priority.description=Review Priority
wf_workflowmodel.association.wf_reviewer.title=Reviewer
wf_workflowmodel.association.wf_reviewer.description=Reviewer
# Review & Approve Process Definitions
wf_review.node.start.title=Start wf_review.node.start.title=Start
wf_review.node.start.transition.review.title=Review wf_review.node.start.description=Start
wf_review.node.review.title=Review wf_review.node.review.title=Review
wf_review.task.wf_submitReviewTask.title=Review wf_review.node.review.description=Review
wf_workflowmodel.type.wf_submitReviewTask.title=Review wf_review.task.wf_review.title=Review
wf_review.task.wf_review.description=Review
wf_review.node.review.transition.reject.title=Reject
wf_review.node.review.transition.reject.description=Reject
wf_review.node.review.transition.approve.title=Approve
wf_review.node.review.transition.approve.description=Approve
wf_review.node.rejected.title=Rejected
wf_review.node.rejected.description=Rejected
wf_review.task.wf_rejected.title=Rejected
wf_review.task.wf_rejected.description=Rejected
wf_review.node.approved.title=Approved
wf_review.node.approved.description=Approved
wf_review.task.wf_approved.title=Approved
wf_review.task.wf_approved.description=Approved
wf_review.node.end.title=End
wf_review.node.end.description=End

View File

@ -153,21 +153,6 @@
</type> </type>
<!-- -->
<!-- The base for all Ad-hoc Tasks as created by Users -->
<!-- -->
<type name="bpm:adhocTask">
<title>Ad-hoc Task</title>
<description>Task assigned by User</description>
<parent>bpm:task</parent>
<mandatory-aspects>
<aspect>cm:attachable</aspect>
</mandatory-aspects>
</type>
<!-- --> <!-- -->
<!-- The base for all Tasks assigned via a Workflow --> <!-- The base for all Tasks assigned via a Workflow -->
<!-- --> <!-- -->
@ -200,6 +185,12 @@
<type>d:noderef</type> <type>d:noderef</type>
</property> </property>
<!-- Items within package marked as complete -->
<property name="bpm:completedItems">
<type>d:noderef</type>
<multiple>true</multiple>
</property>
<!-- TODO: Add Package Action Group --> <!-- TODO: Add Package Action Group -->
</properties> </properties>
@ -223,16 +214,6 @@
</type> </type>
<!-- -->
<!-- An Alfresco Space for managing ad-hoc Tasks -->
<!-- -->
<type name="bpm:taskspace">
<title>Task Space</title>
<parent>cm:folder</parent>
</type>
</types> </types>
<aspects> <aspects>
@ -249,14 +230,6 @@
<properties> <properties>
<!-- TODO: Move to Task -->
<!-- Items within package that have been marked as complete -->
<property name="bpm:completedItems">
<type>d:noderef</type>
<multiple>true</multiple>
</property>
<!-- TODO: Define properties (replicated from Workflow/Task Engine) for --> <!-- TODO: Define properties (replicated from Workflow/Task Engine) for -->
<!-- search within Alfresco e.g. task info, workflow info ... --> <!-- search within Alfresco e.g. task info, workflow info ... -->
@ -270,27 +243,6 @@
</aspect> </aspect>
<!-- Capability for adding a task management space to any entity in the system, -->
<!-- in particular, folders and content -->
<aspect name="bpm:tasks">
<associations>
<child-association name="bpm:tasks">
<source>
<mandatory>false</mandatory>
<many>false</many>
</source>
<target>
<class>bpm:taskspace</class>
<mandatory>true</mandatory>
<many>false</many>
</target>
<duplicate>false</duplicate>
</child-association>
</associations>
</aspect>
</aspects> </aspects>
</model> </model>

View File

@ -33,6 +33,14 @@
<type>d:date</type> <type>d:date</type>
</property> </property>
<property name="wf:reviewPriority">
<title>Review Priority</title>
<type>d:int</type>
<constraints>
<constraint ref="bpm:allowedPriority"/>
</constraints>
</property>
</properties> </properties>
<associations> <associations>

View File

@ -26,6 +26,10 @@ import org.alfresco.service.namespace.QName;
public interface WorkflowModel public interface WorkflowModel
{ {
//
// Base Business Process Management Definitions
//
// task constants // task constants
static final QName TYPE_TASK = QName.createQName(NamespaceService.BPM_MODEL_1_0_URI, "task"); static final QName TYPE_TASK = QName.createQName(NamespaceService.BPM_MODEL_1_0_URI, "task");
static final QName PROP_TASK_ID = QName.createQName(NamespaceService.BPM_MODEL_1_0_URI, "taskId"); static final QName PROP_TASK_ID = QName.createQName(NamespaceService.BPM_MODEL_1_0_URI, "taskId");
@ -35,14 +39,28 @@ public interface WorkflowModel
static final QName PROP_PRIORITY = QName.createQName(NamespaceService.BPM_MODEL_1_0_URI, "priority"); static final QName PROP_PRIORITY = QName.createQName(NamespaceService.BPM_MODEL_1_0_URI, "priority");
static final QName PROP_STATUS = QName.createQName(NamespaceService.BPM_MODEL_1_0_URI, "status"); static final QName PROP_STATUS = QName.createQName(NamespaceService.BPM_MODEL_1_0_URI, "status");
static final QName PROP_PERCENT_COMPLETE = QName.createQName(NamespaceService.BPM_MODEL_1_0_URI, "percentComplete"); static final QName PROP_PERCENT_COMPLETE = QName.createQName(NamespaceService.BPM_MODEL_1_0_URI, "percentComplete");
static final QName PROP_COMPLETED_ITEMS = QName.createQName(NamespaceService.BPM_MODEL_1_0_URI, "completedItems");
static final QName ASSOC_POOLED_ACTORS = QName.createQName(NamespaceService.BPM_MODEL_1_0_URI, "pooledActors"); static final QName ASSOC_POOLED_ACTORS = QName.createQName(NamespaceService.BPM_MODEL_1_0_URI, "pooledActors");
// workflow task contstants // workflow task contstants
static final QName TYPE_WORKFLOW_TASK = QName.createQName(NamespaceService.BPM_MODEL_1_0_URI, "workflowTask"); static final QName TYPE_WORKFLOW_TASK = QName.createQName(NamespaceService.BPM_MODEL_1_0_URI, "workflowTask");
static final QName PROP_CONTEXT = QName.createQName(NamespaceService.BPM_MODEL_1_0_URI, "context"); static final QName PROP_CONTEXT = QName.createQName(NamespaceService.BPM_MODEL_1_0_URI, "context");
static final QName PROP_WORKFLOW_DEFINITION_ID = QName.createQName(NamespaceService.BPM_MODEL_1_0_URI, "workflowDefinitionId");
static final QName PROP_WORKFLOW_INSTANCE_ID = QName.createQName(NamespaceService.BPM_MODEL_1_0_URI, "workflowInstanceId");
static final QName ASSOC_PACKAGE = QName.createQName(NamespaceService.BPM_MODEL_1_0_URI, "package"); static final QName ASSOC_PACKAGE = QName.createQName(NamespaceService.BPM_MODEL_1_0_URI, "package");
// workflow package // workflow package
static final QName ASPECT_WORKFLOW_PACKAGE = QName.createQName(NamespaceService.BPM_MODEL_1_0_URI, "workflowPackage"); static final QName ASPECT_WORKFLOW_PACKAGE = QName.createQName(NamespaceService.BPM_MODEL_1_0_URI, "workflowPackage");
//
// Workflow Models
//
// review & approve
static final QName TYPE_SUBMITREVIEW_TASK = QName.createQName(NamespaceService.WORKFLOW_MODEL_1_0_URI, "submitReviewTask");
static final QName PROP_REVIEW_PRIORITY = QName.createQName(NamespaceService.WORKFLOW_MODEL_1_0_URI, "reviewPriority");
static final QName PROP_REVIEW_DUE_DATE = QName.createQName(NamespaceService.WORKFLOW_MODEL_1_0_URI, "reviewDueDate");
static final QName ASSOC_REVIEWER = QName.createQName(NamespaceService.WORKFLOW_MODEL_1_0_URI, "reviewer");
} }

View File

@ -1258,7 +1258,8 @@ public class JBPMEngine extends BPMEngine
} }
else else
{ {
value = new JBPMNode((NodeRef)value, serviceRegistry); List<NodeRef> nodeRefs = (List<NodeRef>)value;
value = (nodeRefs.size() == 0 ? null : new JBPMNode(nodeRefs.get(0), serviceRegistry));
} }
} }
@ -1440,7 +1441,7 @@ public class JBPMEngine extends BPMEngine
workflowTask.properties = getTaskProperties(task); workflowTask.properties = getTaskProperties(task);
String name = task.getName(); String name = task.getName();
String processName = task.getTask().getProcessDefinition().getName(); String processName = task.getTask().getProcessDefinition().getName();
workflowTask.title = getLabel(processName + ".node." + name, TITLE_LABEL, name); workflowTask.title = getLabel(processName + ".task." + name, TITLE_LABEL, null);
if (workflowTask.title == null) if (workflowTask.title == null)
{ {
workflowTask.title = workflowTask.definition.metadata.getTitle(); workflowTask.title = workflowTask.definition.metadata.getTitle();
@ -1449,7 +1450,7 @@ public class JBPMEngine extends BPMEngine
workflowTask.title = name; workflowTask.title = name;
} }
} }
workflowTask.description = getLabel(processName + ".node." + name, DESC_LABEL, workflowTask.title); workflowTask.description = getLabel(processName + ".task." + name, DESC_LABEL, null);
if (workflowTask.description == null) if (workflowTask.description == null)
{ {
String description = workflowTask.definition.metadata.getDescription(); String description = workflowTask.definition.metadata.getDescription();

View File

@ -394,12 +394,6 @@ public class JBPMEngineTest extends BaseSpringTest
} }
public void testWorkflowPackageNodeRef()
{
}
public void testScript() public void testScript()
throws IOException throws IOException
{ {

View File

@ -23,7 +23,6 @@ import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import org.alfresco.model.ContentModel;
import org.alfresco.repo.content.MimetypeMap; import org.alfresco.repo.content.MimetypeMap;
import org.alfresco.repo.security.authentication.AuthenticationComponent; import org.alfresco.repo.security.authentication.AuthenticationComponent;
import org.alfresco.repo.workflow.BPMEngineRegistry; import org.alfresco.repo.workflow.BPMEngineRegistry;
@ -69,18 +68,7 @@ public class ReviewAndApproveTest extends BaseSpringTest
workflowComponent = registry.getWorkflowComponent("jbpm"); workflowComponent = registry.getWorkflowComponent("jbpm");
taskComponent = registry.getTaskComponent("jbpm"); taskComponent = registry.getTaskComponent("jbpm");
// retrieve review and approve process definition // deploy latest review and approve process definition
// ClassPathResource processDef = new ClassPathResource("org/alfresco/repo/workflow/jbpm/review_and_approve_processdefinition.xml");
// assertTrue(workflowComponent.isDefinitionDeployed(processDef.getInputStream(), MimetypeMap.MIMETYPE_XML));
// List<WorkflowDefinition> definitions = workflowComponent.getDefinitions();
// for (WorkflowDefinition definition : definitions)
// {
// if (definition.title.equals("Review & Approve"))
// {
// testWorkflowDef = definition;
// break;
// }
// }
ClassPathResource processDef = new ClassPathResource("org/alfresco/repo/workflow/jbpm/review_and_approve_processdefinition.xml"); ClassPathResource processDef = new ClassPathResource("org/alfresco/repo/workflow/jbpm/review_and_approve_processdefinition.xml");
WorkflowDeployment deployment = workflowComponent.deployDefinition(processDef.getInputStream(), MimetypeMap.MIMETYPE_XML); WorkflowDeployment deployment = workflowComponent.deployDefinition(processDef.getInputStream(), MimetypeMap.MIMETYPE_XML);
testWorkflowDef = deployment.definition; testWorkflowDef = deployment.definition;
@ -93,7 +81,6 @@ public class ReviewAndApproveTest extends BaseSpringTest
// get valid node ref // get valid node ref
NodeService nodeService = (NodeService)applicationContext.getBean(ServiceRegistry.NODE_SERVICE.getLocalName()); NodeService nodeService = (NodeService)applicationContext.getBean(ServiceRegistry.NODE_SERVICE.getLocalName());
testNodeRef = nodeService.getRootNode(new StoreRef(StoreRef.PROTOCOL_WORKSPACE, "spacesStore")); testNodeRef = nodeService.getRootNode(new StoreRef(StoreRef.PROTOCOL_WORKSPACE, "spacesStore"));
nodeService.setProperty(testNodeRef, ContentModel.PROP_CREATED, new Date());
} }
@Override @Override
@ -103,12 +90,14 @@ public class ReviewAndApproveTest extends BaseSpringTest
} }
public void testWorkflowPackage() public void testSubmitForReview()
{ {
WorkflowDefinition workflowDef = testWorkflowDef; WorkflowDefinition workflowDef = testWorkflowDef;
Map<QName, Serializable> params = new HashMap<QName, Serializable>(); Map<QName, Serializable> params = new HashMap<QName, Serializable>();
params.put(WorkflowModel.ASSOC_PACKAGE, testNodeRef); params.put(WorkflowModel.ASSOC_PACKAGE, testNodeRef);
Date reviewDueDate = new Date();
params.put(QName.createQName("http://www.alfresco.org/model/workflow/1.0", "reviewDueDate"), reviewDueDate);
NodeRef reviewer = personService.getPerson("admin"); NodeRef reviewer = personService.getPerson("admin");
params.put(QName.createQName("http://www.alfresco.org/model/workflow/1.0", "reviewer"), reviewer); params.put(QName.createQName("http://www.alfresco.org/model/workflow/1.0", "reviewer"), reviewer);
@ -127,6 +116,7 @@ public class ReviewAndApproveTest extends BaseSpringTest
assignedTasks = filterTasksByWorkflowInstance(assignedTasks, path.instance.id); assignedTasks = filterTasksByWorkflowInstance(assignedTasks, path.instance.id);
assertEquals(testNodeRef, assignedTasks.get(0).properties.get(WorkflowModel.ASSOC_PACKAGE)); assertEquals(testNodeRef, assignedTasks.get(0).properties.get(WorkflowModel.ASSOC_PACKAGE));
assertEquals(reviewDueDate, assignedTasks.get(0).properties.get(WorkflowModel.PROP_DUE_DATE));
} }
/** /**

View File

@ -2,47 +2,61 @@
<process-definition xmlns="urn:jbpm.org:jpdl-3.1" name="wf:review"> <process-definition xmlns="urn:jbpm.org:jpdl-3.1" name="wf:review">
<swimlane name="initiator"></swimlane> <swimlane name="initiator"/>
<start-state name="start"> <start-state name="start">
<task name="wf:submitReviewTask" swimlane="Initiator" blocking="true"> <task name="wf:submitReviewTask" swimlane="initiator">
<controller> <controller>
<variable name="reviewer" access="write,required" mapped-name="wf:reviewer"/> <variable name="reviewer" access="write" mapped-name="wf:reviewer"/>
<variable name="package" access="write,required" mapped-name="bpm:package"/> <variable name="reviewduedate" access="write" mapped-name="wf:reviewDueDate"/>
<variable name="reviewpriority" access="write" mapped-name="wf:reviewPriority"/>
<variable name="package" access="write" mapped-name="bpm:package"/>
</controller> </controller>
</task> </task>
<transition name="" to="Review"></transition> <transition name="" to="review"/>
<transition name="end" to="end"></transition>
</start-state> </start-state>
<swimlane name="Reviewer">
<assignment actor-id="#{reviewer.properties['cm:userName']}"></assignment> <swimlane name="reviewer">
<assignment actor-id="#{reviewer.properties['cm:userName']}"/>
</swimlane> </swimlane>
<task-node name="Review">
<task name="Review" duedate="1 business day" blocking="true" swimlane="Reviewer"> <task-node name="review">
<task name="wf:review" swimlane="reviewer">
<event type="task-create">
<script>
taskInstance.dueDate = reviewduedate;
// taskInstance.priority = reviewpriority;
</script>
</event>
<controller> <controller>
<variable name="comment" access="read,write,required"></variable> <variable name="comment" access="read,write,required"/>
<variable name="package" access="read,required" mapped-name="bpm:package"/> <variable name="package" access="read,required" mapped-name="bpm:package"/>
</controller> </controller>
</task> </task>
<transition name="reject" to="Rejected"></transition> <transition name="reject" to="rejected"/>
<transition name="approve" to="Approved"></transition> <transition name="approve" to="approved"/>
</task-node> </task-node>
<task-node name="Rejected">
<task name="Rejected" swimlane="Initiator"> <task-node name="rejected">
<task name="wf:rejected" swimlane="initiator">
<controller> <controller>
<variable name="comment" access="read"></variable> <variable name="comment" access="read"/>
<variable name="package" access="read,required" mapped-name="bpm:package"/> <variable name="package" access="read,required" mapped-name="bpm:package"/>
</controller> </controller>
</task> </task>
<transition name="" to="end"></transition> <transition name="" to="end"/>
</task-node> </task-node>
<task-node name="Approved">
<task name="Approved" swimlane="Initiator"> <task-node name="approved">
<task name="wf:approved" swimlane="initiator">
<controller> <controller>
<variable name="comment" access="read"></variable> <variable name="comment" access="read"/>
<variable name="package" access="read,required" mapped-name="bpm:package"/> <variable name="package" access="read,required" mapped-name="bpm:package"/>
</controller> </controller>
</task> </task>
<transition name="" to="end"></transition> <transition name="" to="end"/>
</task-node> </task-node>
<end-state name="end"></end-state>
<end-state name="end"/>
</process-definition> </process-definition>

View File

@ -30,8 +30,12 @@
<event type="node-enter"> <event type="node-enter">
<action class="org.alfresco.repo.workflow.jbpm.AlfrescoJavaScript"> <action class="org.alfresco.repo.workflow.jbpm.AlfrescoJavaScript">
<script> <script>
<!-- following line fails as it attempts to convert properties of children to javascript objects -->
<!-- except the beanshell line above has already pre-created the children without the javascript scope -->
<!-- object -->
<!-- var result = "testNode.created: " + testNode.properties["cm:created"] + ", testNode.children.length: " + testNode.children[0].properties["cm:name"]; -->
<expression> <expression>
var result = "testNode.created: " + testNode.properties["cm:created"]; var result = "testNode.created: " + testNode.properties["cm:created"] + ", testNode.children.length: " + testNode.children.length;
result; result;
</expression> </expression>
<variable name="testNode" access="read"/> <variable name="testNode" access="read"/>

View File

@ -72,6 +72,12 @@ public interface NamespaceService extends NamespacePrefixResolver
/** Business Process Model Prefix */ /** Business Process Model Prefix */
public static final String BPM_MODEL_PREFIX = "bpm"; public static final String BPM_MODEL_PREFIX = "bpm";
/** Workflow Model URI */
public static final String WORKFLOW_MODEL_1_0_URI = "http://www.alfresco.org/model/workflow/1.0";
/** Workflow Model Prefix */
public static final String WORKFLOW_MODEL_PREFIX = "wf";
/** Alfresco View Namespace URI */ /** Alfresco View Namespace URI */
public static final String REPOSITORY_VIEW_1_0_URI = "http://www.alfresco.org/view/repository/1.0"; public static final String REPOSITORY_VIEW_1_0_URI = "http://www.alfresco.org/view/repository/1.0";