ALF-2764 Fixed an issue with the ForEachFork incorrectly naming the paths it creates resulting in attempts to cancel the path failing.

git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@22693 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
N Smith
2010-09-24 13:51:01 +00:00
parent 54f28f7c9b
commit 05e3ba62db
4 changed files with 350 additions and 128 deletions

View File

@@ -0,0 +1,87 @@
<?xml version="1.0" encoding="UTF-8"?>
<process-definition xmlns="urn:jbpm.org:jpdl-3.1" name="wf:parallelreview">
<swimlane name="initiator" />
<start-state name="start">
<task name="wf:submitParallelReviewTask" swimlane="initiator" />
<transition name="" to="startreview"/>
</start-state>
<node name="startreview">
<action class="org.alfresco.repo.workflow.jbpm.ForEachFork">
<foreach>#{bpm_assignees}</foreach>
<var>reviewer</var>
</action>
<event type="node-enter">
<script>
<variable name="wf_approveCount" access="write" />
<expression>
wf_approveCount = 0;
</expression>
</script>
</event>
<transition name="review" to="review" />
</node>
<task-node name="review">
<task name="wf:reviewTask">
<assignment class="org.alfresco.repo.workflow.jbpm.AlfrescoAssignment">
<actor>#{reviewer}</actor>
</assignment>
<event type="task-create">
<script>
if (bpm_workflowDueDate != void) taskInstance.dueDate = bpm_workflowDueDate;
if (bpm_workflowPriority != void) taskInstance.priority = bpm_workflowPriority;
</script>
</event>
</task>
<transition name="approve" to="endreview">
<script>
<variable name="wf_approveCount" access="read,write" />
<expression>
wf_approveCount = wf_approveCount +1;
</expression>
</script>
</transition>
<transition name="reject" to="endreview" />
</task-node>
<join name="endreview">
<transition to="isapproved" />
</join>
<decision name="isapproved">
<event type="node-enter">
<script>
<variable name="wf_reviewerCount" access="write"/>
<variable name="wf_requiredPercent" access="write"/>
<variable name="wf_actualPercent" access="write"/>
<expression>
wf_requiredPercent = wf_requiredApprovePercent;
wf_reviewerCount = bpm_assignees.size();
wf_actualPercent = ((wf_approveCount * 100) / wf_reviewerCount);
</expression>
</script>
</event>
<transition name="reject" to="rejected" />
<transition name="approve" to="approved">
<condition>#{wf_actualPercent >= wf_requiredApprovePercent}</condition>
</transition>
</decision>
<task-node name="rejected">
<task name="wf:rejectedParallelTask" swimlane="initiator" />
<transition to="startreview" name="again" />
<transition to="end" />
</task-node>
<task-node name="approved">
<task name="wf:approvedParallelTask" swimlane="initiator" />
<transition to="end" />
</task-node>
<end-state name="end"/>
</process-definition>

View File

@@ -66,6 +66,7 @@ public interface WorkflowModel
static final QName PROP_WORKFLOW_PRIORITY = QName.createQName(NamespaceService.BPM_MODEL_1_0_URI, "workflowPriority");
static final QName PROP_WORKFLOW_DUE_DATE = QName.createQName(NamespaceService.BPM_MODEL_1_0_URI, "workflowDueDate");
static final QName ASSOC_ASSIGNEE = QName.createQName(NamespaceService.BPM_MODEL_1_0_URI, "assignee");
static final QName ASSOC_ASSIGNEES = QName.createQName(NamespaceService.BPM_MODEL_1_0_URI, "assignees");
// workflow package
static final QName ASPECT_WORKFLOW_PACKAGE = QName.createQName(NamespaceService.BPM_MODEL_1_0_URI, "workflowPackage");

View File

