示例#1
0
 @Nullable
 private static TypeWrapper wrap(Type type) {
   if (type == null) {
     return null;
   } else if (type instanceof Class) {
     return new ClassTypeWrapper((Class<?>) type);
   } else if (type instanceof ParameterizedType) {
     ParameterizedType parameterizedType = (ParameterizedType) type;
     return new ParameterizedTypeWrapper(
         toWrappers(parameterizedType.getActualTypeArguments()),
         (ClassTypeWrapper) wrap(parameterizedType.getRawType()),
         wrap(parameterizedType.getOwnerType()));
   } else if (type instanceof WildcardType) {
     WildcardType wildcardType = (WildcardType) type;
     return new WildcardTypeWrapper(
         toWrappers(wildcardType.getUpperBounds()),
         toWrappers(wildcardType.getLowerBounds()),
         type.hashCode());
   } else if (type instanceof TypeVariable) {
     TypeVariable<?> typeVariable = (TypeVariable<?>) type;
     return new TypeVariableTypeWrapper(
         typeVariable.getName(), toWrappers(typeVariable.getBounds()), type.hashCode());
   } else if (type instanceof GenericArrayType) {
     GenericArrayType genericArrayType = (GenericArrayType) type;
     return new GenericArrayTypeWrapper(
         wrap(genericArrayType.getGenericComponentType()), type.hashCode());
   } else {
     throw new IllegalArgumentException("cannot wrap type of type " + type.getClass());
   }
 }
  public String toString() {
    StringBuilder sb = new StringBuilder();

    if (ownerType != null) {
      if (ownerType instanceof Class) sb.append(((Class) ownerType).getName());
      else sb.append(ownerType.toString());

      sb.append(".");

      if (ownerType instanceof ParameterizedTypeImpl) {
        // Find simple name of nested type by removing the
        // shared prefix with owner.
        sb.append(
            rawType
                .getName()
                .replace(((ParameterizedTypeImpl) ownerType).rawType.getName() + "$", ""));
      } else sb.append(rawType.getName());
    } else sb.append(rawType.getName());

    if (actualTypeArguments != null && actualTypeArguments.length > 0) {
      sb.append("<");
      boolean first = true;
      for (Type t : actualTypeArguments) {
        if (!first) sb.append(", ");
        if (t instanceof Class) sb.append(((Class) t).getName());
        else sb.append(t.toString());
        first = false;
      }
      sb.append(">");
    }

    return sb.toString();
  }
  /**
   * Resolve current method generic return type to a {@link GenericMetadataSupport}.
   *
   * @param method Method to resolve the return type.
   * @return {@link GenericMetadataSupport} representing this generic return type.
   */
  public GenericMetadataSupport resolveGenericReturnType(Method method) {
    Type genericReturnType = method.getGenericReturnType();
    // logger.log("Method '" + method.toGenericString() + "' has return type : " +
    // genericReturnType.getClass().getInterfaces()[0].getSimpleName() + " : " + genericReturnType);

    if (genericReturnType instanceof Class) {
      return new NotGenericReturnTypeSupport(genericReturnType);
    }
    if (genericReturnType instanceof ParameterizedType) {
      return new ParameterizedReturnType(
          this, method.getTypeParameters(), (ParameterizedType) method.getGenericReturnType());
    }
    if (genericReturnType instanceof TypeVariable) {
      return new TypeVariableReturnType(
          this, method.getTypeParameters(), (TypeVariable) genericReturnType);
    }

    throw new MockitoException(
        "Ouch, it shouldn't happen, type '"
            + genericReturnType.getClass().getCanonicalName()
            + "' on method : '"
            + method.toGenericString()
            + "' is not supported : "
            + genericReturnType);
  }
