You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@cocoon.apache.org by cz...@apache.org on 2005/06/01 21:40:17 UTC

svn commit: r179405 - in /cocoon/blocks/portal/trunk/java/org/apache/cocoon/portal/event: EventManager.java Publisher.java Receiver.java Register.java aspect/EventAspectContext.java impl/DefaultEventManager.java

Author: cziegeler
Date: Wed Jun  1 12:40:16 2005
New Revision: 179405

URL: http://svn.apache.org/viewcvs?rev=179405&view=rev
Log:
Start new, simpler event infrastructure

Added:
    cocoon/blocks/portal/trunk/java/org/apache/cocoon/portal/event/Receiver.java   (with props)
Modified:
    cocoon/blocks/portal/trunk/java/org/apache/cocoon/portal/event/EventManager.java
    cocoon/blocks/portal/trunk/java/org/apache/cocoon/portal/event/Publisher.java
    cocoon/blocks/portal/trunk/java/org/apache/cocoon/portal/event/Register.java
    cocoon/blocks/portal/trunk/java/org/apache/cocoon/portal/event/aspect/EventAspectContext.java
    cocoon/blocks/portal/trunk/java/org/apache/cocoon/portal/event/impl/DefaultEventManager.java

Modified: cocoon/blocks/portal/trunk/java/org/apache/cocoon/portal/event/EventManager.java
URL: http://svn.apache.org/viewcvs/cocoon/blocks/portal/trunk/java/org/apache/cocoon/portal/event/EventManager.java?rev=179405&r1=179404&r2=179405&view=diff
==============================================================================
--- cocoon/blocks/portal/trunk/java/org/apache/cocoon/portal/event/EventManager.java (original)
+++ cocoon/blocks/portal/trunk/java/org/apache/cocoon/portal/event/EventManager.java Wed Jun  1 12:40:16 2005
@@ -1,5 +1,5 @@
 /*
- * Copyright 1999-2002,2004 The Apache Software Foundation.
+ * Copyright 1999-2002,2004-2005 The Apache Software Foundation.
  * 
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -18,15 +18,20 @@
 import org.apache.cocoon.ProcessingException;
 
 /**
- * <p>Service to manage event notification. The designed has been inspired by the paper by 
+ * This component manages the event handling mechanism in the portal.
+ * The event mechanism is based on the publisher/subscriber principle.
+ * An interested component (a {@link org.apache.cocoon.portal.event.Receiver}
+ * can subscribe itself for a specific class (or classes) of events.
+ * All Events have a common ancestor type {@link Event} and the event types are 
+ * identified by a (sub)class
+ * 
+ * The old design which is now deprecated has been inspired by the paper by 
  * Gupta, S., J. M. Hartkopf, and S. Ramaswamy, in Java Report, Vol. 3, No. 7, July 1998, 19-36,
- * "Event Notifier: A Pattern for Event Notification".</p>  
+ * "Event Notifier: A Pattern for Event Notification".  
  * 
- * <p>EventManager brokers events between a <tt>Publisher</tt>, which produces events,
+ * EventManager brokers events between a <tt>Publisher</tt>, which produces events,
  * and a <tt>Subscriber</tt>, which handles the notification of events.
  * A <tt>Filter</tt> discards events not of interest to a subscriber.
- * All Events have a common ancestor type <tt>Event</tt> and the event types are 
- * identified by a <tt>Class</tt>.</p>
  * 
  * @author <a href="mailto:cziegeler@s-und-n.de">Carsten Ziegeler</a>
  * @author <a href="mailto:volker.schmitt@basf-it-services.com">Volker Schmitt</a>
@@ -37,18 +42,20 @@
 public interface EventManager {
  
     /**
-     * Represents Role of the service
+     * Represents the role of the service
      */
     String ROLE = EventManager.class.getName(); 
     
      /**
       *  Returns the Publisher with which events can be published.
+      *  @deprecated Use {@link #send(Event)} instead.
       */
     Publisher getPublisher();
     
      /**
       *  Returns the Register with which subscribers can 
       *  subscribe and unsubscribe interest to given Events.
+      *  @deprecated Use {@link #subscribe(Class, Receiver)} and {@link #unsubscribe(Receiver)}.
       */
     Register getRegister();
 
