1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27 package org.grouplens.grapht.reflect.internal;
28
29 import org.grouplens.grapht.ConstructionException;
30 import org.grouplens.grapht.Instantiator;
31 import org.grouplens.grapht.reflect.InjectionPoint;
32 import org.grouplens.grapht.util.LogContext;
33 import org.slf4j.Logger;
34 import org.slf4j.LoggerFactory;
35
36 import java.lang.reflect.Field;
37 import java.lang.reflect.InvocationTargetException;
38 import java.lang.reflect.Method;
39 import java.util.Map;
40
41 enum InjectionStrategy {
42
43
44 FIELD {
45 @Override
46 public void inject(InjectionPoint ip, Object instance, Instantiator provider,
47 Map<Method, ClassInstantiator.InjectionArgs> settersAndArguments)
48 throws ConstructionException {
49 Field field;
50 Object value;
51 FieldInjectionPoint fd = (FieldInjectionPoint)ip;
52 try {
53 value = ClassInstantiator.checkNull(fd, provider.instantiate());
54 field = fd.getMember();
55 logger.trace("Setting field {} with arguments {}", field, value);
56 field.setAccessible(true);
57 field.set(instance, value);
58 } catch (IllegalAccessException e) {
59 throw new ConstructionException(fd, e);
60 }
61 }
62 },
63
64
65 SETTER {
66 @Override
67 public void inject(InjectionPoint ip, Object instance, Instantiator provider,
68 Map<Method, ClassInstantiator.InjectionArgs> settersAndArguments)
69 throws ConstructionException {
70 SetterInjectionPoint st = (SetterInjectionPoint)ip;
71 ClassInstantiator.InjectionArgs args = settersAndArguments.get(st.getMember());
72 Method setter = st.getMember();
73 if (args == null) {
74
75 args = new ClassInstantiator.InjectionArgs(setter.getParameterTypes().length);
76 settersAndArguments.put(setter, args);
77 }
78 args.set(st.getParameterIndex(), ClassInstantiator.checkNull(st, provider.instantiate()));
79
80 if (args.isCompleted()) {
81
82 try {
83 logger.trace("Invoking setter {} with arguments {}", setter, args.arguments);
84 setter.setAccessible(true);
85 setter.invoke(instance, args.arguments);
86 } catch (InvocationTargetException e) {
87 String message = "Exception thrown by ";
88 if (args.arguments.length == 1) {
89 message += st;
90 } else {
91 message += setter;
92 }
93 throw new ConstructionException(st, message, e);
94 } catch (IllegalAccessException e) {
95 String message = "Access violation calling ";
96 if (args.arguments.length == 1) {
97 message += st;
98 } else {
99 message += setter;
100 }
101 throw new ConstructionException(st, message, e);
102 }
103 }
104 }
105 },
106
107
108 NOARGUMENT {
109 @Override
110 public void inject(InjectionPoint ip, Object instance, Instantiator provider,
111 Map<Method, ClassInstantiator.InjectionArgs> settersAndArguments)
112 throws ConstructionException {
113 Method method = null;
114 NoArgumentInjectionPoint noArugment = (NoArgumentInjectionPoint)ip;
115 try {
116 method = noArugment.getMember();
117 logger.trace("Injection point method with no argument in progress {}",noArugment);
118 logger.trace("Invoking no-argument injection point {}", ip);
119 method.setAccessible(true);
120 method.invoke(instance);
121 } catch (InvocationTargetException e) {
122 throw new ConstructionException(ip, "Exception throw by " + method, e);
123 } catch (IllegalAccessException e) {
124 throw new ConstructionException(ip, "Access violation invoking " + method, e);
125 }
126 }
127 },
128
129 DEFAULTCASE {
130 @Override
131 public void inject(InjectionPoint ip, Object instance, Instantiator provider,
132 Map<Method, ClassInstantiator.InjectionArgs> settersAndArguments)
133 throws ConstructionException {
134 }
135 };
136
137 private static final Logger logger = LoggerFactory.getLogger(InjectionStrategy.class);
138
139 public abstract void inject(InjectionPoint ip, Object instance, Instantiator provider,
140 Map<Method, ClassInstantiator.InjectionArgs> settersAndArguments)
141 throws ConstructionException;
142
143 public static InjectionStrategy forInjectionPoint(InjectionPoint ip) {
144 if(ip instanceof FieldInjectionPoint) {
145 return InjectionStrategy.FIELD;
146 }
147 else if(ip instanceof SetterInjectionPoint) {
148 return InjectionStrategy.SETTER;
149 }
150 else if(ip instanceof NoArgumentInjectionPoint) {
151 return InjectionStrategy.NOARGUMENT;
152 }
153 else {
154 return InjectionStrategy.DEFAULTCASE;
155 }
156 }
157 }