示例#4
0
 private static int checkParameterizedType(
     String subroutineName,
     ParameterizedType expectedType,
     ArgumentsList arguments,
     List<LispObject> args,
     int argsCounter,
     int i) {
   Type rawType = expectedType.getRawType();
   Type expectedTypeArguments = expectedType.getActualTypeArguments()[0];
   try {
     if (((Class) rawType).isInstance(args.get(argsCounter))) {
       Type actualTypeArguments =
           ((ParameterizedType) (Type) args.get(argsCounter).getClass())
               .getActualTypeArguments()[0];
       if (!expectedTypeArguments.equals(actualTypeArguments)) {
         throw new WrongTypeArgumentException(
             ((Class) rawType).getSimpleName()
                 + "<"
                 + ((Class) expectedTypeArguments).getSimpleName()
                 + ">",
             args.get(argsCounter));
       }
       arguments.setValue(i, args.get(argsCounter));
       return argsCounter + 1;
     } else {
       if (arguments.isOptional(i)) return -1;
       throw new WrongTypeArgumentException(expectedType.toString(), args.get(argsCounter));
     }
   } catch (IndexOutOfBoundsException e) {
     if (arguments.isOptional(i)) return -1;
     throw new WrongNumberOfArgumentsException(subroutineName, i);
   }
 }
示例#5
0
  /**
   * 通过反射, 获得Class定义中声明的父类的泛型参数的类型. 如无法找到, 返回Object.class.
   *
   * <p>如public UserDao extends HibernateDao<User,Long>
   *
   * @param clazz clazz The class to introspect
   * @param index the Index of the generic ddeclaration,start from 0.
   * @return the index generic declaration, or Object.class if cannot be determined
   */
  @SuppressWarnings("rawtypes")
  public static Class getSuperClassGenricType(final Class clazz, final int index) {

    Type genType = clazz.getGenericSuperclass();

    if (!(genType.getClass().isAssignableFrom(ParameterizedType.class))) {
      log.warn(clazz.getSimpleName() + "'s superclass not ParameterizedType");
      return Object.class;
    }

    Type[] params = ((ParameterizedType) genType).getActualTypeArguments();

    if (index >= params.length || index < 0) {
      log.warn(
          "Index: "
              + index
              + ", Size of "
              + clazz.getSimpleName()
              + "'s Parameterized Type: "
              + params.length);
      return Object.class;
    }
    if (!(params[index].getClass().isAssignableFrom(Class.class))) {
      log.warn(clazz.getSimpleName() + " not set the actual class on superclass generic parameter");
      return Object.class;
    }

    return (Class) params[index];
  }
 private List<String> GetImplements(Class<?> cls) {
   List<String> list = new ArrayList<>();
   for (Type interf : cls.getGenericInterfaces()) {
     list.add(interf.getTypeName());
   }
   return list;
 }
  protected Class<T> getTClass() {
    ParameterizedType type = (ParameterizedType) getClass().getGenericSuperclass();
    Type resultType = type.getActualTypeArguments()[0];
    // ImplForType, ParameterizedTypeImpl
    //        if ("ParameterizedTypeImpl".equals(resultType.getClass().getSimpleName()) ||
    // "ImplForType".equals(resultType.getClass().getSimpleName())) {
    //            try {
    //                Field field = resultType.getClass().getDeclaredField("rawTypeName");
    //                field.setAccessible(true);
    //                String rawTypeName = (String) field.get(resultType);
    //                return (Class<T>) Class.forName(rawTypeName);
    //            } catch (Exception e) {
    //                return (Class<T>) Collection.class;
    //            }
    //        } else {
    //            return (Class<T>) resultType;
    //        }

    if (resultType instanceof Class) {
      return (Class<T>) resultType;
    } else {
      // 处理集合
      try {
        Field field = resultType.getClass().getDeclaredField("rawTypeName");
        field.setAccessible(true);
        String rawTypeName = (String) field.get(resultType);
        return (Class<T>) Class.forName(rawTypeName);
      } catch (Exception e) {
        return (Class<T>) Collection.class;
      }
    }
  }
