All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.jboss.seam.bpm.BusinessProcess Maven / Gradle / Ivy

There is a newer version: 3.2.26.ayg
Show newest version
package org.jboss.seam.bpm;

import static org.jboss.seam.annotations.Install.BUILT_IN;

import java.io.Serializable;

import org.jboss.seam.Component;
import org.jboss.seam.ScopeType;
import org.jboss.seam.annotations.Install;
import org.jboss.seam.annotations.Name;
import org.jboss.seam.annotations.Scope;
import org.jboss.seam.annotations.intercept.BypassInterceptors;
import org.jboss.seam.contexts.Contexts;
import org.jboss.seam.core.AbstractMutable;
import org.jboss.seam.core.Events;
import org.jboss.seam.international.StatusMessage;
import org.jboss.seam.international.StatusMessages;
import org.jbpm.graph.def.ProcessDefinition;
import org.jbpm.graph.exe.ProcessInstance;
import org.jbpm.taskmgmt.exe.TaskInstance;

/**
 * Holds the task and process ids for the current conversation,
 * and provides programmatic control over the business process.
 * 
 * @author Gavin King
 *
 */
@Scope(ScopeType.CONVERSATION)
@Name("org.jboss.seam.bpm.businessProcess")
@BypassInterceptors
@Install(dependencies = "org.jboss.seam.bpm.jbpm", precedence = BUILT_IN)
public class BusinessProcess extends AbstractMutable implements Serializable {

	private static final long serialVersionUID = 4722350870845851070L;
	private Long processId;
	private Long taskId;

	public BusinessProcess() {
		super();
	}
	
	public static BusinessProcess instance() {
		if (!Contexts.isConversationContextActive()) {
			throw new IllegalStateException("No active conversation context");
		}
		return (BusinessProcess) Component.getInstance(BusinessProcess.class, ScopeType.CONVERSATION);
	}

	/**
	* Is there a process instance associated with 
	* the current conversation?
	*/
	public boolean hasCurrentProcess() {
		return processId != null;
	}

	/**
	* Is there a process instance that has not ended 
	* associated with the current conversation?
	*/
	public boolean hasActiveProcess() {
		return hasCurrentProcess() && org.jboss.seam.bpm.ProcessInstance.instance() != null
				&& !org.jboss.seam.bpm.ProcessInstance.instance().hasEnded();
	}

	/**
	* Is there a task instance associated with 
	* the current conversation?
	*/
	public boolean hasCurrentTask() {
		return taskId != null;
	}

	/**
	* The jBPM process instance id associated with
	* the current conversation.
	*/
	public Long getProcessId() {
		return processId;
	}

	/**
	* Set the process instance id, without validating
	* that the process instance actually exists.
	*/
	public void setProcessId(Long processId) {
		setDirty(this.processId, processId);
		this.processId = processId;
	}

	/**
	* The jBPM task instance id associated with
	* the current conversation.
	*/
	public Long getTaskId() {
		return taskId;
	}

	/**
	* Set the task instance id, without validating
	* that the task instance actually exists.
	*/
	public void setTaskId(Long taskId) {
		setDirty(this.taskId, taskId);
		this.taskId = taskId;
	}

	/**
	* Create a process instance and associate it with the
	* current conversation.
	* 
	* @param processDefinitionName the jBPM process definition name
	*/
	public void createProcess(String processDefinitionName) {
		createProcess(processDefinitionName, true);
	}

	/**
	* Create a process instance and associate it with the
	* current conversation.
	* 
	* @param processDefinitionName the jBPM process definition name
	*/
	public void createProcess(String processDefinitionName, boolean shouldSignalProcess) {
		ProcessInstance process = ManagedJbpmContext.instance().newProcessInstanceForUpdate(processDefinitionName);
		afterCreateProcess(processDefinitionName, process, shouldSignalProcess);
	}

	/**
	* Create a process instance and associate it with the
	* current conversation.
	* 
	* @param processDefinitionName the jBPM process definition name
	* @param businessKey the business key of the new process definition
	*/
	public void createProcess(String processDefinitionName, String businessKey) {
		/*ProcessInstance process = ManagedJbpmContext.instance().getGraphSession()
		       .findLatestProcessDefinition(processDefinitionName)
		       .createProcessInstance(Collections.EMPTY_MAP, businessKey);*/
		ProcessInstance process = ManagedJbpmContext.instance().newProcessInstanceForUpdate(processDefinitionName);
		process.setKey(businessKey);
		afterCreateProcess(processDefinitionName, process, true);
	}

	private void afterCreateProcess(String processDefinitionName, ProcessInstance process, boolean shouldSignalProcess) {
		setProcessId(process.getId());
		// need to set process variables before the signal
		Contexts.getBusinessProcessContext().flush();
		if (shouldSignalProcess) {
			process.signal();
		}

		Events.instance().raiseEvent("org.jboss.seam.createProcess." + processDefinitionName);
	}

	/**
	* Start the current task, using the current actor id
	* 
	* @see Actor
	*/
	public void startTask() {
		String actorId = Actor.instance().getId();
		TaskInstance task = org.jboss.seam.bpm.TaskInstance.instance();
		if (actorId != null) {
			task.start(actorId);
		} else {
			task.start();
		}

		Events.instance().raiseEvent("org.jboss.seam.startTask." + task.getTask().getName());
	}

