use of java.lang.reflect.TypeVariable in project Entitas-Java by Rubentxu.
the class TypeResolver method getTypeVariableMap.
private static Map<TypeVariable<?>, Type> getTypeVariableMap(final Class<?> targetType, Class<?> functionalInterface) {
Reference<Map<TypeVariable<?>, Type>> ref = TYPE_VARIABLE_CACHE.get(targetType);
Map<TypeVariable<?>, Type> map = ref != null ? ref.get() : null;
if (map == null) {
map = new HashMap<TypeVariable<?>, Type>();
// Populate lambdas
if (functionalInterface != null)
populateLambdaArgs(functionalInterface, targetType, map);
// Populate interfaces
populateSuperTypeArgs(targetType.getGenericInterfaces(), map, functionalInterface != null);
// Populate super classes and interfaces
Type genericType = targetType.getGenericSuperclass();
Class<?> type = targetType.getSuperclass();
while (type != null && !Object.class.equals(type)) {
if (genericType instanceof ParameterizedType)
populateTypeArgs((ParameterizedType) genericType, map, false);
populateSuperTypeArgs(type.getGenericInterfaces(), map, false);
genericType = type.getGenericSuperclass();
type = type.getSuperclass();
}
// Populate enclosing classes
type = targetType;
while (type.isMemberClass()) {
genericType = type.getGenericSuperclass();
if (genericType instanceof ParameterizedType)
populateTypeArgs((ParameterizedType) genericType, map, functionalInterface != null);
type = type.getEnclosingClass();
}
if (CACHE_ENABLED)
TYPE_VARIABLE_CACHE.put(targetType, new WeakReference<Map<TypeVariable<?>, Type>>(map));
}
return map;
}
use of java.lang.reflect.TypeVariable in project Entitas-Java by Rubentxu.
the class TypeResolver method populateLambdaArgs.
/**
* Populates the {@code map} with variable/argument pairs for the {@code functionalInterface}.
*/
private static void populateLambdaArgs(Class<?> functionalInterface, final Class<?> lambdaType, Map<TypeVariable<?>, Type> map) {
if (RESOLVES_LAMBDAS) {
// Find SAM
for (Method m : functionalInterface.getMethods()) {
if (!isDefaultMethod(m) && !Modifier.isStatic(m.getModifiers()) && !m.isBridge()) {
// Skip methods that override Object.class
Method objectMethod = OBJECT_METHODS.get(m.getName());
if (objectMethod != null && Arrays.equals(m.getTypeParameters(), objectMethod.getTypeParameters()))
continue;
// Get functional interface's type params
Type returnTypeVar = m.getGenericReturnType();
Type[] paramTypeVars = m.getGenericParameterTypes();
Member member = getMemberRef(lambdaType);
if (member == null)
return;
// Populate return type argument
if (returnTypeVar instanceof TypeVariable) {
Class<?> returnType = member instanceof Method ? ((Method) member).getReturnType() : ((Constructor<?>) member).getDeclaringClass();
returnType = wrapPrimitives(returnType);
if (!returnType.equals(Void.class))
map.put((TypeVariable<?>) returnTypeVar, returnType);
}
Class<?>[] arguments = member instanceof Method ? ((Method) member).getParameterTypes() : ((Constructor<?>) member).getParameterTypes();
// Populate object type from arbitrary object method reference
int paramOffset = 0;
if (paramTypeVars.length > 0 && paramTypeVars[0] instanceof TypeVariable && paramTypeVars.length == arguments.length + 1) {
Class<?> instanceType = member.getDeclaringClass();
map.put((TypeVariable<?>) paramTypeVars[0], instanceType);
paramOffset = 1;
}
// Handle additional arguments that are captured from the lambda's enclosing scope
int argOffset = 0;
if (paramTypeVars.length < arguments.length) {
argOffset = arguments.length - paramTypeVars.length;
}
// Populate type arguments
for (int i = 0; i + argOffset < arguments.length; i++) {
if (paramTypeVars[i] instanceof TypeVariable)
map.put((TypeVariable<?>) paramTypeVars[i + paramOffset], wrapPrimitives(arguments[i + argOffset]));
}
return;
}
}
}
}
use of java.lang.reflect.TypeVariable in project Entitas-Java by Rubentxu.
the class TypeResolver method resolveRawClass.
private static Class<?> resolveRawClass(Type genericType, Class<?> subType, Class<?> functionalInterface) {
if (genericType instanceof Class) {
return (Class<?>) genericType;
} else if (genericType instanceof ParameterizedType) {
return resolveRawClass(((ParameterizedType) genericType).getRawType(), subType, functionalInterface);
} else if (genericType instanceof GenericArrayType) {
GenericArrayType arrayType = (GenericArrayType) genericType;
Class<?> component = resolveRawClass(arrayType.getGenericComponentType(), subType, functionalInterface);
return Array.newInstance(component, 0).getClass();
} else if (genericType instanceof TypeVariable) {
TypeVariable<?> variable = (TypeVariable<?>) genericType;
genericType = getTypeVariableMap(subType, functionalInterface).get(variable);
genericType = genericType == null ? resolveBound(variable) : resolveRawClass(genericType, subType, functionalInterface);
}
return genericType instanceof Class ? (Class<?>) genericType : Unknown.class;
}
use of java.lang.reflect.TypeVariable in project Entitas-Java by Rubentxu.
the class TypeResolver method resolveRawArguments.
/**
* Returns an array of raw classes representing arguments for the {@code genericType} using type variable information
* from the {@code subType}. Arguments for {@code genericType} that cannot be resolved are returned as
* {@code Unknown.class}. If no arguments can be resolved then {@code null} is returned.
*
* @param genericType to resolve arguments for
* @param subType to extract type variable information from
* @return array of raw classes representing arguments for the {@code genericType} else {@code null} if no type
* arguments are declared
*/
public static Class<?>[] resolveRawArguments(Type genericType, Class<?> subType) {
Class<?>[] result = null;
Class<?> functionalInterface = null;
// Handle lambdas
if (RESOLVES_LAMBDAS && subType.isSynthetic()) {
Class<?> fi = genericType instanceof ParameterizedType && ((ParameterizedType) genericType).getRawType() instanceof Class ? (Class<?>) ((ParameterizedType) genericType).getRawType() : genericType instanceof Class ? (Class<?>) genericType : null;
if (fi != null && fi.isInterface())
functionalInterface = fi;
}
if (genericType instanceof ParameterizedType) {
ParameterizedType paramType = (ParameterizedType) genericType;
Type[] arguments = paramType.getActualTypeArguments();
result = new Class[arguments.length];
for (int i = 0; i < arguments.length; i++) result[i] = resolveRawClass(arguments[i], subType, functionalInterface);
} else if (genericType instanceof TypeVariable) {
result = new Class[1];
result[0] = resolveRawClass(genericType, subType, functionalInterface);
} else if (genericType instanceof Class) {
TypeVariable<?>[] typeParams = ((Class<?>) genericType).getTypeParameters();
result = new Class[typeParams.length];
for (int i = 0; i < typeParams.length; i++) result[i] = resolveRawClass(typeParams[i], subType, functionalInterface);
}
return result;
}
use of java.lang.reflect.TypeVariable in project atmosphere by Atmosphere.
the class TypeResolver method getTypeVariableMap.
private static Map<TypeVariable<?>, Type> getTypeVariableMap(final Class<?> targetType) {
Reference<Map<TypeVariable<?>, Type>> ref = typeVariableCache.get(targetType);
Map<TypeVariable<?>, Type> map = ref != null ? ref.get() : null;
if (map == null) {
map = new HashMap<TypeVariable<?>, Type>();
// Populate interfaces
buildTypeVariableMap(targetType.getGenericInterfaces(), map);
// Populate super classes and interfaces
Type genericType = targetType.getGenericSuperclass();
Class<?> type = targetType.getSuperclass();
while (type != null && !Object.class.equals(type)) {
if (genericType instanceof ParameterizedType)
buildTypeVariableMap((ParameterizedType) genericType, map);
buildTypeVariableMap(type.getGenericInterfaces(), map);
genericType = type.getGenericSuperclass();
type = type.getSuperclass();
}
// Populate enclosing classes
type = targetType;
while (type.isMemberClass()) {
genericType = type.getGenericSuperclass();
if (genericType instanceof ParameterizedType)
buildTypeVariableMap((ParameterizedType) genericType, map);
type = type.getEnclosingClass();
}
if (cacheEnabled)
typeVariableCache.put(targetType, new WeakReference<Map<TypeVariable<?>, Type>>(map));
}
return map;
}
Aggregations