Package jfun.yan.containers

Source Code of jfun.yan.containers.SimpleContainer

/*****************************************************************************
* Copyright (C) Codehaus.org. All rights reserved.            *
* ------------------------------------------------------------------------- *
* The software in this package is published under the terms of the BSD      *
* style license a copy of which has been included with this distribution in *
* the LICENSE.txt file.                                                     *
*****************************************************************************/
/*
* Created on Feb 28, 2005
*
* Author Ben Yu
* ZBS
*/
package jfun.yan.containers;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import jfun.util.Misc;
import jfun.yan.AmbiguousComponentResolutionException;
import jfun.yan.Component;
import jfun.yan.ComponentInstantiationException;
import jfun.yan.ComponentMap;
import jfun.yan.Components;
import jfun.yan.Container;
import jfun.yan.Creator;
import jfun.yan.CyclicDependencyException;
import jfun.yan.Dependency;
import jfun.yan.Registrar;
import jfun.yan.UnknownComponentTypeException;
import jfun.yan.UnresolvedComponentException;
import jfun.yan.UnsatisfiedComponentException;
import jfun.yan.YanException;
import jfun.yan.factory.Factory;

/**
* A simple implementation of interface {@link Container}.
* <p>
* It forwards all method call to the delegated {@link Registrar} object,
* which makes it handy for customizing a Registrar object by subclassing.
* </p>
* <p>
* Plus, SimpleContainer implements {@link Container} interface,
* which provides convenient API's.
* </p>
* <p>
* In this implementation,
* registerStaticMethod and registerConstructor use singleton pattern.
* Override these methods or the {@link #defaultTransform(Component)} method to
* disable the singleton or get a different transformation.
* </p>
* Codehaus.org.
*
* @author Ben Yu
*
*/
public class SimpleContainer implements Container, java.io.Serializable{
  private final Registrar target;
 
  /**
   * Create a new SimpleContainer object.
   * @param target the Registrar object.
   */
  public SimpleContainer(final Registrar target) {
    this.target = target;
  }

  public void registerComponent(Object key, Component cc) {
    target.registerComponent(key, cc);
  }
  public void registerComponent(Component cc){
    final Class ctype = cc.getType();
    if(ctype==null){
      throw new UnknownComponentTypeException(
          "immature component cannot be registered");
    }
    registerComponent(ctype, cc);
  }
  public void unregisterComponent(Object key) {
    target.unregisterComponent(key);
  }
 
  public void unregisterComponentsOfType(Class type) {
    target.unregisterComponentsOfType(type);
  }
  public boolean containsKey(Object key) {
    return target.containsKey(key);
  }

  public boolean containsType(Class type) {
    return target.containsType(type);
  }

  public Component getComponent(Object key) {
    return target.getComponent(key);
  }
 
  public <T> Component<T> getComponentOfType(Class<T> type) {
    return target.getComponentOfType(type);
  }
  public <T> List<Component<T>> getComponentsOfType(Class<T> type) {
    return target.getComponentsOfType(type);
  }

  public <T> T getInstanceOfType(final Class<T> type, ComponentMap cmap){
    try{
      final Component<T> cc = getComponentOfType(type);
      if(cc==null){
        throw new UnresolvedComponentException(type);
      }
      return cc.create(cmap.getDependencyOfType(type, cmap));
    }
    catch(YanException e){
      e.push("getInstanceOfType <" + Misc.getTypeName(type)+">");
      throw e;
    }
  }
  public <T> List<T> getInstancesOfType(final Class<T> type, ComponentMap cmap){
    try{
      java.util.List<Component<T>> ccs = getComponentsOfType(type);
      final java.util.List<T> ret = new java.util.ArrayList<T>();
      for(final Component<T> cc : ccs){
        final Class ctype = cc.getType();
        if(ctype != null)
          ret.add(cc.create(cmap.getDependencyOfType(ctype, cmap)));
      }
      return ret;
    }
    catch(YanException e){
      e.push("getInstancesOfType <" + Misc.getTypeName(type) + ">");
      throw e;
    }
  }
  public <T> T getInstanceOfType(Class<T> type){
    return getInstanceOfType(type, this);
  }
  public <T> List<T> getInstancesOfType(Class<T> type){
    return getInstancesOfType(type, this);
  }
  public Dependency getDependencyOfType(Class type, ComponentMap cmap) {
    return target.getDependencyOfType(type, cmap);
  }
  public Dependency getDependency(Object key, ComponentMap cmap){
    return target.getDependency(key, cmap);
  }
  public Dependency getDependency(Object key){
    return getDependency(key, this);
  }
  public Dependency getDependencyOfType(Class type){
    return getDependencyOfType(type, this);
  }
  public void verify(ComponentMap cmap) {
    target.verify(cmap);
  }
  public void verify(){
    target.verify(this);
  }
 
