/** * Creates a proxy instance for the supplied annotation type and values. * * @param classLoader The class loader that should be used for loading the annotation's values. * @param annotationType The annotation's type. * @param values The values that the annotation contains. * @param <S> The type of the handled annotation. * @return A proxy for the annotation type and values. * @throws ClassNotFoundException If the class of an instance that is contained by this annotation could not be found. */ @SuppressWarnings("unchecked") public static <S extends Annotation> S of(ClassLoader classLoader, Class<S> annotationType, Map<String, ? extends AnnotationValue<?, ?>> values) throws ClassNotFoundException { LinkedHashMap<Method, AnnotationValue.Loaded<?>> loadedValues = new LinkedHashMap<Method, AnnotationValue.Loaded<?>>(); for (Method method : annotationType.getDeclaredMethods()) { AnnotationValue<?, ?> annotationValue = values.get(method.getName()); loadedValues.put(method, (annotationValue == null ? defaultValueOf(method) : annotationValue).load(classLoader)); } return (S) Proxy.newProxyInstance(classLoader, new Class<?>[]{annotationType}, new AnnotationInvocationHandler<S>(annotationType, loadedValues)); }
/** * {@inheritDoc} */ public Object invoke(Object proxy, Method method, Object[] argument) { if (method.getDeclaringClass() != annotationType) { if (method.getName().equals(HASH_CODE)) { return hashCodeRepresentation(); } else if (method.getName().equals(EQUALS) && method.getParameterTypes().length == 1) { return equalsRepresentation(proxy, argument[0]); } else if (method.getName().equals(TO_STRING)) { return toStringRepresentation(); } else /* if (method.getName().equals("annotationType")) */ { return annotationType; } } Object value = values.get(method).resolve(); if (!asWrapper(method.getReturnType()).isAssignableFrom(value.getClass())) { throw new AnnotationTypeMismatchException(method, value.getClass().toString()); } return value; }
/** * {@inheritDoc} */ public S load() throws ClassNotFoundException { return AnnotationInvocationHandler.of(annotationType.getClassLoader(), annotationType, values); }
/** * {@inheritDoc} */ @SuppressWarnings("unchecked") public Loaded<Annotation> load(ClassLoader classLoader) throws ClassNotFoundException { Class<?> type = Class.forName(annotationToken.getBinaryName(), false, classLoader); if (type.isAnnotation()) { return new ForAnnotationDescription.Loaded<Annotation>(AnnotationDescription.AnnotationInvocationHandler.of(classLoader, (Class<? extends Annotation>) type, annotationToken.getValues())); } else { return new ForAnnotationDescription.IncompatibleRuntimeType(type); } }
/** * {@inheritDoc} */ public S load() throws ClassNotFoundException { return annotationType == annotation.annotationType() ? annotation : AnnotationInvocationHandler.of(annotationType.getClassLoader(), annotationType, asValue(annotation)); }
/** * {@inheritDoc} */ public S load() throws ClassNotFoundException { return AnnotationDescription.AnnotationInvocationHandler.of(annotationType.getClassLoader(), annotationType, annotationValues); }