Package jfun.yan.containers

Source Code of jfun.yan.containers.SimpleRegistrar

/*****************************************************************************
* 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 27, 2005
*
* Author Ben Yu
* ZBS
*/
package jfun.yan.containers;


import java.util.Iterator;
import java.util.LinkedHashMap;

import jfun.yan.AmbiguousComponentResolutionException;
import jfun.yan.Component;
import jfun.yan.ComponentMap;
import jfun.yan.Dependency;
import jfun.yan.Registrar;
import jfun.yan.SimpleDependency;
import jfun.yan.YanException;
import jfun.yan.util.ReflectionUtil;

/**
* A simple implementation of Registrar.
* It ensures the Component objects and instances are retrieved and
* created in the same order as the Component objects are registered.
* <br>
* This implementation enables auto-wiring.
* It uses {@link SimpleDependency} to resolve parameters and properties.
* <br>
* It is also thread-safe.
* <p>
* Codehaus.org.
*
* @author Ben Yu
*
*/
public class SimpleRegistrar
implements Registrar, java.io.Serializable{
  private final LinkedHashMap creators = new LinkedHashMap();
  public synchronized int size(){
    return creators.size();
  }
  public synchronized java.util.Set keys(){
    return java.util.Collections.unmodifiableSet(creators.keySet());
  }
  public synchronized java.util.Collection getComponents(){
    return java.util.Collections.unmodifiableCollection(creators.values());
  }
  public synchronized boolean containsKey(final Object key){
    return creators.containsKey(key);
  }
  public synchronized Component getComponent(final Object key) {
    return (Component)creators.get(key);
  }
  public synchronized boolean containsType(final Class type){
    Component cc = getComponent(type);
    if(cc!=null){
      final Class ctype = cc.getType();
      if(ctype == null
          || ReflectionUtil.isAssignableFrom(type, ctype)){
        //if the type is dynamically bound, we trust the key.
        return true;
      }
      cc = null;
    }
    for(Iterator it=creators.values().iterator();it.hasNext();){
      final Component cci = (Component)it.next();
      final Class typei = cci.getType();
      if(typei!=null && !void.class.equals(typei) &&
          //void type does actively feed itself to a by-type search.
          //It does suppress type error when forced to match against another type.
          ReflectionUtil.isAssignableFrom(
          type, typei)){
        return true;
      }
    }
    return false;
  }
  public synchronized Component getComponentOfType(final Class type){
    Component cc = getComponent(type);
    if(cc!=null){
      final Class ctype = cc.getType();
      if(ctype == null
          || ReflectionUtil.isAssignableFrom(type, ctype)){
        //if the type is dynamically bound, we trust the key.
        return cc;
      }
      cc = null;
    }
    Class subtype = null;
    for(Iterator it=creators.values().iterator();it.hasNext();){
      final Component cci = (Component)it.next();
      final Class typei = cci.getType();
      if(typei!=null && !void.class.equals(typei) &&
          //void type does actively feed itself to a by-type search.
          //It does suppress type error when forced to match against another type.
          ReflectionUtil.isAssignableFrom(
          type, typei)){
        if(subtype!=null){
          throw
            new AmbiguousComponentResolutionException(type, subtype, typei);
        }
        else{
          subtype = typei;
          cc = cci;
        }
      }
    }
    return cc;
  }
  public synchronized java.util.List getComponentsOfType(final Class type){
    final java.util.ArrayList ret = new java.util.ArrayList();
    for(Iterator it=creators.values().iterator();it.hasNext();){
      final Component cci = (Component)it.next();
      final Class typei = cci.getType();
      if(typei!=null &&
          !void.class.equals(typei) && ReflectionUtil.isAssignableFrom(
          type, typei)){
        ret.add(cci);
      }
    }
    return ret;
  }
  public synchronized void unregisterComponentsOfType(Class type){
    for(Iterator it=creators.values().iterator();it.hasNext();){
      final Component cci = (Component)it.next();
      final Class typei = cci.getType();
      if(typei!=null && ReflectionUtil.isAssignableFrom(
          type, typei)){
        it.remove();
      }
    }
  }
  public synchronized void registerComponent(Object key,
      Component cc) {
    creators.put(key, cc);
  }

  public synchronized void unregisterComponent(Object key) {
    creators.remove(key);
  }
  public synchronized void verify(final ComponentMap cmap) {
    for(Iterator it=creators.keySet().iterator();it.hasNext();){
      final Object ki = it.next();
      try{
        final Component cc = (Component)creators.get(ki);
        cc.verify(cmap.getDependency(ki, cmap));
      }
      catch(YanException e){
        e.push("verify <" + ki +">");
        throw e;
      }
    }
  }
  /**
   * This uses SimpleDependency which resolves parameters and
   * arguments by type.
   * Different resolution policy can be provided by overriding this method.
   */
  public synchronized Dependency getDependency(final Object ckey
      ,final ComponentMap cmap){
    return new SimpleDependency(ckey, cmap);
  }
  /**
   * This uses SimpleDependency which resolves parameters and
   * arguments by type.
   * Different resolution policy can be provided by overriding this method.
   */
  public synchronized Dependency getDependencyOfType(
      final Class type, final ComponentMap cmap){
    return new SimpleDependency(type, cmap);
  }
  public synchronized boolean equals(Object obj) {
    if(obj instanceof SimpleRegistrar){
      final SimpleRegistrar sc2 = (SimpleRegistrar)obj;
      return creators.equals(sc2.creators);
    }
    else return false;
  }
  public synchronized int hashCode() {
    return creators.hashCode();
  }
  public synchronized String toString() {
    return creators.toString();
  }
}
TOP

Related Classes of jfun.yan.containers.SimpleRegistrar

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.