/** * {@inheritDoc} */ @SuppressWarnings("unchecked") public <T extends Annotation> Loadable<T> prepare(Class<T> annotationType) { if (!annotation.annotationType().getName().equals(annotationType.getName())) { throw new IllegalArgumentException(annotationType + " does not represent " + annotation.annotationType()); } return annotationType == annotation.annotationType() ? (Loadable<T>) this : new ForLoadedAnnotation<T>((T) annotation, annotationType); }
/** * {@inheritDoc} */ @SuppressWarnings("deprecation") // Due to isAccessible() call. @SuppressFBWarnings(value = "REC_CATCH_EXCEPTION", justification = "Exception should always be wrapped for clarity") public AnnotationValue<?, ?> getValue(MethodDescription.InDefinedShape property) { if (!property.getDeclaringType().represents(annotation.annotationType())) { throw new IllegalArgumentException(property + " does not represent " + annotation.annotationType()); } try { boolean accessible = property.getDeclaringType().isPublic(); // method is required to be public Method method = property instanceof MethodDescription.ForLoadedMethod ? ((MethodDescription.ForLoadedMethod) property).getLoadedMethod() : null; if (method == null || method.getDeclaringClass() != annotation.annotationType() || (!accessible && !method.isAccessible())) { method = annotation.annotationType().getMethod(property.getName()); if (!accessible) { AccessController.doPrivileged(new SetAccessibleAction<Method>(method)); } } return asValue(method.invoke(annotation), method.getReturnType()); } catch (InvocationTargetException exception) { throw new IllegalStateException("Error reading annotation property " + property, exception.getCause()); } catch (Exception exception) { throw new IllegalStateException("Cannot access annotation property " + property, exception); } }
/** * {@inheritDoc} */ public AnnotationDescription get(int index) { return AnnotationDescription.ForLoadedAnnotation.of(annotations.get(index)); }
return AnnotationValue.ForAnnotationDescription.<Annotation>of(TypeDescription.ForLoadedType.of(type), asValue((Annotation) value)); } else if (Annotation[].class.isAssignableFrom(type)) { Annotation[] element = (Annotation[]) value; int index = 0; for (Annotation anElement : element) { annotationDescription[index++] = new AnnotationDescription.Latent(TypeDescription.ForLoadedType.of(type.getComponentType()), asValue(anElement));
/** * Extracts the annotation values of an annotation into a property map. * * @param annotation The annotation to convert. * @return A mapping of property names to their annotation value. */ private static Map<String, AnnotationValue<?, ?>> asValue(Annotation annotation) { Map<String, AnnotationValue<?, ?>> annotationValues = new HashMap<String, AnnotationValue<?, ?>>(); for (Method property : annotation.annotationType().getDeclaredMethods()) { try { annotationValues.put(property.getName(), asValue(property.invoke(annotation), property.getReturnType())); } catch (InvocationTargetException exception) { throw new IllegalStateException("Cannot read " + property, exception.getCause()); } catch (IllegalAccessException exception) { throw new IllegalStateException("Cannot access " + property, exception); } } return annotationValues; }
/** * {@inheritDoc} */ public <W> MethodDefinition.ReceiverTypeDefinition<V> defaultValue(W value, Class<? extends W> type) { return defaultValue(AnnotationDescription.ForLoadedAnnotation.asValue(value, type)); } }
/** * {@inheritDoc} */ public ParameterBinding<?> bind(MethodDescription source, Implementation.Target implementationTarget, Assigner assigner) { return Argument.Binder.INSTANCE.bind(AnnotationDescription.ForLoadedAnnotation.<Argument>of(new DefaultArgument(target.getIndex())), source, target, implementationTarget, assigner, typing); }
/** * Returns a builder with the additional annotation property. * * @param property The name of the property to define. * @param annotation The annotation value to define. * @return A builder with the additional annotation property. */ public Builder define(String property, Annotation annotation) { return define(property, new ForLoadedAnnotation<Annotation>(annotation)); }
/** * {@inheritDoc} */ public AnnotationValue<?, ?> getDefaultValue() { Object value = method.getDefaultValue(); return value == null ? AnnotationValue.UNDEFINED : AnnotationDescription.ForLoadedAnnotation.asValue(value, method.getReturnType()); }
/** * Creates a description of the given annotation. * * @param annotation The annotation to be described. * @param <U> The type of the annotation. * @return A description of the given annotation. */ public static <U extends Annotation> Loadable<U> of(U annotation) { return new ForLoadedAnnotation<U>(annotation); }
/** * Exactly matches a given annotation as an {@link AnnotationDescription}. * * @param annotation The annotation to match by its description. * @param <T> The type of the matched object. * @return An element matcher that exactly matches the given annotation. */ public static <T extends AnnotationDescription> ElementMatcher.Junction<T> is(Annotation annotation) { return is(AnnotationDescription.ForLoadedAnnotation.of(annotation)); }
/** * {@inheritDoc} */ public S load() throws ClassNotFoundException { return annotationType == annotation.annotationType() ? annotation : AnnotationInvocationHandler.of(annotationType.getClassLoader(), annotationType, asValue(annotation)); }
/** * Creates a default value for the given method. * * @param method The method from which to attempt the extraction of a default value. * @return A default value representation. */ private static AnnotationValue<?, ?> defaultValueOf(Method method) { Object defaultValue = method.getDefaultValue(); return defaultValue == null ? MissingValue.of(method) : AnnotationDescription.ForLoadedAnnotation.asValue(defaultValue, method.getReturnType()); }