Coverage report

  %line %branch
net.sf.tlc.ioc.impl.EmbeddableContainer
84% 
97% 

 1  
 /*
 2  
  * Created on May 20, 2005
 3  
  *
 4  
  * An embeddable IoC/dependcy-inject container (similar to <a
 5  
  * href="http://www.picocontainer.org">PicoContainer </a>).
 6  
  */
 7  
 package net.sf.tlc.ioc.impl;
 8  
 
 9  
 import java.lang.reflect.Constructor;
 10  
 import java.lang.reflect.InvocationTargetException;
 11  
 import java.util.ArrayList;
 12  
 import java.util.Iterator;
 13  
 import java.util.LinkedHashSet;
 14  
 import java.util.Set;
 15  
 
 16  
 import net.sf.tlc.ioc.IocContainer;
 17  
 import net.sf.tlc.util.ClassUtils;
 18  
 
 19  
 /**
 20  
  * An embeddable IoC/dependcy-inject container (similar to <a
 21  
  * href="http://www.picocontainer.org">PicoContainer </a>).
 22  
  * 
 23  
  * @author aisrael
 24  
  */
 25  
 public class EmbeddableContainer implements IocContainer {
 26  
 
 27  
     private final DependencyManager dependencyManager;
 28  
 
 29  
     private final Set objects;
 30  
 
 31  
     /**
 32  
      * Constructor
 33  
      * 
 34  
      * @param dependencyManager
 35  
      *            DependencyManager
 36  
      */
 37  150
     public EmbeddableContainer(final DependencyManager dependencyManager) {
 38  150
         this.dependencyManager = dependencyManager;
 39  150
         objects = new LinkedHashSet();
 40  150
     }
 41  
 
 42  
     /**
 43  
      * Default constructor
 44  
      */
 45  
     public EmbeddableContainer() {
 46  0
         this(new DefaultDependencyManager());
 47  0
     }
 48  
 
 49  
     /**
 50  
      * (non-Javadoc)
 51  
      * 
 52  
      * @see net.sf.tlc.ioc.IocContainer#register(java.lang.Class)
 53  
      */
 54  
     public final void register(class="keyword">final Class c) {
 55  160
         dependencyManager.registerClass(c);
 56  160
     }
 57  
 
 58  
     /**
 59  
      * (non-Javadoc)
 60  
      * 
 61  
      * @see net.sf.tlc.ioc.IocContainer#add(java.lang.Object)
 62  
      */
 63  
     public final void add(class="keyword">final Object o) {
 64  280
         if (null != o) {
 65  289
             if (Class.class.equals(o.getClass())) {
 66  0
                 throw new IllegalArgumentException(
 67  
                         "WARNING: adding a Class, maybe you should call register()?");
 68  
             }
 69  280
             objects.add(o);
 70  280
             dependencyManager.registerClass(o.getClass());
 71  
         }
 72  280
     }
 73  
 
 74  
     /**
 75  
      * @param c
 76  
      *            Class
 77  
      * @return Object
 78  
      */
 79  
     private Object findObjectOfType(final Class c) {
 80  359
         for (final Iterator i = objects.iterator(); i.hasNext();) {
 81  140
             final Object o = i.next();
 82  140
             if (c.isAssignableFrom(o.getClass())) {
 83  70
                 return o;
 84  
             }
 85  
         }
 86  250
         return null;
 87  
     }
 88  
 
 89  
     /**
 90  
      * (non-Javadoc)
 91  
      * 
 92  
      * @see net.sf.tlc.ioc.IocContainer#getInstance(java.lang.Class)
 93  
      */
 94  
     public final Object getInstance(class="keyword">final Class c) {
 95  320
         Object result = null;
 96  
 
 97  320
         result = findObjectOfType(c);
 98  320
         if (null == result) {
 99  250
             if (ClassUtils.isAbstractClass(c) || c.isInterface()) {
 100  50
                 result = createConcreteObjectFor(c);
 101  
             } else {
 102  200
                 result = createObjectOfType(c);
 103  
             }
 104  
         }
 105  
 
 106  320
         return result;
 107  
     }
 108  
 
 109  
     /**
 110  
      * @param c
 111  
      *            Class
 112  
      * @return Object that extends or implements the class
 113  
      */
 114  
     private Object createConcreteObjectFor(final Class c) {
 115  50
         Object result = null;
 116  50
         final Class[] classes = dependencyManager.listAllImplementingClasses(c);
 117  50
         final ArrayList possibleClasses = new ArrayList();
 118  90
         for (int i = 0; i < classes.length; ++i) {
 119  40
             if (dependencyManager.canConstructClass(classes[i])) {
 120  40
                 possibleClasses.add(classes[i]);
 121  
             }
 122  
         }
 123  50
         if (possibleClasses.size() == 1) {
 124  40
             final Class d = (Class) possibleClasses.get(0);
 125  40
             result = createObjectOfType(d);
 126  10
         } else if (possibleClasses.size() > 1) {
 127  0
             throw new RuntimeException("More than one possible class! What to choose?!");
 128  
         }
 129  50
         return result;
 130  
     }
 131  
 
 132  
     /**
 133  
      * @param c
 134  
      *            Class
 135  
      * @return Object
 136  
      */
 137  
     private Object createObjectOfType(final Class c) {
 138  240
         Object result = null;
 139  240
         final ArrayList possibleConstructors = new ArrayList();
 140  240
         final Constructor[] constructors = c.getConstructors();
 141  540
         for (int i = 0; i < constructors.length; ++i) {
 142  300
             final Constructor constructor = constructors[i];
 143  300
             if (dependencyManager.canConstructClass(c, constructor)) {
 144  220
                 possibleConstructors.add(constructor);
 145  
             }
 146  
         }
 147  
 
 148  240
         Constructor constructor = null;
 149  240
         if (possibleConstructors.size() == 1) {
 150  
             // only one possible constructor found, use that
 151  200
             constructor = (Constructor) possibleConstructors.get(possibleConstructors.size() - 1);
 152  40
         } else if (possibleConstructors.size() > 0) {
 153  
             // more than one possible constructor found... hmmn...
 154  
             // try and use default constructor
 155  
             // TODO something else
 156  10
             Constructor defaultConstructor = null;
 157  13
             for (final Iterator i = possibleConstructors.iterator(); i.hasNext();) {
 158  20
                 final Constructor cons = (Constructor) i.next();
 159  20
                 if (0 == cons.getParameterTypes().length) {
 160  10
                     constructor = cons;
 161  
                 }
 162  
             }
 163  
         }
 164  
 
 165  240
         if (null != constructor) {
 166  210
             result = construct(c, constructor);
 167  210
             add(result);
 168  
         }
 169  240
         return result;
 170  
     }
 171  
 
 172  
     /**
 173  
      * @param c
 174  
      *            Class
 175  
      * @param constructor
 176  
      *            Constructor
 177  
      * @return Object
 178  
      */
 179  
     private Object construct(final Class c, class="keyword">final Constructor constructor) {
 180  
         Object result;
 181  210
         final Class[] parameters = constructor.getParameterTypes();
 182  210
         final Object[] args = new Object[parameters.length];
 183  340
         for (int i = 0; i < parameters.length; ++i) {
 184  130
             args[i] = getInstance(parameters[i]);
 185  
         }
 186  210
         final StringBuffer sb = new StringBuffer();
 187  210
         sb.append("Constructing ").append(c.getName()).append("(");
 188  244
         for (int i = 0; i < args.length;) {
 189  130
             sb.append(args[i].toString());
 190  130
             ++i;
 191  130
             if (i < args.length) {
 192  10
                 sb.append(", ");
 193  
             }
 194  
         }
 195  210
         sb.append(")");
 196  210
         System.out.println(sb.toString());
 197  
         try {
 198  210
             result = constructor.newInstance(args);
 199  0
         } catch (IllegalArgumentException e) {
 200  0
             throw new RuntimeException(e);
 201  0
         } catch (InstantiationException e) {
 202  0
             throw new RuntimeException(e);
 203  0
         } catch (IllegalAccessException e) {
 204  0
             throw new RuntimeException(e);
 205  0
         } catch (InvocationTargetException e) {
 206  0
             throw new RuntimeException(e);
 207  189
         }
 208  210
         return result;
 209  
     }
 210  
 }

This report is generated by jcoverage, Maven and Maven JCoverage Plugin.