View Javadoc

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 }