  public Class verifyComponent(Component cc){
    try{
      /*final Class ctype = cc.getType();
      if(ctype == null)
        throw new IllegalArgumentException(
            "dynamic-bound component cannot be verified");
      */
      return cc.verify(getDependency(null));
    }
    catch(YanException e){
      e.push("verifyComponent <" + cc + ">");
      throw e;
    }
  }
  public Class verifyKey(Object key){
    try{
      final Component c = getComponent(key);
      if(c==null){
        throw new UnresolvedComponentException(key);
      }
      return c.verify(getDependency(key));
    }
    catch(YanException e){
      e.push("verifyKey <" + key +">");
      throw e;
    }
  }
  public Class verifyType(Class type){
    try{
      final Component c = getComponentOfType(type);
      if(c==null)
        throw new UnresolvedComponentException(type);
      return c.verify(getDependencyOfType(type));
    }
    catch(YanException e){
      e.push("verifyType <" + Misc.getTypeName(type) +">");
      throw e;
    }
  }
  public Class getComponentType(Object key) {
    final Component cc = getComponent(key);
    if(cc==null) return null;
    return cc.getType();
  }

 
  public <T> T instantiateComponent(Creator<T> cc, ComponentMap cmap)
      throws AmbiguousComponentResolutionException,
      ComponentInstantiationException, CyclicDependencyException,
      UnresolvedComponentException, UnsatisfiedComponentException, YanException {
    try{
      return cc.create(getDependency(null, cmap));
    }
    catch(YanException e){
      e.push("instantiateComponent <" + cc + ">");
      throw e;
    }
  }
  public <T> T instantiateComponent(Object key, Creator<T> cc, ComponentMap cmap)
  throws AmbiguousComponentResolutionException,
  ComponentInstantiationException, CyclicDependencyException,
  UnresolvedComponentException, UnsatisfiedComponentException, YanException {
    try{
      return cc.create(getDependency(key, cmap));
    }
    catch(YanException e){
      e.push("instantiateComponent <" + key + ">");
      throw e;
    }
  }
  public <T> T instantiateComponent(Creator<T> cc)
      throws AmbiguousComponentResolutionException,
      ComponentInstantiationException, CyclicDependencyException,
      UnresolvedComponentException, UnsatisfiedComponentException, YanException {
    return instantiateComponent(cc, this);
  }
  public <T> T instantiateComponent(Object key, Creator<T> cc)
  throws AmbiguousComponentResolutionException,
  ComponentInstantiationException, CyclicDependencyException,
  UnresolvedComponentException, UnsatisfiedComponentException, YanException {
    return instantiateComponent(key, cc, this);
  }
  public Object getInstance(Object key, ComponentMap cmap) {
    try{
      final Component cc = getComponent(key);
      if(cc==null){
        throw new UnresolvedComponentException(key);
      }
      return cc.create(cmap.getDependency(key,cmap));
    }
    catch(YanException e){
      e.push("getInstance <" + key + ">");
      throw e;
    }
  }
  public Object getInstance(Object key){
    return getInstance(key, this);
  }

