
org.refcodes.component.ext.observer.impls.ObservableLifeCycleAutomatonImpl Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of refcodes-component-ext-observer Show documentation
Show all versions of refcodes-component-ext-observer Show documentation
Artifact for providing event based extended functionality for the
refcodes-component artifact.
// /////////////////////////////////////////////////////////////////////////////
// REFCODES.ORG
// =============================================================================
// This code is copyright (c) by Siegfried Steiner, Munich, Germany and licensed
// under the following (see "http://en.wikipedia.org/wiki/Multi-licensing")
// licenses:
// =============================================================================
// GNU General Public License, v3.0 ("http://www.gnu.org/licenses/gpl-3.0.html")
// together with the GPL linking exception applied; as being applied by the GNU
// Classpath ("http://www.gnu.org/software/classpath/license.html")
// =============================================================================
// Apache License, v2.0 ("http://www.apache.org/licenses/LICENSE-2.0")
// =============================================================================
// Please contact the copyright holding author(s) of the software artifacts in
// question for licensing issues not being covered by the above listed licenses,
// also regarding commercial licensing models or regarding the compatibility
// with other open source licenses.
// /////////////////////////////////////////////////////////////////////////////
package org.refcodes.component.ext.observer.impls;
import java.util.concurrent.ExecutorService;
import org.refcodes.component.InitializeException;
import org.refcodes.component.LifeCycleComponent;
import org.refcodes.component.LifeCycleStatus;
import org.refcodes.component.PauseException;
import org.refcodes.component.ResumeException;
import org.refcodes.component.StartException;
import org.refcodes.component.StopException;
import org.refcodes.component.ext.observer.DestroyedEvent;
import org.refcodes.component.ext.observer.InitializedEvent;
import org.refcodes.component.ext.observer.LifeCycleEvent;
import org.refcodes.component.ext.observer.LifeCycleObserver;
import org.refcodes.component.ext.observer.LifeCycleRequest;
import org.refcodes.component.ext.observer.ObservableLifeCycleAutomaton;
import org.refcodes.component.ext.observer.PausedEvent;
import org.refcodes.component.ext.observer.ResumedEvent;
import org.refcodes.component.ext.observer.StartedEvent;
import org.refcodes.component.ext.observer.StoppedEvent;
import org.refcodes.component.impls.LifeCycleAutomatonImpl;
import org.refcodes.controlflow.ExecutionStrategy;
import org.refcodes.exception.VetoException;
import org.refcodes.logger.RuntimeLogger;
import org.refcodes.logger.impls.RuntimeLoggerSingleton;
import org.refcodes.observer.ActionEvent;
import org.refcodes.observer.EventMetaData;
import org.refcodes.observer.MetaDataEvent;
import org.refcodes.observer.impls.AbstractObservable;
import org.refcodes.observer.impls.EventMetaDataImpl;
/**
* Abstract implementation of the {@link ObservableLifeCycleAutomaton} interface
* with the according hook methods for you to create your domain driven
* {@link ObservableLifeCycleAutomaton}.
*/
public class ObservableLifeCycleAutomatonImpl extends LifeCycleAutomatonImpl implements ObservableLifeCycleAutomaton {
protected static RuntimeLogger LOGGER = RuntimeLoggerSingleton.getInstance();
// /////////////////////////////////////////////////////////////////////////
// VARIABLES:
// /////////////////////////////////////////////////////////////////////////
private LifeCycleObservable _observable;
private EventMetaData _eventMetaData;
private Object _source;
// /////////////////////////////////////////////////////////////////////////
// CONSTRUCTORS:
// /////////////////////////////////////////////////////////////////////////
public ObservableLifeCycleAutomatonImpl() {
super();
_eventMetaData = new EventMetaDataImpl();
_source = this;
_observable = new LifeCycleObservable();
}
/**
* {@inheritDoc}
*
* @param aSource The source instance to be used when firing events in case
* the source is to be different from this class' instance.
*/
public ObservableLifeCycleAutomatonImpl( Object aSource ) {
super();
_eventMetaData = new EventMetaDataImpl();
_source = aSource;
_observable = new LifeCycleObservable();
}
/**
* {@inheritDoc}
*
* @param aEventMetaData The {@link EventMetaData} to be used when firing
* events in case the {@link EventMetaData} is to be different from
* the auto-generated {@link EventMetaData}.
*/
public ObservableLifeCycleAutomatonImpl( EventMetaData aEventMetaData ) {
super();
_eventMetaData = aEventMetaData;
_source = this;
_observable = new LifeCycleObservable();
}
/**
* {@inheritDoc}
*
* @param aEventMetaData The {@link EventMetaData} to be used when firing
* events in case the {@link EventMetaData} is to be different from
* the auto-generated {@link EventMetaData}.
*
* @param aSource The source instance to be used when firing events in case
* the source is to be different from this class' instance.
*/
public ObservableLifeCycleAutomatonImpl( EventMetaData aEventMetaData, Object aSource ) {
super();
_eventMetaData = aEventMetaData;
_source = aSource;
_observable = new LifeCycleObservable();
}
/**
* {@inheritDoc}
*
* @param aLifeCycleComponent The {@link LifeCycleComponent} to which the
* life-cycle method calls are to be delegated to.
*/
public ObservableLifeCycleAutomatonImpl( LifeCycleComponent aLifeCycleComponent ) {
super( aLifeCycleComponent );
_eventMetaData = new EventMetaDataImpl( this.getClass() );
_source = this;
_observable = new LifeCycleObservable();
}
/**
* {@inheritDoc}
*
* @param aLifeCycleComponent The {@link LifeCycleComponent} to which the
* life-cycle method calls are to be delegated to.
*
* @param aSource The source instance to be used when firing events in case
* the source is to be different from this class' instance.
*/
public ObservableLifeCycleAutomatonImpl( LifeCycleComponent aLifeCycleComponent, Object aSource ) {
super( aLifeCycleComponent );
_eventMetaData = new EventMetaDataImpl( this.getClass() );
_source = aSource;
_observable = new LifeCycleObservable();
}
/**
* {@inheritDoc}
*
* @param aLifeCycleComponent The {@link LifeCycleComponent} to which the
* life-cycle method calls are to be delegated to.
*
* @param aEventMetaData The {@link EventMetaData} to be used when firing
* events in case the {@link EventMetaData} is to be different from
* the auto-generated {@link EventMetaData}.
*/
public ObservableLifeCycleAutomatonImpl( LifeCycleComponent aLifeCycleComponent, EventMetaData aEventMetaData ) {
super( aLifeCycleComponent );
_eventMetaData = aEventMetaData;
_source = this;
_observable = new LifeCycleObservable();
}
/**
* {@inheritDoc}
*
* @param aLifeCycleComponent The {@link LifeCycleComponent} to which the
* life-cycle method calls are to be delegated to.
*
* @param aEventMetaData The {@link EventMetaData} to be used when firing
* events in case the {@link EventMetaData} is to be different from
* the auto-generated {@link EventMetaData}.
*
* @param aSource The source instance to be used when firing events in case
* the source is to be different from this class' instance.
*/
public ObservableLifeCycleAutomatonImpl( LifeCycleComponent aLifeCycleComponent, EventMetaData aEventMetaData, Object aSource ) {
super( aLifeCycleComponent );
_eventMetaData = aEventMetaData;
_source = aSource;
_observable = new LifeCycleObservable();
}
// WITH EXECUTOR-SERVICE:
/**
* {@inheritDoc}
*
* @param aExecutorService The executor service to be used when firing
* {@link ActionEvent} instances in multiple threads (if null then a
* default one is used).
*
* @param aExecutionStrategy The {@link ExecutionStrategy} to be used when
* firing {@link ActionEvent} instance (if null then the default
* {@link ExecutionStrategy#SEQUENTIAL} is used).
*/
public ObservableLifeCycleAutomatonImpl( ExecutorService aExecutorService, ExecutionStrategy aExecutionStrategy ) {
super();
_eventMetaData = new EventMetaDataImpl();
_source = this;
_observable = new LifeCycleObservable( aExecutorService, aExecutionStrategy );
}
/**
* {@inheritDoc}
*
* @param aSource The source instance to be used when firing events in case
* the source is to be different from this class' instance.
*
* @param aExecutorService The executor service to be used when firing
* {@link ActionEvent} instances in multiple threads (if null then a
* default one is used).
*
* @param aExecutionStrategy The {@link ExecutionStrategy} to be used when
* firing {@link ActionEvent} instance (if null then the default
* {@link ExecutionStrategy#SEQUENTIAL} is used).
*/
public ObservableLifeCycleAutomatonImpl( Object aSource, ExecutorService aExecutorService, ExecutionStrategy aExecutionStrategy ) {
super();
_eventMetaData = new EventMetaDataImpl();
_source = aSource;
_observable = new LifeCycleObservable( aExecutorService, aExecutionStrategy );
}
/**
* {@inheritDoc}
*
* @param aEventMetaData The {@link EventMetaData} to be used when firing
* events in case the {@link EventMetaData} is to be different from
* the auto-generated {@link EventMetaData}.
*
* @param aExecutorService The executor service to be used when firing
* {@link ActionEvent} instances in multiple threads (if null then a
* default one is used).
*
* @param aExecutionStrategy The {@link ExecutionStrategy} to be used when
* firing {@link ActionEvent} instance (if null then the default
* {@link ExecutionStrategy#SEQUENTIAL} is used).
*/
public ObservableLifeCycleAutomatonImpl( EventMetaData aEventMetaData, ExecutorService aExecutorService, ExecutionStrategy aExecutionStrategy ) {
super();
_eventMetaData = aEventMetaData;
_source = this;
_observable = new LifeCycleObservable( aExecutorService, aExecutionStrategy );
}
/**
* {@inheritDoc}
*
* @param aEventMetaData The {@link EventMetaData} to be used when firing
* events in case the {@link EventMetaData} is to be different from
* the auto-generated {@link EventMetaData}.
*
* @param aSource The source instance to be used when firing events in case
* the source is to be different from this class' instance.
*
* @param aExecutorService The executor service to be used when firing
* {@link ActionEvent} instances in multiple threads (if null then a
* default one is used).
*
* @param aExecutionStrategy The {@link ExecutionStrategy} to be used when
* firing {@link ActionEvent} instance (if null then the default
* {@link ExecutionStrategy#SEQUENTIAL} is used).
*/
public ObservableLifeCycleAutomatonImpl( EventMetaData aEventMetaData, Object aSource, ExecutorService aExecutorService, ExecutionStrategy aExecutionStrategy ) {
super();
_eventMetaData = aEventMetaData;
_source = aSource;
_observable = new LifeCycleObservable( aExecutorService, aExecutionStrategy );
}
/**
* {@inheritDoc}
*
* @param aLifeCycleComponent The {@link LifeCycleComponent} to which the
* life-cycle method calls are to be delegated to.
*
* @param aExecutorService The executor service to be used when firing
* {@link ActionEvent} instances in multiple threads (if null then a
* default one is used).
*
* @param aExecutionStrategy The {@link ExecutionStrategy} to be used when
* firing {@link ActionEvent} instance (if null then the default
* {@link ExecutionStrategy#SEQUENTIAL} is used).
*/
public ObservableLifeCycleAutomatonImpl( LifeCycleComponent aLifeCycleComponent, ExecutorService aExecutorService, ExecutionStrategy aExecutionStrategy ) {
super( aLifeCycleComponent );
_eventMetaData = new EventMetaDataImpl( this.getClass() );
_source = this;
_observable = new LifeCycleObservable( aExecutorService, aExecutionStrategy );
}
/**
* {@inheritDoc}
*
* @param aLifeCycleComponent The {@link LifeCycleComponent} to which the
* life-cycle method calls are to be delegated to.
*
* @param aSource The source instance to be used when firing events in case
* the source is to be different from this class' instance.
*
* @param aExecutorService The executor service to be used when firing
* {@link ActionEvent} instances in multiple threads (if null then a
* default one is used).
*
* @param aExecutionStrategy The {@link ExecutionStrategy} to be used when
* firing {@link ActionEvent} instance (if null then the default
* {@link ExecutionStrategy#SEQUENTIAL} is used).
*/
public ObservableLifeCycleAutomatonImpl( LifeCycleComponent aLifeCycleComponent, Object aSource, ExecutorService aExecutorService, ExecutionStrategy aExecutionStrategy ) {
super( aLifeCycleComponent );
_eventMetaData = new EventMetaDataImpl( this.getClass() );
_source = aSource;
_observable = new LifeCycleObservable( aExecutorService, aExecutionStrategy );
}
/**
* {@inheritDoc}
*
* @param aLifeCycleComponent The {@link LifeCycleComponent} to which the
* life-cycle method calls are to be delegated to.
*
* @param aEventMetaData The {@link EventMetaData} to be used when firing
* events in case the {@link EventMetaData} is to be different from
* the auto-generated {@link EventMetaData}.
*
* @param aExecutorService The executor service to be used when firing
* {@link ActionEvent} instances in multiple threads (if null then a
* default one is used).
*
* @param aExecutionStrategy The {@link ExecutionStrategy} to be used when
* firing {@link ActionEvent} instance (if null then the default
* {@link ExecutionStrategy#SEQUENTIAL} is used).
*/
public ObservableLifeCycleAutomatonImpl( LifeCycleComponent aLifeCycleComponent, EventMetaData aEventMetaData, ExecutorService aExecutorService, ExecutionStrategy aExecutionStrategy ) {
super( aLifeCycleComponent );
_eventMetaData = aEventMetaData;
_source = this;
_observable = new LifeCycleObservable( aExecutorService, aExecutionStrategy );
}
/**
* {@inheritDoc}
*
* @param aLifeCycleComponent The {@link LifeCycleComponent} to which the
* life-cycle method calls are to be delegated to.
*
* @param aEventMetaData The {@link EventMetaData} to be used when firing
* events in case the {@link EventMetaData} is to be different from
* the auto-generated {@link EventMetaData}.
*
* @param aSource The source instance to be used when firing events in case
* the source is to be different from this class' instance.
*
* @param aExecutorService The executor service to be used when firing
* {@link ActionEvent} instances in multiple threads (if null then a
* default one is used).
*
* @param aExecutionStrategy The {@link ExecutionStrategy} to be used when
* firing {@link ActionEvent} instance (if null then the default
* {@link ExecutionStrategy#SEQUENTIAL} is used).
*/
public ObservableLifeCycleAutomatonImpl( LifeCycleComponent aLifeCycleComponent, EventMetaData aEventMetaData, Object aSource, ExecutorService aExecutorService, ExecutionStrategy aExecutionStrategy ) {
super( aLifeCycleComponent );
_eventMetaData = aEventMetaData;
_source = aSource;
_observable = new LifeCycleObservable( aExecutorService, aExecutionStrategy );
}
// /////////////////////////////////////////////////////////////////////////
// OBSERVERS:
// /////////////////////////////////////////////////////////////////////////
@Override
public boolean hasObserverSubscription( LifeCycleObserver aObserver ) {
return _observable.hasObserverSubscription( aObserver );
}
@Override
public boolean subscribeObserver( LifeCycleObserver aObserver ) {
return _observable.subscribeObserver( aObserver );
}
@Override
public boolean unsubscribeObserver( LifeCycleObserver aObserver ) {
return _observable.unsubscribeObserver( aObserver );
}
// /////////////////////////////////////////////////////////////////////////
// LIFE-CYCLE:
// /////////////////////////////////////////////////////////////////////////
@Override
public synchronized void initialize() throws InitializeException {
LOGGER.info( "About to " + LifeCycleRequest.INITIALIZE + " component \"" + ((getLifeCycleComponent() != null) ? (getLifeCycleComponent().getClass().getName()) : (getClass().getName())) + "\" ..." );
boolean isFireEvent = isInitalizable();
super.initialize();
if ( isFireEvent && isInitialized() ) {
try {
_observable.fireEvent( new InitializedEventImpl( _eventMetaData, _source ) );
}
catch ( VetoException e ) {
/* Cannot happen here */
}
}
LOGGER.info( "Component \"" + ((getLifeCycleComponent() != null) ? (getLifeCycleComponent().getClass().getName()) : (getClass().getName())) + "\" is " + LifeCycleStatus.INITIALIZED + "." );
}
@Override
public synchronized void start() throws StartException {
LOGGER.info( "About to " + LifeCycleRequest.START + " component \"" + ((getLifeCycleComponent() != null) ? (getLifeCycleComponent().getClass().getName()) : (getClass().getName())) + "\" ..." );
boolean isFireEvent = isStartable();
super.start();
if ( isFireEvent && isRunning() ) {
try {
_observable.fireEvent( new StartedEventImpl( _eventMetaData, _source ) );
}
catch ( VetoException e ) {
/* Cannot happen here */
}
}
LOGGER.info( "Component \"" + ((getLifeCycleComponent() != null) ? (getLifeCycleComponent().getClass().getName()) : (getClass().getName())) + "\" is " + LifeCycleStatus.STARTED + "." );
}
@Override
public synchronized void pause() throws PauseException {
LOGGER.info( "About to " + LifeCycleRequest.PAUSE + " component \"" + ((getLifeCycleComponent() != null) ? (getLifeCycleComponent().getClass().getName()) : (getClass().getName())) + "\" ..." );
boolean isFireEvent = isPausable();
super.pause();
if ( isFireEvent && isPaused() ) {
try {
_observable.fireEvent( new PausedEventImpl( _eventMetaData, _source ) );
}
catch ( VetoException e ) {
/* Cannot happen here */
}
}
LOGGER.info( "Component \"" + ((getLifeCycleComponent() != null) ? (getLifeCycleComponent().getClass().getName()) : (getClass().getName())) + "\" is " + LifeCycleStatus.PAUSED + "." );
}
@Override
public synchronized void resume() throws ResumeException {
LOGGER.info( "About to " + LifeCycleRequest.RESUME + " component \"" + ((getLifeCycleComponent() != null) ? (getLifeCycleComponent().getClass().getName()) : (getClass().getName())) + "\" ..." );
boolean isFireEvent = isResumable();
super.resume();
if ( isFireEvent && isRunning() ) {
try {
_observable.fireEvent( new ResumedEventImpl( _eventMetaData, _source ) );
}
catch ( VetoException e ) {
/* Cannot happen here */
}
}
LOGGER.info( "Component \"" + ((getLifeCycleComponent() != null) ? (getLifeCycleComponent().getClass().getName()) : (getClass().getName())) + "\" is " + LifeCycleStatus.STARTED + "." );
}
@Override
public synchronized void stop() throws StopException {
LOGGER.info( "About to " + LifeCycleRequest.STOP + " component \"" + ((getLifeCycleComponent() != null) ? (getLifeCycleComponent().getClass().getName()) : (getClass().getName())) + "\" ..." );
boolean isFireEvent = isStoppable();
super.stop();
if ( isFireEvent && isStopped() ) {
try {
_observable.fireEvent( new StoppedEventImpl( _eventMetaData, _source ) );
}
catch ( VetoException e ) {
/* Cannot happen here */
}
}
LOGGER.info( "Component \"" + ((getLifeCycleComponent() != null) ? (getLifeCycleComponent().getClass().getName()) : (getClass().getName())) + "\" is " + LifeCycleStatus.STOPPED + "." );
}
@Override
public synchronized void destroy() {
LOGGER.info( "About to " + LifeCycleRequest.DESTROY + " component \"" + ((getLifeCycleComponent() != null) ? (getLifeCycleComponent().getClass().getName()) : (getClass().getName())) + "\" ..." );
boolean isFireEvent = isDestroyable();
super.destroy();
if ( isFireEvent && isDestroyed() ) {
try {
_observable.fireEvent( new DestroyedEventImpl( _eventMetaData, _source ) );
}
catch ( VetoException e ) {
/* Cannot happen here */
}
}
_observable.clear();
_observable = null;
_source = null;
_eventMetaData = null;
LOGGER.info( "Component \"" + ((getLifeCycleComponent() != null) ? (getLifeCycleComponent().getClass().getName()) : (getClass().getName())) + "\" is " + LifeCycleStatus.DESTROYED + "." );
}
// /////////////////////////////////////////////////////////////////////////
// INNER CLASSES:
// /////////////////////////////////////////////////////////////////////////
/**
* Implementation of the {@link AbstractObservable} for event distribution.
*/
private class LifeCycleObservable extends AbstractObservable> {
// /////////////////////////////////////////////////////////////////////
// VARIABLES:
// /////////////////////////////////////////////////////////////////////
private ExecutionStrategy _executionStrategy;
// /////////////////////////////////////////////////////////////////////
// CONSTRUCTORS:
// /////////////////////////////////////////////////////////////////////
public LifeCycleObservable() {
super();
_executionStrategy = ExecutionStrategy.SEQUENTIAL;
}
public LifeCycleObservable( ExecutorService aExecutorService, ExecutionStrategy aExecutionStrategy ) {
super( aExecutorService );
_executionStrategy = (aExecutionStrategy != null) ? aExecutionStrategy : ExecutionStrategy.SEQUENTIAL;
}
// /////////////////////////////////////////////////////////////////////
// METHODS:
// /////////////////////////////////////////////////////////////////////
@Override
public int size() {
return super.size();
}
@Override
public boolean isEmpty() {
return super.isEmpty();
}
@Override
public void clear() {
super.clear();
}
// /////////////////////////////////////////////////////////////////////
// HOOKS:
// /////////////////////////////////////////////////////////////////////
@Override
protected boolean fireEvent( MetaDataEvent> aEvent, LifeCycleObserver aEventListener, ExecutionStrategy aEventExecutionStrategy ) throws VetoException {
if ( aEvent instanceof InitializedEvent ) {
aEventListener.onInitialized( (InitializedEvent) aEvent );
}
else if ( aEvent instanceof StartedEvent ) {
aEventListener.onStarted( (StartedEvent) aEvent );
}
else if ( aEvent instanceof PausedEvent ) {
aEventListener.onPaused( (PausedEvent) aEvent );
}
else if ( aEvent instanceof ResumedEvent ) {
aEventListener.onResumed( (ResumedEvent) aEvent );
}
else if ( aEvent instanceof StoppedEvent ) {
aEventListener.onStopped( (StoppedEvent) aEvent );
}
else if ( aEvent instanceof DestroyedEvent ) {
aEventListener.onDestroyed( (DestroyedEvent) aEvent );
}
aEventListener.onEvent( (LifeCycleEvent) aEvent );
return true;
}
/**
* Fires the according event.
*
* @param aEvent The {@link ActionEvent} to be fired.
*
* @throws VetoException Thrown in case of a veto.
*/
protected boolean fireEvent( MetaDataEvent> aEvent ) throws VetoException {
return super.fireEvent( aEvent, _executionStrategy );
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy