Example #1
0
  /**
   * Checks if the subject type may be implicitly cast to the target parameterized type following
   * the Java generics rules.
   *
   * @param type the subject type to be assigned to the target type
   * @param toParameterizedType the target parameterized type
   * @return true if <code>type</code> is assignable to <code>toType</code>.
   */
  private static boolean isAssignable(
      Type type, ParameterizedType toParameterizedType, Map<TypeVariable<?>, Type> typeVarAssigns) {
    if (type == null) {
      return true;
    }

    // only a null type can be assigned to null type which
    // would have cause the previous to return true
    if (toParameterizedType == null) {
      return false;
    }

    // all types are assignable to themselves
    if (toParameterizedType.equals(type)) {
      return true;
    }

    // get the target type's raw type
    Class<?> toClass = getRawType(toParameterizedType);
    // get the subject type's type arguments including owner type arguments
    // and supertype arguments up to and including the target class.
    Map<TypeVariable<?>, Type> fromTypeVarAssigns = getTypeArguments(type, toClass, null);

    // null means the two types are not compatible
    if (fromTypeVarAssigns == null) {
      return false;
    }

    // compatible types, but there's no type arguments. this is equivalent
    // to comparing Map< ?, ? > to Map, and raw types are always assignable
    // to parameterized types.
    if (fromTypeVarAssigns.isEmpty()) {
      return true;
    }

    // get the target type's type arguments including owner type arguments
    Map<TypeVariable<?>, Type> toTypeVarAssigns =
        getTypeArguments(toParameterizedType, toClass, typeVarAssigns);

    // now to check each type argument
    for (Map.Entry<TypeVariable<?>, Type> entry : toTypeVarAssigns.entrySet()) {
      Type toTypeArg = entry.getValue();
      Type fromTypeArg = fromTypeVarAssigns.get(entry.getKey());

      // parameters must either be absent from the subject type, within
      // the bounds of the wildcard type, or be an exact match to the
      // parameters of the target type.
      if (fromTypeArg != null
          && !toTypeArg.equals(fromTypeArg)
          && !(toTypeArg instanceof WildcardType
              && isAssignable(fromTypeArg, toTypeArg, typeVarAssigns))) {
        return false;
      }
    }

    return true;
  }
  /** Private recursive helper function to actually do the type-safe checking of assignability. */
  private static boolean isAssignableFrom(
      Type from, ParameterizedType to, Map<String, Type> typeVarMap) {

    if (from == null) {
      return false;
    }

    if (to.equals(from)) {
      return true;
    }

    // First figure out the class and any type information.
    Class<?> clazz = getRawType(from);
    ParameterizedType ptype = null;
    if (from instanceof ParameterizedType) {
      ptype = (ParameterizedType) from;
    }

    // Load up parameterized variable info if it was parameterized.
    if (ptype != null) {
      Type[] tArgs = ptype.getActualTypeArguments();
      TypeVariable<?>[] tParams = clazz.getTypeParameters();
      for (int i = 0; i < tArgs.length; i++) {
        Type arg = tArgs[i];
        TypeVariable<?> var = tParams[i];
        while (arg instanceof TypeVariable) {
          TypeVariable<?> v = (TypeVariable<?>) arg;
          arg = typeVarMap.get(v.getName());
        }
        typeVarMap.put(var.getName(), arg);
      }

      // check if they are equivalent under our current mapping.
      if (typeEquals(ptype, to, typeVarMap)) {
        return true;
      }
    }

    for (Type itype : clazz.getGenericInterfaces()) {
      if (isAssignableFrom(itype, to, new HashMap<String, Type>(typeVarMap))) {
        return true;
      }
    }

    // Interfaces didn't work, try the superclass.
    Type sType = clazz.getGenericSuperclass();
    if (isAssignableFrom(sType, to, new HashMap<String, Type>(typeVarMap))) {
      return true;
    }

    return false;
  }
 private static boolean isAssignable(
     Type paramType, ParameterizedType paramParameterizedType, Map paramMap) {
   if (paramType == null) return true;
   if (paramParameterizedType == null) return false;
   if (paramParameterizedType.equals(paramType)) return true;
   Class localClass = getRawType(paramParameterizedType);
   Map localMap = getTypeArguments(paramType, localClass, null);
   if (localMap == null) return false;
   if (localMap.isEmpty()) return true;
   Iterator localIterator =
       getTypeArguments(paramParameterizedType, localClass, paramMap).entrySet().iterator();
   while (localIterator.hasNext()) {
     Map.Entry localEntry = (Map.Entry) localIterator.next();
     Type localType1 = (Type) localEntry.getValue();
     Type localType2 = (Type) localMap.get(localEntry.getKey());
     if ((localType2 != null)
         && (!localType1.equals(localType2))
         && ((!(localType1 instanceof WildcardType))
             || (!isAssignable(localType2, localType1, paramMap)))) return false;
   }
   return true;
 }
Example #4
0
 private static boolean isAssignableFrom(Type object, ParameterizedType parameterizedType, Map<String, Type> map) {
     int n2;
     if (object == null) {
         return false;
     }
     if (parameterizedType.equals(object)) {
         return true;
     }
     Class class_ = $Gson$Types.getRawType((Type)object);
     ParameterizedType parameterizedType2 = null;
     if (object instanceof ParameterizedType) {
         parameterizedType2 = (ParameterizedType)object;
     }
     if (parameterizedType2 != null) {
         Type[] arrtype = parameterizedType2.getActualTypeArguments();
         TypeVariable<Class<?>>[] arrtypeVariable = class_.getTypeParameters();
         for (n2 = 0; n2 < arrtype.length; ++n2) {
             object = arrtype[n2];
             TypeVariable typeVariable = arrtypeVariable[n2];
             while (object instanceof TypeVariable) {
                 object = map.get(((TypeVariable)object).getName());
             }
             map.put(typeVariable.getName(), (Type)object);
         }
         if (TypeToken.typeEquals(parameterizedType2, parameterizedType, map)) {
             return true;
         }
     }
     object = class_.getGenericInterfaces();
     int n3 = object.length;
     for (n2 = 0; n2 < n3; ++n2) {
         if (!TypeToken.isAssignableFrom(object[n2], parameterizedType, new HashMap<String, Type>(map))) continue;
         return true;
     }
     return TypeToken.isAssignableFrom(class_.getGenericSuperclass(), parameterizedType, new HashMap<String, Type>(map));
 }