2009/05/20 - Apache Shale has been retired.

For more information, please explore the Attic.

View Javadoc

1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to you under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  
18  package org.apache.shale.dialog.base;
19  
20  import java.util.ArrayList;
21  import java.util.List;
22  
23  import org.apache.commons.logging.Log;
24  import org.apache.commons.logging.LogFactory;
25  import org.apache.shale.dialog.DialogContext;
26  import org.apache.shale.dialog.DialogContextListener;
27  
28  /***
29   * <p>Convenience abstract {@link DialogContext} implementation.
30   * Provides listener registration and convenience event firing methods.
31   * Subclasses are expected to be serializable.</p>
32   *
33   * @since 1.0.4
34   */
35  public abstract class AbstractDialogContext implements DialogContext {
36  
37  
38      // -------------------------------------------------------------- Properties
39  
40  
41      /***
42       * The list of all registered {@link DialogContextListener}s for this
43       * {@link DialogContext}.
44       */
45      private List listeners = new ArrayList();
46  
47  
48      /***
49       * <p>The <code>Log</code> instance for this class.</p>
50       */
51      private transient Log log;
52  
53  
54      // ---------------------------------------------------- Listener Bookkeeping
55  
56  
57      /***
58       * Register given {@link DialogContextListener} for this {@link DialogContext}.
59       * Listener cannot be <code>null</code>.
60       *
61       * @param listener The {@link DialogContextListener} instance.
62       */
63      public void addDialogContextListener(DialogContextListener listener) {
64  
65          if (listener == null) {
66              throw new IllegalArgumentException("Cannot register null DialogContextListener");
67          }
68  
69          synchronized (listeners) {
70              if (listeners.contains(listener)) {
71                  throw new IllegalArgumentException("DialogContextListener already registered");
72              }
73              listener.setDialogContext(this); // attach self reference
74              listeners.add(listener);
75          }
76      }
77  
78  
79      /***
80       * Return the set of currently registered {@link DialogContextListener}s.
81       */
82      public DialogContextListener[] getDialogContextListeners() {
83  
84          synchronized (listeners) {
85              return (DialogContextListener[])
86                listeners.toArray(new DialogContextListener[listeners.size()]);
87          }
88  
89      }
90  
91  
92      /***
93       * Remove this previously registered {@link DialogContextListener} for this
94       * {@link DialogContext}. The listener will no longer receive any
95       * associated callbacks.
96       *
97       * @param listener The {@link DialogContextListener} instance.
98       */
99      public void removeDialogContextListener(DialogContextListener listener) {
100 
101         if (listener == null) {
102             throw new IllegalArgumentException("Cannot remove null DialogContextListener");
103         }
104 
105         boolean removed;
106         synchronized (listeners) {
107             removed = listeners.remove(listener);
108         }
109         if (removed) {
110             listener.setDialogContext(null); // detach self reference
111         }
112 
113     }
114 
115 
116     // -------------------- Utilities for firing DialogContextListener callbacks
117 
118 
119     /***
120      * <p>Inform all registered {@link DialogContextListener}s that the dialog
121      * instance has been activated.</p>
122      *
123      */
124     protected void fireOnActivate() {
125 
126         DialogContextListener[] listeners = getDialogContextListeners();
127         for (int i = 0; i < listeners.length; i++) {
128             listeners[i].onActivate();
129         }
130 
131     }
132 
133 
134     /***
135      * <p>Inform all registered {@link DialogContextListener}s that the dialog
136      * instance has been passivated.</p>
137      *
138      */
139     protected void fireOnPassivate() {
140 
141         DialogContextListener[] listeners = getDialogContextListeners();
142         for (int i = 0; i < listeners.length; i++) {
143             listeners[i].onPassivate();
144         }
145 
146     }
147 
148 
149     /***
150      * Inform all registered {@link DialogContextListener}s that the dialog
151      * instance has begun execution.
152      *
153      */
154     protected void fireOnStart() {
155 
156         DialogContextListener[] listeners = getDialogContextListeners();
157         for (int i = 0; i < listeners.length; i++) {
158             listeners[i].onStart();
159         }
160 
161     }
162 
163 
164     /***
165      * Inform all registered {@link DialogContextListener}s that the dialog
166      * instance has finished execution normally.
167      *
168      */
169     protected void fireOnStop() {
170 
171         DialogContextListener[] listeners = getDialogContextListeners();
172         for (int i = 0; i < listeners.length; i++) {
173             listeners[i].onStop();
174         }
175 
176     }
177 
178 
179     /***
180      * Inform all registered {@link DialogContextListener}s that the dialog
181      * instance has encountered an unexpected error condition. The exception
182      * is first logged for archival.
183      *
184      * @param exception A potentially implementation specific exception
185      *                  during the execution of this dialog instance
186      */
187     protected void fireOnException(Exception exception) {
188 
189         log().error(exception.getMessage(), exception);
190 
191         DialogContextListener[] listeners = getDialogContextListeners();
192         for (int i = 0; i < listeners.length; i++) {
193             listeners[i].onException(exception);
194         }
195 
196     }
197 
198 
199     /***
200      * Inform all registered {@link DialogContextListener}s that the dialog instance
201      * execution has entered a particular state.
202      *
203      * @param stateId Implementation specific identifier of the state
204      *                that has been entered
205      */
206     protected void fireOnEntry(String stateId) {
207 
208         DialogContextListener[] listeners = getDialogContextListeners();
209         for (int i = 0; i < listeners.length; i++) {
210             listeners[i].onEntry(stateId);
211         }
212 
213     }
214 
215 
216     /***
217      * Inform all registered {@link DialogContextListener}s that the dialog instance
218      * execution has exited a particular state.
219      *
220      * @param stateId Implementation specific identifier of the state
221      *                that has been exited
222      */
223     protected void fireOnExit(String stateId) {
224 
225         DialogContextListener[] listeners = getDialogContextListeners();
226         for (int i = 0; i < listeners.length; i++) {
227             listeners[i].onExit(stateId);
228         }
229 
230     }
231 
232 
233     /***
234      * Inform all registered {@link DialogContextListener}s that the dialog instance
235      * execution has followed a particular transition.
236      *
237      * @param fromStateId Implementation specific identifier of the source
238      *                    state for the transition that has been followed
239      * @param toStateId Implementation specific identifier of the target
240      *                  state for the transition that has been followed
241      */
242     protected void fireOnTransition(String fromStateId, String toStateId) {
243 
244         DialogContextListener[] listeners = getDialogContextListeners();
245         for (int i = 0; i < listeners.length; i++) {
246             listeners[i].onTransition(fromStateId, toStateId);
247         }
248 
249     }
250 
251 
252     /***
253      * <p>Return the <code>Log</code> instance for this class.</p>
254      */
255     private Log log() {
256 
257         if (log == null) {
258             log = LogFactory.getLog(AbstractDialogContext.class);
259         }
260         return log;
261 
262     }
263 
264 }