mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-08-07 17:49:17 +00:00
git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@30270 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
@@ -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>
|
||||
|
||||
<!-- -->
|
||||
|
@@ -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());
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -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!");
|
||||
}
|
||||
|
||||
|
@@ -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
|
||||
|
@@ -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)
|
||||
|
@@ -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
|
||||
|
@@ -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.
|
||||
|
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -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}
|
||||
*/
|
||||
|
@@ -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;
|
||||
}
|
||||
}
|
@@ -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);
|
||||
}
|
||||
}
|
||||
|
@@ -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)
|
||||
|
Reference in New Issue
Block a user