Package net.sourceforge.javautil.container.impl

Source Code of net.sourceforge.javautil.container.impl.ContainerAbstract$BoundLifecycle

package net.sourceforge.javautil.container.impl;

import java.util.HashMap;
import java.util.Map;

import net.sourceforge.javautil.common.classloader.ClassLoaderResource;
import net.sourceforge.javautil.common.shutdown.Shutdown;
import net.sourceforge.javautil.container.IContainer;
import net.sourceforge.javautil.lifecycle.ILifecycle;
import net.sourceforge.javautil.lifecycle.ILifecycle.PhaseType;
import net.sourceforge.javautil.lifecycle.LifecycleException;
import net.sourceforge.javautil.lifecycle.annotation.Phase;
import net.sourceforge.javautil.lifecycle.impl.ChildLifecycle;
import net.sourceforge.javautil.lifecycle.impl.LifecycleAbstract;
import net.sourceforge.javautil.lifecycle.impl.LifecyclePojo;
import net.sourceforge.javautil.lifecycle.impl.ParentLifecycle;

/**
* The base for most {@link IContainer} implementations.
*
* @author elponderador
* @author $Author$
* @version $Id$
*/
public abstract class ContainerAbstract<L extends ILifecycle<?>> implements IContainer {
 
  protected final String name;
  protected final Map<IContainer, BoundLifecycle> bindings = new HashMap<IContainer, BoundLifecycle>();
 
  private L lifecycle;

  public ContainerAbstract(String name) {
    this.name = name;
  }

  public String getName() { return this.name; }

  public final void start() { this.getLifecycleInternal().start(); }

  public final void stop() { this.getLifecycleInternal().stop(); }

  public L getLifecycle() { return this.getLifecycleInternal(); }

  @Override public synchronized void bind(IContainer childContainer, boolean autoStartChild) {
    switch (this.getLifecycle().getCurrentPhase()) {
      case DESTROY:
        throw new LifecycleException("Cannot bind child container after destroy", childContainer.getLifecycle());
       
      default:
        if (this.bindings.containsKey(childContainer))
          throw new IllegalArgumentException("Child container already bound");
       
        ParentLifecycle parent = new ParentLifecycle(childContainer.getLifecycle(), autoStartChild);
        ChildLifecycle child = new ChildLifecycle(getLifecycle());
       
        this.bindings.put(childContainer, new BoundLifecycle(parent, child));
       
        getLifecycle().addListener(parent);
        childContainer.getLifecycle().addListener(child);
       
        if (this.isStarted() && !childContainer.isStarted()) childContainer.start();
    }
  }

  @Override public synchronized void unbind(IContainer childContainer) {
    if (this.bindings.containsKey(childContainer)) {
      BoundLifecycle bound = this.bindings.get(childContainer);
      getLifecycle().removeListener(bound.parent);
      childContainer.getLifecycle().removeListener(bound.child);
     
      this.bindings.remove(childContainer);
    }
  }

  public boolean isStarted() {
    return this.getLifecycleInternal().getCurrentPhase() == PhaseType.START;
  }

  public boolean isStopped() {
    return this.getLifecycleInternal().getCurrentPhase().ordinal() >= PhaseType.STOP.ordinal();
  }

  public void shutdown() {
    switch (this.getLifecycleInternal().getCurrentPhase()) {
      case START:
        this.getLifecycleInternal().stop();
       
      case CREATE: case STOP:
        this.getLifecycleInternal().destroy();
       
      default:
        // Ignore other phases
    }
  }
 
  /**
   * @return The lazily-initialized life-cycle
   */
  protected L getLifecycleInternal () {
    if (this.lifecycle == null) {
      synchronized (this) {
        if (this.lifecycle == null) {
          this.lifecycle = this.createLifecycle();
        }
      }
    }
    return this.lifecycle;
  }
 
  /**
   * @return The implementation specific life cycle for this container
   */
  protected abstract L createLifecycle ();
 
  /**
   * A composite of information about bound {@link ILifecycle}'s.
   *
   * @author elponderador
   * @author $Author$
   * @version $Id$
   */
  protected class BoundLifecycle {
   
    protected final ParentLifecycle parent;
    protected final ChildLifecycle child;
   
    public BoundLifecycle(ParentLifecycle parent, ChildLifecycle child) {
      this.parent = parent;
      this.child = child;
    }
   
  }
 
}
TOP

Related Classes of net.sourceforge.javautil.container.impl.ContainerAbstract$BoundLifecycle

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.