KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > objectweb > proactive > core > event > AbstractEventProducer


1 /*
2  * ################################################################
3  *
4  * ProActive: The Java(TM) library for Parallel, Distributed,
5  * Concurrent computing with Security and Mobility
6  *
7  * Copyright (C) 1997-2002 INRIA/University of Nice-Sophia Antipolis
8  * Contact: proactive-support@inria.fr
9  *
10  * This library is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU Lesser General Public
12  * License as published by the Free Software Foundation; either
13  * version 2.1 of the License, or any later version.
14  *
15  * This library is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18  * Lesser General Public License for more details.
19  *
20  * You should have received a copy of the GNU Lesser General Public
21  * License along with this library; if not, write to the Free Software
22  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
23  * USA
24  *
25  * Initial developer(s): The ProActive Team
26  * http://www.inria.fr/oasis/ProActive/contacts.html
27  * Contributor(s):
28  *
29  * ################################################################
30  */

31 package org.objectweb.proactive.core.event;
32
33 import org.apache.log4j.Logger;
34
35
36 /**
37  * <p>
38  * Provides support for adding, removing and notifying <code>ProActiveListener</code>. This class
39  * is a generic class that can be derived to get immediate support for sending <code>ProActiveEvent</code>
40  * to <code>ProActiveListener</code>.
41  * </p><p>
42  * A class producing <code>ProActiveEvent</code> and allowing <code>ProActiveListener</code> to register can
43  * have two strategies with those listeners in case of migration. If the listeners are local to the JVM,
44  * it doesn't make sense to serialize them with the migrating object. If the listener are part of the
45  * migrating subsystem, they should be serialized with the subsystem.
46  * </p><p>
47  * This class supports the two strategies and a boolean passed to the constructor indicates the strategy
48  * to apply with the registered listeners in case of migration.
49  * </p>
50  * </p><p>
51  * In case of the listeners are not serialized with this object, meaning that there are not part of the subsystem
52  * in which is attached this object, we only keep weak references on them. The reference this event producer is
53  * keeping on one given listener won't prevent it to be garbage collected if no other strong reference are kept
54  * by another object.
55  * </p><p>
56  * This class is thread safe.
57  * </p>
58  *
59  * @author ProActive Team
60  * @version 1.0, 2001/10/23
61  * @since ProActive 0.9
62  *
63  */

64 public abstract class AbstractEventProducer implements java.io.Serializable JavaDoc {
65     //
66
// -- PROTECTED MEMBERS -----------------------------------------------
67
//
68
protected static Logger logger = Logger.getLogger(AbstractEventProducer.class.getName());
69
70     /** flag specifying if the list of listeners should be serialized */
71     protected boolean shouldSerializeListeners;
72
73     /** the list of listeners. There are serialized or not depending the value
74        of the variable shouldSerializeListeners.
75        If not serialized we use WeakReference to reference them. */

76     protected transient ListenerList eventListeners;
77
78     //
79
// -- CONSTRUCTORS -----------------------------------------------
80
//
81

82     /**
83      * Creates an <code>AbstractEventProducer</code> that does not serialize its registered listener.
84      */

85     public AbstractEventProducer() {
86         this(false);
87     }
88
89     /**
90      * Creates an <code>AbstractEventProducer</code> and specifies whether its registered listener
91      * should be serialized or not
92      * @param shouldSerializeListeners true if the registered listeners should be serialized, false else.
93      */

94     public AbstractEventProducer(boolean shouldSerializeListeners) {
95         this.shouldSerializeListeners = shouldSerializeListeners;
96         if (shouldSerializeListeners) {
97             eventListeners = new PlainListenerList();
98         } else {
99             eventListeners = new WeakReferenceListenerList();
100         }
101     }
102
103     //
104
// -- PUBLIC METHODS -----------------------------------------------
105
//
106
//
107
// -- PROTECTED METHODS -----------------------------------------------
108
//
109

110     /**
111      * Returns true is this event producer has at least one registered listener
112      * @return true is this event producer has at least one registered listener
113      */

114     protected boolean hasListeners() {
115         return !eventListeners.isEmpty();
116     }
117
118     /**
119      * Adds the given listener
120      * @param <code>listener</code> the listener to register
121      */

122     protected void addListener(ProActiveListener listener) {
123         synchronized (eventListeners) {
124             if (!eventListeners.contains(listener)) {
125                 eventListeners.add(listener);
126             }
127         }
128     }
129
130     /**
131      * Removes the given listener
132      * @param <code>listener</code> the listener to remove
133      */

134     protected void removeListener(ProActiveListener listener) {
135         synchronized (eventListeners) {
136             eventListeners.remove(listener);
137         }
138     }
139
140     /**
141      * Notifies all registered listener with the event. This method call
142      * <code>notifyOneListener</code> on each registered listener.
143      * @param <code>event</code> the event to fire to all listeners.
144      */

145     protected void notifyAllListeners(ProActiveEvent event) {
146         synchronized (eventListeners) {
147             java.util.Iterator JavaDoc iterator = eventListeners.iterator();
148             while (iterator.hasNext()) {
149                 notifyOneListener((ProActiveListener) iterator.next(), event);
150             }
151         }
152     }
153
154     /**
155      * Notifies one listener with the event.
156      * @param <code>listener</code> the listener to notify.
157      * @param <code>event</code> the event to fire to the listener.
158      */

159     protected abstract void notifyOneListener(ProActiveListener listener,
160         ProActiveEvent event);
161
162     //
163
// -- PRIVATE METHODS -----------------------------------------------
164
//
165

166     /**
167      * @serialData Write serializable fields, if any exist.
168      */

169     private void writeObject(java.io.ObjectOutputStream JavaDoc s)
170         throws java.io.IOException JavaDoc {
171         s.writeBoolean(shouldSerializeListeners);
172         if (shouldSerializeListeners) {
173             s.writeObject(eventListeners);
174         }
175     }
176
177     /**
178      *
179      * @serialData Read serializable fields, if any exist.
180      * Recreate eventListeners.
181      */

182     private void readObject(java.io.ObjectInputStream JavaDoc s)
183         throws java.io.IOException JavaDoc, ClassNotFoundException JavaDoc {
184         shouldSerializeListeners = s.readBoolean();
185         if (shouldSerializeListeners) {
186             eventListeners = (ListenerList) s.readObject();
187         } else {
188             eventListeners = new WeakReferenceListenerList();
189         }
190     }
191
192     //
193
// -- INNER CLASSES -----------------------------------------------
194
//
195

196     /**
197      * <p>
198      * A class implementing this interface provide a minimum set of methods
199      * to support the addition and removal of listener.
200      * </p>
201      *
202      * @author ProActive Team
203      * @version 1.0, 2001/10/23
204      * @since ProActive 0.9
205      *
206      */

207     protected interface ListenerList {
208
209         /**
210          * Returns true if no listener is in the list.
211          * @return true if no listener is in the list.
212          */

213         public boolean isEmpty();
214
215         /**
216          * Returns the number of listeners in the list.
217          * @return the number of listeners in the list.
218          */

219         public int size();
220
221         /**
222          * Returns true if <code>listener</code> is a listener contained in the list.
223          * @return true if <code>listener</code> is a listener contained in the list.
224          */

225         public boolean contains(ProActiveListener listener);
226
227         /**
228          * Adds the given listener
229          * @param <code>listener</code> the listener to add in the list
230          * @return true if the listener has been added.
231          */

232         public boolean add(ProActiveListener listener);
233
234         /**
235          * Removes the given listener
236          * @param <code>listener</code> the listener to remove from the list
237          * @return true if the listener has been removed.
238          */

239         public boolean remove(ProActiveListener listener);
240
241         /**
242          * Returns an iterator on the listeners of the list
243          * @return an iterator on the listeners of the list
244          */

245         public java.util.Iterator JavaDoc iterator();
246     }
247
248     /**
249      * <p>
250      * Implements a simple list of listeners backed by an <code>ArrayList</code>.
251      * </p>
252      *
253      * @author ProActive Team
254      * @version 1.0, 2001/10/23
255      * @since ProActive 0.9
256      *
257      */

258     private class PlainListenerList implements java.io.Serializable JavaDoc,
259         ListenerList {
260         protected java.util.ArrayList JavaDoc list;
261
262         public PlainListenerList() {
263             list = new java.util.ArrayList JavaDoc();
264         }
265
266         public boolean isEmpty() {
267             return list.isEmpty();
268         }
269
270         public int size() {
271             return list.size();
272         }
273
274         public boolean contains(ProActiveListener listener) {
275             return list.contains(listener);
276         }
277
278         public boolean add(ProActiveListener listener) {
279             return list.add(listener);
280         }
281
282         public boolean remove(ProActiveListener listener) {
283             return list.remove(listener);
284         }
285
286         public java.util.Iterator JavaDoc iterator() {
287             return list.iterator();
288         }
289     }
290
291     /**
292      * <p>
293      * Implements a list of listeners in which the reference to one listener
294      * is a WeakReference allowing that listener to be garbage collected if
295      * it is no more used.
296      * </p>
297      *
298      * @author ProActive Team
299      * @version 1.0, 2001/10/23
300      * @since ProActive 0.9
301      *
302      */

303     private class WeakReferenceListenerList extends PlainListenerList {
304         public WeakReferenceListenerList() {
305         }
306
307         public boolean contains(ProActiveListener listener) {
308             java.util.Iterator JavaDoc iterator = iterator();
309             while (iterator.hasNext()) {
310                 if (iterator.next() == listener) {
311                     return true;
312                 }
313             }
314             return false;
315         }
316
317         public boolean add(ProActiveListener listener) {
318             return list.add(new java.lang.ref.WeakReference JavaDoc(listener));
319         }
320
321         public boolean remove(ProActiveListener listener) {
322             java.util.Iterator JavaDoc iterator = iterator();
323             while (iterator.hasNext()) {
324                 if (iterator.next() == listener) {
325                     iterator.remove();
326                     return true;
327                 }
328             }
329             return false;
330         }
331
332         public java.util.Iterator JavaDoc iterator() {
333             return new WeakReferenceIterator(list.iterator());
334         }
335     }
336
337     /**
338      * <p>
339      * Implements an <code>Iterator</code> on a list containing
340      * <code>WeakReference</code>s and return the referenced object.
341      * The iterator automatically removed from the list the objects
342      * that have been garbage collected.
343      * </p>
344      *
345      * @author ProActive Team
346      * @version 1.0, 2001/10/23
347      * @since ProActive 0.9
348      *
349      */

350     private class WeakReferenceIterator implements java.util.Iterator JavaDoc {
351         private java.util.Iterator JavaDoc iterator;
352         private Object JavaDoc nextObject;
353
354         public WeakReferenceIterator(java.util.Iterator JavaDoc iterator) {
355             this.iterator = iterator;
356             nextObject = getNextObject();
357         }
358
359         public boolean hasNext() {
360             return nextObject != null;
361         }
362
363         public Object JavaDoc next() {
364             Object JavaDoc result = nextObject;
365             nextObject = getNextObject();
366             return result;
367         }
368
369         public void remove() {
370             iterator.remove();
371         }
372
373         private Object JavaDoc getNextObject() {
374             while (iterator.hasNext()) {
375                 java.lang.ref.WeakReference JavaDoc ref = (java.lang.ref.WeakReference JavaDoc) iterator.next();
376                 Object JavaDoc target = ref.get();
377                 if (target == null) {
378                     // object has been removed
379
//logger.debug("!!!!!!!!!!!! REMOVED A GARBAGED LISTENER");
380
iterator.remove();
381                 } else {
382                     return target;
383                 }
384             }
385             return null;
386         }
387     }
388      // end inner class WeakReferenceIterator
389
}
390
Popular Tags