mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-08-07 17:49:17 +00:00
Reversed merged revisions 25061,25072,25261,25326
- ALF-1787 needs re-implementing on HEAD git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@26796 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
@@ -23,16 +23,14 @@ import java.io.InputStream;
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.locks.ReentrantReadWriteLock;
|
||||
import java.util.concurrent.locks.ReentrantReadWriteLock.ReadLock;
|
||||
import java.util.concurrent.locks.ReentrantReadWriteLock.WriteLock;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.zip.ZipInputStream;
|
||||
|
||||
import org.alfresco.model.ContentModel;
|
||||
@@ -72,9 +70,7 @@ import org.alfresco.service.namespace.NamespaceException;
|
||||
import org.alfresco.service.namespace.NamespaceService;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
import org.alfresco.util.GUID;
|
||||
import org.hibernate.CacheMode;
|
||||
import org.hibernate.Criteria;
|
||||
import org.hibernate.FlushMode;
|
||||
import org.hibernate.Query;
|
||||
import org.hibernate.Session;
|
||||
import org.hibernate.criterion.Conjunction;
|
||||
@@ -134,8 +130,6 @@ public class JBPMEngine extends AlfrescoBpmEngine implements WorkflowEngine
|
||||
protected StoreRef companyHomeStore;
|
||||
protected String companyHomePath;
|
||||
|
||||
private QNameCache qNameCache = new QNameCache();
|
||||
|
||||
// Note: jBPM query which is not provided out-of-the-box
|
||||
// TODO: Check jBPM 3.2 and get this implemented in jBPM
|
||||
private final static String COMPLETED_TASKS_QUERY = "select ti " + "from org.jbpm.taskmgmt.exe.TaskInstance as ti "
|
||||
@@ -796,16 +790,26 @@ public class JBPMEngine extends AlfrescoBpmEngine implements WorkflowEngine
|
||||
return new WorkflowException(msg, e);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.alfresco.repo.workflow.WorkflowComponent#getActiveWorkflows(java.lang.String)
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public List<WorkflowInstance> getActiveWorkflows(final String workflowDefinitionId)
|
||||
{
|
||||
return getWorkflowsInternal(workflowDefinitionId, true);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.alfresco.repo.workflow.WorkflowComponent#getCompletedWorkflows(java.lang.String)
|
||||
*/
|
||||
public List<WorkflowInstance> getCompletedWorkflows(final String workflowDefinitionId)
|
||||
{
|
||||
return getWorkflowsInternal(workflowDefinitionId, false);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.alfresco.repo.workflow.WorkflowComponent#getWorkflows(java.lang.String)
|
||||
*/
|
||||
public List<WorkflowInstance> getWorkflows(final String workflowDefinitionId)
|
||||
{
|
||||
return getWorkflowsInternal(workflowDefinitionId, null);
|
||||
@@ -1300,11 +1304,6 @@ public class JBPMEngine extends AlfrescoBpmEngine implements WorkflowEngine
|
||||
{
|
||||
try
|
||||
{
|
||||
// arsenyko: I think it's necessary to avoid undesirable growth,
|
||||
// since a cache implementation is quite simple and doesn't care about
|
||||
// max elements in the cache.
|
||||
qNameCache.clear();
|
||||
|
||||
return (List<WorkflowTask>) jbpmTemplate.execute(new JbpmCallback()
|
||||
{
|
||||
public List<WorkflowTask> doInJbpm(JbpmContext context)
|
||||
@@ -1313,22 +1312,16 @@ public class JBPMEngine extends AlfrescoBpmEngine implements WorkflowEngine
|
||||
List<TaskInstance> tasks;
|
||||
if (state.equals(WorkflowTaskState.IN_PROGRESS))
|
||||
{
|
||||
Session session = context.getSession();
|
||||
Query query = session.getNamedQuery("org.alfresco.repo.workflow.findTaskInstancesByActorId");
|
||||
query.setString("actorId", authority);
|
||||
query.setBoolean("true", true);
|
||||
List<WorkflowTask> workflowTasks = getWorkflowTasks(session, query.list());
|
||||
// Do we need to clear a session here? It takes 3 seconds with 2000 workflows.
|
||||
// session.clear();
|
||||
return workflowTasks;
|
||||
TaskMgmtSession taskSession = context.getTaskMgmtSession();
|
||||
tasks = taskSession.findTaskInstances(authority);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Note: This method is not implemented by jBPM
|
||||
tasks = findCompletedTaskInstances(context, authority);
|
||||
return getWorkflowTasks(tasks);
|
||||
}
|
||||
|
||||
return getWorkflowTasks(tasks);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1343,7 +1336,6 @@ public class JBPMEngine extends AlfrescoBpmEngine implements WorkflowEngine
|
||||
* the actor to retrieve tasks for
|
||||
* @return the tasks
|
||||
*/
|
||||
@SuppressWarnings("rawtypes")
|
||||
private List<TaskInstance> findCompletedTaskInstances(JbpmContext jbpmContext, String actorId)
|
||||
{
|
||||
List<TaskInstance> result = null;
|
||||
@@ -1370,6 +1362,9 @@ public class JBPMEngine extends AlfrescoBpmEngine implements WorkflowEngine
|
||||
}
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.alfresco.repo.workflow.TaskComponent#getPooledTasks(java.util.List)
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public List<WorkflowTask> getPooledTasks(final List<String> authorities)
|
||||
{
|
||||
@@ -1429,218 +1424,6 @@ public class JBPMEngine extends AlfrescoBpmEngine implements WorkflowEngine
|
||||
}
|
||||
}
|
||||
|
||||
protected List<WorkflowTask> getWorkflowTasks(Session session, List<Object[]> rows)
|
||||
{
|
||||
List<WorkflowTask> workflowTasks = new ArrayList<WorkflowTask>(rows.size());
|
||||
|
||||
/// ------------------------
|
||||
|
||||
// Preload data into L1 session
|
||||
List<Long> taskInstanceIds = new ArrayList<Long>(rows.size());
|
||||
List<Long> contextInstanceIds = new ArrayList<Long>(rows.size());
|
||||
for (Object[] row : rows)
|
||||
{
|
||||
TaskInstance ti = (TaskInstance) row[0];
|
||||
taskInstanceIds.add(ti.getId());
|
||||
ContextInstance ci = (ContextInstance) row[8];
|
||||
contextInstanceIds.add(ci.getId());
|
||||
}
|
||||
Map<Long, TaskInstance> taskInstanceCache = new HashMap<Long, TaskInstance>(rows.size());
|
||||
if (taskInstanceIds.size() > 0)
|
||||
{
|
||||
taskInstanceCache = cacheTasks(session, taskInstanceIds);
|
||||
}
|
||||
Map<Long, TokenVariableMap> variablesCache = new HashMap<Long, TokenVariableMap>(rows.size());
|
||||
if (contextInstanceIds.size() > 0)
|
||||
{
|
||||
variablesCache = cacheVariables(session, contextInstanceIds);
|
||||
}
|
||||
taskInstanceIds.clear();
|
||||
contextInstanceIds.clear();
|
||||
/// ------------------------
|
||||
for(Object[] row : rows)
|
||||
{
|
||||
TaskInstance ti = (TaskInstance) row[0];
|
||||
Token token = (Token)row[2];
|
||||
ProcessInstance processInstance = (ProcessInstance)row[3];
|
||||
Node node = (Node)row[4];
|
||||
Task task = (Task)row[5];
|
||||
ProcessDefinition processDefinition = (ProcessDefinition)row[6];
|
||||
Task startTask = (Task)row[7];
|
||||
ContextInstance contextInstance = (ContextInstance) row[8];
|
||||
|
||||
if (tenantService.isEnabled())
|
||||
{
|
||||
try
|
||||
{
|
||||
tenantService.checkDomain(processDefinition.getName());
|
||||
}
|
||||
catch (RuntimeException re)
|
||||
{
|
||||
// deliberately skip this one - due to domain mismatch - eg. when querying by group authority
|
||||
continue;
|
||||
}
|
||||
}
|
||||
// TaskInstance with some precached properties
|
||||
TaskInstance helperTi = taskInstanceCache.get(ti.getId());
|
||||
// WorkflowTask
|
||||
WorkflowTask workflowTask = new WorkflowTask();
|
||||
workflowTask.id = createGlobalId(new Long(ti.getId()).toString());
|
||||
workflowTask.name = ti.getName();
|
||||
workflowTask.state = getWorkflowTaskState(ti);
|
||||
// WorkflowPath
|
||||
WorkflowPath path = new WorkflowPath();
|
||||
String tokenId = token.getFullName().replace("/", WORKFLOW_TOKEN_SEPERATOR);
|
||||
path.id = createGlobalId(processInstance.getId() + WORKFLOW_PATH_SEPERATOR + tokenId);
|
||||
// WorkflowInstance
|
||||
WorkflowInstance workflowInstance = new WorkflowInstance();
|
||||
workflowInstance.id = createGlobalId(new Long(processInstance.getId()).toString());
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
Map<String, Object> variables = variablesCache.get(contextInstance.getId()).getVariables();
|
||||
|
||||
workflowInstance.description = (String)variables.get(mapQNameToName(WorkflowModel.PROP_WORKFLOW_DESCRIPTION));
|
||||
String name = tenantService.getBaseName(processDefinition.getName());
|
||||
String title = getLabel(name + ".workflow", TITLE_LABEL, name);
|
||||
String description = getLabel(name + ".workflow", DESC_LABEL, title);
|
||||
workflowInstance.definition = new WorkflowDefinition(createGlobalId(new Long(processDefinition.getId()).toString()),
|
||||
createGlobalId(name),
|
||||
new Integer(processDefinition.getVersion()).toString(),
|
||||
title,
|
||||
description,
|
||||
(startTask != null
|
||||
? createWorkflowTaskDefinition(startTask)
|
||||
: null));
|
||||
workflowInstance.active = !processInstance.hasEnded();
|
||||
JBPMNode initiator = (JBPMNode)variables.get("initiator");
|
||||
if (initiator != null)
|
||||
{
|
||||
workflowInstance.initiator = initiator.getNodeRef();
|
||||
}
|
||||
JBPMNode context = (JBPMNode)variables.get(mapQNameToName(WorkflowModel.PROP_CONTEXT));
|
||||
if (context != null)
|
||||
{
|
||||
workflowInstance.context = context.getNodeRef();
|
||||
}
|
||||
JBPMNode workflowPackage = (JBPMNode)variables.get(mapQNameToName(WorkflowModel.ASSOC_PACKAGE));
|
||||
if (workflowPackage != null)
|
||||
{
|
||||
workflowInstance.workflowPackage = workflowPackage.getNodeRef();
|
||||
}
|
||||
workflowInstance.priority = (Integer)variables.get(mapQNameToName(WorkflowModel.PROP_WORKFLOW_PRIORITY));
|
||||
workflowInstance.dueDate = (Date)variables.get(mapQNameToName(WorkflowModel.PROP_WORKFLOW_DUE_DATE));
|
||||
workflowInstance.startDate = processInstance.getStart();
|
||||
workflowInstance.endDate = processInstance.getEnd();
|
||||
path.instance = workflowInstance;
|
||||
// WorkflowNode
|
||||
path.node = createWorkflowNode(node);
|
||||
path.active = !token.hasEnded();
|
||||
workflowTask.path = path;
|
||||
// WorkflowTaskDefinition
|
||||
workflowTask.definition = createWorkflowTaskDefinition(task);
|
||||
// WorkflowTaskProperies
|
||||
workflowTask.properties = getTaskProperties(helperTi != null ? helperTi : ti, false, variablesCache);
|
||||
|
||||
String workflowDisplayId = processDefinition.getName() + ".task." + workflowTask.name;
|
||||
workflowTask.title = getLabel(workflowDisplayId, TITLE_LABEL, null);
|
||||
if (workflowTask.title == null)
|
||||
{
|
||||
workflowTask.title = workflowTask.definition.metadata.getTitle();
|
||||
if (workflowTask.title == null)
|
||||
{
|
||||
workflowTask.title = workflowTask.name;
|
||||
}
|
||||
}
|
||||
workflowTask.description = getLabel(workflowDisplayId, DESC_LABEL, null);
|
||||
if (workflowTask.description == null)
|
||||
{
|
||||
description = workflowTask.definition.metadata.getDescription();
|
||||
workflowTask.description = (description == null) ? workflowTask.title : description;
|
||||
}
|
||||
|
||||
workflowTasks.add(workflowTask);
|
||||
}
|
||||
return workflowTasks;
|
||||
}
|
||||
|
||||
private Map<Long, TokenVariableMap> cacheVariables(Session session, List<Long> ids)
|
||||
{
|
||||
// Preload data into L1 session
|
||||
int batchSize = 800; // Must limit IN clause size!
|
||||
List<Long> batch = new ArrayList<Long>(ids.size());
|
||||
Map<Long, TokenVariableMap> cachedResults = new HashMap<Long, TokenVariableMap>();
|
||||
for (Long id : ids)
|
||||
{
|
||||
batch.add(id);
|
||||
if (batch.size() >= batchSize)
|
||||
{
|
||||
cacheVariablesNoBatch(session, batch, cachedResults);
|
||||
batch.clear();
|
||||
}
|
||||
}
|
||||
if (batch.size() > 0)
|
||||
{
|
||||
cacheVariablesNoBatch(session, batch, cachedResults);
|
||||
}
|
||||
batch.clear();
|
||||
return cachedResults;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private void cacheVariablesNoBatch(Session session, List<Long> contextInstanceIds, Map<Long, TokenVariableMap> variablesCache)
|
||||
{
|
||||
Query query = session.getNamedQuery("org.alfresco.repo.workflow.cacheInstanceVariables");
|
||||
query.setParameterList("ids", contextInstanceIds);
|
||||
query.setCacheMode(CacheMode.PUT);
|
||||
query.setFlushMode(FlushMode.MANUAL);
|
||||
query.setCacheable(true);
|
||||
|
||||
List<TokenVariableMap> results = (List<TokenVariableMap>) query.list();
|
||||
for (TokenVariableMap tokenVariableMap : results)
|
||||
{
|
||||
variablesCache.put(tokenVariableMap.getContextInstance().getId(), tokenVariableMap);
|
||||
}
|
||||
}
|
||||
|
||||
private Map<Long, TaskInstance> cacheTasks(Session session, List<Long> ids)
|
||||
{
|
||||
// Preload data into L1 session
|
||||
int batchSize = 800; // Must limit IN clause size!
|
||||
List<Long> batch = new ArrayList<Long>(ids.size());
|
||||
Map<Long, TaskInstance> cachedResults = new HashMap<Long, TaskInstance>();
|
||||
for (Long id : ids)
|
||||
{
|
||||
batch.add(id);
|
||||
if (batch.size() >= batchSize)
|
||||
{
|
||||
cacheTasksNoBatch(session, batch, cachedResults);
|
||||
batch.clear();
|
||||
}
|
||||
}
|
||||
if (batch.size() > 0)
|
||||
{
|
||||
cacheTasksNoBatch(session, batch, cachedResults);
|
||||
}
|
||||
batch.clear();
|
||||
return cachedResults;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private void cacheTasksNoBatch(Session session, List<Long> taskInstanceIds, Map<Long, TaskInstance> returnMap)
|
||||
{
|
||||
Query query = session.getNamedQuery("org.alfresco.repo.workflow.cacheTaskInstanceProperties");
|
||||
query.setParameterList("ids", taskInstanceIds);
|
||||
query.setCacheMode(CacheMode.PUT);
|
||||
query.setFlushMode(FlushMode.MANUAL);
|
||||
query.setCacheable(true);
|
||||
|
||||
List<TaskInstance> results = (List<TaskInstance>) query.list();
|
||||
for (TaskInstance taskInstance : results)
|
||||
{
|
||||
returnMap.put(taskInstance.getId(), taskInstance);
|
||||
}
|
||||
}
|
||||
|
||||
protected List<WorkflowTask> getWorkflowTasks(List<TaskInstance> tasks)
|
||||
{
|
||||
// convert tasks to appropriate service response format
|
||||
@@ -2003,11 +1786,12 @@ public class JBPMEngine extends AlfrescoBpmEngine implements WorkflowEngine
|
||||
|
||||
// create properties to set on task instance
|
||||
Map<QName, Serializable> newProperties = new HashMap<QName, Serializable>(10);
|
||||
|
||||
if(properties!=null)
|
||||
{
|
||||
newProperties.putAll(properties);
|
||||
}
|
||||
Map<QName, Serializable> existingProperties = getTaskProperties(taskInstance, false, null);
|
||||
Map<QName, Serializable> existingProperties = getTaskProperties(taskInstance, false);
|
||||
if (add != null)
|
||||
{
|
||||
// add new associations
|
||||
@@ -2419,10 +2203,9 @@ public class JBPMEngine extends AlfrescoBpmEngine implements WorkflowEngine
|
||||
*
|
||||
* @param instance task instance
|
||||
* @param properties properties to set
|
||||
* @param variablesCache cahce og context instance variables if any exists
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
protected Map<QName, Serializable> getTaskProperties(TaskInstance instance, boolean localProperties, Map<Long, TokenVariableMap> variablesCache)
|
||||
protected Map<QName, Serializable> getTaskProperties(TaskInstance instance, boolean localProperties)
|
||||
{
|
||||
// retrieve type definition for task
|
||||
TypeDefinition taskDef = getFullTaskDefinition(instance);
|
||||
@@ -2437,16 +2220,7 @@ public class JBPMEngine extends AlfrescoBpmEngine implements WorkflowEngine
|
||||
Token token = instance.getToken();
|
||||
while (token != null)
|
||||
{
|
||||
TokenVariableMap varMap = null;
|
||||
if (variablesCache != null && variablesCache.containsKey(context.getId()))
|
||||
{
|
||||
varMap = variablesCache.get(context.getId());
|
||||
}
|
||||
else
|
||||
{
|
||||
varMap = context.getTokenVariableMap(token);
|
||||
}
|
||||
|
||||
TokenVariableMap varMap = context.getTokenVariableMap(token);
|
||||
if (varMap != null)
|
||||
{
|
||||
Map<String, Object> tokenVars = varMap.getVariablesLocally();
|
||||
@@ -2498,11 +2272,11 @@ public class JBPMEngine extends AlfrescoBpmEngine implements WorkflowEngine
|
||||
}
|
||||
|
||||
// map jBPM task instance collections to associations
|
||||
Set<PooledActor> pooledActors = instance.getPooledActors();
|
||||
Set pooledActors = instance.getPooledActors();
|
||||
if (pooledActors != null)
|
||||
{
|
||||
List<NodeRef> pooledNodeRefs = new ArrayList<NodeRef>(pooledActors.size());
|
||||
for (PooledActor pooledActor : pooledActors)
|
||||
for (PooledActor pooledActor : (Set<PooledActor>)pooledActors)
|
||||
{
|
||||
NodeRef pooledNodeRef = null;
|
||||
String pooledActorId = pooledActor.getActorId();
|
||||
@@ -2732,7 +2506,7 @@ public class JBPMEngine extends AlfrescoBpmEngine implements WorkflowEngine
|
||||
*/
|
||||
protected void setDefaultTaskProperties(TaskInstance instance)
|
||||
{
|
||||
Map<QName, Serializable> existingValues = getTaskProperties(instance, true, null);
|
||||
Map<QName, Serializable> existingValues = getTaskProperties(instance, true);
|
||||
Map<QName, Serializable> defaultValues = new HashMap<QName, Serializable>();
|
||||
|
||||
// construct an anonymous type that flattens all mandatory aspects
|
||||
@@ -2806,7 +2580,7 @@ public class JBPMEngine extends AlfrescoBpmEngine implements WorkflowEngine
|
||||
*/
|
||||
protected void setDefaultWorkflowProperties(TaskInstance startTask)
|
||||
{
|
||||
Map<QName, Serializable> taskProperties = getTaskProperties(startTask, true, null);
|
||||
Map<QName, Serializable> taskProperties = getTaskProperties(startTask, true);
|
||||
|
||||
ContextInstance processContext = startTask.getContextInstance();
|
||||
String workflowDescriptionName = mapQNameToName(WorkflowModel.PROP_WORKFLOW_DESCRIPTION);
|
||||
@@ -2852,7 +2626,7 @@ public class JBPMEngine extends AlfrescoBpmEngine implements WorkflowEngine
|
||||
List<QName> missingProps = null;
|
||||
|
||||
// retrieve properties of task
|
||||
Map<QName, Serializable> existingValues = getTaskProperties(instance, false, null);
|
||||
Map<QName, Serializable> existingValues = getTaskProperties(instance, false);
|
||||
|
||||
// retrieve definition of task
|
||||
ClassDefinition classDef = getFullTaskDefinition(instance);
|
||||
@@ -3067,11 +2841,8 @@ public class JBPMEngine extends AlfrescoBpmEngine implements WorkflowEngine
|
||||
*/
|
||||
private QName mapNameToQName(String name)
|
||||
{
|
||||
QName qname = qNameCache.getNameToQName(name);
|
||||
if (qname == null)
|
||||
{
|
||||
// NOTE: Map names using old conversion scheme (i.e. : -> _) as well as
|
||||
// new scheme (i.e. } -> _)
|
||||
QName qname = null;
|
||||
// NOTE: Map names using old conversion scheme (i.e. : -> _) as well as new scheme (i.e. } -> _)
|
||||
String qnameStr = (name.indexOf('}') == -1) ? name.replaceFirst("_", ":") : name.replace("}", ":");
|
||||
try
|
||||
{
|
||||
@@ -3080,8 +2851,6 @@ public class JBPMEngine extends AlfrescoBpmEngine implements WorkflowEngine
|
||||
catch(NamespaceException e)
|
||||
{
|
||||
qname = QName.createQName(name, this.namespaceService);
|
||||
}
|
||||
qNameCache.putNameToQName(name, qname);
|
||||
}
|
||||
return qname;
|
||||
}
|
||||
@@ -3095,21 +2864,14 @@ public class JBPMEngine extends AlfrescoBpmEngine implements WorkflowEngine
|
||||
*/
|
||||
private String mapQNameToName(QName name)
|
||||
{
|
||||
// NOTE: Map names using old conversion scheme (i.e. : -> _) as well as
|
||||
// new scheme (i.e. } -> _)
|
||||
// NOTE: Map names using old conversion scheme (i.e. : -> _) as well as new scheme (i.e. } -> _)
|
||||
// NOTE: Use new scheme
|
||||
String cachedName = qNameCache.getQNameToName(name);
|
||||
if (cachedName == null)
|
||||
{
|
||||
String nameStr = name.toPrefixString(this.namespaceService);
|
||||
if (nameStr.indexOf('_') != -1 && nameStr.indexOf('_') < nameStr.indexOf(':'))
|
||||
{
|
||||
cachedName = nameStr.replace(':', '}');
|
||||
}
|
||||
cachedName = nameStr.replace(':', '_');
|
||||
return nameStr.replace(':', '}');
|
||||
}
|
||||
qNameCache.putQNameToName(name, cachedName);
|
||||
return cachedName;
|
||||
return nameStr.replace(':', '_');
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -3200,7 +2962,6 @@ public class JBPMEngine extends AlfrescoBpmEngine implements WorkflowEngine
|
||||
String type = getRealNode(node).getClass().getSimpleName();
|
||||
// TODO: Is there a formal way of determing if task node?
|
||||
boolean isTaskNode = type.equals("TaskNode");
|
||||
@SuppressWarnings("rawtypes")
|
||||
List<Transition> transitions = node.getLeavingTransitions();
|
||||
List<WorkflowTransition> wfTransitions;
|
||||
if (transitions != null)
|
||||
@@ -3323,7 +3084,7 @@ public class JBPMEngine extends AlfrescoBpmEngine implements WorkflowEngine
|
||||
WorkflowPath path = createWorkflowPath(task.getToken());
|
||||
WorkflowTaskState state = getWorkflowTaskState(task);
|
||||
WorkflowTaskDefinition definition = createWorkflowTaskDefinition(task.getTask());
|
||||
Map<QName, Serializable> properties = getTaskProperties(task, false, null);
|
||||
Map<QName, Serializable> properties = getTaskProperties(task, false);
|
||||
return factory.createTask(id, definition, name, null, null, state, path, properties);
|
||||
}
|
||||
|
||||
@@ -3420,103 +3181,4 @@ public class JBPMEngine extends AlfrescoBpmEngine implements WorkflowEngine
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Basic cache implementation for performance improvement with mapping QNames and Names of properties.
|
||||
*/
|
||||
private class QNameCache
|
||||
{
|
||||
private Map<QName, String> mapQNameToNameCache;
|
||||
private Map<String, QName> mapNameToQNameCache;
|
||||
|
||||
private ReentrantReadWriteLock qNameToNameLock = new ReentrantReadWriteLock();
|
||||
private WriteLock qNameToNameWriteLock = qNameToNameLock.writeLock();
|
||||
private ReadLock qNameToNameReadLock = qNameToNameLock.readLock();
|
||||
|
||||
private ReentrantReadWriteLock nameToQNameLock = new ReentrantReadWriteLock();
|
||||
private WriteLock nameToQNameWriteLock = nameToQNameLock.writeLock();
|
||||
private ReadLock nameToQNameReadLock = nameToQNameLock.readLock();
|
||||
|
||||
QNameCache()
|
||||
{
|
||||
mapQNameToNameCache = new HashMap<QName, String>();
|
||||
mapNameToQNameCache = new HashMap<String, QName>();
|
||||
}
|
||||
|
||||
String getQNameToName(QName qName)
|
||||
{
|
||||
qNameToNameReadLock.lock();
|
||||
try
|
||||
{
|
||||
return mapQNameToNameCache.get(qName);
|
||||
}
|
||||
finally
|
||||
{
|
||||
qNameToNameReadLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
void putQNameToName(QName qName, String name)
|
||||
{
|
||||
qNameToNameWriteLock.lock();
|
||||
try
|
||||
{
|
||||
mapQNameToNameCache.put(qName, name);
|
||||
}
|
||||
finally
|
||||
{
|
||||
qNameToNameWriteLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
QName getNameToQName(String name)
|
||||
{
|
||||
nameToQNameReadLock.lock();
|
||||
try
|
||||
{
|
||||
return mapNameToQNameCache.get(name);
|
||||
}
|
||||
finally
|
||||
{
|
||||
nameToQNameReadLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
void putNameToQName(String name, QName qName)
|
||||
{
|
||||
nameToQNameWriteLock.lock();
|
||||
try
|
||||
{
|
||||
mapNameToQNameCache.put(name, qName);
|
||||
}
|
||||
finally
|
||||
{
|
||||
nameToQNameWriteLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
void clear()
|
||||
{
|
||||
nameToQNameWriteLock.lock();
|
||||
try
|
||||
{
|
||||
mapNameToQNameCache.clear();
|
||||
}
|
||||
finally
|
||||
{
|
||||
nameToQNameWriteLock.unlock();
|
||||
}
|
||||
qNameToNameWriteLock.lock();
|
||||
try
|
||||
{
|
||||
mapQNameToNameCache.clear();
|
||||
}
|
||||
finally
|
||||
{
|
||||
qNameToNameWriteLock.unlock();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -1,239 +0,0 @@
|
||||
package org.alfresco.repo.workflow.jbpm;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Arrays;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.repo.security.authentication.AuthenticationComponent;
|
||||
import org.alfresco.repo.transaction.RetryingTransactionHelper;
|
||||
import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback;
|
||||
import org.alfresco.repo.workflow.BPMEngineRegistry;
|
||||
import org.alfresco.repo.workflow.WorkflowModel;
|
||||
import org.alfresco.service.ServiceRegistry;
|
||||
import org.alfresco.service.cmr.model.FileFolderService;
|
||||
import org.alfresco.service.cmr.model.FileInfo;
|
||||
import org.alfresco.service.cmr.repository.ContentWriter;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.cmr.repository.NodeService;
|
||||
import org.alfresco.service.cmr.repository.StoreRef;
|
||||
import org.alfresco.service.cmr.workflow.WorkflowDefinition;
|
||||
import org.alfresco.service.cmr.workflow.WorkflowService;
|
||||
import org.alfresco.service.cmr.workflow.WorkflowTask;
|
||||
import org.alfresco.service.cmr.workflow.WorkflowTaskState;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
import org.hibernate.Query;
|
||||
import org.hibernate.Session;
|
||||
import org.jbpm.JbpmContext;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
import org.springmodules.workflow.jbpm31.JbpmCallback;
|
||||
import org.springmodules.workflow.jbpm31.JbpmTemplate;
|
||||
|
||||
/**
|
||||
* This test shows a performance benefit from a usage of direct queries
|
||||
* instead of creating required classes like WorkflowTask in a loop with collecting
|
||||
* required properties from different services.
|
||||
*
|
||||
* @author arsenyko
|
||||
*
|
||||
*/
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@ContextConfiguration(locations = { "classpath:alfresco/application-context.xml" })
|
||||
public class JBPMJunit4LoadTests
|
||||
{
|
||||
|
||||
private static String WORKFLOW_NAME = "jbpm$wf:adhoc";
|
||||
private static String WORKFLOW_NODE_NAME = "workflow-test-19243cbb-c58a-485e-bcd9-2e2be030dfb9.txt";
|
||||
|
||||
private static int WORKFLOW_COUNT = 2000;
|
||||
|
||||
@Autowired
|
||||
protected ApplicationContext applicationContext;
|
||||
protected ServiceRegistry serviceRegistry;
|
||||
protected RetryingTransactionHelper retryingTransactionHelper;
|
||||
protected NodeService nodeService;
|
||||
protected WorkflowService workflowService;
|
||||
protected FileFolderService fileFolderService;
|
||||
|
||||
protected JBPMEngine jbpmEngine;
|
||||
|
||||
protected AuthenticationComponent authenticationComponent;
|
||||
|
||||
private NodeRef companyHomeNodeRef;
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception
|
||||
{
|
||||
serviceRegistry = (ServiceRegistry) applicationContext.getBean(ServiceRegistry.SERVICE_REGISTRY);
|
||||
serviceRegistry.getAuthenticationService().authenticate("admin", "admin".toCharArray());
|
||||
|
||||
retryingTransactionHelper = serviceRegistry.getRetryingTransactionHelper();
|
||||
fileFolderService = serviceRegistry.getFileFolderService();
|
||||
workflowService = serviceRegistry.getWorkflowService();
|
||||
nodeService = serviceRegistry.getNodeService();
|
||||
|
||||
BPMEngineRegistry registry = (BPMEngineRegistry)applicationContext.getBean("bpm_engineRegistry");
|
||||
jbpmEngine = (JBPMEngine) registry.getWorkflowComponent("jbpm");
|
||||
|
||||
NodeRef storeRootNodeRef = nodeService.getRootNode(new StoreRef("workspace://SpacesStore"));
|
||||
companyHomeNodeRef = serviceRegistry.getSearchService().selectNodes(storeRootNodeRef, "/app:company_home", null, serviceRegistry.getNamespaceService(), false).get(0);
|
||||
System.out.println(" -------------- ");
|
||||
createWorkflowStuff();
|
||||
}
|
||||
|
||||
public void createWorkflowStuff() throws Exception
|
||||
{
|
||||
System.out.println(" [createWorkflowStuff] Started at " + new Date().toString());
|
||||
|
||||
NodeRef workflowNode = nodeService.getChildByName(companyHomeNodeRef, ContentModel.ASSOC_CONTAINS, WORKFLOW_NODE_NAME);
|
||||
|
||||
if (workflowNode == null)
|
||||
{
|
||||
RetryingTransactionCallback<Void> callback = new RetryingTransactionCallback<Void>(){
|
||||
|
||||
@Override
|
||||
public Void execute() throws Throwable
|
||||
{
|
||||
FileInfo fileInfo = fileFolderService.create(companyHomeNodeRef, WORKFLOW_NODE_NAME, ContentModel.TYPE_CONTENT);
|
||||
ContentWriter writer = serviceRegistry.getContentService().getWriter(fileInfo.getNodeRef(), ContentModel.PROP_CONTENT, true);
|
||||
writer.setMimetype("text/plain");
|
||||
writer.setEncoding("UTF-8");
|
||||
writer.putContent("many workflows many workflows many workflows many workflows many workflows many workflows many workflows many workflows");
|
||||
System.out.println(" [createWorkflowStuff] Workflow node '" + WORKFLOW_NODE_NAME + "' has been created");
|
||||
|
||||
//WorkflowDefinition wfDef = workflowService.getDefinitionByName(WORKFLOW_NAME);
|
||||
WorkflowDefinition wfDef = jbpmEngine.getDefinitionByName(WORKFLOW_NAME);
|
||||
long startTime = new Date().getTime();
|
||||
for (Integer i = 0; i < WORKFLOW_COUNT; i++)
|
||||
{
|
||||
// We are creating workflows in usual way, but with new persistent objects.
|
||||
// There is a some performance issue with sesssion.flash() in each iteration,
|
||||
// but this was made to avoid a lot of changes in a logic related to org.alfresco.service.cmr.workflow.*
|
||||
// classes.
|
||||
workflowService.startWorkflow(wfDef.id, prepareWorkflowProperties(fileInfo.getNodeRef(), i.toString()));
|
||||
// jbpmEngine.startWorkflow_ALF1787(wfDef.id, prepareWorkflowProperties(fileInfo.getNodeRef(), i.toString()));
|
||||
}
|
||||
long endTime = new Date().getTime();
|
||||
System.out.println(" [createWorkflowStuff] Execution time (ms): " + (endTime - startTime));
|
||||
return null;
|
||||
}
|
||||
|
||||
};
|
||||
retryingTransactionHelper.setMaxRetries(1);
|
||||
retryingTransactionHelper.doInTransaction(callback);
|
||||
System.out.println(" [createWorkflowStuff] Finished at " + new Date().toString());
|
||||
}
|
||||
else
|
||||
{
|
||||
System.out.println(" [createWorkflowStuff] Workflow node '" + WORKFLOW_NODE_NAME + "' already exists");
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
//@Test
|
||||
public void testQuery1() throws Exception
|
||||
{
|
||||
RetryingTransactionCallback<Void> callback = new RetryingTransactionCallback<Void>(){
|
||||
|
||||
@Override
|
||||
public Void execute() throws Throwable
|
||||
{
|
||||
JbpmTemplate jbpmTemplate = (JbpmTemplate) applicationContext.getBean("jbpm_template");
|
||||
List<Object[]> result = (List<Object[]>) jbpmTemplate.execute(new JbpmCallback()
|
||||
{
|
||||
public List<Object[]> doInJbpm(JbpmContext context)
|
||||
{
|
||||
Session session = context.getSession();
|
||||
Query query = session.getNamedQuery("org.alfresco.repo.workflow.findTaskInstancesByActorId");
|
||||
return query.setString("actorId", "admin").list();
|
||||
}
|
||||
});
|
||||
for(Object[] ti : result)
|
||||
{
|
||||
System.out.println(Arrays.toString(ti));
|
||||
}
|
||||
System.out.println(result.size());
|
||||
return null;
|
||||
}
|
||||
};
|
||||
retryingTransactionHelper.setMaxRetries(1);
|
||||
retryingTransactionHelper.doInTransaction(callback);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetAssignedTasks_NEW() throws Exception
|
||||
{
|
||||
final int RUN_COUNT = 7;
|
||||
RetryingTransactionCallback<Void> callback = new RetryingTransactionCallback<Void>(){
|
||||
|
||||
@Override
|
||||
public Void execute() throws Throwable
|
||||
{
|
||||
Date beginTime = new Date();
|
||||
System.out.println(" [testGetAssignedTasks_NEW] Started at " + beginTime.toString());
|
||||
List<WorkflowTask> tasks = workflowService.getAssignedTasks("admin", WorkflowTaskState.IN_PROGRESS);
|
||||
Date endTime = new Date();
|
||||
System.out.println(" [testGetAssignedTasks_NEW] Retrieved tasks: " + tasks.size() + " in " + (endTime.getTime() - beginTime.getTime()) + " ms");
|
||||
System.out.println(" [testGetAssignedTasks_NEW] Finished at " + endTime.toString());
|
||||
return null;
|
||||
}
|
||||
};
|
||||
retryingTransactionHelper.setMaxRetries(1);
|
||||
for(int i=0; i<RUN_COUNT; i++)
|
||||
{
|
||||
retryingTransactionHelper.doInTransaction(callback);
|
||||
}
|
||||
}
|
||||
/*
|
||||
@Test
|
||||
public void testGetAssignedTasks_OLD() throws Exception
|
||||
{
|
||||
RetryingTransactionCallback<Void> callback = new RetryingTransactionCallback<Void>(){
|
||||
|
||||
@Override
|
||||
public Void execute() throws Throwable
|
||||
{
|
||||
Date beginTime = new Date();
|
||||
System.out.println(" [testGetAssignedTasks_OLD] Started at " + beginTime.toString());
|
||||
List<WorkflowTask> tasks = jbpmEngine.getAssignedTasks_OLD("admin", WorkflowTaskState.IN_PROGRESS);
|
||||
Date endTime = new Date();
|
||||
System.out.println(" [testGetAssignedTasks_OLD] Retrieved tasks: " + tasks.size() + " in " + (endTime.getTime() - beginTime.getTime()) + " ms");
|
||||
System.out.println(" [testGetAssignedTasks_OLD] Finished at " + new Date().toString());
|
||||
return null;
|
||||
}
|
||||
};
|
||||
retryingTransactionHelper.setMaxRetries(1);
|
||||
retryingTransactionHelper.doInTransaction(callback);
|
||||
}
|
||||
*/
|
||||
|
||||
@After
|
||||
public void tearDown() throws Exception
|
||||
{
|
||||
System.out.println(" -------------- ");
|
||||
}
|
||||
|
||||
private Map<QName, Serializable> prepareWorkflowProperties(NodeRef nodeRef, String id)
|
||||
{
|
||||
Map<QName, Serializable> parameters = new HashMap<QName, Serializable>();
|
||||
|
||||
parameters.put(WorkflowModel.ASSOC_PACKAGE, nodeRef);
|
||||
parameters.put(WorkflowModel.ASSOC_ASSIGNEE, "admin");
|
||||
parameters.put(WorkflowModel.PROP_WORKFLOW_DESCRIPTION, "Test workflow '" + id + "'");
|
||||
parameters.put(WorkflowModel.PROP_WORKFLOW_DEFINITION_NAME, "test_workflow_" + id);
|
||||
|
||||
return parameters;
|
||||
|
||||
}
|
||||
|
||||
}
|
Reference in New Issue
Block a user