mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-07-24 17:32:48 +00:00
Workflow checkpoint:
- BPM Engine Registry & Plug-in SPIs - First JBoss JBPM based Implementation of SPIs - Workflow Service Implementation - Tests git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@3436 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
@@ -44,6 +44,7 @@ import org.alfresco.service.cmr.security.PermissionService;
|
||||
import org.alfresco.service.cmr.version.VersionService;
|
||||
import org.alfresco.service.cmr.view.ExporterService;
|
||||
import org.alfresco.service.cmr.view.ImporterService;
|
||||
import org.alfresco.service.cmr.workflow.WorkflowService;
|
||||
import org.alfresco.service.descriptor.DescriptorService;
|
||||
import org.alfresco.service.namespace.NamespaceService;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
@@ -313,4 +314,12 @@ public class ServiceDescriptorRegistry
|
||||
{
|
||||
return (ScriptService)getService(SCRIPT_SERVICE);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.alfresco.service.ServiceRegistry#getWorkflowService()
|
||||
*/
|
||||
public WorkflowService getWorkflowService()
|
||||
{
|
||||
return (WorkflowService)getService(WORKFLOW_SERVICE);
|
||||
}
|
||||
}
|
||||
|
100
source/java/org/alfresco/repo/workflow/BPMEngine.java
Normal file
100
source/java/org/alfresco/repo/workflow/BPMEngine.java
Normal file
@@ -0,0 +1,100 @@
|
||||
/*
|
||||
* 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.cmr.workflow.WorkflowException;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
|
||||
|
||||
/**
|
||||
* Base functionality for a plug-in BPM Engine
|
||||
*
|
||||
* @author davidc
|
||||
*/
|
||||
public class BPMEngine implements InitializingBean
|
||||
{
|
||||
private BPMEngineRegistry registry;
|
||||
private String engineId;
|
||||
|
||||
|
||||
/**
|
||||
* Sets the BPM Engine Registry
|
||||
*
|
||||
* @param registry the registry
|
||||
*/
|
||||
public void setBPMEngineRegistry(BPMEngineRegistry registry)
|
||||
{
|
||||
this.registry = registry;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the BPM Engine Id
|
||||
*
|
||||
* @param engineId the id
|
||||
*/
|
||||
public void setEngineId(String engineId)
|
||||
{
|
||||
this.engineId = engineId;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet()
|
||||
*/
|
||||
public void afterPropertiesSet() throws Exception
|
||||
{
|
||||
if (engineId == null || engineId.length() == 0)
|
||||
{
|
||||
throw new WorkflowException("Engine Id not specified");
|
||||
}
|
||||
|
||||
if (this instanceof WorkflowDefinitionComponent)
|
||||
{
|
||||
registry.registerWorkflowDefinitionComponent(engineId, (WorkflowDefinitionComponent)this);
|
||||
}
|
||||
if (this instanceof WorkflowComponent)
|
||||
{
|
||||
registry.registerWorkflowComponent(engineId, (WorkflowComponent)this);
|
||||
}
|
||||
if (this instanceof TaskComponent)
|
||||
{
|
||||
registry.registerTaskComponent(engineId, (TaskComponent)this);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a global Id for use outside of the engine
|
||||
*
|
||||
* @param localId the local engine id
|
||||
* @return the global id
|
||||
*/
|
||||
protected String createGlobalId(String localId)
|
||||
{
|
||||
return BPMEngineRegistry.createGlobalId(engineId, localId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a local Id from a global Id
|
||||
*
|
||||
* @param globalId the global id
|
||||
* @return the local id
|
||||
*/
|
||||
protected String createLocalId(String globalId)
|
||||
{
|
||||
return BPMEngineRegistry.getLocalId(globalId);
|
||||
}
|
||||
}
|
234
source/java/org/alfresco/repo/workflow/BPMEngineRegistry.java
Normal file
234
source/java/org/alfresco/repo/workflow/BPMEngineRegistry.java
Normal file
@@ -0,0 +1,234 @@
|
||||
/*
|
||||
* 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 java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.alfresco.service.cmr.workflow.WorkflowException;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
|
||||
/**
|
||||
* BPM Engine Registry
|
||||
*
|
||||
* Responsible for managing the list of registered BPM Engines for the
|
||||
* following components:
|
||||
*
|
||||
* - Workflow Definition Component
|
||||
* - Workflow Component
|
||||
* - Task Component
|
||||
*
|
||||
* @author davidc
|
||||
*/
|
||||
public class BPMEngineRegistry
|
||||
{
|
||||
/** ID seperator used in global Ids */
|
||||
private static final String ID_SEPERATOR = "://";
|
||||
|
||||
/** Logging support */
|
||||
private static Log logger = LogFactory.getLog("org.alfresco.repo.workflow");
|
||||
|
||||
private Map<String, WorkflowDefinitionComponent> workflowDefinitionComponents;
|
||||
private Map<String, WorkflowComponent> workflowComponents;
|
||||
private Map<String, TaskComponent> taskComponents;
|
||||
|
||||
|
||||
/**
|
||||
* Construct
|
||||
*/
|
||||
public BPMEngineRegistry()
|
||||
{
|
||||
workflowDefinitionComponents = new HashMap<String, WorkflowDefinitionComponent>();
|
||||
workflowComponents = new HashMap<String, WorkflowComponent>();
|
||||
taskComponents = new HashMap<String, TaskComponent>();
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a BPM Engine Workflow Definition Component
|
||||
*
|
||||
* @param engineId engine id
|
||||
* @param engine implementing engine
|
||||
*/
|
||||
public void registerWorkflowDefinitionComponent(String engineId, WorkflowDefinitionComponent engine)
|
||||
{
|
||||
if (workflowDefinitionComponents.containsKey(engineId))
|
||||
{
|
||||
throw new WorkflowException("Workflow Definition Component already registered for engine id '" + engineId + "'");
|
||||
}
|
||||
workflowDefinitionComponents.put(engineId, engine);
|
||||
|
||||
if (logger.isInfoEnabled())
|
||||
logger.info("Registered Workflow Definition Component '" + engineId + "' (" + engine.getClass() + ")");
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets all registered Workflow Definition Components
|
||||
*
|
||||
* @return array of engine ids
|
||||
*/
|
||||
public String[] getWorkflowDefinitionComponents()
|
||||
{
|
||||
return workflowDefinitionComponents.keySet().toArray(new String[workflowDefinitionComponents.keySet().size()]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a specific BPM Engine Workflow Definition Component
|
||||
*
|
||||
* @param engineId engine id
|
||||
* @return the Workflow Definition Component
|
||||
*/
|
||||
public WorkflowDefinitionComponent getWorkflowDefinitionComponent(String engineId)
|
||||
{
|
||||
return workflowDefinitionComponents.get(engineId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a BPM Engine Workflow Component
|
||||
*
|
||||
* @param engineId engine id
|
||||
* @param engine implementing engine
|
||||
*/
|
||||
public void registerWorkflowComponent(String engineId, WorkflowComponent engine)
|
||||
{
|
||||
if (workflowComponents.containsKey(engineId))
|
||||
{
|
||||
throw new WorkflowException("Workflow Component already registered for engine id '" + engineId + "'");
|
||||
}
|
||||
workflowComponents.put(engineId, engine);
|
||||
|
||||
if (logger.isInfoEnabled())
|
||||
logger.info("Registered Workflow Component '" + engineId + "' (" + engine.getClass() + ")");
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets all registered Workflow Components
|
||||
*
|
||||
* @return array of engine ids
|
||||
*/
|
||||
public String[] getWorkflowComponents()
|
||||
{
|
||||
return workflowComponents.keySet().toArray(new String[workflowComponents.keySet().size()]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a specific BPM Engine Workflow Component
|
||||
*
|
||||
* @param engineId engine id
|
||||
* @return the Workflow Component
|
||||
*/
|
||||
public WorkflowComponent getWorkflowComponent(String engineId)
|
||||
{
|
||||
return workflowComponents.get(engineId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a BPM Engine Task Component
|
||||
*
|
||||
* @param engineId engine id
|
||||
* @param engine implementing engine
|
||||
*/
|
||||
public void registerTaskComponent(String engineId, TaskComponent engine)
|
||||
{
|
||||
if (taskComponents.containsKey(engineId))
|
||||
{
|
||||
throw new WorkflowException("Task Component already registered for engine id '" + engineId + "'");
|
||||
}
|
||||
taskComponents.put(engineId, engine);
|
||||
|
||||
if (logger.isInfoEnabled())
|
||||
logger.info("Registered Task Component '" + engineId + "' (" + engine.getClass() + ")");
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets all registered Task Components
|
||||
*
|
||||
* @return array of engine ids
|
||||
*/
|
||||
public String[] getTaskComponents()
|
||||
{
|
||||
return taskComponents.keySet().toArray(new String[taskComponents.keySet().size()]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a specific BPM Engine Task Component
|
||||
*
|
||||
* @param engineId engine id
|
||||
* @return the Workflow Component
|
||||
*/
|
||||
public TaskComponent getTaskComponent(String engineId)
|
||||
{
|
||||
return taskComponents.get(engineId);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// BPM Engine Id support
|
||||
//
|
||||
|
||||
/**
|
||||
* Construct a global Id
|
||||
*
|
||||
* @param engineId engine id
|
||||
* @param localId engine local id
|
||||
* @return the global id
|
||||
*/
|
||||
public static String createGlobalId(String engineId, String localId)
|
||||
{
|
||||
return engineId + ID_SEPERATOR + localId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Break apart a global id into its engine and local ids
|
||||
*
|
||||
* @param globalId the global id
|
||||
* @return array containing engine id and global id in that order
|
||||
*/
|
||||
public static String[] getGlobalIdParts(String globalId)
|
||||
{
|
||||
String[] parts = globalId.split(ID_SEPERATOR);
|
||||
if (parts.length != 2)
|
||||
{
|
||||
throw new WorkflowException("Invalid Global Id '" + globalId + "'");
|
||||
}
|
||||
return parts;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the engine id from a global id
|
||||
*
|
||||
* @param globalId the global id
|
||||
* @return the engine id
|
||||
*/
|
||||
public static String getEngineId(String globalId)
|
||||
{
|
||||
return getGlobalIdParts(globalId)[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the local id from a global id
|
||||
*
|
||||
* @param globalId the global id
|
||||
* @return the local id
|
||||
*/
|
||||
public static String getLocalId(String globalId)
|
||||
{
|
||||
return getGlobalIdParts(globalId)[1];
|
||||
}
|
||||
|
||||
}
|
83
source/java/org/alfresco/repo/workflow/TaskComponent.java
Normal file
83
source/java/org/alfresco/repo/workflow/TaskComponent.java
Normal file
@@ -0,0 +1,83 @@
|
||||
/*
|
||||
* 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 java.io.Serializable;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.cmr.workflow.WorkflowTask;
|
||||
import org.alfresco.service.cmr.workflow.WorkflowTaskState;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
|
||||
|
||||
/**
|
||||
* SPI to be implemented by a BPM Engine that provides Task management.
|
||||
*
|
||||
* @author davidc
|
||||
*/
|
||||
public interface TaskComponent
|
||||
{
|
||||
|
||||
/**
|
||||
* Gets a Task by unique Id
|
||||
*
|
||||
* @param taskId the task id
|
||||
* @return the task
|
||||
*/
|
||||
public WorkflowTask getTaskById(String taskId);
|
||||
|
||||
/**
|
||||
* Gets all tasks assigned to the specified authority
|
||||
*
|
||||
* @param authority the authority
|
||||
* @param state filter by specified workflow task state
|
||||
* @return the list of assigned tasks
|
||||
*/
|
||||
public List<WorkflowTask> getAssignedTasks(String authority, WorkflowTaskState state);
|
||||
|
||||
/**
|
||||
* Gets the pooled tasks available to the specified authority
|
||||
*
|
||||
* @param authority the authority
|
||||
* @return the list of pooled tasks
|
||||
*/
|
||||
public List<WorkflowTask> getPooledTasks(List<String> authorities);
|
||||
|
||||
/**
|
||||
* Update the Properties and Associations of a Task
|
||||
*
|
||||
* @param taskId the task id to update
|
||||
* @param properties the map of properties to set on the task (or null, if none to set)
|
||||
* @param add the map of items to associate with the task (or null, if none to add)
|
||||
* @param remove the map of items to dis-associate with the task (or null, if none to remove)
|
||||
* @return the update task
|
||||
*/
|
||||
public WorkflowTask updateTask(String taskId, Map<QName, Serializable> properties, Map<QName, List<NodeRef>> add, Map<QName, List<NodeRef>> remove);
|
||||
|
||||
/**
|
||||
* End the Task (i.e. complete the task)
|
||||
*
|
||||
* @param taskId the task id to end
|
||||
* @param transition the task transition to take on completion (or null, for the default transition)
|
||||
* @return the updated task
|
||||
*/
|
||||
public WorkflowTask endTask(String taskId, String transition);
|
||||
|
||||
}
|
||||
|
@@ -0,0 +1,89 @@
|
||||
/*
|
||||
* 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 java.io.Serializable;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.alfresco.service.cmr.workflow.WorkflowInstance;
|
||||
import org.alfresco.service.cmr.workflow.WorkflowPath;
|
||||
import org.alfresco.service.cmr.workflow.WorkflowTask;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
|
||||
|
||||
/**
|
||||
* SPI to be implemented by a BPM Engine that provides Workflow instance management.
|
||||
*
|
||||
* @author davidc
|
||||
*/
|
||||
public interface WorkflowComponent
|
||||
{
|
||||
|
||||
/**
|
||||
* Start a Workflow Instance
|
||||
*
|
||||
* @param workflowDefinitionId the workflow definition id
|
||||
* @param parameters the initial set of parameters used to populate the "Start Task" properties
|
||||
* @return the initial workflow path
|
||||
*/
|
||||
public WorkflowPath startWorkflow(String workflowDefinitionId, Map<QName, Serializable> parameters);
|
||||
|
||||
/**
|
||||
* Gets all "in-flight" workflow instances of the specified Workflow Definition
|
||||
*
|
||||
* @param workflowDefinitionId the workflow definition id
|
||||
* @return the list of "in-fligth" workflow instances
|
||||
*/
|
||||
public List<WorkflowInstance> getActiveWorkflows(String workflowDefinitionId);
|
||||
|
||||
/**
|
||||
* Gets all Paths for the specified Workflow instance
|
||||
*
|
||||
* @param workflowId workflow instance id
|
||||
* @return the list of workflow paths
|
||||
*/
|
||||
public List<WorkflowPath> getWorkflowPaths(String workflowId);
|
||||
|
||||
/**
|
||||
* Cancel an "in-fligth" Workflow instance
|
||||
*
|
||||
* @param workflowId the workflow instance to cancel
|
||||
* @return an updated representation of the workflow instance
|
||||
*/
|
||||
public WorkflowInstance cancelWorkflow(String workflowId);
|
||||
|
||||
/**
|
||||
* Signal the transition from one Workflow Node to another within an "in-flight"
|
||||
* process.
|
||||
*
|
||||
* @param pathId the workflow path to signal on
|
||||
* @param transition the transition to follow (or null, for the default transition)
|
||||
* @return the updated workflow path
|
||||
*/
|
||||
public WorkflowPath signal(String pathId, String transition);
|
||||
|
||||
/**
|
||||
* Gets all Tasks associated with the specified path
|
||||
*
|
||||
* @param pathId the path id
|
||||
* @return the list of associated tasks
|
||||
*/
|
||||
public List<WorkflowTask> getTasksForWorkflowPath(String pathId);
|
||||
|
||||
}
|
||||
|
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
* 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 java.io.InputStream;
|
||||
import java.util.List;
|
||||
|
||||
import org.alfresco.service.cmr.workflow.WorkflowDefinition;
|
||||
|
||||
|
||||
/**
|
||||
* SPI to be implemented by a BPM Engine that provides Workflow Definition management.
|
||||
*
|
||||
* @author davidc
|
||||
*/
|
||||
public interface WorkflowDefinitionComponent
|
||||
{
|
||||
|
||||
/**
|
||||
* Deploy a Workflow Definition
|
||||
*
|
||||
* @param workflowDefinition the content object containing the definition
|
||||
* @return workflow definition
|
||||
*/
|
||||
public WorkflowDefinition deployDefinition(InputStream workflowDefinition);
|
||||
|
||||
/**
|
||||
* Undeploy an exisiting Workflow Definition
|
||||
*
|
||||
* TODO: Determine behaviour when "in-flight" workflow instances exist
|
||||
*
|
||||
* @param workflowDefinitionId the id of the definition to undeploy
|
||||
*/
|
||||
public void undeployDefinition(String workflowDefinitionId);
|
||||
|
||||
/**
|
||||
* Gets all deployed Workflow Definitions
|
||||
*
|
||||
* @return the deployed workflow definitions
|
||||
*/
|
||||
public List<WorkflowDefinition> getDefinitions();
|
||||
|
||||
/**
|
||||
* Gets a Workflow Definition by unique Id
|
||||
*
|
||||
* @param workflowDefinitionId the workflow definition id
|
||||
* @return the deployed workflow definition
|
||||
*/
|
||||
public WorkflowDefinition getDefinitionById(String workflowDefinitionId);
|
||||
|
||||
}
|
||||
|
279
source/java/org/alfresco/repo/workflow/WorkflowServiceImpl.java
Normal file
279
source/java/org/alfresco/repo/workflow/WorkflowServiceImpl.java
Normal file
@@ -0,0 +1,279 @@
|
||||
/*
|
||||
* 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 java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.cmr.workflow.WorkflowDefinition;
|
||||
import org.alfresco.service.cmr.workflow.WorkflowException;
|
||||
import org.alfresco.service.cmr.workflow.WorkflowInstance;
|
||||
import org.alfresco.service.cmr.workflow.WorkflowPath;
|
||||
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;
|
||||
|
||||
|
||||
/**
|
||||
* Default Alfresco Workflow Service whose implementation is backed by registered
|
||||
* BPM Engine plug-in components.
|
||||
*
|
||||
* @author davidc
|
||||
*/
|
||||
public class WorkflowServiceImpl implements WorkflowService
|
||||
{
|
||||
private BPMEngineRegistry registry;
|
||||
|
||||
|
||||
/**
|
||||
* Sets the BPM Engine Registry
|
||||
*
|
||||
* @param registry bpm engine registry
|
||||
*/
|
||||
public void setBPMEngineRegistry(BPMEngineRegistry registry)
|
||||
{
|
||||
this.registry = registry;
|
||||
}
|
||||
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.alfresco.service.cmr.workflow.WorkflowService#deployDefinition(org.alfresco.service.cmr.repository.NodeRef)
|
||||
*/
|
||||
public WorkflowDefinition deployDefinition(NodeRef definitionContent)
|
||||
{
|
||||
// TODO
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.alfresco.service.cmr.workflow.WorkflowService#undeployDefinition(java.lang.String)
|
||||
*/
|
||||
public void undeployDefinition(String processDefinitionId)
|
||||
{
|
||||
// TODO
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.alfresco.service.cmr.workflow.WorkflowService#getDefinitions()
|
||||
*/
|
||||
public List<WorkflowDefinition> getDefinitions()
|
||||
{
|
||||
List<WorkflowDefinition> definitions = new ArrayList<WorkflowDefinition>(10);
|
||||
String[] ids = registry.getWorkflowDefinitionComponents();
|
||||
for (String id: ids)
|
||||
{
|
||||
WorkflowDefinitionComponent component = registry.getWorkflowDefinitionComponent(id);
|
||||
definitions.addAll(component.getDefinitions());
|
||||
}
|
||||
return Collections.unmodifiableList(definitions);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.alfresco.service.cmr.workflow.WorkflowService#getDefinitionById(java.lang.String)
|
||||
*/
|
||||
public WorkflowDefinition getDefinitionById(String workflowDefinitionId)
|
||||
{
|
||||
String engineId = BPMEngineRegistry.getEngineId(workflowDefinitionId);
|
||||
WorkflowDefinitionComponent component = getWorkflowDefinitionComponent(engineId);
|
||||
return component.getDefinitionById(workflowDefinitionId);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.alfresco.service.cmr.workflow.WorkflowService#startWorkflow(java.lang.String, java.util.Map)
|
||||
*/
|
||||
public WorkflowPath startWorkflow(String workflowDefinitionId, Map<QName, Serializable> parameters)
|
||||
{
|
||||
String engineId = BPMEngineRegistry.getEngineId(workflowDefinitionId);
|
||||
WorkflowComponent component = getWorkflowComponent(engineId);
|
||||
return component.startWorkflow(workflowDefinitionId, parameters);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.alfresco.service.cmr.workflow.WorkflowService#startWorkflowFromTemplate(org.alfresco.service.cmr.repository.NodeRef)
|
||||
*/
|
||||
public WorkflowPath startWorkflowFromTemplate(NodeRef templateDefinition)
|
||||
{
|
||||
// TODO
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.alfresco.service.cmr.workflow.WorkflowService#getActiveWorkflows(java.lang.String)
|
||||
*/
|
||||
public List<WorkflowInstance> getActiveWorkflows(String workflowDefinitionId)
|
||||
{
|
||||
String engineId = BPMEngineRegistry.getEngineId(workflowDefinitionId);
|
||||
WorkflowComponent component = getWorkflowComponent(engineId);
|
||||
return component.getActiveWorkflows(workflowDefinitionId);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.alfresco.service.cmr.workflow.WorkflowService#getWorkflowPaths(java.lang.String)
|
||||
*/
|
||||
public List<WorkflowPath> getWorkflowPaths(String workflowId)
|
||||
{
|
||||
String engineId = BPMEngineRegistry.getEngineId(workflowId);
|
||||
WorkflowComponent component = getWorkflowComponent(engineId);
|
||||
return component.getWorkflowPaths(workflowId);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.alfresco.service.cmr.workflow.WorkflowService#cancelWorkflow(java.lang.String)
|
||||
*/
|
||||
public WorkflowInstance cancelWorkflow(String workflowId)
|
||||
{
|
||||
String engineId = BPMEngineRegistry.getEngineId(workflowId);
|
||||
WorkflowComponent component = getWorkflowComponent(engineId);
|
||||
return component.cancelWorkflow(workflowId);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.alfresco.service.cmr.workflow.WorkflowService#signal(java.lang.String, java.lang.String)
|
||||
*/
|
||||
public WorkflowPath signal(String pathId, String transition)
|
||||
{
|
||||
String engineId = BPMEngineRegistry.getEngineId(pathId);
|
||||
WorkflowComponent component = getWorkflowComponent(engineId);
|
||||
return component.signal(pathId, transition);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.alfresco.service.cmr.workflow.WorkflowService#getTasksForWorkflowPath(java.lang.String)
|
||||
*/
|
||||
public List<WorkflowTask> getTasksForWorkflowPath(String pathId)
|
||||
{
|
||||
String engineId = BPMEngineRegistry.getEngineId(pathId);
|
||||
WorkflowComponent component = getWorkflowComponent(engineId);
|
||||
return component.getTasksForWorkflowPath(pathId);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.alfresco.service.cmr.workflow.WorkflowService#getAssignedTasks(java.lang.String, org.alfresco.service.cmr.workflow.WorkflowTaskState)
|
||||
*/
|
||||
public List<WorkflowTask> getAssignedTasks(String authority, WorkflowTaskState state)
|
||||
{
|
||||
List<WorkflowTask> tasks = new ArrayList<WorkflowTask>(10);
|
||||
String[] ids = registry.getTaskComponents();
|
||||
for (String id: ids)
|
||||
{
|
||||
TaskComponent component = registry.getTaskComponent(id);
|
||||
tasks.addAll(component.getAssignedTasks(authority, state));
|
||||
}
|
||||
return Collections.unmodifiableList(tasks);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.alfresco.service.cmr.workflow.WorkflowService#getPooledTasks(java.lang.String)
|
||||
*/
|
||||
public List<WorkflowTask> getPooledTasks(String authority)
|
||||
{
|
||||
// TODO: Expand authorities to include associated groups (and parent groups)
|
||||
List<String> authorities = new ArrayList<String>();
|
||||
authorities.add(authority);
|
||||
|
||||
List<WorkflowTask> tasks = new ArrayList<WorkflowTask>(10);
|
||||
String[] ids = registry.getTaskComponents();
|
||||
for (String id: ids)
|
||||
{
|
||||
TaskComponent component = registry.getTaskComponent(id);
|
||||
tasks.addAll(component.getPooledTasks(authorities));
|
||||
}
|
||||
return Collections.unmodifiableList(tasks);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.alfresco.service.cmr.workflow.WorkflowService#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)
|
||||
{
|
||||
String engineId = BPMEngineRegistry.getEngineId(taskId);
|
||||
TaskComponent component = getTaskComponent(engineId);
|
||||
return component.updateTask(taskId, properties, add, remove);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.alfresco.service.cmr.workflow.WorkflowService#endTask(java.lang.String, java.lang.String)
|
||||
*/
|
||||
public WorkflowTask endTask(String taskId, String transition)
|
||||
{
|
||||
String engineId = BPMEngineRegistry.getEngineId(taskId);
|
||||
TaskComponent component = getTaskComponent(engineId);
|
||||
return component.endTask(taskId, transition);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.alfresco.service.cmr.workflow.WorkflowService#getTaskById(java.lang.String)
|
||||
*/
|
||||
public WorkflowTask getTaskById(String taskId)
|
||||
{
|
||||
// TODO
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Gets the Workflow Definition Component registered against the specified BPM Engine Id
|
||||
*
|
||||
* @param engineId engine id
|
||||
*/
|
||||
private WorkflowDefinitionComponent getWorkflowDefinitionComponent(String engineId)
|
||||
{
|
||||
WorkflowDefinitionComponent component = registry.getWorkflowDefinitionComponent(engineId);
|
||||
if (component == null)
|
||||
{
|
||||
throw new WorkflowException("Workflow Definition Component for engine id '" + engineId + "' is not registered");
|
||||
}
|
||||
return component;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the Workflow Component registered against the specified BPM Engine Id
|
||||
*
|
||||
* @param engineId engine id
|
||||
*/
|
||||
private WorkflowComponent getWorkflowComponent(String engineId)
|
||||
{
|
||||
WorkflowComponent component = registry.getWorkflowComponent(engineId);
|
||||
if (component == null)
|
||||
{
|
||||
throw new WorkflowException("Workflow Component for engine id '" + engineId + "' is not registered");
|
||||
}
|
||||
return component;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the Task Component registered against the specified BPM Engine Id
|
||||
*
|
||||
* @param engineId engine id
|
||||
*/
|
||||
private TaskComponent getTaskComponent(String engineId)
|
||||
{
|
||||
TaskComponent component = registry.getTaskComponent(engineId);
|
||||
if (component == null)
|
||||
{
|
||||
throw new WorkflowException("Task Component for engine id '" + engineId + "' is not registered");
|
||||
}
|
||||
return component;
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
* 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 java.util.List;
|
||||
|
||||
import org.alfresco.service.ServiceRegistry;
|
||||
import org.alfresco.service.cmr.workflow.WorkflowDefinition;
|
||||
import org.alfresco.service.cmr.workflow.WorkflowPath;
|
||||
import org.alfresco.service.cmr.workflow.WorkflowService;
|
||||
import org.alfresco.util.BaseSpringTest;
|
||||
|
||||
|
||||
/**
|
||||
* Workflow Service Implementation Tests
|
||||
*
|
||||
* @author davidc
|
||||
*/
|
||||
public class WorkflowServiceImplTest extends BaseSpringTest
|
||||
{
|
||||
WorkflowService workflowService;
|
||||
|
||||
//@Override
|
||||
protected void onSetUpInTransaction() throws Exception
|
||||
{
|
||||
workflowService = (WorkflowService)applicationContext.getBean(ServiceRegistry.WORKFLOW_SERVICE.getLocalName());
|
||||
}
|
||||
|
||||
public void testGetWorkflowDefinitions()
|
||||
{
|
||||
List<WorkflowDefinition> workflowDefs = workflowService.getDefinitions();
|
||||
assertNotNull(workflowDefs);
|
||||
assertTrue(workflowDefs.size() > 0);
|
||||
}
|
||||
|
||||
public void testStartWorkflow()
|
||||
{
|
||||
List<WorkflowDefinition> workflowDefs = workflowService.getDefinitions();
|
||||
assertNotNull(workflowDefs);
|
||||
assertTrue(workflowDefs.size() > 0);
|
||||
WorkflowDefinition workflowDef = workflowDefs.get(0);
|
||||
WorkflowPath path = workflowService.startWorkflow(workflowDef.id, null);
|
||||
assertNotNull(path);
|
||||
assertTrue(path.active);
|
||||
assertNotNull(path.node);
|
||||
assertNotNull(path.instance);
|
||||
assertEquals(workflowDef.id, path.instance.definition.id);
|
||||
}
|
||||
}
|
757
source/java/org/alfresco/repo/workflow/jbpm/JBPMEngine.java
Normal file
757
source/java/org/alfresco/repo/workflow/jbpm/JBPMEngine.java
Normal file
@@ -0,0 +1,757 @@
|
||||
/*
|
||||
* 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.jbpm;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import org.alfresco.repo.security.authentication.AuthenticationUtil;
|
||||
import org.alfresco.repo.workflow.BPMEngine;
|
||||
import org.alfresco.repo.workflow.TaskComponent;
|
||||
import org.alfresco.repo.workflow.WorkflowComponent;
|
||||
import org.alfresco.repo.workflow.WorkflowDefinitionComponent;
|
||||
import org.alfresco.service.cmr.dictionary.DictionaryService;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.cmr.workflow.WorkflowDefinition;
|
||||
import org.alfresco.service.cmr.workflow.WorkflowException;
|
||||
import org.alfresco.service.cmr.workflow.WorkflowInstance;
|
||||
import org.alfresco.service.cmr.workflow.WorkflowNode;
|
||||
import org.alfresco.service.cmr.workflow.WorkflowPath;
|
||||
import org.alfresco.service.cmr.workflow.WorkflowTask;
|
||||
import org.alfresco.service.cmr.workflow.WorkflowTaskDefinition;
|
||||
import org.alfresco.service.cmr.workflow.WorkflowTaskState;
|
||||
import org.alfresco.service.namespace.NamespaceService;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
import org.hibernate.proxy.HibernateProxy;
|
||||
import org.jbpm.JbpmContext;
|
||||
import org.jbpm.JbpmException;
|
||||
import org.jbpm.context.exe.ContextInstance;
|
||||
import org.jbpm.db.GraphSession;
|
||||
import org.jbpm.db.TaskMgmtSession;
|
||||
import org.jbpm.graph.def.Node;
|
||||
import org.jbpm.graph.def.ProcessDefinition;
|
||||
import org.jbpm.graph.def.Transition;
|
||||
import org.jbpm.graph.exe.ProcessInstance;
|
||||
import org.jbpm.graph.exe.Token;
|
||||
import org.jbpm.taskmgmt.def.Task;
|
||||
import org.jbpm.taskmgmt.exe.TaskInstance;
|
||||
import org.springmodules.workflow.jbpm31.JbpmCallback;
|
||||
import org.springmodules.workflow.jbpm31.JbpmTemplate;
|
||||
|
||||
|
||||
/**
|
||||
* JBoss JBPM based implementation of:
|
||||
*
|
||||
* Workflow Definition Component
|
||||
* Workflow Component
|
||||
* Task Component
|
||||
*
|
||||
* @author davidc
|
||||
*/
|
||||
public class JBPMEngine extends BPMEngine
|
||||
implements WorkflowDefinitionComponent, WorkflowComponent, TaskComponent
|
||||
{
|
||||
// Implementation dependencies
|
||||
protected DictionaryService dictionaryService;
|
||||
protected NamespaceService namespaceService;
|
||||
private JbpmTemplate jbpmTemplate;
|
||||
|
||||
/**
|
||||
* Sets the JBPM Template used for accessing JBoss JBPM in the correct context
|
||||
*
|
||||
* @param jbpmTemplate
|
||||
*/
|
||||
public void setJBPMTemplate(JbpmTemplate jbpmTemplate)
|
||||
{
|
||||
this.jbpmTemplate = jbpmTemplate;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the Dictionary Service
|
||||
*
|
||||
* @param dictionaryService
|
||||
*/
|
||||
public void setDictionaryService(DictionaryService dictionaryService)
|
||||
{
|
||||
this.dictionaryService = dictionaryService;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the Namespace Service
|
||||
*
|
||||
* @param namespaceService
|
||||
*/
|
||||
public void setNamespaceService(NamespaceService namespaceService)
|
||||
{
|
||||
this.namespaceService = namespaceService;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Workflow Definition...
|
||||
//
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.alfresco.repo.workflow.WorkflowDefinitionComponent#deployDefinition(java.io.InputStream)
|
||||
*/
|
||||
public WorkflowDefinition deployDefinition(InputStream workflowDefinition)
|
||||
{
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.alfresco.repo.workflow.WorkflowDefinitionComponent#undeployDefinition(java.lang.String)
|
||||
*/
|
||||
public void undeployDefinition(String workflowDefinitionId)
|
||||
{
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.alfresco.repo.workflow.WorkflowDefinitionComponent#getDefinitions()
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public List<WorkflowDefinition> getDefinitions()
|
||||
{
|
||||
try
|
||||
{
|
||||
return (List<WorkflowDefinition>)jbpmTemplate.execute(new JbpmCallback()
|
||||
{
|
||||
public Object doInJbpm(JbpmContext context)
|
||||
{
|
||||
GraphSession graphSession = context.getGraphSession();
|
||||
List<ProcessDefinition> processDefs = (List<ProcessDefinition>)graphSession.findLatestProcessDefinitions();
|
||||
List<WorkflowDefinition> workflowDefs = new ArrayList<WorkflowDefinition>(processDefs.size());
|
||||
for (ProcessDefinition processDef : processDefs)
|
||||
{
|
||||
WorkflowDefinition workflowDef = createWorkflowDefinition(processDef);
|
||||
workflowDefs.add(workflowDef);
|
||||
}
|
||||
return workflowDefs;
|
||||
}
|
||||
});
|
||||
}
|
||||
catch(JbpmException e)
|
||||
{
|
||||
throw new WorkflowException("Failed to retrieve workflow definitions", e);
|
||||
}
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.alfresco.repo.workflow.WorkflowDefinitionComponent#getDefinitionById(java.lang.String)
|
||||
*/
|
||||
public WorkflowDefinition getDefinitionById(String workflowDefinitionId)
|
||||
{
|
||||
// TODO
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Workflow Instance Management...
|
||||
//
|
||||
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.alfresco.repo.workflow.WorkflowComponent#startWorkflow(java.lang.String, java.util.Map)
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public WorkflowPath startWorkflow(final String workflowDefinitionId, final Map<QName, Serializable> parameters)
|
||||
{
|
||||
try
|
||||
{
|
||||
return (WorkflowPath) jbpmTemplate.execute(new JbpmCallback()
|
||||
{
|
||||
public Object doInJbpm(JbpmContext context)
|
||||
{
|
||||
// initialise jBPM actor (for any processes that wish to record the initiator)
|
||||
context.setActorId(AuthenticationUtil.getCurrentUserName());
|
||||
|
||||
// construct a new process
|
||||
GraphSession graphSession = context.getGraphSession();
|
||||
ProcessDefinition processDefinition = graphSession.loadProcessDefinition(getJbpmId(workflowDefinitionId));
|
||||
ProcessInstance processInstance = new ProcessInstance(processDefinition);
|
||||
Token token = processInstance.getRootToken();
|
||||
|
||||
// create the start task if one exists
|
||||
Task startTask = processInstance.getTaskMgmtInstance().getTaskMgmtDefinition().getStartTask();
|
||||
if (startTask != null)
|
||||
{
|
||||
TaskInstance taskInstance = processInstance.getTaskMgmtInstance().createStartTaskInstance();
|
||||
setTaskProperties(taskInstance, parameters);
|
||||
token = taskInstance.getToken();
|
||||
}
|
||||
|
||||
// Save the process instance along with the task instance
|
||||
context.save(processInstance);
|
||||
return createWorkflowPath(token);
|
||||
}
|
||||
});
|
||||
}
|
||||
catch(JbpmException e)
|
||||
{
|
||||
throw new WorkflowException("Failed to start workflow " + workflowDefinitionId, e);
|
||||
}
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.alfresco.repo.workflow.WorkflowComponent#getActiveWorkflows(java.lang.String)
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public List<WorkflowInstance> getActiveWorkflows(final String workflowDefinitionId)
|
||||
{
|
||||
try
|
||||
{
|
||||
return (List<WorkflowInstance>) jbpmTemplate.execute(new JbpmCallback()
|
||||
{
|
||||
public Object doInJbpm(JbpmContext context)
|
||||
{
|
||||
GraphSession graphSession = context.getGraphSession();
|
||||
List<ProcessInstance> processInstances = graphSession.findProcessInstances(getJbpmId(workflowDefinitionId));
|
||||
List<WorkflowInstance> workflowInstances = new ArrayList<WorkflowInstance>(processInstances.size());
|
||||
for (ProcessInstance processInstance : processInstances)
|
||||
{
|
||||
if (!processInstance.hasEnded())
|
||||
{
|
||||
WorkflowInstance workflowInstance = createWorkflowInstance(processInstance);
|
||||
workflowInstances.add(workflowInstance);
|
||||
}
|
||||
}
|
||||
return workflowInstances;
|
||||
}
|
||||
});
|
||||
}
|
||||
catch(JbpmException e)
|
||||
{
|
||||
throw new WorkflowException("Failed to retrieve workflow instances for definition '" + workflowDefinitionId + "'", e);
|
||||
}
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.alfresco.repo.workflow.WorkflowComponent#getWorkflowPaths(java.lang.String)
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public List<WorkflowPath> getWorkflowPaths(final String workflowId)
|
||||
{
|
||||
try
|
||||
{
|
||||
return (List<WorkflowPath>) jbpmTemplate.execute(new JbpmCallback()
|
||||
{
|
||||
public Object doInJbpm(JbpmContext context)
|
||||
{
|
||||
// retrieve process instance
|
||||
GraphSession graphSession = context.getGraphSession();
|
||||
ProcessInstance processInstance = graphSession.loadProcessInstance(getJbpmId(workflowId));
|
||||
|
||||
// convert jBPM tokens to workflow posisitons
|
||||
List<Token> tokens = processInstance.findAllTokens();
|
||||
List<WorkflowPath> paths = new ArrayList<WorkflowPath>(tokens.size());
|
||||
for (Token token : tokens)
|
||||
{
|
||||
if (!token.hasEnded())
|
||||
{
|
||||
WorkflowPath path = createWorkflowPath(token);
|
||||
paths.add(path);
|
||||
}
|
||||
}
|
||||
|
||||
return paths;
|
||||
}
|
||||
});
|
||||
}
|
||||
catch(JbpmException e)
|
||||
{
|
||||
throw new WorkflowException("Failed to retrieve workflow paths for workflow instance '" + workflowId + "'", e);
|
||||
}
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.alfresco.repo.workflow.WorkflowComponent#cancelWorkflow(java.lang.String)
|
||||
*/
|
||||
public WorkflowInstance cancelWorkflow(final String workflowId)
|
||||
{
|
||||
try
|
||||
{
|
||||
return (WorkflowInstance) jbpmTemplate.execute(new JbpmCallback()
|
||||
{
|
||||
public Object doInJbpm(JbpmContext context)
|
||||
{
|
||||
// retrieve and cancel process instance
|
||||
GraphSession graphSession = context.getGraphSession();
|
||||
ProcessInstance processInstance = graphSession.loadProcessInstance(getJbpmId(workflowId));
|
||||
processInstance.end();
|
||||
|
||||
// save the process instance along with the task instance
|
||||
context.save(processInstance);
|
||||
return createWorkflowInstance(processInstance);
|
||||
}
|
||||
});
|
||||
}
|
||||
catch(JbpmException e)
|
||||
{
|
||||
throw new WorkflowException("Failed to cancel workflow instance '" + workflowId + "'", e);
|
||||
}
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.alfresco.repo.workflow.WorkflowComponent#signal(java.lang.String, java.lang.String)
|
||||
*/
|
||||
public WorkflowPath signal(final String pathId, final String transition)
|
||||
{
|
||||
try
|
||||
{
|
||||
return (WorkflowPath) jbpmTemplate.execute(new JbpmCallback()
|
||||
{
|
||||
public Object doInJbpm(JbpmContext context)
|
||||
{
|
||||
// retrieve jBPM token for workflow position
|
||||
GraphSession graphSession = context.getGraphSession();
|
||||
Token token = getWorkflowToken(graphSession, pathId);
|
||||
|
||||
// signal the transition
|
||||
if (transition == null)
|
||||
{
|
||||
token.signal();
|
||||
}
|
||||
else
|
||||
{
|
||||
Node node = token.getNode();
|
||||
if (!node.hasLeavingTransition(transition))
|
||||
{
|
||||
throw new WorkflowException("Transition '" + transition + "' is invalid for Workflow path '" + pathId + "'");
|
||||
}
|
||||
token.signal(transition);
|
||||
}
|
||||
|
||||
// save
|
||||
ProcessInstance processInstance = token.getProcessInstance();
|
||||
context.save(processInstance);
|
||||
|
||||
// return new workflow path
|
||||
return createWorkflowPath(token);
|
||||
}
|
||||
});
|
||||
}
|
||||
catch(JbpmException e)
|
||||
{
|
||||
throw new WorkflowException("Failed to signal transition '" + transition + "' from workflow path '" + pathId + "'", e);
|
||||
}
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.alfresco.repo.workflow.WorkflowComponent#getTasksForWorkflowPath(java.lang.String)
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public List<WorkflowTask> getTasksForWorkflowPath(final String pathId)
|
||||
{
|
||||
try
|
||||
{
|
||||
return (List<WorkflowTask>) jbpmTemplate.execute(new JbpmCallback()
|
||||
{
|
||||
public List<WorkflowTask> doInJbpm(JbpmContext context)
|
||||
{
|
||||
// retrieve tasks at specified workflow path
|
||||
GraphSession graphSession = context.getGraphSession();
|
||||
Token token = getWorkflowToken(graphSession, pathId);
|
||||
TaskMgmtSession taskSession = context.getTaskMgmtSession();
|
||||
List<TaskInstance> tasks = taskSession.findTaskInstancesByToken(token.getId());
|
||||
List<WorkflowTask> workflowTasks = new ArrayList<WorkflowTask>(tasks.size());
|
||||
for (TaskInstance task : tasks)
|
||||
{
|
||||
WorkflowTask workflowTask = createWorkflowTask(task);
|
||||
workflowTasks.add(workflowTask);
|
||||
}
|
||||
return workflowTasks;
|
||||
}
|
||||
});
|
||||
}
|
||||
catch(JbpmException e)
|
||||
{
|
||||
throw new WorkflowException("Failed to retrieve tasks assigned at Workflow path '" + pathId + "'", e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Task Management ...
|
||||
//
|
||||
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.alfresco.repo.workflow.TaskComponent#getAssignedTasks(java.lang.String, org.alfresco.service.cmr.workflow.WorkflowTaskState)
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public List<WorkflowTask> getAssignedTasks(final String authority, final WorkflowTaskState state)
|
||||
{
|
||||
try
|
||||
{
|
||||
return (List<WorkflowTask>) jbpmTemplate.execute(new JbpmCallback()
|
||||
{
|
||||
public List<WorkflowTask> doInJbpm(JbpmContext context)
|
||||
{
|
||||
// retrieve tasks assigned to authority
|
||||
TaskMgmtSession taskSession = context.getTaskMgmtSession();
|
||||
List<TaskInstance> tasks = taskSession.findTaskInstances(authority);
|
||||
List<WorkflowTask> workflowTasks = new ArrayList<WorkflowTask>(tasks.size());
|
||||
for (TaskInstance task : tasks)
|
||||
{
|
||||
if (getWorkflowTaskState(task).equals(state))
|
||||
{
|
||||
WorkflowTask workflowTask = createWorkflowTask(task);
|
||||
workflowTasks.add(workflowTask);
|
||||
}
|
||||
}
|
||||
return workflowTasks;
|
||||
}
|
||||
});
|
||||
}
|
||||
catch(JbpmException e)
|
||||
{
|
||||
throw new WorkflowException("Failed to retrieve tasks assigned to authority '" + authority + "'", e);
|
||||
}
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.alfresco.repo.workflow.TaskComponent#getPooledTasks(java.util.List)
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public List<WorkflowTask> getPooledTasks(final List<String> authorities)
|
||||
{
|
||||
try
|
||||
{
|
||||
return (List<WorkflowTask>) jbpmTemplate.execute(new JbpmCallback()
|
||||
{
|
||||
public List<WorkflowTask> doInJbpm(JbpmContext context)
|
||||
{
|
||||
// retrieve pooled tasks for specified authorities
|
||||
TaskMgmtSession taskSession = context.getTaskMgmtSession();
|
||||
List<TaskInstance> tasks = taskSession.findPooledTaskInstances(authorities);
|
||||
List<WorkflowTask> workflowTasks = new ArrayList<WorkflowTask>(tasks.size());
|
||||
for (TaskInstance task : tasks)
|
||||
{
|
||||
WorkflowTask workflowTask = createWorkflowTask(task);
|
||||
workflowTasks.add(workflowTask);
|
||||
}
|
||||
return workflowTasks;
|
||||
}
|
||||
});
|
||||
}
|
||||
catch(JbpmException e)
|
||||
{
|
||||
throw new WorkflowException("Failed to retrieve pooled tasks for authorities '" + authorities + "'", e);
|
||||
}
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @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)
|
||||
{
|
||||
// TODO
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.alfresco.repo.workflow.TaskComponent#endTask(java.lang.String, java.lang.String)
|
||||
*/
|
||||
public WorkflowTask endTask(final String taskId, final String transition)
|
||||
{
|
||||
try
|
||||
{
|
||||
return (WorkflowTask) jbpmTemplate.execute(new JbpmCallback()
|
||||
{
|
||||
public Object doInJbpm(JbpmContext context)
|
||||
{
|
||||
// retrieve task
|
||||
TaskMgmtSession taskSession = context.getTaskMgmtSession();
|
||||
TaskInstance taskInstance = taskSession.loadTaskInstance(getJbpmId(taskId));
|
||||
|
||||
// signal the transition on the task
|
||||
if (transition == null)
|
||||
{
|
||||
taskInstance.end();
|
||||
}
|
||||
else
|
||||
{
|
||||
Node node = taskInstance.getTask().getTaskNode();
|
||||
if (node.getLeavingTransition(transition) == null)
|
||||
{
|
||||
throw new WorkflowException("Transition '" + transition + "' is invalid for Workflow task '" + taskId + "'");
|
||||
}
|
||||
taskInstance.end(transition);
|
||||
}
|
||||
|
||||
// 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 signal transition '" + transition + "' from workflow task '" + taskId + "'", e);
|
||||
}
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.alfresco.repo.workflow.TaskComponent#getTaskById(java.lang.String)
|
||||
*/
|
||||
public WorkflowTask getTaskById(String taskId)
|
||||
{
|
||||
// TODO Auto-generated method stub
|
||||
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...
|
||||
//
|
||||
|
||||
|
||||
/**
|
||||
* Get JBoss JBPM Id from Engine Global Id
|
||||
*
|
||||
* @param id global id
|
||||
* @return JBoss JBPM Id
|
||||
*/
|
||||
protected long getJbpmId(String id)
|
||||
{
|
||||
try
|
||||
{
|
||||
String theLong = createLocalId(id);
|
||||
return new Long(theLong);
|
||||
}
|
||||
catch(NumberFormatException e)
|
||||
{
|
||||
throw new WorkflowException("Format of id '" + id + "' is invalid", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the JBoss JBPM Token for the Workflow Path
|
||||
*
|
||||
* @param session JBoss JBPM Graph Session
|
||||
* @param pathId workflow path id
|
||||
* @return JBoss JBPM Token
|
||||
*/
|
||||
protected Token getWorkflowToken(GraphSession session, String pathId)
|
||||
{
|
||||
// extract process id and token path within process
|
||||
String[] path = pathId.split("::");
|
||||
if (path.length != 2)
|
||||
{
|
||||
throw new WorkflowException("Invalid workflow path '" + pathId + "'");
|
||||
}
|
||||
|
||||
// retrieve jBPM token for workflow position
|
||||
ProcessInstance processInstance = session.loadProcessInstance(getJbpmId(path[0]));
|
||||
Token token = processInstance.findToken(path[1]);
|
||||
if (token == null)
|
||||
{
|
||||
throw new WorkflowException("Workflow path '" + pathId + "' does not exist");
|
||||
}
|
||||
|
||||
return token;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Workflow Data Object Creation...
|
||||
//
|
||||
|
||||
/**
|
||||
* Creates a Workflow Path
|
||||
*
|
||||
* @param token JBoss JBPM Token
|
||||
* @return Workflow Path
|
||||
*/
|
||||
protected WorkflowPath createWorkflowPath(Token token)
|
||||
{
|
||||
WorkflowPath path = new WorkflowPath();
|
||||
path.id = createGlobalId(token.getProcessInstance().getId() + "::" + token.getFullName());
|
||||
path.instance = createWorkflowInstance(token.getProcessInstance());
|
||||
path.node = createWorkflowNode(token.getNode());
|
||||
path.active = !token.hasEnded();
|
||||
return path;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a Workflow Node
|
||||
*
|
||||
* @param node JBoss JBPM Node
|
||||
* @return Workflow Node
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
protected WorkflowNode createWorkflowNode(Node node)
|
||||
{
|
||||
WorkflowNode workflowNode = new WorkflowNode();
|
||||
workflowNode.name = node.getName();
|
||||
if (node instanceof HibernateProxy)
|
||||
{
|
||||
Node realNode = (Node)((HibernateProxy)node).getHibernateLazyInitializer().getImplementation();
|
||||
workflowNode.type = realNode.getClass().getSimpleName();
|
||||
}
|
||||
else
|
||||
{
|
||||
workflowNode.type = node.getClass().getSimpleName();
|
||||
}
|
||||
// TODO: Is there a formal way of determing if task node?
|
||||
workflowNode.isTaskNode = workflowNode.type.equals("TaskNode");
|
||||
List transitions = node.getLeavingTransitions();
|
||||
workflowNode.transitions = new String[transitions.size()];
|
||||
int i = 0;
|
||||
for (Transition transition : (List<Transition>)transitions)
|
||||
{
|
||||
workflowNode.transitions[i++] = transition.getName();
|
||||
}
|
||||
return workflowNode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a Workflow Instance
|
||||
*
|
||||
* @param instance JBoss JBPM Process Instance
|
||||
* @return Workflow instance
|
||||
*/
|
||||
protected WorkflowInstance createWorkflowInstance(ProcessInstance instance)
|
||||
{
|
||||
WorkflowInstance workflowInstance = new WorkflowInstance();
|
||||
workflowInstance.id = createGlobalId(new Long(instance.getId()).toString());
|
||||
workflowInstance.definition = createWorkflowDefinition(instance.getProcessDefinition());
|
||||
workflowInstance.active = !instance.hasEnded();
|
||||
return workflowInstance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a Workflow Definition
|
||||
*
|
||||
* @param definition JBoss Process Definition
|
||||
* @return Workflow Definition
|
||||
*/
|
||||
protected WorkflowDefinition createWorkflowDefinition(ProcessDefinition definition)
|
||||
{
|
||||
WorkflowDefinition workflowDef = new WorkflowDefinition();
|
||||
workflowDef.id = createGlobalId(new Long(definition.getId()).toString());
|
||||
workflowDef.name = definition.getName();
|
||||
Task startTask = definition.getTaskMgmtDefinition().getStartTask();
|
||||
if (startTask != null)
|
||||
{
|
||||
workflowDef.startTaskDefinition = createWorkflowTaskDefinition(startTask);
|
||||
}
|
||||
|
||||
return workflowDef;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a Workflow Task
|
||||
*
|
||||
* @param task JBoss Task Instance
|
||||
* @return Workflow Task
|
||||
*/
|
||||
protected WorkflowTask createWorkflowTask(TaskInstance task)
|
||||
{
|
||||
WorkflowTask workflowTask = new WorkflowTask();
|
||||
workflowTask.id = createGlobalId(new Long(task.getId()).toString());
|
||||
workflowTask.name = task.getName();
|
||||
workflowTask.path = createWorkflowPath(task.getToken());
|
||||
workflowTask.state = getWorkflowTaskState(task);
|
||||
workflowTask.definition = createWorkflowTaskDefinition(task.getTask());
|
||||
|
||||
// TODO: Properties and Associations
|
||||
|
||||
return workflowTask;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a Workflow Task Definition
|
||||
*
|
||||
* @param task JBoss JBPM Task
|
||||
* @return Workflow Task Definition
|
||||
*/
|
||||
protected WorkflowTaskDefinition createWorkflowTaskDefinition(Task task)
|
||||
{
|
||||
// TODO: Extend jBPM task instance to include dictionary definition qname
|
||||
WorkflowTaskDefinition taskDef = new WorkflowTaskDefinition();
|
||||
taskDef.id = task.getName();
|
||||
QName typeName = QName.createQName(taskDef.id, namespaceService);
|
||||
taskDef.metadata = dictionaryService.getType(typeName);
|
||||
return taskDef;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Workflow Task State for the specified JBoss JBPM Task
|
||||
*
|
||||
* @param task task
|
||||
* @return task state
|
||||
*/
|
||||
protected WorkflowTaskState getWorkflowTaskState(TaskInstance task)
|
||||
{
|
||||
if (task.hasEnded())
|
||||
{
|
||||
return WorkflowTaskState.COMPLETED;
|
||||
}
|
||||
else
|
||||
{
|
||||
return WorkflowTaskState.IN_PROGRESS;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
215
source/java/org/alfresco/repo/workflow/jbpm/JBPMEngineTest.java
Normal file
215
source/java/org/alfresco/repo/workflow/jbpm/JBPMEngineTest.java
Normal file
@@ -0,0 +1,215 @@
|
||||
/*
|
||||
* 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.jbpm;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.alfresco.repo.workflow.BPMEngineRegistry;
|
||||
import org.alfresco.repo.workflow.TaskComponent;
|
||||
import org.alfresco.repo.workflow.WorkflowComponent;
|
||||
import org.alfresco.repo.workflow.WorkflowDefinitionComponent;
|
||||
import org.alfresco.service.cmr.workflow.WorkflowDefinition;
|
||||
import org.alfresco.service.cmr.workflow.WorkflowException;
|
||||
import org.alfresco.service.cmr.workflow.WorkflowInstance;
|
||||
import org.alfresco.service.cmr.workflow.WorkflowPath;
|
||||
import org.alfresco.service.cmr.workflow.WorkflowTask;
|
||||
import org.alfresco.service.cmr.workflow.WorkflowTaskState;
|
||||
import org.alfresco.service.namespace.NamespaceService;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
import org.alfresco.util.BaseSpringTest;
|
||||
|
||||
|
||||
/**
|
||||
* JBPM Engine Tests
|
||||
*
|
||||
* @author davidc
|
||||
*/
|
||||
public class JBPMEngineTest extends BaseSpringTest
|
||||
{
|
||||
WorkflowDefinitionComponent workflowDefinitionComponent;
|
||||
WorkflowComponent workflowComponent;
|
||||
TaskComponent taskComponent;
|
||||
|
||||
|
||||
//@Override
|
||||
protected void onSetUpInTransaction() throws Exception
|
||||
{
|
||||
BPMEngineRegistry registry = (BPMEngineRegistry)applicationContext.getBean("bpm_engineRegistry");
|
||||
workflowDefinitionComponent = registry.getWorkflowDefinitionComponent("jbpm");
|
||||
workflowComponent = registry.getWorkflowComponent("jbpm");
|
||||
taskComponent = registry.getTaskComponent("jbpm");
|
||||
}
|
||||
|
||||
|
||||
public void testGetWorkflowDefinitions()
|
||||
{
|
||||
List<WorkflowDefinition> workflowDefs = workflowDefinitionComponent.getDefinitions();
|
||||
assertNotNull(workflowDefs);
|
||||
assertTrue(workflowDefs.size() > 0);
|
||||
}
|
||||
|
||||
|
||||
public void testStartWorkflow()
|
||||
{
|
||||
try
|
||||
{
|
||||
@SuppressWarnings("unused") WorkflowPath path = workflowComponent.startWorkflow("norfolknchance", null);
|
||||
fail("Failed to catch invalid definition id");
|
||||
}
|
||||
catch(WorkflowException e)
|
||||
{
|
||||
}
|
||||
|
||||
// TODO: Determine why process definition is loaded, even though it doesn't exist
|
||||
// try
|
||||
// {
|
||||
// @SuppressWarnings("unused") WorkflowPosition pos = workflowComponent.startProcess("1000", null);
|
||||
// fail("Failed to catch workflow definition id that does not exist");
|
||||
// }
|
||||
// catch(WorkflowException e)
|
||||
// {
|
||||
// }
|
||||
|
||||
WorkflowDefinition workflowDef = getTestDefinition();
|
||||
WorkflowPath path = workflowComponent.startWorkflow(workflowDef.id, null);
|
||||
assertNotNull(path);
|
||||
assertTrue(path.id.endsWith("::/"));
|
||||
assertNotNull(path.node);
|
||||
assertNotNull(path.instance);
|
||||
assertEquals(workflowDef.id, path.instance.definition.id);
|
||||
}
|
||||
|
||||
|
||||
public void testGetWorkflowInstances()
|
||||
{
|
||||
WorkflowDefinition workflowDef = getTestDefinition();
|
||||
workflowComponent.startWorkflow(workflowDef.id, null);
|
||||
workflowComponent.startWorkflow(workflowDef.id, null);
|
||||
List<WorkflowInstance> instances = workflowComponent.getActiveWorkflows(workflowDef.id);
|
||||
assertNotNull(instances);
|
||||
assertEquals(2, instances.size());
|
||||
for (WorkflowInstance instance : instances)
|
||||
{
|
||||
assertEquals(workflowDef.id, instance.definition.id);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void testGetPositions()
|
||||
{
|
||||
WorkflowDefinition workflowDef = getTestDefinition();
|
||||
workflowComponent.startWorkflow(workflowDef.id, null);
|
||||
List<WorkflowInstance> instances = workflowComponent.getActiveWorkflows(workflowDef.id);
|
||||
assertNotNull(instances);
|
||||
assertEquals(1, instances.size());
|
||||
List<WorkflowPath> paths = workflowComponent.getWorkflowPaths(instances.get(0).id);
|
||||
assertNotNull(paths);
|
||||
assertEquals(1, paths.size());
|
||||
assertEquals(instances.get(0).id, paths.get(0).instance.id);
|
||||
assertTrue(paths.get(0).id.endsWith("::/"));
|
||||
}
|
||||
|
||||
|
||||
public void testCancelWorkflowInstance()
|
||||
{
|
||||
WorkflowDefinition workflowDef = getTestDefinition();
|
||||
workflowComponent.startWorkflow(workflowDef.id, null);
|
||||
List<WorkflowInstance> instances1 = workflowComponent.getActiveWorkflows(workflowDef.id);
|
||||
assertNotNull(instances1);
|
||||
assertEquals(1, instances1.size());
|
||||
WorkflowInstance cancelledInstance = workflowComponent.cancelWorkflow(instances1.get(0).id);
|
||||
assertNotNull(cancelledInstance);
|
||||
assertFalse(cancelledInstance.active);
|
||||
List<WorkflowInstance> instances2 = workflowComponent.getActiveWorkflows(workflowDef.id);
|
||||
assertNotNull(instances2);
|
||||
assertEquals(0, instances2.size());
|
||||
}
|
||||
|
||||
|
||||
public void testSignal()
|
||||
{
|
||||
WorkflowDefinition workflowDef = getTestDefinition();
|
||||
Map<QName, Serializable> parameters = new HashMap<QName, Serializable>();
|
||||
parameters.put(QName.createQName(NamespaceService.DEFAULT_URI, "reviewer"), "admin");
|
||||
WorkflowPath path = workflowComponent.startWorkflow(workflowDef.id, parameters);
|
||||
assertNotNull(path);
|
||||
WorkflowPath updatedPath = workflowComponent.signal(path.id, path.node.transitions[0]);
|
||||
assertNotNull(updatedPath);
|
||||
}
|
||||
|
||||
|
||||
public void testGetAssignedTasks()
|
||||
{
|
||||
WorkflowDefinition workflowDef = getTestDefinition();
|
||||
Map<QName, Serializable> parameters = new HashMap<QName, Serializable>();
|
||||
parameters.put(QName.createQName(NamespaceService.DEFAULT_URI, "reviewer"), "admin");
|
||||
WorkflowPath path = workflowComponent.startWorkflow(workflowDef.id, parameters);
|
||||
assertNotNull(path);
|
||||
assertNotNull(path);
|
||||
WorkflowPath updatedPath = workflowComponent.signal(path.id, path.node.transitions[0]);
|
||||
assertNotNull(updatedPath);
|
||||
List<WorkflowTask> completedTasks = taskComponent.getAssignedTasks("admin", WorkflowTaskState.COMPLETED);
|
||||
assertNotNull(completedTasks);
|
||||
assertEquals(0, completedTasks.size());
|
||||
List<WorkflowTask> assignedTasks = taskComponent.getAssignedTasks("admin", WorkflowTaskState.IN_PROGRESS);
|
||||
assertNotNull(assignedTasks);
|
||||
assertEquals(1, assignedTasks.size());
|
||||
assertEquals("Review", assignedTasks.get(0).name);
|
||||
}
|
||||
|
||||
|
||||
public void testEndTask()
|
||||
{
|
||||
WorkflowDefinition workflowDef = getTestDefinition();
|
||||
Map<QName, Serializable> parameters = new HashMap<QName, Serializable>();
|
||||
parameters.put(QName.createQName(NamespaceService.DEFAULT_URI, "reviewer"), "admin");
|
||||
WorkflowPath path = workflowComponent.startWorkflow(workflowDef.id, parameters);
|
||||
assertNotNull(path);
|
||||
assertNotNull(path);
|
||||
List<WorkflowTask> tasks1 = workflowComponent.getTasksForWorkflowPath(path.id);
|
||||
assertNotNull(tasks1);
|
||||
assertEquals(1, tasks1.size());
|
||||
assertEquals(WorkflowTaskState.IN_PROGRESS, tasks1.get(0).state);
|
||||
WorkflowTask updatedTask = taskComponent.endTask(tasks1.get(0).id, null);
|
||||
assertNotNull(updatedTask);
|
||||
assertEquals(WorkflowTaskState.COMPLETED, updatedTask.state);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Locate the Test Workflow Definition
|
||||
*
|
||||
* @return workflow definition
|
||||
*/
|
||||
private WorkflowDefinition getTestDefinition()
|
||||
{
|
||||
List<WorkflowDefinition> workflowDefs = workflowDefinitionComponent.getDefinitions();
|
||||
for (WorkflowDefinition workflowDef : workflowDefs)
|
||||
{
|
||||
if (workflowDef.name.equals("Review and Approve"))
|
||||
{
|
||||
return workflowDef;
|
||||
}
|
||||
}
|
||||
fail("Test Workflow Definition not found");
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
@@ -38,6 +38,7 @@ import org.alfresco.service.cmr.security.PermissionService;
|
||||
import org.alfresco.service.cmr.version.VersionService;
|
||||
import org.alfresco.service.cmr.view.ExporterService;
|
||||
import org.alfresco.service.cmr.view.ImporterService;
|
||||
import org.alfresco.service.cmr.workflow.WorkflowService;
|
||||
import org.alfresco.service.descriptor.DescriptorService;
|
||||
import org.alfresco.service.namespace.NamespaceService;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
@@ -81,6 +82,7 @@ public interface ServiceRegistry
|
||||
static final QName TEMPLATE_SERVICE = QName.createQName(NamespaceService.ALFRESCO_URI, "TemplateService");
|
||||
static final QName FILE_FOLDER_SERVICE = QName.createQName(NamespaceService.ALFRESCO_URI, "FileFolderService");
|
||||
static final QName SCRIPT_SERVICE = QName.createQName(NamespaceService.ALFRESCO_URI, "ScriptService");
|
||||
static final QName WORKFLOW_SERVICE = QName.createQName(NamespaceService.ALFRESCO_URI, "WorkflowService");
|
||||
|
||||
/**
|
||||
* Get the list of services provided by the Repository
|
||||
@@ -254,4 +256,10 @@ public interface ServiceRegistry
|
||||
*/
|
||||
@NotAuditable
|
||||
ScriptService getScriptService();
|
||||
|
||||
/**
|
||||
* @return the workflow service (or null if one is not provided)
|
||||
*/
|
||||
@NotAuditable
|
||||
WorkflowService getWorkflowService();
|
||||
}
|
||||
|
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* 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.service.cmr.workflow;
|
||||
|
||||
|
||||
/**
|
||||
* Workflow Definition Data Object
|
||||
*
|
||||
* @author davidc
|
||||
*/
|
||||
public class WorkflowDefinition
|
||||
{
|
||||
/** Workflow Definition unique id */
|
||||
public String id;
|
||||
|
||||
/** Workflow Definition name */
|
||||
public String name;
|
||||
|
||||
/** Task Definition for Workflow Start Task (Optional) */
|
||||
public WorkflowTaskDefinition startTaskDefinition;
|
||||
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see java.lang.Object#toString()
|
||||
*/
|
||||
public String toString()
|
||||
{
|
||||
return "WorkflowDefinition[id=" + id + ",name=" + name + ",startTask=" + startTaskDefinition.toString() + "]";
|
||||
}
|
||||
}
|
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
* 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.service.cmr.workflow;
|
||||
|
||||
import org.alfresco.error.AlfrescoRuntimeException;
|
||||
|
||||
/**
|
||||
* Base Exception of Workflow Exceptions.
|
||||
*
|
||||
* @author David Caruana
|
||||
*/
|
||||
public class WorkflowException extends AlfrescoRuntimeException
|
||||
{
|
||||
private static final long serialVersionUID = -7338963365877285084L;
|
||||
|
||||
public WorkflowException(String msgId)
|
||||
{
|
||||
super(msgId);
|
||||
}
|
||||
|
||||
public WorkflowException(String msgId, Throwable cause)
|
||||
{
|
||||
super(msgId, cause);
|
||||
}
|
||||
|
||||
public WorkflowException(String msgId, Object ... args)
|
||||
{
|
||||
super(msgId, args);
|
||||
}
|
||||
|
||||
public WorkflowException(String msgId, Throwable cause, Object ... args)
|
||||
{
|
||||
super(msgId, args, cause);
|
||||
}
|
||||
}
|
@@ -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.service.cmr.workflow;
|
||||
|
||||
|
||||
/**
|
||||
* Workflow Instance Data Object
|
||||
*
|
||||
* Represents an "in-flight" workflow.
|
||||
*
|
||||
* @author davidc
|
||||
*/
|
||||
public class WorkflowInstance
|
||||
{
|
||||
/** Workflow Instance unique id */
|
||||
public String id;
|
||||
|
||||
/** Is this Workflow instance still "in-flight" or has it completed? */
|
||||
public boolean active;
|
||||
|
||||
/** Workflow Definition */
|
||||
public WorkflowDefinition definition;
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see java.lang.Object#toString()
|
||||
*/
|
||||
public String toString()
|
||||
{
|
||||
return "WorkflowInstance[id=" + id + ",active=" + active + ",def=" + definition.toString() + "]";
|
||||
}
|
||||
}
|
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* 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.service.cmr.workflow;
|
||||
|
||||
|
||||
/**
|
||||
* Workflow Node Data Object
|
||||
*
|
||||
* Represents a Node within the Workflow Definition.
|
||||
*
|
||||
* @author davidc
|
||||
*/
|
||||
public class WorkflowNode
|
||||
{
|
||||
/** Name of the Workflow Node */
|
||||
public String name;
|
||||
|
||||
/** Type of the Workflow Node (typically this is BPM engine specific - informational only */
|
||||
public String type;
|
||||
|
||||
/** Does this Workflow Node represent human interaction? */
|
||||
public boolean isTaskNode;
|
||||
|
||||
/** The transitions leaving this node (or null, if none) */
|
||||
public String[] transitions;
|
||||
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see java.lang.Object#toString()
|
||||
*/
|
||||
public String toString()
|
||||
{
|
||||
String transitionsArray = "{";
|
||||
for (int i = 0; i < transitions.length; i++)
|
||||
{
|
||||
transitionsArray += ((i == 0) ? "" : ",") + "'" + transitions[i] + "'";
|
||||
}
|
||||
transitionsArray += "}";
|
||||
return "WorkflowNode[name=" + name + ",type=" + type + ",transitions=" + transitionsArray + "]";
|
||||
}
|
||||
}
|
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
* 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.service.cmr.workflow;
|
||||
|
||||
|
||||
/**
|
||||
* Workflow Path Data Object
|
||||
*
|
||||
* Represents a path within an "in-flight" workflow instance.
|
||||
*
|
||||
* Simple workflows consists of a single "root" path. Multiple paths occur when a workflow
|
||||
* instance branches, therefore more than one concurrent path is taken.
|
||||
*
|
||||
* @author davidc
|
||||
*/
|
||||
public class WorkflowPath
|
||||
{
|
||||
/** Unique id of Workflow Path */
|
||||
public String id;
|
||||
|
||||
/** Workflow Instance this path is part of */
|
||||
public WorkflowInstance instance;
|
||||
|
||||
/** The Workflow Node the path is at */
|
||||
public WorkflowNode node;
|
||||
|
||||
/** Is the path still active? */
|
||||
public boolean active;
|
||||
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see java.lang.Object#toString()
|
||||
*/
|
||||
public String toString()
|
||||
{
|
||||
return "WorkflowPath[id=" + id + ",instance=" + instance.toString() + ",active=" + active + ",node=" + node.toString()+ "]";
|
||||
}
|
||||
}
|
@@ -0,0 +1,194 @@
|
||||
/*
|
||||
* 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.service.cmr.workflow;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
|
||||
|
||||
/**
|
||||
* Workflow Service.
|
||||
*
|
||||
* Client facing API for interacting with Alfresco Workflows and Tasks.
|
||||
*
|
||||
* @author davidc
|
||||
*/
|
||||
public interface WorkflowService
|
||||
{
|
||||
//
|
||||
// Workflow Definition Management
|
||||
//
|
||||
|
||||
/**
|
||||
* Deploy a Workflow Definition to the Alfresco Repository
|
||||
*
|
||||
* Note: The specified content object must be of type bpm:workflowdefinition.
|
||||
* This type describes for which BPM engine the definition is appropriate.
|
||||
*
|
||||
* @param workflowDefinition the content object containing the definition
|
||||
* @return workflow definition
|
||||
*/
|
||||
public WorkflowDefinition deployDefinition(NodeRef workflowDefinition);
|
||||
|
||||
/**
|
||||
* Undeploy an exisiting Workflow Definition
|
||||
*
|
||||
* TODO: Determine behaviour when "in-flight" workflow instances exist
|
||||
*
|
||||
* @param workflowDefinitionId the id of the definition to undeploy
|
||||
*/
|
||||
public void undeployDefinition(String workflowDefinitionId);
|
||||
|
||||
/**
|
||||
* Gets all deployed Workflow Definitions
|
||||
*
|
||||
* @return the deployed workflow definitions
|
||||
*/
|
||||
public List<WorkflowDefinition> getDefinitions();
|
||||
|
||||
/**
|
||||
* Gets a Workflow Definition by unique Id
|
||||
*
|
||||
* @param workflowDefinitionId the workflow definition id
|
||||
* @return the deployed workflow definition
|
||||
*/
|
||||
public WorkflowDefinition getDefinitionById(String workflowDefinitionId);
|
||||
|
||||
|
||||
//
|
||||
// Workflow Instance Management
|
||||
//
|
||||
|
||||
|
||||
/**
|
||||
* Start a Workflow Instance
|
||||
*
|
||||
* @param workflowDefinitionId the workflow definition id
|
||||
* @param parameters the initial set of parameters used to populate the "Start Task" properties
|
||||
* @return the initial workflow path
|
||||
*/
|
||||
public WorkflowPath startWorkflow(String workflowDefinitionId, Map<QName, Serializable> parameters);
|
||||
|
||||
/**
|
||||
* Start a Workflow Instance from an existing "Start Task" template node held in the
|
||||
* Repository. The node must be of the Type as described in the Workflow Definition.
|
||||
*
|
||||
* @param templateDefinition the node representing the Start Task properties
|
||||
* @return the initial workflow path
|
||||
*/
|
||||
public WorkflowPath startWorkflowFromTemplate(NodeRef templateDefinition);
|
||||
|
||||
/**
|
||||
* Gets all "in-flight" workflow instances of the specified Workflow Definition
|
||||
*
|
||||
* @param workflowDefinitionId the workflow definition id
|
||||
* @return the list of "in-fligth" workflow instances
|
||||
*/
|
||||
public List<WorkflowInstance> getActiveWorkflows(String workflowDefinitionId);
|
||||
|
||||
/**
|
||||
* Gets all Paths for the specified Workflow instance
|
||||
*
|
||||
* @param workflowId workflow instance id
|
||||
* @return the list of workflow paths
|
||||
*/
|
||||
public List<WorkflowPath> getWorkflowPaths(String workflowId);
|
||||
|
||||
/**
|
||||
* Cancel an "in-fligth" Workflow instance
|
||||
*
|
||||
* @param workflowId the workflow instance to cancel
|
||||
* @return an updated representation of the workflow instance
|
||||
*/
|
||||
public WorkflowInstance cancelWorkflow(String workflowId);
|
||||
|
||||
/**
|
||||
* Signal the transition from one Workflow Node to another
|
||||
*
|
||||
* @param pathId the workflow path to signal on
|
||||
* @param transition the transition to follow (or null, for the default transition)
|
||||
* @return the updated workflow path
|
||||
*/
|
||||
public WorkflowPath signal(String pathId, String transition);
|
||||
|
||||
/**
|
||||
* Gets all Tasks associated with the specified path
|
||||
*
|
||||
* @param pathId the path id
|
||||
* @return the list of associated tasks
|
||||
*/
|
||||
public List<WorkflowTask> getTasksForWorkflowPath(String pathId);
|
||||
|
||||
|
||||
//
|
||||
// Task Management
|
||||
//
|
||||
|
||||
/**
|
||||
* Gets a Task by unique Id
|
||||
*
|
||||
* @param taskId the task id
|
||||
* @return the task
|
||||
*/
|
||||
public WorkflowTask getTaskById(String taskId);
|
||||
|
||||
/**
|
||||
* Gets all tasks assigned to the specified authority
|
||||
*
|
||||
* @param authority the authority
|
||||
* @param state filter by specified workflow task state
|
||||
* @return the list of assigned tasks
|
||||
*/
|
||||
public List<WorkflowTask> getAssignedTasks(String authority, WorkflowTaskState state);
|
||||
|
||||
/**
|
||||
* Gets the pooled tasks available to the specified authority
|
||||
*
|
||||
* @param authority the authority
|
||||
* @return the list of pooled tasks
|
||||
*/
|
||||
public List<WorkflowTask> getPooledTasks(String authority);
|
||||
|
||||
/**
|
||||
* Update the Properties and Associations of a Task
|
||||
*
|
||||
* @param taskId the task id to update
|
||||
* @param properties the map of properties to set on the task (or null, if none to set)
|
||||
* @param add the map of items to associate with the task (or null, if none to add)
|
||||
* @param remove the map of items to dis-associate with the task (or null, if none to remove)
|
||||
* @return the update task
|
||||
*/
|
||||
public WorkflowTask updateTask(String taskId, Map<QName, Serializable> properties, Map<QName, List<NodeRef>> add, Map<QName, List<NodeRef>> remove);
|
||||
|
||||
/**
|
||||
* End the Task (i.e. complete the task)
|
||||
*
|
||||
* @param taskId the task id to end
|
||||
* @param transition the task transition to take on completion (or null, for the default transition)
|
||||
* @return the updated task
|
||||
*/
|
||||
public WorkflowTask endTask(String taskId, String transition);
|
||||
|
||||
|
||||
// todo: workflow package apis
|
||||
// createPackage
|
||||
|
||||
}
|
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
* 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.service.cmr.workflow;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
|
||||
|
||||
/**
|
||||
* Workflow Task Data Object
|
||||
*
|
||||
* Represents a human-oriented task within an "in-fligth" workflow instance
|
||||
*
|
||||
* @author davidc
|
||||
*/
|
||||
public class WorkflowTask
|
||||
{
|
||||
/** Unique id of Task */
|
||||
public String id;
|
||||
|
||||
/** Name of Task */
|
||||
public String name;
|
||||
|
||||
/** Task State */
|
||||
public WorkflowTaskState state;
|
||||
|
||||
/** Workflow path this Task is associated with */
|
||||
public WorkflowPath path;
|
||||
|
||||
/** Task Definition */
|
||||
public WorkflowTaskDefinition definition;
|
||||
|
||||
/** Task Properties as described by Task Definition */
|
||||
public Map<QName, Serializable> properties;
|
||||
|
||||
/** Task Associations as described by Task Definition */
|
||||
public Map<QName, List<NodeRef>> associations;
|
||||
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see java.lang.Object#toString()
|
||||
*/
|
||||
public String toString()
|
||||
{
|
||||
return "WorkflowTask[id=" + id + ",name=" + name + ",state=" + state + ",def=" + definition + ",path=" + path.toString() + "]";
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* 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.service.cmr.workflow;
|
||||
|
||||
import org.alfresco.service.cmr.dictionary.TypeDefinition;
|
||||
|
||||
|
||||
/**
|
||||
* Workflow Task Definition Data Object.
|
||||
*
|
||||
* Represents meta-data for a Workflow Task. The meta-data is described in terms
|
||||
* of the Alfresco Data Dictionary.
|
||||
*
|
||||
* @author davidc
|
||||
*/
|
||||
public class WorkflowTaskDefinition
|
||||
{
|
||||
/** Unique id of Workflow Task Definition */
|
||||
public String id;
|
||||
|
||||
// TODO: Convert to TaskDefinition (derived from TypeDefinition)
|
||||
/** Task Metadata */
|
||||
public TypeDefinition metadata;
|
||||
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see java.lang.Object#toString()
|
||||
*/
|
||||
public String toString()
|
||||
{
|
||||
return "WorkflowTaskDefinition[id=" + id + ",metadata=" + metadata + "]";
|
||||
}
|
||||
}
|
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* 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.service.cmr.workflow;
|
||||
|
||||
|
||||
/**
|
||||
* Workflow Task State
|
||||
*
|
||||
* Represents the high-level state of Workflow Task (in relation to "in-flight"
|
||||
* workflow instance).
|
||||
*
|
||||
* A user-defined task state may be represented as Task Property (and described
|
||||
* by the Alfresco Data Dictionary).
|
||||
*
|
||||
* @author davidc
|
||||
*/
|
||||
public enum WorkflowTaskState
|
||||
{
|
||||
IN_PROGRESS,
|
||||
COMPLETED;
|
||||
}
|
Reference in New Issue
Block a user