All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.infinispan.cdi.common.util.Annotateds Maven / Gradle / Ivy

The newest version!
package org.infinispan.cdi.common.util;

import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Set;

import jakarta.enterprise.inject.spi.Annotated;
import jakarta.enterprise.inject.spi.AnnotatedCallable;
import jakarta.enterprise.inject.spi.AnnotatedConstructor;
import jakarta.enterprise.inject.spi.AnnotatedField;
import jakarta.enterprise.inject.spi.AnnotatedMethod;
import jakarta.enterprise.inject.spi.AnnotatedParameter;
import jakarta.enterprise.inject.spi.AnnotatedType;

/**
 * 

* Utilities for working with {@link Annotated}s. *

*

*

* Includes utilities to check the equality of and create unique id's for * Annotated instances. *

* * @author Stuart Douglas <[email protected]> */ public class Annotateds { /** * Does the first stage of comparing AnnoatedCallables, however it cannot * compare the method parameters */ private static class AnnotatedCallableComparator implements Comparator> { public int compare(AnnotatedCallable arg0, AnnotatedCallable arg1) { // compare the names first int result = (arg0.getJavaMember().getName().compareTo(arg1.getJavaMember().getName())); if (result != 0) { return result; } result = arg0.getJavaMember().getDeclaringClass().getName().compareTo(arg1.getJavaMember().getDeclaringClass().getName()); if (result != 0) { return result; } result = arg0.getParameters().size() - arg1.getParameters().size(); return result; } } private static class AnnotatedMethodComparator implements Comparator> { public static Comparator> instance() { return new AnnotatedMethodComparator(); } private AnnotatedCallableComparator callableComparator = new AnnotatedCallableComparator(); public int compare(AnnotatedMethod arg0, AnnotatedMethod arg1) { int result = callableComparator.compare(arg0, arg1); if (result != 0) { return result; } for (int i = 0; i < arg0.getJavaMember().getParameterCount(); ++i) { Class p0 = arg0.getJavaMember().getParameterTypes()[i]; Class p1 = arg1.getJavaMember().getParameterTypes()[i]; result = p0.getName().compareTo(p1.getName()); if (result != 0) { return result; } } return 0; } } private static class AnnotatedConstructorComparator implements Comparator> { public static Comparator> instance() { return new AnnotatedConstructorComparator(); } private AnnotatedCallableComparator callableComparator = new AnnotatedCallableComparator(); public int compare(AnnotatedConstructor arg0, AnnotatedConstructor arg1) { int result = callableComparator.compare(arg0, arg1); if (result != 0) { return result; } for (int i = 0; i < arg0.getJavaMember().getParameterCount(); ++i) { Class p0 = arg0.getJavaMember().getParameterTypes()[i]; Class p1 = arg1.getJavaMember().getParameterTypes()[i]; result = p0.getName().compareTo(p1.getName()); if (result != 0) { return result; } } return 0; } } private static class AnnotatedFieldComparator implements Comparator> { public static Comparator> instance() { return new AnnotatedFieldComparator(); } public int compare(AnnotatedField arg0, AnnotatedField arg1) { if (arg0.getJavaMember().getName().equals(arg1.getJavaMember().getName())) { return arg0.getJavaMember().getDeclaringClass().getName().compareTo(arg1.getJavaMember().getDeclaringClass().getName()); } return arg0.getJavaMember().getName().compareTo(arg1.getJavaMember().getName()); } } private static class AnnotationComparator implements Comparator { public static final Comparator INSTANCE = new AnnotationComparator(); public int compare(Annotation arg0, Annotation arg1) { return arg0.annotationType().getName().compareTo(arg1.annotationType().getName()); } } private static class MethodComparator implements Comparator { public static final Comparator INSTANCE = new MethodComparator(); public int compare(Method arg0, Method arg1) { return arg0.getName().compareTo(arg1.getName()); } } private static final char SEPERATOR = ';'; private Annotateds() { } /** * Generates a deterministic signature for an {@link AnnotatedType}. Two * AnnotatedTypes that have the same annotations and underlying * type will generate the same signature. *

* This can be used to create a unique bean id for a passivation capable bean * that is added directly through the SPI. * * @param annotatedType The type to generate a signature for * @return A string representation of the annotated type */ public static String createTypeId(AnnotatedType annotatedType) { return createTypeId(annotatedType.getJavaClass(), annotatedType.getAnnotations(), annotatedType.getMethods(), annotatedType.getFields(), annotatedType.getConstructors()); } /** * Generates a unique signature for a concrete class. Annotations are not * read directly from the class, but are read from the * annotations, methods, fields and * constructors arguments * * @param clazz The java class tyoe * @param annotations Annotations present on the java class * @param methods The AnnotatedMethods to include in the signature * @param fields The AnnotatedFields to include in the signature * @param constructors The AnnotatedConstructors to include in the signature * @return A string representation of the type */ public static String createTypeId(Class clazz, Collection annotations, Collection> methods, Collection> fields, Collection> constructors) { StringBuilder builder = new StringBuilder(); builder.append(clazz.getName()); builder.append(createAnnotationCollectionId(annotations)); builder.append("{"); // now deal with the fields List> sortedFields = new ArrayList>(); sortedFields.addAll(fields); Collections.sort(sortedFields, AnnotatedFieldComparator.instance()); for (AnnotatedField field : sortedFields) { if (!field.getAnnotations().isEmpty()) { builder.append(createFieldId(field)); builder.append(SEPERATOR); } } // methods List> sortedMethods = new ArrayList>(); sortedMethods.addAll(methods); Collections.sort(sortedMethods, AnnotatedMethodComparator.instance()); for (AnnotatedMethod method : sortedMethods) { if (!method.getAnnotations().isEmpty() || hasMethodParameters(method)) { builder.append(createCallableId(method)); builder.append(SEPERATOR); } } // constructors List> sortedConstructors = new ArrayList>(); sortedConstructors.addAll(constructors); Collections.sort(sortedConstructors, AnnotatedConstructorComparator.instance()); for (AnnotatedConstructor constructor : sortedConstructors) { if (!constructor.getAnnotations().isEmpty() || hasMethodParameters(constructor)) { builder.append(createCallableId(constructor)); builder.append(SEPERATOR); } } builder.append("}"); return builder.toString(); } /** * Generates a deterministic signature for an {@link AnnotatedField}. Two * AnnotatedFields that have the same annotations and * underlying field will generate the same signature. */ public static String createFieldId(AnnotatedField field) { return createFieldId(field.getJavaMember(), field.getAnnotations()); } /** * Creates a deterministic signature for a {@link Field}. * * @param field The field to generate the signature for * @param annotations The annotations to include in the signature */ public static String createFieldId(Field field, Collection annotations) { StringBuilder builder = new StringBuilder(); builder.append(field.getDeclaringClass().getName()); builder.append('.'); builder.append(field.getName()); builder.append(createAnnotationCollectionId(annotations)); return builder.toString(); } /** * Generates a deterministic signature for an {@link AnnotatedCallable}. Two * AnnotatedCallables that have the same annotations and * underlying callable will generate the same signature. */ public static String createCallableId(AnnotatedCallable method) { StringBuilder builder = new StringBuilder(); builder.append(method.getJavaMember().getDeclaringClass().getName()); builder.append('.'); builder.append(method.getJavaMember().getName()); builder.append(createAnnotationCollectionId(method.getAnnotations())); builder.append(createParameterListId(method.getParameters())); return builder.toString(); } /** * Generates a unique string representation of a list of * {@link AnnotatedParameter}s. */ public static String createParameterListId(List> parameters) { StringBuilder builder = new StringBuilder(); builder.append("("); for (int i = 0; i < parameters.size(); ++i) { AnnotatedParameter ap = parameters.get(i); builder.append(createParameterId(ap)); if (i + 1 != parameters.size()) { builder.append(','); } } builder.append(")"); return builder.toString(); } /** * Creates a string representation of an {@link AnnotatedParameter}. */ public static String createParameterId(AnnotatedParameter annotatedParameter) { return createParameterId(annotatedParameter.getBaseType(), annotatedParameter.getAnnotations()); } /** * Creates a string representation of a given type and set of annotations. */ public static String createParameterId(Type type, Set annotations) { StringBuilder builder = new StringBuilder(); if (type instanceof Class) { Class c = (Class) type; builder.append(c.getName()); } else { builder.append(type.toString()); } builder.append(createAnnotationCollectionId(annotations)); return builder.toString(); } private static boolean hasMethodParameters(AnnotatedCallable callable) { for (AnnotatedParameter parameter : callable.getParameters()) { if (!parameter.getAnnotations().isEmpty()) { return true; } } return false; } private static String createAnnotationCollectionId(Collection annotations) { if (annotations.isEmpty()) { return ""; } StringBuilder builder = new StringBuilder(); builder.append('['); List annotationList = new ArrayList(annotations.size()); annotationList.addAll(annotations); Collections.sort(annotationList, AnnotationComparator.INSTANCE); for (Annotation a : annotationList) { builder.append('@'); builder.append(a.annotationType().getName()); builder.append('('); Method[] declaredMethods = a.annotationType().getDeclaredMethods(); List methods = new ArrayList(declaredMethods.length); for (Method m : declaredMethods) { methods.add(m); } Collections.sort(methods, MethodComparator.INSTANCE); for (int i = 0; i < methods.size(); ++i) { Method method = methods.get(i); try { Object value = method.invoke(a); builder.append(method.getName()); builder.append('='); builder.append(value.toString()); } catch (NullPointerException e) { throw new RuntimeException("NullPointerException accessing annotation member, annotation:" + a.annotationType().getName() + " member: " + method.getName(), e); } catch (IllegalArgumentException e) { throw new RuntimeException("IllegalArgumentException accessing annotation member, annotation:" + a.annotationType().getName() + " member: " + method.getName(), e); } catch (IllegalAccessException e) { throw new RuntimeException("IllegalAccessException accessing annotation member, annotation:" + a.annotationType().getName() + " member: " + method.getName(), e); } catch (InvocationTargetException e) { throw new RuntimeException("InvocationTargetException accessing annotation member, annotation:" + a.annotationType().getName() + " member: " + method.getName(), e); } if (i + 1 != methods.size()) { builder.append(','); } } builder.append(')'); } builder.append(']'); return builder.toString(); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy