
com.samskivert.util.Lifecycle Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of samskivert Show documentation
Show all versions of samskivert Show documentation
A collection of Java utilities.
//
// $Id: Lifecycle.java 2974 2011-01-01 05:09:33Z [email protected] $
//
// samskivert library - useful routines for java programs
// Copyright (C) 2001-2011 Michael Bayne, et al.
//
// This library is free software; you can redistribute it and/or modify it
// under the terms of the GNU Lesser General Public License as published
// by the Free Software Foundation; either version 2.1 of the License, or
// (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
package com.samskivert.util;
import static com.samskivert.Log.log;
/**
* Manages the lifecycle (initialization and shutdown) of a collection of components.
*/
public class Lifecycle
{
/** An interface implemented by components which wish to participate in the lifecycle. */
public interface BaseComponent
{
}
/** An interface implemented by components which wish to participate in the lifecycle. */
public interface InitComponent extends BaseComponent
{
/** Called after dependencies have been fully resolved to initialize this component. */
public void init ();
}
/** An interface implemented by components which wish to participate in the lifecycle. */
public interface ShutdownComponent extends BaseComponent
{
/** Called when the server is shutting down. */
public void shutdown ();
}
/** An interface implemented by components which wish to participate in the lifecycle. */
public interface Component extends InitComponent, ShutdownComponent
{
}
/** Constraints for use with {@link #addInitConstraint} and {@link #addShutdownConstraint}. */
public static enum Constraint { RUNS_BEFORE, RUNS_AFTER }
/**
* Registers a component with the lifecycle. This should be done during dependency resolution
* by injecting the Lifecycle into your constructor and calling this method there.
*/
public void addComponent (BaseComponent comp)
{
if (comp instanceof InitComponent) {
if (_initers == null) {
throw new IllegalStateException("Too late to register InitComponent.");
}
_initers.add((InitComponent)comp);
}
if (comp instanceof ShutdownComponent) {
if (_downers == null) {
throw new IllegalStateException("Too late to register ShutdownComponent.");
}
_downers.add((ShutdownComponent)comp);
}
}
/**
* Removes a component from the lifecycle. This is generally not used.
*/
public void removeComponent (BaseComponent comp)
{
if (_initers != null && comp instanceof InitComponent) {
_initers.remove((InitComponent)comp);
}
if (_downers != null && comp instanceof ShutdownComponent) {
_downers.remove((ShutdownComponent)comp);
}
}
/**
* Adds a constraint that a certain component must be initialized before another.
*/
public void addInitConstraint (InitComponent lhs, Constraint constraint, InitComponent rhs)
{
if (lhs == null || rhs == null) {
throw new IllegalArgumentException("Cannot add constraint about null component.");
}
InitComponent before = (constraint == Constraint.RUNS_BEFORE) ? lhs : rhs;
InitComponent after = (constraint == Constraint.RUNS_BEFORE) ? rhs : lhs;
_initers.addDependency(after, before);
}
/**
* Adds a constraint that a certain component must be shutdown before another.
*/
public void addShutdownConstraint (ShutdownComponent lhs, Constraint constraint,
ShutdownComponent rhs)
{
if (lhs == null || rhs == null) {
throw new IllegalArgumentException("Cannot add constraint about null component.");
}
ShutdownComponent before = (constraint == Constraint.RUNS_BEFORE) ? lhs : rhs;
ShutdownComponent after = (constraint == Constraint.RUNS_BEFORE) ? rhs : lhs;
_downers.addDependency(after, before);
}
/**
* Returns true if we're in the process of shutting down.
*/
public boolean isShuttingDown ()
{
return (_downers == null);
}
/**
* Initializes all components immediately on the caller's thread.
*/
public void init ()
{
if (_initers == null) {
log.warning("Refusing repeat init() request.");
return;
}
ObserverList list = _initers.toObserverList();
_initers = null;
list.apply(new ObserverList.ObserverOp() {
public boolean apply (InitComponent comp) {
log.debug("Initializing component", "comp", comp);
comp.init();
return true;
}
});
}
/**
* Shuts down all components immediately on the caller's thread.
*/
public void shutdown ()
{
if (_downers == null) {
log.warning("Refusing repeat shutdown() request.");
return;
}
ObserverList list = _downers.toObserverList();
_downers = null;
list.apply(new ObserverList.ObserverOp() {
public boolean apply (ShutdownComponent comp) {
log.debug("Shutting down component", "comp", comp);
comp.shutdown();
return true;
}
});
}
/** A dependency graph of our components arranged by initialization dependencies. */
protected DependencyGraph _initers = new DependencyGraph();
/** A dependency graph of our components arranged by shutdown dependencies. */
protected DependencyGraph _downers =
new DependencyGraph();
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy