mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-07-24 17:32:48 +00:00
Workflow Checkpoint:
- BPM Model (xml & QName definitions) - Getting / Setting / Updating Task Properties git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@3470 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
280
config/alfresco/model/bpmModel.xml
Normal file
280
config/alfresco/model/bpmModel.xml
Normal file
@@ -0,0 +1,280 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
|
||||||
|
<model name="bpm:businessprocessmodel" xmlns="http://www.alfresco.org/model/dictionary/1.0">
|
||||||
|
|
||||||
|
<description>Business Process Model</description>
|
||||||
|
<author>Alfresco</author>
|
||||||
|
<version>1.0</version>
|
||||||
|
|
||||||
|
<!-- Imports are required to allow references to definitions in other models -->
|
||||||
|
<imports>
|
||||||
|
<!-- Import Alfresco Dictionary Definitions -->
|
||||||
|
<import uri="http://www.alfresco.org/model/dictionary/1.0" prefix="d"/>
|
||||||
|
<!-- Import Alfresco Content Domain Model Definitions -->
|
||||||
|
<import uri="http://www.alfresco.org/model/content/1.0" prefix="cm"/>
|
||||||
|
</imports>
|
||||||
|
|
||||||
|
<namespaces>
|
||||||
|
<namespace uri="http://www.alfresco.org/model/bpm/1.0" prefix="bpm"/>
|
||||||
|
</namespaces>
|
||||||
|
|
||||||
|
<constraints>
|
||||||
|
|
||||||
|
<constraint name="bpm:allowedPriority" type="LIST">
|
||||||
|
<parameter name="allowedValues">
|
||||||
|
<!-- TODO: Determine if priority values can be mapped to human-readable strings -->
|
||||||
|
<list>
|
||||||
|
<value>1</value>
|
||||||
|
<value>2</value>
|
||||||
|
<value>3</value>
|
||||||
|
</list>
|
||||||
|
</parameter>
|
||||||
|
</constraint>
|
||||||
|
|
||||||
|
<constraint name="bpm:allowedStatus" type="LIST">
|
||||||
|
<parameter name="allowedValues">
|
||||||
|
<!-- TODO: Determine if status values can be mapped to human-readable strings -->
|
||||||
|
<list>
|
||||||
|
<value>Not Yet Started</value>
|
||||||
|
<value>In Progress</value>
|
||||||
|
<value>On Hold</value>
|
||||||
|
<value>Cancelled</value>
|
||||||
|
<value>Completed</value>
|
||||||
|
</list>
|
||||||
|
</parameter>
|
||||||
|
</constraint>
|
||||||
|
|
||||||
|
<constraint name="bpm:percentage" type="MINMAX">
|
||||||
|
<parameter name="minValue"><value>0</value></parameter>
|
||||||
|
<parameter name="maxValue"><value>100</value></parameter>
|
||||||
|
</constraint>
|
||||||
|
|
||||||
|
</constraints>
|
||||||
|
|
||||||
|
<types>
|
||||||
|
|
||||||
|
<!-- -->
|
||||||
|
<!-- Base definition for all Tasks -->
|
||||||
|
<!-- -->
|
||||||
|
|
||||||
|
<type name="bpm:task">
|
||||||
|
<title>Task</title>
|
||||||
|
<description>Task</description>
|
||||||
|
<parent>cm:content</parent>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
|
||||||
|
<!-- -->
|
||||||
|
<!-- Assignment -->
|
||||||
|
<!-- -->
|
||||||
|
<!-- Note: Implemented via cm:ownable aspect -->
|
||||||
|
|
||||||
|
<!-- -->
|
||||||
|
<!-- Task Identifier -->
|
||||||
|
<!-- -->
|
||||||
|
<property name="bpm:taskId">
|
||||||
|
<title>Task Identifier</title>
|
||||||
|
<type>d:long</type>
|
||||||
|
<protected>true</protected>
|
||||||
|
</property>
|
||||||
|
|
||||||
|
<!-- -->
|
||||||
|
<!-- Task Dates -->
|
||||||
|
<!-- -->
|
||||||
|
<property name="bpm:startDate">
|
||||||
|
<title>Start Date</title>
|
||||||
|
<type>d:date</type>
|
||||||
|
<protected>true</protected>
|
||||||
|
</property>
|
||||||
|
<property name="bpm:completionDate">
|
||||||
|
<title>End Date</title>
|
||||||
|
<type>d:date</type>
|
||||||
|
<protected>true</protected>
|
||||||
|
</property>
|
||||||
|
<property name="bpm:dueDate">
|
||||||
|
<title>Due Date</title>
|
||||||
|
<type>d:date</type>
|
||||||
|
</property>
|
||||||
|
|
||||||
|
<!-- -->
|
||||||
|
<!-- Task Progress -->
|
||||||
|
<!-- -->
|
||||||
|
<property name="bpm:status">
|
||||||
|
<title>Status</title>
|
||||||
|
<type>d:text</type>
|
||||||
|
<protected>true</protected>
|
||||||
|
<constraints>
|
||||||
|
<constraint ref="bpm:allowedStatus"/>
|
||||||
|
</constraints>
|
||||||
|
</property>
|
||||||
|
<property name="bpm:priority">
|
||||||
|
<title>Priority</title>
|
||||||
|
<type>d:int</type>
|
||||||
|
<constraints>
|
||||||
|
<constraint ref="bpm:allowedPriority"/>
|
||||||
|
</constraints>
|
||||||
|
</property>
|
||||||
|
<property name="bpm:percentComplete">
|
||||||
|
<title>Percentage Complete</title>
|
||||||
|
<type>d:int</type>
|
||||||
|
<constraints>
|
||||||
|
<constraint ref="bpm:percentage"/>
|
||||||
|
</constraints>
|
||||||
|
</property>
|
||||||
|
|
||||||
|
<!-- -->
|
||||||
|
<!-- Task Notes -->
|
||||||
|
<!-- -->
|
||||||
|
<!-- Note: Implemented via cm:content property : see 'fm:post' -->
|
||||||
|
|
||||||
|
</properties>
|
||||||
|
|
||||||
|
<associations>
|
||||||
|
|
||||||
|
<!-- List of users who may potentially get assigned to the task -->
|
||||||
|
<association name="bpm:pooledActors">
|
||||||
|
<title>Pooled Users</title>
|
||||||
|
<source>
|
||||||
|
<mandatory>false</mandatory>
|
||||||
|
<many>false</many>
|
||||||
|
</source>
|
||||||
|
<target>
|
||||||
|
<class>cm:person</class>
|
||||||
|
<mandatory>false</mandatory>
|
||||||
|
<many>true</many>
|
||||||
|
</target>
|
||||||
|
</association>
|
||||||
|
|
||||||
|
</associations>
|
||||||
|
|
||||||
|
<mandatory-aspects>
|
||||||
|
<aspect>cm:ownable</aspect>
|
||||||
|
</mandatory-aspects>
|
||||||
|
</type>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- -->
|
||||||
|
<!-- The base for all Ad-hoc Tasks as created by Users -->
|
||||||
|
<!-- -->
|
||||||
|
|
||||||
|
<type name="bpm:adhocTask">
|
||||||
|
<title>Ad-hoc Task</title>
|
||||||
|
<description>Task assigned by User</description>
|
||||||
|
<parent>bpm:task</parent>
|
||||||
|
|
||||||
|
<mandatory-aspects>
|
||||||
|
<aspect>cm:attachable</aspect>
|
||||||
|
</mandatory-aspects>
|
||||||
|
</type>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- -->
|
||||||
|
<!-- The base for all Tasks assigned via a Workflow -->
|
||||||
|
<!-- -->
|
||||||
|
|
||||||
|
<type name="bpm:workflowTask">
|
||||||
|
<title>Workflow Task</title>
|
||||||
|
<description>Task assigned via Workflow</description>
|
||||||
|
<parent>bpm:task</parent>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
|
||||||
|
<!-- -->
|
||||||
|
<!-- Task Context -->
|
||||||
|
<!-- e.g. Space, Document -->
|
||||||
|
<!-- -->
|
||||||
|
<property name="bpm:context">
|
||||||
|
<title>Task Context</title>
|
||||||
|
<type>d:noderef</type>
|
||||||
|
</property>
|
||||||
|
|
||||||
|
</properties>
|
||||||
|
|
||||||
|
<associations>
|
||||||
|
|
||||||
|
<association name="bpm:package">
|
||||||
|
<title>Workflow Package</title>
|
||||||
|
<source>
|
||||||
|
<mandatory>false</mandatory>
|
||||||
|
<many>false</many>
|
||||||
|
</source>
|
||||||
|
<target>
|
||||||
|
<class>bpm:workflowPackage</class>
|
||||||
|
<mandatory>true</mandatory>
|
||||||
|
<many>false</many>
|
||||||
|
</target>
|
||||||
|
</association>
|
||||||
|
|
||||||
|
</associations>
|
||||||
|
|
||||||
|
</type>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- -->
|
||||||
|
<!-- An Alfresco Space for managing ad-hoc Tasks -->
|
||||||
|
<!-- -->
|
||||||
|
|
||||||
|
<type name="bpm:taskspace">
|
||||||
|
<title>Task Space</title>
|
||||||
|
<parent>cm:folder</parent>
|
||||||
|
</type>
|
||||||
|
|
||||||
|
</types>
|
||||||
|
|
||||||
|
<aspects>
|
||||||
|
|
||||||
|
<!-- -->
|
||||||
|
<!-- A collection of content routed through a workflow. -->
|
||||||
|
<!-- -->
|
||||||
|
<!-- Note: this aspect should be applied to a container such as -->
|
||||||
|
<!-- a folder, versioned folder or layered folder. -->
|
||||||
|
<!-- -->
|
||||||
|
|
||||||
|
<aspect name="bpm:workflowPackage">
|
||||||
|
<title>Workflow Package</title>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
|
||||||
|
<!-- Items within package that have been marked as complete -->
|
||||||
|
<property name="bpm:completedItems">
|
||||||
|
<type>d:noderef</type>
|
||||||
|
<multiple>true</multiple>
|
||||||
|
</property>
|
||||||
|
|
||||||
|
<!-- TODO: Define properties (replicated from Workflow/Task Engine) for -->
|
||||||
|
<!-- search within Alfresco e.g. task info, workflow info ... -->
|
||||||
|
|
||||||
|
</properties>
|
||||||
|
|
||||||
|
<!-- Commentary -->
|
||||||
|
<!-- Note: Implement tracking of comments via fm:discussable aspect -->
|
||||||
|
<!-- Note: Haven't made this aspect mandatory as this would force creation -->
|
||||||
|
<!-- of forum folder against each package, even if there aren't any -->
|
||||||
|
<!-- comments -->
|
||||||
|
|
||||||
|
</aspect>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- Capability for adding a task management space to any entity in the system, -->
|
||||||
|
<!-- in particular, folders and content -->
|
||||||
|
|
||||||
|
<aspect name="bpm:tasks">
|
||||||
|
<associations>
|
||||||
|
<child-association name="bpm:tasks">
|
||||||
|
<source>
|
||||||
|
<mandatory>false</mandatory>
|
||||||
|
<many>false</many>
|
||||||
|
</source>
|
||||||
|
<target>
|
||||||
|
<class>bpm:taskspace</class>
|
||||||
|
<mandatory>true</mandatory>
|
||||||
|
<many>false</many>
|
||||||
|
</target>
|
||||||
|
<duplicate>false</duplicate>
|
||||||
|
</child-association>
|
||||||
|
</associations>
|
||||||
|
</aspect>
|
||||||
|
|
||||||
|
</aspects>
|
||||||
|
|
||||||
|
</model>
|
@@ -3,6 +3,18 @@
|
|||||||
|
|
||||||
<beans>
|
<beans>
|
||||||
|
|
||||||
|
<!-- -->
|
||||||
|
<!-- Workflow Model -->
|
||||||
|
<!-- -->
|
||||||
|
|
||||||
|
<bean id="workflow.dictionaryBootstrap" parent="dictionaryModelBootstrap" depends-on="dictionaryBootstrap">
|
||||||
|
<property name="models">
|
||||||
|
<list>
|
||||||
|
<value>alfresco/model/bpmModel.xml</value>
|
||||||
|
</list>
|
||||||
|
</property>
|
||||||
|
</bean>
|
||||||
|
|
||||||
<!-- -->
|
<!-- -->
|
||||||
<!-- Workflow Service Implementation -->
|
<!-- Workflow Service Implementation -->
|
||||||
<!-- -->
|
<!-- -->
|
||||||
|
@@ -70,6 +70,25 @@ public interface TaskComponent
|
|||||||
*/
|
*/
|
||||||
public WorkflowTask updateTask(String taskId, Map<QName, Serializable> properties, Map<QName, List<NodeRef>> add, Map<QName, List<NodeRef>> remove);
|
public WorkflowTask updateTask(String taskId, Map<QName, Serializable> properties, Map<QName, List<NodeRef>> add, Map<QName, List<NodeRef>> remove);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Start the specified Task
|
||||||
|
*
|
||||||
|
* Note: this is an optional task operation. It may be used to track
|
||||||
|
* when work started on a task as well as resume a suspended task.
|
||||||
|
*
|
||||||
|
* @param taskId the task to start
|
||||||
|
* @return the updated task
|
||||||
|
*/
|
||||||
|
public WorkflowTask startTask(String taskId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Suspend the specified Task
|
||||||
|
*
|
||||||
|
* @param taskId
|
||||||
|
* @return the update task
|
||||||
|
*/
|
||||||
|
public WorkflowTask suspendTask(String taskId);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* End the Task (i.e. complete the task)
|
* End the Task (i.e. complete the task)
|
||||||
*
|
*
|
||||||
|
45
source/java/org/alfresco/repo/workflow/WorkflowModel.java
Normal file
45
source/java/org/alfresco/repo/workflow/WorkflowModel.java
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2005 Alfresco, Inc.
|
||||||
|
*
|
||||||
|
* Licensed under the Mozilla Public License version 1.1
|
||||||
|
* with a permitted attribution clause. You may obtain a
|
||||||
|
* copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.alfresco.org/legal/license.txt
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing,
|
||||||
|
* software distributed under the License is distributed on an
|
||||||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
|
||||||
|
* either express or implied. See the License for the specific
|
||||||
|
* language governing permissions and limitations under the
|
||||||
|
* License.
|
||||||
|
*/
|
||||||
|
package org.alfresco.repo.workflow;
|
||||||
|
|
||||||
|
import org.alfresco.service.namespace.NamespaceService;
|
||||||
|
import org.alfresco.service.namespace.QName;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Workflow Model Constants
|
||||||
|
*/
|
||||||
|
public interface WorkflowModel
|
||||||
|
{
|
||||||
|
|
||||||
|
// task constants
|
||||||
|
static final QName TYPE_TASK = QName.createQName(NamespaceService.BPM_MODEL_1_0_URI, "task");
|
||||||
|
static final QName PROP_TASK_ID = QName.createQName(NamespaceService.BPM_MODEL_1_0_URI, "taskId");
|
||||||
|
static final QName PROP_START_DATE = QName.createQName(NamespaceService.BPM_MODEL_1_0_URI, "startDate");
|
||||||
|
static final QName PROP_DUE_DATE = QName.createQName(NamespaceService.BPM_MODEL_1_0_URI, "dueDate");
|
||||||
|
static final QName PROP_COMPLETION_DATE = QName.createQName(NamespaceService.BPM_MODEL_1_0_URI, "completionDate");
|
||||||
|
static final QName PROP_PRIORITY = QName.createQName(NamespaceService.BPM_MODEL_1_0_URI, "priority");
|
||||||
|
static final QName PROP_STATUS = QName.createQName(NamespaceService.BPM_MODEL_1_0_URI, "status");
|
||||||
|
static final QName PROP_PERCENT_COMPLETE = QName.createQName(NamespaceService.BPM_MODEL_1_0_URI, "percentComplete");
|
||||||
|
static final QName ASSOC_POOLED_ACTORS = QName.createQName(NamespaceService.BPM_MODEL_1_0_URI, "pooledActors");
|
||||||
|
|
||||||
|
// workflow task contstants
|
||||||
|
static final QName TYPE_WORKFLOW_TASK = QName.createQName(NamespaceService.BPM_MODEL_1_0_URI, "workflowTask");
|
||||||
|
static final QName PROP_CONTEXT = QName.createQName(NamespaceService.BPM_MODEL_1_0_URI, "context");
|
||||||
|
static final QName ASSOC_PACKAGE = QName.createQName(NamespaceService.BPM_MODEL_1_0_URI, "package");
|
||||||
|
|
||||||
|
}
|
@@ -19,17 +19,28 @@ package org.alfresco.repo.workflow.jbpm;
|
|||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
import java.util.Map.Entry;
|
import java.util.Map.Entry;
|
||||||
|
|
||||||
|
import org.alfresco.model.ContentModel;
|
||||||
import org.alfresco.repo.security.authentication.AuthenticationUtil;
|
import org.alfresco.repo.security.authentication.AuthenticationUtil;
|
||||||
import org.alfresco.repo.workflow.BPMEngine;
|
import org.alfresco.repo.workflow.BPMEngine;
|
||||||
import org.alfresco.repo.workflow.TaskComponent;
|
import org.alfresco.repo.workflow.TaskComponent;
|
||||||
import org.alfresco.repo.workflow.WorkflowComponent;
|
import org.alfresco.repo.workflow.WorkflowComponent;
|
||||||
import org.alfresco.repo.workflow.WorkflowDefinitionComponent;
|
import org.alfresco.repo.workflow.WorkflowDefinitionComponent;
|
||||||
|
import org.alfresco.repo.workflow.WorkflowModel;
|
||||||
|
import org.alfresco.service.cmr.dictionary.AspectDefinition;
|
||||||
|
import org.alfresco.service.cmr.dictionary.AssociationDefinition;
|
||||||
import org.alfresco.service.cmr.dictionary.DictionaryService;
|
import org.alfresco.service.cmr.dictionary.DictionaryService;
|
||||||
|
import org.alfresco.service.cmr.dictionary.PropertyDefinition;
|
||||||
|
import org.alfresco.service.cmr.dictionary.TypeDefinition;
|
||||||
import org.alfresco.service.cmr.repository.NodeRef;
|
import org.alfresco.service.cmr.repository.NodeRef;
|
||||||
|
import org.alfresco.service.cmr.repository.NodeService;
|
||||||
|
import org.alfresco.service.cmr.security.PersonService;
|
||||||
import org.alfresco.service.cmr.workflow.WorkflowDefinition;
|
import org.alfresco.service.cmr.workflow.WorkflowDefinition;
|
||||||
import org.alfresco.service.cmr.workflow.WorkflowException;
|
import org.alfresco.service.cmr.workflow.WorkflowException;
|
||||||
import org.alfresco.service.cmr.workflow.WorkflowInstance;
|
import org.alfresco.service.cmr.workflow.WorkflowInstance;
|
||||||
@@ -43,7 +54,6 @@ import org.alfresco.service.namespace.QName;
|
|||||||
import org.hibernate.proxy.HibernateProxy;
|
import org.hibernate.proxy.HibernateProxy;
|
||||||
import org.jbpm.JbpmContext;
|
import org.jbpm.JbpmContext;
|
||||||
import org.jbpm.JbpmException;
|
import org.jbpm.JbpmException;
|
||||||
import org.jbpm.context.exe.ContextInstance;
|
|
||||||
import org.jbpm.db.GraphSession;
|
import org.jbpm.db.GraphSession;
|
||||||
import org.jbpm.db.TaskMgmtSession;
|
import org.jbpm.db.TaskMgmtSession;
|
||||||
import org.jbpm.graph.def.Node;
|
import org.jbpm.graph.def.Node;
|
||||||
@@ -72,6 +82,8 @@ public class JBPMEngine extends BPMEngine
|
|||||||
// Implementation dependencies
|
// Implementation dependencies
|
||||||
protected DictionaryService dictionaryService;
|
protected DictionaryService dictionaryService;
|
||||||
protected NamespaceService namespaceService;
|
protected NamespaceService namespaceService;
|
||||||
|
protected NodeService nodeService;
|
||||||
|
protected PersonService personService;
|
||||||
private JbpmTemplate jbpmTemplate;
|
private JbpmTemplate jbpmTemplate;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -104,6 +116,26 @@ public class JBPMEngine extends BPMEngine
|
|||||||
this.namespaceService = namespaceService;
|
this.namespaceService = namespaceService;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the Node Service
|
||||||
|
*
|
||||||
|
* @param nodeService
|
||||||
|
*/
|
||||||
|
public void setNodeService(NodeService nodeService)
|
||||||
|
{
|
||||||
|
this.nodeService = nodeService;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the Person Service
|
||||||
|
*
|
||||||
|
* @param personService
|
||||||
|
*/
|
||||||
|
public void setPersonService(PersonService personService)
|
||||||
|
{
|
||||||
|
this.personService = personService;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Workflow Definition...
|
// Workflow Definition...
|
||||||
@@ -114,8 +146,8 @@ public class JBPMEngine extends BPMEngine
|
|||||||
*/
|
*/
|
||||||
public WorkflowDefinition deployDefinition(InputStream workflowDefinition)
|
public WorkflowDefinition deployDefinition(InputStream workflowDefinition)
|
||||||
{
|
{
|
||||||
// TODO Auto-generated method stub
|
// TODO
|
||||||
return null;
|
throw new UnsupportedOperationException();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* (non-Javadoc)
|
/* (non-Javadoc)
|
||||||
@@ -123,8 +155,8 @@ public class JBPMEngine extends BPMEngine
|
|||||||
*/
|
*/
|
||||||
public void undeployDefinition(String workflowDefinitionId)
|
public void undeployDefinition(String workflowDefinitionId)
|
||||||
{
|
{
|
||||||
// TODO Auto-generated method stub
|
// TODO
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* (non-Javadoc)
|
/* (non-Javadoc)
|
||||||
@@ -465,10 +497,121 @@ public class JBPMEngine extends BPMEngine
|
|||||||
/* (non-Javadoc)
|
/* (non-Javadoc)
|
||||||
* @see org.alfresco.repo.workflow.TaskComponent#updateTask(java.lang.String, java.util.Map, java.util.Map, java.util.Map)
|
* @see org.alfresco.repo.workflow.TaskComponent#updateTask(java.lang.String, java.util.Map, java.util.Map, java.util.Map)
|
||||||
*/
|
*/
|
||||||
public WorkflowTask updateTask(String taskId, Map<QName, Serializable> properties, Map<QName, List<NodeRef>> add, Map<QName, List<NodeRef>> remove)
|
public WorkflowTask updateTask(final String taskId, final Map<QName, Serializable> properties, final Map<QName, List<NodeRef>> add, final Map<QName, List<NodeRef>> remove)
|
||||||
{
|
{
|
||||||
// TODO
|
try
|
||||||
throw new UnsupportedOperationException();
|
{
|
||||||
|
return (WorkflowTask) jbpmTemplate.execute(new JbpmCallback()
|
||||||
|
{
|
||||||
|
public Object doInJbpm(JbpmContext context)
|
||||||
|
{
|
||||||
|
// retrieve task
|
||||||
|
TaskMgmtSession taskSession = context.getTaskMgmtSession();
|
||||||
|
TaskInstance taskInstance = taskSession.loadTaskInstance(getJbpmId(taskId));
|
||||||
|
|
||||||
|
// create properties to set on task instance
|
||||||
|
Map<QName, Serializable> newProperties = properties;
|
||||||
|
if (newProperties == null && (add != null || remove != null))
|
||||||
|
{
|
||||||
|
newProperties = new HashMap<QName, Serializable>(10);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (add != null || remove != null)
|
||||||
|
{
|
||||||
|
Map<QName, Serializable> existingProperties = getTaskProperties(taskInstance);
|
||||||
|
|
||||||
|
if (add != null)
|
||||||
|
{
|
||||||
|
// add new associations
|
||||||
|
for (Entry<QName, List<NodeRef>> toAdd : add.entrySet())
|
||||||
|
{
|
||||||
|
// retrieve existing list of noderefs for association
|
||||||
|
List<NodeRef> existingAdd = (List<NodeRef>)newProperties.get(toAdd.getKey());
|
||||||
|
if (existingAdd == null)
|
||||||
|
{
|
||||||
|
existingAdd = (List<NodeRef>)existingProperties.get(toAdd.getKey());
|
||||||
|
}
|
||||||
|
|
||||||
|
// make the additions
|
||||||
|
if (existingAdd == null)
|
||||||
|
{
|
||||||
|
newProperties.put(toAdd.getKey(), (Serializable)toAdd.getValue());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (NodeRef nodeRef : (List<NodeRef>)toAdd.getValue())
|
||||||
|
{
|
||||||
|
if (!(existingAdd.contains(nodeRef)))
|
||||||
|
{
|
||||||
|
existingAdd.add(nodeRef);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (remove != null)
|
||||||
|
{
|
||||||
|
// add new associations
|
||||||
|
for (Entry<QName, List<NodeRef>> toRemove: remove.entrySet())
|
||||||
|
{
|
||||||
|
// retrieve existing list of noderefs for association
|
||||||
|
List<NodeRef> existingRemove = (List<NodeRef>)newProperties.get(toRemove.getKey());
|
||||||
|
if (existingRemove == null)
|
||||||
|
{
|
||||||
|
existingRemove = (List<NodeRef>)existingProperties.get(toRemove.getKey());
|
||||||
|
}
|
||||||
|
|
||||||
|
// make the subtractions
|
||||||
|
if (existingRemove != null)
|
||||||
|
{
|
||||||
|
for (NodeRef nodeRef : (List<NodeRef>)toRemove.getValue())
|
||||||
|
{
|
||||||
|
existingRemove.remove(nodeRef);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// update the task
|
||||||
|
if (newProperties != null)
|
||||||
|
{
|
||||||
|
setTaskProperties(taskInstance, newProperties);
|
||||||
|
|
||||||
|
// save
|
||||||
|
ProcessInstance processInstance = taskInstance.getToken().getProcessInstance();
|
||||||
|
context.save(processInstance);
|
||||||
|
}
|
||||||
|
|
||||||
|
// note: the ending of a task may not have signalled (i.e. more than one task exists at
|
||||||
|
// this node)
|
||||||
|
return createWorkflowTask(taskInstance);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
catch(JbpmException e)
|
||||||
|
{
|
||||||
|
throw new WorkflowException("Failed to update workflow task '" + taskId + "'", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* (non-Javadoc)
|
||||||
|
* @see org.alfresco.repo.workflow.TaskComponent#startTask(java.lang.String)
|
||||||
|
*/
|
||||||
|
public WorkflowTask startTask(String taskId)
|
||||||
|
{
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* (non-Javadoc)
|
||||||
|
* @see org.alfresco.repo.workflow.TaskComponent#suspendTask(java.lang.String)
|
||||||
|
*/
|
||||||
|
public WorkflowTask suspendTask(String taskId)
|
||||||
|
{
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* (non-Javadoc)
|
/* (non-Javadoc)
|
||||||
@@ -526,45 +669,51 @@ public class JBPMEngine extends BPMEngine
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets Properties of Task
|
|
||||||
*
|
|
||||||
* @param instance task instance
|
|
||||||
* @param properties properties to set
|
|
||||||
*/
|
|
||||||
protected void setTaskProperties(TaskInstance instance, Map<QName, Serializable> properties)
|
|
||||||
{
|
|
||||||
if (properties == null)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: Use Dictionary to drive mapping
|
|
||||||
|
|
||||||
// TODO: Determine if NodeRefs and collection of NodeRefs need to be converted to String
|
|
||||||
|
|
||||||
ContextInstance context = instance.getContextInstance();
|
|
||||||
for (Entry<QName, Serializable> entry : properties.entrySet())
|
|
||||||
{
|
|
||||||
String name = null;
|
|
||||||
QName qname = entry.getKey();
|
|
||||||
if (qname.getNamespaceURI().equals(NamespaceService.DEFAULT_URI))
|
|
||||||
{
|
|
||||||
name = qname.getLocalName();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
name = qname.toPrefixString(namespaceService);
|
|
||||||
}
|
|
||||||
context.setVariable(name, entry.getValue());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Helpers...
|
// Helpers...
|
||||||
//
|
//
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the Task definition of the specified Task
|
||||||
|
*
|
||||||
|
* @param task the task
|
||||||
|
* @return the task definition
|
||||||
|
*/
|
||||||
|
private TypeDefinition getTaskDefinition(Task task)
|
||||||
|
{
|
||||||
|
// TODO: Extend jBPM task instance to include dictionary definition qname?
|
||||||
|
QName typeName = QName.createQName(task.getName(), namespaceService);
|
||||||
|
TypeDefinition typeDef = dictionaryService.getType(typeName);
|
||||||
|
if (typeDef == null)
|
||||||
|
{
|
||||||
|
typeDef = dictionaryService.getType(WorkflowModel.TYPE_WORKFLOW_TASK);
|
||||||
|
if (typeDef == null)
|
||||||
|
{
|
||||||
|
throw new WorkflowException("Failed to find type definition '" + WorkflowModel.TYPE_WORKFLOW_TASK + "'");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return typeDef;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert the specified Type definition to an anonymous Type definition.
|
||||||
|
*
|
||||||
|
* This collapses all mandatory aspects into a single Type definition.
|
||||||
|
*
|
||||||
|
* @param typeDef the type definition
|
||||||
|
* @return the anonymous type definition
|
||||||
|
*/
|
||||||
|
private TypeDefinition getAnonymousTaskDefinition(TypeDefinition typeDef)
|
||||||
|
{
|
||||||
|
List<AspectDefinition> aspects = typeDef.getDefaultAspects();
|
||||||
|
List<QName> aspectNames = new ArrayList<QName>(aspects.size());
|
||||||
|
for (AspectDefinition aspect : aspects)
|
||||||
|
{
|
||||||
|
aspectNames.add(aspect.getName());
|
||||||
|
}
|
||||||
|
return dictionaryService.getAnonymousType(typeDef.getName(), aspectNames);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get JBoss JBPM Id from Engine Global Id
|
* Get JBoss JBPM Id from Engine Global Id
|
||||||
@@ -612,6 +761,214 @@ public class JBPMEngine extends BPMEngine
|
|||||||
return token;
|
return token;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets Properties of Task
|
||||||
|
*
|
||||||
|
* @param instance task instance
|
||||||
|
* @param properties properties to set
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
protected Map<QName, Serializable> getTaskProperties(TaskInstance instance)
|
||||||
|
{
|
||||||
|
// establish task definition
|
||||||
|
TypeDefinition taskDef = getAnonymousTaskDefinition(getTaskDefinition(instance.getTask()));
|
||||||
|
Map<QName, AssociationDefinition> taskAssocs = taskDef.getAssociations();
|
||||||
|
|
||||||
|
// map arbitrary task variables
|
||||||
|
Map<QName, Serializable> properties = new HashMap<QName, Serializable>(10);
|
||||||
|
Map<String, Object> vars = instance.getVariablesLocally();
|
||||||
|
for (Entry<String, Object> entry : vars.entrySet())
|
||||||
|
{
|
||||||
|
String key = entry.getKey();
|
||||||
|
Object value = entry.getValue();
|
||||||
|
|
||||||
|
// perform data conversions
|
||||||
|
// NOTE: Only convert Authority name to NodeRef for now
|
||||||
|
QName qname = QName.createQName(key);
|
||||||
|
AssociationDefinition assocDef = taskAssocs.get(qname);
|
||||||
|
if (assocDef != null && assocDef.getTargetClass().equals(ContentModel.TYPE_PERSON))
|
||||||
|
{
|
||||||
|
// TODO: Also support group authorities
|
||||||
|
if (!(value instanceof String[]))
|
||||||
|
{
|
||||||
|
throw new WorkflowException("Task variable '" + qname + "' value is invalid format");
|
||||||
|
}
|
||||||
|
value = mapNameToAuthority((String[])value);
|
||||||
|
}
|
||||||
|
|
||||||
|
// place task variable in map to return
|
||||||
|
properties.put(qname, (Serializable)value);
|
||||||
|
}
|
||||||
|
|
||||||
|
// map jBPM task instance fields to properties
|
||||||
|
properties.put(WorkflowModel.PROP_TASK_ID, instance.getId());
|
||||||
|
properties.put(WorkflowModel.PROP_START_DATE, instance.getStart());
|
||||||
|
properties.put(WorkflowModel.PROP_DUE_DATE, instance.getDueDate());
|
||||||
|
properties.put(WorkflowModel.PROP_COMPLETION_DATE, instance.getEnd());
|
||||||
|
properties.put(WorkflowModel.PROP_PRIORITY, instance.getPriority());
|
||||||
|
properties.put(ContentModel.PROP_OWNER, instance.getActorId());
|
||||||
|
|
||||||
|
// map jBPM task instance collections to associations
|
||||||
|
Set pooledActors = instance.getPooledActors();
|
||||||
|
if (pooledActors != null)
|
||||||
|
{
|
||||||
|
String[] pooledActorIds = new String[pooledActors.size()];
|
||||||
|
pooledActors.toArray(pooledActorIds);
|
||||||
|
List<NodeRef> pooledActorNodeRefs = mapNameToAuthority(pooledActorIds);
|
||||||
|
properties.put(WorkflowModel.ASSOC_POOLED_ACTORS, (Serializable)pooledActorNodeRefs);
|
||||||
|
}
|
||||||
|
|
||||||
|
return properties;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets Properties of Task
|
||||||
|
*
|
||||||
|
* @param instance task instance
|
||||||
|
* @param properties properties to set
|
||||||
|
*/
|
||||||
|
protected void setTaskProperties(TaskInstance instance, Map<QName, Serializable> properties)
|
||||||
|
{
|
||||||
|
if (properties == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// establish task definition
|
||||||
|
TypeDefinition taskDef = getAnonymousTaskDefinition(getTaskDefinition(instance.getTask()));
|
||||||
|
Map<QName, PropertyDefinition> taskProperties = taskDef.getProperties();
|
||||||
|
Map<QName, AssociationDefinition> taskAssocs = taskDef.getAssociations();
|
||||||
|
|
||||||
|
// map each parameter to task
|
||||||
|
for (Entry<QName, Serializable> entry : properties.entrySet())
|
||||||
|
{
|
||||||
|
QName key = entry.getKey();
|
||||||
|
Serializable value = entry.getValue();
|
||||||
|
|
||||||
|
// determine if writing property
|
||||||
|
// NOTE: some properties map to fields on jBPM task instance whilst
|
||||||
|
// others are set in the general variable bag on the task
|
||||||
|
PropertyDefinition propDef = taskProperties.get(key);
|
||||||
|
if (propDef != null)
|
||||||
|
{
|
||||||
|
if (propDef.isProtected())
|
||||||
|
{
|
||||||
|
// NOTE: only write non-protected properties
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// map property to specific jBPM task instance field
|
||||||
|
if (key.equals(WorkflowModel.PROP_DUE_DATE))
|
||||||
|
{
|
||||||
|
if (!(value instanceof Date))
|
||||||
|
{
|
||||||
|
throw new WorkflowException("Task due date '" + value + "' is invalid");
|
||||||
|
}
|
||||||
|
instance.setDueDate((Date)value);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else if (key.equals(WorkflowModel.PROP_PRIORITY))
|
||||||
|
{
|
||||||
|
if (!(value instanceof Integer))
|
||||||
|
{
|
||||||
|
throw new WorkflowException("Task priority '" + value + "' is invalid");
|
||||||
|
}
|
||||||
|
instance.setPriority((Integer)value);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else if (key.equals(ContentModel.PROP_OWNER))
|
||||||
|
{
|
||||||
|
if (!(value instanceof String))
|
||||||
|
{
|
||||||
|
throw new WorkflowException("Task owner '" + value + "' is invalid");
|
||||||
|
}
|
||||||
|
instance.setActorId((String)value);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// determine if writing association
|
||||||
|
AssociationDefinition assocDef = taskAssocs.get(key);
|
||||||
|
if (assocDef != null)
|
||||||
|
{
|
||||||
|
// if association is to people, map them to authority names
|
||||||
|
// TODO: support group authorities
|
||||||
|
if (assocDef.getTargetClass().equals(ContentModel.TYPE_PERSON))
|
||||||
|
{
|
||||||
|
value = mapAuthorityToName((List<NodeRef>)value);
|
||||||
|
}
|
||||||
|
|
||||||
|
// map association to specific jBPM task instance field
|
||||||
|
if (key.equals(WorkflowModel.ASSOC_POOLED_ACTORS))
|
||||||
|
{
|
||||||
|
instance.setPooledActors((String[])value);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// no specific mapping to jBPM task has been established, so place into
|
||||||
|
// the generic task variable bag
|
||||||
|
String name = null;
|
||||||
|
if (key.getNamespaceURI().equals(NamespaceService.DEFAULT_URI))
|
||||||
|
{
|
||||||
|
name = key.getLocalName();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
name = key.toString();
|
||||||
|
}
|
||||||
|
instance.setVariableLocally(name, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert a list of Alfresco Authorities to a list of authority Names
|
||||||
|
*
|
||||||
|
* @param authorities the authorities to convert
|
||||||
|
* @return the authority names
|
||||||
|
*/
|
||||||
|
private String[] mapAuthorityToName(List<NodeRef> authorities)
|
||||||
|
{
|
||||||
|
String[] names = null;
|
||||||
|
if (authorities != null)
|
||||||
|
{
|
||||||
|
names = new String[authorities.size()];
|
||||||
|
int i = 0;
|
||||||
|
for (NodeRef person : authorities)
|
||||||
|
{
|
||||||
|
String name = (String)nodeService.getProperty(person, ContentModel.PROP_USERNAME);
|
||||||
|
names[i++] = name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return names;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert a list of authority Names to Alfresco Authorities
|
||||||
|
*
|
||||||
|
* @param names the authority names to convert
|
||||||
|
* @return the Alfresco authorities
|
||||||
|
*/
|
||||||
|
private List<NodeRef> mapNameToAuthority(String[] names)
|
||||||
|
{
|
||||||
|
List<NodeRef> authorities = null;
|
||||||
|
if (names != null)
|
||||||
|
{
|
||||||
|
authorities = new ArrayList<NodeRef>(names.length);
|
||||||
|
for (String name : names)
|
||||||
|
{
|
||||||
|
// TODO: Should this be an exception?
|
||||||
|
if (personService.personExists(name))
|
||||||
|
{
|
||||||
|
authorities.add(personService.getPerson(name));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return authorities;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Workflow Data Object Creation...
|
// Workflow Data Object Creation...
|
||||||
@@ -714,9 +1071,7 @@ public class JBPMEngine extends BPMEngine
|
|||||||
workflowTask.path = createWorkflowPath(task.getToken());
|
workflowTask.path = createWorkflowPath(task.getToken());
|
||||||
workflowTask.state = getWorkflowTaskState(task);
|
workflowTask.state = getWorkflowTaskState(task);
|
||||||
workflowTask.definition = createWorkflowTaskDefinition(task.getTask());
|
workflowTask.definition = createWorkflowTaskDefinition(task.getTask());
|
||||||
|
workflowTask.properties = getTaskProperties(task);
|
||||||
// TODO: Properties and Associations
|
|
||||||
|
|
||||||
return workflowTask;
|
return workflowTask;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -728,11 +1083,9 @@ public class JBPMEngine extends BPMEngine
|
|||||||
*/
|
*/
|
||||||
protected WorkflowTaskDefinition createWorkflowTaskDefinition(Task task)
|
protected WorkflowTaskDefinition createWorkflowTaskDefinition(Task task)
|
||||||
{
|
{
|
||||||
// TODO: Extend jBPM task instance to include dictionary definition qname
|
|
||||||
WorkflowTaskDefinition taskDef = new WorkflowTaskDefinition();
|
WorkflowTaskDefinition taskDef = new WorkflowTaskDefinition();
|
||||||
taskDef.id = task.getName();
|
taskDef.id = task.getName();
|
||||||
QName typeName = QName.createQName(taskDef.id, namespaceService);
|
taskDef.metadata = getTaskDefinition(task);
|
||||||
taskDef.metadata = dictionaryService.getType(typeName);
|
|
||||||
return taskDef;
|
return taskDef;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -17,14 +17,19 @@
|
|||||||
package org.alfresco.repo.workflow.jbpm;
|
package org.alfresco.repo.workflow.jbpm;
|
||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Date;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.alfresco.model.ContentModel;
|
||||||
import org.alfresco.repo.workflow.BPMEngineRegistry;
|
import org.alfresco.repo.workflow.BPMEngineRegistry;
|
||||||
import org.alfresco.repo.workflow.TaskComponent;
|
import org.alfresco.repo.workflow.TaskComponent;
|
||||||
import org.alfresco.repo.workflow.WorkflowComponent;
|
import org.alfresco.repo.workflow.WorkflowComponent;
|
||||||
import org.alfresco.repo.workflow.WorkflowDefinitionComponent;
|
import org.alfresco.repo.workflow.WorkflowDefinitionComponent;
|
||||||
|
import org.alfresco.repo.workflow.WorkflowModel;
|
||||||
|
import org.alfresco.service.cmr.repository.NodeRef;
|
||||||
import org.alfresco.service.cmr.workflow.WorkflowDefinition;
|
import org.alfresco.service.cmr.workflow.WorkflowDefinition;
|
||||||
import org.alfresco.service.cmr.workflow.WorkflowException;
|
import org.alfresco.service.cmr.workflow.WorkflowException;
|
||||||
import org.alfresco.service.cmr.workflow.WorkflowInstance;
|
import org.alfresco.service.cmr.workflow.WorkflowInstance;
|
||||||
@@ -55,6 +60,8 @@ public class JBPMEngineTest extends BaseSpringTest
|
|||||||
workflowDefinitionComponent = registry.getWorkflowDefinitionComponent("jbpm");
|
workflowDefinitionComponent = registry.getWorkflowDefinitionComponent("jbpm");
|
||||||
workflowComponent = registry.getWorkflowComponent("jbpm");
|
workflowComponent = registry.getWorkflowComponent("jbpm");
|
||||||
taskComponent = registry.getTaskComponent("jbpm");
|
taskComponent = registry.getTaskComponent("jbpm");
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -97,6 +104,121 @@ public class JBPMEngineTest extends BaseSpringTest
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void testStartWorkflowParameters()
|
||||||
|
{
|
||||||
|
WorkflowDefinition workflowDef = getTestDefinition();
|
||||||
|
|
||||||
|
Map<QName, Serializable> params = new HashMap<QName, Serializable>();
|
||||||
|
params.put(WorkflowModel.PROP_TASK_ID, 3); // protected - shouldn't be written
|
||||||
|
params.put(WorkflowModel.PROP_DUE_DATE, new Date()); // task instance field
|
||||||
|
params.put(WorkflowModel.PROP_PRIORITY, 1); // task instance field
|
||||||
|
params.put(WorkflowModel.PROP_PERCENT_COMPLETE, 10); // context variable
|
||||||
|
params.put(QName.createQName("", "Message"), "Hello World"); // context variable outside of task definition
|
||||||
|
params.put(QName.createQName("", "Array"), new String[] { "one", "two" }); // context variable outside of task definition
|
||||||
|
params.put(QName.createQName("", "NodeRef"), new NodeRef("workspace://1/1001")); // context variable outside of task definition
|
||||||
|
params.put(ContentModel.PROP_OWNER, "admin"); // task assignment
|
||||||
|
|
||||||
|
WorkflowPath path = workflowComponent.startWorkflow(workflowDef.id, params);
|
||||||
|
assertNotNull(path);
|
||||||
|
assertTrue(path.id.endsWith("::/"));
|
||||||
|
assertNotNull(path.node);
|
||||||
|
assertNotNull(path.instance);
|
||||||
|
assertEquals(workflowDef.id, path.instance.definition.id);
|
||||||
|
List<WorkflowTask> tasks1 = workflowComponent.getTasksForWorkflowPath(path.id);
|
||||||
|
assertNotNull(tasks1);
|
||||||
|
assertEquals(1, tasks1.size());
|
||||||
|
|
||||||
|
WorkflowTask task = tasks1.get(0);
|
||||||
|
assertTrue(task.properties.containsKey(WorkflowModel.PROP_TASK_ID));
|
||||||
|
assertTrue(task.properties.containsKey(WorkflowModel.PROP_DUE_DATE));
|
||||||
|
assertTrue(task.properties.containsKey(WorkflowModel.PROP_PRIORITY));
|
||||||
|
assertTrue(task.properties.containsKey(WorkflowModel.PROP_PERCENT_COMPLETE));
|
||||||
|
assertTrue(task.properties.containsKey(ContentModel.PROP_OWNER));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void testUpdateTask()
|
||||||
|
{
|
||||||
|
WorkflowDefinition workflowDef = getTestDefinition();
|
||||||
|
|
||||||
|
Map<QName, Serializable> params = new HashMap<QName, Serializable>();
|
||||||
|
params.put(WorkflowModel.PROP_TASK_ID, 3); // protected - shouldn't be written
|
||||||
|
params.put(WorkflowModel.PROP_DUE_DATE, new Date()); // task instance field
|
||||||
|
params.put(WorkflowModel.PROP_PRIORITY, 1); // task instance field
|
||||||
|
params.put(WorkflowModel.PROP_PERCENT_COMPLETE, 10); // context variable
|
||||||
|
params.put(QName.createQName("", "Message"), "Hello World"); // context variable outside of task definition
|
||||||
|
params.put(QName.createQName("", "Array"), new String[] { "one", "two" }); // context variable outside of task definition
|
||||||
|
params.put(QName.createQName("", "NodeRef"), new NodeRef("workspace://1/1001")); // context variable outside of task definition
|
||||||
|
params.put(ContentModel.PROP_OWNER, "admin"); // task assignment
|
||||||
|
|
||||||
|
WorkflowPath path = workflowComponent.startWorkflow(workflowDef.id, params);
|
||||||
|
assertNotNull(path);
|
||||||
|
assertTrue(path.id.endsWith("::/"));
|
||||||
|
assertNotNull(path.node);
|
||||||
|
assertNotNull(path.instance);
|
||||||
|
assertEquals(workflowDef.id, path.instance.definition.id);
|
||||||
|
List<WorkflowTask> tasks1 = workflowComponent.getTasksForWorkflowPath(path.id);
|
||||||
|
assertNotNull(tasks1);
|
||||||
|
assertEquals(1, tasks1.size());
|
||||||
|
|
||||||
|
WorkflowTask task = tasks1.get(0);
|
||||||
|
assertTrue(task.properties.containsKey(WorkflowModel.PROP_TASK_ID));
|
||||||
|
assertTrue(task.properties.containsKey(WorkflowModel.PROP_DUE_DATE));
|
||||||
|
assertTrue(task.properties.containsKey(WorkflowModel.PROP_PRIORITY));
|
||||||
|
assertTrue(task.properties.containsKey(WorkflowModel.PROP_PERCENT_COMPLETE));
|
||||||
|
assertTrue(task.properties.containsKey(ContentModel.PROP_OWNER));
|
||||||
|
|
||||||
|
// update with null parameters
|
||||||
|
try
|
||||||
|
{
|
||||||
|
WorkflowTask taskU1 = taskComponent.updateTask(task.id, null, null, null);
|
||||||
|
assertNotNull(taskU1);
|
||||||
|
}
|
||||||
|
catch(Throwable e)
|
||||||
|
{
|
||||||
|
fail("Task update failed with null parameters");
|
||||||
|
}
|
||||||
|
|
||||||
|
// update property value
|
||||||
|
Map<QName, Serializable> updateProperties2 = new HashMap<QName, Serializable>();
|
||||||
|
updateProperties2.put(WorkflowModel.PROP_PERCENT_COMPLETE, 100);
|
||||||
|
WorkflowTask taskU2 = taskComponent.updateTask(task.id, updateProperties2, null, null);
|
||||||
|
assertEquals(100, taskU2.properties.get(WorkflowModel.PROP_PERCENT_COMPLETE));
|
||||||
|
|
||||||
|
// add to assocation
|
||||||
|
QName assocName = QName.createQName("", "TestAssoc");
|
||||||
|
List<NodeRef> toAdd = new ArrayList<NodeRef>();
|
||||||
|
toAdd.add(new NodeRef("workspace://1/1001"));
|
||||||
|
toAdd.add(new NodeRef("workspace://1/1002"));
|
||||||
|
toAdd.add(new NodeRef("workspace://1/1003"));
|
||||||
|
Map<QName, List<NodeRef>> addAssocs = new HashMap<QName, List<NodeRef>>();
|
||||||
|
addAssocs.put(assocName, toAdd);
|
||||||
|
WorkflowTask taskU3 = taskComponent.updateTask(task.id, null, addAssocs, null);
|
||||||
|
assertNotNull(taskU3.properties.get(assocName));
|
||||||
|
assertEquals(3, ((List<NodeRef>)taskU3.properties.get(assocName)).size());
|
||||||
|
|
||||||
|
// add to assocation again
|
||||||
|
List<NodeRef> toAddAgain = new ArrayList<NodeRef>();
|
||||||
|
toAddAgain.add(new NodeRef("workspace://1/1004"));
|
||||||
|
toAddAgain.add(new NodeRef("workspace://1/1005"));
|
||||||
|
Map<QName, List<NodeRef>> addAssocsAgain = new HashMap<QName, List<NodeRef>>();
|
||||||
|
addAssocsAgain.put(assocName, toAddAgain);
|
||||||
|
WorkflowTask taskU4 = taskComponent.updateTask(task.id, null, addAssocsAgain, null);
|
||||||
|
assertNotNull(taskU4.properties.get(assocName));
|
||||||
|
assertEquals(5, ((List<NodeRef>)taskU4.properties.get(assocName)).size());
|
||||||
|
|
||||||
|
// remove assocation
|
||||||
|
List<NodeRef> toRemove = new ArrayList<NodeRef>();
|
||||||
|
toRemove.add(new NodeRef("workspace://1/1002"));
|
||||||
|
toRemove.add(new NodeRef("workspace://1/1003"));
|
||||||
|
Map<QName, List<NodeRef>> removeAssocs = new HashMap<QName, List<NodeRef>>();
|
||||||
|
removeAssocs.put(assocName, toRemove);
|
||||||
|
WorkflowTask taskU5 = taskComponent.updateTask(task.id, null, null, removeAssocs);
|
||||||
|
assertNotNull(taskU5.properties.get(assocName));
|
||||||
|
assertEquals(3, ((List<NodeRef>)taskU5.properties.get(assocName)).size());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public void testGetWorkflowInstances()
|
public void testGetWorkflowInstances()
|
||||||
{
|
{
|
||||||
WorkflowDefinition workflowDef = getTestDefinition();
|
WorkflowDefinition workflowDef = getTestDefinition();
|
||||||
|
@@ -17,10 +17,8 @@
|
|||||||
package org.alfresco.service.cmr.workflow;
|
package org.alfresco.service.cmr.workflow;
|
||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import org.alfresco.service.cmr.repository.NodeRef;
|
|
||||||
import org.alfresco.service.namespace.QName;
|
import org.alfresco.service.namespace.QName;
|
||||||
|
|
||||||
|
|
||||||
@@ -51,16 +49,13 @@ public class WorkflowTask
|
|||||||
/** Task Properties as described by Task Definition */
|
/** Task Properties as described by Task Definition */
|
||||||
public Map<QName, Serializable> properties;
|
public Map<QName, Serializable> properties;
|
||||||
|
|
||||||
/** Task Associations as described by Task Definition */
|
|
||||||
public Map<QName, List<NodeRef>> associations;
|
|
||||||
|
|
||||||
|
|
||||||
/* (non-Javadoc)
|
/* (non-Javadoc)
|
||||||
* @see java.lang.Object#toString()
|
* @see java.lang.Object#toString()
|
||||||
*/
|
*/
|
||||||
public String toString()
|
public String toString()
|
||||||
{
|
{
|
||||||
return "WorkflowTask[id=" + id + ",name=" + name + ",state=" + state + ",def=" + definition + ",path=" + path.toString() + "]";
|
String propCount = (properties == null) ? "null" : "" + properties.size();
|
||||||
|
return "WorkflowTask[id=" + id + ",name=" + name + ",state=" + state + ",props=" + propCount + ",def=" + definition + ",path=" + path.toString() + "]";
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -66,6 +66,12 @@ public interface NamespaceService extends NamespacePrefixResolver
|
|||||||
/** Application Model Prefix */
|
/** Application Model Prefix */
|
||||||
public static final String APP_MODEL_PREFIX = "app";
|
public static final String APP_MODEL_PREFIX = "app";
|
||||||
|
|
||||||
|
/** Business Process Model URI */
|
||||||
|
public static final String BPM_MODEL_1_0_URI = "http://www.alfresco.org/model/bpm/1.0";
|
||||||
|
|
||||||
|
/** Business Process Model Prefix */
|
||||||
|
public static final String BPM_MODEL_PREFIX = "bpm";
|
||||||
|
|
||||||
/** Alfresco View Namespace URI */
|
/** Alfresco View Namespace URI */
|
||||||
public static final String REPOSITORY_VIEW_1_0_URI = "http://www.alfresco.org/view/repository/1.0";
|
public static final String REPOSITORY_VIEW_1_0_URI = "http://www.alfresco.org/view/repository/1.0";
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user