diff --git a/config/alfresco/activiti-context.xml b/config/alfresco/activiti-context.xml index f4fbd8a48a..221c74a8ad 100644 --- a/config/alfresco/activiti-context.xml +++ b/config/alfresco/activiti-context.xml @@ -30,11 +30,11 @@ + class="org.alfresco.repo.workflow.activiti.AlfrescoBpmnParseListener"> - + diff --git a/source/java/org/alfresco/repo/invitation/AbstractInvitationServiceImplTest.java b/source/java/org/alfresco/repo/invitation/AbstractInvitationServiceImplTest.java index 66453f2d7f..508334d8f0 100644 --- a/source/java/org/alfresco/repo/invitation/AbstractInvitationServiceImplTest.java +++ b/source/java/org/alfresco/repo/invitation/AbstractInvitationServiceImplTest.java @@ -799,6 +799,7 @@ public abstract class AbstractInvitationServiceImplTest extends BaseAlfrescoSpri { invitationService.approve(invitationId, "No Way Hosea!"); assertTrue("excetion not thrown", false); + } catch (Exception e) { @@ -867,6 +868,7 @@ public abstract class AbstractInvitationServiceImplTest extends BaseAlfrescoSpri { invitationService.reject(invitationId, "No Way Hosea!"); assertTrue("excetion not thrown", false); + } catch (Exception e) { @@ -967,9 +969,16 @@ public abstract class AbstractInvitationServiceImplTest extends BaseAlfrescoSpri * Search with an empty criteria - should find all open invitations */ InvitationSearchCriteria crit2 = new InvitationSearchCriteriaImpl(); - invitationService.searchInvitation(crit2); assertTrue("search everything returned 0 elements", resFive.size() > 0); + + InvitationSearchCriteriaImpl crit3 = new InvitationSearchCriteriaImpl(); + crit3.setInviter(USER_MANAGER); + crit3.setInvitationType(InvitationSearchCriteria.InvitationType.NOMINATED); + + List res3 = invitationService.searchInvitation(crit3); + assertEquals("user one does not have 2 nominated", 2, res3.size()); + } /** diff --git a/source/java/org/alfresco/repo/invitation/InvitationServiceImpl.java b/source/java/org/alfresco/repo/invitation/InvitationServiceImpl.java index 3df3d287a1..9354bf81fd 100644 --- a/source/java/org/alfresco/repo/invitation/InvitationServiceImpl.java +++ b/source/java/org/alfresco/repo/invitation/InvitationServiceImpl.java @@ -273,12 +273,12 @@ public class InvitationServiceImpl implements InvitationService, NodeServicePoli { WorkflowTask startTask = getStartTask(invitationId); NominatedInvitation invitation = getNominatedInvitation(startTask); - if (invitation == null) + if(invitation == null) { throw new InvitationException("State error, accept may only be called on a nominated invitation."); } // Check invitationId and ticket match - if (invitation.getTicket().equals(ticket)==false) + if(invitation.getTicket().equals(ticket)==false) { //TODO localise msg String msg = "Response to invite has supplied an invalid ticket. The response to the invitation could thus not be processed"; @@ -293,12 +293,12 @@ public class InvitationServiceImpl implements InvitationService, NodeServicePoli private void endInvitation(WorkflowTask startTask, String transition, Map properties, QName... taskTypes ) { List tasks = workflowService.getTasksForWorkflowPath(startTask.getPath().getId()); - if (tasks.size()==1) + if(tasks.size()==1) { WorkflowTask task = tasks.get(0); - if (taskTypeMatches(task, taskTypes)) + if(taskTypeMatches(task, taskTypes)) { - if (properties != null) + if(properties != null) { workflowService.updateTask(task.getId(), properties, null, null); } @@ -321,7 +321,7 @@ public class InvitationServiceImpl implements InvitationService, NodeServicePoli { WorkflowTask startTask = getStartTask(invitationId); ModeratedInvitation invitation = getModeratedInvitation(startTask); - if (invitation == null) + if(invitation == null) { String msg = "State error, can only call approve on a Moderated invitation."; throw new InvitationException(msg); @@ -349,7 +349,7 @@ public class InvitationServiceImpl implements InvitationService, NodeServicePoli public Invitation reject(String invitationId, String reason) { WorkflowTask startTask = getStartTask(invitationId); - if (taskTypeMatches(startTask, WorkflowModelModeratedInvitation.WF_START_TASK)) + if(taskTypeMatches(startTask, WorkflowModelModeratedInvitation.WF_START_TASK)) { return rejectModeratedInvitation(startTask, reason); } @@ -392,7 +392,7 @@ public class InvitationServiceImpl implements InvitationService, NodeServicePoli public Invitation cancel(String invitationId) { WorkflowTask startTask = getStartTask(invitationId); - if (taskTypeMatches(startTask, WorkflowModelModeratedInvitation.WF_START_TASK)) + if(taskTypeMatches(startTask, WorkflowModelModeratedInvitation.WF_START_TASK)) { return cancelModeratedInvitation(startTask); } @@ -445,7 +445,7 @@ public class InvitationServiceImpl implements InvitationService, NodeServicePoli private Invitation getInvitation(WorkflowTask startTask) { Invitation invitation = getNominatedInvitation(startTask); - if (invitation == null) + if(invitation == null) { invitation = getModeratedInvitation(startTask); } @@ -576,12 +576,12 @@ public class InvitationServiceImpl implements InvitationService, NodeServicePoli return false; } String inviter = criteria.getInviter(); - if (inviter!= null) + if(inviter!= null) { if (invitation instanceof NominatedInvitation) { NominatedInvitation modInvite = (NominatedInvitation) invitation; - if(inviter.equals(modInvite.getInviterUserName())) + if(false == inviter.equals(modInvite.getInviterUserName())) { return false; } @@ -627,20 +627,20 @@ public class InvitationServiceImpl implements InvitationService, NodeServicePoli // query for invite workflow tasks List results = new ArrayList(); - if (workflowAdminService.isEngineEnabled(JBPMEngine.ENGINE_ID)) + if(workflowAdminService.isEngineEnabled(JBPMEngine.ENGINE_ID)) { query.setTaskName(WorkflowModelModeratedInvitation.WF_REVIEW_TASK); List jbpmTasks = this.workflowService.queryTasks(query); - if (jbpmTasks != null) + if(jbpmTasks !=null) { results.addAll(jbpmTasks); } } - if (workflowAdminService.isEngineEnabled(ActivitiConstants.ENGINE_ID)) + if(workflowAdminService.isEngineEnabled(ActivitiConstants.ENGINE_ID)) { query.setTaskName(WorkflowModelModeratedInvitation.WF_ACTIVITI_REVIEW_TASK); List jbpmTasks = this.workflowService.queryTasks(query); - if (jbpmTasks != null) + if(jbpmTasks !=null) { results.addAll(jbpmTasks); } @@ -654,7 +654,7 @@ public class InvitationServiceImpl implements InvitationService, NodeServicePoli query.setTaskState(WorkflowTaskState.IN_PROGRESS); String invitee = criteria.getInvitee(); - if (invitee != null) + if(invitee != null) { query.setActorId(invitee); } @@ -682,20 +682,20 @@ public class InvitationServiceImpl implements InvitationService, NodeServicePoli query.setProcessCustomProps(queryProps); List results = new ArrayList(); - if (workflowAdminService.isEngineEnabled(JBPMEngine.ENGINE_ID)) + if(workflowAdminService.isEngineEnabled(JBPMEngine.ENGINE_ID)) { query.setTaskName(WorkflowModelNominatedInvitation.WF_TASK_INVITE_PENDING); List jbpmTasks = this.workflowService.queryTasks(query); - if (jbpmTasks != null) + if(jbpmTasks !=null) { results.addAll(jbpmTasks); } } - if (workflowAdminService.isEngineEnabled(ActivitiConstants.ENGINE_ID)) + if(workflowAdminService.isEngineEnabled(ActivitiConstants.ENGINE_ID)) { query.setTaskName(WorkflowModelNominatedInvitation.WF_TASK_ACTIVIT_INVITE_PENDING); List jbpmTasks = this.workflowService.queryTasks(query); - if (jbpmTasks != null) + if(jbpmTasks !=null) { results.addAll(jbpmTasks); } @@ -1180,29 +1180,27 @@ public class InvitationServiceImpl implements InvitationService, NodeServicePoli private String getNominatedDefinitionName() { - if (workflowAdminService.isEngineEnabled(ActivitiConstants.ENGINE_ID)) + if(workflowAdminService.isEngineEnabled(ActivitiConstants.ENGINE_ID)) { return WorkflowModelNominatedInvitation.WORKFLOW_DEFINITION_NAME_ACTIVITI; } - else if (workflowAdminService.isEngineEnabled(JBPMEngine.ENGINE_ID)) + else if(workflowAdminService.isEngineEnabled(JBPMEngine.ENGINE_ID)) { return WorkflowModelNominatedInvitation.WORKFLOW_DEFINITION_NAME; } - throw new IllegalStateException("None of the Workflow engines supported by teh InvitationService are currently enabled!"); } private String getModeratedDefinitionName() { - if (workflowAdminService.isEngineEnabled(ActivitiConstants.ENGINE_ID)) + if(workflowAdminService.isEngineEnabled(ActivitiConstants.ENGINE_ID)) { return WorkflowModelModeratedInvitation.WORKFLOW_DEFINITION_NAME_ACTIVITI; } - else if (workflowAdminService.isEngineEnabled(JBPMEngine.ENGINE_ID)) + else if(workflowAdminService.isEngineEnabled(JBPMEngine.ENGINE_ID)) { return WorkflowModelModeratedInvitation.WORKFLOW_DEFINITION_NAME; } - throw new IllegalStateException("None of the Workflow engines supported by teh InvitationService are currently enabled!"); } diff --git a/source/java/org/alfresco/repo/jscript/ScriptNode.java b/source/java/org/alfresco/repo/jscript/ScriptNode.java index ecb7d4bbd4..f5af05fb3e 100644 --- a/source/java/org/alfresco/repo/jscript/ScriptNode.java +++ b/source/java/org/alfresco/repo/jscript/ScriptNode.java @@ -82,7 +82,6 @@ import org.alfresco.service.cmr.security.PermissionService; import org.alfresco.service.cmr.thumbnail.ThumbnailService; import org.alfresco.service.cmr.version.Version; import org.alfresco.service.cmr.version.VersionHistory; -import org.alfresco.service.cmr.version.VersionServiceException; import org.alfresco.service.cmr.version.VersionType; import org.alfresco.service.cmr.workflow.WorkflowInstance; import org.alfresco.service.cmr.workflow.WorkflowService; @@ -118,7 +117,7 @@ import org.springframework.extensions.surf.util.URLEncoder; * * @author Kevin Roast */ -public class ScriptNode implements Serializable, Scopeable, NamespacePrefixResolverProvider +public class ScriptNode implements Scopeable, NamespacePrefixResolverProvider { private static final long serialVersionUID = -3378946227712939601L; @@ -880,6 +879,15 @@ public class ScriptNode implements Serializable, Scopeable, NamespacePrefixResol return getParentAssocs(); } + /** + * Checks whether the {@link ScriptNode} exists in the repository. + * @return + */ + public boolean exists() + { + return nodeService.exists(nodeRef); + } + /** * Return all the properties known about this node. The Map returned implements the Scriptable interface to * allow access to the properties via JavaScript associative array access. This means properties of a node can diff --git a/source/java/org/alfresco/repo/tenant/MultiTServiceImpl.java b/source/java/org/alfresco/repo/tenant/MultiTServiceImpl.java index 3ced724ca3..6d23624055 100644 --- a/source/java/org/alfresco/repo/tenant/MultiTServiceImpl.java +++ b/source/java/org/alfresco/repo/tenant/MultiTServiceImpl.java @@ -31,10 +31,10 @@ import org.alfresco.service.cmr.repository.StoreRef; import org.alfresco.service.cmr.search.SearchService; import org.alfresco.service.namespace.NamespaceService; import org.alfresco.service.namespace.QName; -import org.springframework.extensions.surf.util.I18NUtil; -import org.springframework.extensions.surf.util.ParameterCheck; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import org.springframework.extensions.surf.util.I18NUtil; +import org.springframework.extensions.surf.util.ParameterCheck; /* * MT Service implementation @@ -537,6 +537,11 @@ public class MultiTServiceImpl implements TenantService * @see org.alfresco.repo.tenant.TenantService#isTenantName(java.lang.String) */ public boolean isTenantName(String name) + { + return getMultiTenantDomainName(name) != null; + } + + public static String getMultiTenantDomainName(String name) { // Check that all the passed values are not null ParameterCheck.mandatory("name", name); @@ -547,11 +552,12 @@ public class MultiTServiceImpl implements TenantService int idx2 = name.indexOf(SEPARATOR, 1); if (idx2 != -1) { - return true; + return name.substring(1, idx2); + } } - return false; + return null; } /* (non-Javadoc) diff --git a/source/java/org/alfresco/repo/workflow/WorkflowDeployer.java b/source/java/org/alfresco/repo/workflow/WorkflowDeployer.java index 1b98ad6545..30b97b582e 100644 --- a/source/java/org/alfresco/repo/workflow/WorkflowDeployer.java +++ b/source/java/org/alfresco/repo/workflow/WorkflowDeployer.java @@ -333,7 +333,17 @@ public class WorkflowDeployer extends AbstractLifecycleBean catch(Throwable e) { // rollback the transaction - try { if (userTransaction != null) {userTransaction.rollback();} } catch (Exception ex) { /* NOOP */ } + try + { + if (userTransaction != null) + { + userTransaction.rollback(); + } + } + catch (Exception ex) + { + // NOOP + } throw new AlfrescoRuntimeException("Workflow deployment failed", e); } finally diff --git a/source/java/org/alfresco/repo/workflow/WorkflowObjectFactory.java b/source/java/org/alfresco/repo/workflow/WorkflowObjectFactory.java index 772e81ce17..ae6e8701a5 100644 --- a/source/java/org/alfresco/repo/workflow/WorkflowObjectFactory.java +++ b/source/java/org/alfresco/repo/workflow/WorkflowObjectFactory.java @@ -21,10 +21,12 @@ package org.alfresco.repo.workflow; import java.io.Serializable; import java.util.Date; +import java.util.List; import java.util.Map; import org.alfresco.repo.i18n.MessageService; import org.alfresco.repo.jscript.ScriptNode; +import org.alfresco.repo.tenant.MultiTServiceImpl; import org.alfresco.repo.tenant.TenantService; import org.alfresco.service.cmr.dictionary.DictionaryService; import org.alfresco.service.cmr.dictionary.TypeDefinition; @@ -41,6 +43,9 @@ import org.alfresco.service.cmr.workflow.WorkflowTaskState; import org.alfresco.service.cmr.workflow.WorkflowTimer; import org.alfresco.service.cmr.workflow.WorkflowTransition; import org.alfresco.service.namespace.QName; +import org.alfresco.util.collections.CollectionUtils; +import org.alfresco.util.collections.Filter; +import org.alfresco.util.collections.Function; /** * @author Nick Smith @@ -158,7 +163,7 @@ public class WorkflowObjectFactory workflowInstance.priority = (Integer) getVariable(variables, WorkflowModel.PROP_WORKFLOW_PRIORITY); Date dueDate = (Date) getVariable(variables, WorkflowModel.PROP_WORKFLOW_DUE_DATE); - if (dueDate != null) + if(dueDate != null) { workflowInstance.dueDate = dueDate; } @@ -190,7 +195,7 @@ public class WorkflowObjectFactory public WorkflowTaskDefinition createTaskDefinition(String id, WorkflowNode node, String typeName, boolean isStart) { TypeDefinition metaData = getTaskTypeDefinition(typeName, isStart); - if (id == null) + if(id == null) { id = qNameConverter.mapQNameToName(metaData.getName()); } @@ -217,13 +222,13 @@ public class WorkflowObjectFactory } public WorkflowTimer createWorkflowTimer(String id, String name, String error, - Date dueDate, WorkflowPath workflowPath, WorkflowTask workflowTask) + Date dueDate, WorkflowPath workflowPath, WorkflowTask workflowTask) { String actualId = buildGlobalId(id); return new WorkflowTimer(actualId, name, workflowPath, workflowTask, dueDate, error); } - private String getProcessKey(String defName) + public String getProcessKey(String defName) { String processKey = defName; if (isGlobalId(defName)) @@ -260,7 +265,7 @@ public class WorkflowObjectFactory String key = keyBase+ "." + labelKey; String label = messageService.getMessage(key); int i = 0; - while (label == null && i < defaults.length) + while(label==null && i variables, QName qName) { Object obj = getVariable(variables, qName); - if (obj == null) + if (obj==null) { return null; } - if (obj instanceof ScriptNode) + if(obj instanceof ScriptNode) { ScriptNode scriptNode = (ScriptNode) obj; return scriptNode.getNodeRef(); @@ -286,7 +291,7 @@ public class WorkflowObjectFactory private Object getVariable(Map variables, QName qName) { - if (variables == null || qName == null) + if(variables == null || qName == null) return null; String varName = qNameConverter.mapQNameToName(qName); return variables.get(varName); @@ -294,7 +299,7 @@ public class WorkflowObjectFactory private Object getVariable(Map variables, String key) { - if (variables == null || key == null) + if(variables == null || key == null) return null; return variables.get(key); } @@ -303,7 +308,7 @@ public class WorkflowObjectFactory * Throws exception if domain mismatch * @param defName */ - private void checkDomain(String defName) + public void checkDomain(String defName) { if (tenantService.isEnabled()) { @@ -316,6 +321,29 @@ public class WorkflowObjectFactory } } + public List filterByDomain(List values, final Function processKeyGetter) + { + final boolean enabled = tenantService.isEnabled(); + final String currentDomain = tenantService.getCurrentUserDomain(); + return CollectionUtils.filter(values, new Filter() + { + public Boolean apply(T value) + { + String key = processKeyGetter.apply(value); + String domain = MultiTServiceImpl.getMultiTenantDomainName(key); + if(enabled && false == currentDomain.equals(domain)) + { + return false; // The domains do not match so ignore. + } + else if(domain!=null) + { + return false; // Ignore domain-specific definitions + } + return true; + } + }); + } + /** * Returns an anonymous {@link TypeDefinition} for the given name with all * the mandatory aspects applied. @@ -342,7 +370,7 @@ public class WorkflowObjectFactory public TypeDefinition getTaskTypeDefinition(String name, boolean isStart) { TypeDefinition typeDef = null; - if (name!=null) + if(name!=null) { QName typeName = qNameConverter.mapNameToQName(name); typeDef = dictionaryService.getType(typeName); @@ -360,7 +388,7 @@ public class WorkflowObjectFactory return typeDef; } - /** + /** * Map QName to jBPM variable name * * @param name QName diff --git a/source/java/org/alfresco/repo/workflow/activiti/ActivitiTypeConverter.java b/source/java/org/alfresco/repo/workflow/activiti/ActivitiTypeConverter.java index ddee63a755..1ff1174111 100644 --- a/source/java/org/alfresco/repo/workflow/activiti/ActivitiTypeConverter.java +++ b/source/java/org/alfresco/repo/workflow/activiti/ActivitiTypeConverter.java @@ -56,6 +56,7 @@ import org.alfresco.service.cmr.workflow.WorkflowTaskDefinition; import org.alfresco.service.cmr.workflow.WorkflowTaskState; import org.alfresco.service.cmr.workflow.WorkflowTransition; import org.alfresco.service.namespace.QName; +import org.alfresco.util.collections.Function; /** * @author Nick Smith @@ -91,6 +92,12 @@ public class ActivitiTypeConverter this.propertyConverter =propertyConverter; this.activitiUtil = new ActivitiUtil(processEngine); } + + public List filterByDomainAndConvert(List values, Function processKeyGetter) + { + List filtered = factory.filterByDomain(values, processKeyGetter); + return convert(filtered); + } /** * Convert a {@link Deployment} into a {@link WorkflowDeployment}. @@ -99,7 +106,7 @@ public class ActivitiTypeConverter */ public WorkflowDeployment convert(Deployment deployment) { - if (deployment == null) + if(deployment == null) return null; List processDefs = repoService.createProcessDefinitionQuery() @@ -117,7 +124,7 @@ public class ActivitiTypeConverter */ public WorkflowDefinition convert(ProcessDefinition definition) { - if (definition==null) + if(definition==null) return null; String defId = definition.getId(); @@ -127,7 +134,7 @@ public class ActivitiTypeConverter String startTaskName = null; StartFormData startFormData = formService.getStartFormData(definition.getId()); - if (startFormData != null) + if(startFormData != null) { startTaskName = startFormData.getFormKey(); } @@ -147,7 +154,7 @@ public class ActivitiTypeConverter String startTitle = (String) activity.getProperty(ActivitiConstants.NODE_NAME); String startDescription= (String) activity.getProperty(ActivitiConstants.NODE_DESCRIPTION); String startType = (String) activity.getProperty(ActivitiConstants.NODE_TYPE); - if (taskFormKey == null) + if(taskFormKey == null) { taskFormKey = startId; } @@ -163,20 +170,20 @@ public class ActivitiTypeConverter public WorkflowInstance convertAndSetVariables(ProcessInstance instance, Map collectedvariables) { - if (instance == null) + if(instance == null) return null; HistoricProcessInstance historicInstance = historyService - .createHistoricProcessInstanceQuery() - .processInstanceId(instance.getId()) - .singleResult(); + .createHistoricProcessInstanceQuery() + .processInstanceId(instance.getId()) + .singleResult(); return convertToInstanceAndSetVariables(historicInstance, collectedvariables); } public WorkflowInstance convert(HistoricProcessInstance instance, Map collectedvariables) { - if (instance == null) + if(instance == null) return null; HistoricProcessInstance historicInstance = historyService @@ -196,7 +203,7 @@ public class ActivitiTypeConverter public WorkflowPath convert(Execution execution, ProcessInstance instance) { - if (execution == null) + if(execution == null) return null; boolean isActive = !execution.isEnded(); @@ -221,22 +228,22 @@ public class ActivitiTypeConverter public WorkflowNode convert(PvmActivity activity, boolean forceIsTaskNode) { - String procDefId = activity.getProcessDefinition().getId(); - String key = activitiUtil.getProcessDefinition(procDefId).getKey(); - String name = activity.getId(); - String defaultTitle = (String) activity.getProperty(ActivitiConstants.NODE_NAME); - String defaultDescription = (String) activity.getProperty(ActivitiConstants.NODE_DESCRIPTION); - String type = (String) activity.getProperty(ActivitiConstants.NODE_TYPE); - boolean isTaskNode = forceIsTaskNode || ActivitiConstants.USER_TASK_NODE_TYPE.equals(type); - - if (defaultTitle == null) - { - defaultTitle = name; - } - if (defaultDescription == null) - { - defaultDescription = name; - } + String procDefId = activity.getProcessDefinition().getId(); + String key = activitiUtil.getProcessDefinition(procDefId).getKey(); + String name = activity.getId(); + String defaultTitle = (String) activity.getProperty(ActivitiConstants.NODE_NAME); + String defaultDescription = (String) activity.getProperty(ActivitiConstants.NODE_DESCRIPTION); + String type = (String) activity.getProperty(ActivitiConstants.NODE_TYPE); + boolean isTaskNode = forceIsTaskNode || ActivitiConstants.USER_TASK_NODE_TYPE.equals(type); + + if(defaultTitle == null) + { + defaultTitle = name; + } + if(defaultDescription == null) + { + defaultDescription = name; + } return factory.createNode(name, key, defaultTitle, defaultDescription, type, isTaskNode, NEXT_TRANSITION); } @@ -263,7 +270,7 @@ public class ActivitiTypeConverter for (Object in : inputs) { T out = (T) convert(in); - if (out != null) + if(out != null) { results.add(out); } @@ -279,7 +286,7 @@ public class ActivitiTypeConverter */ private Object convert(Object obj) { - if (obj == null) + if(obj == null) return null; if (obj instanceof Deployment) @@ -306,11 +313,11 @@ public class ActivitiTypeConverter { return convert( (Task) obj); } - if (obj instanceof HistoricTaskInstance) + if(obj instanceof HistoricTaskInstance) { return convert((HistoricTaskInstance) obj); } - if (obj instanceof HistoricProcessInstance) + if(obj instanceof HistoricProcessInstance) { return convert((HistoricProcessInstance) obj); } @@ -320,9 +327,8 @@ public class ActivitiTypeConverter public WorkflowTask convert(Task task) { - if (task == null) + if(task == null) return null; - String id = task.getId(); String defaultTitle = task.getName(); String defaultDescription = task.getDescription(); @@ -338,14 +344,14 @@ public class ActivitiTypeConverter TaskFormData taskFormData =formService.getTaskFormData(task.getId()); String taskDefId = null; - if (taskFormData != null) + if(taskFormData != null) { taskDefId = taskFormData.getFormKey(); } WorkflowTaskDefinition taskDef = factory.createTaskDefinition(taskDefId, node, taskDefId, false); // All task-properties should be fetched, not only local - Map properties = propertyConverter.getTaskProperties(task, false); + Map properties = propertyConverter.getTaskProperties(task); return factory.createTask(id, taskDef, taskDef.getId(), defaultTitle, defaultDescription, state, path, properties); @@ -361,7 +367,7 @@ public class ActivitiTypeConverter String id = ActivitiConstants.START_TASK_PREFIX + execution.getProcessInstanceId(); WorkflowTaskState state = null; - if (inProgress) + if(inProgress) { state = WorkflowTaskState.IN_PROGRESS; } @@ -378,7 +384,7 @@ public class ActivitiTypeConverter StartFormData startFormData = formService.getStartFormData(processInstance.getProcessDefinitionId()); String taskDefId = null; - if (startFormData != null) + if(startFormData != null) { taskDefId = startFormData.getFormKey(); } @@ -402,7 +408,7 @@ public class ActivitiTypeConverter public WorkflowTask getVirtualStartTask(HistoricProcessInstance historicProcessInstance) { - if (historicProcessInstance == null) + if(historicProcessInstance == null) { return null; } @@ -413,7 +419,7 @@ public class ActivitiTypeConverter WorkflowTaskState state = null; boolean completed = historicProcessInstance.getEndTime() != null; - if (completed) + if(completed) { state = WorkflowTaskState.COMPLETED; } @@ -424,7 +430,7 @@ public class ActivitiTypeConverter // We use the process-instance ID as execution-id. It's ended anyway WorkflowPath path = buildCompletedPath(processInstanceId, processInstanceId); - if (path == null) + if(path == null) { return null; } @@ -448,7 +454,7 @@ public class ActivitiTypeConverter public WorkflowTask convert(HistoricTaskInstance historicTaskInstance) { - if (historicTaskInstance == null) + if(historicTaskInstance == null) { return null; } @@ -456,7 +462,7 @@ public class ActivitiTypeConverter // Check to see if the instance is still running Execution execution = activitiUtil.getExecution(historicTaskInstance.getExecutionId()); - if (execution != null) + if(execution != null) { // Process execution still running path = convert(execution); @@ -467,7 +473,7 @@ public class ActivitiTypeConverter path = buildCompletedPath(historicTaskInstance.getExecutionId(), historicTaskInstance.getProcessInstanceId()); } - if (path == null) + if(path == null) { // When path is null, workflow is deleted or cancelled. Task should // not be used @@ -497,16 +503,16 @@ public class ActivitiTypeConverter private WorkflowNode buildHistoricTaskWorkflowNode(HistoricTaskInstance historicTaskInstance) { - ReadOnlyProcessDefinition procDef = activitiUtil.getDeployedProcessDefinition(historicTaskInstance.getProcessDefinitionId()); - PvmActivity taskActivity = procDef.findActivity(historicTaskInstance.getTaskDefinitionKey()); - return convert(taskActivity); - } + ReadOnlyProcessDefinition procDef = activitiUtil.getDeployedProcessDefinition(historicTaskInstance.getProcessDefinitionId()); + PvmActivity taskActivity = procDef.findActivity(historicTaskInstance.getTaskDefinitionKey()); + return convert(taskActivity); + } - public WorkflowPath buildCompletedPath(String executionId, String processInstanceId) + public WorkflowPath buildCompletedPath(String executionId, String processInstanceId) { WorkflowInstance wfInstance = null; ProcessInstance processInstance = activitiUtil.getProcessInstance(processInstanceId); - if (processInstance != null) + if(processInstance != null) { wfInstance = convert(processInstance); } @@ -516,10 +522,10 @@ public class ActivitiTypeConverter if(historicProcessInstance!= null) wfInstance = convert(historicProcessInstance); } - if (wfInstance == null) + if(wfInstance == null) { - // When workflow is cancelled or deleted, WorkflowPath should not be returned - return null; + // When workflow is cancelled or deleted, WorkflowPath should not be returned + return null; } WorkflowNode node = null; return factory.createPath(executionId, wfInstance, node, false); @@ -539,9 +545,9 @@ public class ActivitiTypeConverter Date endDate = historicProcessInstance.getEndTime(); // Copy all variables to map, if not null - if (collectedVariables != null) + if(collectedVariables != null) { - collectedVariables.putAll(variables); + collectedVariables.putAll(variables); } boolean isActive = historicProcessInstance.getEndTime() == null; @@ -551,6 +557,7 @@ public class ActivitiTypeConverter public WorkflowInstance convert(HistoricProcessInstance historicProcessInstance) { - return convertToInstanceAndSetVariables(historicProcessInstance, null); + return convertToInstanceAndSetVariables(historicProcessInstance, null); } + } diff --git a/source/java/org/alfresco/repo/workflow/activiti/ActivitiWorkflowEngine.java b/source/java/org/alfresco/repo/workflow/activiti/ActivitiWorkflowEngine.java index 181e7d0310..65b1f68550 100644 --- a/source/java/org/alfresco/repo/workflow/activiti/ActivitiWorkflowEngine.java +++ b/source/java/org/alfresco/repo/workflow/activiti/ActivitiWorkflowEngine.java @@ -99,6 +99,7 @@ import org.alfresco.service.cmr.workflow.WorkflowTimer; import org.alfresco.service.namespace.NamespaceService; import org.alfresco.service.namespace.QName; import org.alfresco.util.GUID; +import org.alfresco.util.collections.Function; import org.apache.commons.io.IOUtils; import org.apache.commons.lang.StringUtils; import org.apache.xerces.parsers.DOMParser; @@ -200,7 +201,6 @@ public class ActivitiWorkflowEngine extends BPMEngine implements WorkflowEngine { super(); } - /** * {@inheritDoc} */ @@ -226,7 +226,7 @@ public class ActivitiWorkflowEngine extends BPMEngine implements WorkflowEngine try { ProcessInstance processInstance = runtimeService.createProcessInstanceQuery().processInstanceId(localId).singleResult(); - if (processInstance == null) + if(processInstance == null) { throw new WorkflowException(messageService.getMessage(ERR_CANCEL_UNEXISTING_WORKFLOW)); } @@ -237,8 +237,8 @@ public class ActivitiWorkflowEngine extends BPMEngine implements WorkflowEngine // Convert historic process instance HistoricProcessInstance deletedInstance = historyService.createHistoricProcessInstanceQuery() - .processInstanceId(processInstance.getId()) - .singleResult(); + .processInstanceId(processInstance.getId()) + .singleResult(); WorkflowInstance result = typeConverter.convert(deletedInstance); // Delete the historic process instance @@ -246,7 +246,7 @@ public class ActivitiWorkflowEngine extends BPMEngine implements WorkflowEngine return result; } - catch (ActivitiException ae) + catch(ActivitiException ae) { String msg = messageService.getMessage(ERR_CANCEL_WORKFLOW); throw new WorkflowException(msg, ae); @@ -263,7 +263,7 @@ public class ActivitiWorkflowEngine extends BPMEngine implements WorkflowEngine try { ProcessInstance processInstance = runtimeService.createProcessInstanceQuery().processInstanceId(localId).singleResult(); - if (processInstance == null) + if(processInstance == null) { throw new WorkflowException(messageService.getMessage(ERR_DELETE_UNEXISTING_WORKFLOW)); } @@ -273,8 +273,8 @@ public class ActivitiWorkflowEngine extends BPMEngine implements WorkflowEngine // Convert historic process instance HistoricProcessInstance deletedInstance = historyService.createHistoricProcessInstanceQuery() - .processInstanceId(processInstance.getId()) - .singleResult(); + .processInstanceId(processInstance.getId()) + .singleResult(); WorkflowInstance result = typeConverter.convert(deletedInstance); // Delete the historic process instance @@ -282,7 +282,7 @@ public class ActivitiWorkflowEngine extends BPMEngine implements WorkflowEngine return result; } - catch (ActivitiException ae) + catch(ActivitiException ae) { String msg = messageService.getMessage(ERR_DELETE_WORKFLOW); throw new WorkflowException(msg, ae); @@ -316,7 +316,7 @@ public class ActivitiWorkflowEngine extends BPMEngine implements WorkflowEngine // not exposed return typeConverter.convert(deployment); } - catch (ActivitiException ae) + catch(ActivitiException ae) { String msg = messageService.getMessage(ERR_DEPLOY_WORKFLOW); throw new WorkflowException(msg, ae); @@ -343,7 +343,7 @@ public class ActivitiWorkflowEngine extends BPMEngine implements WorkflowEngine { return getWorkflowInstances(workflowDefinitionId, true); } - catch (ActivitiException ae) + catch(ActivitiException ae) { String message = messageService.getMessage(ERR_GET_ACTIVE_WORKFLOW_INSTS, workflowDefinitionId); throw new WorkflowException(message, ae); @@ -376,19 +376,9 @@ public class ActivitiWorkflowEngine extends BPMEngine implements WorkflowEngine { try { - String name = workflowName; - if (tenantService.isEnabled()) - { - // When a definition is requested from a wrong domain, an - // AlfrescoRuntimeException will be thrown - name = tenantService.getName(createLocalId(workflowName)); - } - else - { - name = createLocalId(workflowName); - } + String key = factory.getProcessKey(workflowName); List definitions = repoService.createProcessDefinitionQuery() - .processDefinitionKey(name) + .processDefinitionKey(key) .list(); return typeConverter.convert(definitions); } @@ -445,20 +435,9 @@ public class ActivitiWorkflowEngine extends BPMEngine implements WorkflowEngine { try { - String name = workflowName; - if (tenantService.isEnabled()) - { - // When a definition is requested from a wrong domain, and - // ActivitiRuntimeException will be thrown - name = tenantService.getName(createLocalId(workflowName)); - } - else - { - name = createLocalId(workflowName); - } - + String key =factory.getProcessKey(workflowName); ProcessDefinition definition = repoService.createProcessDefinitionQuery() - .processDefinitionKey(name) + .processDefinitionKey(key) .latestVersion() .singleResult(); return typeConverter.convert(definition); @@ -483,13 +462,13 @@ public class ActivitiWorkflowEngine extends BPMEngine implements WorkflowEngine .processDefinitionId(processDefinitionId) .singleResult(); - if (processDefinition == null) + if(processDefinition == null) { throw new WorkflowException(messageService.getMessage(ERR_GET_DEF_UNEXISTING_IMAGE, workflowDefinitionId)); } String diagramResourceName = ((ReadOnlyProcessDefinition)processDefinition).getDiagramResourceName(); - if (diagramResourceName != null) + if(diagramResourceName != null) { ByteArrayOutputStream out = new ByteArrayOutputStream(); InputStream resourceInputStream = repoService.getResourceAsStream(processDefinitionId, diagramResourceName); @@ -500,12 +479,12 @@ public class ActivitiWorkflowEngine extends BPMEngine implements WorkflowEngine // No image was found for the process definition return null; } - catch (IOException ioe) + catch(IOException ioe) { String msg = messageService.getMessage(ERR_GET_DEF_IMAGE, workflowDefinitionId); throw new WorkflowException(msg, ioe); } - catch (ActivitiException ae) + catch(ActivitiException ae) { String msg = messageService.getMessage(ERR_GET_DEF_IMAGE, workflowDefinitionId); throw new WorkflowException(msg, ae); @@ -555,18 +534,14 @@ public class ActivitiWorkflowEngine extends BPMEngine implements WorkflowEngine ReadOnlyProcessDefinition processDefinition =((RepositoryServiceImpl)repoService).getDeployedProcessDefinition(processDefinitionId); String processName = processDefinition.getName(); - if (tenantService.isEnabled()) - { - // If domain doesn't match, an exception is thrown - tenantService.checkDomain(processName); - } + factory.checkDomain(processName); // Process start task definition PvmActivity startEvent = processDefinition.getInitial(); String startTaskName = null; StartFormData startFormData = formService.getStartFormData(processDefinition.getId()); - if (startFormData != null) + if(startFormData != null) { startTaskName = startFormData.getFormKey(); } @@ -576,7 +551,7 @@ public class ActivitiWorkflowEngine extends BPMEngine implements WorkflowEngine // Now, continue through process, finding all user-tasks Collection taskActivities = findUserTasks(startEvent); - for (PvmActivity act : taskActivities) + for(PvmActivity act : taskActivities) { String formKey = getFormKey(act); defs.add(typeConverter.getTaskDefinition(act, formKey, processDefinition.getId())); @@ -587,14 +562,14 @@ public class ActivitiWorkflowEngine extends BPMEngine implements WorkflowEngine private String getFormKey(PvmActivity act) { - if (act instanceof ActivityImpl) + if(act instanceof ActivityImpl) { ActivityImpl actImpl = (ActivityImpl) act; if (actImpl.getActivityBehavior() instanceof UserTaskActivityBehavior) { - UserTaskActivityBehavior uta = (UserTaskActivityBehavior) actImpl.getActivityBehavior(); + UserTaskActivityBehavior uta = (UserTaskActivityBehavior) actImpl.getActivityBehavior(); TaskFormHandler handler = uta.getTaskDefinition().getTaskFormHandler(); - if (handler != null && handler instanceof DefaultTaskFormHandler) + if(handler != null && handler instanceof DefaultTaskFormHandler) { // We cast to DefaultTaskFormHandler since we do not configure our own return ((DefaultTaskFormHandler)handler).getFormKey(); @@ -607,7 +582,7 @@ public class ActivitiWorkflowEngine extends BPMEngine implements WorkflowEngine private boolean isReceiveTask(PvmActivity act) { - if (act instanceof ActivityImpl) + if(act instanceof ActivityImpl) { ActivityImpl actImpl = (ActivityImpl) act; return (actImpl.getActivityBehavior() instanceof ReceiveTaskActivityBehavior); @@ -628,7 +603,7 @@ public class ActivitiWorkflowEngine extends BPMEngine implements WorkflowEngine private boolean isFirstActivity(PvmActivity activity, ReadOnlyProcessDefinition procDef) { - if (procDef.getInitial().getOutgoingTransitions().size() == 1) + if(procDef.getInitial().getOutgoingTransitions().size() == 1) { if (procDef.getInitial().getOutgoingTransitions().get(0).getDestination().equals(activity)) { @@ -641,19 +616,19 @@ public class ActivitiWorkflowEngine extends BPMEngine implements WorkflowEngine private void findUserTasks(PvmActivity currentActivity, Map userTasks) { // Only process activity if not already present to prevent endless loops - if (!userTasks.containsKey(currentActivity.getId())) + if(!userTasks.containsKey(currentActivity.getId())) { - if (isUserTask(currentActivity)) + if(isUserTask(currentActivity)) { userTasks.put(currentActivity.getId(), currentActivity); } // Process outgoing transitions - if (currentActivity.getOutgoingTransitions() != null) + if(currentActivity.getOutgoingTransitions() != null) { - for (PvmTransition transition : currentActivity.getOutgoingTransitions()) + for(PvmTransition transition : currentActivity.getOutgoingTransitions()) { - if (transition.getDestination() != null) + if(transition.getDestination() != null) { findUserTasks(transition.getDestination(), userTasks); } @@ -666,7 +641,7 @@ public class ActivitiWorkflowEngine extends BPMEngine implements WorkflowEngine { // TODO: Validate if this is the best way to find out an activity is a usertask String type = (String) currentActivity.getProperty(ActivitiConstants.NODE_TYPE); - if (type != null && type.equals(ActivitiConstants.USER_TASK_NODE_TYPE)) + if(type != null && type.equals(ActivitiConstants.USER_TASK_NODE_TYPE)) { return true; } @@ -683,14 +658,14 @@ public class ActivitiWorkflowEngine extends BPMEngine implements WorkflowEngine { // Extract the Activiti ID from the path String executionId = getExecutionIdFromPath(pathId); - if (executionId == null) + if(executionId == null) { throw new WorkflowException(messageService.getMessage(ERR_GET_WORKFLOW_TOKEN_INVALID, pathId)); } // Check if the execution exists Execution execution = runtimeService.createExecutionQuery().executionId(executionId).singleResult(); - if (execution == null) + if(execution == null) { throw new WorkflowException(messageService.getMessage(ERR_GET_WORKFLOW_TOKEN_NULL, pathId)); } @@ -700,20 +675,20 @@ public class ActivitiWorkflowEngine extends BPMEngine implements WorkflowEngine // Check if workflow's start task has been completed. If not, return the virtual task // Otherwise, just return the runtime activiti tasks Date startTaskEndDate = (Date) runtimeService.getVariable(execution.getProcessInstanceId(), - ActivitiConstants.PROP_START_TASK_END_DATE); + ActivitiConstants.PROP_START_TASK_END_DATE); boolean startTaskEnded = (startTaskEndDate != null); - if (startTaskEnded) + if(startTaskEnded) { - List tasks = taskService.createTaskQuery().executionId(executionId).list(); - for (Task task : tasks) - { - resultList.add(typeConverter.convert(task)); - } + List tasks = taskService.createTaskQuery().executionId(executionId).list(); + for(Task task : tasks) + { + resultList.add(typeConverter.convert(task)); + } } else { - resultList.add(typeConverter.getVirtualStartTask(executionId, true)); + resultList.add(typeConverter.getVirtualStartTask(executionId, true)); } return resultList; } @@ -723,13 +698,13 @@ public class ActivitiWorkflowEngine extends BPMEngine implements WorkflowEngine throw new WorkflowException(msg, ae); } } - + protected String getExecutionIdFromPath(String workflowPath) { - if (workflowPath != null) + if(workflowPath != null) { String[] parts = workflowPath.split(WORKFLOW_TOKEN_SEPERATOR); - if (parts.length != 2) + if(parts.length != 2) { throw new WorkflowException(messageService.getMessage(ERR_GET_WORKFLOW_TOKEN_INVALID, workflowPath)); } @@ -744,41 +719,41 @@ public class ActivitiWorkflowEngine extends BPMEngine implements WorkflowEngine @Override public List getTimers(String workflowId) { - try - { - List timers = new ArrayList(); + try + { + List timers = new ArrayList(); - String processInstanceId = createLocalId(workflowId); - List timerJobs = managementService.createJobQuery() - .processInstanceId(processInstanceId) - .timers() - .list(); + String processInstanceId = createLocalId(workflowId); + List timerJobs = managementService.createJobQuery() + .processInstanceId(processInstanceId) + .timers() + .list(); + + // Only fetch process-instance when timers are available, to prevent extra unneeded query + ProcessInstance jobsProcessInstance = null; + if(timerJobs.size() > 0) + { + // Reuse the process-instance, is used from WorkflowPath creation + jobsProcessInstance = runtimeService.createProcessInstanceQuery() + .processInstanceId(processInstanceId).singleResult(); + } + + // Convert the timerJobs to WorkflowTimers + for(Job job : timerJobs) + { + Execution jobExecution = runtimeService.createExecutionQuery() + .executionId(job.getExecutionId()).singleResult(); + + WorkflowPath path = typeConverter.convert(jobExecution, jobsProcessInstance); + WorkflowTask workflowTask = getTaskForTimer(job, jobsProcessInstance, jobExecution); + + WorkflowTimer workflowTimer = factory.createWorkflowTimer(job.getId(), job.getId(), + job.getExceptionMessage(), job.getDuedate(), path, workflowTask); + timers.add(workflowTimer); + } + + return timers; - // Only fetch process-instance when timers are available, to prevent extra unneeded query - ProcessInstance jobsProcessInstance = null; - if (timerJobs.size() > 0) - { - // Reuse the process-instance, is used from WorkflowPath creation - jobsProcessInstance = runtimeService.createProcessInstanceQuery() - .processInstanceId(processInstanceId).singleResult(); - } - - // Convert the timerJobs to WorkflowTimers - for (Job job : timerJobs) - { - Execution jobExecution = runtimeService.createExecutionQuery() - .executionId(job.getExecutionId()).singleResult(); - - WorkflowPath path = typeConverter.convert(jobExecution, jobsProcessInstance); - WorkflowTask workflowTask = getTaskForTimer(job, jobsProcessInstance, jobExecution); - - WorkflowTimer workflowTimer = factory.createWorkflowTimer(job.getId(), job.getId(), - job.getExceptionMessage(), job.getDuedate(), path, workflowTask); - timers.add(workflowTimer); - } - - return timers; - } catch (ActivitiException ae) { @@ -791,30 +766,30 @@ public class ActivitiWorkflowEngine extends BPMEngine implements WorkflowEngine { if (job instanceof TimerEntity) { - ReadOnlyProcessDefinition def = activitiUtil.getDeployedProcessDefinition(processInstance.getProcessDefinitionId()); - List activeActivityIds = runtimeService.getActiveActivityIds(jobExecution.getId()); - - if (activeActivityIds.size() == 1) - { - PvmActivity targetActivity = def.findActivity(activeActivityIds.get(0)); - if (targetActivity != null) - { - // Only get tasks of active activity is a user-task - String activityType = (String) targetActivity.getProperty(ActivitiConstants.NODE_TYPE); - if (ActivitiConstants.USER_TASK_NODE_TYPE.equals(activityType)) - { - Task task = taskService.createTaskQuery().executionId(job.getExecutionId()).singleResult(); - return typeConverter.convert(task); - } - } - } - } - return null; - } + ReadOnlyProcessDefinition def = activitiUtil.getDeployedProcessDefinition(processInstance.getProcessDefinitionId()); + List activeActivityIds = runtimeService.getActiveActivityIds(jobExecution.getId()); + + if(activeActivityIds.size() == 1) + { + PvmActivity targetActivity = def.findActivity(activeActivityIds.get(0)); + if(targetActivity != null) + { + // Only get tasks of active activity is a user-task + String activityType = (String) targetActivity.getProperty(ActivitiConstants.NODE_TYPE); + if(ActivitiConstants.USER_TASK_NODE_TYPE.equals(activityType)) + { + Task task = taskService.createTaskQuery().executionId(job.getExecutionId()).singleResult(); + return typeConverter.convert(task); + } + } + } + } + return null; + } - /** - * {@inheritDoc} - */ + /** + * {@inheritDoc} + */ @Override public WorkflowInstance getWorkflowById(String workflowId) { @@ -827,7 +802,7 @@ public class ActivitiWorkflowEngine extends BPMEngine implements WorkflowEngine .processInstanceId(processInstanceId) .singleResult(); - if (processIntance != null) + if(processIntance != null) { instance = typeConverter.convert(processIntance); } @@ -961,7 +936,7 @@ public class ActivitiWorkflowEngine extends BPMEngine implements WorkflowEngine Execution oldExecution = activitiUtil.getExecution(execId); runtimeService.signal(execId); Execution execution = activitiUtil.getExecution(execId); - if (execution !=null) + if(execution !=null) { return typeConverter.convert(execution); } @@ -1004,7 +979,7 @@ public class ActivitiWorkflowEngine extends BPMEngine implements WorkflowEngine // Start the process-instance ProcessInstance instance = runtimeService.startProcessInstanceById(processDefId, variables); - if (instance.isEnded()) + if(instance.isEnded()) { return typeConverter.buildCompletedPath(instance.getId(), instance.getId()); } @@ -1104,30 +1079,58 @@ public class ActivitiWorkflowEngine extends BPMEngine implements WorkflowEngine /** * Converts the given list of {@link ProcessDefinition}s to a list of {@link WorkflowDefinition}s - * that have a valid domain. If TenantService is disabled, all definitions are converted. - * @param processDefinitions + * that have a valid domain. + * @param definitions */ - private List getValidWorkflowDefinitions(List processDefinitions) + private List getValidWorkflowDefinitions(List definitions) { - List resultList = new ArrayList(); - for(ProcessDefinition processDefinition : processDefinitions) + return typeConverter.filterByDomainAndConvert(definitions, new Function() { - if (tenantService.isEnabled()) + public String apply(ProcessDefinition value) { - try - { - tenantService.checkDomain(processDefinition.getName()); - } - catch (RuntimeException re) - { - // Domain doesn't match, skip this process definition - continue; - } + return value.getKey(); } - resultList.add(typeConverter.convert(processDefinition)); - - } - return resultList; + }); + } + + /** + * Converts the given list of {@link Task}s to a list of {@link WorkflowTask}s + * that have a valid domain. + * @param tasks + */ + private List getValidWorkflowTasks(List tasks) + { + return typeConverter.filterByDomainAndConvert(tasks, new Function() + { + public String apply(Task task) + { + //TODO This probably isn't very performant! + String defId = task.getProcessDefinitionId(); + ProcessDefinition definition = repoService.createProcessDefinitionQuery().processDefinitionId(defId) + .singleResult(); + return definition.getKey(); + } + }); + } + + /** + * Converts the given list of {@link Task}s to a list of {@link WorkflowTask}s + * that have a valid domain. + * @param tasks + */ + private List getValidHistoricTasks(List tasks) + { + return typeConverter.filterByDomainAndConvert(tasks, new Function() + { + public String apply(HistoricTaskInstance task) + { + // TODO This probably isn't very performant! + String defId = task.getProcessDefinitionId(); + ProcessDefinition definition = repoService.createProcessDefinitionQuery().processDefinitionId(defId) + .singleResult(); + return definition.getKey(); + } + }); } /** @@ -1263,7 +1266,7 @@ public class ActivitiWorkflowEngine extends BPMEngine implements WorkflowEngine { String localTaskId = createLocalId(taskId); // Check if the task is a virtual start task - if (localTaskId.startsWith(ActivitiConstants.START_TASK_PREFIX)) + if(localTaskId.startsWith(ActivitiConstants.START_TASK_PREFIX)) { return endStartTask(taskId, localTaskId, transition); } @@ -1276,7 +1279,7 @@ public class ActivitiWorkflowEngine extends BPMEngine implements WorkflowEngine // Retrieve task Task task = taskService.createTaskQuery().taskId(localTaskId).singleResult(); - if (task == null) + if(task == null) { String msg = messageService.getMessage(ERR_END_UNEXISTING_TASK, taskId); throw new WorkflowException(msg); @@ -1295,11 +1298,11 @@ public class ActivitiWorkflowEngine extends BPMEngine implements WorkflowEngine boolean isDefaultTransition = transition == null || ActivitiConstants.DEFAULT_TRANSITION_NAME.equals(transition); - Map properties = propertyConverter.getTaskProperties(task, false); + Map properties = propertyConverter.getTaskProperties(task); QName outcomePropName = (QName) properties.get(WorkflowModel.PROP_OUTCOME_PROPERTY_NAME); - if (outcomePropName !=null) + if(outcomePropName !=null) { - if (isDefaultTransition == false) + if(isDefaultTransition == false) { outcomeValue = transition; Serializable transitionValue = propertyConverter.convertValueToPropertyType(task, transition, outcomePropName); @@ -1308,13 +1311,13 @@ public class ActivitiWorkflowEngine extends BPMEngine implements WorkflowEngine else { Serializable rawOutcome = properties.get(outcomePropName); - if (rawOutcome != null) + if(rawOutcome != null) { outcomeValue = DefaultTypeConverter.INSTANCE.convert(String.class, rawOutcome); } } } - else if (isDefaultTransition == false) + else if (isDefaultTransition==false) { // Only 'Next' is supported as transition. String taskId = createGlobalId(task.getId()); @@ -1342,7 +1345,7 @@ public class ActivitiWorkflowEngine extends BPMEngine implements WorkflowEngine ReadOnlyProcessDefinition procDef = activitiUtil.getDeployedProcessDefinition(processInstance.getProcessDefinitionId()); PvmActivity activity = procDef.findActivity(currentActivity); - if (isReceiveTask(activity) && isFirstActivity(activity, procDef)) + if(isReceiveTask(activity) && isFirstActivity(activity, procDef)) { // Signal the process to start flowing, beginning from the recieve task runtimeService.signal(processInstanceId); @@ -1363,6 +1366,7 @@ public class ActivitiWorkflowEngine extends BPMEngine implements WorkflowEngine // Return virtual start task for the execution, it's safe to use the processInstanceId return typeConverter.getVirtualStartTask(processInstanceId, false); } + } /** @@ -1373,7 +1377,7 @@ public class ActivitiWorkflowEngine extends BPMEngine implements WorkflowEngine { try { - if (state == WorkflowTaskState.IN_PROGRESS) + if(state == WorkflowTaskState.IN_PROGRESS) { List tasks = taskService.createTaskQuery() .taskAssignee(authority) @@ -1444,10 +1448,10 @@ public class ActivitiWorkflowEngine extends BPMEngine implements WorkflowEngine return Collections.emptyList(); } - catch (ActivitiException ae) + catch(ActivitiException ae) { String authorityString = null; - if (authorities != null) + if(authorities != null) { authorityString = StringUtils.join(authorities.iterator(), ", "); } @@ -1459,7 +1463,7 @@ public class ActivitiWorkflowEngine extends BPMEngine implements WorkflowEngine private void addTasksForCandidateGroup(String groupName, Map resultingTasks) { List tasks = taskService.createTaskQuery().taskCandidateGroup(groupName).list(); - for (Task task : tasks) + for(Task task : tasks) { resultingTasks.put(task.getId(), task); } @@ -1468,7 +1472,7 @@ public class ActivitiWorkflowEngine extends BPMEngine implements WorkflowEngine private void addTasksForCandidateUser(String userName, Map resultingTasks) { List tasks = taskService.createTaskQuery().taskCandidateUser(userName).list(); - for (Task task : tasks) + for(Task task : tasks) { resultingTasks.put(task.getId(), task); } @@ -1483,7 +1487,7 @@ public class ActivitiWorkflowEngine extends BPMEngine implements WorkflowEngine try { String localId = createLocalId(taskId); - if (localId.startsWith(ActivitiConstants.START_TASK_PREFIX)) + if(localId.startsWith(ActivitiConstants.START_TASK_PREFIX)) { String processInstanceId = localId.replace(ActivitiConstants.START_TASK_PREFIX ,""); return getVirtualStartTaskForProcessInstance(processInstanceId); @@ -1491,7 +1495,7 @@ public class ActivitiWorkflowEngine extends BPMEngine implements WorkflowEngine else { Task task = activitiUtil.getTaskInstance(localId); - if (task != null) + if(task != null) { return typeConverter.convert(task); } @@ -1514,13 +1518,13 @@ public class ActivitiWorkflowEngine extends BPMEngine implements WorkflowEngine { ArrayList result = new ArrayList(); WorkflowTaskState taskState = query.getTaskState(); - if (WorkflowTaskState.COMPLETED.equals(taskState) == false) + if(WorkflowTaskState.COMPLETED.equals(taskState) == false) { result.addAll(queryRuntimeTasks(query)); } // Depending on the state, history should be included/excluded as wel - if (WorkflowTaskState.IN_PROGRESS.equals(taskState) == false) + if(WorkflowTaskState.IN_PROGRESS.equals(taskState) == false) { result.addAll(queryHistoricTasks(query)); result.addAll(queryStartTasks(query)); @@ -1557,7 +1561,7 @@ public class ActivitiWorkflowEngine extends BPMEngine implements WorkflowEngine if (query.getWorkflowDefinitionName() != null) { - String processName = getWorkflowDefinitionNameMTSafe(query.getWorkflowDefinitionName()); + String processName = factory.getProcessKey(query.getWorkflowDefinitionName()); taskQuery.processDefinitionKey(processName); } @@ -1599,7 +1603,7 @@ public class ActivitiWorkflowEngine extends BPMEngine implements WorkflowEngine { results = taskQuery.list(); } - return typeConverter.convert(results); + return getValidWorkflowTasks(results); } return new ArrayList(); } @@ -1607,43 +1611,19 @@ public class ActivitiWorkflowEngine extends BPMEngine implements WorkflowEngine private void addProcessPropertiesToQuery( Map processCustomProps, TaskQuery taskQuery) { - for (Entry customProperty : processCustomProps.entrySet()) + for(Entry customProperty : processCustomProps.entrySet()) { String name =factory.mapQNameToName(customProperty.getKey()); taskQuery.processVariableValueEquals(name, customProperty.getValue()); } } - protected String getProcessNameMTSafe(QName processNameQName) + private String getProcessNameMTSafe(QName processNameQName) { - String processName = null; - if (tenantService.isEnabled()) - { - QName baseProcessName = tenantService.getBaseName(processNameQName, true); - processName = tenantService.getName(baseProcessName.toPrefixString(namespaceService)); - } - else - { - processName = processNameQName.toPrefixString(namespaceService); - } - return processName; + String key = processNameQName.toPrefixString(namespaceService); + return factory.getProcessKey(key); } - protected String getWorkflowDefinitionNameMTSafe(String name) - { - String processName = null; - if (tenantService.isEnabled()) - { - String baseName = tenantService.getBaseName(name, true); - processName = tenantService.getName(baseName); - } - else - { - processName = name; - } - return processName; - } - private void orderQuery(TaskQuery taskQuery, OrderBy[] orderBy) { for (WorkflowTaskQuery.OrderBy orderByPart : orderBy) @@ -1749,7 +1729,7 @@ public class ActivitiWorkflowEngine extends BPMEngine implements WorkflowEngine private void addTaskPropertiesToQuery(Map taskCustomProps, TaskQuery taskQuery) { - for (Entry customProperty : taskCustomProps.entrySet()) + for(Entry customProperty : taskCustomProps.entrySet()) { String name =factory.mapQNameToName(customProperty.getKey()); taskQuery.taskVariableValueEquals(name, customProperty.getValue()); @@ -1790,7 +1770,7 @@ public class ActivitiWorkflowEngine extends BPMEngine implements WorkflowEngine if (query.getWorkflowDefinitionName() != null) { - String processName = getWorkflowDefinitionNameMTSafe(query.getWorkflowDefinitionName()); + String processName = factory.getProcessKey(query.getWorkflowDefinitionName()); historicQuery.processDefinitionKey(processName); } @@ -1832,39 +1812,27 @@ public class ActivitiWorkflowEngine extends BPMEngine implements WorkflowEngine { results = historicQuery.list(); } - - List workflowTasks = new ArrayList(); - for (HistoricTaskInstance historicTask : results) - { - WorkflowTask wfTask = typeConverter.convert(historicTask); - if (wfTask != null) - { - // Converter returns null if the task belongs to - // deleted/cancelled WF - workflowTasks.add(wfTask); - } - } - return workflowTasks; + return getValidHistoricTasks(results); } private void addTaskPropertiesToQuery(Map taskCustomProps, HistoricTaskInstanceQuery taskQuery) { - for (Entry customProperty : taskCustomProps.entrySet()) - { - String name =factory.mapQNameToName(customProperty.getKey()); - taskQuery.taskVariableValueEquals(name, customProperty.getValue()); - } + for(Entry customProperty : taskCustomProps.entrySet()) + { + String name =factory.mapQNameToName(customProperty.getKey()); + taskQuery.taskVariableValueEquals(name, customProperty.getValue()); + } } private void addProcessPropertiesToQuery(Map processCustomProps, HistoricTaskInstanceQuery taskQuery) { - for (Entry customProperty : processCustomProps.entrySet()) - { - String name =factory.mapQNameToName(customProperty.getKey()); - taskQuery.processVariableValueEquals(name, customProperty.getValue()); - } + for(Entry customProperty : processCustomProps.entrySet()) + { + String name =factory.mapQNameToName(customProperty.getKey()); + taskQuery.processVariableValueEquals(name, customProperty.getValue()); + } } private List queryStartTasks(WorkflowTaskQuery query) @@ -1873,16 +1841,16 @@ public class ActivitiWorkflowEngine extends BPMEngine implements WorkflowEngine String processInstanceId = null; String taskId = query.getTaskId(); - if (taskId != null ) + if(taskId != null ) { String localTaskId = createLocalId(taskId); - if (localTaskId.startsWith(ActivitiConstants.START_TASK_PREFIX)) + if(localTaskId.startsWith(ActivitiConstants.START_TASK_PREFIX)) processInstanceId = localTaskId.substring(ActivitiConstants.START_TASK_PREFIX.length()); } else { String processId = query.getProcessId(); - if (processId != null) + if(processId != null) { // Start task for a specific process processInstanceId = createLocalId(processId); @@ -1890,17 +1858,17 @@ public class ActivitiWorkflowEngine extends BPMEngine implements WorkflowEngine } // Only return start-task when a process or task id is set - if (processInstanceId != null) + if(processInstanceId != null) { // Extract processInstanceId WorkflowTask workflowTask = getVirtualStartTaskForProcessInstance(processInstanceId); - if (workflowTask != null) + if(workflowTask != null) { - boolean startTaskMatches = isStartTaskMatching(workflowTask, query); - if (startTaskMatches) - { - startTasks.add(workflowTask); - } + boolean startTaskMatches = isStartTaskMatching(workflowTask, query); + if(startTaskMatches) + { + startTasks.add(workflowTask); + } } } return startTasks; @@ -1909,134 +1877,135 @@ public class ActivitiWorkflowEngine extends BPMEngine implements WorkflowEngine private boolean isStartTaskMatching(WorkflowTask workflowTask, WorkflowTaskQuery query) { - if (query.isActive() != null) + if(query.isActive() != null) + { + if(query.isActive() && !workflowTask.getPath().isActive()) + { + return false; + } + if(!query.isActive() && workflowTask.getPath().isActive()) + { + return false; + } + } + + if(query.getActorId() != null && !query.getActorId().equals(workflowTask.getProperties().get(ContentModel.PROP_OWNER))) + { + return false; + } + + if(query.getProcessCustomProps() != null) + { + // Get properties for process instance, based on path of start task, which is process-instance + Map props = getPathProperties(workflowTask.getPath().getId()); + if(!checkPropertiesPresent(query.getProcessCustomProps(), props)) + { + return false; + } + } + + if(query.getProcessId() != null) + { + if(!query.getProcessId().equals(workflowTask.getPath().getInstance().getId())) + { + return false; + } + } + + // Query by process name deprecated, but still implemented. + if(query.getProcessName() != null) + { + String processName = factory.mapQNameToName(query.getProcessName()); + if(!processName.equals(workflowTask.getPath().getInstance().getDefinition().getName())) + { + return false; + } + } + + if(query.getWorkflowDefinitionName() != null) { - if (query.isActive() && !workflowTask.getPath().isActive()) - { - return false; - } - if (!query.isActive() && workflowTask.getPath().isActive()) + if(!query.getWorkflowDefinitionName().equals(workflowTask.getPath().getInstance().getDefinition().getName())) { return false; } } - - if (query.getActorId() != null && !query.getActorId().equals(workflowTask.getProperties().get(ContentModel.PROP_OWNER))) - { - return false; - } - - if (query.getProcessCustomProps() != null) - { - // Get properties for process instance, based on path of start task, which is process-instance - Map props = getPathProperties(workflowTask.getPath().getId()); - if (!checkPropertiesPresent(query.getProcessCustomProps(), props)) - { - return false; - } - } - - if (query.getProcessId() != null) - { - if (!query.getProcessId().equals(workflowTask.getPath().getInstance().getId())) - { - return false; - } - } - - // Query by process name deprecated, but still implemented. - if (query.getProcessName() != null) - { - String processName = factory.mapQNameToName(query.getProcessName()); - if (!processName.equals(workflowTask.getPath().getInstance().getDefinition().getName())) - { - return false; - } - } - - if (query.getWorkflowDefinitionName() != null) - { - if (!query.getWorkflowDefinitionName().equals(workflowTask.getPath().getInstance().getDefinition().getName())) - { - return false; - } - } - - if (query.getTaskCustomProps() != null) - { - if (!checkPropertiesPresent(query.getTaskCustomProps(), workflowTask.getProperties())) - { - return false; - } - } - - if (query.getTaskId() != null) - { - if (!query.getTaskId().equals(workflowTask.getId())) - { - return false; - } - } - - if (query.getTaskName() != null) - { - if (!query.getTaskName().equals(workflowTask.getDefinition().getMetadata().getName())) - { - return false; - } - } - - if (query.getTaskState() != null) - { - if (!query.getTaskState().equals(workflowTask.getState())) - { - return false; - } - } - - // If we fall through, start task matches the query - return true; + + if(query.getTaskCustomProps() != null) + { + if(!checkPropertiesPresent(query.getTaskCustomProps(), workflowTask.getProperties())) + { + return false; + } + } + + if(query.getTaskId() != null) + { + if(!query.getTaskId().equals(workflowTask.getId())) + { + return false; + } + } + + if(query.getTaskName() != null) + { + if(!query.getTaskName().equals(workflowTask.getDefinition().getMetadata().getName())) + { + return false; + } + } + + if(query.getTaskState() != null) + { + if(!query.getTaskState().equals(workflowTask.getState())) + { + return false; + } + } + + // If we fall through, start task matches the query + return true; } private boolean checkPropertiesPresent(Map expectedProperties, Map props) { - for(Map.Entry entry : expectedProperties.entrySet()) - { - if (props.containsKey(entry.getKey())) - { - Object requiredValue = entry.getValue(); - Object actualValue = props.get(entry.getKey()); - - if (requiredValue != null) - { - if (!requiredValue.equals(actualValue)) - { - return false; - } - break; - } - else - { - if (actualValue != null) - { - return false; - } - break; - } - } - if (entry.getValue() != null) - { - // If variable is not found and required value is non null, start-task doesn't match - return false; - } - } - - return true; + for(Map.Entry entry : expectedProperties.entrySet()) + { + if(props.containsKey(entry.getKey())) + { + Object requiredValue = entry.getValue(); + Object actualValue = props.get(entry.getKey()); + + if(requiredValue != null) + { + if(!requiredValue.equals(actualValue)) + { + return false; + } + break; + } + else + { + if(actualValue != null) + { + return false; + } + break; + } + } + if(entry.getValue() != null) + { + // If variable is not found and required value is non null, start-task doesn't match + return false; + } + } + + return true; } - /** - * {@inheritDoc} - */ + + /** + * {@inheritDoc} + */ @Override public WorkflowTask getStartTask(String workflowInstanceId) { @@ -2051,11 +2020,11 @@ public class ActivitiWorkflowEngine extends BPMEngine implements WorkflowEngine .processInstanceId(processInstanceId) .singleResult(); - if (runningInstance != null) + if(runningInstance != null) { // Check the process instance variable to see if start-task has been completed Date startTaskEndDate = (Date) runtimeService.getVariable(runningInstance.getProcessInstanceId(), - ActivitiConstants.PROP_START_TASK_END_DATE); + ActivitiConstants.PROP_START_TASK_END_DATE); boolean startTaskEnded = (startTaskEndDate != null); return typeConverter.getVirtualStartTask(runningInstance.getId(), !startTaskEnded); } @@ -2096,7 +2065,7 @@ public class ActivitiWorkflowEngine extends BPMEngine implements WorkflowEngine { try { - if (taskId.startsWith(ActivitiConstants.START_TASK_PREFIX)) + if(taskId.startsWith(ActivitiConstants.START_TASK_PREFIX)) { // Known limitation, start-tasks cannot be updated String msg = messageService.getMessage(ERR_UPDATE_START_TASK, taskId); @@ -2104,7 +2073,7 @@ public class ActivitiWorkflowEngine extends BPMEngine implements WorkflowEngine } Task task = taskService.createTaskQuery().taskId(createLocalId(taskId)).singleResult(); - if (task != null) + if(task != null) { Task updatedTask = propertyConverter.updateTask(task, properties, add, remove); return typeConverter.convert(updatedTask); @@ -2115,7 +2084,7 @@ public class ActivitiWorkflowEngine extends BPMEngine implements WorkflowEngine throw new WorkflowException(msg); } } - catch (ActivitiException ae) + catch(ActivitiException ae) { String msg = messageService.getMessage(ERR_UPDATE_TASK, taskId); throw new WorkflowException(msg, ae); @@ -2126,7 +2095,7 @@ public class ActivitiWorkflowEngine extends BPMEngine implements WorkflowEngine { String processDefId = createLocalId(workflowDefinitionId); LinkedList results = new LinkedList(); - if (Boolean.FALSE.equals(isActive)==false) + if(Boolean.FALSE.equals(isActive)==false) { List activeInstances = runtimeService.createProcessInstanceQuery() .processDefinitionId(processDefId) @@ -2134,7 +2103,7 @@ public class ActivitiWorkflowEngine extends BPMEngine implements WorkflowEngine List activeResults = typeConverter.convert(activeInstances); results.addAll(activeResults); } - if (Boolean.TRUE.equals(isActive)==false) + if(Boolean.TRUE.equals(isActive)==false) { List completedInstances = historyService.createHistoricProcessInstanceQuery() .processDefinitionId(processDefId) diff --git a/source/java/org/alfresco/repo/workflow/activiti/AddTaskListenerParseListener.java b/source/java/org/alfresco/repo/workflow/activiti/AlfrescoBpmnParseListener.java similarity index 62% rename from source/java/org/alfresco/repo/workflow/activiti/AddTaskListenerParseListener.java rename to source/java/org/alfresco/repo/workflow/activiti/AlfrescoBpmnParseListener.java index 34da576757..d58588c3a2 100644 --- a/source/java/org/alfresco/repo/workflow/activiti/AddTaskListenerParseListener.java +++ b/source/java/org/alfresco/repo/workflow/activiti/AlfrescoBpmnParseListener.java @@ -29,129 +29,132 @@ import org.activiti.engine.impl.pvm.process.ScopeImpl; import org.activiti.engine.impl.pvm.process.TransitionImpl; import org.activiti.engine.impl.util.xml.Element; import org.activiti.engine.impl.variable.VariableDeclaration; +import org.alfresco.repo.tenant.TenantService; /** - * A {@link BpmnParseListener} that adds a start- and endTaskListener to - * all parsed userTasks. + * A {@link BpmnParseListener} that adds a start- and endTaskListener to all + * parsed userTasks. * * This is used to wire in custom logic when task is created and completed. - * + * * @author Frederik Heremans + * @author Nick Smith * @since 3.4.e */ -public class AddTaskListenerParseListener implements BpmnParseListener +public class AlfrescoBpmnParseListener implements BpmnParseListener { - private TaskListener completeTaskListener; - private TaskListener createTaskListener; + private TaskListener completeTaskListener; + private TaskListener createTaskListener; private ExecutionListener processCreateListener; - + private TenantService tenantService; + @Override public void parseUserTask(Element userTaskElement, ScopeImpl scope, ActivityImpl activity) { - ActivityBehavior activitybehaviour = activity.getActivityBehavior(); - if (activitybehaviour instanceof UserTaskActivityBehavior) - { - UserTaskActivityBehavior userTaskActivity = (UserTaskActivityBehavior) activitybehaviour; - if (createTaskListener != null) - { - userTaskActivity.getTaskDefinition().addTaskListener(TaskListener.EVENTNAME_CREATE, createTaskListener); - } - if (completeTaskListener != null) - { - userTaskActivity.getTaskDefinition().addTaskListener(TaskListener.EVENTNAME_COMPLETE, completeTaskListener); - } - } + ActivityBehavior activitybehaviour = activity.getActivityBehavior(); + if (activitybehaviour instanceof UserTaskActivityBehavior) + { + UserTaskActivityBehavior userTaskActivity = (UserTaskActivityBehavior) activitybehaviour; + if (createTaskListener != null) + { + userTaskActivity.getTaskDefinition().addTaskListener(TaskListener.EVENTNAME_CREATE, createTaskListener); + } + if (completeTaskListener != null) + { + userTaskActivity.getTaskDefinition().addTaskListener(TaskListener.EVENTNAME_COMPLETE, + completeTaskListener); + } + } } - + @Override public void parseProcess(Element processElement, ProcessDefinitionEntity processDefinition) { processDefinition.addExecutionListener(ExecutionListener.EVENTNAME_START, processCreateListener); + if (tenantService.isEnabled()) + { + String key = tenantService.getName(processDefinition.getKey()); + processDefinition.setKey(key); + } } @Override - public void parseStartEvent(Element startEventElement, ScopeImpl scope, - ActivityImpl startEventActivity) + public void parseStartEvent(Element startEventElement, ScopeImpl scope, ActivityImpl startEventActivity) { - // Nothing to do here + // Nothing to do here } @Override - public void parseExclusiveGateway(Element exclusiveGwElement, ScopeImpl scope, - ActivityImpl activity) + public void parseExclusiveGateway(Element exclusiveGwElement, ScopeImpl scope, ActivityImpl activity) { - // Nothing to do here + // Nothing to do here } @Override - public void parseParallelGateway(Element parallelGwElement, ScopeImpl scope, - ActivityImpl activity) + public void parseParallelGateway(Element parallelGwElement, ScopeImpl scope, ActivityImpl activity) { - // Nothing to do here + // Nothing to do here } @Override public void parseScriptTask(Element scriptTaskElement, ScopeImpl scope, ActivityImpl activity) { - // Nothing to do here + // Nothing to do here } @Override public void parseServiceTask(Element serviceTaskElement, ScopeImpl scope, ActivityImpl activity) { - // Nothing to do here + // Nothing to do here } @Override public void parseTask(Element taskElement, ScopeImpl scope, ActivityImpl activity) { - // Nothing to do here + // Nothing to do here } @Override public void parseManualTask(Element manualTaskElement, ScopeImpl scope, ActivityImpl activity) { - // Nothing to do here + // Nothing to do here } @Override public void parseEndEvent(Element endEventElement, ScopeImpl scope, ActivityImpl activity) { - // Nothing to do here + // Nothing to do here } @Override - public void parseBoundaryTimerEventDefinition(Element timerEventDefinition, - boolean interrupting, ActivityImpl timerActivity) + public void parseBoundaryTimerEventDefinition(Element timerEventDefinition, boolean interrupting, + ActivityImpl timerActivity) { - // Nothing to do here + // Nothing to do here } @Override public void parseSubProcess(Element subProcessElement, ScopeImpl scope, ActivityImpl activity) { - // Nothing to do here + // Nothing to do here } @Override - public void parseCallActivity(Element callActivityElement, ScopeImpl scope, - ActivityImpl activity) + public void parseCallActivity(Element callActivityElement, ScopeImpl scope, ActivityImpl activity) { - // Nothing to do here + // Nothing to do here } @Override - public void parseProperty(Element propertyElement, VariableDeclaration variableDeclaration, - ActivityImpl activity) + public void parseProperty(Element propertyElement, VariableDeclaration variableDeclaration, ActivityImpl activity) { - // Nothing to do here + // Nothing to do here } @Override - public void parseSequenceFlow(Element sequenceFlowElement, ScopeImpl scopeElement, - TransitionImpl transition) + public void parseSequenceFlow(Element sequenceFlowElement, ScopeImpl scopeElement, TransitionImpl transition) { - // Nothing to do here + // Nothing to do here } @Override @@ -159,37 +162,33 @@ public class AddTaskListenerParseListener implements BpmnParseListener { // Nothing to do here } - + @Override - public void parseBusinessRuleTask(Element businessRuleTaskElement, ScopeImpl scope, - ActivityImpl activity) + public void parseBusinessRuleTask(Element businessRuleTaskElement, ScopeImpl scope, ActivityImpl activity) { // Nothing to do here } - + @Override - public void parseBoundaryErrorEventDefinition(Element errorEventDefinition, - boolean interrupting, ActivityImpl activity, - ActivityImpl nestedErrorEventActivity) + public void parseBoundaryErrorEventDefinition(Element errorEventDefinition, boolean interrupting, + ActivityImpl activity, ActivityImpl nestedErrorEventActivity) { // Nothing to do here } - + @Override - public void parseIntermediateTimerEventDefinition( - Element timerEventDefinition, ActivityImpl timerActivity) + public void parseIntermediateTimerEventDefinition(Element timerEventDefinition, ActivityImpl timerActivity) { // Nothing to do here } - + @Override - public void parseMultiInstanceLoopCharacteristics(Element activityElement, - Element multiInstanceLoopCharacteristicsElement, - ActivityImpl activity) + public void parseMultiInstanceLoopCharacteristics(Element activityElement, + Element multiInstanceLoopCharacteristicsElement, ActivityImpl activity) { // Nothing to do here } - + public void setCompleteTaskListener(TaskListener completeTaskListener) { this.completeTaskListener = completeTaskListener; @@ -199,9 +198,18 @@ public class AddTaskListenerParseListener implements BpmnParseListener { this.createTaskListener = createTaskListener; } - + public void setProcessCreateListener(ExecutionListener processCreateListener) { this.processCreateListener = processCreateListener; } + + /** + * @param tenantService + * the tenantService to set + */ + public void setTenantService(TenantService tenantService) + { + this.tenantService = tenantService; + } } diff --git a/source/java/org/alfresco/repo/workflow/activiti/listener/ProcessStartExecutionListener.java b/source/java/org/alfresco/repo/workflow/activiti/listener/ProcessStartExecutionListener.java index 6edbd78c9f..33befd8370 100644 --- a/source/java/org/alfresco/repo/workflow/activiti/listener/ProcessStartExecutionListener.java +++ b/source/java/org/alfresco/repo/workflow/activiti/listener/ProcessStartExecutionListener.java @@ -34,10 +34,11 @@ import org.alfresco.repo.workflow.activiti.ActivitiConstants; */ public class ProcessStartExecutionListener implements ExecutionListener { + public void notify(DelegateExecution execution) throws Exception { // Add the workflow ID - execution.setVariable(WorkflowConstants.PROP_WORKFLOW_INSTANCE_ID, BPMEngineRegistry - .createGlobalId(ActivitiConstants.ENGINE_ID, execution.getId())); + String instanceId = BPMEngineRegistry.createGlobalId(ActivitiConstants.ENGINE_ID, execution.getId()); + execution.setVariable(WorkflowConstants.PROP_WORKFLOW_INSTANCE_ID, instanceId); } } diff --git a/source/java/org/alfresco/repo/workflow/activiti/properties/ActivitiPropertyConverter.java b/source/java/org/alfresco/repo/workflow/activiti/properties/ActivitiPropertyConverter.java index 176db7eb91..fe8e6f3a94 100644 --- a/source/java/org/alfresco/repo/workflow/activiti/properties/ActivitiPropertyConverter.java +++ b/source/java/org/alfresco/repo/workflow/activiti/properties/ActivitiPropertyConverter.java @@ -103,7 +103,7 @@ public class ActivitiPropertyConverter this.typeManager = new ActivitiTaskTypeManager(factory, activitiUtil.getFormService()); } - public Map getTaskProperties(Task task, boolean localOnly) + public Map getTaskProperties(Task task) { // retrieve type definition for task TypeDefinition taskDef = typeManager.getFullTaskDefinition(task); @@ -112,42 +112,21 @@ public class ActivitiPropertyConverter Map properties = new HashMap(); TaskService taskService = activitiUtil.getTaskService(); - // Get the local task variables - Map localVariables = taskService.getVariablesLocal(task.getId()); - Map variables = null; - - if (!localOnly) - { - variables = new HashMap(); - variables.putAll(localVariables); - - // Execution-variables should also be added, if no value is present locally - Map executionVariables = activitiUtil.getExecutionVariables(task.getExecutionId()); - - for (Entry entry : executionVariables.entrySet()) - { - if (!localVariables.containsKey(entry.getKey())) - { - variables.put(entry.getKey(), entry.getValue()); - } - } - } - else - { - // Only local variables should be used. - variables = localVariables; - } + // Get all task variables including execution vars. + Map variables = taskService.getVariables(task.getId()); // Map the arbitrary properties + Map localVariables = taskService.getVariablesLocal(task.getId()); mapArbitraryProperties(variables, properties, localVariables, taskProperties, taskAssociations); // Map activiti task instance fields to properties properties.put(WorkflowModel.PROP_TASK_ID, task.getId()); properties.put(WorkflowModel.PROP_DESCRIPTION, task.getDescription()); + // Since the task is never started explicitally, we use the create time properties.put(WorkflowModel.PROP_START_DATE, task.getCreateTime()); - - // Due date is present on the process instance + + // Due date is present on the task properties.put(WorkflowModel.PROP_DUE_DATE, task.getDueDate()); // Since this is a runtime-task, it's not completed yet @@ -158,7 +137,7 @@ public class ActivitiPropertyConverter // Be sure to fetch the outcome String outcomeVarName = factory.mapQNameToName(WorkflowModel.PROP_OUTCOME); - if (variables.get(outcomeVarName) != null) + if(variables.get(outcomeVarName) != null) { properties.put(WorkflowModel.PROP_OUTCOME, (Serializable) variables.get(outcomeVarName)); } @@ -185,14 +164,14 @@ public class ActivitiPropertyConverter public List getPooledActorsReference(Collection links) { List pooledActorRefs = new ArrayList(); - if (links != null) + if(links != null) { - for (IdentityLink link : links) + for(IdentityLink link : links) { - if (IdentityLinkType.CANDIDATE.equals(link.getType())) + if(IdentityLinkType.CANDIDATE.equals(link.getType())) { String id = link.getGroupId(); - if (id == null) + if(id == null) { id = link.getUserId(); } @@ -227,7 +206,7 @@ public class ActivitiPropertyConverter Map localVariables = task.getVariablesLocal(); Map variables = null; - if (localOnly == false) + if(localOnly==false) { variables = new HashMap(); variables.putAll(localVariables); @@ -235,7 +214,7 @@ public class ActivitiPropertyConverter // Execution-variables should also be added, if no value is present locally Map executionVariables = task.getExecution().getVariables(); - for (Entry entry : executionVariables.entrySet()) + for(Entry entry : executionVariables.entrySet()) { String key = entry.getKey(); if(localVariables.containsKey(key)==false) @@ -307,7 +286,7 @@ public class ActivitiPropertyConverter // Be sure to fetch the outcome String outcomeVarName = factory.mapQNameToName(WorkflowModel.PROP_OUTCOME); - if (variables.get(outcomeVarName) != null) + if(variables.get(outcomeVarName) != null) { properties.put(WorkflowModel.PROP_OUTCOME, (Serializable) variables.get(outcomeVarName)); } @@ -315,16 +294,15 @@ public class ActivitiPropertyConverter // History of pooled actors is stored in task variable List pooledActors = new ArrayList(); List pooledActorRefIds = (List) variables.get(ActivitiConstants.PROP_POOLED_ACTORS_HISTORY); - if (pooledActorRefIds != null) + if(pooledActorRefIds != null) { - for (String nodeId : pooledActorRefIds) + for(String nodeId : pooledActorRefIds) { pooledActors.add(new NodeRef(nodeId)); } } - // Add pooled actors. When no actors are found, set empty list - properties.put(WorkflowModel.ASSOC_POOLED_ACTORS, (Serializable) pooledActors); + properties.put(WorkflowModel.ASSOC_POOLED_ACTORS, (Serializable) pooledActors); return filterTaskProperties(properties); } @@ -448,7 +426,7 @@ public class ActivitiPropertyConverter String wfDueDateKey = factory.mapQNameToName(WorkflowModel.PROP_WORKFLOW_DUE_DATE); String dueDateKey = factory.mapQNameToName(WorkflowModel.PROP_DUE_DATE); Serializable dueDate = (Serializable) variables.get(wfDueDateKey); - if (dueDate == null) + if(dueDate == null) { dueDate = (Serializable) variables.get(dueDateKey); } @@ -460,7 +438,7 @@ public class ActivitiPropertyConverter // Use workflow priority at the time of starting the process String priorityKey = factory.mapQNameToName(WorkflowModel.PROP_PRIORITY); Serializable priority = (Serializable) variables.get(priorityKey); - if (priority == null) + if(priority == null) { String wfPriorityKey = factory.mapQNameToName(WorkflowModel.PROP_WORKFLOW_PRIORITY); priority = (Serializable) variables.get(wfPriorityKey); @@ -471,12 +449,12 @@ public class ActivitiPropertyConverter // Use initiator username as owner ActivitiScriptNode ownerNode = (ActivitiScriptNode) variables.get(WorkflowConstants.PROP_INITIATOR); - if (ownerNode != null) + if(ownerNode != null && ownerNode.exists()) { properties.put(ContentModel.PROP_OWNER, (Serializable) ownerNode.getProperties().get("userName")); } - if (completed) + if(completed) { // Override default 'Not Yet Started' when start-task is completed properties.put(WorkflowModel.PROP_STATUS, WorkflowConstants.TASK_STATUS_COMPLETED); @@ -557,8 +535,11 @@ public class ActivitiPropertyConverter return convertHistoricDetails(historicDetails); } - private void mapArbitraryProperties(Map variables, Map properties, - Map localVariables, Map taskProperties, Map taskAssociations) + private void mapArbitraryProperties(Map variables, + Map properties, + Map localVariables, + Map taskProperties, + Map taskAssociations) { // Map arbitrary task variables for (Entry entry : variables.entrySet()) @@ -568,7 +549,9 @@ public class ActivitiPropertyConverter // Add variable, only if part of task definition or locally defined // on task - if (taskProperties.containsKey(qname) || taskAssociations.containsKey(qname) || localVariables.containsKey(key)) + if (taskProperties.containsKey(qname) + || taskAssociations.containsKey(qname) + || localVariables.containsKey(key)) { Serializable value = convertPropertyValue(entry.getValue()); properties.put(qname, value); @@ -589,7 +572,7 @@ public class ActivitiPropertyConverter { return null; } - if (nodeConverter.isSupported(value)) + if(nodeConverter.isSupported(value)) { return nodeConverter.convert(value); } @@ -611,7 +594,7 @@ public class ActivitiPropertyConverter { TypeDefinition taskDef = typeManager.getFullTaskDefinition(task); PropertyDefinition propDef = taskDef.getProperties().get(propertyName); - if (propDef != null) + if(propDef != null) { return (Serializable) DefaultTypeConverter.INSTANCE.convert(propDef.getDataType(), value); } @@ -622,7 +605,7 @@ public class ActivitiPropertyConverter private Map getNewTaskProperties(Task task, Map properties, Map> add, Map> remove) { - // create properties to set on task instance + // create properties to set on task instance Map newProperties = properties; if (add != null || remove != null) @@ -632,7 +615,7 @@ public class ActivitiPropertyConverter newProperties = new HashMap(10); } - Map existingProperties = getTaskProperties(task, false); + Map existingProperties = getTaskProperties(task); if (add != null) { @@ -694,12 +677,11 @@ public class ActivitiPropertyConverter public void setTaskProperties(DelegateTask task, Map properties) { - if (properties==null || properties.isEmpty()) + if(properties==null || properties.isEmpty()) return; - TypeDefinition type = typeManager.getFullTaskDefinition(task); Map variablesToSet = handlerRegistry.handleVariablesToSet(properties, type, task, DelegateTask.class); - if (variablesToSet.size() > 0) + if(variablesToSet.size() > 0) { task.setVariablesLocal(variablesToSet); } @@ -711,7 +693,7 @@ public class ActivitiPropertyConverter */ public void setTaskProperties(Task task, Map properties) { - if (properties == null || properties.isEmpty()) + if(properties==null || properties.isEmpty()) return; TypeDefinition type = typeManager.getFullTaskDefinition(task); @@ -745,7 +727,7 @@ public class ActivitiPropertyConverter String currentAssignee = task.getAssignee(); // Only set the assignee if the value has changes to prevent // triggering assignementhandlers when not needed - if (ObjectUtils.equals(currentAssignee, assignee) == false) + if (ObjectUtils.equals(currentAssignee, assignee)==false) { activitiUtil.getTaskService().setAssignee(task.getId(), assignee); } @@ -767,7 +749,7 @@ public class ActivitiPropertyConverter private Map filterTaskProperties( Map properties) { - if (properties != null) + if(properties != null) { properties.remove(QName.createQName(null, ActivitiConstants.PROP_POOLED_ACTORS_HISTORY)); properties.remove(QName.createQName(null, ActivitiConstants.PROP_TASK_FORM_KEY)); @@ -793,11 +775,11 @@ public class ActivitiPropertyConverter } }); Map variables = new HashMap(); - for (HistoricDetail detail : details) + for(HistoricDetail detail : details) { HistoricVariableUpdate varUpdate = (HistoricVariableUpdate) detail; // First value for a single key is used - if (!variables.containsKey(varUpdate.getVariableName())) + if(!variables.containsKey(varUpdate.getVariableName())) { variables.put(varUpdate.getVariableName(), varUpdate.getValue()); } @@ -835,7 +817,7 @@ public class ActivitiPropertyConverter // Special case for task description default value // Use the shared description set in the workflowinstance String description = (String) defaultProperties.get(WorkflowModel.PROP_DESCRIPTION); - if (description == null) + if(description == null) { String wfDescription = (String) defaultProperties.get(WorkflowModel.PROP_WORKFLOW_DESCRIPTION); String procDefKey = procDef.getKey(); @@ -912,7 +894,7 @@ public class ActivitiPropertyConverter private boolean isMandatory(ClassAttributeDefinition definition) { - if (definition instanceof PropertyDefinition) + if(definition instanceof PropertyDefinition) { PropertyDefinition propDef = (PropertyDefinition) definition; return propDef.isMandatory(); @@ -927,7 +909,7 @@ public class ActivitiPropertyConverter */ private boolean isEmptyString(Object value) { - if (value instanceof String) + if(value instanceof String) { String str = (String)value; return str.isEmpty();