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.util;
18
19
20 import java.util.Map;
21 import org.apache.commons.workflow.Context;
22 import org.apache.commons.workflow.ContextEvent;
23 import org.apache.commons.workflow.ContextListener;
24 import org.apache.commons.workflow.Step;
25 import org.apache.commons.workflow.StepException;
26
27
28 /**
29 * <strong>ContextSupport</strong> is a convenience class for managing the
30 * firing of <code>ContextEvents</code> to registered
31 * <code>ContextListeners</code>.
32 *
33 * @version $Revision: 155475 $ $Date: 2005-02-26 13:31:11 +0000 (Sat, 26 Feb 2005) $
34 * @author Craig R. McClanahan
35 */
36
37 public class ContextSupport {
38
39
40 // ----------------------------------------------------------- Constructors
41
42
43 /**
44 * Construct a new ContextSupport object associated with the
45 * specified Context.
46 *
47 * @param context Context for whom we will fire events
48 */
49 public ContextSupport(Context context) {
50
51 super();
52 this.context = context;
53
54 }
55
56
57 // ----------------------------------------------------- Instance Variables
58
59
60 /**
61 * The set of registered <code>ContextListener</code> event listeners.
62 */
63 protected ContextListener listeners[] = new ContextListener[0];
64
65
66 /**
67 * The <code>Context</code> for whom we will fire events.
68 */
69 protected Context context = null;
70
71
72 // ------------------------------------------------- Event Listener Methods
73
74
75 /**
76 * Add a listener that is notified each time beans are added,
77 * replaced, or removed in this context.
78 *
79 * @param listener The ContextListener to be added
80 */
81 public void addContextListener(ContextListener listener) {
82
83 synchronized (listeners) {
84 ContextListener results[] =
85 new ContextListener[listeners.length + 1];
86 System.arraycopy(listeners, 0, results, 0, listeners.length);
87 results[listeners.length] = listener;
88 listeners = results;
89 }
90
91 }
92
93
94 /**
95 * Remove a listener that is notified each time beans are added,
96 * replaced, or removed in this context.
97 *
98 * @param listener The ContextListener to be removed
99 */
100 public void removeContextListener(ContextListener listener) {
101
102 synchronized (listeners) {
103 int n = -1;
104 for (int i = 0; i < listeners.length; i++) {
105 if (listeners[i] == listener) {
106 n = i;
107 break;
108 }
109 }
110 if (n < 0)
111 return;
112 ContextListener results[] =
113 new ContextListener[listeners.length - 1];
114 int j = 0;
115 for (int i = 0; i < listeners.length; i++) {
116 if (i != n)
117 results[j++] = listeners[i];
118 }
119 listeners = results;
120 }
121
122 }
123
124
125 // --------------------------------------------------- Event Firing Methods
126
127
128 /**
129 * Fire a <code>afterActivity</code> event to all registered listeners.
130 *
131 * @param step Step that was executed last
132 */
133 public void fireAfterActivity(Step step) {
134
135 if (listeners.length == 0)
136 return;
137 ContextEvent event = new ContextEvent(context, step);
138 ContextListener interested[] = null;
139 synchronized (listeners) {
140 interested = (ContextListener[]) listeners.clone();
141 }
142 for (int i = 0; i < interested.length; i++)
143 interested[i].afterActivity(event);
144
145 }
146
147
148 /**
149 * Fire a <code>afterActivity</code> event to all registered listeners.
150 *
151 * @param step Step that was executed last
152 * @param exception StepException thrown by the last Step
153 */
154 public void fireAfterActivity(Step step, StepException exception) {
155
156 if (listeners.length == 0)
157 return;
158 ContextEvent event = new ContextEvent(context, step, exception);
159 ContextListener interested[] = null;
160 synchronized (listeners) {
161 interested = (ContextListener[]) listeners.clone();
162 }
163 for (int i = 0; i < interested.length; i++)
164 interested[i].afterActivity(event);
165
166 }
167
168
169 /**
170 * Fire a <code>afterStep</code> event to all registered listeners.
171 *
172 * @param step Step that was executed
173 */
174 public void fireAfterStep(Step step) {
175
176 if (listeners.length == 0)
177 return;
178 ContextEvent event = new ContextEvent(context, step);
179 ContextListener interested[] = null;
180 synchronized (listeners) {
181 interested = (ContextListener[]) listeners.clone();
182 }
183 for (int i = 0; i < interested.length; i++)
184 interested[i].afterStep(event);
185
186 }
187
188
189 /**
190 * Fire a <code>afterStep</code> event to all registered listeners.
191 *
192 * @param step Step that was executed
193 * @param exception StepException thrown by the executed step
194 */
195 public void fireAfterStep(Step step, StepException exception) {
196
197 if (listeners.length == 0)
198 return;
199 ContextEvent event = new ContextEvent(context, step, exception);
200 ContextListener interested[] = null;
201 synchronized (listeners) {
202 interested = (ContextListener[]) listeners.clone();
203 }
204 for (int i = 0; i < interested.length; i++)
205 interested[i].afterStep(event);
206
207 }
208
209
210 /**
211 * Fire a <code>beforeActivity</code> event to all registered listeners.
212 *
213 * @param step Step that will be executed first
214 */
215 public void fireBeforeActivity(Step step) {
216
217 if (listeners.length == 0)
218 return;
219 ContextEvent event = new ContextEvent(context, step);
220 ContextListener interested[] = null;
221 synchronized (listeners) {
222 interested = (ContextListener[]) listeners.clone();
223 }
224 for (int i = 0; i < interested.length; i++)
225 interested[i].beforeActivity(event);
226
227 }
228
229
230 /**
231 * Fire a <code>beforeStep</code> event to all registered listeners.
232 *
233 * @param step Step that is about to be executed
234 */
235 public void fireBeforeStep(Step step) {
236
237 if (listeners.length == 0)
238 return;
239 ContextEvent event = new ContextEvent(context, step);
240 ContextListener interested[] = null;
241 synchronized (listeners) {
242 interested = (ContextListener[]) listeners.clone();
243 }
244 for (int i = 0; i < interested.length; i++)
245 interested[i].beforeStep(event);
246
247 }
248
249
250 }