diff --git a/bin/utils/test_file_list.yaml b/bin/utils/test_file_list.yaml index 13915bc6bbe3..86bd12d5d1bb 100644 --- a/bin/utils/test_file_list.yaml +++ b/bin/utils/test_file_list.yaml @@ -10,7 +10,7 @@ - filename: "samples/client/petstore/java/okhttp-gson/src/test/java/org/openapitools/client/ClientTest.java" sha256: 325fdd5d7e2c97790c0fb44f712ab7b2ba022d7e1a5b0056f47b07f342682b6d - filename: "samples/client/petstore/java/okhttp-gson/src/test/java/org/openapitools/client/JSONTest.java" - sha256: 08b089934586d0b1564e9e5940c3dc4f3ef0b79d191ba91d36ee2f07356eab38 + sha256: ddd53d2f640aee7712299f1540779cdb508f0b9c1e96082191686e218eadb04c - filename: "samples/client/petstore/java/okhttp-gson/src/test/java/org/openapitools/client/api/PetApiTest.java" sha256: 8b1b8f2a2ad00ccb090873a94a5f73e328b98317d2ec715f53bd7a1accb2a023 - filename: "samples/client/petstore/java/okhttp-gson/src/test/java/org/openapitools/client/model/PetTest.java" diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/JavaClientCodegen.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/JavaClientCodegen.java index bf0978b1e6de..6a4cfcc3c4c9 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/JavaClientCodegen.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/JavaClientCodegen.java @@ -1207,6 +1207,25 @@ public CodegenModel fromModel(String name, Schema model) { return codegenModel; } + @Override + public Map postProcessAllModels(Map objs) { + objs = super.postProcessAllModels(objs); + if (isLibrary(OKHTTP_GSON)) { + // gson refuses a class whose hierarchy declares two fields bound to one JSON name, so + // the okhttp-gson additionalProperties bag is declared once, on the topmost ancestor + // that has one; every descendant inherits it instead of declaring its own copy + for (CodegenModel cm : getAllModels(objs).values()) { + for (CodegenModel ancestor = cm.getParentModel(); ancestor != null; ancestor = ancestor.getParentModel()) { + if (ancestor.isAdditionalPropertiesTrue) { + cm.vendorExtensions.put("x-inherits-additional-properties", true); + break; + } + } + } + } + return objs; + } + @Override public ModelsMap postProcessModelsEnum(ModelsMap objs) { objs = super.postProcessModelsEnum(objs); diff --git a/modules/openapi-generator/src/main/resources/Java/libraries/okhttp-gson/additional_properties.mustache b/modules/openapi-generator/src/main/resources/Java/libraries/okhttp-gson/additional_properties.mustache index bca54f84d575..a778ae489c3d 100644 --- a/modules/openapi-generator/src/main/resources/Java/libraries/okhttp-gson/additional_properties.mustache +++ b/modules/openapi-generator/src/main/resources/Java/libraries/okhttp-gson/additional_properties.mustache @@ -1,4 +1,5 @@ {{#isAdditionalPropertiesTrue}} +{{^vendorExtensions.x-inherits-additional-properties}} /** * A container for additional, undeclared properties. * This is a holder for any undeclared properties as specified with @@ -43,4 +44,21 @@ } return this.additionalProperties.get(key); } +{{/vendorExtensions.x-inherits-additional-properties}} +{{#vendorExtensions.x-inherits-additional-properties}} + /** + * Set the additional (undeclared) property with the specified name and value. + * If the property does not already exist, create it otherwise replace it. + * The bag is inherited from the superclass. + * + * @param key name of the property + * @param value value of the property + * @return the {{classname}} instance itself + */ + @Override + public {{classname}} putAdditionalProperty(String key, Object value) { + super.putAdditionalProperty(key, value); + return this; + } +{{/vendorExtensions.x-inherits-additional-properties}} {{/isAdditionalPropertiesTrue}} diff --git a/modules/openapi-generator/src/main/resources/Java/libraries/okhttp-gson/pojo.mustache b/modules/openapi-generator/src/main/resources/Java/libraries/okhttp-gson/pojo.mustache index 0224febae000..52e1b20cc785 100644 --- a/modules/openapi-generator/src/main/resources/Java/libraries/okhttp-gson/pojo.mustache +++ b/modules/openapi-generator/src/main/resources/Java/libraries/okhttp-gson/pojo.mustache @@ -206,8 +206,8 @@ public class {{classname}} {{#parent}}extends {{{.}}} {{/parent}}{{#vendorExtens }{{#hasVars}} {{classname}} {{classVarName}} = ({{classname}}) o; return {{#vars}}{{#isByteArray}}Arrays{{/isByteArray}}{{^isByteArray}}Objects{{/isByteArray}}.equals(this.{{name}}, {{classVarName}}.{{name}}){{^-last}} && - {{/-last}}{{/vars}}{{#isAdditionalPropertiesTrue}}&& - Objects.equals(this.additionalProperties, {{classVarName}}.additionalProperties){{/isAdditionalPropertiesTrue}}{{#parent}} && + {{/-last}}{{/vars}}{{#isAdditionalPropertiesTrue}}{{^vendorExtensions.x-inherits-additional-properties}}&& + Objects.equals(this.additionalProperties, {{classVarName}}.additionalProperties){{/vendorExtensions.x-inherits-additional-properties}}{{/isAdditionalPropertiesTrue}}{{#parent}} && super.equals(o){{/parent}};{{/hasVars}}{{^hasVars}} return {{#parent}}super.equals(o){{/parent}}{{^parent}}true{{/parent}};{{/hasVars}} {{/useReflectionEqualsHashCode}} @@ -223,7 +223,7 @@ public class {{classname}} {{#parent}}extends {{{.}}} {{/parent}}{{#vendorExtens return HashCodeBuilder.reflectionHashCode(this); {{/useReflectionEqualsHashCode}} {{^useReflectionEqualsHashCode}} - return Objects.hash({{#vars}}{{^isByteArray}}{{name}}{{/isByteArray}}{{#isByteArray}}Arrays.hashCode({{name}}){{/isByteArray}}{{^-last}}, {{/-last}}{{/vars}}{{#parent}}{{#hasVars}}, {{/hasVars}}super.hashCode(){{/parent}}{{#isAdditionalPropertiesTrue}}{{#hasVars}}, {{/hasVars}}{{^hasVars}}{{#parent}}, {{/parent}}{{/hasVars}}additionalProperties{{/isAdditionalPropertiesTrue}}); + return Objects.hash({{#vars}}{{^isByteArray}}{{name}}{{/isByteArray}}{{#isByteArray}}Arrays.hashCode({{name}}){{/isByteArray}}{{^-last}}, {{/-last}}{{/vars}}{{#parent}}{{#hasVars}}, {{/hasVars}}super.hashCode(){{/parent}}{{#isAdditionalPropertiesTrue}}{{^vendorExtensions.x-inherits-additional-properties}}{{#hasVars}}, {{/hasVars}}{{^hasVars}}{{#parent}}, {{/parent}}{{/hasVars}}additionalProperties{{/vendorExtensions.x-inherits-additional-properties}}{{/isAdditionalPropertiesTrue}}); {{/useReflectionEqualsHashCode}} }{{#vendorExtensions.x-jackson-optional-nullable-helpers}} @@ -245,7 +245,9 @@ public class {{classname}} {{#parent}}extends {{{.}}} {{/parent}}{{#vendorExtens sb.append(" {{name}}: ").append({{#isPassword}}"*"{{/isPassword}}{{^isPassword}}toIndentedString({{name}}){{/isPassword}}).append("\n"); {{/vars}} {{#isAdditionalPropertiesTrue}} +{{^vendorExtensions.x-inherits-additional-properties}} sb.append(" additionalProperties: ").append(toIndentedString(additionalProperties)).append("\n"); +{{/vendorExtensions.x-inherits-additional-properties}} {{/isAdditionalPropertiesTrue}} sb.append("}"); return sb.toString(); diff --git a/modules/openapi-generator/src/test/java/org/openapitools/codegen/java/JavaClientCodegenTest.java b/modules/openapi-generator/src/test/java/org/openapitools/codegen/java/JavaClientCodegenTest.java index e2cf0bac4cc4..95267ea425a3 100644 --- a/modules/openapi-generator/src/test/java/org/openapitools/codegen/java/JavaClientCodegenTest.java +++ b/modules/openapi-generator/src/test/java/org/openapitools/codegen/java/JavaClientCodegenTest.java @@ -2024,6 +2024,61 @@ public void testJdkHttpClientWithAndWithoutParentExtension() { .content().contains("public class AnotherChild {"); } + @Test + public void testAdditionalPropertiesFieldIsDeclaredOncePerHierarchyForGson() { + final Path output = generateOkHttpGsonWithAdditionalProperties("src/test/resources/3_0/allOf_extension_parent.yaml"); + + // exactly one class per hierarchy declares the bag; descendants inherit it + assertThat(output.resolve("src/main/java/xyz/abcdef/model/Person.java")) + .content().contains("private Map additionalProperties;"); + assertThat(output.resolve("src/main/java/xyz/abcdef/model/Child.java")) + .content() + .contains("public class Child extends Person {") + .contains("public Child putAdditionalProperty(String key, Object value) {") + .doesNotContain("Map additionalProperties;"); + // a model without an allOf parent declares its own bag, as before + assertThat(output.resolve("src/main/java/xyz/abcdef/model/PersonA.java")) + .content().contains("private Map additionalProperties;"); + } + + @Test + public void testAdditionalPropertiesFieldIsDeclaredOnceAcrossMultiLevelAllOfForGson() { + final Path output = generateOkHttpGsonWithAdditionalProperties("src/test/resources/3_0/java/okhttp-gson-additional-properties-allof-chain.yaml"); + + // exactly one class per hierarchy declares the bag, also across Root <- Middle <- Leaf + assertThat(output.resolve("src/main/java/xyz/abcdef/model/Root.java")) + .content().contains("private Map additionalProperties;"); + assertThat(output.resolve("src/main/java/xyz/abcdef/model/Middle.java")) + .content() + .contains("public class Middle extends Root {") + .contains("public Middle putAdditionalProperty(String key, Object value) {") + .doesNotContain("Map additionalProperties;"); + assertThat(output.resolve("src/main/java/xyz/abcdef/model/Leaf.java")) + .content() + .contains("public class Leaf extends Middle {") + .contains("public Leaf putAdditionalProperty(String key, Object value) {") + .doesNotContain("Map additionalProperties;"); + } + + private Path generateOkHttpGsonWithAdditionalProperties(String inputSpec) { + final Path output = newTempFolder(); + final CodegenConfigurator configurator = new CodegenConfigurator() + .setGeneratorName(JAVA_GENERATOR) + // use default `okhttp-gson` + .addAdditionalProperty(CodegenConstants.API_PACKAGE, "xyz.abcdef.api") + .addAdditionalProperty(CodegenConstants.MODEL_PACKAGE, "xyz.abcdef.model") + .addAdditionalProperty(CodegenConstants.INVOKER_PACKAGE, "xyz.abcdef.invoker") + .addAdditionalProperty("disallowAdditionalPropertiesIfNotPresent", "false") + .setInputSpec(inputSpec) + .setOutputDir(output.toString().replace("\\", "/")); + + DefaultGenerator generator = new DefaultGenerator(); + generator.setGeneratorPropertyDefault(CodegenConstants.MODELS, "true"); + List files = generator.opts(configurator.toClientOptInput()).generate(); + validateJavaSourceFiles(files); + return output; + } + @Test public void allOfWithSeveralRefsAndRefAsParentInAllOfNormalizationIsTrue() { final Path output = newTempFolder(); diff --git a/modules/openapi-generator/src/test/resources/3_0/java/okhttp-gson-additional-properties-allof-chain.yaml b/modules/openapi-generator/src/test/resources/3_0/java/okhttp-gson-additional-properties-allof-chain.yaml new file mode 100644 index 000000000000..e7ae2b648d75 --- /dev/null +++ b/modules/openapi-generator/src/test/resources/3_0/java/okhttp-gson-additional-properties-allof-chain.yaml @@ -0,0 +1,33 @@ +openapi: 3.0.3 +info: {title: t, version: '1'} +paths: + /c: + get: + responses: + '200': + description: ok + content: + application/json: + schema: {$ref: '#/components/schemas/Leaf'} +components: + schemas: + Root: + type: object + required: [kind] + discriminator: {propertyName: kind} + properties: + kind: {type: string} + a: {type: string} + Middle: + allOf: + - $ref: '#/components/schemas/Root' + - type: object + properties: + b: {type: string} + discriminator: {propertyName: kind} + Leaf: + allOf: + - $ref: '#/components/schemas/Middle' + - type: object + properties: + c: {type: string} diff --git a/samples/client/petstore/java/okhttp-gson-3.1/src/main/java/org/openapitools/client/model/Cat.java b/samples/client/petstore/java/okhttp-gson-3.1/src/main/java/org/openapitools/client/model/Cat.java index 0300276dbb47..fa9be23e1ffc 100644 --- a/samples/client/petstore/java/okhttp-gson-3.1/src/main/java/org/openapitools/client/model/Cat.java +++ b/samples/client/petstore/java/okhttp-gson-3.1/src/main/java/org/openapitools/client/model/Cat.java @@ -79,51 +79,21 @@ public void setDeclawed(@javax.annotation.Nullable Boolean declawed) { this.declawed = declawed; } - /** - * A container for additional, undeclared properties. - * This is a holder for any undeclared properties as specified with - * the 'additionalProperties' keyword in the OAS document. - */ - private Map additionalProperties; - /** * Set the additional (undeclared) property with the specified name and value. * If the property does not already exist, create it otherwise replace it. + * The bag is inherited from the superclass. * * @param key name of the property * @param value value of the property * @return the Cat instance itself */ + @Override public Cat putAdditionalProperty(String key, Object value) { - if (this.additionalProperties == null) { - this.additionalProperties = new HashMap(); - } - this.additionalProperties.put(key, value); + super.putAdditionalProperty(key, value); return this; } - /** - * Return the additional (undeclared) property. - * - * @return a map of objects - */ - public Map getAdditionalProperties() { - return additionalProperties; - } - - /** - * Return the additional (undeclared) property with the specified name. - * - * @param key name of the property - * @return an object - */ - public Object getAdditionalProperty(String key) { - if (this.additionalProperties == null) { - return null; - } - return this.additionalProperties.get(key); - } - @Override public boolean equals(Object o) { @@ -134,14 +104,13 @@ public boolean equals(Object o) { return false; } Cat cat = (Cat) o; - return Objects.equals(this.declawed, cat.declawed)&& - Objects.equals(this.additionalProperties, cat.additionalProperties) && + return Objects.equals(this.declawed, cat.declawed) && super.equals(o); } @Override public int hashCode() { - return Objects.hash(declawed, super.hashCode(), additionalProperties); + return Objects.hash(declawed, super.hashCode()); } @Override @@ -150,7 +119,6 @@ public String toString() { sb.append("class Cat {\n"); sb.append(" ").append(toIndentedString(super.toString())).append("\n"); sb.append(" declawed: ").append(toIndentedString(declawed)).append("\n"); - sb.append(" additionalProperties: ").append(toIndentedString(additionalProperties)).append("\n"); sb.append("}"); return sb.toString(); } diff --git a/samples/client/petstore/java/okhttp-gson-3.1/src/main/java/org/openapitools/client/model/Dog.java b/samples/client/petstore/java/okhttp-gson-3.1/src/main/java/org/openapitools/client/model/Dog.java index 84fda067106f..b36509e2e2b4 100644 --- a/samples/client/petstore/java/okhttp-gson-3.1/src/main/java/org/openapitools/client/model/Dog.java +++ b/samples/client/petstore/java/okhttp-gson-3.1/src/main/java/org/openapitools/client/model/Dog.java @@ -79,51 +79,21 @@ public void setBreed(@javax.annotation.Nullable String breed) { this.breed = breed; } - /** - * A container for additional, undeclared properties. - * This is a holder for any undeclared properties as specified with - * the 'additionalProperties' keyword in the OAS document. - */ - private Map additionalProperties; - /** * Set the additional (undeclared) property with the specified name and value. * If the property does not already exist, create it otherwise replace it. + * The bag is inherited from the superclass. * * @param key name of the property * @param value value of the property * @return the Dog instance itself */ + @Override public Dog putAdditionalProperty(String key, Object value) { - if (this.additionalProperties == null) { - this.additionalProperties = new HashMap(); - } - this.additionalProperties.put(key, value); + super.putAdditionalProperty(key, value); return this; } - /** - * Return the additional (undeclared) property. - * - * @return a map of objects - */ - public Map getAdditionalProperties() { - return additionalProperties; - } - - /** - * Return the additional (undeclared) property with the specified name. - * - * @param key name of the property - * @return an object - */ - public Object getAdditionalProperty(String key) { - if (this.additionalProperties == null) { - return null; - } - return this.additionalProperties.get(key); - } - @Override public boolean equals(Object o) { @@ -134,14 +104,13 @@ public boolean equals(Object o) { return false; } Dog dog = (Dog) o; - return Objects.equals(this.breed, dog.breed)&& - Objects.equals(this.additionalProperties, dog.additionalProperties) && + return Objects.equals(this.breed, dog.breed) && super.equals(o); } @Override public int hashCode() { - return Objects.hash(breed, super.hashCode(), additionalProperties); + return Objects.hash(breed, super.hashCode()); } @Override @@ -150,7 +119,6 @@ public String toString() { sb.append("class Dog {\n"); sb.append(" ").append(toIndentedString(super.toString())).append("\n"); sb.append(" breed: ").append(toIndentedString(breed)).append("\n"); - sb.append(" additionalProperties: ").append(toIndentedString(additionalProperties)).append("\n"); sb.append("}"); return sb.toString(); } diff --git a/samples/client/petstore/java/okhttp-gson/src/main/java/org/openapitools/client/model/Cat.java b/samples/client/petstore/java/okhttp-gson/src/main/java/org/openapitools/client/model/Cat.java index e393b16c03fd..8a41d8f9d0c0 100644 --- a/samples/client/petstore/java/okhttp-gson/src/main/java/org/openapitools/client/model/Cat.java +++ b/samples/client/petstore/java/okhttp-gson/src/main/java/org/openapitools/client/model/Cat.java @@ -80,51 +80,21 @@ public void setDeclawed(@javax.annotation.Nullable Boolean declawed) { this.declawed = declawed; } - /** - * A container for additional, undeclared properties. - * This is a holder for any undeclared properties as specified with - * the 'additionalProperties' keyword in the OAS document. - */ - private Map additionalProperties; - /** * Set the additional (undeclared) property with the specified name and value. * If the property does not already exist, create it otherwise replace it. + * The bag is inherited from the superclass. * * @param key name of the property * @param value value of the property * @return the Cat instance itself */ + @Override public Cat putAdditionalProperty(String key, Object value) { - if (this.additionalProperties == null) { - this.additionalProperties = new HashMap(); - } - this.additionalProperties.put(key, value); + super.putAdditionalProperty(key, value); return this; } - /** - * Return the additional (undeclared) property. - * - * @return a map of objects - */ - public Map getAdditionalProperties() { - return additionalProperties; - } - - /** - * Return the additional (undeclared) property with the specified name. - * - * @param key name of the property - * @return an object - */ - public Object getAdditionalProperty(String key) { - if (this.additionalProperties == null) { - return null; - } - return this.additionalProperties.get(key); - } - @Override public boolean equals(Object o) { @@ -135,14 +105,13 @@ public boolean equals(Object o) { return false; } Cat cat = (Cat) o; - return Objects.equals(this.declawed, cat.declawed)&& - Objects.equals(this.additionalProperties, cat.additionalProperties) && + return Objects.equals(this.declawed, cat.declawed) && super.equals(o); } @Override public int hashCode() { - return Objects.hash(declawed, super.hashCode(), additionalProperties); + return Objects.hash(declawed, super.hashCode()); } @Override @@ -151,7 +120,6 @@ public String toString() { sb.append("class Cat {\n"); sb.append(" ").append(toIndentedString(super.toString())).append("\n"); sb.append(" declawed: ").append(toIndentedString(declawed)).append("\n"); - sb.append(" additionalProperties: ").append(toIndentedString(additionalProperties)).append("\n"); sb.append("}"); return sb.toString(); } diff --git a/samples/client/petstore/java/okhttp-gson/src/main/java/org/openapitools/client/model/Dog.java b/samples/client/petstore/java/okhttp-gson/src/main/java/org/openapitools/client/model/Dog.java index d0a09fb3fbea..ff82e15d3230 100644 --- a/samples/client/petstore/java/okhttp-gson/src/main/java/org/openapitools/client/model/Dog.java +++ b/samples/client/petstore/java/okhttp-gson/src/main/java/org/openapitools/client/model/Dog.java @@ -79,51 +79,21 @@ public void setBreed(@javax.annotation.Nullable String breed) { this.breed = breed; } - /** - * A container for additional, undeclared properties. - * This is a holder for any undeclared properties as specified with - * the 'additionalProperties' keyword in the OAS document. - */ - private Map additionalProperties; - /** * Set the additional (undeclared) property with the specified name and value. * If the property does not already exist, create it otherwise replace it. + * The bag is inherited from the superclass. * * @param key name of the property * @param value value of the property * @return the Dog instance itself */ + @Override public Dog putAdditionalProperty(String key, Object value) { - if (this.additionalProperties == null) { - this.additionalProperties = new HashMap(); - } - this.additionalProperties.put(key, value); + super.putAdditionalProperty(key, value); return this; } - /** - * Return the additional (undeclared) property. - * - * @return a map of objects - */ - public Map getAdditionalProperties() { - return additionalProperties; - } - - /** - * Return the additional (undeclared) property with the specified name. - * - * @param key name of the property - * @return an object - */ - public Object getAdditionalProperty(String key) { - if (this.additionalProperties == null) { - return null; - } - return this.additionalProperties.get(key); - } - @Override public boolean equals(Object o) { @@ -134,14 +104,13 @@ public boolean equals(Object o) { return false; } Dog dog = (Dog) o; - return Objects.equals(this.breed, dog.breed)&& - Objects.equals(this.additionalProperties, dog.additionalProperties) && + return Objects.equals(this.breed, dog.breed) && super.equals(o); } @Override public int hashCode() { - return Objects.hash(breed, super.hashCode(), additionalProperties); + return Objects.hash(breed, super.hashCode()); } @Override @@ -150,7 +119,6 @@ public String toString() { sb.append("class Dog {\n"); sb.append(" ").append(toIndentedString(super.toString())).append("\n"); sb.append(" breed: ").append(toIndentedString(breed)).append("\n"); - sb.append(" additionalProperties: ").append(toIndentedString(additionalProperties)).append("\n"); sb.append("}"); return sb.toString(); } diff --git a/samples/client/petstore/java/okhttp-gson/src/main/java/org/openapitools/client/model/ParentPet.java b/samples/client/petstore/java/okhttp-gson/src/main/java/org/openapitools/client/model/ParentPet.java index 281f4083faac..1412facdeb6e 100644 --- a/samples/client/petstore/java/okhttp-gson/src/main/java/org/openapitools/client/model/ParentPet.java +++ b/samples/client/petstore/java/okhttp-gson/src/main/java/org/openapitools/client/model/ParentPet.java @@ -55,51 +55,21 @@ public class ParentPet extends GrandparentAnimal { public ParentPet() { this.petType = this.getClass().getSimpleName(); } - /** - * A container for additional, undeclared properties. - * This is a holder for any undeclared properties as specified with - * the 'additionalProperties' keyword in the OAS document. - */ - private Map additionalProperties; - /** * Set the additional (undeclared) property with the specified name and value. * If the property does not already exist, create it otherwise replace it. + * The bag is inherited from the superclass. * * @param key name of the property * @param value value of the property * @return the ParentPet instance itself */ + @Override public ParentPet putAdditionalProperty(String key, Object value) { - if (this.additionalProperties == null) { - this.additionalProperties = new HashMap(); - } - this.additionalProperties.put(key, value); + super.putAdditionalProperty(key, value); return this; } - /** - * Return the additional (undeclared) property. - * - * @return a map of objects - */ - public Map getAdditionalProperties() { - return additionalProperties; - } - - /** - * Return the additional (undeclared) property with the specified name. - * - * @param key name of the property - * @return an object - */ - public Object getAdditionalProperty(String key) { - if (this.additionalProperties == null) { - return null; - } - return this.additionalProperties.get(key); - } - @Override public boolean equals(Object o) { @@ -114,7 +84,7 @@ public boolean equals(Object o) { @Override public int hashCode() { - return Objects.hash(super.hashCode(), additionalProperties); + return Objects.hash(super.hashCode()); } @Override @@ -122,7 +92,6 @@ public String toString() { StringBuilder sb = new StringBuilder(); sb.append("class ParentPet {\n"); sb.append(" ").append(toIndentedString(super.toString())).append("\n"); - sb.append(" additionalProperties: ").append(toIndentedString(additionalProperties)).append("\n"); sb.append("}"); return sb.toString(); } diff --git a/samples/client/petstore/java/okhttp-gson/src/test/java/org/openapitools/client/JSONTest.java b/samples/client/petstore/java/okhttp-gson/src/test/java/org/openapitools/client/JSONTest.java index 5631c34e7786..86c22dc25e15 100644 --- a/samples/client/petstore/java/okhttp-gson/src/test/java/org/openapitools/client/JSONTest.java +++ b/samples/client/petstore/java/okhttp-gson/src/test/java/org/openapitools/client/JSONTest.java @@ -40,6 +40,16 @@ public void setup() { order = new Order(); } + @Test + public void testAdditionalPropertiesRoundTripOnAllOfChild() { + Gson gson = json.getGson(); + + // Dog extends Animal and both allow additional properties; gson used to refuse Dog outright + Dog dog = gson.fromJson("{\"className\":\"Dog\",\"breed\":\"b\",\"extra\":\"e\"}", Dog.class); + assertEquals(Collections.singletonMap("extra", "e"), dog.getAdditionalProperties()); + assertEquals("e", gson.toJsonTree(dog).getAsJsonObject().get("extra").getAsString()); + } + @Test public void testAnyOfWithNullableRequiredFields() { Gson gson = json.getGson();