Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Extends #1542

Open
wants to merge 10 commits into
base: master
Choose a base branch
from
Original file line number Diff line number Diff line change
Expand Up @@ -634,5 +634,9 @@ default boolean isUseInnerClassBuilders() {
* @return Whether to use <a href="http://jcp.org/en/jsr/detail?id=303">JSR-303</a> annotations from {@code jakarta.validation} package instead of {@code javax.validation} package when adding JSR-303 annotations to generated Java types
*/
boolean isUseJakartaValidation();

default boolean isOnlyAbstractJavaTypeClasses() {
return false;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import java.io.IOException;
import java.net.URI;
import java.net.URL;
import java.util.Iterator;

import org.jsonschema2pojo.rules.RuleFactory;

Expand All @@ -29,6 +30,7 @@
import com.fasterxml.jackson.databind.node.JsonNodeFactory;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.sun.codemodel.JCodeModel;
import com.sun.codemodel.JDefinedClass;
import com.sun.codemodel.JPackage;
import com.sun.codemodel.JType;

Expand Down Expand Up @@ -87,8 +89,22 @@ public JType generate(JCodeModel codeModel, String className, String packageName

ObjectNode schemaNode = readSchema(schemaUrl);

return ruleFactory.getSchemaRule().apply(className, schemaNode, null, jpackage, new Schema(null, schemaNode, null));

JType type = ruleFactory.getSchemaRule().apply(className, schemaNode, null, jpackage, new Schema(null, schemaNode, null));
if (ruleFactory.getGenerationConfig().isOnlyAbstractJavaTypeClasses()) {
Iterator<JPackage> packages = codeModel.packages();
while(packages.hasNext()) {
Iterator<JDefinedClass> classes = packages.next().classes();
while(classes.hasNext()) {
JDefinedClass jclass = classes.next();
if (jclass.name().startsWith("_")) {
int className_pos = jclass.fullName().lastIndexOf(".") + 1;
String subClassName = jclass.fullName().substring(0, className_pos) + jclass.fullName().substring(className_pos + 1, jclass.fullName().length());
codeModel._getClass(subClassName).hide();
}
}
}
}
return type;
}

private ObjectNode readSchema(URL schemaUrl) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@
import java.util.Map;
import java.util.Set;

import org.jsonschema2pojo.AnnotationStyle;
import org.jsonschema2pojo.Annotator;
import org.jsonschema2pojo.Schema;
import org.jsonschema2pojo.exception.ClassAlreadyExistsException;
Expand Down Expand Up @@ -95,21 +94,23 @@ public JType apply(String nodeName, JsonNode node, JsonNode parent, JPackage _pa
} catch (ClassAlreadyExistsException e) {
return e.getExistingClass();
}

jclass._extends((JClass) superType);


if (jclass._extends() == null) {
jclass._extends((JClass) superType);
}
JDefinedClass parentClass = jclass._extends() instanceof JDefinedClass ? (JDefinedClass) jclass._extends(): jclass;
schema.setJavaTypeIfEmpty(jclass);

if (node.has("title")) {
ruleFactory.getTitleRule().apply(nodeName, node.get("title"), node, jclass, schema);
ruleFactory.getTitleRule().apply(nodeName, node.get("title"), node, parentClass, schema);
}

if (node.has("description")) {
ruleFactory.getDescriptionRule().apply(nodeName, node.get("description"), node, jclass, schema);
ruleFactory.getDescriptionRule().apply(nodeName, node.get("description"), node, parentClass, schema);
}

if (node.has("$comment")) {
ruleFactory.getCommentRule().apply(nodeName, node.get("$comment"), node, jclass, schema);
ruleFactory.getCommentRule().apply(nodeName, node.get("$comment"), node, parentClass, schema);
}

// Creates the class definition for the builder
Expand All @@ -120,40 +121,40 @@ public JType apply(String nodeName, JsonNode node, JsonNode parent, JPackage _pa
ruleFactory.getPropertiesRule().apply(nodeName, node.get("properties"), node, jclass, schema);

if (node.has("javaInterfaces")) {
addInterfaces(jclass, node.get("javaInterfaces"));
addInterfaces(parentClass, node.get("javaInterfaces"));
}

ruleFactory.getAdditionalPropertiesRule().apply(nodeName, node.get("additionalProperties"), node, jclass, schema);

ruleFactory.getDynamicPropertiesRule().apply(nodeName, node.get("properties"), node, jclass, schema);
ruleFactory.getDynamicPropertiesRule().apply(nodeName, node.get("properties"), node, parentClass, schema);

if (node.has("required")) {
ruleFactory.getRequiredArrayRule().apply(nodeName, node.get("required"), node, jclass, schema);
ruleFactory.getRequiredArrayRule().apply(nodeName, node.get("required"), node, parentClass, schema);
}

if (ruleFactory.getGenerationConfig().isIncludeGeneratedAnnotation()) {
AnnotationHelper.addGeneratedAnnotation(ruleFactory.getGenerationConfig(), jclass);
AnnotationHelper.addGeneratedAnnotation(ruleFactory.getGenerationConfig(), parentClass);
}
if (ruleFactory.getGenerationConfig().isIncludeToString()) {
addToString(jclass);
addToString(parentClass);
}

if (ruleFactory.getGenerationConfig().isIncludeHashcodeAndEquals()) {
addHashCode(jclass, node);
addEquals(jclass, node);
addHashCode(parentClass, node);
addEquals(parentClass, node);
}

if (ruleFactory.getGenerationConfig().isParcelable()) {
addParcelSupport(jclass);
addParcelSupport(parentClass);
}

if (ruleFactory.getGenerationConfig().isIncludeConstructors()) {
ruleFactory.getConstructorRule().apply(nodeName, node, parent, jclass, schema);
ruleFactory.getConstructorRule().apply(nodeName, node, parent, parentClass, schema);

}

if (ruleFactory.getGenerationConfig().isSerializable()) {
SerializableHelper.addSerializableSupport(jclass);
SerializableHelper.addSerializableSupport(parentClass);
}

return jclass;
Expand Down Expand Up @@ -239,24 +240,24 @@ private JDefinedClass createClass(String nodeName, JsonNode node, JPackage _pack
if (usePolymorphicDeserialization) {
newType = _package.owner()._class(JMod.PUBLIC, fqn, ClassType.CLASS);
} else {
newType = _package.owner()._class(fqn);
int className_pos = fqn.lastIndexOf(".") + 1;
newType = _package.owner()._class(fqn)._extends(_package.owner()._class(JMod.PUBLIC + JMod.ABSTRACT, fqn.substring(0, className_pos) + "_" + fqn.substring(className_pos), ClassType.CLASS));
}
ruleFactory.getLogger().debug("Adding " + newType.fullName());
} else {
final String className = ruleFactory.getNameHelper().getUniqueClassName(nodeName, node, _package);
if (usePolymorphicDeserialization) {
newType = _package._class(JMod.PUBLIC, className, ClassType.CLASS);
} else {
newType = _package._class(className);
}
ruleFactory.getLogger().debug("Adding " + newType.fullName());
}
ruleFactory.getLogger().info("Adding " + newType.fullName() + (!newType._extends().fullName().equals("java.lang.Object") ? " extends " + newType._extends().fullName() : ""));
} catch (JClassAlreadyExistsException e) {
throw new ClassAlreadyExistsException(e.getExistingClass());
}

annotator.typeInfo(newType, node);
annotator.propertyInclusion(newType, node);
JDefinedClass parentClass = newType._extends() instanceof JDefinedClass ? (JDefinedClass) newType._extends(): newType;
annotator.typeInfo(parentClass, node);
annotator.propertyInclusion(parentClass, node);

return newType;

Expand Down Expand Up @@ -525,17 +526,4 @@ private void addInterfaces(JDefinedClass jclass, JsonNode javaInterfaces) {
jclass._implements(resolveType(jclass._package(), i.asText()));
}
}

private boolean usesPolymorphicDeserialization(JsonNode node) {

AnnotationStyle annotationStyle = ruleFactory.getGenerationConfig().getAnnotationStyle();

if (annotationStyle == AnnotationStyle.JACKSON
|| annotationStyle == AnnotationStyle.JACKSON2) {
return ruleFactory.getGenerationConfig().isIncludeTypeInfo() || node.has("deserializationClassProperty");
}

return false;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -63,18 +63,16 @@ public JDefinedClass apply(String nodeName, JsonNode node, JsonNode parent, JDef
if (node == null) {
node = JsonNodeFactory.instance.objectNode();
}

for (Iterator<String> properties = node.fieldNames(); properties.hasNext(); ) {
String property = properties.next();

ruleFactory.getPropertyRule().apply(property, node.get(property), node, jclass, schema);
}

if (ruleFactory.getGenerationConfig().isGenerateBuilders() && !jclass._extends().name().equals("Object")) {
addOverrideBuilders(jclass, jclass.owner()._getClass(jclass._extends().fullName()));
JDefinedClass parentClass = jclass._extends() instanceof JDefinedClass ? (JDefinedClass) jclass._extends(): jclass;
if (ruleFactory.getGenerationConfig().isGenerateBuilders() && !parentClass._extends().name().equals("Object")) {
addOverrideBuilders(parentClass, parentClass.owner()._getClass(parentClass._extends().fullName()));
}

ruleFactory.getAnnotator().propertyOrder(jclass, node);
ruleFactory.getAnnotator().propertyOrder(parentClass, node);

return jclass;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ protected PropertyRule(RuleFactory ruleFactory) {
*/
@Override
public JDefinedClass apply(String nodeName, JsonNode node, JsonNode parent, JDefinedClass jclass, Schema schema) {
JDefinedClass parentClass = jclass._extends() instanceof JDefinedClass ? (JDefinedClass) jclass._extends(): jclass;
String propertyName;
if (StringUtils.isEmpty(nodeName)) {
propertyName = "__EMPTY__";
Expand All @@ -82,7 +83,7 @@ public JDefinedClass apply(String nodeName, JsonNode node, JsonNode parent, JDef
}

Schema propertySchema = ruleFactory.getSchemaStore().create(schema, pathToProperty, ruleFactory.getGenerationConfig().getRefFragmentPathDelimiters());
JType propertyType = ruleFactory.getSchemaRule().apply(nodeName, node, parent, jclass, propertySchema);
JType propertyType = ruleFactory.getSchemaRule().apply(nodeName, node, parent, parentClass, propertySchema);
propertySchema.setJavaTypeIfEmpty(propertyType);

boolean isIncludeGetters = ruleFactory.getGenerationConfig().isIncludeGetters();
Expand All @@ -91,23 +92,23 @@ public JDefinedClass apply(String nodeName, JsonNode node, JsonNode parent, JDef
node = resolveRefs(node, schema);

int accessModifier = isIncludeGetters || isIncludeSetters ? JMod.PRIVATE : JMod.PUBLIC;
JFieldVar field = jclass.field(accessModifier, propertyType, propertyName);
JFieldVar field = parentClass.field(accessModifier, propertyType, propertyName);

propertyAnnotations(nodeName, node, schema, field);

formatAnnotation(field, jclass, node);
formatAnnotation(field, parentClass, node);

ruleFactory.getAnnotator().propertyField(field, jclass, nodeName, node);
ruleFactory.getAnnotator().propertyField(field, parentClass, nodeName, node);

if (isIncludeGetters) {
JMethod getter = addGetter(jclass, field, nodeName, node, isRequired(nodeName, node, schema), useOptional(nodeName, node, schema));
ruleFactory.getAnnotator().propertyGetter(getter, jclass, nodeName);
JMethod getter = addGetter(parentClass, field, nodeName, node, isRequired(nodeName, node, schema), useOptional(nodeName, node, schema));
ruleFactory.getAnnotator().propertyGetter(getter, parentClass, nodeName);
propertyAnnotations(nodeName, node, schema, getter);
}

if (isIncludeSetters) {
JMethod setter = addSetter(jclass, field, nodeName, node);
ruleFactory.getAnnotator().propertySetter(setter, jclass, nodeName);
JMethod setter = addSetter(parentClass, field, nodeName, node);
ruleFactory.getAnnotator().propertySetter(setter, parentClass, nodeName);
propertyAnnotations(nodeName, node, schema, setter);
}

Expand Down Expand Up @@ -135,7 +136,7 @@ public JDefinedClass apply(String nodeName, JsonNode node, JsonNode parent, JDef

return jclass;
}

private boolean hasEnumerated(Schema schema, String arrayFieldName, String nodeName) {
JsonNode array = schema.getContent().get(arrayFieldName);
if (array != null) {
Expand Down Expand Up @@ -277,12 +278,13 @@ private JMethod addBuilderMethod(JDefinedClass c, JFieldVar field, String jsonPr
}

private JMethod addLegacyBuilder(JDefinedClass c, JFieldVar field, String jsonPropertyName, JsonNode node) {
JMethod builder = c.method(JMod.PUBLIC, c, getBuilderName(jsonPropertyName, node));
JDefinedClass parentClass = c._extends() instanceof JDefinedClass ? (JDefinedClass) c._extends(): c;
JMethod builder = parentClass.method(JMod.PUBLIC, c, getBuilderName(jsonPropertyName, node));

JVar param = builder.param(field.type(), field.name());
JBlock body = builder.body();
body.assign(JExpr._this().ref(field), param);
body._return(JExpr._this());
body._return(JExpr.cast(c, JExpr._this()));

return builder;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -777,6 +777,9 @@ public class Jsonschema2PojoMojo extends AbstractMojo implements GenerationConfi
*/
@Parameter(property = "jsonschema2pojo.useJakartaValidation", defaultValue = "false")
private boolean useJakartaValidation = false;

@Parameter(property = "jsonschema2pojo.onlyAbstractJavaTypeClasses", defaultValue = "false")
private boolean onlyAbstractJavaTypeClasses = false;

/**
* Executes the plugin, to read the given source and behavioural properties
Expand Down Expand Up @@ -1061,6 +1064,11 @@ public FileFilter getFileFilter() {
public boolean isInitializeCollections() {
return initializeCollections;
}

@Override
public boolean isOnlyAbstractJavaTypeClasses() {
return onlyAbstractJavaTypeClasses;
}

boolean filteringEnabled() {
return !((includes == null || includes.length == 0) && (excludes == null || excludes.length == 0));
Expand Down
6 changes: 1 addition & 5 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,7 @@
<url>https://github.com/joelittlejohn/jsonschema2pojo</url>

<modules>
<module>jsonschema2pojo-ant</module>
<module>jsonschema2pojo-cli</module>
<module>jsonschema2pojo-core</module>
<module>jsonschema2pojo-gradle-plugin</module>
<module>jsonschema2pojo-integration-tests</module>
<module>jsonschema2pojo-core</module>
<module>jsonschema2pojo-maven-plugin</module>
</modules>

Expand Down