KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > mmbase > core > event > EventManager


1 /*
2  * Created on 30-sep-2005
3  *
4  * This software is OSI Certified Open Source Software.
5  * OSI Certified is a certification mark of the Open Source Initiative.
6  *
7  * The license (Mozilla version 1.0) can be read at the MMBase site.
8  * See http://www.MMBase.org/license
9  */

10 package org.mmbase.core.event;
11
12 import java.io.IOException JavaDoc;
13 import java.util.*;
14 import java.net.URL JavaDoc;
15
16 import org.mmbase.util.*;
17 import org.mmbase.util.logging.Logger;
18 import org.mmbase.util.logging.Logging;
19 import org.mmbase.util.xml.DocumentReader;
20 import org.w3c.dom.Document JavaDoc;
21 import org.w3c.dom.Element JavaDoc;
22 import org.xml.sax.SAXException JavaDoc;
23
24 import edu.emory.mathcs.backport.java.util.concurrent.CopyOnWriteArraySet;
25
26 /**
27  * This class manages all event related stuff. it is the place to register event brokers, and it
28  * will propagate all events. The class is set up as a singleton, with lazy instantiation. When the
29  * manager is instantiated, event brokers are added for Event, NodeEvent and RelationEvent
30  * @author Ernst Bunders
31  * @since MMBase-1.8
32  * @version $Id: EventManager.java,v 1.12 2006/06/20 21:23:15 michiel Exp $
33  */

