diff --git a/config/alfresco/hibernate-context.xml b/config/alfresco/hibernate-context.xml
index 1ab65634dc..6b7f56290c 100644
--- a/config/alfresco/hibernate-context.xml
+++ b/config/alfresco/hibernate-context.xml
@@ -135,6 +135,8 @@
org/jbpm/taskmgmt/log/SwimlaneCreateLog.hbm.xml
org/jbpm/taskmgmt/log/SwimlaneAssignLog.hbm.xml
org/jbpm/job/CleanUpProcessJob.hbm.xml
+ org/alfresco/repo/workflow/jbpm/jbpm.ext.queries.hbm.xml
+
diff --git a/source/java/org/alfresco/repo/workflow/AlfrescoBpmEngine.java b/source/java/org/alfresco/repo/workflow/AlfrescoBpmEngine.java
index b349c62756..ef81f122a1 100644
--- a/source/java/org/alfresco/repo/workflow/AlfrescoBpmEngine.java
+++ b/source/java/org/alfresco/repo/workflow/AlfrescoBpmEngine.java
@@ -24,6 +24,7 @@ import org.alfresco.repo.tenant.TenantService;
import org.alfresco.service.cmr.dictionary.DictionaryService;
import org.alfresco.service.cmr.workflow.WorkflowException;
import org.alfresco.service.namespace.NamespaceService;
+import org.alfresco.service.namespace.QNameCache;
/**
* @since 3.4.e
@@ -38,7 +39,7 @@ public abstract class AlfrescoBpmEngine extends BPMEngine
protected DictionaryService dictionaryService;
protected WorkflowObjectFactory factory;
protected WorkflowAuthorityManager authorityManager;
-
+
/**
* {@inheritDoc}
*/
diff --git a/source/java/org/alfresco/repo/workflow/WorkflowObjectFactory.java b/source/java/org/alfresco/repo/workflow/WorkflowObjectFactory.java
index dbd1d855dc..0f133843a1 100644
--- a/source/java/org/alfresco/repo/workflow/WorkflowObjectFactory.java
+++ b/source/java/org/alfresco/repo/workflow/WorkflowObjectFactory.java
@@ -381,4 +381,9 @@ public class WorkflowObjectFactory
{
return qNameConverter.mapNameToQName(name);
}
+
+ public void clearQNameCache()
+ {
+ qNameConverter.clearCache();
+ }
}
\ No newline at end of file
diff --git a/source/java/org/alfresco/repo/workflow/WorkflowQNameConverter.java b/source/java/org/alfresco/repo/workflow/WorkflowQNameConverter.java
index 291f5fe71e..47cabeaf3e 100644
--- a/source/java/org/alfresco/repo/workflow/WorkflowQNameConverter.java
+++ b/source/java/org/alfresco/repo/workflow/WorkflowQNameConverter.java
@@ -22,6 +22,7 @@ package org.alfresco.repo.workflow;
import org.alfresco.service.namespace.NamespacePrefixResolver;
import org.alfresco.service.namespace.NamespaceService;
import org.alfresco.service.namespace.QName;
+import org.alfresco.service.namespace.QNameCache;
/**
* @since 3.4.e
@@ -30,6 +31,8 @@ import org.alfresco.service.namespace.QName;
*/
public class WorkflowQNameConverter
{
+ private static final int MAX_QNAME_CACHE_SIZE = 5000;
+ private final QNameCache cache = new QNameCache(MAX_QNAME_CACHE_SIZE);
private final NamespacePrefixResolver prefixResolver;
public WorkflowQNameConverter(NamespacePrefixResolver prefixResolver)
@@ -40,21 +43,21 @@ public class WorkflowQNameConverter
/**
* Map QName to jBPM variable name
*
- * @param name QName
+ * @param qName QName
* @return jBPM variable name
*/
- public String mapQNameToName(QName name)
+ public String mapQNameToName(QName qName)
{
- // NOTE: Map names using old conversion scheme (i.e. : -> _) as well as new scheme (i.e. } -> _)
- // NOTE: Use new scheme
- String nameStr = name.toPrefixString(prefixResolver);
- if (nameStr.indexOf('_') != -1 && nameStr.indexOf('_') < nameStr.indexOf(':'))
+ String name = cache.getName(qName);
+ if(name == null)
{
- return nameStr.replace(':', '}');
+ name = convertQNameToName(qName);
+ cache.putQNameToName(qName, name);
+ cache.putNameToQName(name, qName);
}
- return nameStr.replace(':', '_');
+ return name;
}
-
+
/**
* Map QName to jBPM variable name
*
@@ -62,6 +65,23 @@ public class WorkflowQNameConverter
* @return jBPM variable name
*/
public QName mapNameToQName(String name)
+ {
+ QName qName = cache.getQName(name);
+ if (qName == null)
+ {
+ qName = convertNameToQName(name);
+ cache.putNameToQName(name, qName);
+ cache.putQNameToName(qName, name);
+ }
+ return qName;
+ }
+
+ public void clearCache()
+ {
+ cache.clear();
+ }
+
+ private QName convertNameToQName(String name)
{
if(name.indexOf(QName.NAMESPACE_BEGIN)==0)
{
@@ -78,5 +98,19 @@ public class WorkflowQNameConverter
}
return QName.createQName(qName, prefixResolver);
}
+
+ private String convertQNameToName(QName name)
+ {
+ // NOTE: Map names using old conversion scheme (i.e. : -> _) as well as new scheme (i.e. } -> _)
+ // NOTE: Use new scheme
+ String nameStr = name.toPrefixString(prefixResolver);
+ if (nameStr.indexOf('_') != -1 && nameStr.indexOf('_') < nameStr.indexOf(':'))
+ {
+ // Return full QName string.
+ return name.toString();
+ }
+ // Return prefixed QName string.
+ return nameStr.replace(':', '_');
+ }
}
diff --git a/source/java/org/alfresco/repo/workflow/jbpm/JBPMEngine.java b/source/java/org/alfresco/repo/workflow/jbpm/JBPMEngine.java
index dbeb942f30..4f62d68ecf 100644
--- a/source/java/org/alfresco/repo/workflow/jbpm/JBPMEngine.java
+++ b/source/java/org/alfresco/repo/workflow/jbpm/JBPMEngine.java
@@ -66,11 +66,12 @@ import org.alfresco.service.cmr.workflow.WorkflowTaskQuery;
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.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;
@@ -125,7 +126,7 @@ public class JBPMEngine extends AlfrescoBpmEngine implements WorkflowEngine
protected AuthorityDAO authorityDAO;
protected JbpmTemplate jbpmTemplate;
protected SearchService unprotectedSearchService;
-
+
// Company Home
protected StoreRef companyHomeStore;
protected String companyHomePath;
@@ -738,7 +739,7 @@ public class JBPMEngine extends AlfrescoBpmEngine implements WorkflowEngine
Serializable packageNode = parameters.get(WorkflowModel.ASSOC_PACKAGE);
if (packageNode != null)
{
- String pckgName = mapQNameToName(WorkflowModel.ASSOC_PACKAGE);
+ String pckgName = factory.mapQNameToName(WorkflowModel.ASSOC_PACKAGE);
processContext.setVariable(pckgName, new JBPMNode((NodeRef) packageNode, serviceRegistry));
}
}
@@ -793,7 +794,6 @@ public class JBPMEngine extends AlfrescoBpmEngine implements WorkflowEngine
/* (non-Javadoc)
* @see org.alfresco.repo.workflow.WorkflowComponent#getActiveWorkflows(java.lang.String)
*/
- @SuppressWarnings("unchecked")
public List getActiveWorkflows(final String workflowDefinitionId)
{
return getWorkflowsInternal(workflowDefinitionId, true);
@@ -992,7 +992,7 @@ public class JBPMEngine extends AlfrescoBpmEngine implements WorkflowEngine
for (Map.Entry entry : tokenVars.entrySet())
{
String key = entry.getKey();
- QName qname = mapNameToQName(key);
+ QName qname = factory.mapNameToQName(key);
if (!properties.containsKey(key))
{
@@ -1312,46 +1312,15 @@ public class JBPMEngine extends AlfrescoBpmEngine implements WorkflowEngine
List tasks;
if (state.equals(WorkflowTaskState.IN_PROGRESS))
{
- TaskMgmtSession taskSession = context.getTaskMgmtSession();
- tasks = taskSession.findTaskInstances(authority);
+ return findActiveTaskInstances(authority, context);
}
else
{
// Note: This method is not implemented by jBPM
tasks = findCompletedTaskInstances(context, authority);
+ return getWorkflowTasks(tasks);
}
- return getWorkflowTasks(tasks);
- }
-
- /**
- * Gets the completed task list for the specified actor
- *
- * TODO: This method provides a query that's not in JBPM! Look
- * to have JBPM implement this.
- *
- * @param jbpmContext
- * the jbpm context
- * @param actorId
- * the actor to retrieve tasks for
- * @return the tasks
- */
- private List findCompletedTaskInstances(JbpmContext jbpmContext, String actorId)
- {
- List result = null;
- try
- {
- Session session = jbpmContext.getSession();
- Query query = session.createQuery(COMPLETED_TASKS_QUERY);
- query.setString("actorId", actorId);
- result = query.list();
- }
- catch (Exception e)
- {
- String msg = messageService.getMessage(ERR_FIND_COMPLETED_TASK_INSTS, actorId);
- throw new JbpmException(msg, e);
- }
- return result;
}
});
}
@@ -1362,8 +1331,207 @@ public class JBPMEngine extends AlfrescoBpmEngine implements WorkflowEngine
}
}
- /* (non-Javadoc)
- * @see org.alfresco.repo.workflow.TaskComponent#getPooledTasks(java.util.List)
+ /**
+ * Gets the completed task list for the specified actor
+ *
+ * @param jbpmContext the jbpm context
+ * @param actorId the actor to retrieve tasks for
+ * @return the tasks
+ */
+ @SuppressWarnings("unchecked")
+ private List findCompletedTaskInstances(JbpmContext jbpmContext, String actorId)
+ {
+ List result = null;
+ try
+ {
+ Session session = jbpmContext.getSession();
+ Query query = session.createQuery(COMPLETED_TASKS_QUERY);
+ query.setString("actorId", actorId);
+ result = query.list();
+ }
+ catch (Exception e)
+ {
+ String msg = messageService.getMessage(ERR_FIND_COMPLETED_TASK_INSTS, actorId);
+ throw new JbpmException(msg, e);
+ }
+ return result;
+ }
+
+ @SuppressWarnings("unchecked")
+ private List findActiveTaskInstances(final String authority, JbpmContext context)
+ {
+ Session session = context.getSession();
+ Query query = session.getNamedQuery("org.alfresco.repo.workflow.findTaskInstancesByActorId");
+ query.setString("actorId", authority);
+ query.setBoolean("true", true);
+ List workflowTasks = getWorkflowTasks(session, query.list());
+ // Do we need to clear a session here? It takes 3 seconds with 2000 workflows.
+ // session.clear();
+ return workflowTasks;
+ }
+
+ protected List getWorkflowTasks(Session session, List