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