@@ -57,9 +64,26 @@
      */
     void processEvents()
     throws ProcessingException;
-     
 
-}
+    /**
+     * Publish an event. All registered receivers get notified.
+     * @param event The event to broadcast.
+     */
+    void send(Event event);
+
+    /**
+     * Subscribes a receiver for a specific type of event.  
+     */
+    void subscribe(Class event, Receiver receiver);
 
+    /**
+     * Subscribes a receiver for several specific events.  
+     */
+    void subscribe(Class[] events, Receiver receiver);
 
+    /**
+     * Unsubscribes a receiver for all events.
+     */
+    void unsubscribe(Receiver receiver);
 
+}

Modified: cocoon/blocks/portal/trunk/java/org/apache/cocoon/portal/event/Publisher.java
URL: http://svn.apache.org/viewcvs/cocoon/blocks/portal/trunk/java/org/apache/cocoon/portal/event/Publisher.java?rev=179405&r1=179404&r2=179405&view=diff
==============================================================================
--- cocoon/blocks/portal/trunk/java/org/apache/cocoon/portal/event/Publisher.java (original)
+++ cocoon/blocks/portal/trunk/java/org/apache/cocoon/portal/event/Publisher.java Wed Jun  1 12:40:16 2005
@@ -23,8 +23,9 @@
  * @author <a href="mailto:cziegeler@s-und-n.de">Carsten Ziegeler</a>
  * @author <a href="mailto:volker.schmitt@basf-it-services.com">Volker Schmitt</a>
  * @author Mauro Talevi
- * 
- * @version CVS $Id: Publisher.java,v 1.2 2004/03/05 13:02:11 bdelacretaz Exp $
+ * @deprecated Use {@link org.apache.cocoon.portal.event.EventManager#send(Event)} instead.
+ *
+ * @version CVS $Id$
  */
 public interface Publisher {
     

Added: cocoon/blocks/portal/trunk/java/org/apache/cocoon/portal/event/Receiver.java
URL: http://svn.apache.org/viewcvs/cocoon/blocks/portal/trunk/java/org/apache/cocoon/portal/event/Receiver.java?rev=179405&view=auto
==============================================================================
--- cocoon/blocks/portal/trunk/java/org/apache/cocoon/portal/event/Receiver.java (added)
+++ cocoon/blocks/portal/trunk/java/org/apache/cocoon/portal/event/Receiver.java Wed Jun  1 12:40:16 2005
@@ -0,0 +1,39 @@
+/*
+ * Copyright 1999-2002,2004 The Apache Software Foundation.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.cocoon.portal.event;
+
+import org.apache.cocoon.portal.PortalService;
+
+/**
+ * A receiver registers its interest in a class (or several classes)
+ * of events through the {@link org.apache.cocoon.portal.event.EventManager}.
+ * When such an event occurs, the receiver is invoked via the
+ * {@link #inform(Event, PortalService)} method.
+ *
+ * @author <a href="mailto:cziegeler@apache.org">Carsten Ziegeler</a>
+ *
+ * @version CVS $Id:$
+ */
+public interface Receiver {
+
+    /**
+     * Callback method informing the receiver of the occurence of an event.
+     *
+     * @param event The event.
+     * @param service The portal service
+     */
+     void inform( Event event, PortalService service);
+}

Propchange: cocoon/blocks/portal/trunk/java/org/apache/cocoon/portal/event/Receiver.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: cocoon/blocks/portal/trunk/java/org/apache/cocoon/portal/event/Receiver.java
------------------------------------------------------------------------------
    svn:keywords = Id

Modified: cocoon/blocks/portal/trunk/java/org/apache/cocoon/portal/event/Register.java
URL: http://svn.apache.org/viewcvs/cocoon/blocks/portal/trunk/java/org/apache/cocoon/portal/event/Register.java?rev=179405&r1=179404&r2=179405&view=diff
==============================================================================
--- cocoon/blocks/portal/trunk/java/org/apache/cocoon/portal/event/Register.java (original)
+++ cocoon/blocks/portal/trunk/java/org/apache/cocoon/portal/event/Register.java Wed Jun  1 12:40:16 2005
@@ -23,8 +23,9 @@
  * @author <a href="mailto:cziegeler@s-und-n.de">Carsten Ziegeler</a>
  * @author <a href="mailto:volker.schmitt@basf-it-services.com">Volker Schmitt</a>
  * @author Mauro Talevi
+ * @deprecated Use {@link org.apache.cocoon.portal.event.EventManager#subscribe(Class, Receiver)} instead.
  * 
- * @version CVS $Id: Register.java,v 1.2 2004/03/05 13:02:11 bdelacretaz Exp $
+ * @version CVS $Id$
  */
 public interface Register {
     

Modified: cocoon/blocks/portal/trunk/java/org/apache/cocoon/portal/event/aspect/EventAspectContext.java
URL: http://svn.apache.org/viewcvs/cocoon/blocks/portal/trunk/java/org/apache/cocoon/portal/event/aspect/EventAspectContext.java?rev=179405&r1=179404&r2=179405&view=diff
==============================================================================
--- cocoon/blocks/portal/trunk/java/org/apache/cocoon/portal/event/aspect/EventAspectContext.java (original)
+++ cocoon/blocks/portal/trunk/java/org/apache/cocoon/portal/event/aspect/EventAspectContext.java Wed Jun  1 12:40:16 2005
@@ -27,7 +27,7 @@
  * @author <a href="mailto:cziegeler@s-und-n.de">Carsten Ziegeler</a>
  * @author <a href="mailto:volker.schmitt@basf-it-services.com">Volker Schmitt</a>
  * 
- * @version CVS $Id: EventAspectContext.java,v 1.2 2004/03/05 13:02:12 bdelacretaz Exp $
+ * @version CVS $Id$
  */
 public interface EventAspectContext {
     
@@ -47,10 +47,11 @@
     EventConverter getEventConverter();
     
     /**
-     * Get the publisher
+     * Get the publisher.
+     * @deprecated The aspect can use the portal service to publish events.
      */
     Publisher getEventPublisher();
-    
+
     /**
      * Get the object model
      */

Modified: cocoon/blocks/portal/trunk/java/org/apache/cocoon/portal/event/impl/DefaultEventManager.java
URL: http://svn.apache.org/viewcvs/cocoon/blocks/portal/trunk/java/org/apache/cocoon/portal/event/impl/DefaultEventManager.java?rev=179405&r1=179404&r2=179405&view=diff
==============================================================================
--- cocoon/blocks/portal/trunk/java/org/apache/cocoon/portal/event/impl/DefaultEventManager.java (original)
+++ cocoon/blocks/portal/trunk/java/org/apache/cocoon/portal/event/impl/DefaultEventManager.java Wed Jun  1 12:40:16 2005
@@ -1,5 +1,5 @@
 /*
- * Copyright 1999-2002,2004 The Apache Software Foundation.
+ * Copyright 1999-2002,2004-2005 The Apache Software Foundation.
  * 
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -16,6 +16,7 @@
 package org.apache.cocoon.portal.event.impl;
 
 import java.util.ArrayList;
+import java.util.HashMap;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
@@ -42,6 +43,7 @@
 import org.apache.cocoon.portal.event.EventConverter;
 import org.apache.cocoon.portal.event.EventManager;
 import org.apache.cocoon.portal.event.Publisher;
+import org.apache.cocoon.portal.event.Receiver;
 import org.apache.cocoon.portal.event.Register;
 import org.apache.cocoon.portal.event.Subscriber;
 import org.apache.cocoon.portal.event.aspect.EventAspect;
@@ -53,7 +55,7 @@
  * @author <a href="mailto:cziegeler@s-und-n.de">Carsten Ziegeler</a>
  * @author <a href="mailto:volker.schmitt@basf-it-services.com">Volker Schmitt</a>
  * 
- * @version CVS $Id: DefaultEventManager.java,v 1.14 2004/03/05 13:02:12 bdelacretaz Exp $
+ * @version CVS $Id$
  */
 public class DefaultEventManager 
     extends AbstractLogEnabled
@@ -68,7 +70,11 @@
                     
     private final String rootEventType = Event.class.getName();
     private Class eventClass;
+    /** The list of all subscribers. */
     private List subscribers = new ArrayList();
+    /** The list of all receivers */
+    private Map receivers = new HashMap();
+
     private ServiceManager manager;
     private Configuration configuration;
     
@@ -77,12 +83,16 @@
     protected ServiceSelector aspectSelector;
 
     protected Context context;
-    
-    /* (non-Javadoc)
+
+    /** The portal service */
+    protected PortalService service;
+
+    /**
      * @see org.apache.avalon.framework.service.Serviceable#service(org.apache.avalon.framework.service.ServiceManager)
      */
     public void service(ServiceManager manager) throws ServiceException {
         this.manager = manager;
+        this.service = (PortalService)manager.lookup(PortalService.ROLE);
     }
 
     /* (non-Javadoc)
@@ -124,6 +134,8 @@
             }
             this.manager.release( this.aspectSelector );
             this.aspectSelector = null;
+            this.manager.release(this.service);
+            this.service = null;
             this.manager = null;
         }
     }
@@ -181,20 +193,7 @@
      * @see org.apache.cocoon.portal.event.Publisher#publish(org.apache.cocoon.portal.event.Event)
      */
     public void publish( final Event event ) {
-        
-        if ( getLogger().isDebugEnabled() ) {
-            getLogger().debug("Publishing event " + event.getClass());
-        } 
-        for ( Iterator e = subscribers.iterator(); e.hasNext(); ){
-            Subscriber subscriber = (Subscriber)e.next();
-            if (subscriber.getEventType().isAssignableFrom(event.getClass())
-            && (subscriber.getFilter() == null || subscriber.getFilter().filter(event))) {
-                if ( getLogger().isDebugEnabled() ) {
-                    getLogger().info("Informing subscriber "+subscriber+" of event "+event.getClass());
-                }
-                subscriber.inform(event);
-            }
-        }
+        this.send(event);        
     }
     
     /* (non-Javadoc)
@@ -284,12 +283,89 @@
 
     }
 
-    /* (non-Javadoc)
+    /**
      * @see org.apache.avalon.framework.context.Contextualizable#contextualize(org.apache.avalon.framework.context.Context)
      */
     public void contextualize(Context context) 
     throws ContextException {
         this.context = context;
+    }
+
+    /**
+     * @see org.apache.cocoon.portal.event.EventManager#send(org.apache.cocoon.portal.event.Event)
+     */
+    public void send(Event event) {
+        if ( getLogger().isDebugEnabled() ) {
+            getLogger().debug("Publishing event " + event.getClass());
+        } 
+        for ( Iterator e = subscribers.iterator(); e.hasNext(); ){
+            Subscriber subscriber = (Subscriber)e.next();
+            if (subscriber.getEventType().isAssignableFrom(event.getClass())
+            && (subscriber.getFilter() == null || subscriber.getFilter().filter(event))) {
+                if ( getLogger().isDebugEnabled() ) {
+                    getLogger().info("Informing subscriber "+subscriber+" of event "+event.getClass());
+                }
+                subscriber.inform(event);
+            }
+        }
+        for (Iterator re = receivers.entrySet().iterator(); re.hasNext(); ) {
+            final Map.Entry current = (Map.Entry)re.next();
+            final Receiver receiver = (Receiver)current.getKey();
+            final List classes = (List)current.getValue();
+            boolean found = false;
+            final Iterator ci = classes.iterator();
+            while ( !found && ci.hasNext() ) {
+                if ( ((Class)ci.next()).isAssignableFrom(event.getClass()) ) {
+                    found = true;
+                }
+            }
+            if ( found ) {
+                if ( getLogger().isDebugEnabled() ) {
+                    getLogger().info("Informing receiver "+receiver+" of event "+event.getClass());
+                }
+                receiver.inform(event, this.service);
+            }
+        }
+    }
+
+    /**
+     * @see org.apache.cocoon.portal.event.EventManager#subscribe(java.lang.Class, org.apache.cocoon.portal.event.Receiver)
+     */
+    public void subscribe(Class event, Receiver receiver) {
+        if ( !eventClass.isAssignableFrom( event ) ) {
+            throw new RuntimeException("Invalid event type " + event
+                                      +" for receiver " + receiver);
+        }
+
+        // Add to list but prevent duplicate subscriptions
+        List eventClassesForReceiver = (List)this.receivers.get(receiver);
+        if ( eventClassesForReceiver == null ) {
+            eventClassesForReceiver = new ArrayList();
+            this.receivers.put(receiver, eventClassesForReceiver);
+        }
+        eventClassesForReceiver.add(event);
+        if ( getLogger().isDebugEnabled() ) {
+            getLogger().debug( "Receiver " + receiver + " subscribed for event: " + event.getName() );
+        }
+    }
+
+    /**
+     * @see org.apache.cocoon.portal.event.EventManager#subscribe(java.lang.Class[], org.apache.cocoon.portal.event.Receiver)
+     */
+    public void subscribe(Class[] events, Receiver receiver) {
+        for(int i=0; i<events.length; i++) {
+            this.subscribe(events[i], receiver);
+        }
+    }
+
+    /**
+     * @see org.apache.cocoon.portal.event.EventManager#unsubscribe(org.apache.cocoon.portal.event.Receiver)
+     */
+    public void unsubscribe(Receiver receiver) {
+        if ( getLogger().isDebugEnabled() ) {
+            getLogger().debug( "Receiver " + receiver + " unsubscribed.");
+        }
+        this.receivers.remove(receiver);
     }
 
 }



Re: svn commit: r179405 - in /cocoon/blocks/portal/trunk/java/org/apache/cocoon/portal/event: EventManager.java Publisher.java Receiver.java Register.java aspect/EventAspectContext.java impl/DefaultEventManager.java

Posted by Carsten Ziegeler <cz...@apache.org>.
Ralph Goers wrote:

> 
> Do you have any details of where you want to go with this?  Is it safe 
> to assume you want to deprecate Subscriber?
Yepp - the whole event manager/subscriber/publisher/register thing is
imho way too complex. So I merged publisher and register into the event
manager and simplified the subscriber (which is now called receiver).
During the various projects we've done with the portal, it turned out
that most of the work is adding your own events and create some
subscribers for the events. And I think the current solution requires
too much coding. For example the new Receiver interface passes not only
the event but also the PortalService to the receiver, so the receiver
has access to the whole portal without requiring to implement any
lifecycle methods.
I have no concrete ideas yet, but I want to simplify the receiver in a
way that you don't have to implement the interface anymore (Don't know
how yet :) ). And I'm interested in enabling scriptable event receivers
- for example write your receiver in flow script. But these are just
some rough ideas.

> 
> While sort of on the same topic, I would like to move in the direction 
> of not exposing event ids in URLs, at least as far as possible.  I 
> started this with a couple of events but I haven't done all the ones 
> that could be.
> 
Yeah, this is a very annoying topic. If you have any suggestions we
should talk about them.

Carsten


-- 
Carsten Ziegeler - Open Source Group, S&N AG
http://www.s-und-n.de
http://www.osoco.org/weblogs/rael/

Re: svn commit: r179405 - in /cocoon/blocks/portal/trunk/java/org/apache/cocoon/portal/event: EventManager.java Publisher.java Receiver.java Register.java aspect/EventAspectContext.java impl/DefaultEventManager.java

Posted by Ralph Goers <Ra...@dslextreme.com>.
cziegeler@apache.org wrote:

>Author: cziegeler
>Date: Wed Jun  1 12:40:16 2005
>New Revision: 179405
>
>URL: http://svn.apache.org/viewcvs?rev=179405&view=rev
>Log:
>Start new, simpler event infrastructure
>
>  
>
Do you have any details of where you want to go with this?  Is it safe 
to assume you want to deprecate Subscriber? 

While sort of on the same topic, I would like to move in the direction 
of not exposing event ids in URLs, at least as far as possible.  I 
started this with a couple of events but I haven't done all the ones 
that could be.

Ralph