| 
 | |||||||||
| PREV CLASS NEXT CLASS | FRAMES NO FRAMES | ||||||||
| SUMMARY: INNER | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD | ||||||||
Notifier instances are used to call the correct call-back method
   defined in a listener type when EventSourceSupport fires
   events. The method EventSourceSupport.fireEvent(EventObject,
   Notifier) presents the event to the notifier for each listener
   that is registered in the EventSourceSupport instance. This
   technique is similar to the well-known double-dispatch.
Abstract preconditions are used to transport information about the
   listener and the event from clients, over type invariants, to the
   implementation of notifyEventListener(EventListener,
   EventObject). An abstract postcondition makes it possible for 
   EventSourceSupport to specify that notifyEventListener(EventListener, EventObject) is actually called.
Most often, this interface is implemented in an inner class of the
   actual event source that used the EventSourceSupport instance.
   A typical implementation looks like this:
 ...
 static final private Notifier _eventNameNotifier =
     new Notifier() {
           /oo
            o also
            o   public behavior
            o     post \result <==> (event != null) && (event instanceof EventNameEvent);
            o public model boolean isValidEvent(EventObject event);
            o/
           /oo
            o also
            o   public behavior
            o     pre listener != null;
            o     post \result <==> (listener instanceof EventNameListener);
            o public model boolean isValidListener(EventListener listener);
            o/
           /oo
            o also
            o   public behavior
            o     pre listener != null;
            o     pre isValidListener(listener);
            o     pre isValidEvent(event);
            o     post (* ((EventNameListener)listener).eventName((EventNameEvent)event)
            o             is called *);
            o/
           public void notifyEventListener(EventListener listener, EventObject event) {
             ((EventNameListener)listener).eventName((EventNameEvent)event);
           }
         };
 ...
 
 EventTypeReliancy and ListenerTypeReliance offer
   support for the case where the validity of events or listeners is
   only limited to type.
In the above example, the notifier instance has no state, and can thus be stored in a final class variable, for use in all event firings. An event firing typically looks like this:
 public void fooMutator(arguments) { 
   store old state
   do mutation
   EventNameEvent event = create new event using old and new state;
   $eventNameEventSourceSupport.fireEvent(event, _eventNameNotifier);
 }
 
 In case more elaborate firing mechanisms are needed, different
   notifiers can be created in the actual event source class, potentially
   as instance variables with state, potentially as inner classes in the
   mutator method, so that they have access to the full context of the
   mutator. If the $eventNameEventSourceSupport is used to
   store listeners of different types, a chain of responsibility of
   notifiers can be used (see ChainNotifier).
ApplicabilityNotifier adds the possibility to check the
   applicability of a notifier in particular listener/event combinations
   at runtime. TypeApplicabilityNotifier adds specification that
   makes it more easy to specify that listeners and events of a
   particular type are valid.
| Field Summary | |
| static java.lang.String | CVS_REVISION | 
| Method Summary | |
| abstract  boolean | isValidEvent(java.util.EventObject event)This model inspector can be used to transport information about the event argument of notifyEventListener from the actual event source providing the event to the class implementing this interface. | 
| abstract  void | notifyEventListener(java.util.EventListener listener,
                    java.util.EventObject event)Subclasses need to overwrite this method to call the call-back method defined in listenerTypewith | 
| abstract  boolean | notifyEventListenerCalled(java.util.EventListener listener,
                          java.util.EventObject event)This model inspector is an abstract postcondition for notifyEventListener(EventListener, EventObject). | 
| Methods inherited from interface org.jutil.event.ListenerValidity | 
| isValidListener | 
| Field Detail | 
public static final java.lang.String CVS_REVISION
| Method Detail | 
public abstract boolean isValidEvent(java.util.EventObject event)
public abstract void notifyEventListener(java.util.EventListener listener,
                                         java.util.EventObject event)
Subclasses need to overwrite this method to call the call-back
   method defined in listenerType with
   
The postcondition is abstract. This is used in EventSourceSupport to specify that this method will indeed be
   called by EventSourceSupport.fireEvent(EventObject,
   Notifier).
public abstract boolean notifyEventListenerCalled(java.util.EventListener listener,
                                                  java.util.EventObject event)
This model inspector is an abstract postcondition for notifyEventListener(EventListener, EventObject). It can be used
   by clients to specify that notifyEventListener(EventListener,
   EventObject) is indeed called.
This is used in EventSourceSupport to specify that
   notifyEventListener(EventListener, EventObject) will be
   called by EventSourceSupport.fireEvent(EventObject, Notifier).
   Because that class can only talk about this type, and not about a
   specific subtype where the abstract postcondition is elaborated,
   the abstract postcondition can only be made true by actually calling
   notifyEventListener(EventListener, EventObject).
This techique depends on the Java limitation of not allowing covariant
   argument type strengthening. Otherwise, the
   EventSourceSupport.fireEvent(EventObject, Notifier) could be
   strengthened in a subclass of EventSourceSupport to only accept
   notifiers of a subtype of this interface, where a new  method could
   be added that uses this model method as abstract postcondition also.
   That class could implement EventSourceSupport.fireEvent(EventObject, Notifier) correctly then
   by calling that new method on all listeners, instead of notifyEventListener(EventListener, EventObject).
| 
 | |||||||||
| PREV CLASS NEXT CLASS | FRAMES NO FRAMES | ||||||||
| SUMMARY: INNER | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD | ||||||||