2 Replies Latest reply on Jul 27, 2012 12:56 PM by Ron Sigal

    Event observer qualifiers

    Ron Sigal Master

      In order to be notified of an event, does an event observer have to have

       

      1) a subset (not necessarily proper subset) of the qualifiers on the event, or

      2) a superset (not necessarily proper superset) of the qualifiers on the event?

       

      The CDI spec and the Weld reference manual seem to say conflicting things:

       

      CDI Spec:

       

      1) page 71 [subset]:

       

      An observer method will be notified of an event if the event object is assignable to the observed event type, and if all the observed event qualifiers are event qualifiers of the event.

       

      2) page 71 [superset]:

       

      An event is delivered to an observer method if:

      ...

        • The observer method has all the event qualifiers.

       

      3) page 72 [subset]:

       

      Consider the following event:

       

        public void login() {

          final User user = ...;

          loggedInEvent.fire( new LoggedInEvent(user), new RoleQualifier() { public String value() { return user.getRole(); } );

        }

       

      Where RoleQualifier is an implementation of the qualifier type Role:

       

        public abstract class RoleQualifier extends AnnotationLiteral<Role> implements Role {}

       

      Then the following observer method will always be notified of the event:

       

        public void afterLogin(@Observes LoggedInEvent event) { ... }

       

      Whereas this observer method may or may not be notified, depending upon the value of user.getRole():

       

        public void afterAdminLogin(@Observes @Role("admin") LoggedInEvent event) { ... }

       

      4) pages 72-73 [subset]:

       

      An event parameter may have multiple qualifiers.

       

        public void afterDocumentUpdatedByAdmin(@Observes @Updated @ByAdmin Document doc) { ... }

       

      Then this observer method will only be notified if all the observed event qualifiers are specified when the event is fired:

       

        documentEvent.fire( document, new UpdatedQualifier() {}, new ByAdminQualifier() {} );

       

      Other, less specific, observers will also be notified of this event:

       

        public void afterDocumentUpdated(@Observes @Updated Document doc) { ... }

        public void afterDocumentEvent(@Observes Document doc) { ... }

       

       

      Weld reference:

       

      1) page 83 [ambiguous]:

       

      An observer method need not specify any event qualifiers—in this case it is interested in only unqualified events of a particular type. If it does specify qualifiers, it's only interested in events which have those qualifiers.

       

      2) page 84: [subset]:

       

      @Inject @Updated Event<Document> documentUpdatedEvent;

       

      Then, every event fired via this instance of Event has the event qualifier @Updated. The event is delivered to every observer method that:

       

        • has an event parameter to which the event object is assignable, and

        • does not have any event qualifier except for the event qualifiers that match those specified at the Event injection point.

       

      3) page 86 [superset]:

       

        @Inject @Blog Event<Document> blogEvent;

        ...

        if (document.isBlog()) blogEvent.select(new AnnotationLiteral<Updated>(){}).fire(document);

       

      Observers must completely match the final qualified type of the event. Assume the following observers in this example:

       

        public void afterBlogUpdate(@Observes @Updated @Blog Document document) { ... }

        public void afterDocumentUpdate(@Observes @Updated Document document) { ... }

        public void onAnyBlogEvent(@Observes @Blog Document document) { ... }

        public void onAnyDocumentEvent(@Observes Document document) { ... }}}

       

      The only observer notified will be:

       

        public void afterBlogUpdate(@Observes @Updated @Blog Document document) { ... }

      ===========================

       

      Not surprisingly, the behavior I'm seeing with Weld is the subset version.  E.g.,  with the event source

       

          ... 

         @Inject @Process Event<String> processEvent;

         @Inject @Read(context="resource")  @Process Event<String> readProcessEvent;

         ...

        

         public int createBook(Book book)

         {

            processEvent.fire("processEvent");

            ...

            readProcessEvent.fire("readProcessEvent");

            ...

         }

       

      and the event observer

       

         public void process(@Observes @Process String event)

         { ...

         }

        

         public void processRead(@Observes @Process @Read(context="resource") String event)

         { ...

         }

       

      the process() method is seeing both events fired by the source, and the processRead() method is seeing only the second fired event.

       

      Any thoughts?

       

      Thanks,

      Confused in New York