1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package net.mchaplin.ioc;
21
22 import java.lang.reflect.Constructor;
23 import java.lang.reflect.InvocationTargetException;
24 import java.lang.reflect.Method;
25 import java.util.Hashtable;
26 import java.util.Iterator;
27 import java.util.List;
28 import java.util.Map;
29 import java.util.Set;
30 import java.util.Vector;
31
32 import net.mchaplin.commons.StackTraceUtils;
33 import net.mchaplin.commons.WmindObject;
34 import net.mchaplin.ioc.component.ComponentFactoryI;
35 import net.mchaplin.ioc.component.ComponentI;
36 import net.mchaplin.ioc.exp.ContainerException;
37
38 /***
39 * Default, ready-to-use ContainerI implementation
40 * Provides Component registration & management
41 * services.
42 *
43 * @author mchaplin@users.sourceforge.net
44 *
45 * TODO Handle interfaces use in constructors
46 * TODO Move component lookup services to a ServiceLocator
47 *
48 * $Header:
49 * $Revision:
50 * $Date:
51 *
52 */
53 public class DefaultContainer extends WmindObject implements ContainerI {
54
55 /***
56 * container instance name
57 */
58 private String instanceName = "";
59
60 /*** Known containers */
61 private List<ContainerI> containers = null;
62 /***
63 * container parent instance
64 */
65 private ContainerI parent = null;
66 /***
67 * containers registering this container as parent
68 */
69 private transient ContainerI[] sons = null;
70
71 /***
72 * registered components in this container
73 */
74 private transient Map<String, List<ComponentI>> regTypes = null;
75
76 /***
77 * registered component factories in this container
78 */
79 private transient Map<String, List<ComponentFactoryI>> regTypesFact = null;
80
81 /***
82 * reference this container
83 */
84 public static final int HERE = 0;
85
86 /***
87 * reference this container parent
88 */
89 public static final int PARENT = 1;
90
91 /***
92 * reference this container sons
93 */
94 public static final int SONS = 2;
95
96 /***
97 * registered sons count
98 */
99 public transient int sonsCount = 0;
100
101 /***
102 * default lentgh for sons array
103 */
104 public static final int SONS_DEFAULT_LENTGH = 5;
105
106 /***
107 * Instanciate a container.
108 *
109 */
110 public DefaultContainer(String name) {
111 super();
112 log.info("Creating container [" + name + "]");
113 instanceName = name;
114 regTypes = new Hashtable<String, List<ComponentI>>();
115 regTypesFact = new Hashtable<String, List<ComponentFactoryI>>();
116 sons = new ContainerI[SONS_DEFAULT_LENTGH];
117 parent = this;
118
119
120 addComponentToContainer(this, "net.mchaplin.ioc.ContainerI");
121 }
122
123 /***
124 * Instanciate & register this container as child of another container
125 *
126 * @param parent
127 */
128 public DefaultContainer(ContainerI parent, String name) {
129 super();
130 log.info("Creating container [" + name + "] with parent [" + parent.getInstanceName() + "]");
131 instanceName = name;
132 this.setParent(parent);
133 sons = new ContainerI[SONS_DEFAULT_LENTGH];
134 parent.addSon(this);
135 regTypes = new Hashtable<String, List<ComponentI>>();
136 regTypesFact = new Hashtable<String, List<ComponentFactoryI>>();
137
138
139 addComponentToContainer(this, "net.mchaplin.ioc.ContainerI");
140 }
141
142
143
144 /***
145 * Register a Component into the Container
146 *
147 * @param component the component to register
148 */
149 public void registerComponentImplementation(Class component) {
150 this.registerComponentImplementation(component, "");
151
152 }
153
154 /***
155 * Register a Factory for later use.
156 *
157 * @param factory the factory to register
158 */
159 public void registerFactoryImplementation(Class factory) {
160 log.debug(METHOD_CALL+"registerFactoryImplementation("+factory.getName()+")");
161 Object instance = instanciateComponent(factory);
162 if (isInterfaceImplemented(factory, ComponentI.CMP_I)) {
163 addFactoryToContainer((ComponentFactoryI) instance, "");
164 } else {
165 log.warn("Factory ["+factory.getName()+"] does not implements ComponentI, registration skipped !");
166 }
167 }
168
169 /***
170 * Component registration. Will try a newInstance() call on it &
171 * register if not already present.
172 *
173 * @param component the component Class to register
174 * @param type optional, the type to register this instance as. If set, the
175 * Component will be registered under its fully qualified class
176 * name
177 */
178
179 public void registerComponentImplementation(Class component, String type) {
180
181 Object instance = instanciateComponent(component);
182
183 if (instance != null && isInterfaceImplemented(component, ComponentI.CMP_I)) {
184 ComponentI cmp = (ComponentI) instance;
185 cmp.setContainer(this);
186 addComponentToContainer(cmp, type);
187 }
188
189 }
190
191 /***
192 * Custom component registration. The factory will be instanciated through a
193 * Factory() Constructor. The component will then be instanciated
194 * through the Factory.retrieveInstance() method
195 *
196 * @param component the component to register
197 * @param factory the factory to register
198 *
199 * @see net.mchaplin.ioc.ContainerI#registerComponentImplementation(java.lang.Class,
200 * java.lang.Class)
201 */
202 public void registerComponentImplementation(Class component, Class factory) throws ContainerException {
203 this.registerComponentImplementation(component, factory, null);
204 }
205
206 /***
207 * Custom component registration. The factory will be instanciated through a
208 * Factory() Constructor. The component will then be instanciated
209 * through the Factory.retrieveInstance() method
210 *
211 * @param component the component to register
212 * @param factory the factory to register
213 * @param type the type to register this instance as. If set, the
214 * Component will be registered under its fully qualified class
215 * name
216 *
217 * @see net.mchaplin.ioc.ContainerI#registerComponentImplementation(java.lang.Class,
218 * java.lang.Class)
219 */
220 public void registerComponentImplementation(Class component, Class factory, String type) throws ContainerException {
221
222
223 if (lookupComponent(component) == null) {
224 ComponentFactoryI oFactory = null;
225 String sFactoryType = null;
226 Object oComponent = null;
227 Method method = null;
228
229
230 String sLocation = lookupComponent(factory);
231 if (sLocation == null) {
232
233 this.registerFactoryImplementation(factory);
234 }
235
236 oFactory = retrieveFactoryInstance(factory);
237 sFactoryType = oFactory.toString().substring(6);
238
239 try {
240 method = oFactory.getClass().getDeclaredMethod("retrieveInstance", (Class[]) null);
241 oComponent = method.invoke(oFactory, (Object[]) null);
242 } catch (IllegalArgumentException e) {
243 StackTraceUtils.printExtendedStackTrace("IllegalArgumentException thrown while instanciating : ", component, e);
244 throw new ContainerException(e.getCause());
245 } catch (NoSuchMethodException e) {
246 StackTraceUtils.printExtendedStackTrace("NoSuchMethodException thrown while instanciating : ", component, e);
247 throw new ContainerException(e.getCause());
248 } catch (IllegalAccessException e) {
249 StackTraceUtils.printExtendedStackTrace("IllegalAccessException thrown while instanciating : ", component, e);
250 throw new ContainerException(e.getCause());
251 } catch (InvocationTargetException e) {
252 StackTraceUtils.printExtendedStackTrace("InvocationTargetException thrown while instanciating : ", component, e);
253 throw new ContainerException(e.getCause());
254 }
255 addComponentToContainer((ComponentI) oComponent, type);
256
257 } else {
258 log.info("Component : "+component.getClass()+" is already registered");
259 }
260 }
261
262 /***
263 * Instanciate a component. Constructor dependencies
264 * are looked up inside the container hierarchy.
265 *
266 * @param component the component to instanciate
267 * @return an instance of component
268 */
269 private Object instanciateComponent(Class component) {
270
271 boolean emtyCnstr = false;
272 String constrLoc = null;
273 int params = 0;
274 Constructor curConstr = null;
275 Constructor targetConstr = null;
276
277
278 Class[] constrParams = null;
279 Class curParam = null;
280 Object instance = null;
281
282 Constructor[] cmpConstr = component.getDeclaredConstructors();
283
284
285 for (int i = 0; i < cmpConstr.length; i++) {
286 curConstr = cmpConstr[i];
287 constrParams = curConstr.getParameterTypes();
288
289 if (constrParams.length != 0) {
290 log.debug("Introspecting a " + constrParams.length + " parameters Constructor");
291
292 for (int j = 0; j < constrParams.length; j++) {
293 curParam = constrParams[j];
294 constrLoc = this.lookupComponent(curParam);
295
296
297 if (constrLoc == null) {
298 constrLoc = this.getParent().lookupComponent(curParam);
299 }
300 }
301
302 if (constrLoc != null && constrParams.length > params) {
303 params = constrParams.length;
304 targetConstr = curConstr;
305 }
306 } else {
307 emtyCnstr = true;
308 }
309 }
310 if (!emtyCnstr && targetConstr != null) {
311 instance = parameterizedConstructorInstanciation(targetConstr);
312 } else {
313 instance = emptyConstructorInstanciation(component);
314 }
315
316 return instance;
317 }
318
319 /***
320 * @param component
321 * @param instance
322 * @return
323 */
324 private Object emptyConstructorInstanciation(Class component) {
325 Object instance = null;
326 try {
327 instance = component.newInstance();
328 } catch (InstantiationException e) {
329 log.error("InstantiationException thrown while instanciating : " + component.toString().substring(6));
330 log.error(WmindObject.EX_CAUSE);
331 StackTraceUtils.printStackTrace(e.getCause());
332 log.error(WmindObject.EX_STACK);
333 } catch (IllegalAccessException e) {
334 log.error("IllegalAccessException thrown while instanciating : " + component.toString().substring(6));
335 StackTraceUtils.printStackTrace(e);
336 }
337
338 return instance;
339 }
340
341 /***
342 * @param component
343 * @param curConstructor
344 * @param constr
345 * @param instance
346 * @return
347 */
348 private Object parameterizedConstructorInstanciation(Constructor constr) {
349 Class[] cnstrPrms = null;
350 Object[] oParams = null;
351 Object instance = null;
352
353
354
355
356 cnstrPrms = constr.getParameterTypes();
357 oParams = new Object[cnstrPrms.length];
358 for (int k = 0; k < cnstrPrms.length; k++) {
359 oParams[k] = this.retrieveComponentInstance(cnstrPrms[k]);
360 }
361 try {
362 instance = constr.newInstance(oParams);
363 } catch (IllegalArgumentException e) {
364 log.error("IllegalArgumentException thrown while instanciating : " + constr.getName());
365 StackTraceUtils.printStackTrace(e);
366 } catch (InstantiationException e) {
367 log.error(WmindObject.EX_CAUSE);
368 StackTraceUtils.printStackTrace(e.getCause());
369 log.error(WmindObject.EX_STACK);
370 log.error("InstantiationException thrown while instanciating : " + constr.getName());
371 StackTraceUtils.printStackTrace(e);
372 } catch (IllegalAccessException e) {
373 log.error("IllegalAccessException thrown while instanciating : " + constr.getName());
374 StackTraceUtils.printStackTrace(e);
375 } catch (InvocationTargetException e) {
376 log.error("InvocationTargetException thrown while instanciating : " + constr.getName());
377 log.error(WmindObject.EX_CAUSE);
378 StackTraceUtils.printStackTrace(e.getCause());
379 log.error(WmindObject.EX_STACK);
380 StackTraceUtils.printStackTrace(e);
381 }
382 return instance;
383 }
384
385 /***
386 * Recursively check in a class implements
387 * a given interface
388 *
389 * @param component the class to introspect
390 * @param name the interface fully-qualified name to look for
391 * @return
392 */
393 private boolean isInterfaceImplemented(Class component, String name) {
394 log.debug(METHOD_CALL+"isInterfaceImplemented("+component.getName()+", "+name+")");
395 boolean found = false;
396 Class[] interfaces = null;
397
398
399 if (component.getInterfaces().length != 0) {
400 interfaces = component.getInterfaces();
401 found = introspectInterfaces(interfaces, name);
402
403 } else {
404 log.debug("Class : "+component.getName()+" has no interfaces.");
405 }
406
407
408 while (!found && component.getSuperclass() != null) {
409 if (component.getSuperclass().getInterfaces().length != 0) {
410 interfaces = component.getSuperclass().getInterfaces();
411 found = introspectInterfaces(interfaces, name);
412 }
413
414 component = component.getSuperclass();
415 }
416
417 if (found) {
418 log.debug("Class ["+component.getName()+"] implements ["+name+"]");
419 } else {
420 log.debug("Class ["+component.getName()+"] does not implements ["+name+"]");
421 }
422
423 return found;
424 }
425
426 /***
427 * @param component
428 * @param name
429 * @param found
430 * @param ct
431 * @return
432 */
433 private boolean introspectInterfaces(Class[] interfaces, String name) {
434
435 boolean found = false;
436 int ct = 0;
437 Class curInterface = null;
438
439 while (!found && ct<interfaces.length) {
440 curInterface = interfaces[ct];
441
442 if (curInterface.getName().equals(name)) {
443 found = true;
444 }
445
446 if (!found) {
447 isInterfaceImplemented(curInterface, name);
448 }
449 ct++;
450 }
451 return found;
452 }
453
454 /***
455 * Add an instance of ComponentI to this Container
456 *
457 * @param oComponent the component to add to this container
458 * @param type optionnal, the type to register this component as
459 */
460 private void addComponentToContainer(ComponentI oComponent, String type) {
461 String cmpName = null;
462 List<ComponentI> lInstances = null;
463 if (oComponent != null) {
464 if (type != null && !type.equals("")) {
465 cmpName = type;
466 } else {
467 cmpName = oComponent.getClass().getName();
468 }
469 log.info("Adding component : [" + cmpName + "] to container ["+this.instanceName+"]");
470
471 if (regTypes.containsKey(cmpName)) {
472 lInstances = regTypes.get(cmpName);
473 } else {
474 lInstances = new Vector<ComponentI>();
475 }
476 lInstances.add(oComponent);
477 this.regTypes.put(cmpName, lInstances);
478 log.debug("Component registered under name : " + cmpName);
479 }
480 }
481
482 /***
483 * Add an instance of ComponentFactoryI to this Container
484 *
485 * @param oComponent the component to add to this container
486 * @param type optionnal, the type to register this component as
487 */
488 private void addFactoryToContainer(ComponentFactoryI oComponent, String type) {
489 String cmpName = null;
490 if (oComponent != null) {
491 cmpName = oComponent.getClass().getName();
492 log.debug("Adding factory : [" + cmpName + "] to container ["+this.instanceName+"]");
493 List<ComponentFactoryI> lInstances = new Vector<ComponentFactoryI>();
494 lInstances.add(oComponent);
495 if (type != null && !type.equals("")) {
496 log.debug("Factory registered under name : " + type);
497 this.regTypesFact.put(type, lInstances);
498 } else {
499 this.regTypesFact.put(cmpName, lInstances);
500 }
501 }
502 }
503
504 public void registerComponentInstance(ComponentI instance) {
505 addComponentToContainer(instance, instance.getClass().getName());
506 }
507
508 public void registerComponentInstance(ComponentI instance, String key) {
509 addComponentToContainer(instance, key);
510 }
511
512
513
514 /***
515 * Retrieve the first instance in List of given type.
516 *
517 * @param classType the Class type to retrieve an instance of.
518 * @return an instance of ComponentI, whose Class match classType
519 */
520 public ComponentI retrieveComponentInstance(Class classType) {
521 String key = classType.getName();
522 return retrieveComponentInstance(key, null);
523 }
524
525 /***
526 * Retrieve the first instance in List of given type.
527 *
528 * @param key the component type to retrieve an instance of
529 * @return an instance of ComponentI, whose full name match key
530 */
531 public ComponentI retrieveComponentInstance(String key) {
532 return retrieveComponentInstance(key, null);
533 }
534
535 /***
536 * Retrieve the first instance in List of given type.
537 *
538 * @param key the component type to retrieve an instance of
539 * @param location the location of the container where the component
540 * should be retrieved from.
541 * @return an instance of ComponentI, whose full name match key
542 */
543 public ComponentI retrieveComponentInstance(String key, String location) {
544
545 ComponentI oComponent = null;
546 ContainerI[] arrSon = null;
547 ContainerI curSon = null;
548 Vector lObjects = null;
549 boolean found = false;
550 int i=0;
551 int ct=0;
552
553 if (this.regTypes.containsKey(key)) {
554 lObjects = (Vector) this.regTypes.get(key);
555 oComponent = (ComponentI) lObjects.firstElement();
556
557 } else if (this.getParent() != null && this.getParent().getRegisteredTypes().containsKey(key)) {
558 lObjects = (Vector) this.getParent().getRegisteredTypes().get(key);
559 oComponent = (ComponentI) lObjects.firstElement();
560 } else {
561
562 arrSon = parent.getSons();
563 ct = arrSon.length;
564 while (!found && i<ct) {
565 if (arrSon[i] != null) {
566 curSon = arrSon[i];
567 if (curSon.getRegisteredTypes().containsKey(key)) {
568 lObjects = (Vector) curSon.getRegisteredTypes().get(key);
569 oComponent = (ComponentI) lObjects.firstElement();
570 found = true;
571 }
572 }
573 i++;
574 }
575 }
576 if (oComponent == null) {
577 log.warn("Container does not contain objects of type : [" + key + "]");
578 }
579 return oComponent;
580 }
581 /***
582 * Retrieve the first instance in List of given type.
583 *
584 * @param classType the Class type to retrieve an instance of.
585 * @return an instance of ComponentI, whose Class match classType
586 */
587 public ComponentFactoryI retrieveFactoryInstance(Class classType) {
588 String key = classType.getName();
589 return retrieveFactoryInstance(key);
590 }
591
592 /***
593 * Retrieve the first instance in List of given type.
594 *
595 * @param key the key to retrieve associated Factory instance.
596 * @return an instance of ComponentI, whose full name match key
597 */
598 public ComponentFactoryI retrieveFactoryInstance(String key) {
599
600 ComponentFactoryI oComponent = null;
601 Vector lObjects = null;
602
603 if (this.regTypesFact.containsKey(key)) {
604 lObjects = (Vector) this.regTypesFact.get(key);
605 oComponent = (ComponentFactoryI) lObjects.firstElement();
606
607 } else if (this.regTypes.containsKey(key)) {
608 lObjects = (Vector) this.regTypes.get(key);
609 oComponent = (ComponentFactoryI) lObjects.firstElement();
610 } else {
611 log.warn("Container does not contain objects of type : [" + key + "]");
612 }
613 return oComponent;
614 }
615
616 /***
617 * Retrieve a list of registered components for the given key
618 *
619 */
620 public List retrieveComponentInstances(String key) {
621 List ret = null;
622 if (regTypes.containsKey(key)) {
623 ret = (List) regTypes.get(key);
624 } else {
625 log.warn("Container does not contain objects of type : [" + key + "]");
626 }
627 return ret;
628 }
629
630 /***
631 * Retrieve a list of all registered components
632 *
633 */
634 public void retrieveComponentInstances() {
635
636 }
637
638 /***
639 * Gives back a Component when you stop using it.
640 * TODO : manage component lock/unlock mode
641 *
642 */
643 public void makeComponentAvailable() {
644
645 }
646
647 public void unregisterComponentInstance(ComponentI instance) {
648
649 }
650
651
652
653 /***
654 * @see net.mchaplin.ioc.ComponentI#getContainer()
655 */
656 public ContainerI getContainer() {
657 return this;
658 }
659
660
661 /***
662 * Lookup for to see if a given component is currently registered in this
663 * Container, its parent or sons. Use if you have no knowledge of where the
664 * component is located
665 *
666 * @param classType
667 * the Class type to lookup for.
668 * @return the name of the container where a Component instance has been
669 * found or null.
670 */
671 public String lookupComponent(Class classType) {
672
673
674 String location = null;
675 boolean found = false;
676 ContainerI curSon = null;
677
678
679
680 if (this.regTypes.containsKey(classType.getName())) {
681 location = this.getInstanceName();
682 } else if (this.getParent() != null && this.getParent().getRegisteredTypes().containsKey(classType.getName())) {
683 location = this.getParent().getInstanceName();
684 } else {
685 int i = 0;
686 while (!found && i < sons.length) {
687 curSon = sons[i];
688 if (curSon != null && curSon.getRegisteredTypes().containsKey(classType.getName())) {
689 found = true;
690 location = curSon.getInstanceName();
691 }
692 i++;
693 }
694 if (!found) {
695 log.debug("Component " + classType.getName() + " lookup failed.");
696 }
697 }
698 if (location != null) {
699 log.debug("Component location : " + location);
700 }
701 return location;
702 }
703
704 /***
705 * Lookup for to see if a given component is currently registered.
706 *
707 *
708 * @param classType the Class type to lookup for.
709 * @param where where to lookup the component : here, parent or sons
710 *
711 * @return the name of the container where a Component instance has been
712 * found or null.
713 */
714 public String lookupComponent(Class classType, int where) {
715 String location = null;
716 boolean found = false;
717 ContainerI curSon = null;
718 switch (where) {
719 case HERE:
720 if (this.regTypes.containsKey(classType.getName())) {
721 location = this.getInstanceName();
722 }
723 break;
724
725 case PARENT:
726 if (this.getParent() != null && this.getParent().getRegisteredTypes().containsKey(classType.getName())) {
727 location = this.getParent().getInstanceName();
728 }
729 break;
730
731 case SONS:
732 int i = 0;
733 while (!found && i < sons.length) {
734 curSon = sons[i];
735 if (curSon.getRegisteredTypes().containsKey(classType.getName())) {
736 found = true;
737 location = curSon.getInstanceName();
738 }
739 i++;
740 }
741 break;
742
743 default:
744 location = lookupComponent(classType);
745 break;
746 }
747
748 return location;
749 }
750
751 /***
752 * @return Returns the containers.
753 */
754 public List<ContainerI> getContainers() {
755 return containers;
756 }
757 /***
758 * @param containers The containers to set.
759 */
760 public void setContainers(List<ContainerI> containers) {
761 this.containers = containers;
762 }
763
764 /***
765 * @return Returns the instanceName.
766 */
767 public String getInstanceName() {
768 return instanceName;
769 }
770
771 /***
772 * @param instanceName
773 * The instanceName to set.
774 */
775 public void setInstanceName(String instanceName) {
776 this.instanceName = instanceName;
777 }
778
779 /***
780 *
781 * @see net.mchaplin.ioc.ContainerI#getParent()
782 */
783 public ContainerI getParent() {
784 return this.parent;
785 }
786
787 /***
788 *
789 * @see net.mchaplin.ioc.ContainerI#setParent(net.mchaplin.ioc.ContainerI)
790 */
791 public final void setParent(ContainerI aParent) {
792 this.parent = aParent;
793 }
794
795
796
797 /***
798 * @return Returns the registeredTypes.
799 */
800 public Map<String,List<ComponentI>> getRegisteredTypes() {
801 return regTypes;
802 }
803
804 /***
805 * @return Returns the sons.
806 */
807 public ContainerI[] getSons() {
808 return sons;
809 }
810
811 /***
812 * Return the current state of a Container instance, as formatted text.
813 *
814 * @return the current Container State as formatted text.
815 */
816 public String getState() {
817 StringBuffer state = new StringBuffer();
818 Iterator it = null;
819 Set kSet = null;
820 ContainerI curSon = null;
821
822 state.append("Container : [").append(this.getInstanceName()).append("] has parent [");
823 state.append(this.parent != null && this.parent.getInstanceName() != null ? this.parent.getInstanceName() : "").append("]").append(
824 " \n");
825
826 if (regTypes.isEmpty()) {
827 state.append("Container is empty.");
828 } else {
829 kSet = regTypes.keySet();
830 it = kSet.iterator();
831 state.append("Registered types : \n");
832 while (it.hasNext()) {
833 state.append("\t -> [").append((String) it.next()).append("]").append("\n");
834 }
835
836 }
837 state.append("Registered sons : \n");
838 if (this.sons != null) {
839 for (int i = 0; i < sonsCount; i++) {
840 curSon = sons[i];
841 state.append("\t -> [").append(curSon.getInstanceName()).append("]").append("\n");
842 }
843 }
844
845 return state.toString();
846 }
847
848 /***
849 * @return Returns the sons.
850 */
851 public void addSon(ContainerI container) {
852 ContainerI[] bigger = null;
853 if (sonsCount < SONS_DEFAULT_LENTGH) {
854 sons[sonsCount] = container;
855 } else {
856
857 bigger = new ContainerI[sonsCount + 1];
858 for (int i = 0; i < sons.length; i++) {
859 bigger[i] = sons[i];
860 }
861 bigger[sonsCount] = container;
862 sons = bigger;
863 }
864 log.info(container.getInstanceName() + " registered as son of " + this.instanceName);
865 sonsCount++;
866 }
867
868
869 /***
870 * @see net.mchaplin.ioc.component.ComponentI#setContainer(net.mchaplin.ioc.ContainerI)
871 */
872 public void setContainer(ContainerI container) {
873 setParent(container);
874 }
875 /***
876 * @see net.mchaplin.ioc.ComponentI#reset()
877 */
878 public void reset() {
879 regTypes = null;
880 regTypesFact = null;
881 sons = null;
882 }
883 }