1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package jp.liq.container;
17
18 import java.util.Stack;
19
20 import jp.liq.container.ContainerException.Reason;
21
22
23
24
25
26
27
28 public abstract class Resolver {
29 private final Stack<ComponentMetadata> resolvingComponents;
30
31 Resolver(ComponentMetadata root) {
32 resolvingComponents = new Stack<ComponentMetadata>();
33 resolvingComponents.push(root);
34 }
35
36 final Object resolve() {
37 return resolvingComponents.get(0).getComponent().getInstance(this);
38 }
39
40
41
42
43
44
45
46
47
48 public final <T> T resolve(Class<T> type)
49 throws ContainerException {
50 ComponentMetadata c = findComponentMetadata(type);
51
52 if(c != null) {
53 if (resolvingComponents.contains(c)) {
54 throw new ContainerException(Reason.CIRCULAR_REFERENCE, type,
55 getDependencyPathStr(resolvingComponents));
56 }
57 resolvingComponents.push(c);
58 Object o = c.getComponent().getInstance(this);
59 resolvingComponents.pop();
60 return type.cast(o);
61 }
62
63 throw new ContainerException(Reason.MISSING_DEPENDENCY, type, getDependencyPathStr(resolvingComponents));
64
65 }
66
67
68
69
70
71
72
73 public Object[] resolve(Class<?>[] types)
74 throws ContainerException {
75 Object[] rv = new Object[types.length];
76
77 for (int i = 0; i < types.length; i++) {
78 Class<?> d = types[i];
79 rv[i] = resolve(d);
80 }
81 return rv;
82 }
83
84
85
86
87 public final ComponentMetadata peek() {
88 return resolvingComponents.peek();
89 }
90
91 abstract ComponentMetadata findComponentMetadata(Class<?> role);
92
93 private String getDependencyPathStr(Stack<ComponentMetadata> path) {
94 StringBuffer sb = new StringBuffer();
95 sb.append(path.get(0).describe());
96 for (int i = 1; i < path.size(); i++) {
97 sb.append(" -> ");
98 sb.append(path.get(i).describe());
99 }
100 return sb.toString();
101 }
102
103 }