|
|||||||||||||||||||
Source file | Conditionals | Statements | Methods | TOTAL | |||||||||||||||
ComponentParameter.java | 83.3% | 96% | 100% | 93.6% |
|
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 | ||
20 | /** | |
21 | * A ComponentParameter should be used to pass in a particular component as argument to a | |
22 | * different component's constructor. This is particularly useful in cases where several | |
23 | * components of the same type have been registered, but with a different key. Passing a | |
24 | * ComponentParameter as a parameter when registering a component will give PicoContainer a hint | |
25 | * about what other component to use in the constructor. Collecting parameter types are | |
26 | * supported for {@link java.lang.reflect.Array},{@link java.util.Collection}and | |
27 | * {@link java.util.Map}. | |
28 | * | |
29 | * @author Jon Tirsén | |
30 | * @author Aslak Hellesøy | |
31 | * @author Jörg Schaible | |
32 | * @author Thomas Heller | |
33 | * @version $Revision: 1804 $ | |
34 | */ | |
35 | public class ComponentParameter | |
36 | extends BasicComponentParameter { | |
37 | ||
38 | /** | |
39 | * <code>DEFAULT</code> is an instance of ComponentParameter using the default constructor. | |
40 | */ | |
41 | public static final ComponentParameter DEFAULT = new ComponentParameter(); | |
42 | /** | |
43 | * Use <code>ARRAY</code> as {@link Parameter}for an Array that must have elements. | |
44 | */ | |
45 | public static final ComponentParameter ARRAY = new ComponentParameter(false); | |
46 | /** | |
47 | * Use <code>ARRAY_ALLOW_EMPTY</code> as {@link Parameter}for an Array that may have no | |
48 | * elements. | |
49 | */ | |
50 | public static final ComponentParameter ARRAY_ALLOW_EMPTY = new ComponentParameter(true); | |
51 | ||
52 | private final Parameter collectionParameter; | |
53 | ||
54 | /** | |
55 | * Expect a parameter matching a component of a specific key. | |
56 | * | |
57 | * @param componentKey the key of the desired component | |
58 | */ | |
59 | 18 | public ComponentParameter(Object componentKey) { |
60 | 18 | this(componentKey, null); |
61 | } | |
62 | ||
63 | /** | |
64 | * Expect any scalar paramter of the appropriate type or an {@link java.lang.reflect.Array}. | |
65 | */ | |
66 | 70 | public ComponentParameter() { |
67 | 70 | this(false); |
68 | } | |
69 | ||
70 | /** | |
71 | * Expect any scalar paramter of the appropriate type or an {@link java.lang.reflect.Array}. | |
72 | * Resolve the parameter even if no compoennt is of the array's component type. | |
73 | * | |
74 | * @param emptyCollection <code>true</code> allows an Array to be empty | |
75 | * @since 1.1 | |
76 | */ | |
77 | 210 | public ComponentParameter(boolean emptyCollection) { |
78 | 210 | this(null, emptyCollection ? CollectionComponentParameter.ARRAY_ALLOW_EMPTY : CollectionComponentParameter.ARRAY); |
79 | } | |
80 | ||
81 | /** | |
82 | * Expect any scalar paramter of the appropriate type or the collecting type | |
83 | * {@link java.lang.reflect.Array},{@link java.util.Collection}or {@link java.util.Map}. | |
84 | * The components in the collection will be of the specified type. | |
85 | * | |
86 | * @param componentValueType the component's type (ignored for an Array) | |
87 | * @param emptyCollection <code>true</code> allows the collection to be empty | |
88 | * @since 1.1 | |
89 | */ | |
90 | 34 | public ComponentParameter(Class componentValueType, boolean emptyCollection) { |
91 | 34 | this(null, new CollectionComponentParameter(componentValueType, emptyCollection)); |
92 | } | |
93 | ||
94 | /** | |
95 | * Expect any scalar paramter of the appropriate type or the collecting type | |
96 | * {@link java.lang.reflect.Array},{@link java.util.Collection}or {@link java.util.Map}. | |
97 | * The components in the collection will be of the specified type and their adapter's key | |
98 | * must have a particular type. | |
99 | * | |
100 | * @param componentKeyType the component adapter's key type | |
101 | * @param componentValueType the component's type (ignored for an Array) | |
102 | * @param emptyCollection <code>true</code> allows the collection to be empty | |
103 | * @since 1.1 | |
104 | */ | |
105 | 4 | public ComponentParameter(Class componentKeyType, Class componentValueType, boolean emptyCollection) { |
106 | 4 | this(null, new CollectionComponentParameter(componentKeyType, componentValueType, emptyCollection)); |
107 | } | |
108 | ||
109 | 266 | private ComponentParameter(Object componentKey, Parameter collectionParameter) { |
110 | 266 | super(componentKey); |
111 | 266 | this.collectionParameter = collectionParameter; |
112 | } | |
113 | ||
114 | 464 | public Object resolveInstance(PicoContainer container, ComponentAdapter adapter, Class expectedType) |
115 | throws PicoInstantiationException { | |
116 | // type check is done in isResolvable | |
117 | 464 | Object result = super.resolveInstance(container, adapter, expectedType); |
118 | 430 | if (result == null && collectionParameter != null) { |
119 | 70 | result = collectionParameter.resolveInstance(container, adapter, expectedType); |
120 | } | |
121 | 430 | return result; |
122 | } | |
123 | ||
124 | 1648 | public boolean isResolvable(PicoContainer container, ComponentAdapter adapter, Class expectedType) { |
125 | 1648 | if (!super.isResolvable(container, adapter, expectedType)) { |
126 | 1130 | if (collectionParameter != null) { |
127 | 1114 | return collectionParameter.isResolvable(container, adapter, expectedType); |
128 | } | |
129 | 16 | return false; |
130 | } | |
131 | 504 | return true; |
132 | } | |
133 | ||
134 | /** | |
135 | * {@inheritDoc} | |
136 | * | |
137 | * @see org.picocontainer.Parameter#verify(org.picocontainer.PicoContainer, | |
138 | * org.picocontainer.ComponentAdapter, java.lang.Class) | |
139 | */ | |
140 | 16 | public void verify(PicoContainer container, ComponentAdapter adapter, Class expectedType) throws PicoIntrospectionException { |
141 | 16 | try { |
142 | 16 | super.verify(container, adapter, expectedType); |
143 | } catch (UnsatisfiableDependenciesException e) { | |
144 | 2 | if (collectionParameter != null) { |
145 | 2 | collectionParameter.verify(container, adapter, expectedType); |
146 | 2 | return; |
147 | } | |
148 | 0 | throw e; |
149 | } | |
150 | } | |
151 | ||
152 | /** | |
153 | * Accept the visitor for the current {@link Parameter}. If internally a | |
154 | * {@link CollectionComponentParameter}is used, it is visited also. | |
155 | * | |
156 | * @see org.picocontainer.defaults.BasicComponentParameter#accept(org.picocontainer.PicoVisitor) | |
157 | */ | |
158 | 12 | public void accept(PicoVisitor visitor) { |
159 | 12 | super.accept(visitor); |
160 | 12 | if (collectionParameter != null) { |
161 | 12 | collectionParameter.accept(visitor); |
162 | } | |
163 | } | |
164 | } |
|