All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.refcodes.decoupling.ext.application.ApplicationContext Maven / Gradle / Ivy

Go to download

Artifact extending the refcodes-decoupling artifact with out of the box application functionality such as properties management (alongside profiles support) and CLI support, an event bus (application bus) as well as lifecycle management.

There is a newer version: 3.3.8
Show newest version
// /////////////////////////////////////////////////////////////////////////////
// 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")
// -----------------------------------------------------------------------------
// 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.decoupling.ext.application;

import java.util.logging.Level;
import java.util.logging.Logger;

import org.refcodes.component.DestroyException;
import org.refcodes.component.Destroyable;
import org.refcodes.component.Initializable;
import org.refcodes.component.InitializeException;
import org.refcodes.component.LifecycleComponent;
import org.refcodes.component.LifecycleComponent.LifecycleAutomaton;
import org.refcodes.component.LifecycleMachine;
import org.refcodes.component.LifecycleStatus;
import org.refcodes.component.Pausable;
import org.refcodes.component.PauseException;
import org.refcodes.component.Resumable;
import org.refcodes.component.ResumeException;
import org.refcodes.component.StartException;
import org.refcodes.component.Startable;
import org.refcodes.component.StopException;
import org.refcodes.component.Stoppable;
import org.refcodes.decoupling.Context;
import org.refcodes.decoupling.Dependency;
import org.refcodes.exception.Trap;

/**
 * The {@link ApplicationContext} extends a {@link Context} for out of the box
 * application requirements such as lifecycle support (as if the
 * {@link LifecycleComponent} alongside the {@link LifecycleMachine}).
 */
public class ApplicationContext extends Context implements LifecycleAutomaton {

	// /////////////////////////////////////////////////////////////////////////
	// STATICS:
	// /////////////////////////////////////////////////////////////////////////

	private static final Logger LOGGER = Logger.getLogger( ApplicationContext.class.getName() );

	// /////////////////////////////////////////////////////////////////////////
	// CONSTANTS:
	// /////////////////////////////////////////////////////////////////////////

	// /////////////////////////////////////////////////////////////////////////
	// VARIABLES:
	// /////////////////////////////////////////////////////////////////////////

	private final LifecycleMachine _lifecycleAutomation = new LifecycleMachine();

	// /////////////////////////////////////////////////////////////////////////
	// CONSTRUCTORS:
	// /////////////////////////////////////////////////////////////////////////

	/**
	 * {@inheritDoc}
	 */
	protected ApplicationContext( Object[] aProfiles ) {
		super( aProfiles );
	}

	/**
	 * {@inheritDoc}
	 */
	public ApplicationContext( Dependency[] aDependencies, Object[] aProfiles ) {
		super( aDependencies, aProfiles );
	}

	// /////////////////////////////////////////////////////////////////////////
	// INJECTION:
	// /////////////////////////////////////////////////////////////////////////

	// /////////////////////////////////////////////////////////////////////////
	// METHODS:
	// /////////////////////////////////////////////////////////////////////////

