mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-07-24 17:32:48 +00:00
Workflow (server-side) groups support
- assignment of groups to pooled tasks - retrieve group members added to javascript git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@4805 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
@@ -17,14 +17,20 @@
|
||||
package org.alfresco.repo.workflow.jbpm;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Set;
|
||||
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.repo.jscript.Node;
|
||||
import org.alfresco.service.ServiceRegistry;
|
||||
import org.alfresco.service.cmr.security.AuthorityService;
|
||||
import org.alfresco.service.cmr.security.AuthorityType;
|
||||
import org.alfresco.service.cmr.workflow.WorkflowException;
|
||||
import org.dom4j.Element;
|
||||
import org.jbpm.graph.exe.ExecutionContext;
|
||||
import org.jbpm.jpdl.el.impl.JbpmExpressionEvaluator;
|
||||
import org.jbpm.taskmgmt.def.AssignmentHandler;
|
||||
import org.jbpm.taskmgmt.exe.Assignable;
|
||||
import org.springframework.beans.factory.BeanFactory;
|
||||
|
||||
|
||||
/**
|
||||
@@ -33,13 +39,24 @@ import org.jbpm.taskmgmt.exe.Assignable;
|
||||
*
|
||||
* @author davidc
|
||||
*/
|
||||
public class AlfrescoAssignment implements AssignmentHandler
|
||||
public class AlfrescoAssignment extends JBPMSpringAssignmentHandler
|
||||
{
|
||||
private static final long serialVersionUID = 1025667849552265719L;
|
||||
private ServiceRegistry services;
|
||||
|
||||
private Element actor;
|
||||
private Element pooledactors;
|
||||
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.alfresco.repo.workflow.jbpm.JBPMSpringActionHandler#initialiseHandler(org.springframework.beans.factory.BeanFactory)
|
||||
*/
|
||||
@Override
|
||||
protected void initialiseHandler(BeanFactory factory)
|
||||
{
|
||||
services = (ServiceRegistry)factory.getBean(ServiceRegistry.SERVICE_REGISTRY);
|
||||
}
|
||||
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.jbpm.taskmgmt.def.AssignmentHandler#assign(org.jbpm.taskmgmt.exe.Assignable, org.jbpm.graph.exe.ExecutionContext)
|
||||
@@ -63,7 +80,8 @@ public class AlfrescoAssignment implements AssignmentHandler
|
||||
{
|
||||
if (actorValStr.startsWith("#{"))
|
||||
{
|
||||
Object eval = JbpmExpressionEvaluator.evaluate(actorValStr, executionContext);
|
||||
String expression = actorValStr.substring(2, actorValStr.length() -1);
|
||||
Object eval = AlfrescoJavaScript.executeScript(executionContext, services, expression, null);
|
||||
if (eval == null)
|
||||
{
|
||||
throw new WorkflowException("actor expression '" + actorValStr + "' evaluates to null");
|
||||
@@ -73,9 +91,9 @@ public class AlfrescoAssignment implements AssignmentHandler
|
||||
{
|
||||
assignedActor = (String)eval;
|
||||
}
|
||||
else if (eval instanceof JBPMNode)
|
||||
else if (eval instanceof Node)
|
||||
{
|
||||
JBPMNode node = (JBPMNode)eval;
|
||||
Node node = (Node)eval;
|
||||
if (!node.getType().equals(ContentModel.TYPE_PERSON))
|
||||
{
|
||||
throw new WorkflowException("actor expression does not evaluate to a person");
|
||||
@@ -106,49 +124,52 @@ public class AlfrescoAssignment implements AssignmentHandler
|
||||
{
|
||||
if (pooledactorValStr.startsWith("#{"))
|
||||
{
|
||||
Object eval = JbpmExpressionEvaluator.evaluate(pooledactorValStr, executionContext);
|
||||
String expression = pooledactorValStr.substring(2, pooledactorValStr.length() -1);
|
||||
Object eval = AlfrescoJavaScript.executeScript(executionContext, services, expression, null);
|
||||
if (eval == null)
|
||||
{
|
||||
throw new WorkflowException("pooledactors expression '" + pooledactorValStr + "' evaluates to null");
|
||||
}
|
||||
|
||||
if (eval instanceof Collection)
|
||||
if (eval instanceof Node[])
|
||||
{
|
||||
Collection coll = (Collection)eval;
|
||||
assignedPooledActors = new String[coll.size()];
|
||||
Node[] nodes = (Node[])eval;
|
||||
assignedPooledActors = new String[nodes.length];
|
||||
|
||||
int i = 0;
|
||||
for (Object obj : coll)
|
||||
for (Node node : (Node[])nodes)
|
||||
{
|
||||
if (!(obj instanceof JBPMNode))
|
||||
if (node.getType().equals(ContentModel.TYPE_PERSON))
|
||||
{
|
||||
throw new WorkflowException("pooledactors does not refer to a collection of people");
|
||||
assignedPooledActors[i++] = (String)node.getProperties().get(ContentModel.PROP_USERNAME);
|
||||
}
|
||||
JBPMNode node = (JBPMNode)obj;
|
||||
if (!node.getType().equals(ContentModel.TYPE_PERSON))
|
||||
else if (node.getType().equals(ContentModel.TYPE_AUTHORITY_CONTAINER))
|
||||
{
|
||||
throw new WorkflowException("pooledactors expression does not evaluate to a collection of people");
|
||||
assignedPooledActors[i++] = (String)node.getProperties().get(ContentModel.PROP_AUTHORITY_NAME);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new WorkflowException("pooledactors expression does not evaluate to a collection of authorities");
|
||||
}
|
||||
assignedPooledActors[i++] = (String)node.getProperties().get(ContentModel.PROP_USERNAME);
|
||||
}
|
||||
}
|
||||
else if (eval instanceof JBPMNode)
|
||||
else if (eval instanceof Node)
|
||||
{
|
||||
JBPMNode node = (JBPMNode)eval;
|
||||
assignedPooledActors = new String[1];
|
||||
Node node = (Node)eval;
|
||||
if (node.getType().equals(ContentModel.TYPE_PERSON))
|
||||
{
|
||||
assignedPooledActors[0] = (String)node.getProperties().get(ContentModel.PROP_USERNAME);
|
||||
}
|
||||
// TODO: Support Group
|
||||
else if (node.getType().equals(ContentModel.TYPE_AUTHORITY_CONTAINER))
|
||||
{
|
||||
assignedPooledActors[0] = (String)node.getProperties().get(ContentModel.PROP_AUTHORITY_NAME);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new WorkflowException("pooledactors expression does not evaluate to a collection of people");
|
||||
throw new WorkflowException("pooledactors expression does not evaluate to a collection of authorities");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new WorkflowException("pooledactor expression does not evaluate to a group or collection of people");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@@ -56,7 +56,6 @@ public class AlfrescoJavaScript extends JBPMSpringActionHandler
|
||||
private static final long serialVersionUID = -2908748080671212745L;
|
||||
|
||||
private static JpdlXmlReader jpdlReader = new JpdlXmlReader((InputSource)null);
|
||||
private ScriptService scriptService;
|
||||
private ServiceRegistry services;
|
||||
private Element script;
|
||||
|
||||
@@ -67,7 +66,6 @@ public class AlfrescoJavaScript extends JBPMSpringActionHandler
|
||||
@Override
|
||||
protected void initialiseHandler(BeanFactory factory)
|
||||
{
|
||||
scriptService = (ScriptService)factory.getBean(ServiceRegistry.SCRIPT_SERVICE.getLocalName());
|
||||
services = (ServiceRegistry)factory.getBean(ServiceRegistry.SERVICE_REGISTRY);
|
||||
}
|
||||
|
||||
@@ -116,9 +114,8 @@ public class AlfrescoJavaScript extends JBPMSpringActionHandler
|
||||
expression = expressionElement.getTextTrim();
|
||||
}
|
||||
|
||||
// construct script arguments and execute
|
||||
Map<String, Object> inputMap = createInputMap(executionContext, variableAccesses);
|
||||
Object result = scriptService.executeScriptString(expression, inputMap);
|
||||
// execute
|
||||
Object result = executeScript(executionContext, services, expression, variableAccesses);
|
||||
|
||||
// map script return variable to process context
|
||||
VariableAccess returnVariable = getWritableVariable(variableAccesses);
|
||||
@@ -130,6 +127,24 @@ public class AlfrescoJavaScript extends JBPMSpringActionHandler
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Execute a script
|
||||
*
|
||||
* @param context jBPM execution context
|
||||
* @param services Alfresco service registry
|
||||
* @param expression script to execute
|
||||
* @param variableAccesses (optional) list of jBPM variables to map into script (all, if not supplied)
|
||||
* @return script result
|
||||
*/
|
||||
public static Object executeScript(ExecutionContext context, ServiceRegistry services, String expression, List<VariableAccess> variableAccesses)
|
||||
{
|
||||
Map<String, Object> inputMap = createInputMap(context, services, variableAccesses);
|
||||
ScriptService scriptService = services.getScriptService();
|
||||
Object result = scriptService.executeScriptString(expression, inputMap);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Construct map of arguments to pass to script
|
||||
@@ -141,7 +156,7 @@ public class AlfrescoJavaScript extends JBPMSpringActionHandler
|
||||
* @return the map of script arguments
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public Map<String, Object> createInputMap(ExecutionContext executionContext, List<VariableAccess> variableAccesses)
|
||||
private static Map<String, Object> createInputMap(ExecutionContext executionContext, ServiceRegistry services, List<VariableAccess> variableAccesses)
|
||||
{
|
||||
Map<String, Object> inputMap = new HashMap<String, Object>();
|
||||
|
||||
@@ -216,7 +231,7 @@ public class AlfrescoJavaScript extends JBPMSpringActionHandler
|
||||
* @param variableAccesses the variables configuration
|
||||
* @return true => there are variables to read
|
||||
*/
|
||||
private boolean hasReadableVariable(List<VariableAccess> variableAccesses)
|
||||
private static boolean hasReadableVariable(List<VariableAccess> variableAccesses)
|
||||
{
|
||||
if (variableAccesses != null)
|
||||
{
|
||||
@@ -238,7 +253,7 @@ public class AlfrescoJavaScript extends JBPMSpringActionHandler
|
||||
* @param variableAccesses the variables configuration
|
||||
* @return true => there is a variable to write
|
||||
*/
|
||||
private VariableAccess getWritableVariable(List<VariableAccess> variableAccesses)
|
||||
private static VariableAccess getWritableVariable(List<VariableAccess> variableAccesses)
|
||||
{
|
||||
if (variableAccesses != null)
|
||||
{
|
||||
|
@@ -20,27 +20,37 @@ import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
import org.alfresco.service.ServiceRegistry;
|
||||
import org.alfresco.service.cmr.workflow.WorkflowException;
|
||||
import org.dom4j.Element;
|
||||
import org.jbpm.graph.def.ActionHandler;
|
||||
import org.jbpm.graph.def.Node;
|
||||
import org.jbpm.graph.def.Transition;
|
||||
import org.jbpm.graph.exe.ExecutionContext;
|
||||
import org.jbpm.graph.exe.Token;
|
||||
import org.jbpm.instantiation.FieldInstantiator;
|
||||
import org.jbpm.jpdl.el.impl.JbpmExpressionEvaluator;
|
||||
import org.springframework.beans.factory.BeanFactory;
|
||||
|
||||
|
||||
/**
|
||||
* For each "item in collection", create a fork.
|
||||
*/
|
||||
public class ForEachFork implements ActionHandler
|
||||
public class ForEachFork extends JBPMSpringActionHandler
|
||||
{
|
||||
private static final long serialVersionUID = 4643103713602441652L;
|
||||
private ServiceRegistry services;
|
||||
|
||||
private Element foreach;
|
||||
private String var;
|
||||
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.alfresco.repo.workflow.jbpm.JBPMSpringActionHandler#initialiseHandler(org.springframework.beans.factory.BeanFactory)
|
||||
*/
|
||||
@Override
|
||||
protected void initialiseHandler(BeanFactory factory)
|
||||
{
|
||||
services = (ServiceRegistry)factory.getBean(ServiceRegistry.SERVICE_REGISTRY);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new child token for each item in list.
|
||||
@@ -68,7 +78,8 @@ public class ForEachFork implements ActionHandler
|
||||
{
|
||||
if (forEachCollStr.startsWith("#{"))
|
||||
{
|
||||
Object eval = JbpmExpressionEvaluator.evaluate(forEachCollStr, executionContext);
|
||||
String expression = forEachCollStr.substring(2, forEachCollStr.length() -1);
|
||||
Object eval = AlfrescoJavaScript.executeScript(executionContext, services, expression, null);
|
||||
if (eval == null)
|
||||
{
|
||||
throw new WorkflowException("forEach expression '" + forEachCollStr + "' evaluates to null");
|
||||
@@ -85,11 +96,23 @@ public class ForEachFork implements ActionHandler
|
||||
}
|
||||
}
|
||||
|
||||
// expression evaluates to Node array
|
||||
else if (eval instanceof org.alfresco.repo.jscript.Node[])
|
||||
{
|
||||
org.alfresco.repo.jscript.Node[] nodes = (org.alfresco.repo.jscript.Node[])eval;
|
||||
forEachColl = new ArrayList(nodes.length);
|
||||
for (org.alfresco.repo.jscript.Node node : nodes)
|
||||
{
|
||||
forEachColl.add(new JBPMNode(node.getNodeRef(), services));
|
||||
}
|
||||
}
|
||||
|
||||
// expression evaluates to collection
|
||||
else if (eval instanceof Collection)
|
||||
{
|
||||
forEachColl = (List)eval;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@@ -23,6 +23,7 @@ import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
@@ -33,6 +34,7 @@ import org.alfresco.i18n.I18NUtil;
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.repo.content.MimetypeMap;
|
||||
import org.alfresco.repo.security.authentication.AuthenticationUtil;
|
||||
import org.alfresco.repo.security.authority.AuthorityDAO;
|
||||
import org.alfresco.repo.workflow.BPMEngine;
|
||||
import org.alfresco.repo.workflow.TaskComponent;
|
||||
import org.alfresco.repo.workflow.WorkflowComponent;
|
||||
@@ -49,6 +51,8 @@ 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.repository.datatype.DefaultTypeConverter;
|
||||
import org.alfresco.service.cmr.security.AuthorityService;
|
||||
import org.alfresco.service.cmr.security.AuthorityType;
|
||||
import org.alfresco.service.cmr.security.PersonService;
|
||||
import org.alfresco.service.cmr.workflow.WorkflowDefinition;
|
||||
import org.alfresco.service.cmr.workflow.WorkflowDeployment;
|
||||
@@ -108,6 +112,8 @@ public class JBPMEngine extends BPMEngine
|
||||
protected NodeService nodeService;
|
||||
protected ServiceRegistry serviceRegistry;
|
||||
protected PersonService personService;
|
||||
protected AuthorityService authorityService;
|
||||
protected AuthorityDAO authorityDAO;
|
||||
protected JbpmTemplate jbpmTemplate;
|
||||
|
||||
// Company Home
|
||||
@@ -183,6 +189,26 @@ public class JBPMEngine extends BPMEngine
|
||||
this.personService = personService;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the Authority Service
|
||||
*
|
||||
* @param authorityService
|
||||
*/
|
||||
public void setAuthorityService(AuthorityService authorityService)
|
||||
{
|
||||
this.authorityService = authorityService;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the Authority DAO
|
||||
*
|
||||
* @param authorityDAO
|
||||
*/
|
||||
public void setAuthorityDAO(AuthorityDAO authorityDAO)
|
||||
{
|
||||
this.authorityDAO = authorityDAO;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the Service Registry
|
||||
*
|
||||
@@ -459,7 +485,7 @@ public class JBPMEngine extends BPMEngine
|
||||
processContext.setVariable("cancelled", false);
|
||||
NodeRef companyHome = getCompanyHome();
|
||||
processContext.setVariable("companyhome", new JBPMNode(companyHome, serviceRegistry));
|
||||
NodeRef initiatorPerson = mapNameToAuthority(currentUserName);
|
||||
NodeRef initiatorPerson = mapNameToPerson(currentUserName);
|
||||
if (initiatorPerson != null)
|
||||
{
|
||||
processContext.setVariable("initiator", new JBPMNode(initiatorPerson, serviceRegistry));
|
||||
@@ -831,9 +857,17 @@ public class JBPMEngine extends BPMEngine
|
||||
{
|
||||
public List<WorkflowTask> doInJbpm(JbpmContext context)
|
||||
{
|
||||
// retrieve pooled tasks for specified authorities
|
||||
// flatten authorities to include all parent authorities
|
||||
Set<String> flattenedAuthorities = new HashSet<String>();
|
||||
for (String authority : authorities)
|
||||
{
|
||||
Set<String> parents = authorityService.getContainingAuthorities(AuthorityType.GROUP, authority, false);
|
||||
flattenedAuthorities.addAll(parents);
|
||||
}
|
||||
|
||||
// retrieve pooled tasks for all flattened authorities
|
||||
TaskMgmtSession taskSession = context.getTaskMgmtSession();
|
||||
List<TaskInstance> tasks = taskSession.findPooledTaskInstances(authorities);
|
||||
List<TaskInstance> tasks = taskSession.findPooledTaskInstances(new ArrayList(flattenedAuthorities));
|
||||
List<WorkflowTask> workflowTasks = new ArrayList<WorkflowTask>(tasks.size());
|
||||
for (TaskInstance task : tasks)
|
||||
{
|
||||
@@ -1281,7 +1315,7 @@ public class JBPMEngine extends BPMEngine
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets Properties of Task
|
||||
* Gets Properties of Task
|
||||
*
|
||||
* @param instance task instance
|
||||
* @param properties properties to set
|
||||
@@ -1778,12 +1812,12 @@ public class JBPMEngine extends BPMEngine
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert authority name to an Alfresco Authority
|
||||
* Convert person name to an Alfresco Person
|
||||
*
|
||||
* @param names the authority names to convert
|
||||
* @return the Alfresco authorities
|
||||
* @param names the person name to convert
|
||||
* @return the Alfresco person
|
||||
*/
|
||||
private NodeRef mapNameToAuthority(String name)
|
||||
private NodeRef mapNameToPerson(String name)
|
||||
{
|
||||
NodeRef authority = null;
|
||||
if (name != null)
|
||||
@@ -1797,6 +1831,26 @@ public class JBPMEngine extends BPMEngine
|
||||
return authority;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert authority name to an Alfresco Authority
|
||||
*
|
||||
* @param names the authority names to convert
|
||||
* @return the Alfresco authorities
|
||||
*/
|
||||
private NodeRef mapNameToAuthority(String name)
|
||||
{
|
||||
NodeRef authority = null;
|
||||
if (name != null)
|
||||
{
|
||||
// TODO: Should this be an exception?
|
||||
if (authorityDAO.authorityExists(name))
|
||||
{
|
||||
authority = authorityDAO.getAuthorityNodeRefOrNull(name);
|
||||
}
|
||||
}
|
||||
return authority;
|
||||
}
|
||||
|
||||
/**
|
||||
* Map jBPM variable name to QName
|
||||
*
|
||||
|
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* 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 org.jbpm.taskmgmt.def.AssignmentHandler;
|
||||
import org.springframework.beans.factory.BeanFactory;
|
||||
import org.springframework.beans.factory.access.BeanFactoryLocator;
|
||||
import org.springframework.beans.factory.access.BeanFactoryReference;
|
||||
import org.springmodules.workflow.jbpm31.JbpmFactoryLocator;
|
||||
|
||||
|
||||
/**
|
||||
* Abstract base implementation of a Jbpm Assignment Handler with access to
|
||||
* Alfresco Spring beans.
|
||||
*
|
||||
* @author davidc
|
||||
*/
|
||||
public abstract class JBPMSpringAssignmentHandler implements AssignmentHandler
|
||||
{
|
||||
|
||||
/**
|
||||
* Construct
|
||||
*/
|
||||
protected JBPMSpringAssignmentHandler()
|
||||
{
|
||||
// The following implementation is derived from Spring Modules v0.4
|
||||
BeanFactoryLocator factoryLocator = new JbpmFactoryLocator();
|
||||
BeanFactoryReference factory = factoryLocator.useBeanFactory(null);
|
||||
initialiseHandler(factory.getFactory());
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialise Action Handler
|
||||
*
|
||||
* @param factory Spring bean factory for accessing Alfresco beans
|
||||
*/
|
||||
protected abstract void initialiseHandler(BeanFactory factory);
|
||||
|
||||
|
||||
}
|
47
source/java/org/alfresco/repo/workflow/jbpm/test_groups.xml
Normal file
47
source/java/org/alfresco/repo/workflow/jbpm/test_groups.xml
Normal file
@@ -0,0 +1,47 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<process-definition xmlns="urn:jbpm.org:jpdl-3.1" name="wf:grouptasks">
|
||||
|
||||
<swimlane name="initiator" />
|
||||
|
||||
<start-state name="start">
|
||||
<task name="wf:submitGroupReviewTask" swimlane="initiator" />
|
||||
<transition name="" to="review" />
|
||||
<transition name="parallel" to="parallel" />
|
||||
</start-state>
|
||||
|
||||
<swimlane name="reviewer">
|
||||
<assignment class="org.alfresco.repo.workflow.jbpm.AlfrescoAssignment">
|
||||
<pooledactors>#{bpm_groupAssignee}</pooledactors>
|
||||
</assignment>
|
||||
</swimlane>
|
||||
|
||||
<task-node name="review">
|
||||
<task name="wf:reviewTask" swimlane="reviewer"/>
|
||||
<transition name="" to="end" />
|
||||
</task-node>
|
||||
|
||||
<node name="parallel">
|
||||
<action class="org.alfresco.repo.workflow.jbpm.ForEachFork">
|
||||
<foreach>#{people.getMembers(bpm_groupAssignee)}</foreach>
|
||||
<var>reviewer</var>
|
||||
</action>
|
||||
<transition name="review" to="parallelreview" />
|
||||
</node>
|
||||
|
||||
<task-node name="parallelreview">
|
||||
<task name="wf:reviewTask">
|
||||
<assignment class="org.alfresco.repo.workflow.jbpm.AlfrescoAssignment">
|
||||
<actor>#{reviewer}</actor>
|
||||
</assignment>
|
||||
</task>
|
||||
<transition name="" to="endparallel" />
|
||||
</task-node>
|
||||
|
||||
<join name="endparallel">
|
||||
<transition to="end" />
|
||||
</join>
|
||||
|
||||
<end-state name="end" />
|
||||
|
||||
</process-definition>
|
Reference in New Issue
Block a user