示例#8
0
  public Object inject(InjectionContext context) {
    if (injectionProvider == null) {
      return null;
    }
    Object injectedValue;
    try {
      injectedValue = injectionProvider.provideInjection(context);
    } catch (InjectionProviderException e) {
      Throwable ex = e;
      if (ex.getCause() != null) {
        ex = ex.getCause();
      }

      String message =
          "InjectionProvider unable to resolve @"
              + injectionAnnotation.annotationType().getSimpleName()
              + " "
              + injectionType.toString();
      throw new ConstructionException(message, ex);
    }
    if (injectedValue == null && !optional) {
      String message =
          "Non-optional @"
              + injectionAnnotation.annotationType().getSimpleName()
              + " "
              + injectionType.toString()
              + " was null in "
              + injectedClass.getName();
      throw new ConstructionException(message);
    }
    return getInjectedValue(injectedValue);
  }
示例#9
0
  public <T> Class<T> inferValueClassForListOrSet(Type genericType, Class<?> entityClass) {
    log.debug(
        "Infer parameterized value class for collection type {} of entity class {} ",
        genericType.toString(),
        entityClass.getCanonicalName());

    Class<T> valueClass;
    if (genericType instanceof ParameterizedType) {
      ParameterizedType pt = (ParameterizedType) genericType;
      Type[] actualTypeArguments = pt.getActualTypeArguments();
      if (actualTypeArguments.length > 0) {
        Type type = actualTypeArguments[actualTypeArguments.length - 1];
        valueClass = getClassFromType(type);
      } else {
        throw new AchillesBeanMappingException(
            "The type '"
                + genericType.getClass().getCanonicalName()
                + "' of the entity '"
                + entityClass.getCanonicalName()
                + "' should be parameterized");
      }
    } else {
      throw new AchillesBeanMappingException(
          "The type '"
              + genericType.getClass().getCanonicalName()
              + "' of the entity '"
              + entityClass.getCanonicalName()
              + "' should be parameterized");
    }

    log.trace("Inferred value class : {}", valueClass.getCanonicalName());

    return valueClass;
  }
 /**
  * Infer value type in one collection type
  *
  * @param genericType
  * @return
  */
 public static Type inferElementTypeIn(Type collectionType) {
   if (collectionType instanceof Class) {
     return Object.class;
   } else if (collectionType instanceof ParameterizedType) {
     ParameterizedType parameterizedCollectionType = (ParameterizedType) collectionType;
     Type collectionValueType = parameterizedCollectionType.getActualTypeArguments()[0];
     if (collectionValueType instanceof Class) {
       return (Class) collectionValueType;
     } else if (collectionValueType instanceof ParameterizedType) {
       ParameterizedType type = (ParameterizedType) collectionValueType;
       return type.getRawType();
     } else if (collectionValueType instanceof WildcardType) {
       throw new UnusableTypeException(
           "we can't infer element type in widlcard type " + collectionType.toString());
     } else if (collectionValueType instanceof TypeVariable) {
       throw new UnusableTypeException(
           "we can't infer element type in type variable " + collectionType.toString());
     }
   } else if (collectionType instanceof WildcardType) {
     throw new UnusableTypeException(
         "we can't infer element type in widlcard type " + collectionType.toString());
   } else if (collectionType instanceof TypeVariable) {
     throw new UnusableTypeException(
         "we can't infer element type in type variable " + collectionType.toString());
   }
   throw new UnusableTypeException("we can't infer element type in " + collectionType.toString());
 }
  @Test
  public void testgeneric4() throws SecurityException, NoSuchMethodException {
    System.out.println("====  testgeneric4 ====");

    Type type = GenericUtils.newArrayType(String.class);
    System.out.println(type.getClass().getName());
    System.out.println("isRawArray:" + GenericUtils.isRawArray(type));
    System.out.println("rawType:" + GenericUtils.getRawClass(type));

    Class<?> c = new String[0].getClass();
    System.out.println(c.getClass().getName());
    System.out.println(c.getName());
    System.out.println(c);

    System.out.println(type.equals(c));
    System.out.println("====  testgeneric4b ====");
    FieldEx field = BeanUtils.getField(GenericTypeTemplateTest.class, "field1");
    System.out.println(field.getType().equals(c));
    System.out.println(field.getGenericType().equals(c)); // 当不是泛型时,返回的是class对象
    System.out.println(field.getType());
    System.out.println(field.getGenericType());
    System.out.println(type);
    System.out.println(field.getGenericType().equals(type));

    System.out.println("====  testgeneric4c ====");
    field = BeanUtils.getField(GenericTypeTemplateTest.class, "field2");
    System.out.println(field.getType());
    System.out.println(field.getGenericType());
    type = field.getGenericType();
    System.out.println("isRawArray:" + GenericUtils.isRawArray(type));
    System.out.println("rawType:" + GenericUtils.getRawClass(type));
    System.out.println(GenericUtils.getRawClass(type).equals(field.getType()));
  }
