KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > picocontainer > defaults > InstantiatingComponentAdapter


1 /*****************************************************************************
2  * Copyright (C) PicoContainer Organization. All rights reserved. *
3  * ------------------------------------------------------------------------- *
4  * The software in this package is published under the terms of the BSD *
5  * style license a copy of which has been included with this distribution in *
6  * the LICENSE.txt file. *
7  * *
8  * Original code by *
9  *****************************************************************************/

10 package org.picocontainer.defaults;
11
12 import org.picocontainer.Parameter;
13 import org.picocontainer.PicoContainer;
14 import org.picocontainer.PicoIntrospectionException;
15 import org.picocontainer.PicoVisitor;
16
17 import java.lang.reflect.Constructor JavaDoc;
18 import java.lang.reflect.InvocationTargetException JavaDoc;
19 import java.lang.reflect.Modifier JavaDoc;
20
21 /**
22  * This ComponentAdapter will instantiate a new object for each call to
23  * {@link org.picocontainer.ComponentAdapter#getComponentInstance(PicoContainer)}.
24  * That means that when used with a PicoContainer, getComponentInstance will
25  * return a new object each time.
26  *
27  * @author Aslak Hellesøy
28  * @author Paul Hammant
29  * @author Jörg Schaible
30  * @version $Revision: 1820 $
31  * @since 1.0
32  */

33 public abstract class InstantiatingComponentAdapter extends AbstractComponentAdapter {
34     /** The cycle guard for the verification. */
35     protected transient Guard verifyingGuard;
36     /** The parameters to use for initialization. */
37     protected transient Parameter[] parameters;
38     /** Flag indicating instanciation of non-public classes. */
39     protected boolean allowNonPublicClasses;
40     
41     protected static abstract class Guard extends ThreadLocalCyclicDependencyGuard {
42         protected PicoContainer guardedContainer;
43         protected void setArguments(PicoContainer container) {
44             this.guardedContainer = container;
45         }
46     }
47
48     /**
49      * Constructs a new ComponentAdapter for the given key and implementation.
50      * @param componentKey the search key for this implementation
51      * @param componentImplementation the concrete implementation
52      * @param parameters the parameters to use for the initialization
53      * @param allowNonPublicClasses flag to allow instantiation of non-public classes.
54      * @throws AssignabilityRegistrationException if the key is a type and the implementation cannot be assigned to.
55      * @throws NotConcreteRegistrationException if the implementation is not a concrete class.
56      */

57     protected InstantiatingComponentAdapter(Object JavaDoc componentKey, Class JavaDoc componentImplementation, Parameter[] parameters, boolean allowNonPublicClasses) {
58         super(componentKey, componentImplementation);
59         checkConcrete();
60
61         this.parameters = parameters;
62         this.allowNonPublicClasses = allowNonPublicClasses;
63     }
64
65     private void checkConcrete() throws NotConcreteRegistrationException {
66         // Assert that the component class is concrete.
67
boolean isAbstract = (getComponentImplementation().getModifiers() & Modifier.ABSTRACT) == Modifier.ABSTRACT;
68         if (getComponentImplementation().isInterface() || isAbstract) {
69             throw new NotConcreteRegistrationException(getComponentImplementation());
70         }
71     }
72
73     /**
74      * Create default parameters for the given types.
75      *
76      * @param parameters the parameter types
77      * @return the array with the default parameters.
78      */

79     protected Parameter[] createDefaultParameters(Class JavaDoc[] parameters) {
80         Parameter[] componentParameters = new Parameter[parameters.length];
81         for (int i = 0; i < parameters.length; i++) {
82             componentParameters[i] = ComponentParameter.DEFAULT;
83         }
84         return componentParameters;
85     }
86
87     public void verify(final PicoContainer container) throws PicoIntrospectionException {
88         if (verifyingGuard == null) {
89             verifyingGuard = new Guard() {
90                 public Object JavaDoc run() {
91                     final Constructor JavaDoc constructor = getGreediestSatisfiableConstructor(guardedContainer);
92                     final Class JavaDoc[] parameterTypes = constructor.getParameterTypes();
93                     final Parameter[] currentParameters = parameters != null ? parameters : createDefaultParameters(parameterTypes);
94                     for (int i = 0; i < currentParameters.length; i++) {
95                         currentParameters[i].verify(container, InstantiatingComponentAdapter.this, parameterTypes[i]);
96                     }
97                     return null;
98                 }
99             };
100         }
101         verifyingGuard.setArguments(container);
102         verifyingGuard.observe(getComponentImplementation());
103     }
104
105     public void accept(PicoVisitor visitor) {
106         super.accept(visitor);
107         if (parameters != null) {
108             for (int i = 0; i < parameters.length; i++) {
109                 parameters[i].accept(visitor);
110             }
111         }
112     }
113     
114     /**
115      * Instantiate an object with given parameters and respect the accessible flag.
116      *
117      * @param constructor the constructor to use
118      * @param parameters the parameters for the constructor
119      * @return the new object.
120      * @throws InstantiationException
121      * @throws IllegalAccessException
122      * @throws InvocationTargetException
123      */

124     protected Object JavaDoc newInstance(Constructor JavaDoc constructor, Object JavaDoc[] parameters) throws InstantiationException JavaDoc, IllegalAccessException JavaDoc, InvocationTargetException JavaDoc {
125         if (allowNonPublicClasses) {
126             constructor.setAccessible(true);
127         }
128         return constructor.newInstance(parameters);
129     }
130
131     /**
132      * Find and return the greediest satisfiable constructor.
133      *
134      * @param container the PicoContainer to resolve dependencies.
135      * @return the found constructor.
136      * @throws PicoIntrospectionException
137      * @throws UnsatisfiableDependenciesException
138      * @throws AmbiguousComponentResolutionException
139      * @throws AssignabilityRegistrationException
140      * @throws NotConcreteRegistrationException
141      */

142     protected abstract Constructor JavaDoc getGreediestSatisfiableConstructor(PicoContainer container) throws PicoIntrospectionException, UnsatisfiableDependenciesException, AmbiguousComponentResolutionException, AssignabilityRegistrationException, NotConcreteRegistrationException;
143 }
144
Popular Tags