34 public class EventManager {
35
36     private static final Logger log = Logging.getLoggerInstance(EventManager.class);
37
38     public static final String JavaDoc PUBLIC_ID_EVENTMANAGER = "-//MMBase//DTD eventmanager config 1.0//EN";
39     public static final String JavaDoc DTD_EVENTMANAGER = "eventmanager_1_0.dtd";
40
41
42     static {
43         org.mmbase.util.XMLEntityResolver.registerPublicID(PUBLIC_ID_EVENTMANAGER, DTD_EVENTMANAGER, EventManager.class);
44     }
45
46     /**
47      * the instance that this singleton will manage
48      */

49     private static final EventManager eventManager = new EventManager();
50
51     /**
52      * The collection of event brokers. There is one for every event type that can be sent/received
53      */

54     private final Set eventBrokers = new CopyOnWriteArraySet();
55
56     private long numberOfPropagatedEvents = 0;
57     private long duration = 0;
58
59     /**
60      * use this metod to get an instance of the event manager
61      */

62     public static EventManager getInstance() {
63         return eventManager;
64     }
65
66     private static AbstractEventBroker findInstance(String JavaDoc className) {
67         if (className == null || "".equals(className)) return null;
68         try {
69             Class JavaDoc aClass = Class.forName(className);
70             return (AbstractEventBroker) aClass.newInstance();
71         } catch (ClassNotFoundException JavaDoc e) {
72             log.error("could not find class with name " + className, e);
73         } catch (InstantiationException JavaDoc e) {
74             log.error("could not instantiate class with name" + className, e);
75         } catch (IllegalAccessException JavaDoc e) {
76             log.error("the constructor of " + className + " is not accessible", e);
77         } catch (ClassCastException JavaDoc e) {
78             log.error("" + className + " is not a AbstratEventBroker");
79         }
80         return null;
81     }
82
83     protected ResourceWatcher watcher = new ResourceWatcher() {
84             public void onChange(String JavaDoc w) {
85                 configure(w);
86             }
87         };
88
89     private EventManager() {
90         watcher.add("eventmanager.xml");
91         watcher.onChange();
92         watcher.start();
93     }
94
95
96     protected void configure(String JavaDoc resource) {
97         log.service("Configuring the event manager");
98         eventBrokers.clear();
99         Iterator i = ResourceLoader.getConfigurationRoot().getResourceList(resource).iterator();
100         while (i.hasNext()) {
101             URL JavaDoc url = (URL JavaDoc) i.next();
102             try {
103                 if (url.openConnection().getDoInput()) {
104
105                     Document JavaDoc config = ResourceLoader.getDocument(url, true, EventManager.class);
106                     DocumentReader configReader = new DocumentReader(config);
107
108                     // find the event brokers
109
Iterator e = configReader.getChildElements("eventmanager.brokers", "broker");
110                     while (e.hasNext()) {
111                         Element JavaDoc element = (Element JavaDoc) e.next();
112                         String JavaDoc className = element.getAttribute("class");
113                         AbstractEventBroker broker = (AbstractEventBroker) findInstance(className);
114                         if (broker != null) {
115                             if (log.isDebugEnabled()) {
116                                 log.debug("adding event broker: " + broker);
117                             }
118                             addEventBroker(broker);
119                         }
120                     }
121                 }
122             } catch (SAXException JavaDoc e1) {
123                 log.error("Something went wrong configuring the event system (" + url + "): " + e1.getMessage(), e1);
124             } catch (IOException JavaDoc e1) {
125                 log.error("something went wrong configuring the event system (" + url + "): " + e1.getMessage(), e1);
126
127             }
128         }
129         if (eventBrokers.size() == 0) {
130             log.fatal("No event brokers could not be found. This means that query-invalidation does not work correctly now. Proceeding anyway.");
131             return;
132         }
133     }
134     /**
135      * add an event broker for a specific type of event
136      * @param broker
137      */

138     public void addEventBroker(AbstractEventBroker broker) {
139         //we want only one instance of each broker
140
if(! eventBrokers.contains(broker)){
141             if (log.isDebugEnabled()) {
142                 log.debug("adding broker " + broker.toString());
143             }
144             eventBrokers.add(broker);
145         } else {
146             if (log.isDebugEnabled()) {
147                 log.debug("broker " + broker.toString() + "was already registered: rejected.");
148             }
149         }
150     }
151
152     /**
153      * remove a broker for a specific type of event
154      * @param broker
155      */

156     public void removeEventBroker(AbstractEventBroker broker) {
157         eventBrokers.remove(broker);
158     }
159
160     /**
161      * @param listener
162      */

163     public void addEventListener(EventListener listener) {
164         BrokerIterator i = findBrokers(listener);
165         while (i.hasNext()) {
166             AbstractEventBroker broker = i.nextBroker();
167             if (broker.addListener(listener)) {
168                 if (log.isDebugEnabled()) {
169                     log.debug("listener " + listener + " added to broker " + broker );
170                 }
171             }
172         }
173     }
174
175
176     /**
177      * @param listener
178      */

179     public void removeEventListener(EventListener listener) {
180         if (log.isDebugEnabled()) {
181             log.debug("removing listener of type: " + listener.getClass().getName());
182         }
183         BrokerIterator i = findBrokers(listener);
184         while (i.hasNext()) {
185             i.nextBroker().removeListener(listener);
186         }
187     }
188
189     /**
190      * This method will propagate the given event to all the aproprate listeners. what makes a
191      * listener apropriate is determined by it's type (class) and by possible constraint properties
192      * (if the handling broker supports those
193      * @see AbstractEventBroker
194      * @param event
195      */

196     public void propagateEvent(Event event) {
197         if (log.isTraceEnabled()) {
198             log.trace("Propagating events to " + eventBrokers);
199         }
200         long startTime = System.currentTimeMillis();
201         for (Iterator i = eventBrokers.iterator(); i.hasNext();) {
202             AbstractEventBroker broker = (AbstractEventBroker) i.next();
203             if (broker.canBrokerForEvent(event)) {
204                 broker.notifyForEvent(event);
205                 if (log.isDebugEnabled()) {
206                     if (log.isTraceEnabled()) {
207                         log.trace("event: " + event + " has been accepted by broker " + broker);
208                     } else {
209                         log.debug("event has been accepted by broker " + broker);
210                     }
211                 }
212             } else {
213                 if (log.isDebugEnabled()) {
214                     if (log.isTraceEnabled()) {
215                         log.trace("event: " + event + " has been rejected by broker " + broker);
216                     } else {
217                         log.debug("event has been rejected by broker " + broker);
218                     }
219                 }
220             }
221         }
222         numberOfPropagatedEvents++;
223         duration += (System.currentTimeMillis() - startTime);
224     }
225
226     /**
227      * @since MMBase-1.8.1
228      */

229     public long getNumberOfPropagatedEvents() {
230         return numberOfPropagatedEvents;
231     }
232     /**
233      * @since MMBase-1.8.1
234      */

235     public long getPropagationCost() {
236         return duration;
237     }
238
239
240     /**
241      * @param listener
242      */

243     private BrokerIterator findBrokers(final EventListener listener) {
244         if (log.isDebugEnabled()) {
245             log.debug("try to find broker for " + listener.getClass().getName());
246         }
247         return new BrokerIterator(eventBrokers.iterator(), listener);
248     }
249
250     private static class BrokerIterator implements Iterator {
251         AbstractEventBroker next;
252         final Iterator i;
253         final EventListener listener;
254
255         BrokerIterator(final Iterator i, final EventListener listener) {
256             this.i = i;
257             this.listener = listener;
258             findNext();
259         }
260         public void remove() {
261             throw new UnsupportedOperationException JavaDoc();
262         }
263         public Object JavaDoc next() {
264             return nextBroker();
265         }
266         public boolean hasNext() {
267             return next != null;
268         }
269         public AbstractEventBroker nextBroker() {
270             if (next == null) throw new NoSuchElementException();
271             AbstractEventBroker n = next;
272             findNext();
273             return n;
274         }
275         protected void findNext() {
276             while(i.hasNext()) {
277                 AbstractEventBroker broker = (AbstractEventBroker) i.next();
278                 if (broker.canBrokerForListener(listener)) {
279                     if (log.isDebugEnabled()) {
280                         log.debug("broker " + broker + " can broker for eventlistener " + listener.getClass().getName());
281                     }
282                     next = broker;
283                     return;
284                 } else if (log.isDebugEnabled()) {
285                     log.debug("broker " + broker + " cannot boker for eventlistener." + listener.getClass().getName());
286                 }
287             }
288             next = null;
289         }
290
291     }
292
293
294
295 }
296
Popular Tags