org.refcodes.decoupling.ext.application.ApplicationContext Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of refcodes-decoupling-ext-application Show documentation
Show all versions of refcodes-decoupling-ext-application Show documentation
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.
// /////////////////////////////////////////////////////////////////////////////
// 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