KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jboss > kernel > plugins > event > AbstractEventEmitter


1 /*
2 * JBoss, Home of Professional Open Source
3 * Copyright 2005, JBoss Inc., and individual contributors as indicated
4 * by the @authors tag. See the copyright.txt in the distribution for a
5 * full listing of individual contributors.
6 *
7 * This is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU Lesser General Public License as
9 * published by the Free Software Foundation; either version 2.1 of
10 * the License, or (at your option) any later version.
11 *
12 * This software is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this software; if not, write to the Free
19 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
21 */

22 package org.jboss.kernel.plugins.event;
23
24 import java.util.Iterator JavaDoc;
25 import java.util.List JavaDoc;
26 import java.util.ListIterator JavaDoc;
27 import java.util.Map JavaDoc;
28
29 import org.jboss.kernel.spi.event.KernelEvent;
30 import org.jboss.kernel.spi.event.KernelEventEmitter;
31 import org.jboss.kernel.spi.event.KernelEventFilter;
32 import org.jboss.kernel.spi.event.KernelEventListener;
33 import org.jboss.logging.Logger;
34 import org.jboss.util.collection.CollectionsFactory;
35
36 /**
37  * Abstract Event emitter.
38  *
39  * @author <a HREF="adrian@jboss.com">Adrian Brock</a>
40  * @version $Revision: 45764 $
41  */

42 public class AbstractEventEmitter implements KernelEventEmitter
43 {
44    /** The log */
45    private static final Logger log = Logger.getLogger(AbstractEventEmitter.class);
46
47    /** Used to represent a null parameter */
48    protected static final Object JavaDoc NULL = new Object JavaDoc();
49
50    /** Used to represent a null filter */
51    protected static final KernelEventFilter NULL_FILTER = new KernelEventFilter()
52    {
53       public boolean wantEvent(KernelEvent event, Object JavaDoc handback)
54       {
55          return false;
56       }
57    };
58
59    /** The registry Map<filter, Map<handback, List<listener>>>*/
60    protected Map JavaDoc<KernelEventFilter, Map JavaDoc<Object JavaDoc, List JavaDoc<KernelEventListener>>> eventListenerRegistry = CollectionsFactory.createConcurrentReaderMap();
61
62    /** The sequence number of this emitter */
63    private long emitterSequence = 0;
64
65    /**
66     * Do we have listeners
67     *
68     * @return true when there are listeners
69     */

70    public boolean hasListeners()
71    {
72       return eventListenerRegistry.isEmpty() == false;
73    }
74
75    /**
76     * Make a new event
77     */

78    public KernelEvent createEvent(String JavaDoc type, Object JavaDoc context)
79    {
80       return new AbstractEvent(this, type, nextEmitterSequence(), System.currentTimeMillis(), context);
81    }
82
83    public void registerListener(KernelEventListener listener, KernelEventFilter filter, Object JavaDoc handback) throws Throwable JavaDoc
84    {
85       KernelEventFilter filterObject = filter == null ? NULL_FILTER : filter;
86       Object JavaDoc handbackObject = handback == null ? NULL : handback;
87
88       synchronized (eventListenerRegistry)
89       {
90          Map JavaDoc<Object JavaDoc, List JavaDoc<KernelEventListener>> handbacks = eventListenerRegistry.get(filterObject);
91          if (handbacks == null)
92          {
93             handbacks = CollectionsFactory.createConcurrentReaderMap();
94             eventListenerRegistry.put(filterObject, handbacks);
95          }
96          List JavaDoc<KernelEventListener> listeners = handbacks.get(handbackObject);
97          if (listeners == null)
98          {
99             listeners = CollectionsFactory.createCopyOnWriteList();
100             handbacks.put(handbackObject, listeners);
101          }
102          listeners.add(listener);
103          if (log.isTraceEnabled())
104             log.trace("Registered listener: " + listener + " with filter=" + filter + " handback=" + handback + " on object " + this);
105
106       }
107    }
108
109    public void unregisterListener(KernelEventListener listener, KernelEventFilter filter, Object JavaDoc handback) throws Throwable JavaDoc
110    {
111       KernelEventFilter filterObject = filter == null ? NULL_FILTER : filter;
112       Object JavaDoc handbackObject = handback == null ? NULL : handback;
113
114       synchronized (eventListenerRegistry)
115       {
116          Map JavaDoc<Object JavaDoc, List JavaDoc<KernelEventListener>> handbacks = eventListenerRegistry.get(filterObject);
117          if (handbacks != null)
118          {
119             List JavaDoc<KernelEventListener> listeners = handbacks.get(handbackObject);
120             if (listeners != null && listeners.remove(listener))
121             {
122                if (log.isTraceEnabled())
123                   log.trace("Unregistered listener: " + listener + " with filter=" + filter + " handback=" + handback + " on object " + this);
124                return;
125             }
126          }
127       }
128       throw new IllegalStateException JavaDoc("Listener not registered.");
129    }
130
131    public void fireKernelEvent(KernelEvent event)
132    {
133       if (log.isTraceEnabled())
134          log.trace("Firing event: " + event + " on object " + this);
135       if (eventListenerRegistry.isEmpty() == false)
136       {
137          for (Iterator JavaDoc i = eventListenerRegistry.entrySet().iterator(); i.hasNext();)
138          {
139             Map.Entry JavaDoc registryEntry = (Map.Entry JavaDoc) i.next();
140
141             Map JavaDoc handbacks = (Map JavaDoc) registryEntry.getValue();
142             if (handbacks != null)
143             {
144                KernelEventFilter filter = null;
145                Object JavaDoc filterObject = registryEntry.getKey();
146                if (filterObject != NULL_FILTER)
147                   filter = (KernelEventFilter) filterObject;
148
149                for (Iterator JavaDoc j = handbacks.entrySet().iterator(); j.hasNext();)
150                {
151                   Map.Entry JavaDoc handbackEntry = (Map.Entry JavaDoc) j.next();
152                   List JavaDoc listeners = (List JavaDoc) handbackEntry.getValue();
153                   if (listeners != null)
154                   {
155                      Object JavaDoc handback = handbackEntry.getKey();
156                      if (handback == NULL)
157                         handback = null;
158
159                      for (ListIterator JavaDoc k = listeners.listIterator(); k.hasNext();)
160                      {
161                         KernelEventListener listener = (KernelEventListener) k.next();
162                         try
163                         {
164                            if (filter == null || filter.wantEvent(event, handback))
165                               fireKernelEvent(listener, event, handback);
166                         }
167                         catch (Throwable JavaDoc t)
168                         {
169                            log.debug("Ignored unhandled throwable: ", t);
170                         }
171                      }
172                   }
173                }
174             }
175          }
176       }
177    }
178
179    /**
180     * Fire a kernel event to a single listener
181     *
182     * @param listener the listener
183     * @param event the event
184     * @param handback the handback object
185     */

186    protected void fireKernelEvent(KernelEventListener listener, KernelEvent event, Object JavaDoc handback)
187    {
188       listener.onEvent(event, handback);
189    }
190
191    /**
192     * Get the next emitter sequence
193     *
194     * @return the next emitter sequence
195     */

196    protected long nextEmitterSequence()
197    {
198       synchronized (eventListenerRegistry)
199       {
200          return emitterSequence++;
201       }
202    }
203 }
204
Popular Tags