  public void registerValue(Object key, Object v){
    registerComponent(key, Components.value(v));
  }
  public void registerValue(Object v){
    //registerValue(v==null?Object.class:v.getClass(), v);
    registerValue(v.getClass(), v);
  }
  /**
   * The component is transformed by {@link #defaultTransform(Component)},
   * which makes it singleton.
   * Override {@link #defaultTransform(Component)} if a different default behavior
   * is desired.
   */
  public void registerConstructor(Class c){
    registerConstructor(c, c);
  }
  /**
   * Transforms a component by calling singleton().
   * registerConstructor and registerStaticMethod
   * call this function to transform the component
   * before registering to the container.
   * Override this function if singleton() is not desired
   * or a different transformation is needed.
   * @param comp the component.
   * @return the transformed component.
   */
  protected Component defaultTransform(Component comp){
    return comp.singleton();
  }
  /**
   * The component is transformed by {@link #defaultTransform(Component)},
   * which makes it singleton.
   * Override {@link #defaultTransform(Component)} if a different default behavior
   * is desired.
   */
  public void registerConstructor(Object key, Class c){
    registerComponent(key, defaultTransform(Components.ctor(c)));
  }
  /**
   * The component is transformed by {@link #defaultTransform(Component)},
   * which makes it singleton.
   * Override {@link #defaultTransform(Component)} if a different default behavior
   * is desired.
   */
  public void registerConstructor(Class c, Class[] param_types){
    registerConstructor(c, c, param_types);
  }
  /**
   * The component is transformed by {@link #defaultTransform(Component)},
   * which makes it singleton.
   * Override {@link #defaultTransform(Component)} if a different default behavior
   * is desired.
   */
  public void registerConstructor(Object key, Class c, Class[] param_types){
    registerComponent(key,
        defaultTransform(Components.ctor(c, param_types)));
  }
  /**
   * The component is transformed by {@link #defaultTransform(Component)},
   * which makes it singleton.
   * Override {@link #defaultTransform(Component)} if a different default behavior
   * is desired.
   */
  public void registerStaticMethod(Class c, String name){
    final Component comp = Components.static_method(c, name);
    registerComponent(defaultTransform(comp));
  }
  /**
   * The component is transformed by {@link #defaultTransform(Component)},
   * which makes it singleton.
   * Override {@link #defaultTransform(Component)} if a different default behavior
   * is desired.
   */
  public void registerStaticMethod(Object key, Class c, String name){
    registerComponent(key,
        defaultTransform(Components.static_method(c, name)));
  }
  /**
   * The component is transformed by {@link #defaultTransform(Component)},
   * which makes it singleton.
   * Override {@link #defaultTransform(Component)} if a different default behavior
   * is desired.
   */
  public void registerStaticMethod(Class c, String name, Class[] param_types){
    final Component comp = Components.static_method(c, name, param_types);
    registerComponent(defaultTransform(comp));
  }
  /**
   * The component is transformed by {@link #defaultTransform(Component)},
   * which makes it singleton.
   * Override {@link #defaultTransform(Component)} if a different default behavior
   * is desired.
   */
  public void registerStaticMethod(Object key, Class c, String name, Class[] param_types){
    registerComponent(key,
        defaultTransform(Components.static_method(c, name, param_types)));
  }
  public Container inherit(Registrar parent){
    if(parent==this) return this;
    return new SimpleContainer(new InheritedRegistrar(parent, this));
  }
  public boolean equals(Object other) {
    if(other instanceof SimpleContainer){
      final SimpleContainer cc2 = (SimpleContainer)other;
      return target.equals(cc2.target);
    }
    else return target.equals(other);
  }
  public int hashCode() {
    return target.hashCode();
  }
  public String toString() {
    return target.toString();
  }
 
  public Set keys() {
    return target.keys();
  }
  public java.util.Collection getComponents(){
    return target.getComponents();
  }
  public void getInstances(Map store){
    getInstances(store, this);
  }
  public java.util.List getInstances(){
    return getInstances(this);
  }
  public void getInstances(Map store, ComponentMap cmap){
    try{
      for(Iterator it = keys().iterator(); it.hasNext();){
        final Object ky = it.next();
        final Component cc = getComponent(ky);
        store.put(ky, cc.create(cmap.getDependency(ky, cmap)));
      }
    }
    catch(YanException e){
      e.push("getInstances");
      throw e;
    }
  }
  public java.util.List getInstances(ComponentMap cmap){
    try{
      final java.util.Set ks = keys();
      final ArrayList ret = new ArrayList();
      for(Iterator it = ks.iterator(); it.hasNext();){
        final Object ky = it.next();
        final Component cc = getComponent(ky);
        ret.add(cc.create(cmap.getDependency(ky, cmap)));
      }
      return ret;
    }
    catch(YanException e){
      e.push("getInstances");
      throw e;
    }
  }
  public Factory getFactory(Object key, ComponentMap cmap) throws UnresolvedComponentException, YanException {
    return instantiateFactory(key, getComponent(key), cmap);
  }

  public Factory getFactory(Object key) throws UnresolvedComponentException, YanException {
    return instantiateFactory(key, getComponent(key));
  }

  public <T> Factory<T> getFactoryOfType(Class<T> type, ComponentMap cmap) throws AmbiguousComponentResolutionException, UnresolvedComponentException, YanException {
    return instantiateFactory(type, getComponentOfType(type), cmap);
  }

  public <T> Factory<T> getFactoryOfType(Class<T> type) throws AmbiguousComponentResolutionException, UnresolvedComponentException, YanException {
    return instantiateFactory(type, getComponentOfType(type));
  }
  private <T> Factory<T> instantiateFactory(Object key, Component<T> cc, ComponentMap src){
    return this.instantiateComponent(key, cc.factory(), src);
  }
  private <T> Factory<T> instantiateFactory(Object key, Component<T> cc){
    return this.instantiateComponent(key, cc.factory());
  }
  /**
   * Gets the Registrar object being delegated.
   * @return the Container object.
   */
  protected final Registrar getDelegateTarget(){
    return target;
  }
}
TOP

Related Classes of jfun.yan.containers.SimpleContainer

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.