View Javadoc

1   /*
2    * Created on 1 janv. 2005
3    *
4    * This program is free software; you can redistribute it and/or
5    * modify it under the terms of the GNU General Public License
6    * as published by the Free Software Foundation; either version 2
7    * of the License, or (at your option) any later version.
8    *
9    * This program is distributed in the hope that it will be useful,
10   * but WITHOUT ANY WARRANTY; without even the implied warranty of
11   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12   * GNU General Public License for more details.
13   * 
14   * Full GNU GPL license terms : http://www.fsf.org/licenses/gpl.txt
15   * 
16   * Author : mchaplin@users.sourceforge.net
17   */
18  package net.mchaplin.ioc.component;
19  
20  import java.lang.reflect.Constructor;
21  import java.lang.reflect.InvocationTargetException;
22  
23  import org.apache.commons.logging.Log;
24  import org.apache.commons.logging.LogFactory;
25  
26  import net.mchaplin.commons.StackTraceUtils;
27  import net.mchaplin.commons.WmindObject;
28  import net.mchaplin.ioc.ContainerI;
29  
30  /***
31   * Delegate class for components instanciation
32   * 
33   * @author mchaplin@users.sourceforge.net
34   * 
35   * $Header$Revision$Date:
36   */
37  public class DefaultComponentFactory implements ComponentI {
38      
39      protected transient ContainerI container;
40      protected static Log log = LogFactory.getLog(DefaultComponentFactory.class);
41      
42      public DefaultComponentFactory(ContainerI aContainer) {
43          container = aContainer;
44      }
45      
46      /***
47       * Instanciate a component. Constructor dependencies
48       * are looked up inside the container hierarchy.
49       * 
50       * @param component the component to instanciate
51       * @return an instance of component
52       */
53      private Object instanciateComponent(Class component) {
54  
55          boolean emtyCnstr = false;
56          String constrLoc = null;
57          int params = 0;
58          Constructor curConstr = null;
59          Constructor targetConstr = null; // the constructor that will be
60                                                // used for this component
61                                                // instanciation
62          Class[] constrParams = null;
63          Class curParam = null;
64          Object instance = null;
65  
66          Constructor[] cmpConstr = component.getDeclaredConstructors();
67  
68          // introspect object constructors : for each constructor
69          for (int i = 0; i < cmpConstr.length; i++) {
70              curConstr = cmpConstr[i];
71              constrParams = curConstr.getParameterTypes();
72              // if it's not an empty parameter one
73              if (constrParams.length != 0) {
74                  log.debug("Introspecting a " + constrParams.length + " parameters Constructor");
75                  // check if the container knows about constructor parameter types
76                  for (int j = 0; j < constrParams.length; j++) {
77                      curParam = constrParams[j];
78                      constrLoc = container.lookupComponent(curParam);
79                      // if not found, check if the parent container knows about
80                      // constructor parameter types
81                      if (constrLoc == null) {
82                          constrLoc = container.getParent().lookupComponent(curParam);
83                      }
84                  }
85                  // check if this is the biggest constructor we know
86                  if (constrLoc != null && constrParams.length > params) {
87                      params = constrParams.length;
88                      targetConstr = curConstr;
89                  }
90              } else {
91                  emtyCnstr = true;
92              }
93          }
94          if (!emtyCnstr && targetConstr != null) {
95              instance = parameterizedConstructorInstanciation(targetConstr);
96          } else { // the component has an empty constructor only.
97              instance = emptyConstructorInstanciation(component);
98          }
99  
100         return instance;
101     }
102     
103     /***
104      * @param component
105      * @param instance
106      * @return
107      */
108     private Object emptyConstructorInstanciation(Class component) {
109         Object instance = null;
110         try {
111             instance = component.newInstance();
112         } catch (InstantiationException e) {
113             log.error("InstantiationException thrown while instanciating : " + component.toString().substring(6));
114             log.error(WmindObject.EX_CAUSE);
115             StackTraceUtils.printStackTrace(e.getCause());
116             log.error(WmindObject.EX_STACK);
117         } catch (IllegalAccessException e) {
118             log.error("IllegalAccessException thrown while instanciating : " + component.toString().substring(6));
119             StackTraceUtils.printStackTrace(e);
120         }
121         
122         return instance;
123     }
124 
125     /***
126      * @param component
127      * @param curConstructor
128      * @param constr
129      * @param instance
130      * @return
131      */
132     private Object parameterizedConstructorInstanciation(Constructor constr) {
133         Class[] cnstrPrms = null;
134         Object[] oParams = null;
135         Object instance = null;
136         /* instanciate the component, injecting instances from container
137          * into constructor 
138          */ 
139         
140         cnstrPrms = constr.getParameterTypes();
141         oParams = new Object[cnstrPrms.length];
142         for (int k = 0; k < cnstrPrms.length; k++) {
143             oParams[k] = container.retrieveComponentInstance(cnstrPrms[k]);
144         }
145         try {
146             instance = constr.newInstance(oParams);
147         } catch (IllegalArgumentException e) {
148             log.error("IllegalArgumentException thrown while instanciating : " + constr.getName());
149             StackTraceUtils.printStackTrace(e);
150         } catch (InstantiationException e) {
151             log.error(WmindObject.EX_CAUSE);
152             StackTraceUtils.printStackTrace(e.getCause());
153             log.error(WmindObject.EX_STACK);
154             log.error("InstantiationException thrown while instanciating : " +  constr.getName());
155             StackTraceUtils.printStackTrace(e);
156         } catch (IllegalAccessException e) {
157             log.error("IllegalAccessException thrown while instanciating : " +  constr.getName());
158             StackTraceUtils.printStackTrace(e);
159         } catch (InvocationTargetException e) {
160             log.error("InvocationTargetException thrown while instanciating : " +  constr.getName());
161             log.error(WmindObject.EX_CAUSE);
162             StackTraceUtils.printStackTrace(e.getCause());
163             log.error(WmindObject.EX_STACK);
164             StackTraceUtils.printStackTrace(e);
165         }
166         return instance;
167     }
168 
169     /* (non-Javadoc)
170      * @see net.mchaplin.container.component.ComponentI#getContainer()
171      */
172     public ContainerI getContainer() {
173         // TODO Auto-generated method stub
174         return null;
175     }
176 
177     /* (non-Javadoc)
178      * @see net.mchaplin.container.component.ComponentI#reset()
179      */
180     public void reset() {
181         // TODO Auto-generated method stub
182         
183     }
184 
185     /* (non-Javadoc)
186      * @see net.mchaplin.container.component.ComponentI#setContainer(net.mchaplin.container.ContainerI)
187      */
188     public void setContainer(ContainerI container) {
189         // TODO Auto-generated method stub
190         
191     }
192     
193     
194 
195 }