This commit is contained in:
N Smith
2011-09-06 15:05:59 +00:00
parent ee3c402701
commit 6fccccb72a
12 changed files with 611 additions and 585 deletions

View File

@@ -30,11 +30,11 @@
<!-- BPMN Parse listener which adds tasklisteners to all userTasks -->
<bean id="activitiParseListener"
class="org.alfresco.repo.workflow.activiti.AddTaskListenerParseListener">
class="org.alfresco.repo.workflow.activiti.AlfrescoBpmnParseListener">
<property name="createTaskListener" ref="activitiCreateTaskListener" />
<property name="completeTaskListener" ref="activitiCompleteTaskListener" />
<property name="processCreateListener" ref="activitiProcessCreateListener" />
<property name="tenantService" ref="tenantService" />
</bean>
<!-- -->

View File

@@ -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<Invitation> res3 = invitationService.searchInvitation(crit3);
assertEquals("user one does not have 2 nominated", 2, res3.size());
}
/**

View File

@@ -581,7 +581,7 @@ public class InvitationServiceImpl implements InvitationService, NodeServicePoli
if (invitation instanceof NominatedInvitation)
{
NominatedInvitation modInvite = (NominatedInvitation) invitation;
if(inviter.equals(modInvite.getInviterUserName()))
if(false == inviter.equals(modInvite.getInviterUserName()))
{
return false;
}
@@ -1188,7 +1188,6 @@ public class InvitationServiceImpl implements InvitationService, NodeServicePoli
{
return WorkflowModelNominatedInvitation.WORKFLOW_DEFINITION_NAME;
}
throw new IllegalStateException("None of the Workflow engines supported by teh InvitationService are currently enabled!");
}
@@ -1202,7 +1201,6 @@ public class InvitationServiceImpl implements InvitationService, NodeServicePoli
{
return WorkflowModelModeratedInvitation.WORKFLOW_DEFINITION_NAME;
}
throw new IllegalStateException("None of the Workflow engines supported by teh InvitationService are currently enabled!");
}

View File

@@ -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

View File

@@ -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)

View File

@@ -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

View File

@@ -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
@@ -223,7 +228,7 @@ public class WorkflowObjectFactory
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))
@@ -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 <T extends Object> List<T> filterByDomain(List<T> values, final Function<T, String> processKeyGetter)
{
final boolean enabled = tenantService.isEnabled();
final String currentDomain = tenantService.getCurrentUserDomain();
return CollectionUtils.filter(values, new Filter<T>()
{
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.

View File

@@ -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
@@ -92,6 +93,12 @@ public class ActivitiTypeConverter
this.activitiUtil = new ActivitiUtil(processEngine);
}
public <F, T> List<T> filterByDomainAndConvert(List<F> values, Function<F, String> processKeyGetter)
{
List<F> filtered = factory.filterByDomain(values, processKeyGetter);
return convert(filtered);
}
/**
* Convert a {@link Deployment} into a {@link WorkflowDeployment}.
* @param deployment
@@ -322,7 +329,6 @@ public class ActivitiTypeConverter
{
if(task == null)
return null;
String id = task.getId();
String defaultTitle = task.getName();
String defaultDescription = task.getDescription();
@@ -345,7 +351,7 @@ public class ActivitiTypeConverter
WorkflowTaskDefinition taskDef = factory.createTaskDefinition(taskDefId, node, taskDefId, false);
// All task-properties should be fetched, not only local
Map<QName, Serializable> properties = propertyConverter.getTaskProperties(task, false);
Map<QName, Serializable> properties = propertyConverter.getTaskProperties(task);
return factory.createTask(id,
taskDef, taskDef.getId(), defaultTitle, defaultDescription, state, path, properties);
@@ -553,4 +559,5 @@ public class ActivitiTypeConverter
{
return convertToInstanceAndSetVariables(historicProcessInstance, null);
}
}

View File

@@ -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}
*/
@@ -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<ProcessDefinition> 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);
@@ -555,11 +534,7 @@ 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();
@@ -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<WorkflowDefinition> getValidWorkflowDefinitions(List<ProcessDefinition> processDefinitions)
private List<WorkflowDefinition> getValidWorkflowDefinitions(List<ProcessDefinition> definitions)
{
List<WorkflowDefinition> resultList = new ArrayList<WorkflowDefinition>();
for(ProcessDefinition processDefinition : processDefinitions)
return typeConverter.filterByDomainAndConvert(definitions, new Function<ProcessDefinition, String>()
{
if (tenantService.isEnabled())
public String apply(ProcessDefinition value)
{
try
{
tenantService.checkDomain(processDefinition.getName());
return value.getKey();
}
catch (RuntimeException re)
{
// Domain doesn't match, skip this process definition
continue;
});
}
}
resultList.add(typeConverter.convert(processDefinition));
/**
* Converts the given list of {@link Task}s to a list of {@link WorkflowTask}s
* that have a valid domain.
* @param tasks
*/
private List<WorkflowTask> getValidWorkflowTasks(List<Task> tasks)
{
return typeConverter.filterByDomainAndConvert(tasks, new Function<Task, String>()
{
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();
}
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<WorkflowTask> getValidHistoricTasks(List<HistoricTaskInstance> tasks)
{
return typeConverter.filterByDomainAndConvert(tasks, new Function<HistoricTaskInstance, String>()
{
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();
}
});
}
/**
@@ -1295,7 +1298,7 @@ public class ActivitiWorkflowEngine extends BPMEngine implements WorkflowEngine
boolean isDefaultTransition = transition == null || ActivitiConstants.DEFAULT_TRANSITION_NAME.equals(transition);
Map<QName, Serializable> properties = propertyConverter.getTaskProperties(task, false);
Map<QName, Serializable> properties = propertyConverter.getTaskProperties(task);
QName outcomePropName = (QName) properties.get(WorkflowModel.PROP_OUTCOME_PROPERTY_NAME);
if(outcomePropName !=null)
{
@@ -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);
}
}
/**
@@ -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<WorkflowTask>();
}
@@ -1614,34 +1618,10 @@ public class ActivitiWorkflowEngine extends BPMEngine implements WorkflowEngine
}
}
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;
}
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;
String key = processNameQName.toPrefixString(namespaceService);
return factory.getProcessKey(key);
}
private void orderQuery(TaskQuery taskQuery, OrderBy[] orderBy)
@@ -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,19 +1812,7 @@ public class ActivitiWorkflowEngine extends BPMEngine implements WorkflowEngine
{
results = historicQuery.list();
}
List<WorkflowTask> workflowTasks = new ArrayList<WorkflowTask>();
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<QName, Object> taskCustomProps,
@@ -2034,6 +2002,7 @@ public class ActivitiWorkflowEngine extends BPMEngine implements WorkflowEngine
return true;
}
/**
* {@inheritDoc}
*/

View File

@@ -29,21 +29,24 @@ 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 ExecutionListener processCreateListener;
private TenantService tenantService;
@Override
public void parseUserTask(Element userTaskElement, ScopeImpl scope, ActivityImpl activity)
@@ -58,7 +61,8 @@ public class AddTaskListenerParseListener implements BpmnParseListener
}
if (completeTaskListener != null)
{
userTaskActivity.getTaskDefinition().addTaskListener(TaskListener.EVENTNAME_COMPLETE, completeTaskListener);
userTaskActivity.getTaskDefinition().addTaskListener(TaskListener.EVENTNAME_COMPLETE,
completeTaskListener);
}
}
}
@@ -67,25 +71,27 @@ public class AddTaskListenerParseListener implements BpmnParseListener
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
}
@Override
public void parseExclusiveGateway(Element exclusiveGwElement, ScopeImpl scope,
ActivityImpl activity)
public void parseExclusiveGateway(Element exclusiveGwElement, ScopeImpl scope, ActivityImpl activity)
{
// 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
}
@@ -121,8 +127,8 @@ public class AddTaskListenerParseListener implements BpmnParseListener
}
@Override
public void parseBoundaryTimerEventDefinition(Element timerEventDefinition,
boolean interrupting, ActivityImpl timerActivity)
public void parseBoundaryTimerEventDefinition(Element timerEventDefinition, boolean interrupting,
ActivityImpl timerActivity)
{
// Nothing to do here
}
@@ -134,22 +140,19 @@ public class AddTaskListenerParseListener implements BpmnParseListener
}
@Override
public void parseCallActivity(Element callActivityElement, ScopeImpl scope,
ActivityImpl activity)
public void parseCallActivity(Element callActivityElement, ScopeImpl scope, ActivityImpl activity)
{
// 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
}
@Override
public void parseSequenceFlow(Element sequenceFlowElement, ScopeImpl scopeElement,
TransitionImpl transition)
public void parseSequenceFlow(Element sequenceFlowElement, ScopeImpl scopeElement, TransitionImpl transition)
{
// Nothing to do here
}
@@ -161,31 +164,27 @@ public class AddTaskListenerParseListener implements BpmnParseListener
}
@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)
Element multiInstanceLoopCharacteristicsElement, ActivityImpl activity)
{
// Nothing to do here
}
@@ -204,4 +203,13 @@ public class AddTaskListenerParseListener implements BpmnParseListener
{
this.processCreateListener = processCreateListener;
}
/**
* @param tenantService
* the tenantService to set
*/
public void setTenantService(TenantService tenantService)
{
this.tenantService = tenantService;
}
}