@@ -20,6 +20,7 @@ package org.alfresco.repo.workflow.jbpm;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
@@ -47,7 +48,6 @@ public class ForEachFork extends JBPMSpringActionHandler
private Element foreach;
private String var;
/* (non-Javadoc)
* @see org.alfresco.repo.workflow.jbpm.JBPMSpringActionHandler#initialiseHandler(org.springframework.beans.factory.BeanFactory)
*/
@@ -63,7 +63,6 @@ public class ForEachFork extends JBPMSpringActionHandler
* @param executionContext
* @throws Exception
*/
@SuppressWarnings("unchecked")
public void execute(final ExecutionContext executionContext)
throws Exception
{
@@ -76,57 +75,7 @@ public class ForEachFork extends JBPMSpringActionHandler
throw new WorkflowException("forEach has not been provided");
}
// build "for each" collection
List forEachColl = null;
String forEachCollStr = foreach.getTextTrim();
if (forEachCollStr != null)
{
if (forEachCollStr.startsWith("#{"))
{
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");
}
// expression evaluates to string
if (eval instanceof String)
{
String[] forEachStrs = ((String)eval).trim().split(",");
forEachColl = new ArrayList(forEachStrs.length);
for (String forEachStr : forEachStrs)
{
forEachColl.add(forEachStr);
}
}
// expression evaluates to Node array
else if (eval instanceof Serializable[])
{
Serializable[] nodes = (Serializable[])eval;
forEachColl = new ArrayList(nodes.length);
for (Serializable node : nodes)
{
if (node instanceof NodeRef)
{
forEachColl.add(new JBPMNode((NodeRef)node, services));
}
}
}
// expression evaluates to collection
else if (eval instanceof Collection)
{
forEachColl = (List)eval;
}
}
}
else
{
forEachColl = (List)FieldInstantiator.getValue(List.class, foreach);
}
// Collection<?> forEachColl = buildForEachCollection(executionContext);
if (var == null || var.length() == 0)
{
@@ -137,31 +86,30 @@ public class ForEachFork extends JBPMSpringActionHandler
// create forked paths
//
Token rootToken = executionContext.getToken();
Node node = executionContext.getNode();
List<ForkedTransition> forkTransitions = new ArrayList<ForkedTransition>();
// first, create a new token and execution context for each item in list
for (int i = 0; i < node.getLeavingTransitions().size(); i++)
{
Transition transition = (Transition) node.getLeavingTransitions().get(i);
Collection<?> forEachColl = buildForEachCollection(executionContext);
for (int iVar = 0; iVar < forEachColl.size(); iVar++)
// Create a new token and execution context for each node transition and item in list
List<Transition> nodeTransitions = node.getLeavingTransitions();
for (Transition noderansition : nodeTransitions)
{
int iVar = 0;
for (Object item: forEachColl)
{
// create child token to represent new path
String tokenName = getTokenName(rootToken, transition.getName(), iVar);
Token loopToken = new Token(rootToken, tokenName);
loopToken.setTerminationImplicit(true);
executionContext.getJbpmContext().getSession().save(loopToken);
Token loopToken = buildChildToken(executionContext, noderansition, iVar);
iVar++;
// assign variable within path
final ExecutionContext newExecutionContext = new ExecutionContext(loopToken);
newExecutionContext.getContextInstance().createVariable(var, forEachColl.get(iVar), loopToken);
newExecutionContext.getContextInstance().createVariable(var, item, loopToken);
// record path & transition
ForkedTransition forkTransition = new ForkedTransition();
forkTransition.executionContext = newExecutionContext;
forkTransition.transition = transition;
forkTransition.transition = noderansition;
forkTransitions.add(forkTransition);
}
}
@@ -175,6 +123,74 @@ public class ForEachFork extends JBPMSpringActionHandler
}
}
private Token buildChildToken(final ExecutionContext executionContext, Transition noderansition,
int iVar)
{
Token rootToken = executionContext.getToken();
String tokenName = getTokenName(rootToken, noderansition.getName(), iVar);
Token loopToken = new Token(rootToken, tokenName);
loopToken.setTerminationImplicit(true);
executionContext.getJbpmContext().getSession().save(loopToken);
return loopToken;
}
private Collection<?> buildForEachCollection(final ExecutionContext executionContext)
{
// build "for each" collection
String text = foreach.getTextTrim();
if (text != null && text.startsWith("#{"))
{
return evaluateForEachExpression(executionContext, text);
}
return (Collection<?>) FieldInstantiator.getValue(List.class, foreach);
}
private Collection<?> evaluateForEachExpression(final ExecutionContext executionContext, String forEachText)
{
String expression = forEachText.substring(2, forEachText.length() -1);
Object result = AlfrescoJavaScript.executeScript(executionContext, services, expression, null);
if (result == null)
{
throw new WorkflowException("forEach expression '" + forEachText + "' evaluates to null");
}
// expression evaluates to string
if (result instanceof String)
{
return buildStrings((String)result);
}
// expression evaluates to Node array
else if (result instanceof Serializable[])
{
return buildJbpmNodes((Serializable[]) result);
}
// expression evaluates to collection
else if (result instanceof Collection<?>)
{
return (Collection<?>)result;
}
else return null;
}
private List<?> buildStrings(String result)
{
String[] results = result.trim().split(",");
return Arrays.asList(results);
}
private List<?> buildJbpmNodes(Serializable[] nodes)
{
List<JBPMNode> jbpmNodes = new ArrayList<JBPMNode>(nodes.length);
for (Serializable node : nodes)
{
if (node instanceof NodeRef)
{
JBPMNode jbpmNode = new JBPMNode((NodeRef)node, services);
jbpmNodes.add(jbpmNode);
}
}
return jbpmNodes;
}
/**
* Create a token name
*
@@ -184,33 +200,53 @@ public class ForEachFork extends JBPMSpringActionHandler
*/
protected String getTokenName(Token parent, String transitionName, int loopIndex)
{
String tokenName = null;
if (transitionName != null && transitionName.length() > 0)
String suffix = "." + loopIndex;
if (transitionName == null || transitionName.isEmpty())
{
if (!parent.hasChild(transitionName))
{
tokenName = transitionName;
}
else
{
int i = 2;
tokenName = transitionName + Integer.toString(i);
while (parent.hasChild(tokenName))
{
i++;
tokenName = transitionName + Integer.toString(i);
}
}
}
else
{
// no transition name
// No transition name
int size = (parent.getChildren() != null) ? parent.getChildren().size() + 1 : 1;
tokenName = "FOREACHFORK" + Integer.toString(size);
return buildTokenName("FOREACHFORK", suffix, size);
}
return tokenName + "." + loopIndex;
return findFirstAvailableTokenName(parent, transitionName, suffix);
}
private String findFirstAvailableTokenName(Token parent, String transitionName, String suffix)
{
int i = 1;
while (true)
{
String tokenName = buildTokenName(transitionName, suffix, i);
if(!parent.hasChild(tokenName))
{
return tokenName;
}
i++;
}
}
private String buildTokenName(String prefix, String suffix, int count)
{
String countStr = count<2 ? "": Integer.toString(count);
return prefix + countStr + suffix;
}
/**
* Sets the list of objects to be iterated over.
* @param foreach the list of objects to set
*/
public void setForeach(Element foreach)
{
this.foreach = foreach;
}
/**
* Set the name of the variable to which the eleements of <code>foreach</code> are assigned.
* @param var the variable name to set
*/
public void setVar(String var)
{
this.var = var;
}
/**
* Fork Transition

View File

@@ -21,25 +21,22 @@ package org.alfresco.repo.workflow.jbpm;
import java.io.IOException;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.springframework.extensions.surf.util.I18NUtil;
import org.alfresco.model.ContentModel;
import org.alfresco.repo.content.MimetypeMap;
import org.alfresco.repo.security.authentication.AuthenticationComponent;
import org.alfresco.repo.security.authentication.AuthenticationUtil;
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.repo.workflow.WorkflowPackageComponent;
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.WorkflowException;
@@ -49,8 +46,10 @@ import org.alfresco.service.cmr.workflow.WorkflowTask;
import org.alfresco.service.cmr.workflow.WorkflowTaskState;
import org.alfresco.service.namespace.NamespaceService;
import org.alfresco.service.namespace.QName;
import org.alfresco.util.BaseSpringTest;
import org.alfresco.util.BaseAlfrescoSpringTest;
import org.alfresco.util.PropertyMap;
import org.springframework.core.io.ClassPathResource;
import org.springframework.extensions.surf.util.I18NUtil;
/**
@@ -58,22 +57,39 @@ import org.springframework.core.io.ClassPathResource;
*
* @author davidc
*/
public class JBPMEngineTest extends BaseSpringTest
public class JBPMEngineTest extends BaseAlfrescoSpringTest
{
AuthenticationComponent authenticationComponent;
NodeService nodeService;
WorkflowComponent workflowComponent;
TaskComponent taskComponent;
WorkflowPackageComponent packageComponent;
WorkflowDefinition testWorkflowDef;
NodeRef testNodeRef;
/**
*
*/
private static final String USER3 = "JbpmEngineTestJoe";
/**
*
*/
private static final String USER2 = "JbpmEngineTestJane";
/**
*
*/
private static final String USER1 = "JbpmEngineTestJohn";
private WorkflowComponent workflowComponent;
private TaskComponent taskComponent;
private WorkflowPackageComponent packageComponent;
private PersonService personService;
private WorkflowDefinition testWorkflowDef;
private NodeRef person1;
private NodeRef person2;
private NodeRef person3;
@SuppressWarnings("deprecation")
@Override
protected void onSetUpInTransaction() throws Exception
{
// run as system
authenticationComponent = (AuthenticationComponent)applicationContext.getBean("authenticationComponent");
authenticationComponent.setCurrentUser(AuthenticationUtil.getAdminUserName());
super.onSetUpInTransaction();
personService = (PersonService) applicationContext.getBean("PersonService");
person1 = createPerson(USER1);
person2 = createPerson(USER2);
person3 = createPerson(USER3);
BPMEngineRegistry registry = (BPMEngineRegistry)applicationContext.getBean("bpm_engineRegistry");
workflowComponent = registry.getWorkflowComponent("jbpm");
@@ -93,20 +109,9 @@ public class JBPMEngineTest extends BaseSpringTest
assertEquals("1", testWorkflowDef.version);
assertTrue(workflowComponent.isDefinitionDeployed(processDef.getInputStream(), MimetypeMap.MIMETYPE_XML));
// get valid node ref
nodeService = (NodeService)applicationContext.getBean(ServiceRegistry.NODE_SERVICE.getLocalName());
testNodeRef = nodeService.getRootNode(new StoreRef(StoreRef.PROTOCOL_WORKSPACE, "SpacesStore"));
nodeService.setProperty(testNodeRef, ContentModel.PROP_CREATED, new Date());
authenticationComponent.setCurrentUser(AuthenticationUtil.getAdminUserName());
}
@Override
protected void onTearDownInTransaction()
{
authenticationComponent.clearCurrentSecurityContext();
}
public void testGetWorkflowDefinitions()
{
List<WorkflowDefinition> workflowDefs = workflowComponent.getDefinitions();
@@ -135,6 +140,7 @@ public class JBPMEngineTest extends BaseSpringTest
}
catch(WorkflowException e)
{
// Do nothing.
}
// TODO: Determine why process definition is loaded, even though it doesn't exist
@@ -325,7 +331,7 @@ public class JBPMEngineTest extends BaseSpringTest
}
public void testCancelWorkflowInstance()
public void testCancelWorkflowInstance() throws Exception
{
WorkflowDefinition workflowDef = getTestDefinition();
workflowComponent.startWorkflow(workflowDef.id, null);
@@ -348,10 +354,79 @@ public class JBPMEngineTest extends BaseSpringTest
}
/**
* See Alf-2764 in Jira.
* @throws Exception
*/
public void testCancelForEachFork() throws Exception
{
// Deploy Parallel Loop Review process definition.
ClassPathResource processDef = new ClassPathResource("test/alfresco/parallel_loop_review_processdefinition.xml");
WorkflowDeployment deployment = workflowComponent.deployDefinition(processDef.getInputStream(),
MimetypeMap.MIMETYPE_XML);
WorkflowDefinition parallelDef = deployment.getDefinition();
assertNotNull(parallelDef);
// Set Current User to USER1.
AuthenticationUtil.setFullyAuthenticatedUser(USER1);
// Set up parameters
QName approvePercentName = QName.createQName(NamespaceService.WORKFLOW_MODEL_1_0_URI, "requiredApprovePercent");
NodeRef pckgNode = packageComponent.createPackage(null);
List<NodeRef> assignees = Arrays.asList(person1, person2, person3);
Map<QName, Serializable> parameters = new HashMap<QName, Serializable>();
parameters.put(WorkflowModel.ASSOC_ASSIGNEES, (Serializable) assignees);
parameters.put(WorkflowModel.ASSOC_PACKAGE, pckgNode);
parameters.put(approvePercentName, 60f );
// Start workflow
WorkflowPath path = workflowComponent.startWorkflow(parallelDef.getId(), parameters);
WorkflowTask startTask = workflowComponent.getTasksForWorkflowPath(path.getId()).get(0);
taskComponent.endTask(startTask.getId(), null);
checkInstanceExists(path.instance.getId(), parallelDef.getId(), true);
// Set all users to reject document.
ParallelReject(USER1);
ParallelReject(USER2);
ParallelReject(USER3);
// Send review back round the loop.
List<WorkflowTask> tasks = workflowComponent.getTasksForWorkflowPath(path.getId());
assertEquals(1, tasks.size());
taskComponent.endTask(tasks.get(0).getId(), "again");
// Try to cancel workflow
WorkflowInstance cancelledWf = workflowComponent.cancelWorkflow(path.getInstance().getId());
checkInstanceExists(cancelledWf.getId(), parallelDef.getId(), false);
}
private void checkInstanceExists(String instanceId, String defId, boolean expected)
{
boolean match=false;
List<WorkflowInstance> activeWfs = workflowComponent.getActiveWorkflows(defId);
for (WorkflowInstance instance : activeWfs)
{
if(instance.getId().equals(instanceId))
{
match = true;
break;
}
}
assertEquals( expected, match);
}
private void ParallelReject(String user)
{
List<WorkflowTask> tasks = taskComponent.getAssignedTasks(user, WorkflowTaskState.IN_PROGRESS);
assertEquals(1, tasks.size());
WorkflowTask task = tasks.get(0);
taskComponent.endTask(task.getId(), "reject");
}
public void testSignal()
{
Map<QName, Serializable> parameters = new HashMap<QName, Serializable>();
parameters.put(QName.createQName(NamespaceService.DEFAULT_URI, "testNode"), testNodeRef);
parameters.put(QName.createQName(NamespaceService.DEFAULT_URI, "testNode"), rootNodeRef);
WorkflowDefinition workflowDef = getTestDefinition();
WorkflowPath path = workflowComponent.startWorkflow(workflowDef.id, parameters);
assertNotNull(path);
@@ -365,7 +440,7 @@ public class JBPMEngineTest extends BaseSpringTest
WorkflowDefinition workflowDef = getTestDefinition();
Map<QName, Serializable> parameters = new HashMap<QName, Serializable>();
parameters.put(QName.createQName(NamespaceService.DEFAULT_URI, "reviewer"), AuthenticationUtil.getAdminUserName());
parameters.put(QName.createQName(NamespaceService.DEFAULT_URI, "testNode"), testNodeRef);
parameters.put(QName.createQName(NamespaceService.DEFAULT_URI, "testNode"), rootNodeRef);
parameters.put(QName.createQName(NamespaceService.BPM_MODEL_1_0_URI, "package"), packageComponent.createPackage(null));
WorkflowPath path = workflowComponent.startWorkflow(workflowDef.id, parameters);
assertNotNull(path);
@@ -395,7 +470,7 @@ public class JBPMEngineTest extends BaseSpringTest
bpm_assignees.add("fred");
Map<QName, Serializable> parameters = new HashMap<QName, Serializable>();
parameters.put(QName.createQName(NamespaceService.BPM_MODEL_1_0_URI, "assignees"), (Serializable)bpm_assignees);
parameters.put(QName.createQName(NamespaceService.DEFAULT_URI, "testNode"), testNodeRef);
parameters.put(QName.createQName(NamespaceService.DEFAULT_URI, "testNode"), rootNodeRef);
WorkflowPath path = workflowComponent.startWorkflow(workflowDef.id, parameters);
assertNotNull(path);
List<WorkflowTask> tasks = workflowComponent.getTasksForWorkflowPath(path.id);
@@ -411,7 +486,7 @@ public class JBPMEngineTest extends BaseSpringTest
WorkflowDefinition workflowDef = getTestDefinition();
Map<QName, Serializable> parameters = new HashMap<QName, Serializable>();
parameters.put(QName.createQName(NamespaceService.DEFAULT_URI, "reviewer"), AuthenticationUtil.getAdminUserName());
parameters.put(QName.createQName(NamespaceService.DEFAULT_URI, "testNode"), testNodeRef);
parameters.put(QName.createQName(NamespaceService.DEFAULT_URI, "testNode"), rootNodeRef);
parameters.put(QName.createQName(NamespaceService.BPM_MODEL_1_0_URI, "package"), packageComponent.createPackage(null));
WorkflowPath path = workflowComponent.startWorkflow(workflowDef.id, parameters);
assertNotNull(path);
@@ -435,7 +510,7 @@ public class JBPMEngineTest extends BaseSpringTest
WorkflowDefinition workflowDef = getTestDefinition();
Map<QName, Serializable> parameters = new HashMap<QName, Serializable>();
parameters.put(QName.createQName(NamespaceService.DEFAULT_URI, "reviewer"), AuthenticationUtil.getAdminUserName());
parameters.put(QName.createQName(NamespaceService.DEFAULT_URI, "testNode"), testNodeRef);
parameters.put(QName.createQName(NamespaceService.DEFAULT_URI, "testNode"), rootNodeRef);
WorkflowPath path = workflowComponent.startWorkflow(workflowDef.id, parameters);
assertNotNull(path);
assertNotNull(path);
@@ -453,7 +528,7 @@ public class JBPMEngineTest extends BaseSpringTest
WorkflowDefinition workflowDef = getTestDefinition();
Map<QName, Serializable> parameters = new HashMap<QName, Serializable>();
parameters.put(QName.createQName(NamespaceService.DEFAULT_URI, "reviewer"), AuthenticationUtil.getAdminUserName());
parameters.put(QName.createQName(NamespaceService.DEFAULT_URI, "testNode"), testNodeRef);
parameters.put(QName.createQName(NamespaceService.DEFAULT_URI, "testNode"), rootNodeRef);
parameters.put(QName.createQName(NamespaceService.BPM_MODEL_1_0_URI, "package"), packageComponent.createPackage(null));
WorkflowPath path = workflowComponent.startWorkflow(workflowDef.id, parameters);
assertNotNull(path);
@@ -477,7 +552,7 @@ public class JBPMEngineTest extends BaseSpringTest
WorkflowDefinition workflowDef = deployment.definition;
Map<QName, Serializable> parameters = new HashMap<QName, Serializable>();
parameters.put(QName.createQName(NamespaceService.DEFAULT_URI, "testNode"), testNodeRef);
parameters.put(QName.createQName(NamespaceService.DEFAULT_URI, "testNode"), rootNodeRef);
parameters.put(QName.createQName(NamespaceService.BPM_MODEL_1_0_URI, "package"), packageComponent.createPackage(null));
WorkflowPath path = workflowComponent.startWorkflow(workflowDef.id, parameters);
assertNotNull(path);
@@ -501,6 +576,29 @@ public class JBPMEngineTest extends BaseSpringTest
}
private NodeRef createPerson(String userName)
{
// if user with given user name doesn't already exist then create user
if (this.authenticationService.authenticationExists(userName) == false)
{
// create user
this.authenticationService.createAuthentication(userName, "password".toCharArray());
}
// if person node with given user name doesn't already exist then create
// person
if (this.personService.personExists(userName) == false)
{
// create person properties
PropertyMap personProps = new PropertyMap();
personProps.put(ContentModel.PROP_USERNAME, userName);
// create person node for user
return personService.createPerson(personProps);
}
return personService.getPerson(userName);
}
/**
* Filter task list by workflow instance
*