diff --git a/jsonschema2pojo-core/src/main/java/org/jsonschema2pojo/rules/PropertiesRule.java b/jsonschema2pojo-core/src/main/java/org/jsonschema2pojo/rules/PropertiesRule.java
index 5289f2064..76aef50ca 100644
--- a/jsonschema2pojo-core/src/main/java/org/jsonschema2pojo/rules/PropertiesRule.java
+++ b/jsonschema2pojo-core/src/main/java/org/jsonschema2pojo/rules/PropertiesRule.java
@@ -16,15 +16,15 @@
package org.jsonschema2pojo.rules;
-import java.util.Iterator;
-
import com.fasterxml.jackson.databind.JsonNode;
+import com.sun.codemodel.*;
import org.jsonschema2pojo.Schema;
-import com.sun.codemodel.JDefinedClass;
+
+import java.util.Iterator;
/**
* Applies the "properties" schema rule.
- *
+ *
* @see http://tools.ietf.org/html/draft-zyp-json-schema-03#section-5.2
*/
@@ -41,7 +41,7 @@ protected PropertiesRule(RuleFactory ruleFactory) {
*
* For each property present within the properties node, this rule will
* invoke the 'property' rule provided by the given schema mapper.
- *
+ *
* @param nodeName
* the name of the node for which properties are being added
* @param node
@@ -54,14 +54,44 @@ protected PropertiesRule(RuleFactory ruleFactory) {
@Override
public JDefinedClass apply(String nodeName, JsonNode node, JDefinedClass jclass, Schema schema) {
- for (Iterator properties = node.fieldNames(); properties.hasNext();) {
+ for (Iterator properties = node.fieldNames(); properties.hasNext(); ) {
String property = properties.next();
ruleFactory.getPropertyRule().apply(property, node.get(property), jclass, schema);
}
+ if (ruleFactory.getGenerationConfig().isGenerateBuilders()) {
+ if (!jclass._extends().name().equals("Object")) {
+ addOverrideBuilders(jclass, jclass.owner()._getClass(jclass._extends().fullName()));
+ }
+ }
+
ruleFactory.getAnnotator().propertyOrder(jclass, node);
return jclass;
}
+
+ private void addOverrideBuilders(JDefinedClass jclass, JDefinedClass parentJclass) {
+ if (parentJclass == null) {
+ return;
+ }
+
+ for (JMethod parentJMethod : parentJclass.methods()) {
+ if (parentJMethod.name().startsWith("with") && parentJMethod.params().size() == 1) {
+ addOverrideBuilder(jclass, parentJMethod, parentJMethod.params().get(0));
+ }
+ }
+ }
+
+ private JMethod addOverrideBuilder(JDefinedClass thisJDefinedClass, JMethod parentBuilder, JVar parentParam) {
+ JMethod builder = thisJDefinedClass.method(parentBuilder.mods().getValue(), thisJDefinedClass, parentBuilder.name());
+ builder.annotate(Override.class);
+
+ JVar param = builder.param(parentParam.type(), parentParam.name());
+ JBlock body = builder.body();
+ body.invoke(JExpr._super(), parentBuilder).arg(param);
+ body._return(JExpr._this());
+
+ return builder;
+ }
}
diff --git a/jsonschema2pojo-integration-tests/src/test/java/org/jsonschema2pojo/integration/ExtendsIT.java b/jsonschema2pojo-integration-tests/src/test/java/org/jsonschema2pojo/integration/ExtendsIT.java
index 360953c08..63c840400 100644
--- a/jsonschema2pojo-integration-tests/src/test/java/org/jsonschema2pojo/integration/ExtendsIT.java
+++ b/jsonschema2pojo-integration-tests/src/test/java/org/jsonschema2pojo/integration/ExtendsIT.java
@@ -13,6 +13,8 @@
package org.jsonschema2pojo.integration;
import java.beans.PropertyDescriptor;
+import java.lang.reflect.Method;
+
import static org.jsonschema2pojo.integration.util.CodeGenerationHelper.*;
import static org.hamcrest.Matchers.*;
import static org.junit.Assert.*;
@@ -100,4 +102,21 @@ public void extendsSchemaWithinDefinitions() throws Exception {
assertThat(subtype.getSuperclass(), is(equalTo(supertype)));
}
+
+ @Test
+ @SuppressWarnings("rawtypes")
+ public void extendsBuilderMethods() throws Exception {
+ ClassLoader resultsClassLoader = generateAndCompile("/schema/extends/subtypeOfSubtypeOfA.json", "com.example", config("generateBuilders", true));
+
+ Class subtype = resultsClassLoader.loadClass("com.example.SubtypeOfSubtypeOfA");
+ Class supertype = resultsClassLoader.loadClass("com.example.SubtypeOfSubtypeOfAParent");
+
+ Method builderMethod = supertype.getDeclaredMethod("withParent", String.class);
+ assertNotNull("no withParent method", builderMethod);
+ assertThat(builderMethod.getReturnType(), is(equalTo(supertype)));
+
+ Method builderMethodOverride = subtype.getDeclaredMethod("withParent", String.class);
+ assertNotNull("no withParent method", builderMethodOverride);
+ assertThat(builderMethodOverride.getReturnType(), is(equalTo(subtype)));
+ }
}