示例#12
0
 protected final boolean isInt(final JakExpression expr) {
   Type type = expr.type(this.context);
   return type.equals(boolean.class)
       || type.equals(byte.class)
       || type.equals(char.class)
       || type.equals(short.class)
       || type.equals(int.class);
 }
示例#13
0
 public static <T> Class<T> getGenericType(Class<?> klass, int index) {
   Type genericSuperclass = klass.getGenericSuperclass();
   if (genericSuperclass instanceof ParameterizedType)
     return (Class<T>)
         ((ParameterizedType) klass.getGenericSuperclass()).getActualTypeArguments()[index];
   if (genericSuperclass.equals(Object.class)) return null;
   return getGenericType(klass.getSuperclass(), index);
 }
 protected boolean containsType(Type type) {
   for (Type providedType : providedHandlers.keySet()) {
     if (providedType.equals(type)) {
       return true;
     }
   }
   return false;
 }
示例#15
0
  /**
   * Checks if two types are the same or are equivalent under a variable mapping given in the type
   * map that was provided.
   */
  private static boolean matches(Type from, Type to, Map<String, Type> typeMap) {
    if (to.equals(from)) return true;

    if (from instanceof TypeVariable) {
      return to.equals(typeMap.get(((TypeVariable<?>) from).getName()));
    }

    return false;
  }
 protected Type rightTypeToGet(Type type) {
   for (Type providedType : providedHandlers.keySet()) {
     if (providedType.equals(type)) {
       return providedType;
     }
   }
   // Did not work...
   return type;
 }
示例#17
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;
  }
示例#18
0
 /**
  * Returns conversion for converting value of source-type to target-type, or throws exception if
  * there's no such conversion.
  */
 @NotNull
 public TypeConversion getConversionFromDbValue(@NotNull Type source, @NotNull Type target) {
   TypeConversion conversion = findConversionFromDbValue(source, target).orElse(null);
   if (conversion != null) return conversion;
   else
     throw new InstantiationFailureException(
         "could not find a conversion from "
             + source.getTypeName()
             + " to "
             + target.getTypeName());
 }
示例#19
0
  public void outject(@Observes MethodExecuted event, Result result, MethodInfo methodInfo) {

    Type returnType = event.getMethodReturnType();

    if (!returnType.equals(Void.TYPE)) {
      String name = extractor.nameFor(returnType);
      Object value = methodInfo.getResult();
      logger.debug("outjecting {}={}", name, value);
      result.include(name, value);
    }
  }
示例#20
0
   public static void main(String[]argv) throws Exception {
	   Method m = Goo.class.getDeclaredMethod("getStrings");
	   Type t = m.getGenericReturnType();
	   if (!t.toString().equals("java.util.List<java.lang.String>")) 
		   throw new RuntimeException("Incorrect signature. Signature is "+t);

	   m = IFace.class.getDeclaredMethod("getStrings");
	   t = m.getGenericReturnType();
	   if (!t.toString().equals("java.util.List<java.lang.String>")) 
		   throw new RuntimeException("Incorrect signature. Signature is "+t);
   }
