org.eigenbase.util.property
Interface Trigger

All Known Implementing Classes:
TriggerBase

public interface Trigger

A Trigger is a callback which allows a subscriber to be notified when a property value changes.

If the user wishes to be able to remove a Trigger at some time after it has been added, then either 1) the user has to keep the instance of the Trigger that was added and use it when calling the remove method or 2) the Trigger must implement the equals method and the Trigger used during the call to the remove method must be equal to the original Trigger added.

Each non-persistent Trigger is wrapped in a WeakReference, so that is can be garbage-collected. But this means that the user had better keep a reference to the Trigger, otherwise it will be removed (garbage collected) without the user knowing.

Persistent Triggers (those that refer to objects in their execute(org.eigenbase.util.property.Property, java.lang.String) method that will never be garbage-collected) are not wrapped in a WeakReference.

What does all this mean, well, objects that might be garbage collected that create a Trigger must keep a reference to the Trigger (otherwise the Trigger will be garbage-collected out from under the object). A common usage pattern is to implement the Trigger interface using an anonymous class - anonymous classes are non-static classes when created in an instance object. But, remember, the anonymous class instance holds a reference to the outer instance object but not the other way around; the instance object does not have an implicit reference to the anonymous class instance - the reference must be explicit. And, if the anonymous Trigger is created with the isPersistent method returning true, then, surprise, the outer instance object will never be garbage collected!!!

Note that it is up to the creator of a set of triggers to make sure that they are ordered correctly. This is done by either having order independent Triggers (they all have the same phase) or by assigning phases to the Triggers where primaries execute before secondary which execute before tertiary.

If a finer level of execution order granularity is needed, then the implementation should be changed so that the phase() method returns just some integer and it's up to the users to coordinate their values.


Nested Class Summary
static class Trigger.VetoRT
           
 
Field Summary
static int PRIMARY_PHASE
           
static int SECONDARY_PHASE
           
static int TERTIARY_PHASE
           
 
Method Summary
 void execute(Property property, String value)
          Executes the trigger, passing in the key of the property whose change triggered the execution.
 boolean isPersistent()
          If a Trigger is associated with a class or singleton, then it should return true because its associated object is not subject to garbage collection.
 int phase()
          Which phase does this Trigger belong to.
 

Field Detail

PRIMARY_PHASE

static final int PRIMARY_PHASE
See Also:
Constant Field Values

SECONDARY_PHASE

static final int SECONDARY_PHASE
See Also:
Constant Field Values

TERTIARY_PHASE

static final int TERTIARY_PHASE
See Also:
Constant Field Values
Method Detail

isPersistent

boolean isPersistent()
If a Trigger is associated with a class or singleton, then it should return true because its associated object is not subject to garbage collection. On the other hand, if a Trigger is associated with an object which will be garbage collected, then this method must return false so that the Trigger will be wrapped in a WeakReference and thus can itself be garbage collected.

Returns:
whether trigger is persistent

phase

int phase()
Which phase does this Trigger belong to.

Returns:
phase trigger belongs to

execute

void execute(Property property,
             String value)
             throws Trigger.VetoRT
Executes the trigger, passing in the key of the property whose change triggered the execution.

Parameters:
property - Property being changed
value - New value of property
Throws:
Trigger.VetoRT