package org.ocpsoft.rewrite.cdi.util;
import javax.enterprise.inject.spi.Annotated;
import javax.enterprise.inject.spi.AnnotatedField;
import javax.enterprise.inject.spi.AnnotatedType;
import javax.enterprise.inject.spi.BeanManager;
import javax.inject.Qualifier;
import java.beans.Introspector;
import java.io.Serializable;
import java.lang.annotation.Annotation;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.reflect.AccessibleObject;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Member;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.lang.reflect.TypeVariable;
import java.lang.reflect.WildcardType;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
public static final Annotation[] EMPTY_ANNOTATION_ARRAY = new Annotation[0];
public static final Object[] EMPTY_OBJECT_ARRAY = new Object[0];
public static final Type[] EMPTY_TYPES = {};
public static final Class<?>[] EMPTY_CLASSES = new Class<?>[0];
@SuppressWarnings("unchecked")
public static <T> T
cast(Object obj) {
return (T) obj;
}
HashSet<Field> fields = new HashSet<Field>();
for (Class<?> c = clazz; c != null && c != Object.class; c = c.getSuperclass()) {
for (Field a : c.getDeclaredFields()) {
fields.add(a);
}
}
return fields;
}
for (Class<?> c = clazz; c != null && c != Object.class; c = c.getSuperclass()) {
try {
return c.getDeclaredField(name);
} catch (NoSuchFieldException e) {
}
}
return null;
}
public static <X> AnnotatedField<?
super X>
getField(AnnotatedType<X> annotatedType, Field field) {
for (AnnotatedField<? super X> annotatedField : annotatedType.getFields()) {
if (annotatedField.getDeclaringType().getJavaClass().equals(field.getDeclaringClass()) && annotatedField.getJavaMember().getName().equals(field.getName())) {
return annotatedField;
}
}
return null;
}
Set<Annotation> set = new HashSet<Annotation>();
for (Annotation annotation : annotations) {
if (annotation.annotationType().isAnnotationPresent(metaAnnotationType)) {
set.add(annotation);
}
}
return set;
}
public static Set<Annotation>
getQualifiers(Set<Annotation> annotations, BeanManager beanManager) {
Set<Annotation> set = new HashSet<Annotation>();
for (Annotation annotation : annotations) {
if (beanManager.isQualifier(annotation.annotationType())) {
set.add(annotation);
}
}
return set;
}
public static boolean methodExists(Class<?> clazz, String name) {
for (Class<?> c = clazz; c != null && c != Object.class; c = c.getSuperclass()) {
for (Method m : c.getDeclaredMethods()) {
if (m.getName().equals(name)) {
return true;
}
}
}
return false;
}
HashSet<Method> methods = new HashSet<Method>();
for (Class<?> c = clazz; c != null && c != Object.class; c = c.getSuperclass()) {
for (Method a : c.getDeclaredMethods()) {
methods.add(a);
}
}
return methods;
}
for (Class<?> c = clazz; c != null && c != Object.class; c = c.getSuperclass()) {
try {
return c.getDeclaredMethod(name, args);
} catch (NoSuchMethodException e) {
}
}
return null;
}
for (Class<?> c = clazz; c != null && c != Object.class; c = c.getSuperclass()) {
try {
return c.getDeclaredConstructor(args);
} catch (NoSuchMethodException e) {
}
}
return null;
}
HashSet<Constructor<?>> constructors = new HashSet<Constructor<?>>();
for (Class<?> c = clazz; c != null && c != Object.class; c = c.getSuperclass()) {
for (Constructor<?> constructor : c.getDeclaredConstructors()) {
constructors.add(constructor);
}
}
return constructors;
}
if (member instanceof Field) {
return ((Field) member).getType();
} else if (member instanceof Method) {
return ((Method) member).getReturnType();
} else if (member instanceof Constructor<?>) {
return ((Constructor<?>) member).getDeclaringClass();
} else {
throw new UnsupportedOperationException("Cannot operate on a member of type " + member.getClass());
}
}
public static Class<?>
classForName(String name, ClassLoader... loaders)
throws ClassNotFoundException {
try {
if (Thread.currentThread().getContextClassLoader() != null) {
return Class.forName(name, true, Thread.currentThread().getContextClassLoader());
} else {
return Class.forName(name);
}
} catch (ClassNotFoundException e) {
for (ClassLoader l : loaders) {
try {
return Class.forName(name, true, l);
} catch (ClassNotFoundException ex) {
}
}
}
if (Thread.currentThread().getContextClassLoader() != null) {
throw new ClassNotFoundException("Could not load class " + name + " with the context class loader " + Thread.currentThread().getContextClassLoader().toString() + " or any of the additional ClassLoaders: " + Arrays.toString(loaders));
} else {
throw new ClassNotFoundException("Could not load class " + name + " using Class.forName or using any of the additional ClassLoaders: " + Arrays.toString(loaders));
}
}
StringBuilder message = new StringBuilder(String.format("Exception invoking method [%s] on object [%s], using arguments [", method.getName(), obj));
if (args != null)
for (int i = 0; i < args.length; i++)
message.append((i > 0 ? "," : "") + args[i]);
message.append("]");
return message.toString();
}
public static <A
extends AccessibleObject> A
setAccessible(A member) {
AccessController.doPrivileged(new SetAccessiblePriviligedAction(member));
return member;
}
public static Object
invokeMethod(Method method, Object instance, Object... args) {
return invokeMethod(false, method, Object.class, instance, args);
}
public static Object
invokeMethod(
boolean setAccessible, Method method, Object instance, Object... args) {
return invokeMethod(setAccessible, method, Object.class, instance, args);
}
public static <T> T
invokeMethod(Method method, Class<T> expectedReturnType, Object instance, Object... args) {
return invokeMethod(false, method, expectedReturnType, instance, args);
}
public static <T> T
invokeMethod(
boolean setAccessible, Method method, Class<T> expectedReturnType, Object instance, Object... args) {
if (setAccessible && !method.isAccessible()) {
setAccessible(method);
}
try {
return expectedReturnType.cast(method.invoke(instance, args));
} catch (IllegalAccessException ex) {
throw new RuntimeException(buildInvokeMethodErrorMessage(method, instance, args), ex);
} catch (IllegalArgumentException ex) {
throw new IllegalArgumentException(buildInvokeMethodErrorMessage(method, instance, args), ex);
} catch (InvocationTargetException ex) {
throw new RuntimeException(buildInvokeMethodErrorMessage(method, instance, args), ex.getCause());
} catch (NullPointerException ex) {
NullPointerException ex2 = new NullPointerException(buildInvokeMethodErrorMessage(method, instance, args));
ex2.initCause(ex.getCause());
throw ex2;
} catch (ExceptionInInitializerError e) {
ExceptionInInitializerError e2 = new ExceptionInInitializerError(buildInvokeMethodErrorMessage(method, instance, args));
e2.initCause(e.getCause());
throw e2;
}
}
public static void setFieldValue(Field field, Object instance, Object value) {
setFieldValue(false, field, instance, value);
}
public static void setFieldValue(
boolean setAccessible, Field field, Object instance, Object value) {
if (setAccessible && !field.isAccessible()) {
setAccessible(field);
}
try {
field.set(instance, value);
} catch (IllegalAccessException e) {
throw new RuntimeException(buildSetFieldValueErrorMessage(field, instance, value), e);
} catch (NullPointerException ex) {
NullPointerException ex2 = new NullPointerException(buildSetFieldValueErrorMessage(field, instance, value));
ex2.initCause(ex.getCause());
throw ex2;
} catch (ExceptionInInitializerError e) {
ExceptionInInitializerError e2 = new ExceptionInInitializerError(buildSetFieldValueErrorMessage(field, instance, value));
e2.initCause(e.getCause());
throw e2;
}
}
return String.format("Exception setting [%s] field on object [%s] to value [%s]", field.getName(), obj, value);
}
return String.format("Exception reading [%s] field from object [%s].", field.getName(), obj);
}
public static Object
getFieldValue(Field field, Object instance) {
return getFieldValue(field, instance, Object.class);
}
public static <T> T
getFieldValue(Field field, Object instance, Class<T> expectedType) {
try {
return Reflections.cast(field.get(instance));
} catch (IllegalAccessException e) {
throw new RuntimeException(buildGetFieldValueErrorMessage(field, instance), e);
} catch (NullPointerException ex) {
NullPointerException ex2 = new NullPointerException(buildGetFieldValueErrorMessage(field, instance));
ex2.initCause(ex.getCause());
throw ex2;
} catch (ExceptionInInitializerError e) {
ExceptionInInitializerError e2 = new ExceptionInInitializerError(buildGetFieldValueErrorMessage(field, instance));
e2.initCause(e.getCause());
throw e2;
}
}
@SuppressWarnings("unchecked")
public static <T> Class<T>
getRawType(Type type) {
if (type instanceof Class<?>) {
return (Class<T>) type;
} else if (type instanceof ParameterizedType) {
if (((ParameterizedType) type).getRawType() instanceof Class<?>) {
return (Class<T>) ((ParameterizedType) type).getRawType();
}
}
return null;
}
return clazz.isPrimitive() || Serializable.class.isAssignableFrom(clazz);
}
public static Map<Class<?>, Type>
buildTypeMap(Set<Type> types) {
Map<Class<?>, Type> map = new HashMap<Class<?>, Type>();
for (Type type : types) {
if (type instanceof Class<?>) {
map.put((Class<?>) type, type);
} else if (type instanceof ParameterizedType) {
if (((ParameterizedType) type).getRawType() instanceof Class<?>) {
map.put((Class<?>) ((ParameterizedType) type).getRawType(), type);
}
} else if (type instanceof TypeVariable<?>) {
}
}
return map;
}
public static boolean isCacheable(Set<Annotation> annotations) {
for (Annotation qualifier : annotations) {
Class<?> clazz = qualifier.getClass();
if (clazz.isAnonymousClass() || (clazz.isMemberClass() && isStatic(clazz))) {
return false;
}
}
return true;
}
public static boolean isCacheable(Annotation[] annotations) {
for (Annotation qualifier : annotations) {
Class<?> clazz = qualifier.getClass();
if (clazz.isAnonymousClass() || (clazz.isMemberClass() && isStatic(clazz))) {
return false;
}
}
return true;
}
String methodName = method.getName();
if (methodName.matches("^(get).*")) {
return Introspector.decapitalize(methodName.substring(3));
} else if (methodName.matches("^(is).*")) {
return Introspector.decapitalize(methodName.substring(2));
} else {
return null;
}
}
public static boolean isFinal(Class<?> clazz) {
return Modifier.isFinal(clazz.getModifiers());
}
if (clazz.isMemberClass() && !isStatic(clazz)) {
return 1 + getNesting(clazz.getDeclaringClass());
} else {
return 0;
}
}
public static boolean isFinal(Member member) {
return Modifier.isFinal(member.getModifiers());
}
public static boolean isPrivate(Member member) {
return Modifier.isPrivate(member.getModifiers());
}
return getNonPrivateFinalMethodOrType(type) != null;
}
if (isFinal(type)) {
return type;
}
for (Method method : type.getDeclaredMethods()) {
if (isFinal(method) && !isPrivate(method)) {
return method;
}
}
return null;
}
return !(Modifier.isPrivate(mod) || Modifier.isProtected(mod) || Modifier.isPublic(mod));
}
public static boolean isStatic(Class<?> type) {
return Modifier.isStatic(type.getModifiers());
}
public static boolean isStatic(Member member) {
return Modifier.isStatic(member.getModifiers());
}
return Modifier.isTransient(member.getModifiers());
}
return Modifier.isAbstract(method.getModifiers());
}
Type type = new HierarchyDiscovery(clazz).getResolvedType();
if (type instanceof ParameterizedType) {
return ((ParameterizedType) type).getActualTypeArguments();
} else {
return EMPTY_TYPES;
}
}
Type resolvedType = new HierarchyDiscovery(type).getResolvedType();
if (resolvedType instanceof ParameterizedType) {
return ((ParameterizedType) resolvedType).getActualTypeArguments();
} else {
return EMPTY_TYPES;
}
}
return rawType.isArray();
}
return type.getTypeParameters().length > 0;
}
if (isParameterizedType(type)) {
return containsWildcards(type.getTypeParameters());
} else {
return false;
}
}
for (Type type : types) {
if (type instanceof WildcardType) {
return true;
}
}
return false;
}
@Deprecated
public static boolean isBindings(Annotation binding) {
boolean isBindingAnnotation = false;
if (binding.annotationType().isAnnotationPresent(Qualifier.class) && binding.annotationType().isAnnotationPresent(Retention.class) && binding.annotationType().getAnnotation(Retention.class).value().equals(RetentionPolicy.RUNTIME)) {
isBindingAnnotation = true;
}
return isBindingAnnotation;
}
public static boolean isAssignableFrom(Class<?> rawType1, Type[] actualTypeArguments1, Class<?> rawType2, Type[] actualTypeArguments2) {
return Types.boxedClass(rawType1).isAssignableFrom(Types.boxedClass(rawType2)) && isAssignableFrom(actualTypeArguments1, actualTypeArguments2);
}
public static boolean matches(Class<?> rawType1, Type[] actualTypeArguments1, Class<?> rawType2, Type[] actualTypeArguments2) {
return Types.boxedClass(rawType1).equals(Types.boxedClass(rawType2)) && isAssignableFrom(actualTypeArguments1, actualTypeArguments2);
}
public static boolean isAssignableFrom(Type[] actualTypeArguments1, Type[] actualTypeArguments2) {
for (int i = 0; i < actualTypeArguments1.length; i++) {
Type type1 = actualTypeArguments1[i];
Type type2 = Object.class;
if (actualTypeArguments2.length > i) {
type2 = actualTypeArguments2[i];
}
if (!isAssignableFrom(type1, type2)) {
return false;
}
}
return true;
}
public static boolean isAssignableFrom(Type type1, Set<?
extends Type> types2) {
for (Type type2 : types2) {
if (isAssignableFrom(type1, type2)) {
return true;
}
}
return false;
}
public static boolean matches(Type type1, Set<?
extends Type> types2) {
for (Type type2 : types2) {
if (matches(type1, type2)) {
return true;
}
}
return false;
}
for (Type type2 : types2) {
if (isAssignableFrom(type1, type2)) {
return true;
}
}
return false;
}
if (type1 instanceof Class<?>) {
Class<?> clazz = (Class<?>) type1;
if (isAssignableFrom(clazz, EMPTY_TYPES, type2)) {
return true;
}
}
if (type1 instanceof ParameterizedType) {
ParameterizedType parameterizedType1 = (ParameterizedType) type1;
if (parameterizedType1.getRawType() instanceof Class<?>) {
if (isAssignableFrom((Class<?>) parameterizedType1.getRawType(), parameterizedType1.getActualTypeArguments(), type2)) {
return true;
}
}
}
if (type1 instanceof WildcardType) {
WildcardType wildcardType = (WildcardType) type1;
if (isTypeBounded(type2, wildcardType.getLowerBounds(), wildcardType.getUpperBounds())) {
return true;
}
}
if (type2 instanceof WildcardType) {
WildcardType wildcardType = (WildcardType) type2;
if (isTypeBounded(type1, wildcardType.getUpperBounds(), wildcardType.getLowerBounds())) {
return true;
}
}
if (type1 instanceof TypeVariable<?>) {
TypeVariable<?> typeVariable = (TypeVariable<?>) type1;
if (isTypeBounded(type2, EMPTY_TYPES, typeVariable.getBounds())) {
return true;
}
}
if (type2 instanceof TypeVariable<?>) {
TypeVariable<?> typeVariable = (TypeVariable<?>) type2;
if (isTypeBounded(type1, typeVariable.getBounds(), EMPTY_TYPES)) {
return true;
}
}
return false;
}
public static boolean matches(Type type1, Type type2) {
if (type1 instanceof Class<?>) {
Class<?> clazz = (Class<?>) type1;
if (matches(clazz, EMPTY_TYPES, type2)) {
return true;
}
}
if (type1 instanceof ParameterizedType) {
ParameterizedType parameterizedType1 = (ParameterizedType) type1;
if (parameterizedType1.getRawType() instanceof Class<?>) {
if (matches((Class<?>) parameterizedType1.getRawType(), parameterizedType1.getActualTypeArguments(), type2)) {
return true;
}
}
}
if (type1 instanceof WildcardType) {
WildcardType wildcardType = (WildcardType) type1;
if (isTypeBounded(type2, wildcardType.getLowerBounds(), wildcardType.getUpperBounds())) {
return true;
}
}
if (type2 instanceof WildcardType) {
WildcardType wildcardType = (WildcardType) type2;
if (isTypeBounded(type1, wildcardType.getUpperBounds(), wildcardType.getLowerBounds())) {
return true;
}
}
if (type1 instanceof TypeVariable<?>) {
TypeVariable<?> typeVariable = (TypeVariable<?>) type1;
if (isTypeBounded(type2, EMPTY_TYPES, typeVariable.getBounds())) {
return true;
}
}
if (type2 instanceof TypeVariable<?>) {
TypeVariable<?> typeVariable = (TypeVariable<?>) type2;
if (isTypeBounded(type1, typeVariable.getBounds(), EMPTY_TYPES)) {
return true;
}
}
return false;
}
public static boolean isTypeBounded(Type type, Type[] lowerBounds, Type[] upperBounds) {
if (lowerBounds.length > 0) {
if (!isAssignableFrom(type, lowerBounds)) {
return false;
}
}
if (upperBounds.length > 0) {
if (!isAssignableFrom(upperBounds, type)) {
return false;
}
}
return true;
}
public static boolean isAssignableFrom(Class<?> rawType1, Type[] actualTypeArguments1, Type type2) {
if (type2 instanceof ParameterizedType) {
ParameterizedType parameterizedType = (ParameterizedType) type2;
if (parameterizedType.getRawType() instanceof Class<?>) {
if (isAssignableFrom(rawType1, actualTypeArguments1, (Class<?>) parameterizedType.getRawType(), parameterizedType.getActualTypeArguments())) {
return true;
}
}
} else if (type2 instanceof Class<?>) {
Class<?> clazz = (Class<?>) type2;
if (isAssignableFrom(rawType1, actualTypeArguments1, clazz, EMPTY_TYPES)) {
return true;
}
} else if (type2 instanceof TypeVariable<?>) {
TypeVariable<?> typeVariable = (TypeVariable<?>) type2;
if (isTypeBounded(rawType1, actualTypeArguments1, typeVariable.getBounds())) {
return true;
}
}
return false;
}
public static boolean matches(Class<?> rawType1, Type[] actualTypeArguments1, Type type2) {
if (type2 instanceof ParameterizedType) {
ParameterizedType parameterizedType = (ParameterizedType) type2;
if (parameterizedType.getRawType() instanceof Class<?>) {
if (matches(rawType1, actualTypeArguments1, (Class<?>) parameterizedType.getRawType(), parameterizedType.getActualTypeArguments())) {
return true;
}
}
} else if (type2 instanceof Class<?>) {
Class<?> clazz = (Class<?>) type2;
if (matches(rawType1, actualTypeArguments1, clazz, EMPTY_TYPES)) {
return true;
}
}
return false;
}
for (Type type : types1) {
if (isAssignableFrom(type, types2)) {
return true;
}
}
return false;
}
public static boolean matches(Set<Type> types1, Set<Type> types2) {
for (Type type : types1) {
if (matches(type, types2)) {
return true;
}
}
return false;
}
for (Type type : types1) {
if (isAssignableFrom(type, type2)) {
return true;
}
}
return false;
}
for (Type type : types1) {
if (isAssignableFrom(type, type2)) {
return true;
}
}
return false;
}
Class<?> rawType = getRawType(type);
return rawType == null ? false : rawType.isPrimitive();
}
}
}