I am building a code generator for Fluent API. I want to create a new class for every existing (POJO)-class. I dont have the existing classes under my control. I parse the existing methods via reflection and if I encounter a setter or an "add" method, I create a method for this in my Fluent-Wrapper class, so I can say child().values(....).get().
This is working fine with simple parameters. It took me a while to figure out how to deal with ParameterizedTypes, but I can manage this now. What I dont get is how to create a concrete method for a generic parameter which type is not defined on the method itself but on the containing class.
I have something like this:
abstract class Parent<T> {
void setValues(List<T> values) {...};
}
class Child extends Parent<String> {}
Now I try to generate code via JCodeModel and need to parse the type of the parameter "values". Problem: I get a ParameterizedType that contains List and a TypeVariable "T". But I cannot map "T" back to String. But I cannot figure out how to get the concrete Type "T" got by implementing "Child". Anyone?
Clarify: I do this, and need not "T" but "String" when it comes to the case "TypeVariable"
JType result = codeModel._ref(typeToClass.apply(type));
if (isParameterizedType(type)) {
for (Type typeArgument : ((ParameterizedType) type).getActualTypeArguments()) {
if (typeArgument instanceof WildcardType) {
result = narrow(result, codeModel.wildcard());
} else if (typeArgument instanceof Class) {
result = narrow(result, typeToClass.asJType(codeModel, typeArgument));
} else if (typeArgument instanceof TypeVariable<?>) {
TypeVariable<?> typeVariable = (TypeVariable<?>) typeArgument;
// this is where I only get "T" but need "String"
result = ((JClass) result).narrow(getTypeVariable(codeModel.parseType(typeVariable.getName()));
}
}
}
If you are using my TypeTools library, this becomes pretty simple: