diff --git a/config/alfresco/core-services-context.xml b/config/alfresco/core-services-context.xml
index f381a269c1..57175cdbd3 100644
--- a/config/alfresco/core-services-context.xml
+++ b/config/alfresco/core-services-context.xml
@@ -549,17 +549,22 @@
+
alfresco/model/dictionaryModel.xml
alfresco/model/systemModel.xml
+ org/alfresco/repo/security/authentication/userModel.xml
+
+
alfresco/model/contentModel.xml
alfresco/model/bpmModel.xml
alfresco/model/wcmModel.xml
+ alfresco/model/forumModel.xml
+
+
alfresco/model/applicationModel.xml
alfresco/model/wcmAppModel.xml
- alfresco/model/forumModel.xml
- org/alfresco/repo/security/authentication/userModel.xml
org/alfresco/repo/action/actionModel.xml
org/alfresco/repo/rule/ruleModel.xml
org/alfresco/repo/version/version_model.xml
diff --git a/config/alfresco/messages/workflow-interpreter-help.txt b/config/alfresco/messages/workflow-interpreter-help.txt
index dd66a44977..23712969a3 100644
--- a/config/alfresco/messages/workflow-interpreter-help.txt
+++ b/config/alfresco/messages/workflow-interpreter-help.txt
@@ -91,6 +91,18 @@ ok> var [*] person
var bpm:assignee* person admin,fred
+ok> var [*] group
+
+ Define or update a (usr:authorityContainer) node ref variable.
+
+ variable name
+ [*] if specified, define a collection
+ variable value (comma-seperate to specify a list of values)
+
+ e.g.
+
+ var bpm:groupAssignee group GROUP_Engineering
+
ok> var package
Define or update a (bpm:workflowPackage) node ref variable.
diff --git a/config/alfresco/model/bpmModel.xml b/config/alfresco/model/bpmModel.xml
index d88eaf5a7e..98e30814de 100644
--- a/config/alfresco/model/bpmModel.xml
+++ b/config/alfresco/model/bpmModel.xml
@@ -12,6 +12,8 @@
+
+
@@ -310,6 +312,29 @@
+
+
+
+
+
+
+
+
+
+ false
+ false
+
+
+
+ usr:authorityContainer
+ true
+ false
+
+
+
+
+
+
diff --git a/config/alfresco/script-services-context.xml b/config/alfresco/script-services-context.xml
index 6e76da9bfe..97978a58ca 100644
--- a/config/alfresco/script-services-context.xml
+++ b/config/alfresco/script-services-context.xml
@@ -70,6 +70,9 @@
+
+
+
diff --git a/config/alfresco/workflow-context.xml b/config/alfresco/workflow-context.xml
index 641750714b..d6bbad2982 100644
--- a/config/alfresco/workflow-context.xml
+++ b/config/alfresco/workflow-context.xml
@@ -34,6 +34,8 @@
+
+
@@ -87,6 +89,8 @@
+
+
${spaces.store}
/${spaces.company_home.childname}
diff --git a/config/alfresco/workflow/submit_processdefinition.xml b/config/alfresco/workflow/submit_processdefinition.xml
index e94c292b9e..b5f8057c5b 100644
--- a/config/alfresco/workflow/submit_processdefinition.xml
+++ b/config/alfresco/workflow/submit_processdefinition.xml
@@ -56,7 +56,7 @@
- #{bpm_assignees[wcmwf_approveCnt]}
+ #{bpm_assignees.get(wcmwf_approveCnt)}
diff --git a/config/alfresco/workflow/workflowModel.xml b/config/alfresco/workflow/workflowModel.xml
index f946336b1c..fee647d2ac 100644
--- a/config/alfresco/workflow/workflowModel.xml
+++ b/config/alfresco/workflow/workflowModel.xml
@@ -24,6 +24,13 @@
+
+ bpm:startTask
+
+ bpm:groupAssignee
+
+
+
bpm:startTask
diff --git a/source/java/org/alfresco/repo/jscript/People.java b/source/java/org/alfresco/repo/jscript/People.java
index cd4ae29534..f212abdc29 100644
--- a/source/java/org/alfresco/repo/jscript/People.java
+++ b/source/java/org/alfresco/repo/jscript/People.java
@@ -16,8 +16,14 @@
*/
package org.alfresco.repo.jscript;
+import java.util.Set;
+
+import org.alfresco.model.ContentModel;
+import org.alfresco.repo.security.authority.AuthorityDAO;
import org.alfresco.service.ServiceRegistry;
import org.alfresco.service.cmr.repository.NodeRef;
+import org.alfresco.service.cmr.security.AuthorityService;
+import org.alfresco.service.cmr.security.AuthorityType;
import org.alfresco.service.cmr.security.PersonService;
import org.mozilla.javascript.Scriptable;
@@ -30,6 +36,7 @@ public final class People extends BaseScriptImplementation implements Scopeable
{
/** Repository Service Registry */
private ServiceRegistry services;
+ private AuthorityDAO authorityDAO;
/** Root scope for this object */
private Scriptable scope;
@@ -44,6 +51,16 @@ public final class People extends BaseScriptImplementation implements Scopeable
this.services = serviceRegistry;
}
+ /**
+ * Set the authority DAO
+ *
+ * @param authorityDAO authority dao
+ */
+ public void setAuthorityDAO(AuthorityDAO authorityDAO)
+ {
+ this.authorityDAO = authorityDAO;
+ }
+
/**
* @see org.alfresco.repo.jscript.Scopeable#setScope(org.mozilla.javascript.Scriptable)
*/
@@ -55,6 +72,7 @@ public final class People extends BaseScriptImplementation implements Scopeable
/**
* Gets the Person given the username
*
+ * @param username the username of the person to get
* @return the person node (type cm:person) or null if no such person exists
*/
public Node getPerson(String username)
@@ -68,5 +86,88 @@ public final class People extends BaseScriptImplementation implements Scopeable
}
return person;
}
+
+ /**
+ * Gets the Group given the group name
+ *
+ * @param groupName name of group to get
+ * @return the group node (type usr:authorityContainer) or null if no such group exists
+ */
+ public Node getGroup(String groupName)
+ {
+ Node group = null;
+ NodeRef groupRef = authorityDAO.getAuthorityNodeRefOrNull(groupName);
+ if (groupRef != null)
+ {
+ group = new Node(groupRef, services, scope);
+ }
+ return group;
+ }
+
+ /**
+ * Gets the members (people) of a group (including all sub-groups)
+ *
+ * @param group the group to retrieve members for
+ * @param recurse recurse into sub-groups
+ * @return the members of the group
+ */
+ public Node[] getMembers(Node group)
+ {
+ return getContainedAuthorities(group, AuthorityType.USER, true);
+ }
+
+ /**
+ * Gets the members (people) of a group
+ *
+ * @param group the group to retrieve members for
+ * @param recurse recurse into sub-groups
+ * @return the members of the group
+ */
+ public Node[] getMembers(Node group, boolean recurse)
+ {
+ return getContainedAuthorities(group, AuthorityType.USER, recurse);
+ }
+
+ /**
+ * Get Contained Authorities
+ *
+ * @param container authority containers
+ * @param type authority type to filter by
+ * @param recurse recurse into sub-containers
+ * @return contained authorities
+ */
+ private Node[] getContainedAuthorities(Node container, AuthorityType type, boolean recurse)
+ {
+ Node[] members = null;
+ if (container.getType().equals(ContentModel.TYPE_AUTHORITY_CONTAINER))
+ {
+ AuthorityService authorityService = services.getAuthorityService();
+ String groupName = (String)container.getProperties().get(ContentModel.PROP_AUTHORITY_NAME);
+ Set authorities = authorityService.getContainedAuthorities(type, groupName, !recurse);
+ members = new Node[authorities.size()];
+ int i = 0;
+ for (String authority : authorities)
+ {
+ AuthorityType authorityType = AuthorityType.getAuthorityType(authority);
+ if (authorityType.equals(AuthorityType.GROUP))
+ {
+ Node group = getGroup(authority);
+ if (group != null)
+ {
+ members[i++] = group;
+ }
+ }
+ else if (authorityType.equals(AuthorityType.USER))
+ {
+ Node person = getPerson(authority);
+ if (person != null)
+ {
+ members[i++] = person;
+ }
+ }
+ }
+ }
+ return members;
+ }
}
diff --git a/source/java/org/alfresco/repo/workflow/WorkflowInterpreter.java b/source/java/org/alfresco/repo/workflow/WorkflowInterpreter.java
index 617e918a14..0d004245f0 100644
--- a/source/java/org/alfresco/repo/workflow/WorkflowInterpreter.java
+++ b/source/java/org/alfresco/repo/workflow/WorkflowInterpreter.java
@@ -38,6 +38,8 @@ import org.alfresco.service.cmr.avm.AVMService;
import org.alfresco.service.cmr.avmsync.AVMDifference;
import org.alfresco.service.cmr.avmsync.AVMSyncService;
import org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork;
+import org.alfresco.repo.security.authority.AuthorityDAO;
+import org.alfresco.repo.transaction.TransactionUtil;
import org.alfresco.service.cmr.model.FileFolderService;
import org.alfresco.service.cmr.model.FileInfo;
import org.alfresco.service.cmr.repository.ContentWriter;
@@ -46,6 +48,7 @@ import org.alfresco.service.cmr.repository.NodeService;
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.WorkflowException;
import org.alfresco.service.cmr.workflow.WorkflowInstance;
import org.alfresco.service.cmr.workflow.WorkflowPath;
import org.alfresco.service.cmr.workflow.WorkflowService;
@@ -54,6 +57,7 @@ import org.alfresco.service.cmr.workflow.WorkflowTaskState;
import org.alfresco.service.cmr.workflow.WorkflowTransition;
import org.alfresco.service.namespace.NamespaceService;
import org.alfresco.service.namespace.QName;
+import org.alfresco.service.transaction.TransactionService;
import org.alfresco.util.ApplicationContextHelper;
import org.alfresco.util.GUID;
import org.springframework.context.ApplicationContext;
@@ -70,6 +74,8 @@ public class WorkflowInterpreter
private WorkflowService workflowService;
private NamespaceService namespaceService;
private NodeService nodeService;
+ private TransactionService transactionService;
+ private AuthorityDAO authorityDAO;
private AVMService avmService;
private AVMSyncService avmSyncService;
private PersonService personService;
@@ -167,6 +173,22 @@ public class WorkflowInterpreter
this.personService = personService;
}
+ /**
+ * @param transactionService transactionService
+ */
+ public void setTransactionService(TransactionService transactionService)
+ {
+ this.transactionService = transactionService;
+ }
+
+ /**
+ * @param authorityDAO authorityDAO
+ */
+ public void setAuthorityDAO(AuthorityDAO authorityDAO)
+ {
+ this.authorityDAO = authorityDAO;
+ }
+
/**
* @param fileFolderService fileFolderService
*/
@@ -220,7 +242,13 @@ public class WorkflowInterpreter
{
public String doWork() throws Exception
{
- return executeCommand(line);
+ return TransactionUtil.executeInUserTransaction(transactionService, new TransactionUtil.TransactionWork()
+ {
+ public String doWork() throws Exception
+ {
+ return executeCommand(line);
+ }
+ });
}
}, username);
}
@@ -882,6 +910,45 @@ public class WorkflowInterpreter
}
out.println("set var " + qname + " = " + vars.get(qname));
}
+ else if (command[2].equals("group"))
+ {
+ boolean multi = false;
+ if (command[1].endsWith("*"))
+ {
+ command[1] = command[1].substring(0, command[1].length() -1);
+ multi = true;
+ }
+ QName qname = QName.createQName(command[1], namespaceService);
+ String[] strValues = command[3].split(",");
+ if (!multi && strValues.length > 1)
+ {
+ return "Syntax Error.\n";
+ }
+ if (!multi)
+ {
+ NodeRef auth = authorityDAO.getAuthorityNodeRefOrNull(strValues[0]);
+ if (auth == null)
+ {
+ throw new WorkflowException("Group " + strValues[0] + " does not exist.");
+ }
+ vars.put(qname, auth);
+ }
+ else
+ {
+ List values = new ArrayList();
+ for (String strValue : strValues)
+ {
+ NodeRef auth = authorityDAO.getAuthorityNodeRefOrNull(strValue);
+ if (auth == null)
+ {
+ throw new WorkflowException("Group " + strValue + " does not exist.");
+ }
+ values.add(auth);
+ }
+ vars.put(qname, (Serializable)values);
+ }
+ out.println("set var " + qname + " = " + vars.get(qname));
+ }
else if (command[2].equals("avmpackage"))
{
// lookup source folder of changes
@@ -979,5 +1046,5 @@ public class WorkflowInterpreter
{
return username;
}
-
+
}
\ No newline at end of file
diff --git a/source/java/org/alfresco/repo/workflow/jbpm/AlfrescoAssignment.java b/source/java/org/alfresco/repo/workflow/jbpm/AlfrescoAssignment.java
index de072856a6..e1c717ede8 100644
--- a/source/java/org/alfresco/repo/workflow/jbpm/AlfrescoAssignment.java
+++ b/source/java/org/alfresco/repo/workflow/jbpm/AlfrescoAssignment.java
@@ -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
{
diff --git a/source/java/org/alfresco/repo/workflow/jbpm/AlfrescoJavaScript.java b/source/java/org/alfresco/repo/workflow/jbpm/AlfrescoJavaScript.java
index 5a630ccb5c..73a768c2af 100644
--- a/source/java/org/alfresco/repo/workflow/jbpm/AlfrescoJavaScript.java
+++ b/source/java/org/alfresco/repo/workflow/jbpm/AlfrescoJavaScript.java
@@ -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 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 variableAccesses)
+ {
+ Map 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 createInputMap(ExecutionContext executionContext, List variableAccesses)
+ private static Map createInputMap(ExecutionContext executionContext, ServiceRegistry services, List variableAccesses)
{
Map inputMap = new HashMap();
@@ -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 variableAccesses)
+ private static boolean hasReadableVariable(List 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 variableAccesses)
+ private static VariableAccess getWritableVariable(List variableAccesses)
{
if (variableAccesses != null)
{
diff --git a/source/java/org/alfresco/repo/workflow/jbpm/ForEachFork.java b/source/java/org/alfresco/repo/workflow/jbpm/ForEachFork.java
index c9569ccfcb..6ce1f4cfae 100644
--- a/source/java/org/alfresco/repo/workflow/jbpm/ForEachFork.java
+++ b/source/java/org/alfresco/repo/workflow/jbpm/ForEachFork.java
@@ -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
diff --git a/source/java/org/alfresco/repo/workflow/jbpm/JBPMEngine.java b/source/java/org/alfresco/repo/workflow/jbpm/JBPMEngine.java
index 0d071e7566..215e0eaa6d 100644
--- a/source/java/org/alfresco/repo/workflow/jbpm/JBPMEngine.java
+++ b/source/java/org/alfresco/repo/workflow/jbpm/JBPMEngine.java
@@ -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 doInJbpm(JbpmContext context)
{
- // retrieve pooled tasks for specified authorities
+ // flatten authorities to include all parent authorities
+ Set flattenedAuthorities = new HashSet();
+ for (String authority : authorities)
+ {
+ Set parents = authorityService.getContainingAuthorities(AuthorityType.GROUP, authority, false);
+ flattenedAuthorities.addAll(parents);
+ }
+
+ // retrieve pooled tasks for all flattened authorities
TaskMgmtSession taskSession = context.getTaskMgmtSession();
- List tasks = taskSession.findPooledTaskInstances(authorities);
+ List tasks = taskSession.findPooledTaskInstances(new ArrayList(flattenedAuthorities));
List workflowTasks = new ArrayList(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
*
diff --git a/source/java/org/alfresco/repo/workflow/jbpm/JBPMSpringAssignmentHandler.java b/source/java/org/alfresco/repo/workflow/jbpm/JBPMSpringAssignmentHandler.java
new file mode 100644
index 0000000000..a9f4f376e3
--- /dev/null
+++ b/source/java/org/alfresco/repo/workflow/jbpm/JBPMSpringAssignmentHandler.java
@@ -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);
+
+
+}
diff --git a/source/java/org/alfresco/repo/workflow/jbpm/test_groups.xml b/source/java/org/alfresco/repo/workflow/jbpm/test_groups.xml
new file mode 100644
index 0000000000..5456b9e080
--- /dev/null
+++ b/source/java/org/alfresco/repo/workflow/jbpm/test_groups.xml
@@ -0,0 +1,47 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ #{bpm_groupAssignee}
+
+
+
+
+
+
+
+
+
+
+ #{people.getMembers(bpm_groupAssignee)}
+ reviewer
+
+
+
+
+
+
+
+ #{reviewer}
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file