package io.ebeaninternal.server.deploy;

import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;

Helper object to find generic parameter types for a given class.
/** * Helper object to find generic parameter types for a given class. */
public class ParamTypeUtil {
Find and return the parameter type given a generic interface or class.

This assumes there is only one generic parameter.

Returns null if no match was found.

Params:
  • cls – the class to search for the parameter type
  • matchType – the type which has the generic parameter
/** * Find and return the parameter type given a generic interface or class. * <p> * This assumes there is only one generic parameter. * </p> * <p> * Returns null if no match was found. * </p> * * @param cls the class to search for the parameter type * @param matchType the type which has the generic parameter */
public static Class<?> findParamType(Class<?> cls, Class<?> matchType) { // search for: implementing a generic interface Type paramType = matchByInterfaces(cls, matchType); if (paramType == null) { // search for: extending a generic class Type genericSuperclass = cls.getGenericSuperclass(); if (genericSuperclass != null) { paramType = matchParamType(genericSuperclass, matchType); } } if (paramType instanceof Class<?>) { // only interested in classes return (Class<?>) paramType; } else { return null; } }
Check if the type is a generic one with parameters and of the correct type we are searching for. Return the parameter type if this matches otherwise return null.
/** * Check if the type is a generic one with parameters and of the correct type we are * searching for. Return the parameter type if this matches otherwise return null. */
private static Type matchParamType(Type type, Class<?> matchType) { if (type instanceof ParameterizedType) { ParameterizedType pt = (ParameterizedType) type; Type rawType = pt.getRawType(); boolean isAssignable = matchType.isAssignableFrom((Class<?>) rawType); if (isAssignable) { // assume there is only one parameter type Type[] typeArguments = pt.getActualTypeArguments(); if (typeArguments.length != 1) { String m = "Expecting only 1 generic paramater but got " + typeArguments.length + " for " + type; throw new RuntimeException(m); } return typeArguments[0]; } } return null; }
Search the interfaces this class implements.
/** * Search the interfaces this class implements. */
private static Type matchByInterfaces(Class<?> cls, Class<?> matchType) { Type[] gis = cls.getGenericInterfaces(); for (Type gi : gis) { Type match = matchParamType(gi, matchType); if (match != null) { return match; } } return null; } }