001: /*
002: * JBoss, Home of Professional Open Source
003: * Copyright 2005, JBoss Inc., and individual contributors as indicated
004: * by the @authors tag. See the copyright.txt in the distribution for a
005: * full listing of individual contributors.
006: *
007: * This is free software; you can redistribute it and/or modify it
008: * under the terms of the GNU Lesser General Public License as
009: * published by the Free Software Foundation; either version 2.1 of
010: * the License, or (at your option) any later version.
011: *
012: * This software is distributed in the hope that it will be useful,
013: * but WITHOUT ANY WARRANTY; without even the implied warranty of
014: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
015: * Lesser General Public License for more details.
016: *
017: * You should have received a copy of the GNU Lesser General Public
018: * License along with this software; if not, write to the Free
019: * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
020: * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
021: */
022: package org.jbpm.graph.exe;
023:
024: import java.util.Stack;
025:
026: import org.jbpm.JbpmContext;
027: import org.jbpm.JbpmException;
028: import org.jbpm.context.exe.ContextInstance;
029: import org.jbpm.graph.def.Action;
030: import org.jbpm.graph.def.Event;
031: import org.jbpm.graph.def.GraphElement;
032: import org.jbpm.graph.def.Node;
033: import org.jbpm.graph.def.ProcessDefinition;
034: import org.jbpm.graph.def.Transition;
035: import org.jbpm.module.def.ModuleDefinition;
036: import org.jbpm.module.exe.ModuleInstance;
037: import org.jbpm.job.Timer;
038: import org.jbpm.taskmgmt.def.Task;
039: import org.jbpm.taskmgmt.exe.TaskInstance;
040: import org.jbpm.taskmgmt.exe.TaskMgmtInstance;
041:
042: public class ExecutionContext {
043:
044: protected Token token = null;
045: protected Event event = null;
046: protected GraphElement eventSource = null;
047: protected Action action = null;
048: protected Throwable exception = null;
049: protected Transition transition = null;
050: protected Node transitionSource = null;
051: protected Task task = null;
052: protected Timer timer = null;
053: protected TaskInstance taskInstance = null;
054: protected ProcessInstance subProcessInstance = null;
055:
056: public ExecutionContext(Token token) {
057: this .token = token;
058: }
059:
060: public ExecutionContext(ExecutionContext other) {
061: this .token = other.token;
062: this .event = other.event;
063: this .action = other.action;
064: }
065:
066: public Node getNode() {
067: return token.getNode();
068: }
069:
070: public ProcessDefinition getProcessDefinition() {
071: ProcessInstance processInstance = getProcessInstance();
072: return (processInstance != null ? processInstance
073: .getProcessDefinition() : null);
074: }
075:
076: public void setAction(Action action) {
077: this .action = action;
078: if (action != null) {
079: this .event = action.getEvent();
080: }
081: }
082:
083: public ProcessInstance getProcessInstance() {
084: return token.getProcessInstance();
085: }
086:
087: public String toString() {
088: return "ExecutionContext[" + token + "]";
089: }
090:
091: // convenience methods //////////////////////////////////////////////////////
092:
093: /**
094: * set a process variable.
095: */
096: public void setVariable(String name, Object value) {
097: if (taskInstance != null) {
098: taskInstance.setVariable(name, value);
099: } else {
100: getContextInstance().setVariable(name, value, token);
101: }
102: }
103:
104: /**
105: * get a process variable.
106: */
107: public Object getVariable(String name) {
108: if (taskInstance != null) {
109: return taskInstance.getVariable(name);
110: } else {
111: return getContextInstance().getVariable(name, token);
112: }
113: }
114:
115: /**
116: * leave this node over the default transition. This method is only available
117: * on node actions. Not on actions that are executed on events. Actions on
118: * events cannot change the flow of execution.
119: */
120: public void leaveNode() {
121: getNode().leave(this );
122: }
123:
124: /**
125: * leave this node over the given transition. This method is only available
126: * on node actions. Not on actions that are executed on events. Actions on
127: * events cannot change the flow of execution.
128: */
129: public void leaveNode(String transitionName) {
130: getNode().leave(this , transitionName);
131: }
132:
133: /**
134: * leave this node over the given transition. This method is only available
135: * on node actions. Not on actions that are executed on events. Actions on
136: * events cannot change the flow of execution.
137: */
138: public void leaveNode(Transition transition) {
139: getNode().leave(this , transition);
140: }
141:
142: public ModuleDefinition getDefinition(Class clazz) {
143: return getProcessDefinition().getDefinition(clazz);
144: }
145:
146: public ModuleInstance getInstance(Class clazz) {
147: ProcessInstance processInstance = (token != null ? token
148: .getProcessInstance() : null);
149: return (processInstance != null ? processInstance
150: .getInstance(clazz) : null);
151: }
152:
153: public ContextInstance getContextInstance() {
154: return (ContextInstance) getInstance(ContextInstance.class);
155: }
156:
157: public TaskMgmtInstance getTaskMgmtInstance() {
158: return (TaskMgmtInstance) getInstance(TaskMgmtInstance.class);
159: }
160:
161: public JbpmContext getJbpmContext() {
162: return JbpmContext.getCurrentJbpmContext();
163: }
164:
165: // getters and setters //////////////////////////////////////////////////////
166:
167: public void setTaskInstance(TaskInstance taskInstance) {
168: this .taskInstance = taskInstance;
169: this .task = (taskInstance != null ? taskInstance.getTask()
170: : null);
171: }
172:
173: public Token getToken() {
174: return token;
175: }
176:
177: public Action getAction() {
178: return action;
179: }
180:
181: public Event getEvent() {
182: return event;
183: }
184:
185: public void setEvent(Event event) {
186: this .event = event;
187: }
188:
189: public Throwable getException() {
190: return exception;
191: }
192:
193: public void setException(Throwable exception) {
194: this .exception = exception;
195: }
196:
197: public Transition getTransition() {
198: return transition;
199: }
200:
201: public void setTransition(Transition transition) {
202: this .transition = transition;
203: }
204:
205: public Node getTransitionSource() {
206: return transitionSource;
207: }
208:
209: public void setTransitionSource(Node transitionSource) {
210: this .transitionSource = transitionSource;
211: }
212:
213: public GraphElement getEventSource() {
214: return eventSource;
215: }
216:
217: public void setEventSource(GraphElement eventSource) {
218: this .eventSource = eventSource;
219: }
220:
221: public Task getTask() {
222: return task;
223: }
224:
225: public void setTask(Task task) {
226: this .task = task;
227: }
228:
229: public TaskInstance getTaskInstance() {
230: return taskInstance;
231: }
232:
233: public ProcessInstance getSubProcessInstance() {
234: return subProcessInstance;
235: }
236:
237: public void setSubProcessInstance(ProcessInstance subProcessInstance) {
238: this .subProcessInstance = subProcessInstance;
239: }
240:
241: public Timer getTimer() {
242: return timer;
243: }
244:
245: public void setTimer(Timer timer) {
246: this .timer = timer;
247: }
248:
249: // thread local execution context
250:
251: static ThreadLocal threadLocalContextStack = new ThreadLocal();
252:
253: static Stack getContextStack() {
254: Stack stack = (Stack) threadLocalContextStack.get();
255: if (stack == null) {
256: stack = new Stack();
257: threadLocalContextStack.set(stack);
258: }
259: return stack;
260: }
261:
262: public static void pushCurrentContext(
263: ExecutionContext executionContext) {
264: getContextStack().push(executionContext);
265: }
266:
267: public static void popCurrentContext(
268: ExecutionContext executionContext) {
269: if (getContextStack().pop() != executionContext) {
270: throw new JbpmException(
271: "current execution context mismatch. make sure that every pushed context gets popped");
272: }
273: }
274:
275: public static ExecutionContext currentExecutionContext() {
276: ExecutionContext executionContext = null;
277: Stack stack = getContextStack();
278: if (!stack.isEmpty()) {
279: executionContext = (ExecutionContext) stack.peek();
280: }
281: return executionContext;
282: }
283: }
|