示例#21
0
文件: Mirror.java 项目: jekey/nutz
 /**
  * 获取一个类的某个一个泛型参数
  *
  * @param klass 类
  * @param index 参数下标 (从 0 开始)
  * @return 泛型参数类型
  */
 @SuppressWarnings("unchecked")
 public static <T> Class<T> getTypeParam(Class<?> klass, int index) {
   Type[] types = getTypeParams(klass);
   if (index >= 0 && index < types.length) {
     Type t = types[index];
     Class<T> clazz = (Class<T>) Lang.getTypeClass(t);
     if (clazz == null) throw Lang.makeThrow("Type '%s' is not a Class", t.toString());
     return clazz;
   }
   throw Lang.makeThrow("Class type param out of range %d/%d", index, types.length);
 }
 @Test
 public void testgeneric5() throws SecurityException, NoSuchMethodException {
   System.out.println("====  testgeneric5 ====");
   Type map1 = GenericUtils.newMapType(String.class, String.class);
   Type map2 = GenericUtils.newMapType(String.class, Object.class);
   Type map3 = Map.class;
   Type c = GenericUtils.newGenericType(GenericTypeTemplateTest.class, java.sql.Date.class);
   ClassEx cw = new ClassEx(c);
   MethodEx method = cw.getFirstMethodByName("test4");
   System.out.println(map1.equals(method.getGenericParameterTypes()[0]));
   System.out.println(map2.equals(method.getGenericReturnType()));
 }
示例#23
0
    Foo() {
      Logger logger = Logger.getLogger(getClass());

      Type t = TypeResolver.resolveInClass(Foo.class, Foo.class);
      logger.debug("........" + t.getClass());
      Field field = null;
      try {
        field = Foo.class.getDeclaredField("var");
      } catch (NoSuchFieldException e) {
        e.printStackTrace();
      }
      logger.debug(field.getType()); // class java.lang.String.
    }
 private boolean shouldTypeBeAdded(final Type t2, final ParameterizedType parameterizedType) {
   if (!(t2 instanceof TypeVariable)) {
     return true;
   }
   TypeVariable<?> typeVariable = (TypeVariable<?>) t2;
   final Type[] bounds = typeVariable.getBounds();
   for (Type bound : bounds) {
     if (bound instanceof ParameterizedType && bound.equals(parameterizedType)) {
       return false;
     }
   }
   return true;
 }
示例#25
0
文件: Lang.java 项目: flymichael/nutz
 /**
  * 当一个类使用<T,K>来定义泛型时,本方法返回类的一个字段的具体类型。
  *
  * @param me
  * @param field
  * @return
  */
 public static Type getFieldType(Mirror<?> me, Field field) {
   Type type = field.getGenericType();
   Type[] types = me.getGenericsTypes();
   if (type instanceof TypeVariable && types != null && types.length > 0) {
     Type[] tvs = me.getType().getTypeParameters();
     for (int i = 0; i < tvs.length; i++) {
       if (type.equals(tvs[i])) {
         type = me.getGenericsType(i);
         break;
       }
     }
   }
   return type;
 }
 /*
  * Don't consider parameter types that are available after conversion.
  * Message, Message<?> and Channel.
  */
 private boolean isEligibleParameter(MethodParameter methodParameter) {
   Type parameterType = methodParameter.getGenericParameterType();
   if (parameterType.equals(Channel.class)
       || parameterType.equals(org.springframework.amqp.core.Message.class)) {
     return false;
   }
   if (parameterType instanceof ParameterizedType) {
     ParameterizedType parameterizedType = (ParameterizedType) parameterType;
     if (parameterizedType.getRawType().equals(Message.class)) {
       return !(parameterizedType.getActualTypeArguments()[0] instanceof WildcardType);
     }
   }
   return !parameterType.equals(Message.class); // could be Message without a generic type
 }