	/**
	 * {@inheritDoc}
	 */
	@Override
	public boolean isDestroyable() {
		return _lifecycleAutomation.isDestroyable();
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public boolean isDestroyed() {
		return _lifecycleAutomation.isDestroyed();
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public boolean isInitalizable() {
		return _lifecycleAutomation.isInitalizable();
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public boolean isInitialized() {
		return _lifecycleAutomation.isInitialized();
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public boolean isPausable() {
		return _lifecycleAutomation.isPausable();
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public boolean isPaused() {
		return _lifecycleAutomation.isPaused();
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public boolean isResumable() {
		return _lifecycleAutomation.isResumable();
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public boolean isRunning() {
		return _lifecycleAutomation.isRunning();
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public boolean isStartable() {
		return _lifecycleAutomation.isStartable();
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public boolean isStoppable() {
		return _lifecycleAutomation.isStoppable();
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public boolean isStopped() {
		return _lifecycleAutomation.isStopped();
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public void initialize() throws InitializeException {
		_lifecycleAutomation.initialize();
		for ( Object eObj : getInstances() ) {
			if ( eObj instanceof Initializable eComponent && eObj != this ) {
				eComponent.initialize();
			}
		}
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public void pause() throws PauseException {
		_lifecycleAutomation.pause();
		for ( Object eObj : getInstances() ) {
			if ( eObj instanceof Pausable eComponent && eObj != this ) {
				eComponent.pause();
			}
		}
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public void resume() throws ResumeException {
		_lifecycleAutomation.resume();
		for ( Object eObj : getInstances() ) {
			if ( eObj instanceof Resumable eComponent && eObj != this ) {
				eComponent.resume();
			}
		}
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public void start() throws StartException {
		_lifecycleAutomation.start();
		for ( Object eObj : getInstances() ) {
			if ( eObj instanceof Startable eComponent && eObj != this ) {
				eComponent.start();
			}
		}
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public void stop() throws StopException {
		StopException theStopException = null;
		_lifecycleAutomation.stop();
		for ( Object eObj : getInstances() ) {
			if ( eObj instanceof Stoppable eComponent && eObj != this ) {
				try {
					eComponent.stop();
				}
				// Try to stop as many as possible! |-->
				catch ( StopException e ) {
					LOGGER.log( Level.WARNING, "Cannot stop the component <" + eComponent + "> of dependency <" + getDependencyByInstance( eComponent ) + "> as of: " + e.toMessage(), e );
					if ( theStopException == null ) {
						theStopException = e;
					}
				}
				// Try to stop as many as possible! <--|
			}
		}
		if ( theStopException != null ) {
			throw new StopException( "Failed to stop at least one dependency's instance(s):" + theStopException.getMessage(), theStopException );
		}
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public void destroy() {
		RuntimeException theDestroyException = null;
		_lifecycleAutomation.destroy();
		for ( Object eObj : getInstances() ) {
			if ( eObj instanceof Destroyable eComponent && eObj != this ) {
				try {
					eComponent.destroy();
				}
				// Try to destroy as many as possible! |-->
				catch ( RuntimeException e ) {
					LOGGER.log( Level.WARNING, "Cannot destroy the component <" + eComponent + "> of dependency <" + getDependencyByInstance( eComponent ) + "> as of: " + Trap.asMessage( e ), e );
					if ( theDestroyException == null ) {
						theDestroyException = e;
					}
				}
				// Try to destroy as many as possible! <--|
			}
		}
		if ( theDestroyException != null ) {
			throw new DestroyException( "Failed to destroy at least one dependency's instance(s):" + theDestroyException.getMessage(), theDestroyException );
		}
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public LifecycleStatus getLifecycleStatus() {
		return _lifecycleAutomation.getLifecycleStatus();
	}

	// /////////////////////////////////////////////////////////////////////////
	// HOOKS:
	// /////////////////////////////////////////////////////////////////////////

	/**
	 * Used internally to Initialize the {@link ApplicationContext} with
	 * omitting initializing the {@link ApplicationContext}'s created instances
	 * (dependencies). The according instances must are (to be) initialized
	 * manually.
	 * 
	 * @throws InitializeException thrown in case initializing caused problems
	 *         (e.g. as of a bad {@link LifecycleStatus} state).
	 */
	void doInitialize() throws InitializeException {
		_lifecycleAutomation.initialize();
	}

	/**
	 * Used internally to start the {@link ApplicationContext} with omitting
	 * starting the {@link ApplicationContext}'s created instances
	 * (dependencies). The according instances are (to be) started manually by
	 * the caller.
	 * 
	 * @throws StartException thrown in case starting caused problems (e.g. as
	 *         of a bad {@link LifecycleStatus} state).
	 */
	void doStart() throws StartException {
		_lifecycleAutomation.start();
	}

	// /////////////////////////////////////////////////////////////////////////
	// HELPER:
	// /////////////////////////////////////////////////////////////////////////

	// /////////////////////////////////////////////////////////////////////////
	// INNER CLASSES:
	// /////////////////////////////////////////////////////////////////////////
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy