KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > nextapp > echo2 > app > event > EventListenerList


1 /*
2  * This file is part of the Echo Web Application Framework (hereinafter "Echo").
3  * Copyright (C) 2002-2005 NextApp, Inc.
4  *
5  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
6  *
7  * The contents of this file are subject to the Mozilla Public License Version
8  * 1.1 (the "License"); you may not use this file except in compliance with
9  * the License. You may obtain a copy of the License at
10  * http://www.mozilla.org/MPL/
11  *
12  * Software distributed under the License is distributed on an "AS IS" basis,
13  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
14  * for the specific language governing rights and limitations under the
15  * License.
16  *
17  * Alternatively, the contents of this file may be used under the terms of
18  * either the GNU General Public License Version 2 or later (the "GPL"), or
19  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
20  * in which case the provisions of the GPL or the LGPL are applicable instead
21  * of those above. If you wish to allow use of your version of this file only
22  * under the terms of either the GPL or the LGPL, and not to allow others to
23  * use your version of this file under the terms of the MPL, indicate your
24  * decision by deleting the provisions above and replace them with the notice
25  * and other provisions required by the GPL or the LGPL. If you do not delete
26  * the provisions above, a recipient may use your version of this file under
27  * the terms of any one of the MPL, the GPL or the LGPL.
28  */

29
30 package nextapp.echo2.app.event;
31
32 import java.io.IOException JavaDoc;
33 import java.io.ObjectInputStream JavaDoc;
34 import java.io.ObjectOutputStream JavaDoc;
35 import java.io.Serializable JavaDoc;
36 import java.util.EventListener JavaDoc;
37
38 /**
39  * A generic storage facility for listeners.
40  */

41 public class EventListenerList
42 implements Serializable JavaDoc {
43
44     private static final Object JavaDoc[] EMPTY = new Object JavaDoc[0];
45     private static final EventListener JavaDoc[] NO_LISTENERS = new EventListener JavaDoc[0];
46     
47     /**
48      * The number of empty slots that should be added when all available
49      * slots are filled and more are required.
50      */

51     private static final int INCREMENT = 3;
52     
53     /**
54      * The number of empty slots available before the storage array should
55      * be trimmed.
56      */

57     private static final int DECREMENT = 5;
58
59     private transient Object JavaDoc[] listeners = EMPTY;
60     private transient int size = 0;
61     
62     /**
63      * Creates a new listener list.
64      */

65     public EventListenerList() {
66         super();
67     }
68     
69     /**
70      * Adds a listener of the given class to the list.
71      *
72      * @param listenerClass the <code>Class</code> of the listener being added
73      * @param l the listener to add
74      */

75     public void addListener(Class JavaDoc listenerClass, EventListener JavaDoc l) {
76         if (size * 2 == listeners.length) {
77             // Expand storage array if necessary.
78
Object JavaDoc[] newListeners = new Object JavaDoc[listeners.length + INCREMENT * 2];
79             System.arraycopy(listeners, 0, newListeners, 0, listeners.length);
80             listeners = newListeners;
81         }
82         
83         listeners[size * 2] = listenerClass;
84         listeners[size * 2 + 1] = l;
85         ++size;
86     }
87     
88     /**
89      * Returns the number of listeners present of the given class.
90      *
91      * @param listenerClass the <code>Class</code> of the listener for which
92      * the listener count is desired
93      * @return the number of listeners present for the specified listener
94      * <code>Class</code>
95      */

96     public int getListenerCount(Class JavaDoc listenerClass) {
97         int count = 0;
98         for (int index = 0; index < size; ++index) {
99             if (listeners[index * 2] == listenerClass) {
100                 ++count;
101             }
102         }
103         return count;
104     }
105     
106     /**
107      * Returns an array of listeners of the given class.
108      *
109      * @param listenerClass the desired <code>Class</code> of listener
110      * @return an array of listeners of the given <code>Class</code>
111      * (if no listeners of the specified class exist, an empty
112      * array is returned)
113      */

114     public EventListener JavaDoc[] getListeners(Class JavaDoc listenerClass) {
115         int listenerCount = getListenerCount(listenerClass);
116         if (listenerCount == 0) {
117             return NO_LISTENERS;
118         } else {
119             EventListener JavaDoc[] matchingListeners = new EventListener JavaDoc[listenerCount];
120             int matchIndex = 0;
121             for (int index = 0; index < size; ++index) {
122                 if (listeners[index * 2] == listenerClass) {
123                     matchingListeners[matchIndex++] = (EventListener JavaDoc) listeners[index * 2 + 1];
124                 }
125             }
126             return matchingListeners;
127         }
128     }
129     
130     /**
131      * @see java.io.Serializable
132      */

133     private void readObject(ObjectInputStream JavaDoc in)
134     throws ClassNotFoundException JavaDoc, IOException JavaDoc {
135         in.defaultReadObject();
136         listeners = EMPTY;
137         size = 0;
138         ClassLoader JavaDoc classLoader = Thread.currentThread().getContextClassLoader();
139         Object JavaDoc listenerClassName = in.readObject();
140         while (listenerClassName != null) {
141             EventListener JavaDoc listener = (EventListener JavaDoc) in.readObject();
142             addListener(Class.forName((String JavaDoc) listenerClassName, true, classLoader), listener);
143             listenerClassName = in.readObject();
144         }
145     }
146     
147     /**
148      * Removes a listener of the given class from the list.
149      *
150      * @param listenerClass the <code>Class</code> of the listener being
151      * removed
152      * @param l the listener to remove
153      */

154     public void removeListener(Class JavaDoc listenerClass, EventListener JavaDoc l) {
155         for (int index = 0; index < size; ++index) {
156             if (listeners[index * 2] == listenerClass && listeners[index * 2 + 1] == l) {
157                 // Last listener replaces current listener.
158
listeners[index * 2] = listeners[(size - 1) * 2];
159                 listeners[index * 2 + 1] = listeners[(size - 1) * 2 + 1];
160                 --size;
161                 break;
162             }
163         }
164         
165         // Reduce list size if necessary.
166
if (size == 0) {
167             listeners = EMPTY;
168         } else if (listeners.length / 2 - size > DECREMENT) {
169             // more than DECREMENT empty slots exist: trim to size.
170
Object JavaDoc[] newListeners = new Object JavaDoc[size * 2];
171             System.arraycopy(listeners, 0, newListeners, 0, newListeners.length);
172             listeners = newListeners;
173         }
174     }
175     
176     /**
177      * @see java.io.Serializable
178      */

179     private void writeObject(ObjectOutputStream JavaDoc out)
180     throws IOException JavaDoc {
181         out.defaultWriteObject();
182         for (int index = 0; index < size; ++index) {
183             String JavaDoc listenerClassName = ((Class JavaDoc) listeners[index * 2]).getName();
184             EventListener JavaDoc listener = (EventListener JavaDoc) listeners[index * 2 + 1];
185             if (listener instanceof Serializable JavaDoc) {
186                 out.writeObject(listenerClassName);
187                 out.writeObject(listener);
188             }
189         }
190         out.writeObject(null); // Note end of listener list.
191
}
192 }
193
Popular Tags