1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.grouplens.grapht.solver;
21
22 import org.grouplens.grapht.*;
23 import org.grouplens.grapht.reflect.*;
24 import org.grouplens.grapht.util.InstanceProvider;
25 import org.grouplens.grapht.util.Types;
26
27 import javax.inject.Provider;
28 import java.io.*;
29 import java.lang.reflect.ParameterizedType;
30 import java.lang.reflect.Type;
31 import java.util.Collections;
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 public class ProviderBindingFunction implements BindingFunction {
49 public ProviderBindingFunction() {
50 }
51
52 @Override
53 public BindingResult bind(InjectionContext context, DesireChain desires) throws ResolutionException {
54 Desire desire = desires.getCurrentDesire();
55 if (Provider.class.equals(desire.getDesiredType())) {
56
57
58 Type providerType = desire.getInjectionPoint().getType();
59 if (providerType instanceof ParameterizedType) {
60
61
62 Type[] typeArgs = ((ParameterizedType) providerType).getActualTypeArguments();
63 if (typeArgs.length == 1 && (typeArgs[0] instanceof Class ||
64 typeArgs[0] instanceof ParameterizedType)) {
65 Class<?> providedType = Types.erase(typeArgs[0]);
66
67
68
69 Desire providedDesire = Desires.create(desire.getInjectionPoint().getQualifier(),
70 providedType, desire.getInjectionPoint().isNullable());
71
72 Desire jitDesire = desire.restrict(new ProviderInjectionSatisfaction(providedDesire));
73
74
75
76 return BindingResult.newBuilder()
77 .setDesire(jitDesire)
78 .setCachePolicy(CachePolicy.NO_PREFERENCE)
79 .addFlag(BindingFlag.DEFERRED)
80 .addFlag(BindingFlag.TERMINAL)
81 .build();
82 }
83 }
84 }
85
86
87
88 return null;
89 }
90
91
92
93
94
95 private static class ProviderInjectionSatisfaction implements Satisfaction, Serializable {
96 private static final long serialVersionUID = 1L;
97
98 private final Desire providedDesire;
99
100 public ProviderInjectionSatisfaction(Desire providedDesire) {
101 this.providedDesire = providedDesire;
102 }
103
104 @Override
105 public CachePolicy getDefaultCachePolicy() {
106 return CachePolicy.NO_PREFERENCE;
107 }
108
109 @Override
110 public List<Desire> getDependencies() {
111 return Collections.singletonList(providedDesire);
112 }
113
114 @Override
115 public Type getType() {
116 return Types.parameterizedType(Provider.class, providedDesire.getDesiredType());
117 }
118
119 @Override
120 public Class<?> getErasedType() {
121 return Provider.class;
122 }
123
124 @Override
125 public boolean hasInstance() {
126 return false;
127 }
128
129 @SuppressWarnings("unchecked")
130 @Override
131 public <T> T visit(SatisfactionVisitor<T> visitor) {
132 return (T) visitor.visitProviderClass((Class) InstanceProvider.class);
133 }
134
135 @Override
136 public Instantiator makeInstantiator(Map<Desire,Instantiator> dependencies,
137 LifecycleManager lm) {
138 Instantiator instantiator = dependencies.get(providedDesire);
139
140
141 return Instantiators.ofInstance(Instantiators.toProvider(instantiator));
142 }
143
144 @Override
145 public boolean equals(Object o) {
146 if (!(o instanceof ProviderInjectionSatisfaction)) {
147 return false;
148 }
149
150 return ((ProviderInjectionSatisfaction) o).providedDesire.equals(providedDesire);
151 }
152
153 @Override
154 public int hashCode() {
155 return providedDesire.hashCode();
156 }
157
158 @Override
159 public String toString() {
160 return "Provider<" + providedDesire + ">";
161 }
162 }
163 }