Classes in this File | Line Coverage | Branch Coverage | Complexity | ||||
Context |
|
| 1.0;1 |
1 | /* | |
2 | * Copyright 1999-2001,2004 The Apache Software Foundation. | |
3 | * | |
4 | * Licensed under the Apache License, Version 2.0 (the "License"); | |
5 | * you may not use this file except in compliance with the License. | |
6 | * You may obtain a copy of the License at | |
7 | * | |
8 | * http://www.apache.org/licenses/LICENSE-2.0 | |
9 | * | |
10 | * Unless required by applicable law or agreed to in writing, software | |
11 | * distributed under the License is distributed on an "AS IS" BASIS, | |
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
13 | * See the License for the specific language governing permissions and | |
14 | * limitations under the License. | |
15 | */ | |
16 | ||
17 | package org.apache.commons.workflow; | |
18 | ||
19 | ||
20 | import java.util.EmptyStackException; | |
21 | import org.apache.commons.jxpath.JXPathContext; | |
22 | ||
23 | ||
24 | /** | |
25 | * <p>A <strong>Context</strong> represents the dynamic computational state of | |
26 | * a workflow process that is currently being executed. If multiple users | |
27 | * are executing the same workflow process at the same time, they must have | |
28 | * their own instance of Context.</p> | |
29 | * | |
30 | * <p>Workflow engine implementations can register zero or more Scope | |
31 | * instances, to provide the Steps that are being executed with access to | |
32 | * arbitrary collections of JavaBeans. A Context will always have at least | |
33 | * one Scope, called the LOCAL scope, which is the default source or | |
34 | * destination for bean references. Scope instances can be identified | |
35 | * by an integer subscript (which must be in the range 0 .. MAX_SCOPES-1), | |
36 | * or a registered name. The registered name of the LOCAL scope is | |
37 | * "local".</p> | |
38 | * | |
39 | * <p>In addition to Scopes, which can be used for storing beans under | |
40 | * specific names, an evaluation stack is provided for the convenience of | |
41 | * Step implementations that want to pass temporary results back and forth. | |
42 | * As with all Stack-based implementations, it is the responsibility of | |
43 | * the Step implementations that are executed to maintain the stack's | |
44 | * integrity.</p> | |
45 | * | |
46 | * @version $Revision: 155475 $ $Date: 2005-02-26 13:31:11 +0000 (Sat, 26 Feb 2005) $ | |
47 | * @author Craig R. McClanahan | |
48 | */ | |
49 | ||
50 | public interface Context { | |
51 | ||
52 | ||
53 | // ----------------------------------------------------- Manifest Constants | |
54 | ||
55 | ||
56 | /** | |
57 | * The public identifier of the LOCAL scope, which is always defined by a | |
58 | * Context implementation. | |
59 | */ | |
60 | public static final int LOCAL_SCOPE = 0; | |
61 | ||
62 | ||
63 | /** | |
64 | * The maximum number of Scopes (including LOCAL_SCOPE) that can be | |
65 | * registered. | |
66 | */ | |
67 | public static final int MAX_SCOPES = 8; | |
68 | ||
69 | ||
70 | ||
71 | // --------------------------------------------------- Scope Access Methods | |
72 | ||
73 | ||
74 | // These methods provide Steps with the ability to get and set arbitrary | |
75 | // objects in arbitrary scopes. When a scope is not mentioned explicitly, | |
76 | // either LOCAL_SCOPE will be used, or scopes will be searched in | |
77 | // increasing order of their identifiers, as specified in the various | |
78 | // method descriptions. | |
79 | ||
80 | ||
81 | /** | |
82 | * Does a bean with the specified key exist in any specified scope? | |
83 | * Scopes will be searched in ascending order of their identifiers, | |
84 | * starting with LOCAL_SCOPE. | |
85 | * | |
86 | * @param key Key of the bean to be searched for (cannot be null) | |
87 | */ | |
88 | public boolean contains(String key); | |
89 | ||
90 | ||
91 | /** | |
92 | * Does a bean with the specified key exist in the specified scope? | |
93 | * | |
94 | * @param key Key of the bean to be searched for (cannot be null) | |
95 | * @param scope Identifier of the scope to be returned. | |
96 | */ | |
97 | public boolean contains(String key, int scope); | |
98 | ||
99 | ||
100 | /** | |
101 | * Return the bean associated with the specified key, if it exists in | |
102 | * any scope. Scopes will be searched in increasing order of their | |
103 | * identifiers, starting with LOCAL_SCOPE. If the underlying Scope | |
104 | * allows null values, a <code>null</code> return will be ambiguous. | |
105 | * Therefore, you can use the <code>contains()</code> method to determine | |
106 | * whether the key actually exists. | |
107 | * | |
108 | * @param key Key of the bean to be retrieved (cannot be null) | |
109 | */ | |
110 | public Object get(String key); | |
111 | ||
112 | ||
113 | /** | |
114 | * Return the bean associated with the specified key, if it exists in | |
115 | * the specified scope. If the underlying Scope allows null values, | |
116 | * a <code>null</code> return will be ambiguous. Therefore, you can | |
117 | * use the <code>contains()</code> method to determine whether the | |
118 | * key actually exists. | |
119 | * | |
120 | * @param key Key of the bean to be searched for | |
121 | * @param scope Identifier of the scope to be searched | |
122 | */ | |
123 | public Object get(String key, int scope); | |
124 | ||
125 | ||
126 | /** | |
127 | * Store the specified bean under the specified key, in local scope, | |
128 | * replacing any previous value for that key. Any previous value will | |
129 | * be returned. | |
130 | * | |
131 | * @param key Key of the bean to be stored (cannot be null) | |
132 | * @param value Value of the bean to be stored | |
133 | */ | |
134 | public Object put(String key, Object value); | |
135 | ||
136 | ||
137 | /** | |
138 | * Store the specified bean under the specified key, in the specified | |
139 | * scope, replacing any previous value for that key. Any previous value | |
140 | * will be returned. | |
141 | * | |
142 | * @param key Key of the bean to be stored (cannot be null) | |
143 | * @param value Value of the bean to be stored | |
144 | * @param scope Identifier of the scope to use for storage | |
145 | */ | |
146 | public Object put(String key, Object value, int scope); | |
147 | ||
148 | ||
149 | /** | |
150 | * Remove any existing value for the specified key, in any scope. | |
151 | * Scopes will be searched in ascending order of their identifiers, | |
152 | * starting with LOCAL_SCOPE. Any previous value for this key will | |
153 | * be returned. | |
154 | * | |
155 | * @param key Key of the bean to be removed | |
156 | */ | |
157 | public Object remove(String key); | |
158 | ||
159 | ||
160 | /** | |
161 | * Remove any existing value for the specified key, from the specified | |
162 | * scope. Any previous value for this key will be returned. | |
163 | * | |
164 | * @param key Key of the bean to be removed | |
165 | * @param scope Scope the bean to be removed from | |
166 | */ | |
167 | public Object remove(String key, int scope); | |
168 | ||
169 | ||
170 | ||
171 | // --------------------------------------------- Scope Registration Methods | |
172 | ||
173 | ||
174 | // These methods provide capabilities to register and retrieve | |
175 | // Scope implementations. Workflow engine implementations will | |
176 | // register desired scopes when they create Context instances. | |
177 | ||
178 | ||
179 | /** | |
180 | * <p>Register a Scope implementation under the specified identifier. | |
181 | * It is not legal to replace the LOCAL_SCOPE implementation that is | |
182 | * provided by the Context implementation.</p> | |
183 | * | |
184 | * <p>In addition to registering the new Scope such that it can be | |
185 | * accessed dirctly via calls like <code>Context.get(String,int)</code>, | |
186 | * the Scope <code>impl</code> object will also be added to the LOCAL | |
187 | * Scope under the same name. This makes possible a single unified | |
188 | * namespace of all accessible objects that can be navigated by | |
189 | * expression languages.</p> | |
190 | * | |
191 | * @param scope Scope identifier to register under | |
192 | * @param name Scope name to register under | |
193 | * @param impl Scope implementation to be registered (or null to | |
194 | * remove a previous registration) | |
195 | * @exception IllegalArgumentException if you attempt to register | |
196 | * or deregister the local scope | |
197 | */ | |
198 | public void addScope(int scope, String name, Scope impl); | |
199 | ||
200 | ||
201 | /** | |
202 | * Return the Scope implementation registered for the specified | |
203 | * identifier, if any; otherwise, return <code>null</code>. | |
204 | * | |
205 | * @param scope Scope identifier to select | |
206 | */ | |
207 | public Scope getScope(int scope); | |
208 | ||
209 | ||
210 | /** | |
211 | * Return the Scope implementation registered for the specified | |
212 | * name, if any; otherwise, return <code>null</code>. | |
213 | * | |
214 | * @param name Scope name to select | |
215 | */ | |
216 | public Scope getScope(String name); | |
217 | ||
218 | ||
219 | /** | |
220 | * Return the Scope identifier registered for the specified | |
221 | * name, if any; otherwise, return <code>null</code>. | |
222 | * | |
223 | * @param name Scope name to select | |
224 | */ | |
225 | public int getScopeId(String name); | |
226 | ||
227 | ||
228 | // ----------------------------------------------- Evaluation Stack Methods | |
229 | ||
230 | ||
231 | /** | |
232 | * Clear the evaluation stack. | |
233 | */ | |
234 | public void clear(); | |
235 | ||
236 | ||
237 | /** | |
238 | * Is the evaluation stack currently empty? | |
239 | */ | |
240 | public boolean isEmpty(); | |
241 | ||
242 | ||
243 | /** | |
244 | * Return the top item from the evaluation stack without removing it. | |
245 | * | |
246 | * @exception EmptyStackException if the stack is empty | |
247 | */ | |
248 | public Object peek() throws EmptyStackException; | |
249 | ||
250 | ||
251 | /** | |
252 | * Pop and return the top item from the evaluation stack. | |
253 | * | |
254 | * @exception EmptyStackException if the stack is empty | |
255 | */ | |
256 | public Object pop() throws EmptyStackException; | |
257 | ||
258 | ||
259 | /** | |
260 | * Push a new item onto the top of the evaluation stack. | |
261 | * | |
262 | * @param item New item to be pushed | |
263 | */ | |
264 | public void push(Object item); | |
265 | ||
266 | ||
267 | // ----------------------------------------------- BlockState Stack Methods | |
268 | ||
269 | ||
270 | /** | |
271 | * Clear the BlockState stack. | |
272 | */ | |
273 | public void clearBlockState(); | |
274 | ||
275 | ||
276 | /** | |
277 | * Is the BlockState stack currently empty? | |
278 | */ | |
279 | public boolean isEmptyBlockState(); | |
280 | ||
281 | ||
282 | /** | |
283 | * Return the top item from the BlockState stack without removing it. | |
284 | * | |
285 | * @exception EmptyStackException if the stack is empty | |
286 | */ | |
287 | public BlockState peekBlockState() throws EmptyStackException; | |
288 | ||
289 | ||
290 | /** | |
291 | * Pop and return the top item from the BlockState stack. | |
292 | * | |
293 | * @exception EmptyStackException if the stack is empty | |
294 | */ | |
295 | public BlockState popBlockState() throws EmptyStackException; | |
296 | ||
297 | ||
298 | /** | |
299 | * Push a new item onto the top of the BlockState stack. | |
300 | * | |
301 | * @param item New item to be pushed | |
302 | */ | |
303 | public void pushBlockState(BlockState item); | |
304 | ||
305 | ||
306 | // ---------------------------------------------- Dynamic Execution Methods | |
307 | ||
308 | ||
309 | // These methods are used to request the dynamic execution of the | |
310 | // Steps related to a particular Activity. | |
311 | ||
312 | ||
313 | /** | |
314 | * <p>Save the execution state (i.e. the currently assigned next step) | |
315 | * of the Activity we are currently executing, and begin executing the | |
316 | * specified Activity. When that Activity exits (either normally | |
317 | * or by throwing an exception), the previous Activity will be resumed | |
318 | * where it left off. | |
319 | * | |
320 | * @param activity The Activity to be called | |
321 | */ | |
322 | public void call(Activity activity); | |
323 | ||
324 | ||
325 | /** | |
326 | * <p>Execute the <code>Step</code> currently identified as the next | |
327 | * step, and continue execution until there is no next step, or until | |
328 | * the <code>suspend</code> property has been set to true. Upon | |
329 | * completion of an activity, any execution state that was saved to due | |
330 | * to utilizing the <code>call()</code> method will be restored, and | |
331 | * the saved Activity execution shall be resumed. | |
332 | * | |
333 | * @exception StepException if an exception is thrown by the | |
334 | * <code>execute()</code> method of a Step we have executed | |
335 | * @exception IllegalStateException if there is no defined next step | |
336 | * (either because there is no Activity, or because we have already | |
337 | * completed all the steps of this activity) | |
338 | */ | |
339 | public void execute() throws StepException; | |
340 | ||
341 | ||
342 | /** | |
343 | * <p>Return the <code>Activity</code> we will be executing when the | |
344 | * <code>execute()</code> method is called, if any.</p> | |
345 | */ | |
346 | public Activity getActivity(); | |
347 | ||
348 | ||
349 | /** | |
350 | * Return the JXPathContext object that represents a unified namespace | |
351 | * covering all of our registered <code>Scopes</code>. | |
352 | */ | |
353 | public JXPathContext getJXPathContext(); | |
354 | ||
355 | ||
356 | /** | |
357 | * <p>Return the <code>Step</code> that will be executed the next time | |
358 | * that <code>execute()</code> is called, if any.</p> | |
359 | */ | |
360 | public Step getNextStep(); | |
361 | ||
362 | ||
363 | /** | |
364 | * <p>Return the suspend flag.</p> | |
365 | */ | |
366 | public boolean getSuspend(); | |
367 | ||
368 | ||
369 | /** | |
370 | * <p>Set the <code>Step</code> that will be executed the next time | |
371 | * that <code>execute()</code> is called. This is called by a | |
372 | * <code>Step</code> that wants to perform branching based on some | |
373 | * calculated results.</p> | |
374 | * | |
375 | * @param nextStep The next Step to be executed | |
376 | * | |
377 | * @exception IllegalArgumentException if the specified Step is not | |
378 | * part of the current Activity | |
379 | */ | |
380 | public void setNextStep(Step nextStep); | |
381 | ||
382 | ||
383 | /** | |
384 | * <p>Set the <code>Activity</code> to be executed, and make the first | |
385 | * defined <code>Step</code> within this <code>Activity</code> the next | |
386 | * action to be performed by <code>execute()</code>.</p> | |
387 | * | |
388 | * <p>If <code>null</code> is passed, any currently associated Activity | |
389 | * will be released, and the evaluation stack and nested call state | |
390 | * stack will be cleared.</p> | |
391 | * | |
392 | * <p><strong>WARNING</strong> - This will have to become more sophisticated | |
393 | * in order to support calling nested Activities.</p> | |
394 | * | |
395 | * @param activity The new Activity to be executed, or <code>null</code> | |
396 | * to release resources | |
397 | */ | |
398 | public void setActivity(Activity activity); | |
399 | ||
400 | ||
401 | /** | |
402 | * <p>Set the suspend flag. This is called by a <code>Step</code> that | |
403 | * wants to signal the <code>Context</code> to return control to the | |
404 | * caller of the <code>execute()</code> method before executing the | |
405 | * next <code>Step</code> in the current activity.</p> | |
406 | * | |
407 | * @param suspend The new suspend flag | |
408 | */ | |
409 | public void setSuspend(boolean suspend); | |
410 | ||
411 | ||
412 | // ------------------------------------------------- Event Listener Methods | |
413 | ||
414 | ||
415 | /** | |
416 | * Add a listener that is notified each time beans are added, | |
417 | * replaced, or removed in this context. | |
418 | * | |
419 | * @param listener The ContextListener to be added | |
420 | */ | |
421 | public void addContextListener(ContextListener listener); | |
422 | ||
423 | ||
424 | /** | |
425 | * Remove a listener that is notified each time beans are added, | |
426 | * replaced, or removed in this context. | |
427 | * | |
428 | * @param listener The ContextListener to be removed | |
429 | */ | |
430 | public void removeContextListener(ContextListener listener); | |
431 | ||
432 | ||
433 | } |