O
- The observer's (event listeners) to be managed by the
Observable
.EV
- The base event to be fired by this Observable
.public abstract class AbstractObservable<O,EV> extends Object implements Observable<O>, org.refcodes.mixin.Disposable
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 and 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 and 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, similar to
Containable.isEmpty() . |
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, similar to
Containable.size() . |
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 ActionEvent
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 eventorg.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 abstract boolean fireEvent(EV aEvent, O aObserver, org.refcodes.controlflow.ExecutionStrategy aExecutionStrategy) throws org.refcodes.exception.VetoException
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
.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 a execution strategyprotected int size()
Containable.size()
.protected boolean isEmpty()
Containable.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 © 2018. All rights reserved.