KickJava   Java API By Example, From Geeks To Geeks.

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


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.ComponentAdapter;
13 import org.picocontainer.Parameter;
14 import org.picocontainer.PicoContainer;
15 import org.picocontainer.PicoInstantiationException;
16 import org.picocontainer.PicoIntrospectionException;
17 import org.picocontainer.PicoVisitor;
18
19 import java.io.Serializable JavaDoc;
20 import java.lang.reflect.Field JavaDoc;
21 import java.util.Arrays JavaDoc;
22 import java.util.HashSet JavaDoc;
23 import java.util.List JavaDoc;
24 import java.util.Iterator JavaDoc;
25
26 /**
27  * A BasicComponentParameter should be used to pass in a particular component as argument to a
28  * different component's constructor. This is particularly useful in cases where several
29  * components of the same type have been registered, but with a different key. Passing a
30  * ComponentParameter as a parameter when registering a component will give PicoContainer a hint
31  * about what other component to use in the constructor. This Parameter will never resolve
32  * against a collecting type, that is not directly registered in the PicoContainer itself.
33  *
34  * @author Jon Tirsén
35  * @author Aslak Hellesøy
36  * @author Jörg Schaible
37  * @author Thomas Heller
38  * @version $Revision: 1944 $
39  */

40 public class BasicComponentParameter
41         implements Parameter, Serializable JavaDoc {
42
43     /**
44      * <code>BASIC_DEFAULT</code> is an instance of BasicComponentParameter using the default constructor.
45      */

46     public static final BasicComponentParameter BASIC_DEFAULT = new BasicComponentParameter();
47
48     private Object JavaDoc componentKey;
49
50     /**
51      * Expect a parameter matching a component of a specific key.
52      *
53      * @param componentKey the key of the desired component
54      */

55     public BasicComponentParameter(Object JavaDoc componentKey) {
56         this.componentKey = componentKey;
57     }
58
59     /**
60      * Expect any paramter of the appropriate type.
61      */

62     public BasicComponentParameter() {
63     }
64
65     /**
66      * Check wether the given Parameter can be statisfied by the container.
67      *
68      * @return <code>true</code> if the Parameter can be verified.
69      * @see org.picocontainer.Parameter#isResolvable(org.picocontainer.PicoContainer,
70      * org.picocontainer.ComponentAdapter, java.lang.Class)
71      */

72     public boolean isResolvable(PicoContainer container, ComponentAdapter adapter, Class JavaDoc expectedType) {
73         return resolveAdapter(container, adapter, expectedType) != null;
74     }
75
76     public Object JavaDoc resolveInstance(PicoContainer container, ComponentAdapter adapter, Class JavaDoc expectedType)
77             throws PicoInstantiationException {
78         final ComponentAdapter componentAdapter = resolveAdapter(container, adapter, expectedType);
79         if (componentAdapter != null) {
80             return container.getComponentInstance(componentAdapter.getComponentKey());
81         }
82         return null;
83     }
84
85     public void verify(PicoContainer container, ComponentAdapter adapter, Class JavaDoc expectedType) throws PicoIntrospectionException {
86         final ComponentAdapter componentAdapter = resolveAdapter(container, adapter, expectedType);
87         if (componentAdapter == null) {
88             final HashSet JavaDoc set = new HashSet JavaDoc();
89             set.add(Arrays.asList(new Class JavaDoc[] {expectedType}));
90             throw new UnsatisfiableDependenciesException(adapter, set);
91         }
92         componentAdapter.verify(container);
93     }
94
95     /**
96      * Visit the current {@link Parameter}.
97      *
98      * @see org.picocontainer.Parameter#accept(org.picocontainer.PicoVisitor)
99      */

100     public void accept(final PicoVisitor visitor) {
101         visitor.visitParameter(this);
102     }
103
104     private ComponentAdapter resolveAdapter(PicoContainer container, ComponentAdapter adapter, Class JavaDoc expectedType) {
105
106         final ComponentAdapter result = getTargetAdapter(container, expectedType,adapter);
107         if (result == null) {
108             return null;
109         }
110
111         if (!expectedType.isAssignableFrom(result.getComponentImplementation())) {
112             // check for primitive value
113
if (expectedType.isPrimitive()) {
114                 try {
115                     final Field JavaDoc field = result.getComponentImplementation().getField("TYPE");
116                     final Class JavaDoc type = (Class JavaDoc) field.get(result.getComponentInstance(null));
117                     if (expectedType.isAssignableFrom(type)) {
118                         return result;
119                     }
120                 } catch (NoSuchFieldException JavaDoc e) {
121                 } catch (IllegalArgumentException JavaDoc e) {
122                 } catch (IllegalAccessException JavaDoc e) {
123                 } catch (ClassCastException JavaDoc e) {
124                 }
125             }
126             return null;
127         }
128         return result;
129     }
130
131     private ComponentAdapter getTargetAdapter(PicoContainer container, Class JavaDoc expectedType, ComponentAdapter excludeAdapter) {
132         if (componentKey != null) {
133             // key tells us where to look so we follow
134
return container.getComponentAdapter(componentKey);
135         } else if(excludeAdapter == null) {
136             return container.getComponentAdapterOfType(expectedType);
137         } else {
138             Object JavaDoc excludeKey = excludeAdapter.getComponentKey();
139             ComponentAdapter byKey = container.getComponentAdapter(expectedType);
140             if(byKey != null ) {
141                 if( byKey.getComponentKey().equals(excludeKey)) {
142                     return null;
143                 }
144                 return byKey;
145             }
146             List JavaDoc found = container.getComponentAdaptersOfType(expectedType);
147             ComponentAdapter exclude = null;
148             ComponentAdapter work;
149             for(Iterator JavaDoc iterator = found.iterator(); iterator.hasNext();) {
150                 work = (ComponentAdapter) iterator.next();
151                 if( work.getComponentKey().equals(excludeKey)) {
152                     exclude = work;
153                 }
154             }
155             found.remove(exclude);
156             if(found.size() == 0) {
157                 if( container.getParent() != null) {
158                     return container.getParent().getComponentAdapterOfType(expectedType);
159                 } else {
160                     return null;
161                 }
162             } else if(found.size() == 1) {
163                 return (ComponentAdapter)found.get(0);
164             } else {
165                 Class JavaDoc[] foundClasses = new Class JavaDoc[found.size()];
166                 for (int i = 0; i < foundClasses.length; i++) {
167                     foundClasses[i] = ((ComponentAdapter) found.get(i)).getComponentImplementation();
168                 }
169                 throw new AmbiguousComponentResolutionException(expectedType, foundClasses);
170             }
171         }
172     }
173 }
174
Popular Tags