📄 tasknode.java
字号:
/*
* JBoss, Home of Professional Open Source
* Copyright 2005, JBoss Inc., and individual contributors as indicated
* by the @authors tag. See the copyright.txt in the distribution for a
* full listing of individual contributors.
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/
package org.jbpm.graph.node;
import java.util.*;
import org.dom4j.Element;
import org.jbpm.graph.def.*;
import org.jbpm.graph.exe.*;
import org.jbpm.jpdl.el.impl.JbpmExpressionEvaluator;
import org.jbpm.jpdl.xml.*;
import org.jbpm.taskmgmt.def.*;
import org.jbpm.taskmgmt.exe.*;
/**
* is a node that relates to one or more tasks.
* Property <code>signal</code> specifies how task completion
* triggers continuation of execution.
*/
public class TaskNode extends Node implements Parsable {
private static final long serialVersionUID = 1L;
/**
* execution always continues, regardless wether tasks are created or still unfinished.
*/
public static final int SIGNAL_UNSYNCHRONIZED = 0;
/**
* execution never continues, regardless wether tasks are created or still unfinished.
*/
public static final int SIGNAL_NEVER = 1;
/**
* proceeds execution when the first task instance is completed.
* when no tasks are created on entrance of this node, execution is continued.
*/
public static final int SIGNAL_FIRST = 2;
/**
* proceeds execution when the first task instance is completed.
* when no tasks are created on entrance of this node, execution is continued.
*/
public static final int SIGNAL_FIRST_WAIT = 3;
/**
* proceeds execution when the last task instance is completed.
* when no tasks are created on entrance of this node, execution waits in the task node till tasks are created.
*/
public static final int SIGNAL_LAST = 4;
/**
* proceeds execution when the last task instance is completed.
* when no tasks are created on entrance of this node, execution waits in the task node till tasks are created.
*/
public static final int SIGNAL_LAST_WAIT = 5;
public static int parseSignal(String text) {
if ("unsynchronized".equalsIgnoreCase(text)) {
return SIGNAL_UNSYNCHRONIZED;
} else if ("never".equalsIgnoreCase(text)) {
return SIGNAL_NEVER;
} else if ("first".equalsIgnoreCase(text)) {
return SIGNAL_FIRST;
} else if ("first-wait".equalsIgnoreCase(text)) {
return SIGNAL_FIRST_WAIT;
} else if ("last-wait".equalsIgnoreCase(text)) {
return SIGNAL_LAST_WAIT;
} else { // return default
return SIGNAL_LAST;
}
}
public static String signalToString(int signal) {
if (signal==SIGNAL_UNSYNCHRONIZED) {
return "unsynchronized";
} else if (signal==SIGNAL_NEVER) {
return "never";
} else if (signal==SIGNAL_FIRST) {
return "first";
} else if (signal==SIGNAL_FIRST_WAIT) {
return "first-wait";
} else if (signal==SIGNAL_LAST) {
return "last";
} else if (signal==SIGNAL_LAST_WAIT) {
return "last-wait";
} else {
return null;
}
}
Set tasks = null;
int signal = SIGNAL_LAST;
boolean createTasks = true;
boolean endTasks = false;
public TaskNode() {
}
public TaskNode(String name) {
super(name);
}
public void read(Element element, JpdlXmlReader jpdlReader) {
// get the signal
String signalText = element.attributeValue("signal");
if (signalText!=null) {
signal = parseSignal(signalText);
}
// create tasks
String createTasksText = element.attributeValue("create-tasks");
if (createTasksText!=null) {
if (("no".equalsIgnoreCase(createTasksText))
|| ("false".equalsIgnoreCase(createTasksText)) ) {
createTasks = false;
}
}
// create tasks
String removeTasksText = element.attributeValue("end-tasks");
if (removeTasksText!=null) {
if (("yes".equalsIgnoreCase(removeTasksText))
|| ("true".equalsIgnoreCase(removeTasksText)) ) {
endTasks = true;
}
}
// parse the tasks
jpdlReader.readTasks(element, this);
}
public void addTask(Task task) {
if (tasks==null) tasks = new HashSet();
tasks.add(task);
task.setTaskNode(this);
}
// node behaviour methods
/////////////////////////////////////////////////////////////////////////////
public void execute(ExecutionContext executionContext) {
TaskMgmtInstance tmi = getTaskMgmtInstance(executionContext.getToken());
// if this tasknode should create instances
if ( (createTasks)
&& (tasks!=null) ) {
Iterator iter = tasks.iterator();
while (iter.hasNext()) {
Task task = (Task) iter.next();
executionContext.setTask(task);
if (evaluateTaskCondition(task.getCondition(), executionContext)) {
tmi.createTaskInstance(task, executionContext);
}
}
}
// check if we should continue execution
boolean continueExecution = false;
switch (signal) {
case SIGNAL_UNSYNCHRONIZED:
continueExecution = true;
break;
case SIGNAL_FIRST_WAIT:
case SIGNAL_LAST_WAIT:
case SIGNAL_NEVER:
continueExecution = false;
break;
case SIGNAL_FIRST:
case SIGNAL_LAST:
continueExecution = tmi.getSignallingTasks(executionContext).isEmpty();
}
if (continueExecution) {
leave(executionContext);
}
}
boolean evaluateTaskCondition(String condition, ExecutionContext executionContext) {
if (condition==null) return true;
Object result = JbpmExpressionEvaluator.evaluate(condition, executionContext);
if (Boolean.TRUE.equals(result)) {
return true;
}
return false;
}
public void leave(ExecutionContext executionContext, Transition transition) {
TaskMgmtInstance tmi = getTaskMgmtInstance(executionContext.getToken());
if (tmi.hasBlockingTaskInstances(executionContext.getToken()) ) {
throw new IllegalStateException("task-node '"+name+"' still has blocking tasks");
}
removeTaskInstanceSynchronization(executionContext.getToken());
super.leave(executionContext, transition);
}
// task behaviour methods
/////////////////////////////////////////////////////////////////////////////
public boolean completionTriggersSignal(TaskInstance taskInstance) {
boolean completionTriggersSignal = false;
if ( (signal==SIGNAL_FIRST)
|| (signal==SIGNAL_FIRST_WAIT) ) {
completionTriggersSignal = true;
} else if ( ( (signal==SIGNAL_LAST)
|| (signal==SIGNAL_LAST_WAIT) )
&& (isLastToComplete(taskInstance) ) ){
completionTriggersSignal = true;
}
return completionTriggersSignal;
}
boolean isLastToComplete(TaskInstance taskInstance) {
Token token = taskInstance.getToken();
TaskMgmtInstance tmi = getTaskMgmtInstance(token);
boolean isLastToComplete = true;
Iterator iter = tmi.getTaskInstances().iterator();
while ( iter.hasNext()
&& (isLastToComplete) ) {
TaskInstance other = (TaskInstance) iter.next();
if ( (token!=null)
&& (token.equals(other.getToken()))
&& (! other.equals(taskInstance))
&& (other.isSignalling())
&& (!other.hasEnded())
) {
isLastToComplete = false;
}
}
return isLastToComplete;
}
public void removeTaskInstanceSynchronization(Token token) {
TaskMgmtInstance tmi = getTaskMgmtInstance(token);
Collection taskInstances = tmi.getTaskInstances();
if (taskInstances!=null) {
Iterator iter = taskInstances.iterator();
while (iter.hasNext()) {
TaskInstance taskInstance = (TaskInstance) iter.next();
if (token.equals(taskInstance.getToken())) {
// remove signalling
if (taskInstance.isSignalling()) {
taskInstance.setSignalling(false);
}
// remove blocking
if (taskInstance.isBlocking()) {
taskInstance.setBlocking(false);
}
// if this is a non-finished task and all those
// tasks should be finished
if ( (! taskInstance.hasEnded())
&& (endTasks)
) {
if (tasks.contains(taskInstance.getTask())) {
// end this task
taskInstance.end();
}
}
}
}
}
}
TaskMgmtInstance getTaskMgmtInstance(Token token) {
return (TaskMgmtInstance) token.getProcessInstance().getInstance(TaskMgmtInstance.class);
}
// getters and setters
/////////////////////////////////////////////////////////////////////////////
/**
* is a Map with the tasks, keyed by task-name or an empty map in case
* no tasks are present in this task-node.
*/
public Map getTasksMap() {
Map tasksMap = new HashMap();
if (tasks!=null) {
Iterator iter = tasks.iterator();
while (iter.hasNext()) {
Task task = (Task) iter.next();
tasksMap.put(task.getName(), task);
}
}
return tasksMap;
}
/**
* is the task in this task-node with the given name or null if the given task
* does not exist in this node.
*/
public Task getTask(String taskName) {
return (Task) getTasksMap().get(taskName);
}
public Set getTasks() {
return tasks;
}
public int getSignal() {
return signal;
}
public boolean getCreateTasks() {
return createTasks;
}
public boolean isEndTasks() {
return endTasks;
}
public void setCreateTasks(boolean createTasks) {
this.createTasks = createTasks;
}
public void setEndTasks(boolean endTasks) {
this.endTasks = endTasks;
}
public void setSignal(int signal) {
this.signal = signal;
}
public void setTasks(Set tasks) {
this.tasks = tasks;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -