package com.miragesql.miragesql.util;
import java.lang.reflect.Array;
import java.lang.reflect.GenericArrayType;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.lang.reflect.WildcardType;
import java.util.List;
public abstract class GenericUtil {
protected GenericUtil() {
}
public static boolean isTypeOf(final Type type, final Class<?> clazz) {
if (Class.class.isInstance(type)) {
return clazz.isAssignableFrom(Class.class.cast(type));
}
if (ParameterizedType.class.isInstance(type)) {
final ParameterizedType parameterizedType = ParameterizedType.class
.cast(type);
return isTypeOf(parameterizedType.getRawType(), clazz);
}
return false;
}
public static Class<?> getRawClass(final Type type) {
if (Class.class.isInstance(type)) {
return Class.class.cast(type);
}
if (ParameterizedType.class.isInstance(type)) {
final ParameterizedType parameterizedType = ParameterizedType.class
.cast(type);
return getRawClass(parameterizedType.getRawType());
}
if (WildcardType.class.isInstance(type)) {
final WildcardType wildcardType = WildcardType.class.cast(type);
final Type[] types = wildcardType.getUpperBounds();
return getRawClass(types[0]);
}
if (GenericArrayType.class.isInstance(type)) {
final GenericArrayType genericArrayType = GenericArrayType.class
.cast(type);
final Class<?> rawClass = getRawClass(genericArrayType
.getGenericComponentType());
return Array.newInstance(rawClass, 0).getClass();
}
return null;
}
public static Type[] getGenericParameter(final Type type) {
if (ParameterizedType.class.isInstance(type)) {
return ParameterizedType.class.cast(type).getActualTypeArguments();
}
if (GenericArrayType.class.isInstance(type)) {
return getGenericParameter(GenericArrayType.class.cast(type)
.getGenericComponentType());
}
return null;
}
public static Type getGenericParameter(final Type type, final int index) {
if (!ParameterizedType.class.isInstance(type)) {
return null;
}
final Type[] genericParameter = getGenericParameter(type);
if (genericParameter == null) {
return null;
}
return genericParameter[index];
}
public static Type getElementTypeOfList(final Type type) {
if (!isTypeOf(type, List.class)) {
return null;
}
return getGenericParameter(type, 0);
}
}