fixed missing enum support for JSONB1 styled output
joerg-d-schneider-db opened this issue · comments
I finally fixed the currently missing support to properly handle enums when generating JSONB1 standard output.
I managed to do that by implementing a customAnnotator and a customRuleFactory.
As my company does not permit to upload any files, I share that solution by posting here - it's not much code anyway.
Thx
package com.db.dice.rules;
import org.jsonschema2pojo.Annotator;
import org.jsonschema2pojo.GenerationConfig;
import org.jsonschema2pojo.SchemaStore;
import org.jsonschema2pojo.rules.Rule;
import org.jsonschema2pojo.rules.RuleFactory;
import com.sun.codemodel.JClassContainer;
import com.sun.codemodel.JType;
/**
* @author sf9100
* @since Jun 2023
*/
public class EnumMapperRuleFactory extends RuleFactory {
public EnumMapperRuleFactory(GenerationConfig generationConfig, Annotator annotator, SchemaStore schemaStore) {
super(generationConfig, annotator, schemaStore);
}
public EnumMapperRuleFactory() {
super();
}
@Override
public Rule<JClassContainer, JType> getEnumRule() {
return new EnumMapperRule(this);
}
}
package com.db.dice.rules;
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.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) {
// implement the JsonbAdapter interface
c._implements(_enum.owner().ref(JsonbAdapter.class).narrow(_enum).narrow(String.class));
// create the adaptToJson 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 adaptFromJson 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();
}
}
}
}
package com.db.dice.util;
import javax.json.bind.annotation.JsonbTypeAdapter;
import org.jsonschema2pojo.AbstractAnnotator;
import com.db.dice.rules.EnumMapperRule;
import com.fasterxml.jackson.databind.JsonNode;
import com.sun.codemodel.JClass;
import com.sun.codemodel.JDefinedClass;
import com.sun.codemodel.JFieldVar;
import com.sun.codemodel.JType;
public class EnumJsonbAdapterAnnotator extends AbstractAnnotator {
@Override
public void propertyField(JFieldVar field, JDefinedClass clazz, String propertyName, JsonNode propertyNode) {
super.propertyField(field, clazz, propertyName, propertyNode);
if (propertyNode.has("enum")) {
try {
JClass temp1 = clazz.owner()
.directClass(field.type().fullName() + "." + field.type().name() + EnumMapperRule.SUFFIX);
field.annotate(JsonbTypeAdapter.class).param("value", (JType) temp1);
} catch (Exception e) {
e.printStackTrace();
}
}
}
}