O
- The observer's (event listeners) to be managed by the
Observable
.EV
- The base event to be fired by this Observable
.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
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.Constructor | Description |
---|---|
AbstractObservable() |
Constructs the
AbstractObservable with a default
ExecutorService pool. |
AbstractObservable(ExecutorService aExecutorService) |
Constructs the
AbstractObservable with a provided
ExecutorService pool. |
Modifier and Type | Method | Description |
---|---|---|
protected void |
clear() |
Clears all observers from this
AbstractObservable . |
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 |
fireEvent(EV aEvent,
org.refcodes.controlflow.ExecutionStrategy aExecutionStrategy) |
To be used by the implementing class when firing an event to it's
listeners.
|
protected abstract boolean |
fireEvent(EV aEvent,
O aObserver,
org.refcodes.controlflow.ExecutionStrategy aExecutionStrategy) |
This hook method is to be implemented by the implementing class.
|
int |
getThreadPriority() |
In case of
ExecutionStrategy.PARALLEL or
ExecutionStrategy.JOIN , the threads' priority is defined by this
attribute. |
boolean |
hasObserverSubscription(O aObserver) |
Tests whether the given observer (event listener) has been added to this
Observable . |
protected boolean |
isEmpty() |
Determines whether there are observers being registered.
|
protected boolean |
isObserversActive() |
|
protected Iterator<O> |
observers() |
|
protected void |
setObserversActive(boolean isActive) |
|
void |
setThreadPriority(int threadPriority) |
In case of
ExecutionStrategy.PARALLEL or
ExecutionStrategy.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).
|
public AbstractObservable()
AbstractObservable
with a default
ExecutorService
pool.public AbstractObservable(ExecutorService aExecutorService)
AbstractObservable
with a provided
ExecutorService
pool.aExecutorService
- The ExecutorService
to be used when
firing GenericActionEvent
instances in
ExecutionStrategy.PARALLEL
or
ExecutionStrategy.JOIN
protected boolean fireEvent(EV aEvent, org.refcodes.controlflow.ExecutionStrategy aExecutionStrategy) throws org.refcodes.exception.VetoException
ExecutionStrategy
.aEvent
- The event to be fired.aExecutionStrategy
- The eventsetObserversActive(boolean)
.org.refcodes.exception.VetoException
- in case one of the invoked event listeners
signaled a veto by throwing that according method. The
VetoException
can only reliably be evaluated in case
the event listeners are executed in sequence.public boolean hasObserverSubscription(O aObserver)
Observable
.hasObserverSubscription
in interface Observable<O>
aObserver
- The observer (event listener) for which to test if it
has been added.public boolean subscribeObserver(O aObserver)
subscribeObserver
in interface Observable<O>
aObserver
- The observer (event listener) which is to be added to
the Observable
.public boolean unsubscribeObserver(O aObserver)
unsubscribeObserver
in interface Observable<O>
aObserver
- The observer (event listener) which is to be removed.protected void setObserversActive(boolean isActive)
protected boolean isObserversActive()
protected abstract boolean fireEvent(EV aEvent, O aObserver, org.refcodes.controlflow.ExecutionStrategy aExecutionStrategy) throws Exception
ExecutionStrategy
, 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 CONCURRENT ExecutionStrategy
the return value
does not have an effect. Throwing a VetoException
has a similar
effect in case of the SEQUENTIAL ExecutionStrategy
, preventing
execution of succeeding event listeners and passing down the exception
the stack so that your business logic can stop a vetoed operation.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.ExecutionStrategy
.org.refcodes.exception.VetoException
- thrown in case an operation published by the given
event has been vetoed by an event listener. Succeeding event
listeners are not being invoked any more in case of the
SEQUENTIAL ExecutionStrategy
.Exception
protected void doHandleEventListenerException(Exception aException, O aObserver, EV aEvent, org.refcodes.controlflow.ExecutionStrategy aExecutionStrategy)
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 strategyprotected int size()
protected boolean isEmpty()
protected void clear()
AbstractObservable
.public int getThreadPriority()
ExecutionStrategy.PARALLEL
or
ExecutionStrategy.JOIN
, the threads' priority is defined by this
attribute.public void setThreadPriority(int threadPriority)
ExecutionStrategy.PARALLEL
or
ExecutionStrategy.JOIN
, the threads' priority is defined by this
attribute.threadPriority
- The thread priority for the threads to be
generated.public void dispose()
dispose
in interface org.refcodes.mixin.Disposable
Copyright © 2021. All rights reserved.