View File

@@ -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);
}
}

View File

@@ -103,7 +103,7 @@ public class ActivitiPropertyConverter
this.typeManager = new ActivitiTaskTypeManager(factory, activitiUtil.getFormService());
}
public Map<QName, Serializable> getTaskProperties(Task task, boolean localOnly)
public Map<QName, Serializable> getTaskProperties(Task task)
{
// retrieve type definition for task
TypeDefinition taskDef = typeManager.getFullTaskDefinition(task);
@@ -112,42 +112,21 @@ public class ActivitiPropertyConverter
Map<QName, Serializable> properties = new HashMap<QName, Serializable>();
TaskService taskService = activitiUtil.getTaskService();
// Get the local task variables
Map<String, Object> localVariables = taskService.getVariablesLocal(task.getId());
Map<String, Object> variables = null;
if (!localOnly)
{
variables = new HashMap<String, Object>();
variables.putAll(localVariables);
// Execution-variables should also be added, if no value is present locally
Map<String, Object> executionVariables = activitiUtil.getExecutionVariables(task.getExecutionId());
for (Entry<String, Object> 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<String, Object> variables = taskService.getVariables(task.getId());
// Map the arbitrary properties
Map<String, Object> 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
@@ -322,7 +301,6 @@ public class ActivitiPropertyConverter
pooledActors.add(new NodeRef(nodeId));
}
}
// Add pooled actors. When no actors are found, set empty list
properties.put(WorkflowModel.ASSOC_POOLED_ACTORS, (Serializable) pooledActors);
@@ -471,7 +449,7 @@ 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"));
}
@@ -557,8 +535,11 @@ public class ActivitiPropertyConverter
return convertHistoricDetails(historicDetails);
}
private void mapArbitraryProperties(Map<String, Object> variables, Map<QName, Serializable> properties,
Map<String, Object> localVariables, Map<QName, PropertyDefinition> taskProperties, Map<QName, AssociationDefinition> taskAssociations)
private void mapArbitraryProperties(Map<String, Object> variables,
Map<QName, Serializable> properties,
Map<String, Object> localVariables,
Map<QName, PropertyDefinition> taskProperties,
Map<QName, AssociationDefinition> taskAssociations)
{
// Map arbitrary task variables
for (Entry<String, Object> 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);
@@ -632,7 +615,7 @@ public class ActivitiPropertyConverter
newProperties = new HashMap<QName, Serializable>(10);
}
Map<QName, Serializable> existingProperties = getTaskProperties(task, false);
Map<QName, Serializable> existingProperties = getTaskProperties(task);
if (add != null)
{
@@ -696,7 +679,6 @@ public class ActivitiPropertyConverter
{
if(properties==null || properties.isEmpty())
return;
TypeDefinition type = typeManager.getFullTaskDefinition(task);
Map<String, Object> variablesToSet = handlerRegistry.handleVariablesToSet(properties, type, task, DelegateTask.class);
if(variablesToSet.size() > 0)