java.lang.Object
org.refcodes.observer.AbstractObservable<O,EV>
- Type Parameters:
O
- The observer's (event listeners) to be managed by theObservable
.EV
- The base event to be fired by thisObservable
.
- All Implemented Interfaces:
org.refcodes.mixin.Disposable
,org.refcodes.mixin.Loggable
,Observable<O>
public abstract class AbstractObservable<O,EV>
extends Object
implements Observable<O>, org.refcodes.mixin.Disposable, org.refcodes.mixin.Loggable
This abstract class provides functionality to implement default refcodes
Observable
behavior. The
fireEvent(Object, Object, ExecutionStrategy)
is to be overwritten to
invoke the according event lister'#s method for a given event to be
distributed. The
doHandleEventListenerException(Exception, Object, Object, ExecutionStrategy)
method can be overwritten to handle any exceptions thrown by the
fireEvent(Object, Object, ExecutionStrategy)
method. Depending on
the ExecutionStrategy
, distribution of the events is handled
differently: ExecutionStrategy.SEQUENTIAL
: You determine that each
event listener is signaled one after the other and not in parallel. In case
you want to restrict thread generation, this sequential event distribution is
the one to go for: Each event listener is invoked after the other one after
the other. The execution chain of invoking the event listeners can be aborted
by a boolean flag returned by an invoked event listener method or by a
VetoException
thrown by an invoked event listener method. In
sequential event distribution, you can also take care of exceptions thrown or
return vales passed to you by the event listeners to affect the execution of
the chain of event listeners. As soon as the execution chain of invoking
event listeners terminates, then this method terminates.
ExecutionStrategy.PARALLEL
: You determine that each event listener is
signaled in parallel. In case you want to prevent that one event listener can
cause the succeeding event listeners to be delayed for signaling, then the
parallel mode is the one to go for. As soon as all event listeners have their
own thread, this method exits. You cannot affect the execution of event
listeners as all of them are invoked ignoring any exceptions or return values
of the other invoked event listeners. Here as we do not collect any
exceptions or any results from each invoked event listener, there are no
means provided to evaluate them during or after event distribution.
ExecutionStrategy.JOIN
: Similar to ExecutionStrategy.PARALLEL
with the difference, that all threads are joined and the method terminates as
soon as the latest thread terminates. As of this, a VetoException
as
well as a return value can be evaluated though still no influence can be
taken upon the execution of the invocation of the event listeners. In case
any of the listeners returns false, then this event distribution mode will
cause to return false, in case any event listener throws a
VetoException
, then the first detected VetoException
is
thrown when executing with this event distribution mode. No matter of the
exceptions or return values, as of the ExecutionStrategy.PARALLEL
event distribution mode, all event listeners are invoked.-
Field Summary
Fields inherited from interface org.refcodes.mixin.Loggable
RUNTIME_LOGGER_CLASS, RUNTIME_LOGGER_FACTORY_CLASS, RUNTIME_LOGGER_FACTORY_METHOD
-
Constructor Summary
ConstructorDescriptionConstructs theAbstractObservable
with a defaultExecutorService
pool.AbstractObservable
(ExecutorService aExecutorService) Constructs theAbstractObservable
with a providedExecutorService
pool. -
Method Summary
Modifier and TypeMethodDescriptionprotected void
clear()
Clears all observers from thisAbstractObservable
.void
dispose()
protected void
doHandleEventListenerException
(Exception aException, O aObserver, EV aEvent, org.refcodes.controlflow.ExecutionStrategy aExecutionStrategy) This hook method allows you to handle any exceptions being thrown by an event listener whilst invoking a given event.protected boolean
To be used by the implementing class when firing an event to it's listeners.protected abstract boolean
This hook method is to be implemented by the implementing class.int
In case ofExecutionStrategy.PARALLEL
orExecutionStrategy.JOIN
, the threads' priority is defined by this attribute.boolean
hasObserverSubscription
(O aObserver) Tests whether the given observer (event listener) has been added to thisObservable
.protected boolean
isEmpty()
Determines whether there are observers being registered.protected boolean
Checks if is observers active.Observers.protected void
setObserversActive
(boolean isActive) Sets the observers active.void
setThreadPriority
(int threadPriority) In case ofExecutionStrategy.PARALLEL
orExecutionStrategy.JOIN
, the threads' priority is defined by this attribute.protected int
size()
Determines the number of observers being registered.boolean
subscribeObserver
(O aObserver) Adds the given observer (event listener).boolean
unsubscribeObserver
(O aObserver) Removes the observer (event listener).Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
Methods inherited from interface org.refcodes.mixin.Loggable
alert, alert, critical, critical, debug, error, info, notice, panic, trace, warn, warn
-
Constructor Details
-
AbstractObservable
public AbstractObservable()Constructs theAbstractObservable
with a defaultExecutorService
pool. -
AbstractObservable
Constructs theAbstractObservable
with a providedExecutorService
pool.- Parameters:
aExecutorService
- TheExecutorService
to be used when firingGenericActionEvent
instances inExecutionStrategy.PARALLEL
orExecutionStrategy.JOIN
-
-
Method Details
-
fireEvent
protected boolean fireEvent(EV aEvent, org.refcodes.controlflow.ExecutionStrategy aExecutionStrategy) throws org.refcodes.exception.VetoException To be used by the implementing class when firing an event to it's listeners. Use one of the event distribution modes as defined inExecutionStrategy
.- Parameters:
aEvent
- The event to be fired.aExecutionStrategy
- The event- Returns:
- True in case all event listeners were invoked, false in case one
invoked event listener returned false ("stop continuing") upon
invocation or the overall observers have been disables as of
setObserversActive(boolean)
. - Throws:
org.refcodes.exception.VetoException
- in case one of the invoked event listeners signaled a veto by throwing that according method. TheVetoException
can only reliably be evaluated in case the event listeners are executed in sequence.
-
hasObserverSubscription
Tests whether the given observer (event listener) has been added to thisObservable
.- Specified by:
hasObserverSubscription
in interfaceObservable<O>
- Parameters:
aObserver
- The observer (event listener) for which to test if it has been added.- Returns:
- True if the given observer (event listener) has been added already.
-
subscribeObserver
Adds the given observer (event listener). The observer (event listener) itself acts as the handle which is used when removing the given observer (event listener) later.- Specified by:
subscribeObserver
in interfaceObservable<O>
- Parameters:
aObserver
- The observer (event listener) which is to be added to theObservable
.- Returns:
- True if the observer (event listener) has been added successfully. If the observer (event listener) has already been added, false is returned.
-
unsubscribeObserver
Removes the observer (event listener). In case the observer (event listener) has not been added before, then false is returned.- Specified by:
unsubscribeObserver
in interfaceObservable<O>
- Parameters:
aObserver
- The observer (event listener) which is to be removed.- Returns:
- True if the observer (event listener) has been removed successfully. If there was none such observer (event listener) or if the observer (event listener) has already been removed, then false is returned.
-
setObserversActive
protected void setObserversActive(boolean isActive) Sets the observers active.- Parameters:
isActive
- the new observers active
-
isObserversActive
protected boolean isObserversActive()Checks if is observers active.- Returns:
- true, if is observers active
-
observers
Observers.- Returns:
- the iterator
-
fireEvent
protected abstract boolean fireEvent(EV aEvent, O aObserver, org.refcodes.controlflow.ExecutionStrategy aExecutionStrategy) throws Exception This hook method is to be implemented by the implementing class. Here you decide which method of the event listener is to be invoked with the provided event and what actions apply upon invoking the event listener's methods. E.g. your event listener's methods might veto an event by throwing an according exception which you can pass down the stack here, or you might want to ignore any exceptions being thrown or you proceed according the the return value of some listener's method. Distribution of events to succeeding event listeners, in case of the SEQUENTIALExecutionStrategy
, is prevented, when false is returned ("stop invoking succeeding event listeners"), succeeding event listeners are invoked in case true is returned ("continue invoking succeeding event listeners"). In CONCURRENTExecutionStrategy
the return value does not have an effect. Throwing aVetoException
has a similar effect in case of the SEQUENTIALExecutionStrategy
, preventing execution of succeeding event listeners and passing down the exception the stack so that your business logic can stop a vetoed operation.- Parameters:
aEvent
- The event to be passed to the event listeneraObserver
- The event listener to which to pass the eventaExecutionStrategy
- Can be either CONCURRENT signaling that the event has been fired concurrently to the event listeners, each event listener is invoked in its own thread or SEQUENTIAL signaling that the event has been fired to the event listeners in sequence, each event listener is invoked one after the other one by one in the calling thread.- Returns:
- True in case succeeding event listeners are to be invoked in case
of the SEQUENTIAL
ExecutionStrategy
. - Throws:
Exception
- the exception
-
doHandleEventListenerException
protected void doHandleEventListenerException(Exception aException, O aObserver, EV aEvent, org.refcodes.controlflow.ExecutionStrategy aExecutionStrategy) This hook method allows you to handle any exceptions being thrown by an event listener whilst invoking a given event.- Parameters:
aException
- The exception thrown by the given event listener.aObserver
- The listener which caused the exception.aEvent
- The event for which the exception was caused.aExecutionStrategy
- the execution strategy
-
size
protected int size()Determines the number of observers being registered.- Returns:
- The number of observers being registered.
-
isEmpty
protected boolean isEmpty()Determines whether there are observers being registered.- Returns:
- True in case there are observers being registered.
-
clear
protected void clear()Clears all observers from thisAbstractObservable
. -
getThreadPriority
public int getThreadPriority()In case ofExecutionStrategy.PARALLEL
orExecutionStrategy.JOIN
, the threads' priority is defined by this attribute.- Returns:
- The thread priority for the threads to be generated.
-
setThreadPriority
public void setThreadPriority(int threadPriority) In case ofExecutionStrategy.PARALLEL
orExecutionStrategy.JOIN
, the threads' priority is defined by this attribute.- Parameters:
threadPriority
- The thread priority for the threads to be generated.
-
dispose
public void dispose()- Specified by:
dispose
in interfaceorg.refcodes.mixin.Disposable
-