Closed joerg-d-schneider-db closed 1 year ago
You need to 'narrow' the class. Try using the .narrow
method on the JDefinedClass and pass in the enum type and String type as arguments.
Hi,
I tried that and roughly 100+ other approaches - still no luck. Sorry for my ignorance.
My custom rule still produces "public static class EventTypeMapper implements JsonbAdapter {" instead of " public static class EventTypeMapper implements JsonbAdapter<EventType, String> {"
Here is the entire code base I'm stuck with
package com.db.dice.rules;
import java.util.List;
import javax.json.bind.adapter.JsonbAdapter;
import org.jsonschema2pojo.AnnotationStyle; import org.jsonschema2pojo.model.EnumDefinition; import org.jsonschema2pojo.rules.EnumRule; import org.jsonschema2pojo.rules.RuleFactory;
import com.sun.codemodel.JClass; import com.sun.codemodel.JClassAlreadyExistsException; import com.sun.codemodel.JDefinedClass; import com.sun.codemodel.JMethod; import com.sun.codemodel.JMod;
public class EnumMapperRule extends EnumRule {
private final RuleFactory ruleFactory;
public static final String SUFFIX = "Mapper";
protected EnumMapperRule(RuleFactory ruleFactory) {
super(ruleFactory);
this.ruleFactory = ruleFactory;
}
@Override
protected void applyCustomizations(EnumDefinition enumDefinition, JDefinedClass _enum) {
if (this.ruleFactory.getGenerationConfig().getAnnotationStyle().equals(AnnotationStyle.JSONB1)
|| this.ruleFactory.getGenerationConfig().getAnnotationStyle().equals(AnnotationStyle.JSONB1)) {
try {
// create an public static inner class inside the enum
JDefinedClass c = _enum._class(JMod.PUBLIC | JMod.STATIC,
enumDefinition.getNodeName() + EnumMapperRule.SUFFIX);
if (c != null) {
// let the class implement JsonbAdapter interface - to do : how to handle generics !!!
JClass temp1 = _enum.owner().ref(JsonbAdapter.class);
if(temp1.isInterface()) {
System.out.println("JsonbAdapter is Interface");
temp1.generify("String", String.class);
temp1.narrow(String.class);
} else {
System.out.println("JsonbAdapter is not an Interface");
}
JDefinedClass temp;
try {
temp = _enum.owner()._class("javax.json.bind.adapter.JsonbAdapter");
} catch(JClassAlreadyExistsException ae) {
temp = _enum.owner()._getClass("javax.json.bind.adapter.JsonbAdapter");
}
if(temp != null) {
temp.generify("String", String.class);
temp.narrow(Object.class);
} else {
System.out.println("temp class is null !!!");
}
JDefinedClass adapter = c._implements(temp1);
adapter.narrow(String.class);
// create the adoptToJson method
JMethod to = c.method(JMod.PUBLIC, String.class, "adaptToJson");
to.annotate(Override.class);
to.param(_enum, "obj");
to.body().directStatement("return obj.value();");
// create the adoptFromJson method
JMethod from = c.method(JMod.PUBLIC, _enum, "adaptFromJson");
from.annotate(Override.class);
from.param(String.class, "obj");
from.body().directStatement("return " + enumDefinition.getNodeName() + ".fromValue(obj);");
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
finally made it
c._implements(model.ref(JsonbAdapter.class).narrow(Object.class).narrow(String.class));
produces
public class TestClass implements JsonbAdapter<Object, String>
Thx for your help - that was the last piece missing ;-)
Hi,
I'm currently implementing a customized rule class to overcome some limitation in handling enums when generating JSONB output.
I'm stuck at the point where I need to create an inner class that implements a typed interface of JsonbAdapter <T, String>
Using JCodeModel statement of
// create an public static inner class inside the enum
c._implements(JsonbAdapter.class)
just gives me
public static class EventTypeMapper implements JsonbAdapter {
What I actually need is
public static class EventTypeMapper implements JsonbAdapter<EventType, String> {
Any idea how that can be achieved with JCodeModel ?
Any help appreciated