Type[] actualTypeParameters =
extractRealTypes(castedType.getActualTypeArguments(), parentType, rawParentClass);
Type rawType = castedType.getRawType();
return new ParameterizedTypeImpl(rawType, actualTypeParameters, owner);
} else if (typeToEvaluate instanceof GenericArrayType) {
GenericArrayType castedType = (GenericArrayType) typeToEvaluate;
Type componentType = castedType.getGenericComponentType();
Type actualType = getActualType(componentType, parentType, rawParentClass);
if (componentType.equals(actualType)) {
return castedType;
}
return actualType instanceof Class<?> ?
TypeUtils.wrapWithArray(TypeUtils.toRawClass(actualType))
: new GenericArrayTypeImpl(actualType);
} else if (typeToEvaluate instanceof TypeVariable<?>) {
if (parentType instanceof ParameterizedType) {
// The class definition has the actual types used for the type variables.
// Find the matching actual type for the Type Variable used for the field.
// For example, class Foo<A> { A a; }
// new Foo<Integer>(); defines the actual type of A to be Integer.
// So, to find the type of the field a, we will have to look at the class'
// actual type arguments.
TypeVariable<?> fieldTypeVariable = (TypeVariable<?>) typeToEvaluate;
TypeVariable<?>[] classTypeVariables = rawParentClass.getTypeParameters();
ParameterizedType objParameterizedType = (ParameterizedType) parentType;
int indexOfActualTypeArgument = getIndex(classTypeVariables, fieldTypeVariable);
Type[] actualTypeArguments = objParameterizedType.getActualTypeArguments();
return actualTypeArguments[indexOfActualTypeArgument];
} else if (typeToEvaluate instanceof TypeVariable<?>) {
Type theSearchedType = null;
do {
theSearchedType = extractTypeForHierarchy(parentType, (TypeVariable<?>) typeToEvaluate);
} while ((theSearchedType != null) && (theSearchedType instanceof TypeVariable<?>));
if (theSearchedType != null) {
return theSearchedType;
}
}
throw new UnsupportedOperationException("Expecting parameterized type, got " + parentType
+ ".\n Are you missing the use of TypeToken idiom?\n See "
+ "http://sites.google.com/site/gson/gson-user-guide#TOC-Serializing-and-Deserializing-Gener");
} else if (typeToEvaluate instanceof WildcardType) {
WildcardType castedType = (WildcardType) typeToEvaluate;
return getActualType(castedType.getUpperBounds()[0], parentType, rawParentClass);
} else {
throw new IllegalArgumentException("Type \'" + typeToEvaluate + "\' is not a Class, "
+ "ParameterizedType, GenericArrayType or TypeVariable. Can't extract type.");
}
}