diff --git a/config/alfresco/activiti-context.xml b/config/alfresco/activiti-context.xml
new file mode 100644
index 0000000000..9d8566e264
--- /dev/null
+++ b/config/alfresco/activiti-context.xml
@@ -0,0 +1,172 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/config/alfresco/bootstrap-context.xml b/config/alfresco/bootstrap-context.xml
index 8e19af941c..5d0d8183eb 100644
--- a/config/alfresco/bootstrap-context.xml
+++ b/config/alfresco/bootstrap-context.xml
@@ -288,6 +288,46 @@
text/xml
false
+
+
+
+ activiti
+ alfresco/workflow/adhoc.bpmn20.xml
+ text/xml
+ false
+
+
+
+
+ activiti
+ alfresco/workflow/review.bpmn20.xml
+ text/xml
+ false
+
+
+
+
+ activiti
+ alfresco/workflow/review-pooled.bpmn20.xml
+ text/xml
+ false
+
+
+
+
+ activiti
+ alfresco/workflow/parallel-review.bpmn20.xml
+ text/xml
+ false
+
+
+
+
+ activiti
+ alfresco/workflow/parallel-review-group.bpmn20.xml
+ text/xml
+ false
+
diff --git a/config/alfresco/core-services-context.xml b/config/alfresco/core-services-context.xml
index 3a2a8b77e4..40c225ff1a 100644
--- a/config/alfresco/core-services-context.xml
+++ b/config/alfresco/core-services-context.xml
@@ -478,6 +478,7 @@
alfresco.messages.avm-messages
alfresco.messages.content-filter-languages
alfresco.messages.jbpm-engine-messages
+ alfresco.messages.activiti-engine-messages
diff --git a/config/alfresco/extension/activiti-adhoc-timer-messages.properties.sample b/config/alfresco/extension/activiti-adhoc-timer-messages.properties.sample
new file mode 100644
index 0000000000..dffb291c2b
--- /dev/null
+++ b/config/alfresco/extension/activiti-adhoc-timer-messages.properties.sample
@@ -0,0 +1,3 @@
+# For Activiti Timer Workflow Example
+activitiAdhocTimer.workflow.title=Activiti Adhoc Timer
+activitiAdhocTimer.workflow.description=Activiti Adhoc Timer Sample Process
\ No newline at end of file
diff --git a/config/alfresco/extension/activiti-adhoc-timer-workflow-context.xml.sample b/config/alfresco/extension/activiti-adhoc-timer-workflow-context.xml.sample
new file mode 100644
index 0000000000..1c6248958b
--- /dev/null
+++ b/config/alfresco/extension/activiti-adhoc-timer-workflow-context.xml.sample
@@ -0,0 +1,22 @@
+
+
+
+
+
+
+
+
+ activiti
+ alfresco/extension/activiti-adhoc-timer.bpmn20.xml
+ text/xml
+ false
+
+
+
+
+
+ alfresco/extension/activiti-adhoc-timer-messages
+
+
+
+
diff --git a/config/alfresco/extension/activiti-adhoc-timer.bpmn20.xml.sample b/config/alfresco/extension/activiti-adhoc-timer.bpmn20.xml.sample
new file mode 100644
index 0000000000..58cacbf13d
--- /dev/null
+++ b/config/alfresco/extension/activiti-adhoc-timer.bpmn20.xml.sample
@@ -0,0 +1,106 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ if (typeof bpm_workflowDueDate != 'undefined') task.setVariableLocal('bpm_dueDate', bpm_workflowDueDate);
+ if (typeof bpm_workflowPriority != 'undefined') task.priority = bpm_workflowPriority;
+
+
+
+
+
+
+ ${bpm_assignee.properties.userName}
+
+
+
+
+
+
+
+
+ PT1H
+
+
+
+
+
+
+
+ The urgent task was completed on time by ${bpm_assignee.properties.userName}.
+
+
+
+
+
+ if (typeof bpm_workflowDueDate != 'undefined') task.setVariableLocal('bpm_dueDate', bpm_workflowDueDate);
+ if (typeof bpm_workflowPriority != 'undefined') task.priority = bpm_workflowPriority;
+
+
+
+
+
+
+ ${initiator.properties.userName}
+
+
+
+
+
+
+ The urgent task was NOT completed on time by ${bpm_assignee.properties.userName}.
+
+
+
+
+
+ if (typeof bpm_workflowDueDate != 'undefined') task.setVariableLocal('bpm_dueDate', bpm_workflowDueDate);
+ if (typeof bpm_workflowPriority != 'undefined') task.priority = bpm_workflowPriority;
+
+
+
+
+
+
+ ${initiator.properties.userName}
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/config/alfresco/extension/lifecycle-messages.properties.sample b/config/alfresco/extension/lifecycle-messages.properties.sample
index 0d41867744..1b28f212e4 100644
--- a/config/alfresco/extension/lifecycle-messages.properties.sample
+++ b/config/alfresco/extension/lifecycle-messages.properties.sample
@@ -1,7 +1,11 @@
-# For Lifecycle Workflow Example
+# For JBPM Lifecycle Workflow Example
wfl_lifecycleapproval.workflow.title=Lifecycle Review & Approve
wfl_lifecycleapproval.workflow.description=Lifecycle Review & Approval workflow (Auto updates document status)
wfl_lifecycleapproval.node.review.transition.reject.title=Reject
wfl_lifecycleapproval.node.review.transition.reject.description=Reject
wfl_lifecycleapproval.node.review.transition.approve.title=Approve
-wfl_lifecycleapproval.node.review.transition.approve.description=Approve
\ No newline at end of file
+wfl_lifecycleapproval.node.review.transition.approve.description=Approve
+
+# For Activiti Lifecycle Workflow Example
+activitiLifecycleApproval=Lifecycle Review & Approve
+activitiLifecycleApproval=Lifecycle Review & Approval workflow Activiti (Auto updates document status)
\ No newline at end of file
diff --git a/config/alfresco/extension/lifecycle-process.bpmn20.xml.sample b/config/alfresco/extension/lifecycle-process.bpmn20.xml.sample
new file mode 100644
index 0000000000..09fa0c48fb
--- /dev/null
+++ b/config/alfresco/extension/lifecycle-process.bpmn20.xml.sample
@@ -0,0 +1,173 @@
+
+
+
+
+
+
+
+
+
+
+ if(cancelled || deleted) {
+ for (var i = 0; i < bpm_package.children.length; i++)
+ {
+ if (!bpm_package.children[i].hasAspect("wfl:status"))
+ {
+ bpm_package.children[i].properties["wfl:status"] = "Draft";
+ bpm_package.children[i].save();
+ }
+ }
+ }
+
+
+
+
+
+
+
+
+
+
+
+ for (var i = 0; i < bpm_package.children.length; i++)
+ {
+ if (!bpm_package.children[i].hasAspect("wfl:status"))
+ {
+ bpm_package.children[i].addAspect("wfl:status");
+ }
+ }
+
+
+
+
+
+
+
+
+
+
+
+ if (typeof bpm_workflowDueDate != 'undefined') task.setVariableLocal('bpm_dueDate', bpm_workflowDueDate);
+ if (typeof bpm_workflowPriority != 'undefined') task.priority = bpm_workflowPriority;
+
+ for (var i = 0; i < bpm_package.children.length; i++)
+ {
+ if (bpm_package.children[0].hasAspect("wfl:status")) {
+ bpm_package.children[i].properties["wfl:status"] = "In Review";
+ bpm_package.children[i].save();
+ }
+ }
+
+
+
+
+
+
+ execution.setVariable('wf_reviewOutcome', task.getVariable('wf_reviewOutcome'));
+
+
+
+
+
+
+ ${bpm_assignee.properties.userName}
+
+
+
+
+
+
+
+
+
+ ${wf_reviewOutcome == 'Approve'}
+
+
+
+
+
+
+ The document was reviewed and approved.
+
+
+
+
+
+ if (typeof bpm_workflowDueDate != 'undefined') task.setVariableLocal('bpm_dueDate', bpm_workflowDueDate);
+ if (typeof bpm_workflowPriority != 'undefined') task.priority = bpm_workflowPriority;
+
+ for (var i = 0; i < bpm_package.children.length; i++)
+ {
+ if (bpm_package.children[0].hasAspect("wfl:status")) {
+ bpm_package.children[i].properties["wfl:status"] = "Approved";
+ bpm_package.children[i].save();
+ }
+ }
+
+
+
+
+
+
+ ${initiator.properties.userName}
+
+
+
+
+
+
+ The document was reviewed and rejected.
+
+
+
+
+
+ if (typeof bpm_workflowDueDate != 'undefined') task.setVariableLocal('bpm_dueDate', bpm_workflowDueDate);
+ if (typeof bpm_workflowPriority != 'undefined') task.priority = bpm_workflowPriority;
+
+ for (var i = 0; i < bpm_package.children.length; i++)
+ {
+ if (bpm_package.children[0].hasAspect("wfl:status"))
+ {
+ bpm_package.children[i].properties["wfl:status"] = "Draft";
+ bpm_package.children[i].save();
+ }
+ }
+
+
+
+
+
+
+ ${initiator.properties.userName}
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/config/alfresco/extension/lifecycle-workflow-context.xml.sample b/config/alfresco/extension/lifecycle-workflow-context.xml.sample
index e2668b7b63..650c878a19 100644
--- a/config/alfresco/extension/lifecycle-workflow-context.xml.sample
+++ b/config/alfresco/extension/lifecycle-workflow-context.xml.sample
@@ -6,12 +6,20 @@
+
jbpm
alfresco/extension/lifecycle_processdefinition.xml
text/xml
false
+
+
+ activiti
+ alfresco/extension/lifecycle-process.bpmn20.xml
+ text/xml
+ false
+
diff --git a/config/alfresco/messages/activiti-engine-messages.properties b/config/alfresco/messages/activiti-engine-messages.properties
new file mode 100644
index 0000000000..36227e3ab6
--- /dev/null
+++ b/config/alfresco/messages/activiti-engine-messages.properties
@@ -0,0 +1,54 @@
+activiti.engine.mandatory.properties.missing=Mandatory task properties have not been provided! {0}
+activiti.engine.deploy.workflow.error=Failed to deploy workflow definition.
+activiti.engine.is.workflow.deployed.error=Failed to determine if workflow definition is already deployed.
+activiti.engine.undeploy.workflow.error=Failed to undeploy workflow definition {0}.
+activiti.engine.undeploy.workflow.unexisting.error=Failed to undeploy unexisting workflow definition {0}.
+activiti.engine.get.workflow.definition.error=Failed to retrieve workflow definitions.
+activiti.engine.get.workflow.definition.by.id.error=Failed to retrieve workflow definition for id {0}.
+activiti.engine.get.workflow.definition.by.name.error=Failed to retrieve workflow definition for name {0}.
+activiti.engine.get.all.workflow.definitions.by.name.error=Failed to retrieve all definitions for workflow {0}.
+activiti.engine.get.workflow.definition.image.error=Failed to retrieve workflow definition image for {0}.
+activiti.engine.get.workflow.definition.unexisting.image.error=Failed to retrieve workflow definition image for {0}, the definition does not exist.
+activiti.engine.get.task.definitions.error=Failed to retrieve workflow task definitions for workflow definition {0}.
+activiti.engine.get.process.definition.error=Workflow definition {0} does not exist.
+activiti.engine.start.workflow.error=Failed to start workflow {0}.
+activiti.engine.start.workflow.no.start.task.error=Failed to start workflow {0}, no start task defined on process definition.
+activiti.engine.get.workflows.error=Failed to retrieve workflow instances for definition {0}.
+activiti.engine.get.active.workflows.error=Failed to retrieve workflow instances for definition {0}.
+activiti.engine.get.completed.workflows.error=Failed to retrieve workflow instances for definition {0}.
+activiti.engine.get.workflow.instance.by.id.error=Failed to retrieve workflow instance with Id {0}.
+activiti.engine.get.process.instance.error=Workflow instance does not exist for Id {0}.
+activiti.engine.get.workflow.paths.error=Failed to retrieve workflow paths for workflow instance {0}.
+activiti.engine.get.path.properties.error=Failed to retrieve properties of path {0}.
+activiti.engine.cancel.workflow.error=Failed to cancel workflow instance {0}.
+activiti.engine.cancel.unexisting.workflow.error=Failed to cancel unexisting workflow instance {0}.
+activiti.engine.delete.workflow.error=Failed to delete workflow instance {0}.
+activiti.engine.delete.unexisting.workflow.error=Failed to delete unexisting workflow instance {0}.
+activiti.engine.signal.transition.error=Failed to signal transition {0} from workflow path {1}..
+activiti.engine.event.unsupported=Firing events is not supported on WorkflowPaths runnin in the Activiti engine.
+activiti.engine.fire.event.error=Failed to fire event {0} on workflow path {1}.
+activiti.engine.get.tasks.for.path.error=Failed to retrieve tasks assigned to Workflow path {0}.
+activiti.engine.get.timers.error=Could not retrieve any timers for workflow {0}.
+activiti.engine.find.completed.task.instances.error=Failed to retrieve completed task instances list for actor {0}.
+activiti.engine.get.assigned.tasks.error=Failed to retrieve tasks assigned to authority {0} in state {1}.
+activiti.engine.get.pooled.tasks.error=Failed to retrieve pooled tasks for authorities {0}.
+activiti.engine.query.tasks.error=Failed to query tasks. Query: {0}.
+activiti.engine.get.task.instance.error=Task instance {0} does not exist.
+activiti.engine.update.task.error=Failed to update workflow task {0}.
+activiti.engine.update.task.unexisting.error=Failed to update workflow task {0}, the task doesn't exist.
+activiti.engine.update.starttask.illegal.error=Failed to update workflow task {0}, start tasks cannot be updated in activiti.
+activiti.engine.end.task.invalid.transition=Transition {0} is invalid for Workflow task {1}, only transition {1} is allowed.
+activiti.engine.end.task.unexisting.error=Failed to signal transition on task {0}, the task doesn't exist.
+activiti.engine.end.task.error=Failed to signal transition {0} from workflow task {1}.
+activiti.engine.get.task.by.id.error=Failed to retrieve task {0}.
+activiti.engine.compile.process.definition.zip.error=Failed to parse process definition from activiti zip archive stream.
+activiti.engine.compile.process.definition.xml.error=Failed to parse process definition from activiti xml stream.
+activiti.engine.compile.process.definition.unsupported.error=Failed to parse process definition - unsupported mime type {0}
+activiti.engine.get.activiti.id.error=Format of id {0} is invalid.
+activiti.engine.get.workflow.token.invalid=Invalid workflow path {0}.
+activiti.engine.get.workflow.token.is.null=Workflow path {0} does not exist.
+activiti.engine.set.task.properties.invalid.value=The value {0} is invalid for the task property {1}.
+activiti.engine.package.already.associated.error=Cannot associate workflow package {0} with workflow instance {1} as its already associated with workflow instance {2}".
+activiti.engine.convert.value.error=Unable to convert activiti value {0} to Alfresco Value since it is not Serializable.
+activiti.engine.get.company.home.invalid=Invalid company home path {0}.
+activiti.engine.get.company.home.multiple=Invalid company home path {0}. Expected 1 match but found {1} matches.
\ No newline at end of file
diff --git a/config/alfresco/messages/bpm-messages.properties b/config/alfresco/messages/bpm-messages.properties
index 242036920c..cc68f91eb1 100644
--- a/config/alfresco/messages/bpm-messages.properties
+++ b/config/alfresco/messages/bpm-messages.properties
@@ -70,3 +70,7 @@ bpm_businessprocessmodel.association.bpm_groupAssignee.title=Workflow Group Assi
bpm_businessprocessmodel.association.bpm_groupAssignee.description=Workflow Group Assignee
bpm_businessprocessmodel.association.bpm_groupAssignees.title=Workflow Group Assignees
bpm_businessprocessmodel.association.bpm_groupAssignees.description=Workflow Group Assignees
+
+# Error Messages
+workflow.get.task.definition.metadata.error=Failed to find task type definition {0}.
+workflow.package.already.associated.error=This node is already being used as a workflow package! NodeRef: {0}
\ No newline at end of file
diff --git a/config/alfresco/messages/jbpm-engine-messages.properties b/config/alfresco/messages/jbpm-engine-messages.properties
index b47470bf71..55b09a012f 100644
--- a/config/alfresco/messages/jbpm-engine-messages.properties
+++ b/config/alfresco/messages/jbpm-engine-messages.properties
@@ -31,15 +31,14 @@ jbpm.engine.update.task.error=Failed to update workflow task {0}.
jbpm.engine.end.task.invalid.transition=Transition {0} is invalid for Workflow task {1}.
jbpm.engine.end.task.error=Failed to signal transition {0} from workflow task {1}.
jbpm.engine.get.task.by.id.error=Failed to retrieve task {0}.
+jbpm.engine.get.start.task.error=Failed to retrieve start task for workflow instance {0}.
jbpm.engine.compile.process.definition.zip.error=Failed to parse process definition from jBPM zip archive stream.
jbpm.engine.compile.process.definition.xml.error=Failed to parse process definition from jBPM xml stream.
jbpm.engine.compile.process.definition.unsupported.error=Failed to parse process definition - unsupported mime type {0}
-jbpm.engine.get.task.definition.error=Failed to find type definition {0}.
jbpm.engine.get.jbpm.id.error=Format of id {0} is invalid.
jbpm.engine.get.workflow.token.invalid=Invalid workflow path {0}.
jbpm.engine.get.workflow.token.is.null=Workflow path {0} does not exist.
jbpm.engine.set.task.properties.invalid.value=The value {0} is invalid for the task property {1}.
-jbpm.engine.package.already.associated.error=Cannot associate workflow package {0} with workflow instance {1} as its already associated with workflow instance {2}".
jbpm.engine.convert.value.error=Unable to convert jBPM value {0} to Alfresco Value since it is not Serializable.
jbpm.engine.get.company.home.invalid=Invalid company home path {0}.
jbpm.engine.get.company.home.multiple=Invalid company home path {0}. Expected 1 match but found {1} matches.
\ No newline at end of file
diff --git a/config/alfresco/messages/workflow-interpreter-help.txt b/config/alfresco/messages/workflow-interpreter-help.txt
index 096b372290..86e9889f21 100644
--- a/config/alfresco/messages/workflow-interpreter-help.txt
+++ b/config/alfresco/messages/workflow-interpreter-help.txt
@@ -37,11 +37,12 @@
class path to workflow definition file.
- ok> deploy
+ ok> deploy
Deploy workflow definition to Alfresco server.
class path to workflow definition.
+ workflow engine name (eg. activiti)
ok> redeploy
diff --git a/config/alfresco/messages/workflow-package-messages.properties b/config/alfresco/messages/workflow-package-messages.properties
new file mode 100644
index 0000000000..68c24f681a
--- /dev/null
+++ b/config/alfresco/messages/workflow-package-messages.properties
@@ -0,0 +1,3 @@
+
+# Error Messages
+workflow.package.already.associated.error=Cannot associate workflow package {0} with workflow instance {1} as its already associated with workflow instance {2}".
diff --git a/config/alfresco/model/bpmModel.xml b/config/alfresco/model/bpmModel.xml
index 72d13d8eee..010bab12a8 100644
--- a/config/alfresco/model/bpmModel.xml
+++ b/config/alfresco/model/bpmModel.xml
@@ -184,7 +184,7 @@
false
-
+
sys:base
false
true
@@ -271,6 +271,19 @@
+
+
+
+
+
+ bpm:workflowTask
+
+
+
+ d:qname
+
+
+
diff --git a/config/alfresco/patch/patch-services-context.xml b/config/alfresco/patch/patch-services-context.xml
index 94b54a2027..7ec1014431 100644
--- a/config/alfresco/patch/patch-services-context.xml
+++ b/config/alfresco/patch/patch-services-context.xml
@@ -1792,8 +1792,8 @@
classpath:alfresco/dbscripts/create/${db.script.dialect}/AlfrescoCreate-PropertyValueTables.sql
-
-
+
+
patch.db-V3.2-AuditTables
patch.schemaUpgradeScript.description
0
diff --git a/config/alfresco/version.properties b/config/alfresco/version.properties
index 14e12b263d..e93b7c3545 100644
--- a/config/alfresco/version.properties
+++ b/config/alfresco/version.properties
@@ -7,7 +7,7 @@
version.major=3
version.minor=4
version.revision=0
-version.label=d
+version.label=e
# Edition label
diff --git a/config/alfresco/workflow-context.xml b/config/alfresco/workflow-context.xml
index 596de6b2e4..5cecc77b2d 100644
--- a/config/alfresco/workflow-context.xml
+++ b/config/alfresco/workflow-context.xml
@@ -40,6 +40,7 @@
+
@@ -80,8 +81,12 @@
-
+
+
+
+
+
@@ -100,20 +105,21 @@
-
-
-
-
${spaces.store}
/${spaces.company_home.childname}
-
+
+
+
+
+
+
diff --git a/config/alfresco/workflow/adhoc.bpmn20.xml b/config/alfresco/workflow/adhoc.bpmn20.xml
new file mode 100644
index 0000000000..7f11df1dea
--- /dev/null
+++ b/config/alfresco/workflow/adhoc.bpmn20.xml
@@ -0,0 +1,82 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ if (typeof bpm_workflowDueDate != 'undefined') task.setVariableLocal('bpm_dueDate', bpm_workflowDueDate);
+ if (typeof bpm_workflowPriority != 'undefined') task.priority = bpm_workflowPriority;
+
+
+
+
+
+
+ ${bpm_assignee.properties.userName}
+
+
+
+
+
+
+
+
+ Verify the arbitrary task was completed.
+
+
+
+
+
+ if (typeof bpm_workflowDueDate != 'undefined') task.setVariableLocal('bpm_dueDate', bpm_workflowDueDate);
+ if (typeof bpm_workflowPriority != 'undefined') task.priority = bpm_workflowPriority;
+
+ if (wf_notifyMe)
+ {
+ var mail = actions.create("mail");
+ mail.parameters.to = initiator.properties.email;
+ mail.parameters.subject = "Adhoc Task " + bpm_workflowDescription;
+ mail.parameters.from = bpm_assignee.properties.email;
+ mail.parameters.text = "It's done";
+ mail.execute(bpm_package);
+ }
+
+
+
+
+
+
+ ${initiator.properties.userName}
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/config/alfresco/workflow/parallel-review-group.bpmn20.xml b/config/alfresco/workflow/parallel-review-group.bpmn20.xml
new file mode 100644
index 0000000000..449915c219
--- /dev/null
+++ b/config/alfresco/workflow/parallel-review-group.bpmn20.xml
@@ -0,0 +1,171 @@
+
+
+
+
+
+
+
+
+
+
+ execution.setVariable('wf_approveCount', 0);
+ execution.setVariable('wf_actualPercent', 0);
+ execution.setVariable('wf_requiredPercent', wf_requiredApprovePercent);
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ var members = people.getMembers(bpm_groupAssignee);
+ var memberNames = new java.util.ArrayList();
+
+ for(var i in members) {
+ memberNames.add(members[i].properties.userName);
+ }
+ execution.setVariable('wf_groupMembers', memberNames);
+ execution.setVariable('wf_reviewerCount', memberNames.size());
+
+
+
+
+
+
+
+
+
+
+
+ if (typeof bpm_workflowDueDate != 'undefined') task.setVariableLocal('bpm_dueDate', bpm_workflowDueDate);
+ if (typeof bpm_workflowPriority != 'undefined') task.priority = bpm_workflowPriority;
+
+
+
+
+
+
+ if(task.getVariableLocal('wf_reviewOutcome') == 'Approve') {
+ var newApprovedCount = wf_approveCount + 1;
+ var newApprovedPercentage = (newApprovedCount / wf_reviewerCount) * 100;
+
+ execution.setVariable('wf_approveCount', newApprovedCount);
+ execution.setVariable('wf_actualPercent', newApprovedPercentage);
+ }
+
+
+
+
+
+
+
+ ${reviewAssignee}
+
+
+
+
+
+ wf_groupMembers
+
+ ${wf_actualPercent >= wf_requiredApprovePercent}
+
+
+
+
+
+
+
+
+ ${wf_actualPercent >= wf_requiredApprovePercent}
+
+
+
+
+
+
+ The document was reviewed and approved.
+
+
+
+
+
+ if (typeof bpm_workflowDueDate != 'undefined') task.setVariableLocal('bpm_dueDate', bpm_workflowDueDate);
+ if (typeof bpm_workflowPriority != 'undefined') task.priority = bpm_workflowPriority;
+
+ // Set parallel review params on task, to be kept in history
+ task.setVariableLocal('wf_reviewerCount', wf_reviewerCount);
+ task.setVariableLocal('wf_requiredPercent', wf_requiredPercent);
+ task.setVariableLocal('wf_actualPercent', wf_actualPercent);
+ task.setVariableLocal('wf_approveCount', wf_approveCount);
+
+
+
+
+
+
+ ${initiator.properties.userName}
+
+
+
+
+
+
+ The document was reviewed and rejected.
+
+
+
+
+
+ if (typeof bpm_workflowDueDate != 'undefined') task.setVariableLocal('bpm_dueDate', bpm_workflowDueDate);
+ if (typeof bpm_workflowPriority != 'undefined') task.priority = bpm_workflowPriority;
+
+ // Set parallel review params on task, to be kept in history
+ task.setVariableLocal('wf_reviewerCount', wf_reviewerCount);
+ task.setVariableLocal('wf_requiredPercent', wf_requiredPercent);
+ task.setVariableLocal('wf_actualPercent', wf_actualPercent);
+ task.setVariableLocal('wf_approveCount', wf_approveCount);
+
+
+
+
+
+
+ ${initiator.properties.userName}
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/config/alfresco/workflow/parallel-review.bpmn20.xml b/config/alfresco/workflow/parallel-review.bpmn20.xml
new file mode 100644
index 0000000000..de9a43b5ff
--- /dev/null
+++ b/config/alfresco/workflow/parallel-review.bpmn20.xml
@@ -0,0 +1,154 @@
+
+
+
+
+
+
+
+
+
+
+ execution.setVariable('wf_approveCount', 0);
+ execution.setVariable('wf_actualPercent', 0);
+ execution.setVariable('wf_reviewerCount', bpm_assignees.size());
+ execution.setVariable('wf_requiredPercent', wf_requiredApprovePercent);
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ if (typeof bpm_workflowDueDate != 'undefined') task.setVariableLocal('bpm_dueDate', bpm_workflowDueDate);
+ if (typeof bpm_workflowPriority != 'undefined') task.priority = bpm_workflowPriority;
+
+
+
+
+
+
+ if(task.getVariableLocal('wf_reviewOutcome') == 'Approve') {
+ var newApprovedCount = wf_approveCount + 1;
+ var newApprovedPercentage = (newApprovedCount / wf_reviewerCount) * 100;
+
+ execution.setVariable('wf_approveCount', newApprovedCount);
+ execution.setVariable('wf_actualPercent', newApprovedPercentage);
+ }
+
+
+
+
+
+
+
+ ${review_assignee.properties.userName}
+
+
+
+
+
+ bpm_assignees
+
+ ${wf_actualPercent >= wf_requiredApprovePercent}
+
+
+
+
+
+
+
+
+ ${wf_actualPercent >= wf_requiredApprovePercent}
+
+
+
+
+
+
+ The document was reviewed and approved.
+
+
+
+
+
+ if (typeof bpm_workflowDueDate != 'undefined') task.setVariableLocal('bpm_dueDate', bpm_workflowDueDate);
+ if (typeof bpm_workflowPriority != 'undefined') task.priority = bpm_workflowPriority;
+
+ // Set parallel review params on task, to be kept in history
+ task.setVariableLocal('wf_reviewerCount', wf_reviewerCount);
+ task.setVariableLocal('wf_requiredPercent', wf_requiredPercent);
+ task.setVariableLocal('wf_actualPercent', wf_actualPercent);
+ task.setVariableLocal('wf_approveCount', wf_approveCount);
+
+
+
+
+
+
+ ${initiator.properties.userName}
+
+
+
+
+
+
+ The document was reviewed and rejected.
+
+
+
+
+
+ if (typeof bpm_workflowDueDate != 'undefined') task.setVariableLocal('bpm_dueDate', bpm_workflowDueDate);
+ if (typeof bpm_workflowPriority != 'undefined') task.priority = bpm_workflowPriority;
+
+ // Set parallel review params on task, to be kept in history
+ task.setVariableLocal('wf_reviewerCount', wf_reviewerCount);
+ task.setVariableLocal('wf_requiredPercent', wf_requiredPercent);
+ task.setVariableLocal('wf_actualPercent', wf_actualPercent);
+ task.setVariableLocal('wf_approveCount', wf_approveCount);
+
+
+
+
+
+
+ ${initiator.properties.userName}
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/config/alfresco/workflow/review-pooled.bpmn20.xml b/config/alfresco/workflow/review-pooled.bpmn20.xml
new file mode 100644
index 0000000000..f6cdd9ed34
--- /dev/null
+++ b/config/alfresco/workflow/review-pooled.bpmn20.xml
@@ -0,0 +1,129 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ if (typeof bpm_workflowDueDate != 'undefined') task.setVariable('bpm_dueDate', bpm_workflowDueDate);
+ if (typeof bpm_workflowPriority != 'undefined') task.priority = bpm_workflowPriority;
+
+
+
+
+
+
+ execution.setVariable('wf_reviewOutcome', task.getVariable('wf_reviewOutcome'));
+
+
+
+
+
+
+
+ ${bpm_groupAssignee.properties.authorityName}
+
+
+
+
+
+
+
+
+
+ ${wf_reviewOutcome == 'Approve'}
+
+
+
+
+
+
+ The document was reviewed and approved.
+
+
+
+
+
+ if (typeof bpm_workflowDueDate != 'undefined') task.setVariableLocal('bpm_dueDate', bpm_workflowDueDate);
+ if (typeof bpm_workflowPriority != 'undefined') task.priority = bpm_workflowPriority;
+
+
+
+
+
+
+ execution.setVariable('bpm_assignee', person);
+
+
+
+
+
+
+ ${initiator.properties.userName}
+
+
+
+
+
+
+ The document was reviewed and rejected.
+
+
+
+
+
+ if (typeof bpm_workflowDueDate != 'undefined') task.setVariableLocal('bpm_dueDate', bpm_workflowDueDate);
+ if (typeof bpm_workflowPriority != 'undefined') task.priority = bpm_workflowPriority;
+
+
+
+
+
+
+ bpm_assignee = person;
+
+
+
+
+
+
+ ${initiator.properties.userName}
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/config/alfresco/workflow/review.bpmn20.xml b/config/alfresco/workflow/review.bpmn20.xml
new file mode 100644
index 0000000000..9c30cc7691
--- /dev/null
+++ b/config/alfresco/workflow/review.bpmn20.xml
@@ -0,0 +1,114 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ if (typeof bpm_workflowDueDate != 'undefined') task.setVariableLocal('bpm_dueDate', bpm_workflowDueDate);
+ if (typeof bpm_workflowPriority != 'undefined') task.priority = bpm_workflowPriority;
+
+
+
+
+
+
+ execution.setVariable('wf_reviewOutcome', task.getVariable('wf_reviewOutcome'));
+
+
+
+
+
+
+ ${bpm_assignee.properties.userName}
+
+
+
+
+
+
+
+
+
+ ${wf_reviewOutcome == 'Approve'}
+
+
+
+
+
+
+ The document was reviewed and approved.
+
+
+
+
+
+ if (typeof bpm_workflowDueDate != 'undefined') task.setVariableLocal('bpm_dueDate', bpm_workflowDueDate);
+ if (typeof bpm_workflowPriority != 'undefined') task.priority = bpm_workflowPriority;
+
+
+
+
+
+
+ ${initiator.properties.userName}
+
+
+
+
+
+
+ The document was reviewed and rejected.
+
+
+
+
+
+ if (typeof bpm_workflowDueDate != 'undefined') task.setVariableLocal('bpm_dueDate', bpm_workflowDueDate);
+ if (typeof bpm_workflowPriority != 'undefined') task.priority = bpm_workflowPriority;
+
+
+
+
+
+
+ ${initiator.properties.userName}
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/config/alfresco/workflow/workflow-messages.properties b/config/alfresco/workflow/workflow-messages.properties
index 3a0d830a81..345e247e4e 100644
--- a/config/alfresco/workflow/workflow-messages.properties
+++ b/config/alfresco/workflow/workflow-messages.properties
@@ -1,5 +1,9 @@
# Display labels for out-of-the-box Content-oriented Workflows
+####################
+# JBPM WORKFLOWS #
+####################
+
#
# Review & Approve Workflow
#
@@ -64,7 +68,9 @@ wf_workflowmodel.property.wf_requiredPercent.description=Required Approval Perce
wf_workflowmodel.property.wf_approveCount.title=Reviewers Who Approved
wf_workflowmodel.property.wf_approveCount.description=Reviewers who approved
wf_workflowmodel.property.wf_actualPercent.title=Actual Approval Percentage
-wf_workflowmodel.property.wf_actualPercentdescription=Actual approval percentage
+wf_workflowmodel.property.wf_actualPercent.description=Actual approval percentage
+wf_workflowmodel.property.wf_reviewOutcome.title=Review Outcome
+wf_workflowmodel.property.wf_reviewOutcome.description=Review Outcome
# Group Review & Approve Process Definitions
@@ -120,3 +126,60 @@ wf_workflowmodel.type.wf_adhocTask.title=Adhoc Task
wf_workflowmodel.type.wf_adhocTask.description=Adhoc Task allocated by colleague
wf_workflowmodel.type.wf_completedAdhocTask.title=Adhoc Task Completed
wf_workflowmodel.type.wf_completedAdhocTask.description=Adhoc Task Completed
+
+#######################
+# ACTIVITI WORKFLOWS #
+#######################
+
+#
+# Activiti Adhoc Task Workflow
+#
+
+activitiAdhoc.workflow.title=Activiti Adhoc
+activitiAdhoc.workflow.description=Assign Activiti task to colleague
+
+# Activiti Adhoc Task Definitions
+
+activitiAdhocmodel.type.wf_submitAdhocTask.title=Start Activiti Adhoc Task
+activitiAdhocmodel.type.wf_submitAdhocTask.description=Allocate Activiti task to colleague
+activitiAdhocmodel.property.wf_notifyMe.title=Notify Me
+activitiAdhocmodel.property.wf_notifyMe.description=Notify me when task is complete
+activitiAdhocmodel.type.wf_adhocTask.title=Activiti Adhoc Task
+activitiAdhocmodel.type.wf_adhocTask.description=Activiti Adhoc Task allocated by colleague
+activitiAdhocmodel.type.wf_completedAdhocTask.title=Activiti Adhoc Task Completed
+activitiAdhocmodel.type.wf_completedAdhocTask.description=Activiti Adhoc Task Completed
+
+#
+# Activiti Review & Approve Workflow
+#
+
+activitiReview.workflow.title=Activiti Review & Approve
+activitiReview.workflow.description=Review & approval of content
+
+# Activiti Review & Approve Task Definitions
+
+activitiReviewmodel.type.wf_submitReviewTask.title=Start Activiti Review
+activitiReviewmodel.type.wf_submitReviewTask.description=Submit documents for review & approval
+activitiReviewmodel.type.wf_reviewTask.title=Activiti Review
+activitiReviewmodel.type.wf_reviewTask.description=Review Documents to Approve or Reject them
+activitiReviewmodel.type.wf_rejectedTask.title=Rejected
+activitiReviewmodel.type.wf_rejectedTask.description=Rejected
+activitiReviewmodel.type.wf_approvedTask.title=Approved
+activitiReviewmodel.type.wf_approvedTask.description=Approved
+
+# Activiti Review & Approve Process Definitions
+
+activitiReview.node.start.title=Start
+activitiReview.node.start.description=Start
+activitiReview.node.review.title=Review
+activitiReview.node.review.description=Review
+activitiReview.node.rejected.title=Rejected
+activitiReview.node.rejected.description=Rejected
+activitiReview.task.wf_rejectedTask.title=Rejected
+wf_review.task.wf_rejectedTask.description=Rejected
+activitiReview.node.approved.title=Approved
+activitiReview.node.approved.description=Approved
+activitiReview.task.wf_approvedTask.title=Approved
+activitiReview.task.wf_approvedTask.description=Approved
+activitiReview.node.end.title=End
+activitiReview.node.end.description=End
diff --git a/config/alfresco/workflow/workflowModel.xml b/config/alfresco/workflow/workflowModel.xml
index bee2cb7edd..371444be5f 100644
--- a/config/alfresco/workflow/workflowModel.xml
+++ b/config/alfresco/workflow/workflowModel.xml
@@ -66,6 +66,36 @@
+
+ bpm:activitiOutcomeTask
+
+
+ d:text
+ Reject
+
+
+
+
+
+ Approve
+ Reject
+
+
+
+
+
+
+
+
+ edit_package_item_actions
+
+
+ {http://www.alfresco.org/model/workflow/1.0}reviewOutcome
+
+
+
+
bpm:workflowTask
diff --git a/source/java/org/alfresco/repo/forms/FormServiceImplTest.java b/source/java/org/alfresco/repo/forms/FormServiceImplTest.java
index be4277ff52..5de79d3191 100644
--- a/source/java/org/alfresco/repo/forms/FormServiceImplTest.java
+++ b/source/java/org/alfresco/repo/forms/FormServiceImplTest.java
@@ -34,9 +34,12 @@ import org.alfresco.repo.forms.FormData.FieldData;
import org.alfresco.repo.forms.PropertyFieldDefinition.FieldConstraint;
import org.alfresco.repo.forms.processor.node.FormFieldConstants;
import org.alfresco.repo.forms.processor.node.TypeFormProcessor;
+import org.alfresco.repo.forms.processor.workflow.TransitionFieldProcessor;
import org.alfresco.repo.jscript.ClasspathScriptLocation;
import org.alfresco.repo.security.permissions.AccessDeniedException;
+import org.alfresco.repo.security.person.TestPersonManager;
import org.alfresco.repo.workflow.WorkflowModel;
+import org.alfresco.repo.workflow.activiti.ActivitiConstants;
import org.alfresco.service.cmr.dictionary.DictionaryService;
import org.alfresco.service.cmr.repository.ContentData;
import org.alfresco.service.cmr.repository.ContentReader;
@@ -46,6 +49,7 @@ import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.ScriptLocation;
import org.alfresco.service.cmr.repository.ScriptService;
import org.alfresco.service.cmr.repository.StoreRef;
+import org.alfresco.service.cmr.security.MutableAuthenticationService;
import org.alfresco.service.cmr.security.PersonService;
import org.alfresco.service.cmr.workflow.WorkflowDefinition;
import org.alfresco.service.cmr.workflow.WorkflowInstance;
@@ -58,7 +62,6 @@ import org.alfresco.service.namespace.NamespaceService;
import org.alfresco.service.namespace.QName;
import org.alfresco.util.BaseAlfrescoSpringTest;
import org.alfresco.util.GUID;
-import org.alfresco.util.PropertyMap;
import org.springframework.util.StringUtils;
/**
@@ -72,10 +75,10 @@ public class FormServiceImplTest extends BaseAlfrescoSpringTest
private FormService formService;
private NamespaceService namespaceService;
private ScriptService scriptService;
- private PersonService personService;
private ContentService contentService;
private WorkflowService workflowService;
-
+ private TestPersonManager personManager;
+
private NodeRef document;
private NodeRef associatedDoc;
private NodeRef childDoc;
@@ -134,16 +137,19 @@ public class FormServiceImplTest extends BaseAlfrescoSpringTest
this.formService = (FormService)this.applicationContext.getBean("FormService");
this.namespaceService = (NamespaceService)this.applicationContext.getBean("NamespaceService");
this.scriptService = (ScriptService)this.applicationContext.getBean("ScriptService");
- this.personService = (PersonService)this.applicationContext.getBean("PersonService");
+ PersonService personService = (PersonService)this.applicationContext.getBean("PersonService");
this.contentService = (ContentService)this.applicationContext.getBean("ContentService");
this.workflowService = (WorkflowService)this.applicationContext.getBean("WorkflowService");
+ MutableAuthenticationService mutableAuthenticationService = (MutableAuthenticationService)applicationContext.getBean("AuthenticationService");
+ this.personManager = new TestPersonManager(mutableAuthenticationService, personService, nodeService);
+
// create users
- createUser(USER_ONE);
- createUser(USER_TWO);
+ personManager.createPerson(USER_ONE);
+ personManager.createPerson(USER_TWO);
// Do the tests as userOne
- authenticationComponent.setCurrentUser(USER_ONE);
+ personManager.setUser(USER_ONE);
String guid = GUID.generate();
@@ -224,23 +230,6 @@ public class FormServiceImplTest extends BaseAlfrescoSpringTest
this.nodeService.createAssociation(this.document, this.associatedDoc, ContentModel.ASSOC_REFERENCES);
}
- private void createUser(String userName)
- {
- if (this.authenticationService.authenticationExists(userName) == false)
- {
- this.authenticationService.createAuthentication(userName, "PWD".toCharArray());
-
- PropertyMap ppOne = new PropertyMap(4);
- ppOne.put(ContentModel.PROP_USERNAME, userName);
- ppOne.put(ContentModel.PROP_FIRSTNAME, "firstName");
- ppOne.put(ContentModel.PROP_LASTNAME, "lastName");
- ppOne.put(ContentModel.PROP_EMAIL, "email@email.com");
- ppOne.put(ContentModel.PROP_JOBTITLE, "jobTitle");
-
- this.personService.createPerson(ppOne);
- }
- }
-
@SuppressWarnings("unchecked")
public void testGetAllDocForm() throws Exception
{
@@ -775,7 +764,7 @@ public class FormServiceImplTest extends BaseAlfrescoSpringTest
String updatedTitle = (String)updatedProps.get(ContentModel.PROP_TITLE);
String updatedAuthor = (String)updatedProps.get(ContentModel.PROP_AUTHOR);
String updatedOriginator = (String)updatedProps.get(ContentModel.PROP_ORIGINATOR);
- List updatedAddressees = (List)updatedProps.get(ContentModel.PROP_ADDRESSEES);
+ List updatedAddressees = (List)updatedProps.get(ContentModel.PROP_ADDRESSEES);
String wrong = (String)updatedProps.get(QName.createQName("cm", "wrong", this.namespaceService));
Date sentDate = (Date)updatedProps.get(ContentModel.PROP_SENTDATE);
@@ -1085,7 +1074,7 @@ public class FormServiceImplTest extends BaseAlfrescoSpringTest
assertEquals(expectedContent, content);
}
- @SuppressWarnings({ "deprecation", "null", "unchecked" })
+ @SuppressWarnings({ "deprecation", "null" })
public void disabledTestFDKModel() throws Exception
{
// NOTE: The FDK is not loaded by default, for this test to work you must
@@ -1216,7 +1205,7 @@ public class FormServiceImplTest extends BaseAlfrescoSpringTest
assertEquals(duplicateValue, values.getFieldData(duplicatePropField.getDataKeyName()).getValue());
FieldData fieldData = values.getFieldData(duplicateAssocField.getDataKeyName());
assertNotNull(fieldData);
- List assocs = (List)fieldData.getValue();
+ List> assocs = (List>)fieldData.getValue();
assertNotNull(assocs);
assertEquals(0, assocs.size());
@@ -1264,10 +1253,20 @@ public class FormServiceImplTest extends BaseAlfrescoSpringTest
assertEquals(1, assocs.size());
}
- public void testGetFormForTask() throws Exception
+ public void testGetFormForJbpmTask() throws Exception
{
- WorkflowTask task = getWorkflowTask();
- Item item = new Item("task", task.id);
+ checkGetFormForTask("jbpm$wf:review");
+ }
+
+ public void testGetFormForActivitiTask() throws Exception
+ {
+ checkGetFormForTask("activiti$activitiReview");
+ }
+
+ private void checkGetFormForTask(String defName)
+ {
+ WorkflowTask task = getWorkflowTask(defName);
+ Item item = new Item("task", task.getId());
Form form = formService.getForm(item);
assertNotNull(form);
@@ -1276,34 +1275,112 @@ public class FormServiceImplTest extends BaseAlfrescoSpringTest
List fieldDefNames = form.getFieldDefinitionNames();
assertTrue(fieldDefNames.size() > 0);
+ // Check the correct field names are present.
List expFields = getExpectedTaskFields();
assertTrue(fieldDefNames.containsAll(expFields));
+
+ // Check default value for priority is correct.
+ List definitions = form.getFieldDefinitions();
+ String priorityName = WorkflowModel.PROP_PRIORITY.toPrefixString(namespaceService);
+ for (FieldDefinition definition : definitions)
+ {
+ if(priorityName.equals(definition.getName()))
+ {
+ assertEquals("2", definition.getDefaultValue());
+ break;
+ }
+ }
}
- public void testSaveTask() throws Exception
+ public void testSaveJbpmTask() throws Exception
{
- WorkflowTask task = getWorkflowTask();
+ checkSaveTask("jbpm$wf:review");
+ }
+
+ public void testSaveActivitiTask() throws Exception
+ {
+ checkSaveTask("activiti$activitiReview");
+ }
+
+ private void checkSaveTask(String defName)
+ {
+ WorkflowTask task = getWorkflowTask(defName);
QName descName = WorkflowModel.PROP_DESCRIPTION;
- Serializable initialDesc = task.properties.get(descName);
+ Serializable initialDesc = task.getProperties().get(descName);
String testDesc = "Foo-Bar-Test-String";
assertFalse(testDesc.equals(initialDesc));
- Item item = new Item("task", task.id);
+ Item item = new Item("task", task.getId());
FormData data = new FormData();
String descFieldName = FormFieldConstants.PROP_DATA_PREFIX
+ descName.toPrefixString(namespaceService).replace(":", "_");
data.addFieldData(descFieldName, testDesc, true);
formService.saveForm(item, data);
- WorkflowTask newTask = workflowService.getTaskById(task.id);
- assertEquals(testDesc, newTask.properties.get(descName));
+ WorkflowTask newTask = workflowService.getTaskById(task.getId());
+ assertEquals(testDesc, newTask.getProperties().get(descName));
+ }
+
+ public void testTransitionJbpmTask() throws Exception
+ {
+ checkTransitionTask("jbpm$wf:review", "approve", "approve");
+ }
+
+ public void testTransitionActivitiTask() throws Exception
+ {
+ checkTransitionTask("activiti$activitiReview", ActivitiConstants.DEFAULT_TRANSITION_NAME, "Approve");
+ }
+
+ private void checkTransitionTask(String defName, String transitionId, String expOutcome)
+ {
+ WorkflowTask task = getWorkflowTask(defName);
+ QName descName = WorkflowModel.PROP_DESCRIPTION;
+ Serializable initialDesc = task.getProperties().get(descName);
+ String testDesc = "Foo-Bar-Test-String";
+ assertFalse(testDesc.equals(initialDesc));
+
+ Item item = new Item("task", task.getId());
+ FormData data = new FormData();
+ String descFieldName = FormFieldConstants.PROP_DATA_PREFIX + descName.toPrefixString(namespaceService).replace(":", "_");
+ data.addFieldData(descFieldName, testDesc, true);
+
+ String reviewOutcomeFieldName = FormFieldConstants.PROP_DATA_PREFIX + "wf_reviewOutcome";
+ data.addFieldData(reviewOutcomeFieldName, "Approve", true);
+
+ String transitionDataKey = FormFieldConstants.PROP_DATA_PREFIX + TransitionFieldProcessor.KEY;
+ data.addFieldData(transitionDataKey, transitionId);
+
+ formService.saveForm(item, data);
+ WorkflowTask newTask = workflowService.getTaskById(task.getId());
+ assertEquals("The description should have been updated!", testDesc, newTask.getProperties().get(descName));
+
+ // Check the task is completed
+ assertEquals("The task should have been completed!", WorkflowTaskState.COMPLETED, newTask.getState());
+
+ Serializable outcome = newTask.getProperties().get(WorkflowModel.PROP_OUTCOME);
+ assertEquals("The transition is wrong!", expOutcome, outcome);
}
- private WorkflowTask getWorkflowTask()
+ private WorkflowTask getWorkflowTask(String definitionName)
{
- WorkflowDefinition reviewDef = workflowService.getDefinitionByName("jbpm$wf:review");
- WorkflowPath path = workflowService.startWorkflow(reviewDef.id, null);
- List tasks = workflowService.getTasksForWorkflowPath(path.id);
+ WorkflowDefinition reviewDef = workflowService.getDefinitionByName(definitionName);
+ Map properties = new HashMap();
+ properties.put(WorkflowModel.ASSOC_ASSIGNEE, personManager.get(USER_ONE));
+ properties.put(WorkflowModel.ASSOC_PACKAGE, folder);
+ WorkflowPath path = workflowService.startWorkflow(reviewDef.getId(), properties);
+ WorkflowTask task = getTaskForPath(path);
+ String startTaskId = reviewDef.getStartTaskDefinition().getId();
+ if (startTaskId.equals(task.getDefinition().getId()))
+ {
+ workflowService.endTask(task.getId(), null);
+ task = getTaskForPath(path);
+ }
+ return task;
+ }
+
+ private WorkflowTask getTaskForPath(WorkflowPath path)
+ {
+ List tasks = workflowService.getTasksForWorkflowPath(path.getId());
assertNotNull(tasks);
assertTrue(tasks.size() > 0);
WorkflowTask task = tasks.get(0);
@@ -1321,18 +1398,32 @@ public class FormServiceImplTest extends BaseAlfrescoSpringTest
return fields;
}
- public void testWorkflowForms() throws Exception
+ public void testJbpmWorkflowForm() throws Exception
+ {
+ checkWorkflowForms("jbpm_wf_adhoc", "|Task Done");
+ }
+
+ public void testActivitiWorkflowForm() throws Exception
+ {
+ checkWorkflowForms("activiti_activitiAdhoc", "Next|Next");
+ }
+
+ private void checkWorkflowForms(String workflowDefName, String transitionLabels) throws Exception
{
// generate a form for a well known workflow-definition supplying
// a legitimate set of fields for the workflow
List fields = new ArrayList(8);
- fields.add("bpm:taskId");
- fields.add("bpm:workflowDescription");
- fields.add("bpm:workflowDueDate");
- fields.add("packageItems");
+ String taskIdName = WorkflowModel.PROP_TASK_ID.toPrefixString(namespaceService);
+ String workflowDescName = WorkflowModel.PROP_WORKFLOW_DESCRIPTION.toPrefixString(namespaceService);
+ String workflowDueDateName = WorkflowModel.PROP_WORKFLOW_DUE_DATE.toPrefixString(namespaceService);
+ String packageItemsName = "packageItems";
+
+ fields.add(taskIdName);
+ fields.add(workflowDescName);
+ fields.add(workflowDueDateName);
+ fields.add(packageItemsName);
// Use URL-friendly format.
- String workflowDefName = "jbpm_wf_adhoc";
Form form = this.formService.getForm(new Item(WORKFLOW_FORM_ITEM_KIND, workflowDefName), fields);
// check a form got returned
@@ -1355,10 +1446,10 @@ public class FormServiceImplTest extends BaseAlfrescoSpringTest
}
// find the fields
- PropertyFieldDefinition idField = (PropertyFieldDefinition)fieldDefMap.get("bpm:taskId");
- PropertyFieldDefinition descriptionField = (PropertyFieldDefinition)fieldDefMap.get("bpm:workflowDescription");
- PropertyFieldDefinition dueDateField = (PropertyFieldDefinition)fieldDefMap.get("bpm:workflowDueDate");
- AssociationFieldDefinition packageItemsField = (AssociationFieldDefinition)fieldDefMap.get("packageItems");
+ PropertyFieldDefinition idField = (PropertyFieldDefinition)fieldDefMap.get(taskIdName);
+ PropertyFieldDefinition descriptionField = (PropertyFieldDefinition)fieldDefMap.get(workflowDescName);
+ PropertyFieldDefinition dueDateField = (PropertyFieldDefinition)fieldDefMap.get(workflowDueDateName);
+ AssociationFieldDefinition packageItemsField = (AssociationFieldDefinition)fieldDefMap.get(packageItemsName);
// check fields are present
assertNotNull("Expecting to find the bpm:taskId field", idField);
@@ -1367,45 +1458,48 @@ public class FormServiceImplTest extends BaseAlfrescoSpringTest
assertNotNull("Expecting to find the packageItems field", packageItemsField);
// get the number of tasks now
- List tasks = this.workflowService.getAssignedTasks(USER_ONE,
+ List tasks = workflowService.getAssignedTasks(USER_ONE,
WorkflowTaskState.IN_PROGRESS);
int tasksBefore = tasks.size();
// persist the form
FormData data = new FormData();
data.addFieldData("prop_bpm_workflowDescription", "This is a new adhoc task");
- data.addFieldData("assoc_bpm_assignee_added",
- this.personService.getPerson(USER_ONE).toString());
- data.addFieldData("assoc_packageItems_added", this.document.toString());
+ data.addFieldData("assoc_bpm_assignee_added", personManager.get(USER_ONE).toString());
+ data.addFieldData("assoc_packageItems_added", document.toString());
+
+// data.addFieldData("prop_bpm_workflowDueDate", new Date());
+// data.addFieldData("prop_bpm_workflowPriority", 1);
// persist the data
- WorkflowInstance workflow = (WorkflowInstance)this.formService.saveForm(
+ WorkflowInstance workflow = (WorkflowInstance)formService.saveForm(
new Item(WORKFLOW_FORM_ITEM_KIND, workflowDefName), data);
// verify that the workflow was started by checking the user has one
// more task and the details on the workflow instance
- tasks = this.workflowService.getAssignedTasks(USER_ONE,
- WorkflowTaskState.IN_PROGRESS);
+ tasks = workflowService.getAssignedTasks(USER_ONE, WorkflowTaskState.IN_PROGRESS);
int tasksAfter = tasks.size();
assertTrue("Expecting there to be more tasks", tasksAfter > tasksBefore);
// check workflow instance details
- assertEquals("jbpm$wf:adhoc", workflow.definition.name);
+ String actualWfName = workflow.getDefinition().getName();
+ assertEquals(workflowDefName, actualWfName.replace('$', '_').replace(':', '_'));
// get the task form and verify data
String taskId = tasks.get(0).getId();
fields.clear();
- fields.add("bpm:taskId");
+ fields.add(taskIdName);
fields.add("transitions");
fields.add("message");
fields.add("taskOwner");
- fields.add("packageItems");
- form = this.formService.getForm(new Item(TASK_FORM_ITEM_KIND, taskId), fields);
+ fields.add(packageItemsName);
+ form = formService.getForm(new Item(TASK_FORM_ITEM_KIND, taskId), fields);
FormData taskData = form.getFormData();
- assertEquals(taskId, "jbpm$" + taskData.getFieldData("prop_bpm_taskId").getValue().toString());
- assertEquals("|Task Done", taskData.getFieldData("prop_transitions").getValue());
- assertEquals("UserOne_FormServiceImplTest|firstName|lastName", taskData.getFieldData("prop_taskOwner").getValue());
+ assertEquals(taskId.substring(taskId.indexOf('$')+1), taskData.getFieldData("prop_bpm_taskId").getValue().toString());
+ assertEquals(transitionLabels, taskData.getFieldData("prop_transitions").getValue());
+ String expOwner = USER_ONE + "|" + personManager.getFirstName(USER_ONE) + "|" + personManager.getLastName(USER_ONE);
+ assertEquals(expOwner, taskData.getFieldData("prop_taskOwner").getValue());
assertEquals("This is a new adhoc task", taskData.getFieldData("prop_message").getValue());
assertNotNull(taskData.getFieldData("assoc_packageItems").getValue());
@@ -1413,7 +1507,7 @@ public class FormServiceImplTest extends BaseAlfrescoSpringTest
String comment = "This is a comment";
data = new FormData();
data.addFieldData("prop_bpm_comment", comment);
- this.formService.saveForm(new Item(TASK_FORM_ITEM_KIND, taskId), data);
+ formService.saveForm(new Item(TASK_FORM_ITEM_KIND, taskId), data);
// check the comment was updated
WorkflowTask task = workflowService.getTaskById(taskId);
@@ -1421,7 +1515,7 @@ public class FormServiceImplTest extends BaseAlfrescoSpringTest
assertEquals(comment, taskComment);
// make sure unauthorized user can not update the task
- authenticationComponent.setCurrentUser(USER_TWO);
+ personManager.setUser(USER_TWO);
try
{
@@ -1483,7 +1577,6 @@ public class FormServiceImplTest extends BaseAlfrescoSpringTest
}
}
- @SuppressWarnings("unchecked")
public void testFormData() throws Exception
{
FormData formData = new FormData();
@@ -1503,14 +1596,14 @@ public class FormServiceImplTest extends BaseAlfrescoSpringTest
assertTrue("Expecting 'multipleValues' to be a List object", (value instanceof List));
formData.addFieldData("multipleValues", "three");
- List list = (List)formData.getFieldData("multipleValues").getValue();
+ List> list = (List>)formData.getFieldData("multipleValues").getValue();
assertEquals("Expecting 'multipleValues' List to have 3 items", 3, list.size());
// add a List initially then add a value to it
- formData.addFieldData("listValue", new ArrayList());
+ formData.addFieldData("listValue", new ArrayList