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.taskmgmt.def;
023:
024: import java.io.Serializable;
025: import java.util.Iterator;
026: import java.util.List;
027:
028: import org.apache.commons.logging.Log;
029: import org.apache.commons.logging.LogFactory;
030: import org.jbpm.context.def.VariableAccess;
031: import org.jbpm.context.exe.ContextInstance;
032: import org.jbpm.graph.exe.ProcessInstance;
033: import org.jbpm.graph.exe.Token;
034: import org.jbpm.instantiation.Delegation;
035: import org.jbpm.instantiation.UserCodeInterceptorConfig;
036: import org.jbpm.taskmgmt.exe.TaskInstance;
037: import org.jbpm.util.EqualsUtil;
038:
039: /**
040: * is a controller for one task. this object either delegates to a custom
041: * {@link org.jbpm.taskmgmt.def.TaskControllerHandler} or it is configured
042: * with {@link org.jbpm.context.def.VariableAccess}s to perform the default
043: * behaviour of the controller functionality for a task.
044: */
045: public class TaskController implements Serializable {
046:
047: private static final long serialVersionUID = 1L;
048:
049: long id = 0;
050:
051: /**
052: * allows the user to specify a custom task controller handler. if this is
053: * specified, the other member variableInstances are ignored. so either a
054: * taskControllerDelegation is specified or the variable- and signalMappings
055: * are specified, but not both.
056: */
057: Delegation taskControllerDelegation = null;
058:
059: /**
060: * maps process variable names (java.lang.String) to VariableAccess objects.
061: */
062: List variableAccesses = null;
063:
064: public TaskController() {
065: }
066:
067: /**
068: * extract the list of information from the process variables and make them available locally.
069: * Note that if no task instance variables are specified, the full process variables scope will be
070: * visible (that means that the user did not specify a special task instance scope).
071: */
072: public void initializeVariables(TaskInstance taskInstance) {
073: if (taskControllerDelegation != null) {
074: TaskControllerHandler taskControllerHandler = (TaskControllerHandler) taskControllerDelegation
075: .instantiate();
076: ProcessInstance processInstance = taskInstance
077: .getTaskMgmtInstance().getProcessInstance();
078: ContextInstance contextInstance = (processInstance != null ? processInstance
079: .getContextInstance()
080: : null);
081: Token token = taskInstance.getToken();
082:
083: if (UserCodeInterceptorConfig.userCodeInterceptor != null) {
084: UserCodeInterceptorConfig.userCodeInterceptor
085: .executeTaskControllerInitialization(
086: taskControllerHandler, taskInstance,
087: contextInstance, token);
088: } else {
089: taskControllerHandler.initializeTaskVariables(
090: taskInstance, contextInstance, token);
091: }
092:
093: } else {
094: Token token = taskInstance.getToken();
095: ProcessInstance processInstance = token
096: .getProcessInstance();
097: ContextInstance contextInstance = processInstance
098: .getContextInstance();
099:
100: if (variableAccesses != null) {
101: Iterator iter = variableAccesses.iterator();
102: while (iter.hasNext()) {
103: VariableAccess variableAccess = (VariableAccess) iter
104: .next();
105: String mappedName = variableAccess.getMappedName();
106: if (variableAccess.isReadable()) {
107: String variableName = variableAccess
108: .getVariableName();
109: Object value = contextInstance.getVariable(
110: variableName, token);
111: log.debug("creating task instance variable '"
112: + mappedName
113: + "' from process variable '"
114: + variableName + "', value '" + value
115: + "'");
116: taskInstance.setVariableLocally(mappedName,
117: value);
118: } else {
119: log
120: .debug("creating task instance local variable '"
121: + mappedName
122: + "'. initializing with null value.");
123: taskInstance.setVariableLocally(mappedName,
124: null);
125: }
126: }
127: }
128: }
129: }
130:
131: /**
132: * update the process variables from the the task-instance variables.
133: */
134: public void submitParameters(TaskInstance taskInstance) {
135: if (taskControllerDelegation != null) {
136: TaskControllerHandler taskControllerHandler = (TaskControllerHandler) taskControllerDelegation
137: .instantiate();
138: ProcessInstance processInstance = taskInstance
139: .getTaskMgmtInstance().getProcessInstance();
140: ContextInstance contextInstance = (processInstance != null ? processInstance
141: .getContextInstance()
142: : null);
143: Token token = taskInstance.getToken();
144:
145: if (UserCodeInterceptorConfig.userCodeInterceptor != null) {
146: UserCodeInterceptorConfig.userCodeInterceptor
147: .executeTaskControllerSubmission(
148: taskControllerHandler, taskInstance,
149: contextInstance, token);
150: } else {
151: taskControllerHandler.submitTaskVariables(taskInstance,
152: contextInstance, token);
153: }
154:
155: } else {
156:
157: Token token = taskInstance.getToken();
158: ProcessInstance processInstance = token
159: .getProcessInstance();
160: ContextInstance contextInstance = processInstance
161: .getContextInstance();
162:
163: if (variableAccesses != null) {
164: String missingTaskVariables = null;
165: Iterator iter = variableAccesses.iterator();
166: while (iter.hasNext()) {
167: VariableAccess variableAccess = (VariableAccess) iter
168: .next();
169: String mappedName = variableAccess.getMappedName();
170: // first check if the required variableInstances are present
171: if ((variableAccess.isRequired())
172: && (!taskInstance
173: .hasVariableLocally(mappedName))) {
174: if (missingTaskVariables == null) {
175: missingTaskVariables = mappedName;
176: } else {
177: missingTaskVariables += ", " + mappedName;
178: }
179: }
180: }
181:
182: // if there are missing, required parameters, throw an IllegalArgumentException
183: if (missingTaskVariables != null) {
184: throw new IllegalArgumentException(
185: "missing task variables: "
186: + missingTaskVariables);
187: }
188:
189: iter = variableAccesses.iterator();
190: while (iter.hasNext()) {
191: VariableAccess variableAccess = (VariableAccess) iter
192: .next();
193: String mappedName = variableAccess.getMappedName();
194: String variableName = variableAccess
195: .getVariableName();
196: if (variableAccess.isWritable()) {
197: Object value = taskInstance
198: .getVariable(mappedName);
199: if (value != null) {
200: log.debug("submitting task variable '"
201: + mappedName
202: + "' to process variable '"
203: + variableName + "', value '"
204: + value + "'");
205: contextInstance.setVariable(variableName,
206: value, token);
207: }
208: }
209: }
210: }
211: }
212: }
213:
214: // equals ///////////////////////////////////////////////////////////////////
215: // hack to support comparing hibernate proxies against the real objects
216: // since this always falls back to ==, we don't need to overwrite the hashcode
217: public boolean equals(Object o) {
218: return EqualsUtil.equals(this , o);
219: }
220:
221: // getters and setters //////////////////////////////////////////////////////
222:
223: public List getVariableAccesses() {
224: return variableAccesses;
225: }
226:
227: public Delegation getTaskControllerDelegation() {
228: return taskControllerDelegation;
229: }
230:
231: public void setTaskControllerDelegation(
232: Delegation taskControllerDelegation) {
233: this .taskControllerDelegation = taskControllerDelegation;
234: }
235:
236: public long getId() {
237: return id;
238: }
239:
240: public void setVariableAccesses(List variableAccesses) {
241: this .variableAccesses = variableAccesses;
242: }
243:
244: private static Log log = LogFactory.getLog(TaskController.class);
245: }
|