| This is a utility class that can be used by a context that supports
event notification. You can use an instance of this class as a member field
of your context and delegate various work to it.
It is currently structured so that each context should have its own
EventSupport (instead of static version shared by all contexts
of a service provider).
This class supports two types of listeners: those that register for
NamingEvents, and those for UnsolicitedNotificationEvents (they can be mixed
into the same listener).
For NamingEvent listeners, it maintains a hashtable that maps
registration requests--the key--to
notifiers--the value. Each registration request consists of:
- The name argument of the registration.
- The filter (default is "(objectclass=*)").
- The search controls (default is null SearchControls).
- The events that the listener is interested in. This is determined by
finding out which NamingListener interface the listener supports.
A notifier (NamingEventNotifier) is a worker thread that is responsible
for gathering information for generating events requested by its listeners.
Each notifier maintains its own list of listeners; these listeners have
all made the same registration request (at different times) and implements
the same NamingListener interfaces.
For unsolicited listeners, this class maintains a vector, unsolicited.
When an unsolicited listener is registered, this class adds itself
to the context's LdapClient. When LdapClient receives an unsolicited
notification, it notifies this EventSupport to fire an event to the
the listeners. Special handling in LdapClient is done for the DISCONNECT
notification. [It results in the EventSupport firing also a
NamingExceptionEvent to the unsolicited listeners.]
When a context no longer needs this EventSupport, it should invoke
cleanup() on it.
Registration
When a registration request is made, this class attempts to find an
existing notifier that's already working on the request. If one is
found, the listener is added to the notifier's list. If one is not found,
a new notifier is created for the listener.
Deregistration
When a deregistration request is made, this class attemps to find its
corresponding notifier. If the notifier is found, the listener is removed
from the notifier's list. If the listener is the last listener on the list,
the notifier's thread is terminated and removed from this class's hashtable.
Nothing happens if the notifier is not found.
Event Dispatching
The notifiers are responsible for gather information for generating events
requested by their respective listeners. When a notifier gets sufficient
information to generate an event, it creates invokes the
appropriate fireXXXEvent on this class with the information and list of
listeners. This causes an event and the list of listeners to be added
to the event queue.
This class maintains an event queue and a dispatching thread that dequeues
events from the queue and dispatches them to the listeners.
Synchronization
This class is used by the main thread (LdapCtx) to add/remove listeners.
It is also used asynchronously by NamingEventNotifiers threads and
the context's Connection thread. It is used by the notifier threads to
queue events and to update the notifiers list when the notifiers exit.
It is used by the Connection thread to fire unsolicited notifications.
Methods that access/update the 'unsolicited' and 'notifiers' lists are
thread-safe.
author: Rosanna Lee |