	/**
	* End the current task, via the given transition. If no transition name 
	* is given, check the Transition component for a transition, or use the 
	* default transition.
	* 
	* @param transitionName the jBPM transition name, or null
	*/
	public void endTask(String transitionName) {
		TaskInstance task = org.jboss.seam.bpm.TaskInstance.instance();
		if (task == null) {
			throw new IllegalStateException("no task instance associated with context");
		}

		if (transitionName == null || "".equals(transitionName)) {
			transitionName = Transition.instance().getName();
		}

		if (transitionName == null) {
			task.end();
		} else {
			task.end(transitionName);
		}

		setTaskId(null); //TODO: do I really need this???!

		Events.instance().raiseEvent("org.jboss.seam.endTask." + task.getTask().getName());
		ProcessInstance process = org.jboss.seam.bpm.ProcessInstance.instance();
		if (process.hasEnded()) {
			Events.instance().raiseEvent("org.jboss.seam.endProcess." + process.getProcessDefinition().getName());
		}
	}

	/**
	* Signal the given transition for the current process instance.
	* 
	* @param transitionName the jBPM transition name 
	*/
	public void transition(String transitionName) {
		ProcessInstance process = org.jboss.seam.bpm.ProcessInstance.instance();
		process.signal(transitionName);
		if (process.hasEnded()) {
			Events.instance().raiseEvent("org.jboss.seam.endProcess." + process.getProcessDefinition().getName());
		}
	}

	/**
	* Associate the task instance with the given id with the current
	* conversation.
	* 
	* @param taskId the jBPM task instance id
	* @return true if the task was found and was not ended
	*/
	public boolean resumeTask(Long taskId) {
		setTaskId(taskId);
		TaskInstance task = org.jboss.seam.bpm.TaskInstance.instance();
		if (task == null) {
			taskNotFound(taskId);
			return false;
		} else if (task.hasEnded()) {
			taskEnded(taskId);
			return false;
		} else {
			setProcessId(task.getTaskMgmtInstance().getProcessInstance().getId());
			Events.instance().raiseEvent("org.jboss.seam.initTask." + task.getTask().getName());
			return true;
		}
	}

	/**
	* Associate the process instance with the given id with the 
	* current conversation.
	* 
	* @param processId the jBPM process instance id
	* @return true if the process was found and was not ended
	*/
	public boolean resumeProcess(Long processId) {
		setProcessId(processId);
		ProcessInstance process = org.jboss.seam.bpm.ProcessInstance.instance();
		return afterResumeProcess(processId, process);
	}

	/**
	* Associate the process instance with the given business key 
	* with the current conversation.
	* 
	* @param processDefinition the jBPM process definition name
	* @param key the jBPM process instance key
	* @return true if the process was found and was not ended
	*/
	public boolean resumeProcess(String processDefinition, String key) {
		ProcessDefinition definition = ManagedJbpmContext.instance().getGraphSession().findLatestProcessDefinition(processDefinition);
		ProcessInstance process = definition == null ? null : ManagedJbpmContext.instance().getProcessInstanceForUpdate(definition, key);
		if (process != null) {
			setProcessId(process.getId());
		}
		return afterResumeProcess(key, process);
	}

	private boolean afterResumeProcess(long processId, ProcessInstance process) {
		if (process == null) {
			processNotFound(processId);
			return false;
		} else if (process.hasEnded()) {
			processEnded(processId);
			return false;
		} else {
			Events.instance().raiseEvent("org.jboss.seam.initProcess." + process.getProcessDefinition().getName());
			return true;
		}
	}

	private boolean afterResumeProcess(String processKey, ProcessInstance process) {
		if (process == null) {
			processNotFound(processKey);
			return false;
		} else if (process.hasEnded()) {
			processEnded(processKey);
			return false;
		} else {
			Events.instance().raiseEvent("org.jboss.seam.initProcess." + process.getProcessDefinition().getName());
			return true;
		}
	}

	/**
	* Check that the task currently associated with the conversation
	* exists and has not ended.
	* 
	* @return true if the task exists and was not ended
	*/
	public boolean validateTask() {
		if (!hasCurrentTask()) {
			taskNotFound(taskId);
			return false;
		} else if (org.jboss.seam.bpm.TaskInstance.instance().hasEnded()) {
			taskEnded(taskId);
			return false;
		} else {
			return true;
		}
	}

	protected void taskNotFound(Long taskId) {
		StatusMessages.instance().addFromResourceBundleOrDefault(StatusMessage.Severity.WARN, "org.jboss.seam.TaskNotFound",
				"Task #0 not found", taskId);
	}

	protected void taskEnded(Long taskId) {
		StatusMessages.instance().addFromResourceBundleOrDefault(StatusMessage.Severity.WARN, "org.jboss.seam.TaskEnded",
				"Task #0 already ended", taskId);
	}

	protected void processEnded(Long processId) {
		StatusMessages.instance().addFromResourceBundleOrDefault(StatusMessage.Severity.WARN, "org.jboss.seam.ProcessEnded",
				"Process #0 already ended", processId);
	}

	protected void processNotFound(Long processId) {
		StatusMessages.instance().addFromResourceBundleOrDefault(StatusMessage.Severity.WARN, "org.jboss.seam.ProcessNotFound",
				"Process #0 not found", processId);
	}

	protected void processEnded(String key) {
		StatusMessages.instance().addFromResourceBundleOrDefault(StatusMessage.Severity.WARN, "org.jboss.seam.ProcessEnded",
				"Process #0 already ended", key);
	}

	protected void processNotFound(String key) {
		StatusMessages.instance().addFromResourceBundleOrDefault(StatusMessage.Severity.WARN, "org.jboss.seam.ProcessNotFound",
				"Process #0 not found", key);
	}

	@Override
	public String toString() {
		return "BusinessProcess(processId=" + processId + ",taskId=" + taskId + ")";
	}

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy