View Javadoc

1   /*
2    * Created on May 22, 2005
3    *
4    * Default implementation of net.sf.tlc.ioc.DependencyManager.
5    */
6   package net.sf.tlc.ioc.impl;
7   
8   import java.lang.reflect.Constructor;
9   import java.util.ArrayList;
10  import java.util.Iterator;
11  import java.util.LinkedHashSet;
12  import java.util.Set;
13  
14  import net.sf.tlc.util.ClassUtils;
15  
16  /***
17   * Default implementation of net.sf.tlc.ioc.DependencyManager.
18   * 
19   * @author aisrael
20   */
21  public final class DefaultDependencyManager implements DependencyManager {
22  
23      private final Set classes = new LinkedHashSet();
24  
25      /***
26       * (non-Javadoc)
27       * 
28       * @see net.sf.tlc.ioc.impl.DependencyManager#registerClass(java.lang.Class)
29       */
30      public void registerClass(final Class c) {
31          classes.add(c);
32      }
33  
34      /***
35       * (non-Javadoc)
36       * 
37       * @see net.sf.tlc.ioc.impl.DependencyManager#hasClass(java.lang.Class)
38       */
39      public boolean hasClass(final Class c) {
40          return classes.contains(c);
41      }
42  
43      /***
44       * (non-Javadoc)
45       * 
46       * @see net.sf.tlc.ioc.impl.DependencyManager#canConstructClass(java.lang.Class,
47       *      java.lang.reflect.Constructor)
48       */
49      public boolean canConstructClass(final Class c, final Constructor constructor) {
50          final Class[] parameters = constructor.getParameterTypes();
51          boolean result;
52          if (0 == parameters.length) {
53              result = true;
54          } else {
55              result = true;
56              for (int i = 0; i < parameters.length; ++i) {
57                  if (c != parameters[i]) {
58                      boolean canConstructParameter = false;
59                      final Class[] candidateDependencies = listAllFulfillingClasses(parameters[i]);
60                      for (int j = 0; j < candidateDependencies.length; ++j) {
61                          if (candidateDependencies[j] != c) {
62                              canConstructParameter = canConstructParameter
63                                      || hasClass(candidateDependencies[j])
64                                      || canConstructClass(candidateDependencies[j]);
65                          }
66                      }
67                      result = result && canConstructParameter;
68                  }
69              }
70          }
71          return result;
72      }
73  
74      /***
75       * @param c
76       *            Class
77       * @return Class[]
78       */
79      private Class[] listAllFulfillingClasses(final Class c) {
80          final ArrayList result = new ArrayList();
81          for (final Iterator i = classes.iterator(); i.hasNext();) {
82              final Class d = (Class) i.next();
83  
84              if ((d == c) || ClassUtils.listAllInterfaces(d).contains(c)
85                      || ClassUtils.listAllSuperClasses(d).contains(c)) {
86                  result.add(d);
87              }
88          }
89          return (Class[]) result.toArray(new Class[0]);
90      }
91  
92      /***
93       * (non-Javadoc)
94       * 
95       * @see net.sf.tlc.ioc.impl.DependencyManager#canConstructClass(java.lang.Class)
96       */
97      public boolean canConstructClass(final Class c) {
98          boolean result = false;
99          final Constructor[] constructors = c.getDeclaredConstructors();
100         for (int i = 0; i < constructors.length; ++i) {
101             result = result || canConstructClass(c, constructors[i]);
102         }
103         return result;
104     }
105 
106     /***
107      * (non-Javadoc)
108      * 
109      * @see net.sf.tlc.ioc.impl.DependencyManager#listAllImplementingClasses(java.lang.Class)
110      */
111     public Class[] listAllImplementingClasses(final Class c) {
112         final ArrayList list = new ArrayList();
113 
114         for (final Iterator i = classes.iterator(); i.hasNext();) {
115             final Class d = (Class) i.next();
116             if (c.isAssignableFrom(d) && !(ClassUtils.isAbstractClass(d) || d.isInterface())) {
117                 list.add(d);
118             }
119         }
120 
121         return (Class[]) list.toArray(new Class[0]);
122     }
123 }