Author: michiel
Date: 2010-04-02 18:03:59 +0200 (Fri, 02 Apr 2010)
New Revision: 41741

Added:
   mmbase/trunk/utils/src/main/java/org/mmbase/core/event/EventManager.java
   mmbase/trunk/utils/src/main/java/org/mmbase/core/event/SystemEvent.java
   mmbase/trunk/utils/src/main/java/org/mmbase/core/event/SystemEventBroker.java
   
mmbase/trunk/utils/src/main/java/org/mmbase/core/event/SystemEventListener.java
Log:
moved from core

Copied: 
mmbase/trunk/utils/src/main/java/org/mmbase/core/event/EventManager.java (from 
rev 41740, 
mmbase/trunk/core/src/main/java/org/mmbase/core/event/EventManager.java)
===================================================================
--- mmbase/trunk/utils/src/main/java/org/mmbase/core/event/EventManager.java    
                        (rev 0)
+++ mmbase/trunk/utils/src/main/java/org/mmbase/core/event/EventManager.java    
2010-04-02 16:03:59 UTC (rev 41741)
@@ -0,0 +1,341 @@
+/*
+ * This software is OSI Certified Open Source Software.
+ * OSI Certified is a certification mark of the Open Source Initiative.
+ *
+ * The license (Mozilla version 1.0) can be read at the MMBase site.
+ * See http://www.MMBase.org/license
+ */
+package org.mmbase.core.event;
+
+import java.io.IOException;
+import java.util.*;
+import java.net.URL;
+
+import org.mmbase.util.*;
+import org.mmbase.util.logging.Logger;
+import org.mmbase.util.logging.Logging;
+import org.mmbase.util.xml.DocumentReader;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.xml.sax.SAXException;
+
+import java.util.concurrent.CopyOnWriteArraySet;
+
+/**
+ * This class manages all event related stuff. it is the place to register 
event brokers, and it
+ * will propagate all events. The class is set up as a singleton. When the 
manager is instantiated,
+ * event brokers are added for Event, NodeEvent and RelationEvent
+ *
+ * @author  Ernst Bunders
+ * @since   MMBase-1.8
+ * @version $Id$
+ */
+public class EventManager implements SystemEventListener {
+
+    private static final Logger log = 
Logging.getLoggerInstance(EventManager.class);
+
+    private static final UUID INSTANCEID = UUID.randomUUID();
+    private static String machineName = "localhost";
+
+    public static final String PUBLIC_ID_EVENTMANAGER = "-//MMBase//DTD 
eventmanager config 1.0//EN";
+    public static final String DTD_EVENTMANAGER = "eventmanager_1_0.dtd";
+
+
+    static {
+        
org.mmbase.util.xml.EntityResolver.registerPublicID(PUBLIC_ID_EVENTMANAGER, 
DTD_EVENTMANAGER, EventManager.class);
+    }
+
+    /**
+     * the instance that this singleton will manage
+     */
+    private static final EventManager eventManager = new EventManager();
+
+    /**
+     * The collection of event brokers. There is one for every event type that 
can be sent/received
+     */
+    private final Set<EventBroker> eventBrokers = new 
CopyOnWriteArraySet<EventBroker>();
+
+    private long numberOfPropagatedEvents = 0;
+    private long duration = 0;
+
+    /**
+     * use this metod to get an instance of the event manager
+     */
+    public static EventManager getInstance() {
+        return eventManager;
+    }
+
+    /**
+     * @since MMBase-2.0
+     */
+    public static UUID getUUID() {
+        return INSTANCEID;
+    }
+    /**
+     * @since MMBase-2.0
+     */
+    public static String getMachineName() {
+        return machineName;
+    }
+
+    public void notify(SystemEvent se) {
+        if (se instanceof SystemEvent.MachineName) {
+            machineName = ((SystemEvent.MachineName) se).getName();
+        }
+    }
+
+
+    protected ResourceWatcher watcher = new ResourceWatcher() {
+            public void onChange(String w) {
+                configure(w);
+            }
+        };
+
+    private EventManager() {
+        watcher.add("eventmanager.xml");
+        watcher.onChange();
+        watcher.start();
+    }
+
+
+    protected void configure(String resource) {
+        log.service("Configuring the event manager");
+        eventBrokers.clear();
+        for (URL url : 
ResourceLoader.getConfigurationRoot().getResourceList(resource)) {
+            try {
+                if (url.openConnection().getDoInput()) {
+
+                    Document config = ResourceLoader.getDocument(url, true, 
EventManager.class);
+                    DocumentReader configReader = new DocumentReader(config);
+
+                    // find the event brokers
+                    for (Element element: 
configReader.getChildElements("eventmanager.brokers", "broker")) {
+                        try {
+                            EventBroker broker = (EventBroker) 
org.mmbase.util.xml.Instantiator.getInstance(element);
+                            if (broker != null) {
+                                if (log.isDebugEnabled()) {
+                                    log.debug("adding event broker: " + 
broker);
+                                }
+                                addEventBroker(broker);
+                            }
+                        } catch (Throwable ee) {
+                            log.warn(ee.getMessage(), ee);
+                        }
+                    }
+                }
+            } catch (SAXException e1) {
+                log.error("Something went wrong configuring the event system 
(" + url + "): " + e1.getMessage(), e1);
+            } catch (IOException e1) {
+                log.error("something went wrong configuring the event system 
(" + url + "): " + e1.getMessage(), e1);
+
+            }
+        }
+        if (eventBrokers.size() == 0) {
+            log.fatal("No event brokers could not be found. This means that 
query-invalidation does not work correctly now. Proceeding anyway.");
+            return;
+        }
+        addEventListener(this);
+    }
+
+    /**
+     * @since MMBase-1.8.5
+     */
+
+    public Collection<EventBroker> getBrokers() {
+        return Collections.unmodifiableSet(eventBrokers);
+    }
+
+    /**
+     * add an event broker for a specific type of event
+     * @param broker
+     */
+    public void addEventBroker(EventBroker broker) {
+        //we want only one instance of each broker
+        if(! eventBrokers.contains(broker)){
+            if (log.isDebugEnabled()) {
+                log.debug("adding broker " + broker.toString());
+            }
+            eventBrokers.add(broker);
+        } else {
+            if (log.isDebugEnabled()) {
+                log.debug("broker " + broker.toString() + "was already 
registered: rejected.");
+            }
+        }
+    }
+
+    /**
+     * remove a broker for a specific type of event
+     * @param broker
+     */
+    public void removeEventBroker(EventBroker broker) {
+        eventBrokers.remove(broker);
+    }
+
+    /**
+     * @param listener
+     */
+    public void addEventListener(EventListener listener) {
+        BrokerIterator i =  findBrokers(listener);
+        while (i.hasNext()) {
+            EventBroker broker = i.next();
+            if (broker.addListener(listener)) {
+                if (log.isDebugEnabled()) {
+                    log.debug("listener " + listener + " added to broker " + 
broker );
+                }
+            }
+        }
+    }
+
+
+    /**
+     * @param listener
+     */
+    public void removeEventListener(EventListener listener) {
+        if (log.isDebugEnabled()) {
+            log.debug("removing listener of type: " + 
listener.getClass().getName());
+        }
+        BrokerIterator i = findBrokers(listener);
+        while (i.hasNext()) {
+            i.next().removeListener(listener);
+        }
+    }
+
+    /**
+     * This method will propagate the given event to all the aproprate 
listeners. what makes a
+     * listener apropriate is determined by it's type (class) and by possible 
constraint properties
+     * (if the handling broker supports those
+     * @see AbstractEventBroker
+     * @param event
+     */
+    public void propagateEvent(Event event) {
+        if (log.isTraceEnabled()) {
+            log.trace("Propagating events to " + eventBrokers);
+        }
+        long startTime = System.nanoTime();
+        for (EventBroker broker :  eventBrokers) {
+            try {
+                if (broker.canBrokerForEvent(event)) {
+                    broker.notifyForEvent(event);
+                    if (log.isDebugEnabled()) {
+                        if (log.isTraceEnabled()) {
+                            log.trace("event from '" + event.getMachine() + 
"': " + event + " has been accepted by broker " + broker);
+                        } else {
+                            log.debug("event from '" + event.getMachine() + "' 
has been accepted by broker " + broker);
+                        }
+                    }
+                } else {
+                    if (log.isDebugEnabled()) {
+                        if (log.isTraceEnabled()) {
+                            log.trace("event from '" + event.getMachine() + 
"': " + event + " has been rejected by broker " + broker);
+                        } else {
+                            log.debug("event from '" + event.getMachine() + "' 
has been rejected by broker " + broker);
+                        }
+                    }
+                }
+            } catch (Exception e) {
+                log.error(e.getMessage(), e);
+            }
+        }
+        numberOfPropagatedEvents++;
+        duration += (System.nanoTime() - startTime);
+    }
+
+    /**
+     * Like {...@link #propagateEvent} but with an extra argument 
'asynchronous'.
+     * @param asynchronous If true, execute the propagation in a different 
thread, and don't let this thread wait for the result.
+     */
+    public void propagateEvent(final Event event, boolean asynchronous) {
+        if (asynchronous) {
+            ThreadPools.jobsExecutor.execute(new Runnable() {
+                    public void run() {
+                        propagateEvent(event);
+                    }
+                });
+        } else {
+            propagateEvent(event);
+        }
+    }
+
+    /**
+     * @since MMBase-1.8.1
+     */
+    public long getNumberOfPropagatedEvents() {
+        return numberOfPropagatedEvents;
+    }
+    /**
+     * @since MMBase-1.8.1
+     */
+    public long getPropagationCost() {
+        return duration / 1000000;
+    }
+    /**
+     * @since MMBase-1.9
+     */
+    public long getPropagationCostNs() {
+        return duration;
+    }
+
+
+    /**
+     * @param listener
+     */
+    private BrokerIterator findBrokers(final EventListener listener) {
+        if (log.isDebugEnabled()) {
+            log.debug("try to find broker for " + 
listener.getClass().getName());
+        }
+        return new BrokerIterator(eventBrokers.iterator(), listener);
+    }
+
+    /**
+     * @since MMBase-1.9
+     */
+    public void shutdown() {
+        log.service("Shutting down event manager");
+        eventBrokers.clear();
+        watcher.exit();
+    }
+
+    private static class BrokerIterator implements Iterator<EventBroker> {
+        EventBroker next;
+        final Iterator<EventBroker> i;
+        final EventListener listener;
+
+        BrokerIterator(final Iterator<EventBroker> i, final EventListener 
listener) {
+            this.i = i;
+            this.listener = listener;
+            findNext();
+        }
+        public void remove() {
+            throw new UnsupportedOperationException();
+        }
+        public EventBroker next() {
+            if (next == null) throw new NoSuchElementException();
+            EventBroker n = next;
+            findNext();
+            return n;
+        }
+        public boolean hasNext() {
+            return next != null;
+        }
+
+        protected void findNext() {
+            while(i.hasNext()) {
+                EventBroker broker = i.next();
+                if (broker.canBrokerForListener(listener)) {
+                    if (log.isDebugEnabled()) {
+                        log.debug("broker " + broker + " can broker for 
eventlistener " + listener.getClass().getName());
+                    }
+                    next = broker;
+                    return;
+                } else if (log.isDebugEnabled()) {
+                    log.debug("broker " + broker + " cannot boker for 
eventlistener." + listener.getClass().getName());
+                }
+            }
+            next = null;
+        }
+
+    }
+
+
+
+}

Copied: mmbase/trunk/utils/src/main/java/org/mmbase/core/event/SystemEvent.java 
(from rev 41740, 
mmbase/trunk/core/src/main/java/org/mmbase/core/event/SystemEvent.java)
===================================================================
--- mmbase/trunk/utils/src/main/java/org/mmbase/core/event/SystemEvent.java     
                        (rev 0)
+++ mmbase/trunk/utils/src/main/java/org/mmbase/core/event/SystemEvent.java     
2010-04-02 16:03:59 UTC (rev 41741)
@@ -0,0 +1,55 @@
+/*
+ * This software is OSI Certified Open Source Software.
+ * OSI Certified is a certification mark of the Open Source Initiative. The
+ * license (Mozilla version 1.0) can be read at the MMBase site. See
+ * http://www.MMBase.org/license
+ */
+package org.mmbase.core.event;
+
+import java.io.*;
+import java.util.*;
+
+import org.mmbase.util.logging.Logger;
+import org.mmbase.util.logging.Logging;
+
+/**
+ *
+ * @author  Michiel Meeuwissen
+ * @since   MMBase-1.9.3
+ * @version $Id: TransactionEvent.java 41369 2010-03-15 20:54:45Z michiel $
+ */
+public abstract class SystemEvent extends Event {
+    private static final Logger LOG = 
Logging.getLoggerInstance(SystemEvent.class);
+
+    public SystemEvent() {
+    }
+
+    /**
+     * Notifies that the local MMBase is now fully up and running
+     */
+    public static class Up extends SystemEvent {
+    }
+
+    /**
+     * Notifies the first determination or change in the 'machinename'
+     */
+    public static class MachineName extends SystemEvent {
+        private final String name;
+        public MachineName(String n) {
+            name = n;
+        }
+        public String getName() {
+            return name;
+        }
+    }
+
+    static {
+        SystemEventListener logger = new SystemEventListener() {
+                public void notify(SystemEvent s) {
+                    LOG.service(" Received " + s);
+                }
+            };
+        EventManager.getInstance().addEventListener(logger);
+    }
+
+}

Copied: 
mmbase/trunk/utils/src/main/java/org/mmbase/core/event/SystemEventBroker.java 
(from rev 41739, 
mmbase/trunk/core/src/main/java/org/mmbase/core/event/SystemEventBroker.java)
===================================================================
--- 
mmbase/trunk/utils/src/main/java/org/mmbase/core/event/SystemEventBroker.java   
                            (rev 0)
+++ 
mmbase/trunk/utils/src/main/java/org/mmbase/core/event/SystemEventBroker.java   
    2010-04-02 16:03:59 UTC (rev 41741)
@@ -0,0 +1,55 @@
+/*
+ * This software is OSI Certified Open Source Software.
+ * OSI Certified is a certification mark of the Open Source Initiative. The
+ * license (Mozilla version 1.0) can be read at the MMBase site. See
+ * http://www.MMBase.org/license
+ */
+package org.mmbase.core.event;
+
+
+/**
+ *
+ * @author Michiel Meeuwissen
+ * @since MMBase-1.9.3
+ * @version $Id: TransactionEventBroker.java 41369 2010-03-15 20:54:45Z 
michiel $
+ */
+public class SystemEventBroker extends AbstractEventBroker {
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see event.AbstractEventBroker#canBrokerFor(java.lang.Class)
+     */
+    public boolean canBrokerForListener(EventListener listener) {
+        return listener instanceof SystemEventListener;
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see event.AbstractEventBroker#shouldNotifyForEvent(event.Event)
+     */
+    public boolean canBrokerForEvent(Event event) {
+        return event instanceof SystemEvent;
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see event.AbstractEventBroker#notifyEventListeners()
+     */
+    protected void notifyEventListener(Event event, EventListener listener) {
+        SystemEvent te = (SystemEvent) event; //!!!!!
+        SystemEventListener sel = (SystemEventListener) listener;
+        sel.notify(te);
+    }
+
+    /* (non-Javadoc)
+     * @see org.mmbase.core.event.AbstractEventBroker#toString()
+     */
+    @Override
+    public String toString() {
+        return "SystemEvent Broker";
+    }
+
+}

Copied: 
mmbase/trunk/utils/src/main/java/org/mmbase/core/event/SystemEventListener.java 
(from rev 41739, 
mmbase/trunk/core/src/main/java/org/mmbase/core/event/SystemEventListener.java)
===================================================================
--- 
mmbase/trunk/utils/src/main/java/org/mmbase/core/event/SystemEventListener.java 
                            (rev 0)
+++ 
mmbase/trunk/utils/src/main/java/org/mmbase/core/event/SystemEventListener.java 
    2010-04-02 16:03:59 UTC (rev 41741)
@@ -0,0 +1,17 @@
+/*
+ * This software is OSI Certified Open Source Software.
+ * OSI Certified is a certification mark of the Open Source Initiative. The
+ * license (Mozilla version 1.0) can be read at the MMBase site. See
+ * http://www.MMBase.org/license
+ */
+package org.mmbase.core.event;
+
+/**
+ *
+ * @author Michiel Meeuwissen
+ * @since MMBase-1.9.3
+ * @version $Id: TransactionEventListener.java 41419 2010-03-16 12:54:44Z 
michiel $
+ */
+public interface SystemEventListener extends EventListener {
+    public void notify(SystemEvent event);
+}

_______________________________________________
Cvs mailing list
[email protected]
http://lists.mmbase.org/mailman/listinfo/cvs

Reply via email to