diff --git a/config/alfresco/messages/bpm-messages.properties b/config/alfresco/messages/bpm-messages.properties
index 5fecac839f..8a8886cb2d 100644
--- a/config/alfresco/messages/bpm-messages.properties
+++ b/config/alfresco/messages/bpm-messages.properties
@@ -28,7 +28,6 @@ bpm_businessprocessmodel.association.bpm_pooledActors.title=Pooled Users
bpm_businessprocessmodel.association.bpm_pooledActors.title=The users who may take ownership of the task
# Workflow Task
-
bpm_businessprocessmodel.type.bpm_workflowTask.title=Worflow Task
bpm_businessprocessmodel.type.bpm_workflowTask.description=Task assigned by a Workflow
bpm_businessprocessmodel.property.bpm_workflowDefinitionId.title=Workflow Definition Id
diff --git a/config/alfresco/workflow-context.xml b/config/alfresco/workflow-context.xml
index 0a8f5871d8..71ca8e5bd1 100644
--- a/config/alfresco/workflow-context.xml
+++ b/config/alfresco/workflow-context.xml
@@ -45,6 +45,22 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/source/java/org/alfresco/repo/workflow/StartWorkflowActionExecuter.java b/source/java/org/alfresco/repo/workflow/StartWorkflowActionExecuter.java
new file mode 100644
index 0000000000..0aa6c80b6d
--- /dev/null
+++ b/source/java/org/alfresco/repo/workflow/StartWorkflowActionExecuter.java
@@ -0,0 +1,135 @@
+/*
+ * Copyright (C) 2005 Alfresco, Inc.
+ *
+ * Licensed under the Mozilla Public License version 1.1
+ * with a permitted attribution clause. You may obtain a
+ * copy of the License at
+ *
+ * http://www.alfresco.org/legal/license.txt
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
+ * either express or implied. See the License for the specific
+ * language governing permissions and limitations under the
+ * License.
+ */
+package org.alfresco.repo.workflow;
+
+import java.io.Serializable;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.alfresco.model.ContentModel;
+import org.alfresco.repo.action.ParameterDefinitionImpl;
+import org.alfresco.repo.action.executer.ActionExecuterAbstractBase;
+import org.alfresco.service.cmr.action.Action;
+import org.alfresco.service.cmr.action.ParameterDefinition;
+import org.alfresco.service.cmr.dictionary.DataTypeDefinition;
+import org.alfresco.service.cmr.repository.ChildAssociationRef;
+import org.alfresco.service.cmr.repository.NodeRef;
+import org.alfresco.service.cmr.repository.NodeService;
+import org.alfresco.service.cmr.workflow.WorkflowDefinition;
+import org.alfresco.service.cmr.workflow.WorkflowService;
+import org.alfresco.service.namespace.NamespaceService;
+import org.alfresco.service.namespace.QName;
+
+/**
+ * Simple workflow action executor
+ *
+ * @author Roy Wetherall
+ */
+public class StartWorkflowActionExecuter extends ActionExecuterAbstractBase
+{
+ public static final String NAME = "start-workflow";
+
+ public static final String PARAM_WORKFLOW_NAME = "workflowName";
+
+ // action dependencies
+ private NamespaceService namespaceService;
+ private WorkflowService workflowService;
+ private NodeService nodeService;
+
+
+ /**
+ * @param namespaceService
+ */
+ public void setNamespaceService(NamespaceService namespaceService)
+ {
+ this.namespaceService = namespaceService;
+ }
+
+ /**
+ * @param nodeService
+ */
+ public void setNodeService(NodeService nodeService)
+ {
+ this.nodeService = nodeService;
+ }
+
+ /**
+ * @param workflowService
+ */
+ public void setWorkflowService(WorkflowService workflowService)
+ {
+ this.workflowService = workflowService;
+ }
+
+
+ /* (non-Javadoc)
+ * @see org.alfresco.repo.action.ParameterizedItemAbstractBase#getAdhocPropertiesAllowed()
+ */
+ @Override
+ protected boolean getAdhocPropertiesAllowed()
+ {
+ return true;
+ }
+
+
+ /* (non-Javadoc)
+ * @see org.alfresco.repo.action.ParameterizedItemAbstractBase#addParameterDefinitions(java.util.List)
+ */
+ @Override
+ protected void addParameterDefinitions(List paramList)
+ {
+ paramList.add(new ParameterDefinitionImpl(PARAM_WORKFLOW_NAME, DataTypeDefinition.TEXT, false, getParamDisplayLabel(PARAM_WORKFLOW_NAME)));
+ // TODO: Start Task Template parameter
+ }
+
+
+ /* (non-Javadoc)
+ * @see org.alfresco.repo.action.executer.ActionExecuterAbstractBase#executeImpl(org.alfresco.service.cmr.action.Action, org.alfresco.service.cmr.repository.NodeRef)
+ */
+ @Override
+ protected void executeImpl(Action ruleAction, NodeRef actionedUponNodeRef)
+ {
+ // retrieve workflow definition
+ String workflowName = (String)ruleAction.getParameterValue(PARAM_WORKFLOW_NAME);
+ WorkflowDefinition def = workflowService.getDefinitionByName(workflowName);
+
+ // create workflow package to contain actioned upon node
+ NodeRef workflowPackage = (NodeRef)ruleAction.getParameterValue(WorkflowModel.ASSOC_PACKAGE.toPrefixString(namespaceService));
+ workflowPackage = workflowService.createPackage(workflowPackage);
+ ChildAssociationRef childAssoc = nodeService.getPrimaryParent(actionedUponNodeRef);
+ nodeService.addChild(workflowPackage, actionedUponNodeRef, ContentModel.ASSOC_CONTAINS, childAssoc.getQName());
+
+ // build map of workflow start task parameters
+ Map paramValues = ruleAction.getParameterValues();
+ Map workflowParameters = new HashMap();
+ workflowParameters.put(WorkflowModel.ASSOC_PACKAGE, workflowPackage);
+ for (Map.Entry entry : paramValues.entrySet())
+ {
+ if (!entry.getKey().equals(PARAM_WORKFLOW_NAME))
+ {
+ QName qname = QName.createQName(entry.getKey(), namespaceService);
+ Serializable value = entry.getValue();
+ workflowParameters.put(qname, value);
+ }
+ }
+
+ // start the workflow
+ workflowService.startWorkflow(def.id, workflowParameters);
+ }
+
+}
diff --git a/source/java/org/alfresco/repo/workflow/StartWorkflowActionExecuterTest.java b/source/java/org/alfresco/repo/workflow/StartWorkflowActionExecuterTest.java
new file mode 100644
index 0000000000..c9e271362a
--- /dev/null
+++ b/source/java/org/alfresco/repo/workflow/StartWorkflowActionExecuterTest.java
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 2005 Alfresco, Inc.
+ *
+ * Licensed under the Mozilla Public License version 1.1
+ * with a permitted attribution clause. You may obtain a
+ * copy of the License at
+ *
+ * http://www.alfresco.org/legal/license.txt
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
+ * either express or implied. See the License for the specific
+ * language governing permissions and limitations under the
+ * License.
+ */
+package org.alfresco.repo.workflow;
+
+import java.util.Date;
+
+import org.alfresco.model.ContentModel;
+import org.alfresco.repo.action.ActionImpl;
+import org.alfresco.repo.security.authentication.AuthenticationComponent;
+import org.alfresco.service.cmr.repository.NodeRef;
+import org.alfresco.service.cmr.repository.NodeService;
+import org.alfresco.service.cmr.repository.StoreRef;
+import org.alfresco.service.cmr.security.PersonService;
+import org.alfresco.service.namespace.NamespaceService;
+import org.alfresco.service.namespace.QName;
+import org.alfresco.util.BaseSpringTest;
+import org.alfresco.util.GUID;
+
+/**
+ * Add features action execution test
+ *
+ * @author Roy Wetherall
+ */
+public class StartWorkflowActionExecuterTest extends BaseSpringTest
+{
+ private NodeService nodeService;
+ private NamespaceService namespaceService;
+ private PersonService personService;
+ private NodeRef rootNodeRef;
+ private NodeRef nodeRef;
+ private StartWorkflowActionExecuter executer;
+
+
+ /**
+ * Called at the begining of all tests
+ */
+ @Override
+ protected void onSetUpInTransaction() throws Exception
+ {
+ this.nodeService = (NodeService)this.applicationContext.getBean("nodeService");
+ this.namespaceService = (NamespaceService)this.applicationContext.getBean("namespaceService");
+ this.personService = (PersonService)this.applicationContext.getBean("personService");
+
+ AuthenticationComponent authenticationComponent = (AuthenticationComponent)applicationContext.getBean("authenticationComponent");
+ authenticationComponent.setCurrentUser(authenticationComponent.getSystemUserName());
+
+ // Create the store and get the root node
+ rootNodeRef = nodeService.getRootNode(new StoreRef(StoreRef.PROTOCOL_WORKSPACE, "spacesStore"));
+ this.nodeRef = this.nodeService.createNode(
+ this.rootNodeRef,
+ ContentModel.ASSOC_CHILDREN,
+ QName.createQName("{test}testnode"),
+ ContentModel.TYPE_CONTENT).getChildRef();
+
+ // Get the executer instance
+ this.executer = (StartWorkflowActionExecuter)this.applicationContext.getBean(StartWorkflowActionExecuter.NAME);
+ }
+
+ /**
+ * Test execution
+ */
+ public void testExecution()
+ {
+ // Execute the action
+ ActionImpl action = new ActionImpl(null, GUID.generate(), StartWorkflowActionExecuter.NAME, null);
+ action.setParameterValue(StartWorkflowActionExecuter.PARAM_WORKFLOW_NAME, "jbpm://wf:review");
+ action.setParameterValue(WorkflowModel.PROP_REVIEW_DUE_DATE.toPrefixString(namespaceService), new Date());
+ NodeRef reviewer = personService.getPerson("admin");
+ action.setParameterValue(WorkflowModel.ASSOC_REVIEWER.toPrefixString(namespaceService), reviewer);
+ executer.execute(action, this.nodeRef);
+ }
+}
diff --git a/source/java/org/alfresco/repo/workflow/WorkflowComponent.java b/source/java/org/alfresco/repo/workflow/WorkflowComponent.java
index 3ebe7fc26d..ea0065cc5c 100644
--- a/source/java/org/alfresco/repo/workflow/WorkflowComponent.java
+++ b/source/java/org/alfresco/repo/workflow/WorkflowComponent.java
@@ -87,6 +87,14 @@ public interface WorkflowComponent
*/
public WorkflowDefinition getDefinitionById(String workflowDefinitionId);
+ /**
+ * Gets a Workflow Definition by unique name
+ *
+ * @param workflowName workflow name e.g. jbpm://review
+ * @return the deployed workflow definition
+ */
+ public WorkflowDefinition getDefinitionByName(String workflowName);
+
//
// Workflow Instance Support
diff --git a/source/java/org/alfresco/repo/workflow/WorkflowServiceImpl.java b/source/java/org/alfresco/repo/workflow/WorkflowServiceImpl.java
index 64ac955e93..bdaac4c483 100644
--- a/source/java/org/alfresco/repo/workflow/WorkflowServiceImpl.java
+++ b/source/java/org/alfresco/repo/workflow/WorkflowServiceImpl.java
@@ -146,6 +146,16 @@ public class WorkflowServiceImpl implements WorkflowService
return component.getDefinitionById(workflowDefinitionId);
}
+ /* (non-Javadoc)
+ * @see org.alfresco.service.cmr.workflow.WorkflowService#getDefinitionByName(java.lang.String)
+ */
+ public WorkflowDefinition getDefinitionByName(String workflowName)
+ {
+ String engineId = BPMEngineRegistry.getEngineId(workflowName);
+ WorkflowComponent component = getWorkflowComponent(engineId);
+ return component.getDefinitionByName(workflowName);
+ }
+
/* (non-Javadoc)
* @see org.alfresco.service.cmr.workflow.WorkflowService#startWorkflow(java.lang.String, java.util.Map)
*/
diff --git a/source/java/org/alfresco/repo/workflow/jbpm/JBPMEngine.java b/source/java/org/alfresco/repo/workflow/jbpm/JBPMEngine.java
index 1fe09531f4..fa7d4af6e1 100644
--- a/source/java/org/alfresco/repo/workflow/jbpm/JBPMEngine.java
+++ b/source/java/org/alfresco/repo/workflow/jbpm/JBPMEngine.java
@@ -312,6 +312,30 @@ public class JBPMEngine extends BPMEngine
throw new UnsupportedOperationException();
}
+ /* (non-Javadoc)
+ * @see org.alfresco.repo.workflow.WorkflowComponent#getDefinitionByName(java.lang.String)
+ */
+ public WorkflowDefinition getDefinitionByName(final String workflowName)
+ {
+ try
+ {
+ return (WorkflowDefinition)jbpmTemplate.execute(new JbpmCallback()
+ {
+ @SuppressWarnings("synthetic-access")
+ public Object doInJbpm(JbpmContext context)
+ {
+ GraphSession graphSession = context.getGraphSession();
+ ProcessDefinition processDef = graphSession.findLatestProcessDefinition(createLocalId(workflowName));
+ return createWorkflowDefinition(processDef);
+ }
+ });
+ }
+ catch(JbpmException e)
+ {
+ throw new WorkflowException("Failed to retrieve workflow definition '" + workflowName + "'", e);
+ }
+ }
+
//
// Workflow Instance Management...
diff --git a/source/java/org/alfresco/repo/workflow/jbpm/NodeListConverterTest.java b/source/java/org/alfresco/repo/workflow/jbpm/NodeListConverterTest.java
new file mode 100644
index 0000000000..52c478ceb4
--- /dev/null
+++ b/source/java/org/alfresco/repo/workflow/jbpm/NodeListConverterTest.java
@@ -0,0 +1,147 @@
+/*
+ * Copyright (C) 2005 Alfresco, Inc.
+ *
+ * Licensed under the Mozilla Public License version 1.1
+ * with a permitted attribution clause. You may obtain a
+ * copy of the License at
+ *
+ * http://www.alfresco.org/legal/license.txt
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
+ * either express or implied. See the License for the specific
+ * language governing permissions and limitations under the
+ * License.
+ */
+package org.alfresco.repo.workflow.jbpm;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.alfresco.repo.content.MimetypeMap;
+import org.alfresco.repo.security.authentication.AuthenticationComponent;
+import org.alfresco.repo.workflow.BPMEngineRegistry;
+import org.alfresco.repo.workflow.TaskComponent;
+import org.alfresco.repo.workflow.WorkflowComponent;
+import org.alfresco.repo.workflow.WorkflowModel;
+import org.alfresco.service.ServiceRegistry;
+import org.alfresco.service.cmr.repository.NodeRef;
+import org.alfresco.service.cmr.repository.NodeService;
+import org.alfresco.service.cmr.repository.StoreRef;
+import org.alfresco.service.cmr.security.PersonService;
+import org.alfresco.service.cmr.workflow.WorkflowDefinition;
+import org.alfresco.service.cmr.workflow.WorkflowDeployment;
+import org.alfresco.service.cmr.workflow.WorkflowPath;
+import org.alfresco.service.cmr.workflow.WorkflowTask;
+import org.alfresco.service.namespace.QName;
+import org.alfresco.util.BaseSpringTest;
+import org.springframework.core.io.ClassPathResource;
+
+
+/**
+ * JBPM Engine Tests
+ *
+ * @author davidc
+ */
+public class NodeListConverterTest extends BaseSpringTest
+{
+ AuthenticationComponent authenticationComponent;
+ PersonService personService;
+ WorkflowComponent workflowComponent;
+ TaskComponent taskComponent;
+ WorkflowDefinition testWorkflowDef;
+ NodeRef testNodeRef;
+
+ private static String taskId = null;
+
+
+ @Override
+ protected void onSetUpInTransaction() throws Exception
+ {
+ personService = (PersonService)applicationContext.getBean("personService");
+ BPMEngineRegistry registry = (BPMEngineRegistry)applicationContext.getBean("bpm_engineRegistry");
+ workflowComponent = registry.getWorkflowComponent("jbpm");
+ taskComponent = registry.getTaskComponent("jbpm");
+
+ // deploy latest review and approve process definition
+ ClassPathResource processDef = new ClassPathResource("org/alfresco/repo/workflow/jbpm/review_and_approve_processdefinition.xml");
+ WorkflowDeployment deployment = workflowComponent.deployDefinition(processDef.getInputStream(), MimetypeMap.MIMETYPE_XML);
+ testWorkflowDef = deployment.definition;
+ assertNotNull(testWorkflowDef);
+
+ // run as system
+ authenticationComponent = (AuthenticationComponent)applicationContext.getBean("authenticationComponent");
+ authenticationComponent.setSystemUserAsCurrentUser();
+
+ // get valid node ref
+ NodeService nodeService = (NodeService)applicationContext.getBean(ServiceRegistry.NODE_SERVICE.getLocalName());
+ testNodeRef = nodeService.getRootNode(new StoreRef(StoreRef.PROTOCOL_WORKSPACE, "spacesStore"));
+ }
+
+
+ public void testStep1Start()
+ {
+ Map params = new HashMap();
+ 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");
+ params.put(QName.createQName("http://www.alfresco.org/model/workflow/1.0", "reviewer"), reviewer);
+
+ WorkflowPath path = workflowComponent.startWorkflow(testWorkflowDef.id, params);
+ assertNotNull(path);
+ List tasks1 = workflowComponent.getTasksForWorkflowPath(path.id);
+ assertNotNull(tasks1);
+ assertEquals(1, tasks1.size());
+
+ setComplete();
+ taskId = tasks1.get(0).id;
+ }
+
+
+ public void testSetNodeRefList()
+ {
+ List nodeRefs = new ArrayList();
+ nodeRefs.add(testNodeRef);
+ nodeRefs.add(testNodeRef);
+ Map params = new HashMap();
+ params.put(WorkflowModel.PROP_COMPLETED_ITEMS, (Serializable)nodeRefs);
+
+ WorkflowTask task = taskComponent.getTaskById(taskId);
+ assertNull(task.properties.get(WorkflowModel.PROP_COMPLETED_ITEMS));
+
+ WorkflowTask updatedTask = taskComponent.updateTask(taskId, params, null, null);
+ assertNotNull(updatedTask);
+ assertTrue(updatedTask.properties.containsKey(WorkflowModel.PROP_COMPLETED_ITEMS));
+ assertEquals(2, ((List)updatedTask.properties.get(WorkflowModel.PROP_COMPLETED_ITEMS)).size());
+
+ setComplete();
+ }
+
+
+ public void testUpdateNodeRefList()
+ {
+ List nodeRefs = new ArrayList();
+// nodeRefs.add(testNodeRef);
+ Map params = new HashMap();
+ params.put(WorkflowModel.PROP_COMPLETED_ITEMS, (Serializable)nodeRefs);
+
+// WorkflowTask task = taskComponent.getTaskById(taskId);
+// assertNotNull(task);
+// assertTrue(task.properties.containsKey(WorkflowModel.PROP_COMPLETED_ITEMS));
+// assertEquals(2, ((List)task.properties.get(WorkflowModel.PROP_COMPLETED_ITEMS)).size());
+
+ WorkflowTask updatedTask = taskComponent.updateTask(taskId, params, null, null);
+ assertNotNull(updatedTask);
+ assertTrue(updatedTask.properties.containsKey(WorkflowModel.PROP_COMPLETED_ITEMS));
+ assertEquals(0, ((List)updatedTask.properties.get(WorkflowModel.PROP_COMPLETED_ITEMS)).size());
+
+ setComplete();
+ }
+
+}
diff --git a/source/java/org/alfresco/service/cmr/workflow/WorkflowService.java b/source/java/org/alfresco/service/cmr/workflow/WorkflowService.java
index fd3d55165d..fe46a1c143 100644
--- a/source/java/org/alfresco/service/cmr/workflow/WorkflowService.java
+++ b/source/java/org/alfresco/service/cmr/workflow/WorkflowService.java
@@ -95,7 +95,15 @@ public interface WorkflowService
* @return the deployed workflow definition
*/
public WorkflowDefinition getDefinitionById(String workflowDefinitionId);
-
+
+ /**
+ * Gets a Workflow Definition by unique name
+ *
+ * @param workflowName workflow name e.g. jbpm://review
+ * @return the deployed workflow definition
+ */
+ public WorkflowDefinition getDefinitionByName(String workflowName);
+
//
// Workflow Instance Management