259 |
259 |
260 return arr; |
260 return arr; |
261 } |
261 } |
262 |
262 |
263 // Needed to unpack the runtime view of containing annotations |
263 // Needed to unpack the runtime view of containing annotations |
264 private static final Class<? extends Annotation> CONTAINED_BY_CLASS = initContainedBy(); |
264 private static final Class<? extends Annotation> REPEATABLE_CLASS = initRepeatable(); |
265 private static final Method VALUE_ELEMENT_METHOD = initValueElementMethod(); |
265 private static final Method VALUE_ELEMENT_METHOD = initValueElementMethod(); |
266 |
266 |
267 private static Class<? extends Annotation> initContainedBy() { |
267 private static Class<? extends Annotation> initRepeatable() { |
268 try { |
268 try { |
269 @SuppressWarnings("unchecked") // java.lang.annotation.ContainedBy extends Annotation by being an annotation type |
269 @SuppressWarnings("unchecked") // java.lang.annotation.Repeatable extends Annotation by being an annotation type |
270 Class<? extends Annotation> c = (Class)Class.forName("java.lang.annotation.ContainedBy"); |
270 Class<? extends Annotation> c = (Class)Class.forName("java.lang.annotation.Repeatable"); |
271 return c; |
271 return c; |
272 } catch (ClassNotFoundException e) { |
272 } catch (ClassNotFoundException e) { |
273 return null; |
273 return null; |
274 } catch (SecurityException e) { |
274 } catch (SecurityException e) { |
275 return null; |
275 return null; |
276 } |
276 } |
277 } |
277 } |
278 private static Method initValueElementMethod() { |
278 private static Method initValueElementMethod() { |
279 if (CONTAINED_BY_CLASS == null) |
279 if (REPEATABLE_CLASS == null) |
280 return null; |
280 return null; |
281 |
281 |
282 Method m = null; |
282 Method m = null; |
283 try { |
283 try { |
284 m = CONTAINED_BY_CLASS.getMethod("value"); |
284 m = REPEATABLE_CLASS.getMethod("value"); |
285 if (m != null) |
285 if (m != null) |
286 m.setAccessible(true); |
286 m.setAccessible(true); |
287 return m; |
287 return m; |
288 } catch (NoSuchMethodException e) { |
288 } catch (NoSuchMethodException e) { |
289 return null; |
289 return null; |
290 } |
290 } |
291 } |
291 } |
292 |
292 |
293 // Helper to getAnnotations |
293 // Helper to getAnnotations |
294 private static Class<? extends Annotation> getContainer(Class<? extends Annotation> annoType) { |
294 private static Class<? extends Annotation> getContainer(Class<? extends Annotation> annoType) { |
295 // Since we can not refer to java.lang.annotation.ContainedBy until we are |
295 // Since we can not refer to java.lang.annotation.Repeatable until we are |
296 // bootstrapping with java 8 we need to get the ContainedBy annotation using |
296 // bootstrapping with java 8 we need to get the Repeatable annotation using |
297 // reflective invocations instead of just using its type and element method. |
297 // reflective invocations instead of just using its type and element method. |
298 if (CONTAINED_BY_CLASS != null && |
298 if (REPEATABLE_CLASS != null && |
299 VALUE_ELEMENT_METHOD != null) { |
299 VALUE_ELEMENT_METHOD != null) { |
300 // Get the ContainedBy instance on the annotations declaration |
300 // Get the Repeatable instance on the annotations declaration |
301 Annotation containedBy = (Annotation)annoType.getAnnotation(CONTAINED_BY_CLASS); |
301 Annotation repeatable = (Annotation)annoType.getAnnotation(REPEATABLE_CLASS); |
302 if (containedBy != null) { |
302 if (repeatable != null) { |
303 try { |
303 try { |
304 // Get the value element, it should be a class |
304 // Get the value element, it should be a class |
305 // indicating the containing annotation type |
305 // indicating the containing annotation type |
306 @SuppressWarnings("unchecked") |
306 @SuppressWarnings("unchecked") |
307 Class<? extends Annotation> containerType = (Class)VALUE_ELEMENT_METHOD.invoke(containedBy); |
307 Class<? extends Annotation> containerType = (Class)VALUE_ELEMENT_METHOD.invoke(repeatable); |
308 if (containerType == null) |
308 if (containerType == null) |
309 return null; |
309 return null; |
310 |
310 |
311 return containerType; |
311 return containerType; |
312 } catch (ClassCastException e) { |
312 } catch (ClassCastException e) { |