1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.jadira.reflection.access.invokedynamic;
17
18 import java.lang.invoke.CallSite;
19 import java.lang.invoke.MethodHandle;
20 import java.lang.invoke.MethodType;
21 import java.lang.reflect.Field;
22
23 import org.dynalang.dynalink.DefaultBootstrapper;
24 import org.jadira.reflection.access.api.FieldAccess;
25
26
27
28
29
30 public class InvokeDynamicFieldAccess<C> implements FieldAccess<C> {
31
32 private String fieldName;
33
34 private Class<C> declaringClass;
35 private Class<?> fieldClass;
36 private Field field;
37
38 CallSite getCallSite;
39 CallSite setCallSite;
40
41 MethodHandle setMh;
42 MethodHandle getMh;
43
44 @SuppressWarnings("unchecked")
45 private InvokeDynamicFieldAccess(InvokeDynamicClassAccess<C> classAccess, Field f) {
46
47 this.declaringClass = (Class<C>) f.getDeclaringClass();
48
49 this.fieldClass = f.getType();
50
51 this.fieldName = f.getName();
52
53 this.field = f;
54
55 setCallSite = DefaultBootstrapper.publicBootstrap(null, "dyn:setProp:" + fieldName, MethodType.methodType(void.class, Object.class, fieldClass));
56 getCallSite = DefaultBootstrapper.publicBootstrap(null, "dyn:getProp:" + fieldName, MethodType.methodType(fieldClass, Object.class));
57
58 setMh = setCallSite.dynamicInvoker();
59 getMh = getCallSite.dynamicInvoker();
60 }
61
62 @Override
63 public Class<C> declaringClass() {
64 return declaringClass;
65 }
66
67 @Override
68 public Class<?> fieldClass() {
69 return fieldClass;
70 }
71
72 @Override
73 public Field field() {
74 return field;
75 }
76
77
78
79
80
81
82
83
84 public static final <C> InvokeDynamicFieldAccess<C> get(InvokeDynamicClassAccess<C> classAccess, Field f) {
85 return new InvokeDynamicFieldAccess<C>(classAccess, f);
86 }
87
88 @Override
89 public Object getValue(C parent) {
90 try {
91 return getMh.invokeExact(parent);
92 } catch (Throwable e) {
93 throw new IllegalStateException("Problem accessing {" + field.getName() + "} of object {"
94 + System.identityHashCode(parent) + "}: " + e.getMessage(), e);
95 }
96 }
97
98 @Override
99 public void putValue(C parent, Object newFieldValue) {
100 try {
101 setMh.invokeExact(parent, newFieldValue);
102 } catch (Throwable e) {
103 throw new IllegalStateException("Problem accessing {" + field.getName() + "} of object {"
104 + System.identityHashCode(parent) + "}: " + e.getMessage(), e);
105 }
106 }
107
108 @Override
109 public boolean getBooleanValue(C parent) {
110 try {
111 return (boolean) getMh.invokeExact(parent);
112 } catch (Throwable e) {
113 throw new IllegalStateException("Problem accessing {" + field.getName() + "} of object {"
114 + System.identityHashCode(parent) + "}: " + e.getMessage(), e);
115 }
116 }
117
118 @Override
119 public byte getByteValue(C parent) {
120 try {
121 return (byte) getMh.invokeExact(parent);
122 } catch (Throwable e) {
123 throw new IllegalStateException("Problem accessing {" + field.getName() + "} of object {"
124 + System.identityHashCode(parent) + "}: " + e.getMessage(), e);
125 }
126 }
127
128 @Override
129 public char getCharValue(C parent) {
130 try {
131 return (char) getMh.invokeExact(parent);
132 } catch (Throwable e) {
133 throw new IllegalStateException("Problem accessing {" + field.getName() + "} of object {"
134 + System.identityHashCode(parent) + "}: " + e.getMessage(), e);
135 }
136 }
137
138 @Override
139 public short getShortValue(C parent) {
140 try {
141 return (short) getMh.invokeExact(parent);
142 } catch (Throwable e) {
143 throw new IllegalStateException("Problem accessing {" + field.getName() + "} of object {"
144 + System.identityHashCode(parent) + "}: " + e.getMessage(), e);
145 }
146 }
147
148 @Override
149 public int getIntValue(C parent) {
150 try {
151 return (int) getMh.invokeExact(parent);
152 } catch (Throwable e) {
153 throw new IllegalStateException("Problem accessing {" + field.getName() + "} of object {"
154 + System.identityHashCode(parent) + "}: " + e.getMessage(), e);
155 }
156 }
157
158 @Override
159 public long getLongValue(C parent) {
160 try {
161 return (long) getMh.invokeExact(parent);
162 } catch (Throwable e) {
163 throw new IllegalStateException("Problem accessing {" + field.getName() + "} of object {"
164 + System.identityHashCode(parent) + "}: " + e.getMessage(), e);
165 }
166 }
167
168 @Override
169 public float getFloatValue(C parent) {
170 try {
171 return (float) getMh.invokeExact(parent);
172 } catch (Throwable e) {
173 throw new IllegalStateException("Problem accessing {" + field.getName() + "} of object {"
174 + System.identityHashCode(parent) + "}: " + e.getMessage(), e);
175 }
176 }
177
178 @Override
179 public double getDoubleValue(C parent) {
180 try {
181 return (double) getMh.invokeExact(parent);
182 } catch (Throwable e) {
183 throw new IllegalStateException("Problem accessing {" + field.getName() + "} of object {"
184 + System.identityHashCode(parent) + "}: " + e.getMessage(), e);
185 }
186 }
187
188 @Override
189 public void putBooleanValue(C parent, boolean newFieldValue) {
190 try {
191 setMh.invokeExact(parent, newFieldValue);
192 } catch (Throwable e) {
193 throw new IllegalStateException("Problem accessing {" + field.getName() + "} of object {"
194 + System.identityHashCode(parent) + "}: " + e.getMessage(), e);
195 }
196 }
197
198 @Override
199 public void putByteValue(C parent, byte newFieldValue) {
200 try {
201 setMh.invokeExact(parent, newFieldValue);
202 } catch (Throwable e) {
203 throw new IllegalStateException("Problem accessing {" + field.getName() + "} of object {"
204 + System.identityHashCode(parent) + "}: " + e.getMessage(), e);
205 }
206 }
207
208 @Override
209 public void putCharValue(C parent, char newFieldValue) {
210 try {
211 setMh.invokeExact(parent, newFieldValue);
212 } catch (Throwable e) {
213 throw new IllegalStateException("Problem accessing {" + field.getName() + "} of object {"
214 + System.identityHashCode(parent) + "}: " + e.getMessage(), e);
215 }
216 }
217
218 @Override
219 public void putShortValue(C parent, short newFieldValue) {
220 try {
221 setMh.invokeExact(parent, newFieldValue);
222 } catch (Throwable e) {
223 throw new IllegalStateException("Problem accessing {" + field.getName() + "} of object {"
224 + System.identityHashCode(parent) + "}: " + e.getMessage(), e);
225 }
226 }
227
228 @Override
229 public void putIntValue(C parent, int newFieldValue) {
230 try {
231 setMh.invokeExact(parent, newFieldValue);
232 } catch (Throwable e) {
233 throw new IllegalStateException("Problem accessing {" + field.getName() + "} of object {"
234 + System.identityHashCode(parent) + "}: " + e.getMessage(), e);
235 }
236 }
237
238 @Override
239 public void putLongValue(C parent, long newFieldValue) {
240 try {
241 setMh.invokeExact(parent, newFieldValue);
242 } catch (Throwable e) {
243 throw new IllegalStateException("Problem accessing {" + field.getName() + "} of object {"
244 + System.identityHashCode(parent) + "}: " + e.getMessage(), e);
245 }
246 }
247
248 @Override
249 public void putFloatValue(C parent, float newFieldValue) {
250 try {
251 setMh.invokeExact(parent, newFieldValue);
252 } catch (Throwable e) {
253 throw new IllegalStateException("Problem accessing {" + field.getName() + "} of object {"
254 + System.identityHashCode(parent) + "}: " + e.getMessage(), e);
255 }
256 }
257
258 @Override
259 public void putDoubleValue(C parent, double newFieldValue) {
260 try {
261 setMh.invokeExact(parent, newFieldValue);
262 } catch (Throwable e) {
263 throw new IllegalStateException("Problem accessing {" + field.getName() + "} of object {"
264 + System.identityHashCode(parent) + "}: " + e.getMessage(), e);
265 }
266 }
267 }