示例#27
0
  public static void toJSON(ConfigurationAdmin admin, Writer osw, String filter) throws Exception {

    Configuration[] list = admin.listConfigurations(filter);
    Encoder encoder = codec.enc().to(osw);

    Protocol p = new Protocol();
    p.version = 1;
    p.date = new Date();
    p.size = list.length;
    encoder.put(p).append('\n');

    if (list != null)
      for (Configuration c : list) {
        Dictionary<String, Object> d = c.getProperties();
        Export export = new Export();
        export.values = new HashMap<String, Object>();
        export.factoryPid = c.getFactoryPid();
        export.pid = c.getPid();

        for (Enumeration<String> e = d.keys(); e.hasMoreElements(); ) {
          String k = e.nextElement();
          Object v = d.get(k);

          if (!(v instanceof String)) {

            if (export.types == null) export.types = new HashMap<String, Type>();

            Type type = new Type();

            Class<?> clazz = v.getClass();
            if (v instanceof Collection) {
              Collection<?> coll = (Collection<?>) v;
              clazz = String.class;
              if (coll.size() > 0) type.vectorOf = shortName(coll.iterator().next().getClass());
              else type.vectorOf = shortName(String.class);
            } else if (v.getClass().isArray()) {
              type.arrayOf = shortName(clazz.getComponentType());
            } else type.scalar = shortName(v.getClass());

            export.types.put(k, type);
          }
          export.values.put(k, v);
        }

        encoder.mark().put(export);
        // encoder.put(encoder.digest());
        encoder.append('\n');
      }
    osw.flush();
  }
示例#28
0
  public static void main(String... args) {
    try {
      Class<?> c = Class.forName(args[0]);
      out.format("Class:%n  %s%n%n", c.getCanonicalName());
      out.format("Modifiers:%n  %s%n%n", Modifier.toString(c.getModifiers()));

      out.format("Type Parameters:%n");
      TypeVariable<?>[] tv = c.getTypeParameters();
      if (tv.length != 0) {
        out.format("  ");
        for (TypeVariable<?> t : tv) out.format("%s ", t.getName());
        out.format("%n%n");
      } else {
        out.format("  -- No Type Parameters --%n%n");
      }

      out.format("Implemented Interfaces:%n");
      Type[] intfs = c.getGenericInterfaces();
      if (intfs.length != 0) {
        for (Type intf : intfs) out.format("  %s%n", intf.toString());
        out.format("%n");
      } else {
        out.format("  -- No Implemented Interfaces --%n%n");
      }

      out.format("Inheritance Path:%n");
      List<Class<?>> l = new ArrayList<Class<?>>();
      printAncestor(c, l);
      if (l.size() != 0) {
        for (Class<?> cl : l) out.format("  %s%n", cl.getCanonicalName());
        out.format("%n");
      } else {
        out.format("  -- No Super Classes --%n%n");
      }

      out.format("Annotations:%n");
      Annotation[] ann = c.getAnnotations();
      if (ann.length != 0) {
        for (Annotation a : ann) out.format("  %s%n", a.toString());
        out.format("%n");
      } else {
        out.format("  -- No Annotations --%n%n");
      }

      // production code should handle this exception more gracefully
    } catch (ClassNotFoundException x) {
      x.printStackTrace();
    }
  }
示例#29
0
 /**
  * @param types - Array of types to resolve. The unresolved type is replaced in the array with the
  *     resolved type.
  * @param containingType - the shallowest type in the hierarchy where type is defined.
  * @return true if any of the types were resolved.
  */
 private static boolean resolve(Type[] types, Type containingType) {
   boolean modified = false;
   for (int i = 0; i < types.length; ++i) {
     Type t = types[i];
     if (!(t instanceof Class)) {
       modified = true;
       final Type resolved = resolve(t, containingType);
       if (!resolved.equals(t)) {
         types[i] = resolved;
         modified = true;
       }
     }
   }
   return modified;
 }
 @Override
 public T deserialize(final JsonElement je, final Type type, final JsonDeserializationContext jdc)
     throws JsonParseException {
   // Get the "content" element from the parsed JSON
   JsonElement content = je;
   if (je.isJsonObject() && je.getAsJsonObject().has("contents")) {
     content = je.getAsJsonObject().get("contents");
     final int lastIndex = type.toString().lastIndexOf('.');
     final String name = type.toString().substring(lastIndex + 1).toLowerCase();
     if (content.isJsonObject() && content.getAsJsonObject().has(name)) {
       content = content.getAsJsonObject().get(name);
     }
   }
   return new Gson().fromJson(content, type);
 }