1 |
| |
2 |
| |
3 |
| |
4 |
| |
5 |
| |
6 |
| |
7 |
| |
8 |
| |
9 |
| |
10 |
| package org.picocontainer.defaults; |
11 |
| |
12 |
| import org.picocontainer.ComponentAdapter; |
13 |
| import org.picocontainer.LifecycleManager; |
14 |
| import org.picocontainer.MutablePicoContainer; |
15 |
| import org.picocontainer.Parameter; |
16 |
| import org.picocontainer.PicoContainer; |
17 |
| import org.picocontainer.PicoException; |
18 |
| import org.picocontainer.PicoRegistrationException; |
19 |
| import org.picocontainer.PicoVerificationException; |
20 |
| import org.picocontainer.PicoVisitor; |
21 |
| import org.picocontainer.Startable; |
22 |
| import org.picocontainer.Disposable; |
23 |
| import org.picocontainer.alternatives.ImmutablePicoContainer; |
24 |
| |
25 |
| import java.io.Serializable; |
26 |
| import java.util.ArrayList; |
27 |
| import java.util.Collection; |
28 |
| import java.util.Collections; |
29 |
| import java.util.HashMap; |
30 |
| import java.util.HashSet; |
31 |
| import java.util.Iterator; |
32 |
| import java.util.List; |
33 |
| import java.util.Map; |
34 |
| |
35 |
| |
36 |
| |
37 |
| |
38 |
| |
39 |
| |
40 |
| |
41 |
| |
42 |
| |
43 |
| |
44 |
| |
45 |
| |
46 |
| |
47 |
| |
48 |
| |
49 |
| |
50 |
| |
51 |
| |
52 |
| |
53 |
| |
54 |
| |
55 |
| |
56 |
| |
57 |
| |
58 |
| |
59 |
| |
60 |
| |
61 |
| public class DefaultPicoContainer implements MutablePicoContainer, Serializable { |
62 |
| |
63 |
| private Map componentKeyToAdapterCache = new HashMap(); |
64 |
| private ComponentAdapterFactory componentAdapterFactory; |
65 |
| private PicoContainer parent; |
66 |
| private List componentAdapters = new ArrayList(); |
67 |
| |
68 |
| |
69 |
| private List orderedComponentAdapters = new ArrayList(); |
70 |
| |
71 |
| private boolean started = false; |
72 |
| private boolean disposed = false; |
73 |
| private HashSet children = new HashSet(); |
74 |
| private LifecycleManager lifecycleManager; |
75 |
| |
76 |
| |
77 |
| |
78 |
| |
79 |
| |
80 |
| |
81 |
| |
82 |
| |
83 |
| |
84 |
| |
85 |
| |
86 |
| |
87 |
| |
88 |
| |
89 |
| |
90 |
1066
| public DefaultPicoContainer(ComponentAdapterFactory componentAdapterFactory, PicoContainer parent,
|
91 |
| LifecycleManager lifecycleManager) { |
92 |
1066
| this.lifecycleManager = lifecycleManager;
|
93 |
0
| if (componentAdapterFactory == null) throw new NullPointerException("componentAdapterFactory");
|
94 |
1066
| this.componentAdapterFactory = componentAdapterFactory;
|
95 |
1066
| this.parent = parent == null ? null : new ImmutablePicoContainer(parent);
|
96 |
| } |
97 |
| |
98 |
| |
99 |
| |
100 |
| |
101 |
| |
102 |
| |
103 |
| |
104 |
| |
105 |
| |
106 |
| |
107 |
| |
108 |
| |
109 |
| |
110 |
| |
111 |
| |
112 |
752
| public DefaultPicoContainer(ComponentAdapterFactory componentAdapterFactory, PicoContainer parent) {
|
113 |
752
| this(componentAdapterFactory, parent, new DefaultLifecycleManager());
|
114 |
| } |
115 |
| |
116 |
| |
117 |
| |
118 |
| |
119 |
| |
120 |
198
| public DefaultPicoContainer(PicoContainer parent) {
|
121 |
198
| this(new DefaultComponentAdapterFactory(), parent);
|
122 |
| } |
123 |
| |
124 |
| |
125 |
| |
126 |
| |
127 |
| |
128 |
| |
129 |
118
| public DefaultPicoContainer(ComponentAdapterFactory componentAdapterFactory) {
|
130 |
118
| this(componentAdapterFactory, null);
|
131 |
| } |
132 |
| |
133 |
| |
134 |
| |
135 |
| |
136 |
| |
137 |
| |
138 |
0
| public DefaultPicoContainer(LifecycleManager lifecycleManager) {
|
139 |
0
| this(new DefaultComponentAdapterFactory(), null, lifecycleManager);
|
140 |
| } |
141 |
| |
142 |
| |
143 |
| |
144 |
| |
145 |
354
| public DefaultPicoContainer() {
|
146 |
354
| this(new DefaultComponentAdapterFactory(), null);
|
147 |
| } |
148 |
| |
149 |
3424
| public Collection getComponentAdapters() {
|
150 |
3424
| return Collections.unmodifiableList(componentAdapters);
|
151 |
| } |
152 |
| |
153 |
3864
| public final ComponentAdapter getComponentAdapter(Object componentKey) throws AmbiguousComponentResolutionException {
|
154 |
3864
| ComponentAdapter adapter = (ComponentAdapter) componentKeyToAdapterCache.get(componentKey);
|
155 |
3864
| if (adapter == null && parent != null) {
|
156 |
320
| adapter = parent.getComponentAdapter(componentKey);
|
157 |
| } |
158 |
3864
| return adapter;
|
159 |
| } |
160 |
| |
161 |
180
| public ComponentAdapter getComponentAdapterOfType(Class componentType) {
|
162 |
| |
163 |
180
| ComponentAdapter adapterByKey = getComponentAdapter(componentType);
|
164 |
180
| if (adapterByKey != null) {
|
165 |
86
| return adapterByKey;
|
166 |
| } |
167 |
| |
168 |
94
| List found = getComponentAdaptersOfType(componentType);
|
169 |
| |
170 |
94
| if (found.size() == 1) {
|
171 |
48
| return ((ComponentAdapter) found.get(0));
|
172 |
46
| } else if (found.size() == 0) {
|
173 |
46
| if (parent != null) {
|
174 |
0
| return parent.getComponentAdapterOfType(componentType);
|
175 |
| } else { |
176 |
46
| return null;
|
177 |
| } |
178 |
| } else { |
179 |
0
| Class[] foundClasses = new Class[found.size()];
|
180 |
0
| for (int i = 0; i < foundClasses.length; i++) {
|
181 |
0
| foundClasses[i] = ((ComponentAdapter) found.get(i)).getComponentImplementation();
|
182 |
| } |
183 |
| |
184 |
0
| throw new AmbiguousComponentResolutionException(componentType, foundClasses);
|
185 |
| } |
186 |
| } |
187 |
| |
188 |
2396
| public List getComponentAdaptersOfType(Class componentType) {
|
189 |
2396
| if (componentType == null) {
|
190 |
0
| return Collections.EMPTY_LIST;
|
191 |
| } |
192 |
2396
| List found = new ArrayList();
|
193 |
2396
| for (Iterator iterator = getComponentAdapters().iterator(); iterator.hasNext();) {
|
194 |
5296
| ComponentAdapter componentAdapter = (ComponentAdapter) iterator.next();
|
195 |
| |
196 |
5296
| if (componentType.isAssignableFrom(componentAdapter.getComponentImplementation())) {
|
197 |
702
| found.add(componentAdapter);
|
198 |
| } |
199 |
| } |
200 |
2396
| return found;
|
201 |
| } |
202 |
| |
203 |
| |
204 |
| |
205 |
| |
206 |
| |
207 |
| |
208 |
1440
| public ComponentAdapter registerComponent(ComponentAdapter componentAdapter) throws DuplicateComponentKeyRegistrationException {
|
209 |
1440
| Object componentKey = componentAdapter.getComponentKey();
|
210 |
1440
| if (componentKeyToAdapterCache.containsKey(componentKey)) {
|
211 |
14
| throw new DuplicateComponentKeyRegistrationException(componentKey);
|
212 |
| } |
213 |
1426
| componentAdapters.add(componentAdapter);
|
214 |
1426
| componentKeyToAdapterCache.put(componentKey, componentAdapter);
|
215 |
1426
| return componentAdapter;
|
216 |
| } |
217 |
| |
218 |
34
| public ComponentAdapter unregisterComponent(Object componentKey) {
|
219 |
34
| ComponentAdapter adapter = (ComponentAdapter) componentKeyToAdapterCache.remove(componentKey);
|
220 |
34
| componentAdapters.remove(adapter);
|
221 |
34
| orderedComponentAdapters.remove(adapter);
|
222 |
34
| return adapter;
|
223 |
| } |
224 |
| |
225 |
| |
226 |
| |
227 |
| |
228 |
| |
229 |
166
| public ComponentAdapter registerComponentInstance(Object component) throws PicoRegistrationException {
|
230 |
166
| return registerComponentInstance(component.getClass(), component);
|
231 |
| } |
232 |
| |
233 |
| |
234 |
| |
235 |
| |
236 |
| |
237 |
264
| public ComponentAdapter registerComponentInstance(Object componentKey, Object componentInstance) throws PicoRegistrationException {
|
238 |
264
| ComponentAdapter componentAdapter = new InstanceComponentAdapter(componentKey, componentInstance);
|
239 |
252
| registerComponent(componentAdapter);
|
240 |
250
| return componentAdapter;
|
241 |
| } |
242 |
| |
243 |
| |
244 |
| |
245 |
| |
246 |
| |
247 |
| |
248 |
528
| public ComponentAdapter registerComponentImplementation(Class componentImplementation) throws PicoRegistrationException {
|
249 |
528
| return registerComponentImplementation(componentImplementation, componentImplementation);
|
250 |
| } |
251 |
| |
252 |
| |
253 |
| |
254 |
| |
255 |
| |
256 |
| |
257 |
810
| public ComponentAdapter registerComponentImplementation(Object componentKey, Class componentImplementation) throws PicoRegistrationException {
|
258 |
810
| return registerComponentImplementation(componentKey, componentImplementation, (Parameter[]) null);
|
259 |
| } |
260 |
| |
261 |
| |
262 |
| |
263 |
| |
264 |
| |
265 |
| |
266 |
956
| public ComponentAdapter registerComponentImplementation(Object componentKey, Class componentImplementation, Parameter[] parameters) throws PicoRegistrationException {
|
267 |
956
| ComponentAdapter componentAdapter = componentAdapterFactory.createComponentAdapter(componentKey, componentImplementation, parameters);
|
268 |
950
| registerComponent(componentAdapter);
|
269 |
938
| return componentAdapter;
|
270 |
| } |
271 |
| |
272 |
| |
273 |
| |
274 |
| |
275 |
| |
276 |
2
| public ComponentAdapter registerComponentImplementation(Object componentKey, Class componentImplementation, List parameters) throws PicoRegistrationException {
|
277 |
2
| Parameter[] parametersAsArray = (Parameter[]) parameters.toArray(new Parameter[parameters.size()]);
|
278 |
2
| return registerComponentImplementation(componentKey, componentImplementation, parametersAsArray);
|
279 |
| } |
280 |
| |
281 |
2022
| private void addOrderedComponentAdapter(ComponentAdapter componentAdapter) {
|
282 |
2022
| if (!orderedComponentAdapters.contains(componentAdapter)) {
|
283 |
928
| orderedComponentAdapters.add(componentAdapter);
|
284 |
| } |
285 |
| } |
286 |
| |
287 |
152
| public List getComponentInstances() throws PicoException {
|
288 |
152
| return getComponentInstancesOfType(Object.class);
|
289 |
| } |
290 |
| |
291 |
506
| public List getComponentInstancesOfType(Class componentType) throws PicoException {
|
292 |
506
| if (componentType == null) {
|
293 |
0
| return Collections.EMPTY_LIST;
|
294 |
| } |
295 |
| |
296 |
506
| Map adapterToInstanceMap = new HashMap();
|
297 |
506
| for (Iterator iterator = componentAdapters.iterator(); iterator.hasNext();) {
|
298 |
698
| ComponentAdapter componentAdapter = (ComponentAdapter) iterator.next();
|
299 |
698
| if (componentType.isAssignableFrom(componentAdapter.getComponentImplementation())) {
|
300 |
496
| Object componentInstance = getInstance(componentAdapter);
|
301 |
494
| adapterToInstanceMap.put(componentAdapter, componentInstance);
|
302 |
| |
303 |
| |
304 |
| |
305 |
494
| addOrderedComponentAdapter(componentAdapter);
|
306 |
| } |
307 |
| } |
308 |
504
| List result = new ArrayList();
|
309 |
504
| for (Iterator iterator = orderedComponentAdapters.iterator(); iterator.hasNext();) {
|
310 |
652
| Object componentAdapter = iterator.next();
|
311 |
652
| final Object componentInstance = adapterToInstanceMap.get(componentAdapter);
|
312 |
652
| if (componentInstance != null) {
|
313 |
| |
314 |
| |
315 |
492
| result.add(componentInstance);
|
316 |
| } |
317 |
| } |
318 |
504
| return result;
|
319 |
| } |
320 |
| |
321 |
1200
| public Object getComponentInstance(Object componentKey) throws PicoException {
|
322 |
1200
| ComponentAdapter componentAdapter = getComponentAdapter(componentKey);
|
323 |
1200
| if (componentAdapter != null) {
|
324 |
1168
| return getInstance(componentAdapter);
|
325 |
| } else { |
326 |
32
| return null;
|
327 |
| } |
328 |
| } |
329 |
| |
330 |
88
| public Object getComponentInstanceOfType(Class componentType) {
|
331 |
88
| final ComponentAdapter componentAdapter = getComponentAdapterOfType(componentType);
|
332 |
88
| return componentAdapter == null ? null : getInstance(componentAdapter);
|
333 |
| } |
334 |
| |
335 |
1744
| private Object getInstance(ComponentAdapter componentAdapter) {
|
336 |
| |
337 |
| |
338 |
1744
| final boolean isLocal = componentAdapters.contains(componentAdapter);
|
339 |
| |
340 |
1744
| if (isLocal) {
|
341 |
1634
| Object instance = componentAdapter.getComponentInstance(this);
|
342 |
| |
343 |
1528
| addOrderedComponentAdapter(componentAdapter);
|
344 |
| |
345 |
1528
| return instance;
|
346 |
110
| } else if (parent != null) {
|
347 |
110
| return parent.getComponentInstance(componentAdapter.getComponentKey());
|
348 |
| } |
349 |
| |
350 |
| |
351 |
| |
352 |
0
| return null;
|
353 |
| } |
354 |
| |
355 |
| |
356 |
2174
| public PicoContainer getParent() {
|
357 |
2174
| return parent;
|
358 |
| } |
359 |
| |
360 |
14
| public ComponentAdapter unregisterComponentByInstance(Object componentInstance) {
|
361 |
14
| Collection componentAdapters = getComponentAdapters();
|
362 |
14
| for (Iterator iterator = componentAdapters.iterator(); iterator.hasNext();) {
|
363 |
4
| ComponentAdapter componentAdapter = (ComponentAdapter) iterator.next();
|
364 |
4
| if (getInstance(componentAdapter).equals(componentInstance)) {
|
365 |
2
| return unregisterComponent(componentAdapter.getComponentKey());
|
366 |
| } |
367 |
| } |
368 |
12
| return null;
|
369 |
| } |
370 |
| |
371 |
| |
372 |
| |
373 |
| |
374 |
0
| public void verify() throws PicoVerificationException {
|
375 |
0
| new VerifyingVisitor().traverse(this);
|
376 |
| } |
377 |
| |
378 |
| |
379 |
| |
380 |
| |
381 |
| |
382 |
| |
383 |
| |
384 |
| |
385 |
| |
386 |
146
| public void start() {
|
387 |
2
| if (disposed) throw new IllegalStateException("Already disposed");
|
388 |
4
| if (started) throw new IllegalStateException("Already started");
|
389 |
140
| lifecycleManager.start(this);
|
390 |
138
| for (Iterator iterator = children.iterator(); iterator.hasNext();) {
|
391 |
42
| PicoContainer child = (PicoContainer) iterator.next();
|
392 |
42
| if (child instanceof Startable) {
|
393 |
42
| child.start();
|
394 |
| } |
395 |
| } |
396 |
136
| started = true;
|
397 |
| } |
398 |
| |
399 |
| |
400 |
| |
401 |
| |
402 |
| |
403 |
| |
404 |
| |
405 |
| |
406 |
| |
407 |
96
| public void stop() {
|
408 |
2
| if (disposed) throw new IllegalStateException("Already disposed");
|
409 |
2
| if (!started) throw new IllegalStateException("Not started");
|
410 |
92
| for (Iterator iterator = children.iterator(); iterator.hasNext();) {
|
411 |
28
| PicoContainer child = (PicoContainer) iterator.next();
|
412 |
28
| if (child instanceof Startable) {
|
413 |
28
| child.stop();
|
414 |
| } |
415 |
| } |
416 |
92
| lifecycleManager.stop(this);
|
417 |
92
| started = false;
|
418 |
| } |
419 |
| |
420 |
| |
421 |
| |
422 |
| |
423 |
| |
424 |
| |
425 |
| |
426 |
| |
427 |
| |
428 |
92
| public void dispose() {
|
429 |
2
| if (disposed) throw new IllegalStateException("Already disposed");
|
430 |
90
| for (Iterator iterator = children.iterator(); iterator.hasNext();) {
|
431 |
28
| PicoContainer child = (PicoContainer) iterator.next();
|
432 |
28
| if (child instanceof Disposable) {
|
433 |
28
| child.dispose();
|
434 |
| } |
435 |
| } |
436 |
90
| lifecycleManager.dispose(this);
|
437 |
90
| disposed = true;
|
438 |
| } |
439 |
| |
440 |
36
| public MutablePicoContainer makeChildContainer() {
|
441 |
36
| DefaultPicoContainer pc = new DefaultPicoContainer(componentAdapterFactory, this, lifecycleManager);
|
442 |
36
| addChildContainer(pc);
|
443 |
36
| return pc;
|
444 |
| } |
445 |
| |
446 |
84
| public boolean addChildContainer(PicoContainer child) {
|
447 |
84
| return children.add(child);
|
448 |
| } |
449 |
| |
450 |
12
| public boolean removeChildContainer(PicoContainer child) {
|
451 |
12
| final boolean result = children.remove(child);
|
452 |
12
| return result;
|
453 |
| } |
454 |
| |
455 |
66
| public void accept(PicoVisitor visitor) {
|
456 |
66
| visitor.visitContainer(this);
|
457 |
64
| final List componentAdapters = new ArrayList(getComponentAdapters());
|
458 |
64
| for (Iterator iterator = componentAdapters.iterator(); iterator.hasNext();) {
|
459 |
144
| ComponentAdapter componentAdapter = (ComponentAdapter) iterator.next();
|
460 |
144
| componentAdapter.accept(visitor);
|
461 |
| } |
462 |
64
| final List allChildren = new ArrayList(children);
|
463 |
64
| for (Iterator iterator = allChildren.iterator(); iterator.hasNext();) {
|
464 |
18
| PicoContainer child = (PicoContainer) iterator.next();
|
465 |
18
| child.accept(visitor);
|
466 |
| } |
467 |
| } |
468 |
| } |