![JAR search and dependency download from the Maven repository](/logo.png)
org.aml.raml2java.SimpleBeanGenerator Maven / Gradle / Ivy
package org.aml.raml2java;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Set;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlElementWrapper;
import org.aml.raml2java.JavaGenerationConfig.MultipleInheritanceStrategy;
import org.aml.typesystem.AbstractType;
import org.aml.typesystem.beans.IProperty;
import org.aml.typesystem.beans.IXMLHints;
import org.aml.typesystem.meta.facets.Default;
import org.aml.typesystem.meta.facets.Description;
import org.aml.typesystem.meta.facets.Discriminator;
import org.aml.typesystem.meta.facets.DiscriminatorValue;
import org.aml.typesystem.meta.facets.XMLFacet;
import org.aml.typesystem.meta.restrictions.ComponentShouldBeOfType;
import org.raml.v2.internal.utils.StreamUtils;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonSubTypes;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.JsonAdapter;
import com.sun.codemodel.ClassType;
import com.sun.codemodel.JAnnotationArrayMember;
import com.sun.codemodel.JAnnotationUse;
import com.sun.codemodel.JArray;
import com.sun.codemodel.JClass;
import com.sun.codemodel.JClassAlreadyExistsException;
import com.sun.codemodel.JDefinedClass;
import com.sun.codemodel.JExpr;
import com.sun.codemodel.JExpression;
import com.sun.codemodel.JFieldVar;
import com.sun.codemodel.JFormatter;
import com.sun.codemodel.JMethod;
import com.sun.codemodel.JMod;
import com.sun.codemodel.JStatement;
import com.sun.codemodel.JType;
public class SimpleBeanGenerator implements ITypeGenerator {
private JavaWriter writer;
private boolean booleanAsIs = false;
public SimpleBeanGenerator(JavaWriter wr) {
this.writer = wr;
}
static class Extras {
ArrayList patterns = new ArrayList<>();
ArrayList fieldNames = new ArrayList<>();
ArrayList types = new ArrayList<>();
boolean needPropertyOverrides;
boolean needSubTypes;
ArrayList params = new ArrayList<>();
}
@Override
public JType define(AbstractType t) {
JDefinedClass defineClass = writer.defineClass(t, ClassType.CLASS);
writer.defined.put(t, defineClass);
AbstractType superType = t.superType();
boolean hasAdditionalOrMap = false;
boolean hasMap = false;
Extras ext = new Extras();
if (superType != null) {
JType type = writer.getType(superType);
defineClass._extends((JClass) type);
for (IProperty p : t.toPropertiesView().properties()) {
generateProperty(defineClass, p, ext);
if (p.isAdditional() || p.isMap()) {
hasAdditionalOrMap = true;
hasMap |= p.isMap();
}
}
;
} else {
if (this.writer.getConfig().multipleInheritance == MultipleInheritanceStrategy.MIX_IN) {
AbstractType primarySuper = null;
int pcount = 0;
for (AbstractType st : t.superTypes()) {
if (primarySuper == null) {
primarySuper = st;
}
if (st.propertySet().size() > pcount) {
pcount = st.propertySet().size();
primarySuper = st;
}
}
Set inheritedPropeties = primarySuper.propertySet();
JType type = writer.getType(primarySuper);
defineClass._extends((JClass) type);
for (IProperty p : t.toPropertiesView().allProperties()) {
if (!inheritedPropeties.contains(p.id())) {
generateProperty(defineClass, p, ext);
if (p.isAdditional() || p.isMap()) {
hasAdditionalOrMap = true;
hasMap |= p.isMap();
}
}
}
;
} else {
for (IProperty p : t.toPropertiesView().allProperties()) {
generateProperty(defineClass, p, ext);
if (p.isAdditional() || p.isMap()) {
hasAdditionalOrMap = true;
hasMap |= p.isMap();
}
}
;
}
}
writer.annotate(defineClass, t);
if (t.subTypes().size() > 0) {
Discriminator oneMeta = t.oneMeta(Discriminator.class);
if (oneMeta != null) {
String str = oneMeta.value();
if (writer.getConfig().isJacksonSupport()) {
defineClass.annotate(JsonTypeInfo.class).param("use", JsonTypeInfo.Id.NAME).param("property", str)
.param("visible", true).param("defaultImpl", defineClass);
JAnnotationArrayMember paramArray = defineClass.annotate(JsonSubTypes.class).paramArray("value");
for (AbstractType s : t.subTypes()) {
if (!s.isAnonimous()) {
JType type = writer.getType(s);
String discriminatorValue = s.name();
if (s.hasDirectMeta(DiscriminatorValue.class)) {
discriminatorValue = "" + s.oneMeta(DiscriminatorValue.class).value();
}
paramArray.annotate(JsonSubTypes.Type.class).param("value", type).param("name",
discriminatorValue);
}
}
}
if (writer.getConfig().isGsonSupport()) {
ext.needSubTypes = true;
}
}
}
addExtraInfoForPatternAndAdditionals(defineClass, hasAdditionalOrMap, ext, hasMap, t);
return defineClass;
}
private void addExtraInfoForPatternAndAdditionals(JDefinedClass defineClass, boolean hasAdditionalOrMap, Extras ext,
boolean hasMap, AbstractType type) {
ClassCustomizerParameters cp = new ClassCustomizerParameters(writer, defineClass, type, ext.params);
writer.runCustomizers(cp);
if (writer.getConfig().isJaxbSupport()) {
defineClass.annotate(XmlAccessorType.class).param("value", XmlAccessType.PROPERTY);
}
if (hasAdditionalOrMap || ext.needPropertyOverrides || ext.needSubTypes) {
if (writer.getConfig().isGsonSupport()) {
if (!defineClass.getPackage().hasResourceFile("PatternAndAdditionalTypeAdapterFactory.java")) {
String string = StreamUtils.toString(SimpleBeanGenerator.class
.getResourceAsStream("/PatternAndAdditionalTypeAdapterFactory.tpl"));
string = string.replace("{packageName}", defineClass.getPackage().name());
defineClass.getPackage().addResourceFile(
new StringResourceFile("PatternAndAdditionalTypeAdapterFactory.java", string));
}
if (!defineClass.getPackage().hasResourceFile("PatternAndAdditionalTypeAdapter.java")) {
String string = StreamUtils.toString(
SimpleBeanGenerator.class.getResourceAsStream("/PatternAndAdditionalTypeAdapter.tpl"));
string = string.replace("{packageName}", defineClass.getPackage().name());
defineClass.getPackage()
.addResourceFile(new StringResourceFile("PatternAndAdditionalTypeAdapter.java", string));
}
defineClass.annotate(JsonAdapter.class).param("value",
JExpr.dotclass(writer.getModel().directClass("PatternAndAdditionalTypeAdapterFactory")));
addPatternInfo(defineClass, ext);
if (ext.needSubTypes) {
addGsonSubTypingInfo(defineClass, type);
}
}
if (writer.getConfig().isJacksonSupport() && hasAdditionalOrMap) {
if (!defineClass.getPackage().hasResourceFile("MapAndAdditionalDeserializer.java")) {
String string = StreamUtils.toString(
SimpleBeanGenerator.class.getResourceAsStream("/MapAndAdditionalDeserializer.tpl"));
string = string.replace("{packageName}", defineClass.getPackage().name());
defineClass.getPackage()
.addResourceFile(new StringResourceFile("MapAndAdditionalDeserializer.java", string));
}
if (!defineClass.getPackage().hasResourceFile("MapAndAdditionalSerializer.java")) {
String string = StreamUtils
.toString(SimpleBeanGenerator.class.getResourceAsStream("/MapAndAdditionalSerializer.tpl"));
string = string.replace("{packageName}", defineClass.getPackage().name());
defineClass.getPackage()
.addResourceFile(new StringResourceFile("MapAndAdditionalSerializer.java", string));
}
try {
JDefinedClass deserializer = defineClass.getPackage()._class(defineClass.name() + "Deserializer");
deserializer._extends(writer.getModel()
.directClass(defineClass.getPackage().name() + ".MapAndAdditionalDeserializer"));
deserializer.constructor(JMod.PUBLIC).body().invoke("super").arg(JExpr.dotclass(defineClass));
defineClass.annotate(JsonDeserialize.class).param("using", JExpr.dotclass(deserializer));
addPatternInfo(deserializer, ext);
} catch (JClassAlreadyExistsException e) {
throw new IllegalStateException(e);
}
try {
JDefinedClass deserializer = defineClass.getPackage()._class(defineClass.name() + "Serializer");
deserializer._extends(writer.getModel()
.directClass(defineClass.getPackage().name() + ".MapAndAdditionalSerializer"));
deserializer.constructor(JMod.PUBLIC).body().invoke("super").arg(JExpr.dotclass(defineClass));
defineClass.annotate(JsonSerialize.class).param("using", JExpr.dotclass(deserializer));
addPatternInfo(deserializer, ext);
} catch (JClassAlreadyExistsException e) {
throw new IllegalStateException(e);
}
}
}
}
private void addGsonSubTypingInfo(JDefinedClass defineClass, AbstractType type) {
defineClass.field(JMod.STATIC | JMod.PUBLIC | JMod.FINAL, String.class, "$DISCRIMINATOR")
.init(JExpr.lit(type.oneMeta(Discriminator.class).value()));
JArray newArray = JExpr.newArray(writer.getModel()._ref(Class.class));
defineClass.field(JMod.STATIC | JMod.FINAL, Class[].class, "$SUBTYPES").init(newArray);
for (AbstractType t : type.subTypes()) {
newArray.add(JExpr.dotclass((JClass) writer.getType(t)));
}
JArray descValues = JExpr.newArray(writer.getModel()._ref(String.class));
defineClass.field(JMod.STATIC | JMod.FINAL, String[].class, "$DISCRIMINATOR_VALUES").init(descValues);
for (AbstractType t : type.subTypes()) {
if (!t.isAnonimous()) {
String vl = t.name();
if (t.hasDirectMeta(DiscriminatorValue.class)) {
vl = "" + t.oneMeta(DiscriminatorValue.class).value();
}
descValues.add(JExpr.lit(vl));
}
}
}
private void addPatternInfo(JDefinedClass defineClass, Extras ext) {
JArray newArray = JExpr.newArray(writer.getModel()._ref(String.class));
defineClass.field(JMod.STATIC, String[].class, "$PATTERNS").init(newArray);
for (String s : ext.patterns) {
newArray.add(JExpr.lit(s));
}
newArray = JExpr.newArray(writer.getModel()._ref(String.class));
defineClass.field(JMod.STATIC, String[].class, "$FIELDS").init(newArray);
for (String s : ext.fieldNames) {
newArray.add(JExpr.lit(s));
}
newArray = JExpr.newArray(writer.getModel()._ref(Class.class));
defineClass.field(JMod.STATIC, Class[].class, "$CLASSES").init(newArray);
for (JType ct : ext.types) {
newArray.add(JExpr.direct(ct.fullName() + ".class"));
}
}
private void generateProperty(JDefinedClass defineClass, IProperty p, Extras ext) {
String name = writer.propNameGenerator.name(p);
JType propType = writer.getType(p.range(), false, false, p);
JExpression initExpr = null;
if (p.isMap() || p.isAdditional()) {
JType oType = propType;
propType = ((JClass) writer.getModel()._ref(Map.class)).narrow(String.class).narrow(propType);
initExpr = JExpr
._new(((JClass) writer.getModel()._ref(LinkedHashMap.class)).narrow(String.class).narrow(oType));
ext.fieldNames.add(name);
ext.patterns.add(p.id().substring(1, p.id().length() - 1));
ext.types.add(oType);
}
if (p.range().isArray()) {
initExpr = writer.toArrayInit(p.range(), p);
} else {
Default dv = p.range().oneMeta(Default.class);
if (dv != null) {
if (p.range().isScalar()) {
if (p.range().isString()) {
initExpr = JExpr.lit("" + dv.value());
}
if (p.range().isBoolean()) {
initExpr = JExpr.lit(Boolean.parseBoolean(""+dv.value()));
}
else if (p.range().isNumber()) {
String name2 = propType.name().toLowerCase();
if(name2.equals("float")){
initExpr = JExpr.lit(Float.parseFloat(((""+dv.value()))));
}
else if(name2.equals("double")){
initExpr = JExpr.lit(Double.parseDouble(((""+dv.value()))));
}
else if(name2.equals("short")){
initExpr = JExpr.lit(Double.parseDouble(((""+dv.value()))));
}
else if(name2.equals("long")){
initExpr = JExpr.lit(Long.parseLong(((""+dv.value()))));
}
else if(name2.equals("byte")){
initExpr = JExpr.lit(Byte.parseByte(((""+dv.value()))));
}
else{
initExpr = JExpr.lit(Double.parseDouble(((""+dv.value()))));
}
}
}
}
}
JClass _extends = defineClass._extends();
boolean needField = true;
JType ts = null;
if (_extends != null && _extends instanceof JDefinedClass) {
JDefinedClass ee = (JDefinedClass) _extends;
JFieldVar jFieldVar = ee.fields().get(name);
if (jFieldVar != null) {
needField = false;
jFieldVar.mods().setProtected();
ts = jFieldVar.type();
}
}
JFieldVar field = null;
if (needField) {
field = defineClass.field(JMod.PROTECTED, propType, name);
if (p.range().isFile() && writer.getConfig().isGsonSupport()) {
if (!defineClass.getPackage().hasResourceFile("ByteArrayToBase64TypeAdapter.java")) {
String string = StreamUtils.toString(
SimpleBeanGenerator.class.getResourceAsStream("/ByteArrayToBase64TypeAdapter.tpl"));
string = string.replace("{packageName}", defineClass.getPackage().name());
defineClass.getPackage()
.addResourceFile(new StringResourceFile("ByteArrayToBase64TypeAdapter.java", string));
field.annotate(JsonAdapter.class).param("value", writer.getModel()
.directClass(defineClass.getPackage().name() + ".ByteArrayToBase64TypeAdapter"));
}
}
if (writer.getConfig().isGsonSupport()) {
if (p.isMap() || p.isAdditional()) {
field.annotate(Expose.class).param("serialize", false).param("deserialize", false);
}
}
if (writer.getConfig().isJacksonSupport()) {
if (p.isMap() || p.isAdditional()) {
field.annotate(JsonIgnore.class);
}
}
if (initExpr != null) {
field.init(initExpr);
}
}
JMethod get = defineClass.method(JMod.PUBLIC, propType,
"get" + Character.toUpperCase(name.charAt(0)) + name.substring(1));
if (p.range().hasDirectMeta(Description.class)) {
get.javadoc().add(p.range().oneMeta(Description.class).value());
}
JExpression ref = JExpr.ref(name);
if (ts != null && !ts.equals(propType)) {
ref = JExpr.cast(propType, ref);
if (writer.getConfig().isGsonSupport()) {
ext.needPropertyOverrides = true;
}
}
get.body()._return(ref);
writer.annotate(get, p.range());
JMethod set = defineClass.method(JMod.PUBLIC, writer.getModel()._ref(void.class),
((p.range().isBoolean() && this.booleanAsIs) ? "is" : "set") + Character.toUpperCase(name.charAt(0))
+ name.substring(1));
set.param(propType, "value");
set.body().add(new JStatement() {
@Override
public void state(JFormatter f) {
f.p("this." + name + "=value;");
f.nl();
}
});
if (writer.getConfig().isGenerateBuilderMethods()){
JMethod builder = defineClass.method(JMod.PUBLIC, defineClass,
"with" + Character.toUpperCase(name.charAt(0))
+ name.substring(1));
builder.param(propType, "value");
builder.body().add(new JStatement() {
@Override
public void state(JFormatter f) {
f.p("this." + name + "=value;");
f.nl();
f.p("return this;");
f.nl();
}
});
}
PropertyCustomizerParameters propCustomizer = new PropertyCustomizerParameters(writer, p, defineClass, get, set,
field);
writer.runCustomizers(propCustomizer);
ext.params.add(propCustomizer);
if (writer.getConfig().isJaxbSupport() && p.getXMLHints() != null) {
IXMLHints xmlHints = p.getXMLHints();
if (xmlHints.isAttribute()) {
JAnnotationUse annotate = get.annotate(XmlAttribute.class);
if (xmlHints.localName() != null && !xmlHints.localName().equals(name)) {
annotate.param("name", xmlHints.localName());
}
} else {
if (xmlHints.wrapped()) {
JAnnotationUse annotate = get.annotate(XmlElementWrapper.class);
annotate.param("name", name);
annotate = get.annotate(XmlElement.class);
String mn = p.range().name();
AbstractType range = p.range();
ComponentShouldBeOfType oneMeta = range.oneMeta(ComponentShouldBeOfType.class);
if (oneMeta != null) {
range = oneMeta.range();
}
if (range.superTypes().size() > 1) {
mn = name;
}
while (mn == null || mn.length() == 0) {
mn = range.name();
if (range.hasDirectMeta(XMLFacet.class)) {
XMLFacet meta = range.oneMeta(XMLFacet.class);
if (meta.getName() != null && meta.getName().length() > 0) {
mn = meta.getName();
}
}
range = range.superType();
}
annotate.param("name", mn);
} else if (xmlHints.localName() != null && !xmlHints.localName().equals(name)) {
JAnnotationUse annotate = get.annotate(XmlElement.class);
annotate.param("name", xmlHints.localName());
}
}
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy