Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
  package com.github.joschi.jersey.util;
  
  import java.util.HashMap;
 import java.util.Map;

Type conversions and generic type manipulations

Author(s):
Bill Burke
Version:
$Revision: 1 $
 
 public final class Types
 {
     private Types() {
     }

    
Is the genericType of a certain class?
 
    public static <T> boolean isA(Class<T> clazzParameterizedType pType)
    {
       return clazz.isAssignableFrom((ClasspType.getRawType());
    }

   
Gets the index-th type argument.
 
    public static Class getArgumentType(ParameterizedType pTypeint index)
    {
       return (ClasspType.getActualTypeArguments()[index];
    }
 
    public static Class getTemplateParameterOfInterface(Class baseClass desiredInterface)
    {
       final Object rtn = getSomething(basedesiredInterface);
       if (rtn instanceof Class) {
           return (Classrtn;
       }
       return null;
    }
 
 
    private static Object getSomething(Class baseClass desiredInterface)
    {
       for (int i = 0; i < base.getInterfaces().lengthi++)
       {
          Class intf = base.getInterfaces()[i];
          if (intf.equals(desiredInterface))
          {
             Type generic = base.getGenericInterfaces()[i];
             if (generic instanceof ParameterizedType)
             {
                ParameterizedType p = (ParameterizedTypegeneric;
                Type type = p.getActualTypeArguments()[0];
                Class rtn = getRawTypeNoException(type);
                if (rtn != null) {
                    return rtn;
                }
                return type;
             }
             else
             {
                return null;
             }
          }
       }
       if (base.getSuperclass() == null || base.getSuperclass().equals(Object.class)) {
           return null;
       }
       Object rtn = getSomething(base.getSuperclass(), desiredInterface);
       if (rtn == null || rtn instanceof Class) {
           return rtn;
       }
       if (!(rtn instanceof TypeVariable)) {
           return null;
       }
 
       String name = ((TypeVariablertn).getName();
       int index = -1;
       TypeVariable[] variables = base.getSuperclass().getTypeParameters();
       if (variables == null || variables.length < 1) {
           return null;
       }
 
       for (int i = 0; i < variables.lengthi++)
       {
          if (variables[i].getName().equals(name)) {
              index = i;
          }
       }
       if (index == -1) {
           return null;
       }
      Type genericSuperclass = base.getGenericSuperclass();
      if (!(genericSuperclass instanceof ParameterizedType)) {
          return null;
      }
      ParameterizedType pt = (ParameterizedTypegenericSuperclass;
      Type type = pt.getActualTypeArguments()[index];
      Class clazz = getRawTypeNoException(type);
      if (clazz != null) {
          return clazz;
      }
      return type;
   }


   
Given an interface Method, look in the implementing class for the method that implements the interface's method to obtain generic type information. This is useful for templatized interfaces like:

 interface Foo<T> {
   @GET
   List<T> get();
 }
 

Parameters:
method interface method
   public static <T> Type getGenericReturnTypeOfGenericInterfaceMethod(Class<T> clazzMethod method)
   {
      if (!method.getDeclaringClass().isInterface()){
          return method.getGenericReturnType();
      }
      try
      {
         Method tmp = clazz.getMethod(method.getName(), method.getParameterTypes());
         return tmp.getGenericReturnType();
      }
      catch (NoSuchMethodException e)
      {
          // Do nothing
      }
      return method.getGenericReturnType();
   }

   
See if the two methods are compatible, that is they have the same relative signature
   public static boolean isCompatible(Method methodMethod intfMethod)
   {
      if (method == intfMethod) {
          return true;
      }
      if (!method.getName().equals(intfMethod.getName())) {
          return false;
      }
      if (method.getParameterTypes().length != intfMethod.getParameterTypes().length) {
          return false;
      }
      for (int i = 0; i < method.getParameterTypes().lengthi++)
      {
         Class<?> rootParam = method.getParameterTypes()[i];
         Class<?> intfParam = intfMethod.getParameterTypes()[i];
         if (!intfParam.isAssignableFrom(rootParam)) {
             return false;
         }
      }
      return true;
   }

   
Given a method and a root class, find the actual method declared in the root that implements the method.
   public static <T> Method getImplementingMethod(Class<T> clazzMethod intfMethod)
   {
      Class<?> declaringClass = intfMethod.getDeclaringClass();
      if (declaringClass.equals(clazz)) {
          return intfMethod;
      }
      Class[] paramTypes = intfMethod.getParameterTypes();
      if (declaringClass.getTypeParameters().length > 0 && paramTypes.length > 0)
      {
         Type[] intfTypes = findParameterizedTypes(clazzdeclaringClass);
         Map<StringTypetypeVarMap = new HashMap<StringType>();
         TypeVariable<? extends Class<?>>[] vars = declaringClass.getTypeParameters();
         for (int i = 0; i < vars.lengthi++)
         {
            if (intfTypes != null && i < intfTypes.length)
            {
               typeVarMap.put(vars[i].getName(), intfTypes[i]);
            }
            else
            {
               // Interface type parameters may not have been filled out
               typeVarMap.put(vars[i].getName(), vars[i].getGenericDeclaration());
            }
         }
         Type[] paramGenericTypes = intfMethod.getGenericParameterTypes();
         paramTypes = new Class[paramTypes.length];
         for (int i = 0; i < paramTypes.lengthi++)
         {
            if (paramGenericTypes[iinstanceof TypeVariable)
            {
               TypeVariable tv = (TypeVariableparamGenericTypes[i];
               Type t = typeVarMap.get(tv.getName());
               if (t == null) {
                   throw new RuntimeException("Unable to resolve type variable");
               }
               paramTypes[i] = getRawType(t);
            }
            else
            {
               paramTypes[i] = getRawType(paramGenericTypes[i]);
            }
         }
      }
      try
      {
         return clazz.getMethod(intfMethod.getName(), paramTypes);
      }
      catch (NoSuchMethodException e)
      {
          // Do nothing
      }
      try
      {
         return clazz.getMethod(intfMethod.getName(), intfMethod.getParameterTypes());
      }
      catch (NoSuchMethodException e)
      {
          // Do nothing
      }
      return intfMethod;
   }
   public static Class<?> getRawType(Type type)
   {
      if (type instanceof Class<?>)
      {
         // type is a normal class.
         return (Class<?>) type;
      }
      else if (type instanceof ParameterizedType)
      {
         ParameterizedType parameterizedType = (ParameterizedTypetype;
         return (Class<?>) parameterizedType.getRawType();
      }
      else if (type instanceof GenericArrayType)
      {
         final GenericArrayType genericArrayType = (GenericArrayTypetype;
         final Class<?> componentRawType = getRawType(genericArrayType.getGenericComponentType());
         return Array.newInstance(componentRawType, 0).getClass();
      }
      else if (type instanceof TypeVariable)
      {
         final TypeVariable typeVar = (TypeVariabletype;
         if (typeVar.getBounds() != null && typeVar.getBounds().length > 0)
         {
            return getRawType(typeVar.getBounds()[0]);
         }
      }
      throw new RuntimeException("Unable to determine base class from Type");
   }
   public static Class<?> getRawTypeNoException(Type type)
   {
       if (type instanceof Class<?>) {
           // type is a normal class.
           return (Class<?>) type;
       } else if (type instanceof ParameterizedType) {
          ParameterizedType parameterizedType = (ParameterizedTypetype;
          return (Class<?>) parameterizedType.getRawType();
       } else if (type instanceof GenericArrayType) {
           final GenericArrayType genericArrayType = (GenericArrayTypetype;
           final Class<?> componentRawType = getRawType(genericArrayType.getGenericComponentType());
           return Array.newInstance(componentRawType, 0).getClass();
       }
       return null;
   }

   
Returns the type argument from a parameterized type

Returns:
null if there is no type parameter
   public static Class<?> getTypeArgument(Type genericType)
   {
      if (!(genericType instanceof ParameterizedType)) {
          return null;
      }
      ParameterizedType parameterizedType = (ParameterizedTypegenericType;
      return (Class<?>) parameterizedType.getActualTypeArguments()[0];
   }
   public static class TypeInfo
   {
      private Class<?> type;
      private Type genericType;
      public TypeInfo(Class<?> typeType genericType)
      {
         this. = type;
         this. = genericType;
      }
      public Class<?> getType()
      {
         return ;
      }
      public Type getGenericType()
      {
         return ;
      }
   }
   public static Class getCollectionBaseType(Class typeType genericType)
   {
      if (genericType instanceof ParameterizedType)
      {
         ParameterizedType parameterizedType = (ParameterizedTypegenericType;
         Type componentGenericType = parameterizedType.getActualTypeArguments()[0];
         return getRawType(componentGenericType);
      }
      else if (genericType instanceof GenericArrayType)
      {
         final GenericArrayType genericArrayType = (GenericArrayTypegenericType;
         Type componentGenericType = genericArrayType.getGenericComponentType();
         return getRawType(componentGenericType);
      }
      else if (type.isArray())
      {
         return type.getComponentType();
      }
      return null;
   }
   public static Class getMapKeyType(Type genericType)
   {
      if (genericType instanceof ParameterizedType)
      {
         ParameterizedType parameterizedType = (ParameterizedTypegenericType;
         Type componentGenericType = parameterizedType.getActualTypeArguments()[0];
         return getRawType(componentGenericType);
      }
      return null;
   }
   public static Class getMapValueType(Type genericType)
   {
      if (genericType instanceof ParameterizedType)
      {
         ParameterizedType parameterizedType = (ParameterizedTypegenericType;
         Type componentGenericType = parameterizedType.getActualTypeArguments()[1];
         return getRawType(componentGenericType);
      }
      return null;
   }

   
Finds an actual value of a type variable. The method looks in a class hierarchy for a class defining the variable and returns the value if present.

Returns:
actual type of the type variable
   public static Type getActualValueOfTypeVariable(final Class<?> clazzfinal TypeVariable<?> typeVariable)
   {
      if (typeVariable.getGenericDeclaration() instanceof Class<?>)
      {
         Class<?> classDeclaringTypeVariable = (Class<?>) typeVariable.getGenericDeclaration();
         // find the generic version of classDeclaringTypeVariable
         Type fromInterface = getTypeVariableViaGenericInterface(clazzclassDeclaringTypeVariabletypeVariable);
         if (fromInterface != null)
         {
            return fromInterface;
         }
         Class<?> cls = clazz;
         while (cls.getSuperclass() != null)
         {
            if (cls.getSuperclass().equals(classDeclaringTypeVariable))
            {
               // found it
               ParameterizedType parameterizedSuperclass = (ParameterizedTypecls.getGenericSuperclass();
               for (int i = 0; i < classDeclaringTypeVariable.getTypeParameters().lengthi++)
               {
                  TypeVariable<?> tv = classDeclaringTypeVariable.getTypeParameters()[i];
                  if (tv.equals(typeVariable))
                  {
                     return parameterizedSuperclass.getActualTypeArguments()[i];
                  }
               }
            }
             cls = cls.getSuperclass();
         }
      }
      throw new RuntimeException("Unable to determine value of type parameter " + typeVariable);
   }
   private static Type getTypeVariableViaGenericInterface(Class<?> clazzClass<?> classDeclaringTypeVariableTypeVariable<?> typeVariable)
   {
      for (Type genericInterface : clazz.getGenericInterfaces())
      {
         if (genericInterface instanceof ParameterizedType)
         {
            ParameterizedType parameterizedType = (ParameterizedTypegenericInterface;
            for (int i = 0; i < classDeclaringTypeVariable.getTypeParameters().lengthi++)
            {
               TypeVariable<?> tv = classDeclaringTypeVariable.getTypeParameters()[i];
               if (tv.equals(typeVariable))
               {
                  return parameterizedType.getActualTypeArguments()[i];
               }
            }
         }
         else if (genericInterface instanceof Class)
         {
            return getTypeVariableViaGenericInterface((Class<?>) genericInterfaceclassDeclaringTypeVariabletypeVariable);
         }
      }
      return null;
   }

   
Given a class and an interfaces, go through the class hierarchy to find the interface and return its type arguments.

Returns:
type arguments of the interface
   public static Type[] getActualTypeArgumentsOfAnInterface(Class<?> classToSearchClass<?> interfaceToFind)
   {
      Class<?> clazz = classToSearch;
      while (clazz != null)
      {
         for (Type genericInterface : clazz.getGenericInterfaces())
         {
            if (getRawType(genericInterface).equals(interfaceToFind) && genericInterface instanceof ParameterizedType)
            {
              return ((ParameterizedTypegenericInterface).getActualTypeArguments();
            }
         }
         clazz = clazz.getSuperclass();
      }
      throw new RuntimeException("Unable to find type arguments of " + interfaceToFind);
   }
   private static final Type[] EMPTY_TYPE_ARRAY = {};

   
Search for the given interface or class within the root's class/interface hierarchy. If the searched for class/interface is a generic return an array of real types that fill it out.
   public static Type[] findParameterizedTypes(Class<?> rootClass<?> searchedFor)
   {
      if (searchedFor.isInterface())
      {
         return findInterfaceParameterizedTypes(rootnullsearchedFor);
      }
      return findClassParameterizedTypes(rootnullsearchedFor);
   }
   public static Type[] findClassParameterizedTypes(Class<?> rootParameterizedType rootTypeClass<?> searchedForClass)
   {
      Map<StringTypetypeVarMap = populateParameterizedMap(rootrootType);
      Class<?> superclass = root.getSuperclass();
      Type genericSuper = root.getGenericSuperclass();
      if (superclass.equals(searchedForClass))
      {
         return extractTypes(typeVarMapgenericSuper);
      }
      if (genericSuper instanceof ParameterizedType)
      {
         ParameterizedType intfParam = (ParameterizedTypegenericSuper;
         Type[] types = findClassParameterizedTypes(superclassintfParamsearchedForClass);
         if (types != null)
         {
            return extractTypeVariables(typeVarMaptypes);
         }
      }
      else
      {
         Type[] types = findClassParameterizedTypes(superclassnullsearchedForClass);
         if (types != null)
         {
            return types;
         }
      }
      return null;
   }
   private static Map<StringTypepopulateParameterizedMap(Class<?> rootParameterizedType rootType)
   {
      Map<StringTypetypeVarMap = new HashMap<StringType>();
      if (rootType != null)
      {
         TypeVariable<? extends Class<?>>[] vars = root.getTypeParameters();
         for (int i = 0; i < vars.lengthi++)
         {
            typeVarMap.put(vars[i].getName(), rootType.getActualTypeArguments()[i]);
         }
      }
      return typeVarMap;
   }
   public static Type[] findInterfaceParameterizedTypes(Class<?> rootParameterizedType rootTypeClass<?> searchedForInterface)
   {
      Map<StringTypetypeVarMap = populateParameterizedMap(rootrootType);
      for (int i = 0; i < root.getInterfaces().lengthi++)
      {
         Class<?> sub = root.getInterfaces()[i];
         Type genericSub = root.getGenericInterfaces()[i];
         if (sub.equals(searchedForInterface))
         {
            return extractTypes(typeVarMapgenericSub);
         }
      }
      for (int i = 0; i < root.getInterfaces().lengthi++)
      {
         Type genericSub = root.getGenericInterfaces()[i];
         Class<?> sub = root.getInterfaces()[i];
         Type[] types = recurseSuperclassForInterface(searchedForInterfacetypeVarMapgenericSubsub);
         if (types != null) {
             return types;
         }
      }
      if (root.isInterface()) {
          return null;
      }
      Class<?> superclass = root.getSuperclass();
      Type genericSuper = root.getGenericSuperclass();
      return recurseSuperclassForInterface(searchedForInterfacetypeVarMapgenericSupersuperclass);
   }
   private static Type[] recurseSuperclassForInterface(Class<?> searchedForInterfaceMap<StringTypetypeVarMapType genericSubClass<?> sub)
   {
      if (genericSub instanceof ParameterizedType)
      {
         ParameterizedType intfParam = (ParameterizedTypegenericSub;
         Type[] types = findInterfaceParameterizedTypes(subintfParamsearchedForInterface);
         if (types != null)
         {
            return extractTypeVariables(typeVarMaptypes);
         }
      }
      else
      {
         Type[] types = findInterfaceParameterizedTypes(subnullsearchedForInterface);
         if (types != null)
         {
            return types;
         }
      }
      return null;
   }
   private static Type[] extractTypeVariables(Map<StringTypetypeVarMapType[] types)
   {
      for (int j = 0; j < types.lengthj++)
      {
         if (types[jinstanceof TypeVariable)
         {
            TypeVariable tv = (TypeVariabletypes[j];
            types[j] = typeVarMap.get(tv.getName());
         }
         else
         {
            types[j] = types[j];
         }
      }
      return types;
   }
   private static Type[] extractTypes(Map<StringTypetypeVarMapType genericSub)
   {
      if (genericSub instanceof ParameterizedType)
      {
         ParameterizedType param = (ParameterizedTypegenericSub;
         Type[] types = param.getActualTypeArguments();
         Type[] returnTypes = new Type[types.length];
         System.arraycopy(types, 0, returnTypes, 0, types.length);
         extractTypeVariables(typeVarMapreturnTypes);
         return returnTypes;
      }
      else
      {
         return ;
      }
   }
New to GrepCode? Check out our FAQ X