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.context.exe;
023:
024: import java.util.HashMap;
025: import java.util.Iterator;
026: import java.util.List;
027: import java.util.Map;
028:
029: import org.jbpm.JbpmException;
030: import org.jbpm.graph.exe.Token;
031: import org.jbpm.module.exe.ModuleInstance;
032:
033: /**
034: * maintains all the key-variable pairs for a process instance. You can obtain a
035: * ContextInstance from a processInstance from a process instance like this :
036: * <pre>
037: * ProcessInstance processInstance = ...;
038: * ContextInstance contextInstance = processInstance.getContextInstance();
039: * </pre>
040: * More information on context and process variableInstances can be found in
041: * <a href="../../../../../userguide/en/html/reference.html#context">the userguide, section context</a>
042: */
043: public class ContextInstance extends ModuleInstance {
044:
045: private static final long serialVersionUID = 1L;
046:
047: // maps Token's to TokenVariableMap's
048: protected Map tokenVariableMaps = null;
049: // maps variablenames (String) to values (Object)
050: protected transient Map transientVariables = null;
051: protected transient List updatedVariableContainers = null;
052:
053: public ContextInstance() {
054: }
055:
056: // normal variableInstances (persistent) ////////////////////////////////////
057:
058: /**
059: * creates a variable on the root-token (= process-instance scope) and
060: * calculates the actual VariableInstance-type from the value.
061: */
062: public void createVariable(String name, Object value) {
063: setVariableLocally(name, value, getRootToken());
064: }
065:
066: /**
067: * sets the variable on the root token, creates the variable if necessary and
068: * calculates the actual VariableInstance-type from the value.
069: */
070: public void setVariableLocally(String name, Object value) {
071: setVariableLocally(name, value, getRootToken());
072: }
073:
074: /**
075: * creates a variable in the scope of the given token and calculates the
076: * actual VariableInstance-type from the value.
077: */
078: public void createVariable(String name, Object value, Token token) {
079: setVariableLocally(name, value, token);
080: }
081:
082: /**
083: * creates a variable in the scope of the given token and calculates the
084: * actual VariableInstance-type from the value.
085: */
086: public void setVariableLocally(String name, Object value,
087: Token token) {
088: TokenVariableMap tokenVariableMap = createTokenVariableMap(token);
089: tokenVariableMap.setVariableLocally(name, value);
090: }
091:
092: /**
093: * gets all the variableInstances on the root-token (= process-instance scope).
094: */
095: public Map getVariables() {
096: return getVariables(getRootToken());
097: }
098:
099: /**
100: * retrieves all the variableInstances in scope of the given token.
101: */
102: public Map getVariables(Token token) {
103: Map variables = null;
104:
105: TokenVariableMap tokenVariableMap = getTokenVariableMap(token);
106: if (tokenVariableMap != null) {
107: variables = tokenVariableMap.getVariables();
108: }
109:
110: return variables;
111: }
112:
113: /**
114: * adds all the variableInstances on the root-token (= process-instance scope).
115: */
116: public void addVariables(Map variables) {
117: setVariables(variables, getRootToken());
118: }
119:
120: /**
121: * The method setVariables is the same as the {@link #addVariables(Map, Token)},
122: * but it was added for more consistency.
123: */
124: public void setVariables(Map variables) {
125: setVariables(variables, getRootToken());
126: }
127:
128: /**
129: * adds all the variableInstances to the scope of the given token.
130: * This method delegates to {@link #setVariables(Map, Token)}.
131: * The method setVariables was added for more consistency.
132: */
133: public void addVariables(Map variables, Token token) {
134: setVariables(variables, token);
135: }
136:
137: /**
138: * adds all the variableInstances to the scope of the given token.
139: * The method setVariables is the same as the {@link #addVariables(Map, Token)},
140: * but it was added for more consistency.
141: */
142: public void setVariables(Map variables, Token token) {
143: Iterator iter = variables.entrySet().iterator();
144: while (iter.hasNext()) {
145: Map.Entry entry = (Map.Entry) iter.next();
146: String name = (String) entry.getKey();
147: Object value = entry.getValue();
148: setVariable(name, value, token);
149: }
150: }
151:
152: /**
153: * gets the variable with the given name on the root-token (= process-instance
154: * scope).
155: */
156: public Object getVariable(String name) {
157: return getVariable(name, getRootToken());
158: }
159:
160: /**
161: * retrieves a variable in the scope of the token. If the given token does not
162: * have a variable for the given name, the variable is searched for up the
163: * token hierarchy.
164: */
165: public Object getVariable(String name, Token token) {
166: Object variable = null;
167: TokenVariableMap tokenVariableMap = getTokenVariableMap(token);
168: if (tokenVariableMap != null) {
169: variable = tokenVariableMap.getVariable(name);
170: }
171: return variable;
172: }
173:
174: /**
175: * retrieves a variable which is local to the token.
176: * Method {@link #getVariableLocally(String, Token)} is the same
177: * as this method and it was added for naming consistency.
178: */
179: public Object getLocalVariable(String name, Token token) {
180: return getVariableLocally(name, token);
181: }
182:
183: /**
184: * retrieves a variable which is local to the token.
185: * this method was added for naming consistency. it is the same
186: * as {@link #getLocalVariable(String, Token)}.
187: */
188: public Object getVariableLocally(String name, Token token) {
189: Object variable = null;
190: if (tokenVariableMaps != null
191: && tokenVariableMaps.containsKey(token)) {
192: TokenVariableMap tokenVariableMap = (TokenVariableMap) tokenVariableMaps
193: .get(token);
194: if (tokenVariableMap != null) {
195: variable = tokenVariableMap.getVariableLocally(name);
196: }
197: }
198: return variable;
199: }
200:
201: /**
202: * sets a variable on the process instance scope.
203: */
204: public void setVariable(String name, Object value) {
205: setVariable(name, value, getRootToken());
206: }
207:
208: /**
209: * sets a variable. If a variable exists in the scope given by the token, that
210: * variable is updated. Otherwise, the variable is created on the root token
211: * (=process instance scope).
212: */
213: public void setVariable(String name, Object value, Token token) {
214: TokenVariableMap tokenVariableMap = getOrCreateTokenVariableMap(token);
215: tokenVariableMap.setVariable(name, value);
216: }
217:
218: /**
219: * checks if a variable is present with the given name on the root-token (=
220: * process-instance scope).
221: */
222: public boolean hasVariable(String name) {
223: return hasVariable(name, getRootToken());
224: }
225:
226: /**
227: * checks if a variable is present with the given name in the scope of the
228: * token.
229: */
230: public boolean hasVariable(String name, Token token) {
231: boolean hasVariable = false;
232: TokenVariableMap tokenVariableMap = getTokenVariableMap(token);
233: if (tokenVariableMap != null) {
234: hasVariable = tokenVariableMap.hasVariable(name);
235: }
236: return hasVariable;
237: }
238:
239: /**
240: * deletes the given variable on the root-token (=process-instance scope).
241: */
242: public void deleteVariable(String name) {
243: deleteVariable(name, getRootToken());
244: }
245:
246: /**
247: * deletes a variable from the given token. For safety reasons, this method does
248: * not propagate the deletion to parent tokens in case the given token does not contain
249: * the variable.
250: */
251: public void deleteVariable(String name, Token token) {
252: TokenVariableMap tokenVariableMap = getTokenVariableMap(token);
253: if (tokenVariableMap != null) {
254: tokenVariableMap.deleteVariable(name);
255: }
256: }
257:
258: // transient variableInstances //////////////////////////////////////////////
259:
260: /**
261: * retrieves the transient variable for the given name.
262: */
263: public Object getTransientVariable(String name) {
264: Object transientVariable = null;
265: if (transientVariables != null) {
266: transientVariable = transientVariables.get(name);
267: }
268: return transientVariable;
269: }
270:
271: /**
272: * sets the transient variable for the given name to the given value.
273: */
274: public void setTransientVariable(String name, Object value) {
275: if (transientVariables == null) {
276: transientVariables = new HashMap();
277: }
278: transientVariables.put(name, value);
279: }
280:
281: /**
282: * tells if a transient variable with the given name is present.
283: */
284: public boolean hasTransientVariable(String name) {
285: if (transientVariables == null) {
286: return false;
287: }
288: return transientVariables.containsKey(name);
289: }
290:
291: /**
292: * retrieves all the transient variableInstances map. note that no deep copy is
293: * performed, changing the map leads to changes in the transient variableInstances of
294: * this context instance.
295: */
296: public Map getTransientVariables() {
297: return transientVariables;
298: }
299:
300: /**
301: * replaces the transient variableInstances with the given map.
302: */
303: public void setTransientVariables(Map transientVariables) {
304: this .transientVariables = transientVariables;
305: }
306:
307: /**
308: * removes the transient variable.
309: */
310: public void deleteTransientVariable(String name) {
311: if (transientVariables == null)
312: return;
313: transientVariables.remove(name);
314: }
315:
316: Token getRootToken() {
317: return processInstance.getRootToken();
318: }
319:
320: /**
321: * searches for the first token-variable-map for the given token
322: * and creates it on the root token if it doesn't exist.
323: */
324: public TokenVariableMap getOrCreateTokenVariableMap(Token token) {
325: if (token == null) {
326: throw new JbpmException(
327: "can't get variables for token 'null'");
328: }
329:
330: // if the given token has a variable map
331: TokenVariableMap tokenVariableMap = null;
332: if ((tokenVariableMaps != null)
333: && (tokenVariableMaps.containsKey(token))) {
334: tokenVariableMap = (TokenVariableMap) tokenVariableMaps
335: .get(token);
336:
337: } else if (!token.isRoot()) {
338: tokenVariableMap = getOrCreateTokenVariableMap(token
339: .getParent());
340:
341: } else {
342: tokenVariableMap = createTokenVariableMap(token);
343: }
344:
345: return tokenVariableMap;
346: }
347:
348: TokenVariableMap createTokenVariableMap(Token token) {
349: if (tokenVariableMaps == null) {
350: tokenVariableMaps = new HashMap();
351: }
352: TokenVariableMap tokenVariableMap = (TokenVariableMap) tokenVariableMaps
353: .get(token);
354: if (tokenVariableMap == null) {
355: tokenVariableMap = new TokenVariableMap(token, this );
356: tokenVariableMaps.put(token, tokenVariableMap);
357: }
358: return tokenVariableMap;
359: }
360:
361: /**
362: * looks for the first token-variable-map that is found
363: * up the token-parent hirarchy.
364: */
365: public TokenVariableMap getTokenVariableMap(Token token) {
366: TokenVariableMap tokenVariableMap = null;
367: if (tokenVariableMaps != null) {
368: if (tokenVariableMaps.containsKey(token)) {
369: tokenVariableMap = (TokenVariableMap) tokenVariableMaps
370: .get(token);
371: } else if (!token.isRoot()) {
372: tokenVariableMap = getTokenVariableMap(token
373: .getParent());
374: }
375: }
376: return tokenVariableMap;
377: }
378:
379: public VariableInstance getVariableInstance(String name, Token token) {
380: VariableInstance variableInstance = null;
381: TokenVariableMap tokenVariableMap = getTokenVariableMap(token);
382: if (tokenVariableMap != null) {
383: tokenVariableMap.getVariableInstances();
384: }
385: return variableInstance;
386: }
387:
388: public Map getTokenVariableMaps() {
389: return tokenVariableMaps;
390: }
391: }
|