From 5ddd3c43ce3268a306e6ca913bad32aa27f9c309 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20D=C3=BCmont?= Date: Fri, 3 Jan 2025 11:14:57 +0100 Subject: [PATCH 01/17] Initial --- .../GenerationConfigurationConverter.java | 39 +++++++++++++++++++ .../oneof_interface.mustache | 16 ++++++++ 2 files changed, 55 insertions(+) diff --git a/datamodel/openapi/openapi-generator/src/main/java/com/sap/cloud/sdk/datamodel/openapi/generator/GenerationConfigurationConverter.java b/datamodel/openapi/openapi-generator/src/main/java/com/sap/cloud/sdk/datamodel/openapi/generator/GenerationConfigurationConverter.java index 7366c6d37..53bfd7d10 100644 --- a/datamodel/openapi/openapi-generator/src/main/java/com/sap/cloud/sdk/datamodel/openapi/generator/GenerationConfigurationConverter.java +++ b/datamodel/openapi/openapi-generator/src/main/java/com/sap/cloud/sdk/datamodel/openapi/generator/GenerationConfigurationConverter.java @@ -8,13 +8,16 @@ import java.nio.file.Paths; import java.time.Year; import java.util.HashMap; +import java.util.HashSet; import java.util.List; import java.util.Map; +import java.util.Set; import javax.annotation.Nonnull; import org.openapitools.codegen.ClientOptInput; import org.openapitools.codegen.CodegenConstants; +import org.openapitools.codegen.CodegenModel; import org.openapitools.codegen.CodegenOperation; import org.openapitools.codegen.config.GlobalSettings; import org.openapitools.codegen.languages.JavaClientCodegen; @@ -27,6 +30,7 @@ import io.swagger.parser.OpenAPIParser; import io.swagger.v3.oas.models.OpenAPI; +import io.swagger.v3.oas.models.media.Schema; import io.swagger.v3.parser.core.models.AuthorizationValue; import io.swagger.v3.parser.core.models.ParseOptions; import lombok.extern.slf4j.Slf4j; @@ -75,6 +79,7 @@ static ClientOptInput convertGenerationConfiguration( private static JavaClientCodegen createCodegenConfig() { + var primitives = Set.of("String", "Integer", "Long", "Double", "Float", "Byte"); return new JavaClientCodegen() { // Custom processor to inject "x-return-nullable" extension @@ -93,6 +98,40 @@ public OperationsMap postProcessOperationsWithModels( } return super.postProcessOperationsWithModels(ops, allModels); } + + @SuppressWarnings( { "rawtypes" } ) + @Override + protected + void + updateModelForComposedSchema( CodegenModel m, Schema schema, Map allDefinitions ) + { + super.updateModelForComposedSchema(m, schema, allDefinitions); + if( m.discriminator != null ) { + return; + } + boolean useCreators = false; + for( Set candidates : List.of(m.anyOf, m.oneOf) ) { + Set candidatesSingle = new HashSet<>(); + Set candidatesMultiple = new HashSet<>(); + + for( String candidate : candidates ) { + if( candidate.startsWith("List<") ) { + var c1 = candidate.substring(5, candidate.length() - 1); + candidatesMultiple.add(c1); + useCreators = true; + } else { + candidatesSingle.add(candidate); + useCreators |= primitives.contains(candidate); + } + } + if( useCreators ) { + candidates.clear(); + var monads = Map.of("single", candidatesSingle, "multiple", candidatesMultiple); + m.vendorExtensions.put("x-monads", monads); + m.vendorExtensions.put("x-is-one-of-interface", true); // enforce template usage + } + } + } }; } diff --git a/datamodel/openapi/openapi-generator/src/main/resources/openapi-generator/mustache-templates/oneof_interface.mustache b/datamodel/openapi/openapi-generator/src/main/resources/openapi-generator/mustache-templates/oneof_interface.mustache index 874a1ba63..88faea195 100644 --- a/datamodel/openapi/openapi-generator/src/main/resources/openapi-generator/mustache-templates/oneof_interface.mustache +++ b/datamodel/openapi/openapi-generator/src/main/resources/openapi-generator/mustache-templates/oneof_interface.mustache @@ -3,9 +3,25 @@ * @deprecated{{/isDeprecated}} */{{#isDeprecated}} @Deprecated{{/isDeprecated}} +{{^model.vendorExtensions.x-monads}} {{>additionalOneOfTypeAnnotations}}{{>typeInfoAnnotation}}{{>xmlAnnotation}} +{{/model.vendorExtensions.x-monads}} public interface {{classname}} {{#vendorExtensions.x-implements}}{{#-first}}extends {{{.}}}{{/-first}}{{^-first}}, {{{.}}}{{/-first}}{{/vendorExtensions.x-implements}} { {{#discriminator}} {{propertyType}} {{propertyGetter}}(); {{/discriminator}} +{{#model.vendorExtensions.x-monads.single}} + record Inner{{.}}(@com.fasterxml.jackson.annotation.JsonValue {{.}} value) implements {{classname}} {} + + @com.fasterxml.jackson.annotation.JsonCreator + static Inner{{.}} create( {{.}} val) { return new Inner{{.}}(val); } + +{{/model.vendorExtensions.x-monads.single}} +{{#model.vendorExtensions.x-monads.multiple}} + record Inner{{.}}s(@com.fasterxml.jackson.annotation.JsonValue List<{{.}}> values) implements {{classname}} {} + + @com.fasterxml.jackson.annotation.JsonCreator + static Inner{{.}}s create( List<{{.}}> val) { return new Inner{{.}}s(val); } + +{{/model.vendorExtensions.x-monads.multiple}} } From 393c6ddc175927e0a6940574b49dec12d6304679 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20D=C3=BCmont?= Date: Fri, 3 Jan 2025 11:15:54 +0100 Subject: [PATCH 02/17] Update test --- .../DataModelGeneratorIntegrationTest.java | 2 +- .../input/sodastore.yaml | 7 ++++ .../output/test/AllOf.java | 41 +++++++++++++++++-- .../output/test/AnyOf.java | 41 +++++++++++++++++-- .../output/test/Cola.java | 2 +- .../output/test/DefaultApi.java | 2 +- .../output/test/Fanta.java | 41 +++++++++++++++++-- .../output/test/OneOf.java | 3 +- .../output/test/OneOfWithDiscriminator.java | 3 +- .../OneOfWithDiscriminatorAndMapping.java | 3 +- 10 files changed, 130 insertions(+), 15 deletions(-) diff --git a/datamodel/openapi/openapi-generator/src/test/java/com/sap/cloud/sdk/datamodel/openapi/generator/DataModelGeneratorIntegrationTest.java b/datamodel/openapi/openapi-generator/src/test/java/com/sap/cloud/sdk/datamodel/openapi/generator/DataModelGeneratorIntegrationTest.java index c2d75fe9f..d5f6db514 100644 --- a/datamodel/openapi/openapi-generator/src/test/java/com/sap/cloud/sdk/datamodel/openapi/generator/DataModelGeneratorIntegrationTest.java +++ b/datamodel/openapi/openapi-generator/src/test/java/com/sap/cloud/sdk/datamodel/openapi/generator/DataModelGeneratorIntegrationTest.java @@ -87,7 +87,7 @@ private enum TestCase ApiMaturity.RELEASED, true, true, - 8, + 9, Map.of("useOneOfInterfaces", "true")), INPUT_SPEC_WITH_BUILDER( "input-spec-with-builder", diff --git a/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/oneof-interfaces-enabled/input/sodastore.yaml b/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/oneof-interfaces-enabled/input/sodastore.yaml index e7a169e45..19b65ab45 100644 --- a/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/oneof-interfaces-enabled/input/sodastore.yaml +++ b/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/oneof-interfaces-enabled/input/sodastore.yaml @@ -56,3 +56,10 @@ components: properties: sodaType: type: string + flavor: + oneOf: + - type: string + - $ref: '#/components/schemas/Cola' + - type: array + items: + type: string diff --git a/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/oneof-interfaces-enabled/output/test/AllOf.java b/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/oneof-interfaces-enabled/output/test/AllOf.java index a2c60509f..ab10d6a1c 100644 --- a/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/oneof-interfaces-enabled/output/test/AllOf.java +++ b/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/oneof-interfaces-enabled/output/test/AllOf.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 SAP SE or an SAP affiliate company. All rights reserved. + * Copyright (c) 2025 SAP SE or an SAP affiliate company. All rights reserved. */ /* @@ -27,6 +27,7 @@ import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonTypeName; import com.fasterxml.jackson.annotation.JsonValue; +import test.FantaFlavor; import com.fasterxml.jackson.annotation.JsonAnySetter; import com.fasterxml.jackson.annotation.JsonAnyGetter; import com.fasterxml.jackson.annotation.JsonIgnore; @@ -45,6 +46,9 @@ public class AllOf @JsonProperty("sodaType") private String sodaType; + @JsonProperty("flavor") + private FantaFlavor flavor; + @JsonAnySetter @JsonAnyGetter private final Map cloudSdkCustomFields = new LinkedHashMap<>(); @@ -78,6 +82,35 @@ public void setSodaType( @Nullable final String sodaType) { this.sodaType = sodaType; } + /** + * Set the flavor of this {@link AllOf} instance and return the same instance. + * + * @param flavor The flavor of this {@link AllOf} + * @return The same instance of this {@link AllOf} class + */ + @Nonnull public AllOf flavor( @Nullable final FantaFlavor flavor) { + this.flavor = flavor; + return this; + } + + /** + * Get flavor + * @return flavor The flavor of this {@link AllOf} instance. + */ + @Nonnull + public FantaFlavor getFlavor() { + return flavor; + } + + /** + * Set the flavor of this {@link AllOf} instance. + * + * @param flavor The flavor of this {@link AllOf} + */ + public void setFlavor( @Nullable final FantaFlavor flavor) { + this.flavor = flavor; + } + /** * Get the names of the unrecognizable properties of the {@link AllOf}. * @return The set of properties names @@ -125,12 +158,13 @@ public boolean equals(@Nullable final java.lang.Object o) { } final AllOf allOf = (AllOf) o; return Objects.equals(this.cloudSdkCustomFields, allOf.cloudSdkCustomFields) && - Objects.equals(this.sodaType, allOf.sodaType); + Objects.equals(this.sodaType, allOf.sodaType) && + Objects.equals(this.flavor, allOf.flavor); } @Override public int hashCode() { - return Objects.hash(sodaType, cloudSdkCustomFields); + return Objects.hash(sodaType, flavor, cloudSdkCustomFields); } @Override @@ -138,6 +172,7 @@ public int hashCode() { final StringBuilder sb = new StringBuilder(); sb.append("class AllOf {\n"); sb.append(" sodaType: ").append(toIndentedString(sodaType)).append("\n"); + sb.append(" flavor: ").append(toIndentedString(flavor)).append("\n"); cloudSdkCustomFields.forEach((k,v) -> sb.append(" ").append(k).append(": ").append(toIndentedString(v)).append("\n")); sb.append("}"); return sb.toString(); diff --git a/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/oneof-interfaces-enabled/output/test/AnyOf.java b/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/oneof-interfaces-enabled/output/test/AnyOf.java index 879569438..57ea2d985 100644 --- a/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/oneof-interfaces-enabled/output/test/AnyOf.java +++ b/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/oneof-interfaces-enabled/output/test/AnyOf.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 SAP SE or an SAP affiliate company. All rights reserved. + * Copyright (c) 2025 SAP SE or an SAP affiliate company. All rights reserved. */ /* @@ -29,6 +29,7 @@ import com.fasterxml.jackson.annotation.JsonValue; import test.Cola; import test.Fanta; +import test.FantaFlavor; import com.fasterxml.jackson.annotation.JsonAnySetter; import com.fasterxml.jackson.annotation.JsonAnyGetter; import com.fasterxml.jackson.annotation.JsonIgnore; @@ -47,6 +48,9 @@ public class AnyOf @JsonProperty("sodaType") private String sodaType; + @JsonProperty("flavor") + private FantaFlavor flavor; + @JsonAnySetter @JsonAnyGetter private final Map cloudSdkCustomFields = new LinkedHashMap<>(); @@ -80,6 +84,35 @@ public void setSodaType( @Nullable final String sodaType) { this.sodaType = sodaType; } + /** + * Set the flavor of this {@link AnyOf} instance and return the same instance. + * + * @param flavor The flavor of this {@link AnyOf} + * @return The same instance of this {@link AnyOf} class + */ + @Nonnull public AnyOf flavor( @Nullable final FantaFlavor flavor) { + this.flavor = flavor; + return this; + } + + /** + * Get flavor + * @return flavor The flavor of this {@link AnyOf} instance. + */ + @Nonnull + public FantaFlavor getFlavor() { + return flavor; + } + + /** + * Set the flavor of this {@link AnyOf} instance. + * + * @param flavor The flavor of this {@link AnyOf} + */ + public void setFlavor( @Nullable final FantaFlavor flavor) { + this.flavor = flavor; + } + /** * Get the names of the unrecognizable properties of the {@link AnyOf}. * @return The set of properties names @@ -127,12 +160,13 @@ public boolean equals(@Nullable final java.lang.Object o) { } final AnyOf anyOf = (AnyOf) o; return Objects.equals(this.cloudSdkCustomFields, anyOf.cloudSdkCustomFields) && - Objects.equals(this.sodaType, anyOf.sodaType); + Objects.equals(this.sodaType, anyOf.sodaType) && + Objects.equals(this.flavor, anyOf.flavor); } @Override public int hashCode() { - return Objects.hash(sodaType, cloudSdkCustomFields); + return Objects.hash(sodaType, flavor, cloudSdkCustomFields); } @Override @@ -140,6 +174,7 @@ public int hashCode() { final StringBuilder sb = new StringBuilder(); sb.append("class AnyOf {\n"); sb.append(" sodaType: ").append(toIndentedString(sodaType)).append("\n"); + sb.append(" flavor: ").append(toIndentedString(flavor)).append("\n"); cloudSdkCustomFields.forEach((k,v) -> sb.append(" ").append(k).append(": ").append(toIndentedString(v)).append("\n")); sb.append("}"); return sb.toString(); diff --git a/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/oneof-interfaces-enabled/output/test/Cola.java b/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/oneof-interfaces-enabled/output/test/Cola.java index 3f3063d9d..6346320ca 100644 --- a/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/oneof-interfaces-enabled/output/test/Cola.java +++ b/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/oneof-interfaces-enabled/output/test/Cola.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 SAP SE or an SAP affiliate company. All rights reserved. + * Copyright (c) 2025 SAP SE or an SAP affiliate company. All rights reserved. */ /* diff --git a/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/oneof-interfaces-enabled/output/test/DefaultApi.java b/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/oneof-interfaces-enabled/output/test/DefaultApi.java index 424ff2c43..236455960 100644 --- a/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/oneof-interfaces-enabled/output/test/DefaultApi.java +++ b/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/oneof-interfaces-enabled/output/test/DefaultApi.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 SAP SE or an SAP affiliate company. All rights reserved. + * Copyright (c) 2025 SAP SE or an SAP affiliate company. All rights reserved. */ package test; diff --git a/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/oneof-interfaces-enabled/output/test/Fanta.java b/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/oneof-interfaces-enabled/output/test/Fanta.java index 4ec3ade18..d909cb462 100644 --- a/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/oneof-interfaces-enabled/output/test/Fanta.java +++ b/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/oneof-interfaces-enabled/output/test/Fanta.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 SAP SE or an SAP affiliate company. All rights reserved. + * Copyright (c) 2025 SAP SE or an SAP affiliate company. All rights reserved. */ /* @@ -27,6 +27,7 @@ import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonTypeName; import com.fasterxml.jackson.annotation.JsonValue; +import test.FantaFlavor; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonSubTypes; import com.fasterxml.jackson.annotation.JsonTypeInfo; @@ -48,6 +49,9 @@ public class Fanta implements OneOf, OneOfWithDiscriminator, OneOfWithDiscrimina @JsonProperty("sodaType") private String sodaType; + @JsonProperty("flavor") + private FantaFlavor flavor; + @JsonAnySetter @JsonAnyGetter private final Map cloudSdkCustomFields = new LinkedHashMap<>(); @@ -81,6 +85,35 @@ public void setSodaType( @Nullable final String sodaType) { this.sodaType = sodaType; } + /** + * Set the flavor of this {@link Fanta} instance and return the same instance. + * + * @param flavor The flavor of this {@link Fanta} + * @return The same instance of this {@link Fanta} class + */ + @Nonnull public Fanta flavor( @Nullable final FantaFlavor flavor) { + this.flavor = flavor; + return this; + } + + /** + * Get flavor + * @return flavor The flavor of this {@link Fanta} instance. + */ + @Nonnull + public FantaFlavor getFlavor() { + return flavor; + } + + /** + * Set the flavor of this {@link Fanta} instance. + * + * @param flavor The flavor of this {@link Fanta} + */ + public void setFlavor( @Nullable final FantaFlavor flavor) { + this.flavor = flavor; + } + /** * Get the names of the unrecognizable properties of the {@link Fanta}. * @return The set of properties names @@ -128,12 +161,13 @@ public boolean equals(@Nullable final java.lang.Object o) { } final Fanta fanta = (Fanta) o; return Objects.equals(this.cloudSdkCustomFields, fanta.cloudSdkCustomFields) && - Objects.equals(this.sodaType, fanta.sodaType); + Objects.equals(this.sodaType, fanta.sodaType) && + Objects.equals(this.flavor, fanta.flavor); } @Override public int hashCode() { - return Objects.hash(sodaType, cloudSdkCustomFields); + return Objects.hash(sodaType, flavor, cloudSdkCustomFields); } @Override @@ -141,6 +175,7 @@ public int hashCode() { final StringBuilder sb = new StringBuilder(); sb.append("class Fanta {\n"); sb.append(" sodaType: ").append(toIndentedString(sodaType)).append("\n"); + sb.append(" flavor: ").append(toIndentedString(flavor)).append("\n"); cloudSdkCustomFields.forEach((k,v) -> sb.append(" ").append(k).append(": ").append(toIndentedString(v)).append("\n")); sb.append("}"); return sb.toString(); diff --git a/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/oneof-interfaces-enabled/output/test/OneOf.java b/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/oneof-interfaces-enabled/output/test/OneOf.java index 8100d34c3..995230845 100644 --- a/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/oneof-interfaces-enabled/output/test/OneOf.java +++ b/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/oneof-interfaces-enabled/output/test/OneOf.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 SAP SE or an SAP affiliate company. All rights reserved. + * Copyright (c) 2025 SAP SE or an SAP affiliate company. All rights reserved. */ /* @@ -29,6 +29,7 @@ import com.fasterxml.jackson.annotation.JsonValue; import test.Cola; import test.Fanta; +import test.FantaFlavor; import com.fasterxml.jackson.annotation.JsonSubTypes; import com.fasterxml.jackson.annotation.JsonTypeInfo; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; diff --git a/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/oneof-interfaces-enabled/output/test/OneOfWithDiscriminator.java b/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/oneof-interfaces-enabled/output/test/OneOfWithDiscriminator.java index ada1c2cfe..a0ba57043 100644 --- a/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/oneof-interfaces-enabled/output/test/OneOfWithDiscriminator.java +++ b/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/oneof-interfaces-enabled/output/test/OneOfWithDiscriminator.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 SAP SE or an SAP affiliate company. All rights reserved. + * Copyright (c) 2025 SAP SE or an SAP affiliate company. All rights reserved. */ /* @@ -32,6 +32,7 @@ import com.fasterxml.jackson.annotation.JsonValue; import test.Cola; import test.Fanta; +import test.FantaFlavor; import com.fasterxml.jackson.annotation.JsonAnySetter; import com.fasterxml.jackson.annotation.JsonAnyGetter; import com.fasterxml.jackson.annotation.JsonIgnore; diff --git a/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/oneof-interfaces-enabled/output/test/OneOfWithDiscriminatorAndMapping.java b/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/oneof-interfaces-enabled/output/test/OneOfWithDiscriminatorAndMapping.java index e55a6a8d0..533a118c7 100644 --- a/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/oneof-interfaces-enabled/output/test/OneOfWithDiscriminatorAndMapping.java +++ b/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/oneof-interfaces-enabled/output/test/OneOfWithDiscriminatorAndMapping.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 SAP SE or an SAP affiliate company. All rights reserved. + * Copyright (c) 2025 SAP SE or an SAP affiliate company. All rights reserved. */ /* @@ -32,6 +32,7 @@ import com.fasterxml.jackson.annotation.JsonValue; import test.Cola; import test.Fanta; +import test.FantaFlavor; import com.fasterxml.jackson.annotation.JsonAnySetter; import com.fasterxml.jackson.annotation.JsonAnyGetter; import com.fasterxml.jackson.annotation.JsonIgnore; From 5bcd134f67c5a11dcf6c291637f6135b88c3b43e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20D=C3=BCmont?= Date: Fri, 3 Jan 2025 11:16:59 +0100 Subject: [PATCH 03/17] update sample project --- datamodel/openapi/openapi-api-sample/pom.xml | 1 + .../openapi/sample/api/OrdersApi.java | 2 +- .../openapi/sample/api/SodasApi.java | 2 +- .../datamodel/openapi/sample/model/AllOf.java | 47 +++++++++++++++++-- .../datamodel/openapi/sample/model/AnyOf.java | 47 +++++++++++++++++-- .../datamodel/openapi/sample/model/Cola.java | 2 +- .../datamodel/openapi/sample/model/Fanta.java | 47 +++++++++++++++++-- .../datamodel/openapi/sample/model/OneOf.java | 2 +- .../sample/model/OneOfWithDiscriminator.java | 2 +- .../OneOfWithDiscriminatorAndMapping.java | 2 +- .../datamodel/openapi/sample/model/Order.java | 2 +- .../sample/model/OrderWithTimestamp.java | 2 +- .../datamodel/openapi/sample/model/Soda.java | 2 +- .../openapi/sample/model/SodaWithId.java | 2 +- .../src/main/resources/sodastore.yaml | 10 ++++ .../sample/api/OneOfDeserializationTest.java | 12 ++++- 16 files changed, 163 insertions(+), 21 deletions(-) diff --git a/datamodel/openapi/openapi-api-sample/pom.xml b/datamodel/openapi/openapi-api-sample/pom.xml index 32febda50..471ac956d 100644 --- a/datamodel/openapi/openapi-api-sample/pom.xml +++ b/datamodel/openapi/openapi-api-sample/pom.xml @@ -127,6 +127,7 @@ true true + true diff --git a/datamodel/openapi/openapi-api-sample/src/main/java/com/sap/cloud/sdk/datamodel/openapi/sample/api/OrdersApi.java b/datamodel/openapi/openapi-api-sample/src/main/java/com/sap/cloud/sdk/datamodel/openapi/sample/api/OrdersApi.java index 79c6baa8b..eaae204c3 100644 --- a/datamodel/openapi/openapi-api-sample/src/main/java/com/sap/cloud/sdk/datamodel/openapi/sample/api/OrdersApi.java +++ b/datamodel/openapi/openapi-api-sample/src/main/java/com/sap/cloud/sdk/datamodel/openapi/sample/api/OrdersApi.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 SAP SE or an SAP affiliate company. All rights reserved. + * Copyright (c) 2025 SAP SE or an SAP affiliate company. All rights reserved. */ package com.sap.cloud.sdk.datamodel.openapi.sample.api; diff --git a/datamodel/openapi/openapi-api-sample/src/main/java/com/sap/cloud/sdk/datamodel/openapi/sample/api/SodasApi.java b/datamodel/openapi/openapi-api-sample/src/main/java/com/sap/cloud/sdk/datamodel/openapi/sample/api/SodasApi.java index ebf06d60d..a512ff249 100644 --- a/datamodel/openapi/openapi-api-sample/src/main/java/com/sap/cloud/sdk/datamodel/openapi/sample/api/SodasApi.java +++ b/datamodel/openapi/openapi-api-sample/src/main/java/com/sap/cloud/sdk/datamodel/openapi/sample/api/SodasApi.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 SAP SE or an SAP affiliate company. All rights reserved. + * Copyright (c) 2025 SAP SE or an SAP affiliate company. All rights reserved. */ package com.sap.cloud.sdk.datamodel.openapi.sample.api; diff --git a/datamodel/openapi/openapi-api-sample/src/main/java/com/sap/cloud/sdk/datamodel/openapi/sample/model/AllOf.java b/datamodel/openapi/openapi-api-sample/src/main/java/com/sap/cloud/sdk/datamodel/openapi/sample/model/AllOf.java index 67884d8a2..c8b77ccfc 100644 --- a/datamodel/openapi/openapi-api-sample/src/main/java/com/sap/cloud/sdk/datamodel/openapi/sample/model/AllOf.java +++ b/datamodel/openapi/openapi-api-sample/src/main/java/com/sap/cloud/sdk/datamodel/openapi/sample/model/AllOf.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 SAP SE or an SAP affiliate company. All rights reserved. + * Copyright (c) 2025 SAP SE or an SAP affiliate company. All rights reserved. */ /* @@ -46,6 +46,9 @@ public class AllOf @JsonProperty( "color" ) private String color; + @JsonProperty( "flavor" ) + private FantaFlavor flavor; + @JsonAnySetter @JsonAnyGetter private final Map cloudSdkCustomFields = new LinkedHashMap<>(); @@ -165,6 +168,42 @@ public void setColor( @Nullable final String color ) this.color = color; } + /** + * Set the flavor of this {@link AllOf} instance and return the same instance. + * + * @param flavor + * The flavor of this {@link AllOf} + * @return The same instance of this {@link AllOf} class + */ + @Nonnull + public AllOf flavor( @Nullable final FantaFlavor flavor ) + { + this.flavor = flavor; + return this; + } + + /** + * Get flavor + * + * @return flavor The flavor of this {@link AllOf} instance. + */ + @Nonnull + public FantaFlavor getFlavor() + { + return flavor; + } + + /** + * Set the flavor of this {@link AllOf} instance. + * + * @param flavor + * The flavor of this {@link AllOf} + */ + public void setFlavor( @Nullable final FantaFlavor flavor ) + { + this.flavor = flavor; + } + /** * Get the names of the unrecognizable properties of the {@link AllOf}. * @@ -224,13 +263,14 @@ public boolean equals( @Nullable final java.lang.Object o ) return Objects.equals(this.cloudSdkCustomFields, allOf.cloudSdkCustomFields) && Objects.equals(this.sodaType, allOf.sodaType) && Objects.equals(this.caffeine, allOf.caffeine) - && Objects.equals(this.color, allOf.color); + && Objects.equals(this.color, allOf.color) + && Objects.equals(this.flavor, allOf.flavor); } @Override public int hashCode() { - return Objects.hash(sodaType, caffeine, color, cloudSdkCustomFields); + return Objects.hash(sodaType, caffeine, color, flavor, cloudSdkCustomFields); } @Override @@ -242,6 +282,7 @@ public String toString() sb.append(" sodaType: ").append(toIndentedString(sodaType)).append("\n"); sb.append(" caffeine: ").append(toIndentedString(caffeine)).append("\n"); sb.append(" color: ").append(toIndentedString(color)).append("\n"); + sb.append(" flavor: ").append(toIndentedString(flavor)).append("\n"); cloudSdkCustomFields .forEach(( k, v ) -> sb.append(" ").append(k).append(": ").append(toIndentedString(v)).append("\n")); sb.append("}"); diff --git a/datamodel/openapi/openapi-api-sample/src/main/java/com/sap/cloud/sdk/datamodel/openapi/sample/model/AnyOf.java b/datamodel/openapi/openapi-api-sample/src/main/java/com/sap/cloud/sdk/datamodel/openapi/sample/model/AnyOf.java index 5c40e1e68..cd8b223b3 100644 --- a/datamodel/openapi/openapi-api-sample/src/main/java/com/sap/cloud/sdk/datamodel/openapi/sample/model/AnyOf.java +++ b/datamodel/openapi/openapi-api-sample/src/main/java/com/sap/cloud/sdk/datamodel/openapi/sample/model/AnyOf.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 SAP SE or an SAP affiliate company. All rights reserved. + * Copyright (c) 2025 SAP SE or an SAP affiliate company. All rights reserved. */ /* @@ -46,6 +46,9 @@ public class AnyOf @JsonProperty( "color" ) private String color; + @JsonProperty( "flavor" ) + private FantaFlavor flavor; + @JsonAnySetter @JsonAnyGetter private final Map cloudSdkCustomFields = new LinkedHashMap<>(); @@ -165,6 +168,42 @@ public void setColor( @Nullable final String color ) this.color = color; } + /** + * Set the flavor of this {@link AnyOf} instance and return the same instance. + * + * @param flavor + * The flavor of this {@link AnyOf} + * @return The same instance of this {@link AnyOf} class + */ + @Nonnull + public AnyOf flavor( @Nullable final FantaFlavor flavor ) + { + this.flavor = flavor; + return this; + } + + /** + * Get flavor + * + * @return flavor The flavor of this {@link AnyOf} instance. + */ + @Nonnull + public FantaFlavor getFlavor() + { + return flavor; + } + + /** + * Set the flavor of this {@link AnyOf} instance. + * + * @param flavor + * The flavor of this {@link AnyOf} + */ + public void setFlavor( @Nullable final FantaFlavor flavor ) + { + this.flavor = flavor; + } + /** * Get the names of the unrecognizable properties of the {@link AnyOf}. * @@ -224,13 +263,14 @@ public boolean equals( @Nullable final java.lang.Object o ) return Objects.equals(this.cloudSdkCustomFields, anyOf.cloudSdkCustomFields) && Objects.equals(this.sodaType, anyOf.sodaType) && Objects.equals(this.caffeine, anyOf.caffeine) - && Objects.equals(this.color, anyOf.color); + && Objects.equals(this.color, anyOf.color) + && Objects.equals(this.flavor, anyOf.flavor); } @Override public int hashCode() { - return Objects.hash(sodaType, caffeine, color, cloudSdkCustomFields); + return Objects.hash(sodaType, caffeine, color, flavor, cloudSdkCustomFields); } @Override @@ -242,6 +282,7 @@ public String toString() sb.append(" sodaType: ").append(toIndentedString(sodaType)).append("\n"); sb.append(" caffeine: ").append(toIndentedString(caffeine)).append("\n"); sb.append(" color: ").append(toIndentedString(color)).append("\n"); + sb.append(" flavor: ").append(toIndentedString(flavor)).append("\n"); cloudSdkCustomFields .forEach(( k, v ) -> sb.append(" ").append(k).append(": ").append(toIndentedString(v)).append("\n")); sb.append("}"); diff --git a/datamodel/openapi/openapi-api-sample/src/main/java/com/sap/cloud/sdk/datamodel/openapi/sample/model/Cola.java b/datamodel/openapi/openapi-api-sample/src/main/java/com/sap/cloud/sdk/datamodel/openapi/sample/model/Cola.java index 80cab38dd..58bcb72a1 100644 --- a/datamodel/openapi/openapi-api-sample/src/main/java/com/sap/cloud/sdk/datamodel/openapi/sample/model/Cola.java +++ b/datamodel/openapi/openapi-api-sample/src/main/java/com/sap/cloud/sdk/datamodel/openapi/sample/model/Cola.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 SAP SE or an SAP affiliate company. All rights reserved. + * Copyright (c) 2025 SAP SE or an SAP affiliate company. All rights reserved. */ /* diff --git a/datamodel/openapi/openapi-api-sample/src/main/java/com/sap/cloud/sdk/datamodel/openapi/sample/model/Fanta.java b/datamodel/openapi/openapi-api-sample/src/main/java/com/sap/cloud/sdk/datamodel/openapi/sample/model/Fanta.java index 5a14ed75b..14ff80b06 100644 --- a/datamodel/openapi/openapi-api-sample/src/main/java/com/sap/cloud/sdk/datamodel/openapi/sample/model/Fanta.java +++ b/datamodel/openapi/openapi-api-sample/src/main/java/com/sap/cloud/sdk/datamodel/openapi/sample/model/Fanta.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 SAP SE or an SAP affiliate company. All rights reserved. + * Copyright (c) 2025 SAP SE or an SAP affiliate company. All rights reserved. */ /* @@ -43,6 +43,9 @@ public class Fanta implements OneOf, OneOfWithDiscriminator, OneOfWithDiscrimina @JsonProperty( "color" ) private String color; + @JsonProperty( "flavor" ) + private FantaFlavor flavor; + @JsonAnySetter @JsonAnyGetter private final Map cloudSdkCustomFields = new LinkedHashMap<>(); @@ -126,6 +129,42 @@ public void setColor( @Nullable final String color ) this.color = color; } + /** + * Set the flavor of this {@link Fanta} instance and return the same instance. + * + * @param flavor + * The flavor of this {@link Fanta} + * @return The same instance of this {@link Fanta} class + */ + @Nonnull + public Fanta flavor( @Nullable final FantaFlavor flavor ) + { + this.flavor = flavor; + return this; + } + + /** + * Get flavor + * + * @return flavor The flavor of this {@link Fanta} instance. + */ + @Nonnull + public FantaFlavor getFlavor() + { + return flavor; + } + + /** + * Set the flavor of this {@link Fanta} instance. + * + * @param flavor + * The flavor of this {@link Fanta} + */ + public void setFlavor( @Nullable final FantaFlavor flavor ) + { + this.flavor = flavor; + } + /** * Get the names of the unrecognizable properties of the {@link Fanta}. * @@ -184,13 +223,14 @@ public boolean equals( @Nullable final java.lang.Object o ) final Fanta fanta = (Fanta) o; return Objects.equals(this.cloudSdkCustomFields, fanta.cloudSdkCustomFields) && Objects.equals(this.sodaType, fanta.sodaType) - && Objects.equals(this.color, fanta.color); + && Objects.equals(this.color, fanta.color) + && Objects.equals(this.flavor, fanta.flavor); } @Override public int hashCode() { - return Objects.hash(sodaType, color, cloudSdkCustomFields); + return Objects.hash(sodaType, color, flavor, cloudSdkCustomFields); } @Override @@ -201,6 +241,7 @@ public String toString() sb.append("class Fanta {\n"); sb.append(" sodaType: ").append(toIndentedString(sodaType)).append("\n"); sb.append(" color: ").append(toIndentedString(color)).append("\n"); + sb.append(" flavor: ").append(toIndentedString(flavor)).append("\n"); cloudSdkCustomFields .forEach(( k, v ) -> sb.append(" ").append(k).append(": ").append(toIndentedString(v)).append("\n")); sb.append("}"); diff --git a/datamodel/openapi/openapi-api-sample/src/main/java/com/sap/cloud/sdk/datamodel/openapi/sample/model/OneOf.java b/datamodel/openapi/openapi-api-sample/src/main/java/com/sap/cloud/sdk/datamodel/openapi/sample/model/OneOf.java index 47e69617e..471876e05 100644 --- a/datamodel/openapi/openapi-api-sample/src/main/java/com/sap/cloud/sdk/datamodel/openapi/sample/model/OneOf.java +++ b/datamodel/openapi/openapi-api-sample/src/main/java/com/sap/cloud/sdk/datamodel/openapi/sample/model/OneOf.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 SAP SE or an SAP affiliate company. All rights reserved. + * Copyright (c) 2025 SAP SE or an SAP affiliate company. All rights reserved. */ /* diff --git a/datamodel/openapi/openapi-api-sample/src/main/java/com/sap/cloud/sdk/datamodel/openapi/sample/model/OneOfWithDiscriminator.java b/datamodel/openapi/openapi-api-sample/src/main/java/com/sap/cloud/sdk/datamodel/openapi/sample/model/OneOfWithDiscriminator.java index 9c31dbc7a..5647968ad 100644 --- a/datamodel/openapi/openapi-api-sample/src/main/java/com/sap/cloud/sdk/datamodel/openapi/sample/model/OneOfWithDiscriminator.java +++ b/datamodel/openapi/openapi-api-sample/src/main/java/com/sap/cloud/sdk/datamodel/openapi/sample/model/OneOfWithDiscriminator.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 SAP SE or an SAP affiliate company. All rights reserved. + * Copyright (c) 2025 SAP SE or an SAP affiliate company. All rights reserved. */ /* diff --git a/datamodel/openapi/openapi-api-sample/src/main/java/com/sap/cloud/sdk/datamodel/openapi/sample/model/OneOfWithDiscriminatorAndMapping.java b/datamodel/openapi/openapi-api-sample/src/main/java/com/sap/cloud/sdk/datamodel/openapi/sample/model/OneOfWithDiscriminatorAndMapping.java index 987be2d11..0297c166e 100644 --- a/datamodel/openapi/openapi-api-sample/src/main/java/com/sap/cloud/sdk/datamodel/openapi/sample/model/OneOfWithDiscriminatorAndMapping.java +++ b/datamodel/openapi/openapi-api-sample/src/main/java/com/sap/cloud/sdk/datamodel/openapi/sample/model/OneOfWithDiscriminatorAndMapping.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 SAP SE or an SAP affiliate company. All rights reserved. + * Copyright (c) 2025 SAP SE or an SAP affiliate company. All rights reserved. */ /* diff --git a/datamodel/openapi/openapi-api-sample/src/main/java/com/sap/cloud/sdk/datamodel/openapi/sample/model/Order.java b/datamodel/openapi/openapi-api-sample/src/main/java/com/sap/cloud/sdk/datamodel/openapi/sample/model/Order.java index 3faac6654..527eddcf6 100644 --- a/datamodel/openapi/openapi-api-sample/src/main/java/com/sap/cloud/sdk/datamodel/openapi/sample/model/Order.java +++ b/datamodel/openapi/openapi-api-sample/src/main/java/com/sap/cloud/sdk/datamodel/openapi/sample/model/Order.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 SAP SE or an SAP affiliate company. All rights reserved. + * Copyright (c) 2025 SAP SE or an SAP affiliate company. All rights reserved. */ /* diff --git a/datamodel/openapi/openapi-api-sample/src/main/java/com/sap/cloud/sdk/datamodel/openapi/sample/model/OrderWithTimestamp.java b/datamodel/openapi/openapi-api-sample/src/main/java/com/sap/cloud/sdk/datamodel/openapi/sample/model/OrderWithTimestamp.java index 7c44c844a..0ea3446b6 100644 --- a/datamodel/openapi/openapi-api-sample/src/main/java/com/sap/cloud/sdk/datamodel/openapi/sample/model/OrderWithTimestamp.java +++ b/datamodel/openapi/openapi-api-sample/src/main/java/com/sap/cloud/sdk/datamodel/openapi/sample/model/OrderWithTimestamp.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 SAP SE or an SAP affiliate company. All rights reserved. + * Copyright (c) 2025 SAP SE or an SAP affiliate company. All rights reserved. */ /* diff --git a/datamodel/openapi/openapi-api-sample/src/main/java/com/sap/cloud/sdk/datamodel/openapi/sample/model/Soda.java b/datamodel/openapi/openapi-api-sample/src/main/java/com/sap/cloud/sdk/datamodel/openapi/sample/model/Soda.java index 41b756de7..2b6a37861 100644 --- a/datamodel/openapi/openapi-api-sample/src/main/java/com/sap/cloud/sdk/datamodel/openapi/sample/model/Soda.java +++ b/datamodel/openapi/openapi-api-sample/src/main/java/com/sap/cloud/sdk/datamodel/openapi/sample/model/Soda.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 SAP SE or an SAP affiliate company. All rights reserved. + * Copyright (c) 2025 SAP SE or an SAP affiliate company. All rights reserved. */ /* diff --git a/datamodel/openapi/openapi-api-sample/src/main/java/com/sap/cloud/sdk/datamodel/openapi/sample/model/SodaWithId.java b/datamodel/openapi/openapi-api-sample/src/main/java/com/sap/cloud/sdk/datamodel/openapi/sample/model/SodaWithId.java index 2f4ef17c1..b12835904 100644 --- a/datamodel/openapi/openapi-api-sample/src/main/java/com/sap/cloud/sdk/datamodel/openapi/sample/model/SodaWithId.java +++ b/datamodel/openapi/openapi-api-sample/src/main/java/com/sap/cloud/sdk/datamodel/openapi/sample/model/SodaWithId.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 SAP SE or an SAP affiliate company. All rights reserved. + * Copyright (c) 2025 SAP SE or an SAP affiliate company. All rights reserved. */ /* diff --git a/datamodel/openapi/openapi-api-sample/src/main/resources/sodastore.yaml b/datamodel/openapi/openapi-api-sample/src/main/resources/sodastore.yaml index 286817bc2..30bc68fb2 100644 --- a/datamodel/openapi/openapi-api-sample/src/main/resources/sodastore.yaml +++ b/datamodel/openapi/openapi-api-sample/src/main/resources/sodastore.yaml @@ -133,6 +133,16 @@ components: type: string color: type: string + flavor: + oneOf: + - type: string + - type: integer + - type: object + properties: + intensity: + type: integer + nuance: + type: string paths: /sodas: get: diff --git a/datamodel/openapi/openapi-api-sample/src/test/java/com/sap/cloud/sdk/datamodel/openapi/sample/api/OneOfDeserializationTest.java b/datamodel/openapi/openapi-api-sample/src/test/java/com/sap/cloud/sdk/datamodel/openapi/sample/api/OneOfDeserializationTest.java index 011356a3b..1b521e8df 100644 --- a/datamodel/openapi/openapi-api-sample/src/test/java/com/sap/cloud/sdk/datamodel/openapi/sample/api/OneOfDeserializationTest.java +++ b/datamodel/openapi/openapi-api-sample/src/test/java/com/sap/cloud/sdk/datamodel/openapi/sample/api/OneOfDeserializationTest.java @@ -18,6 +18,8 @@ import com.sap.cloud.sdk.datamodel.openapi.sample.model.AnyOf; import com.sap.cloud.sdk.datamodel.openapi.sample.model.Cola; import com.sap.cloud.sdk.datamodel.openapi.sample.model.Fanta; +import com.sap.cloud.sdk.datamodel.openapi.sample.model.FantaFlavor; +import com.sap.cloud.sdk.datamodel.openapi.sample.model.FantaFlavorOneOf; import com.sap.cloud.sdk.datamodel.openapi.sample.model.OneOf; import com.sap.cloud.sdk.datamodel.openapi.sample.model.OneOfWithDiscriminator; import com.sap.cloud.sdk.datamodel.openapi.sample.model.OneOfWithDiscriminatorAndMapping; @@ -27,7 +29,12 @@ class OneOfDeserializationTest private static final ObjectMapper objectMapper = newDefaultObjectMapper(); private static final Cola COLA_OBJECT = Cola.create().caffeine(true).sodaType("Cola"); - private static final Fanta FANTA_OBJECT = Fanta.create().color("orange").sodaType("Fanta"); + private static final Fanta FANTA_OBJECT = + Fanta + .create() + .color("orange") + .sodaType("Fanta") + .flavor(new FantaFlavor.InnerFantaFlavorOneOf(FantaFlavorOneOf.create().intensity(3).nuance("wood"))); private static final String COLA_JSON = """ { "sodaType": "Cola", @@ -36,7 +43,8 @@ class OneOfDeserializationTest private static final String FANTA_JSON = """ { "sodaType": "Fanta", - "color": "orange" + "color": "orange", + "flavor": {"intensity":3,"nuance":"wood"} }"""; private static final String UNKNOWN_JSON = """ { From ac7a992c4f021616e3441410d0ee2095524e5627 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20D=C3=BCmont?= Date: Tue, 7 Jan 2025 10:38:49 +0100 Subject: [PATCH 04/17] Fix test assertion --- .../output/test/FantaFlavor.java | 60 +++++++++++++++++++ 1 file changed, 60 insertions(+) create mode 100644 datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/oneof-interfaces-enabled/output/test/FantaFlavor.java diff --git a/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/oneof-interfaces-enabled/output/test/FantaFlavor.java b/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/oneof-interfaces-enabled/output/test/FantaFlavor.java new file mode 100644 index 000000000..102bd3ae4 --- /dev/null +++ b/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/oneof-interfaces-enabled/output/test/FantaFlavor.java @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2025 SAP SE or an SAP affiliate company. All rights reserved. + */ + +/* + * Soda Store API + * API for managing sodas in a soda store + * + * The version of the OpenAPI document: 1.0.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +package test; + +import java.util.Objects; +import java.util.Arrays; +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.NoSuchElementException; +import java.util.Set; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.annotation.JsonValue; +import java.util.List; +import test.Cola; +import com.fasterxml.jackson.annotation.JsonAnySetter; +import com.fasterxml.jackson.annotation.JsonAnyGetter; +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + +import javax.annotation.Nonnull; +import javax.annotation.Nullable; + +/** + * FantaFlavor + */ +public interface FantaFlavor { + record InnerCola(@com.fasterxml.jackson.annotation.JsonValue Cola value) implements FantaFlavor {} + + @com.fasterxml.jackson.annotation.JsonCreator + static InnerCola create( Cola val) { return new InnerCola(val); } + + record InnerString(@com.fasterxml.jackson.annotation.JsonValue String value) implements FantaFlavor {} + + @com.fasterxml.jackson.annotation.JsonCreator + static InnerString create( String val) { return new InnerString(val); } + + record InnerStrings(@com.fasterxml.jackson.annotation.JsonValue List values) implements FantaFlavor {} + + @com.fasterxml.jackson.annotation.JsonCreator + static InnerStrings create( List val) { return new InnerStrings(val); } + +} + From 172ce3beaf82e1ac3cba929b0f00f14c218a7508 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20D=C3=BCmont?= Date: Tue, 7 Jan 2025 10:48:12 +0100 Subject: [PATCH 05/17] Improve Javadoc --- .../oneof_interface.mustache | 18 +++++++++++++ .../output/test/FantaFlavor.java | 27 +++++++++++++++++++ 2 files changed, 45 insertions(+) diff --git a/datamodel/openapi/openapi-generator/src/main/resources/openapi-generator/mustache-templates/oneof_interface.mustache b/datamodel/openapi/openapi-generator/src/main/resources/openapi-generator/mustache-templates/oneof_interface.mustache index 88faea195..87ad9fe4d 100644 --- a/datamodel/openapi/openapi-generator/src/main/resources/openapi-generator/mustache-templates/oneof_interface.mustache +++ b/datamodel/openapi/openapi-generator/src/main/resources/openapi-generator/mustache-templates/oneof_interface.mustache @@ -11,15 +11,33 @@ public interface {{classname}} {{#vendorExtensions.x-implements}}{{#-first}}exte {{propertyType}} {{propertyGetter}}(); {{/discriminator}} {{#model.vendorExtensions.x-monads.single}} + /** + * Helper class to create a {{.}} that implements {@link {{classname}}}. + */ record Inner{{.}}(@com.fasterxml.jackson.annotation.JsonValue {{.}} value) implements {{classname}} {} + /** + * Creator to enable deserialization of a {{.}}. + * + * @param val the value to use + * @return a new instance of {@link Inner{{.}}}. + */ @com.fasterxml.jackson.annotation.JsonCreator static Inner{{.}} create( {{.}} val) { return new Inner{{.}}(val); } {{/model.vendorExtensions.x-monads.single}} {{#model.vendorExtensions.x-monads.multiple}} + /** + * Helper class to create a list of {{.}} that implements {@link {{classname}}}. + */ record Inner{{.}}s(@com.fasterxml.jackson.annotation.JsonValue List<{{.}}> values) implements {{classname}} {} + /** + * Creator to enable deserialization of a list of {{.}}. + * + * @param val the value to use + * @return a new instance of {@link Inner{{.}}s}. + */ @com.fasterxml.jackson.annotation.JsonCreator static Inner{{.}}s create( List<{{.}}> val) { return new Inner{{.}}s(val); } diff --git a/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/oneof-interfaces-enabled/output/test/FantaFlavor.java b/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/oneof-interfaces-enabled/output/test/FantaFlavor.java index 102bd3ae4..24f08e3c5 100644 --- a/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/oneof-interfaces-enabled/output/test/FantaFlavor.java +++ b/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/oneof-interfaces-enabled/output/test/FantaFlavor.java @@ -41,18 +41,45 @@ * FantaFlavor */ public interface FantaFlavor { + /** + * Helper class to create a Cola that implements {@link FantaFlavor}. + */ record InnerCola(@com.fasterxml.jackson.annotation.JsonValue Cola value) implements FantaFlavor {} + /** + * Creator to enable deserialization of a Cola. + * + * @param val the value to use + * @return a new instance of {@link InnerCola}. + */ @com.fasterxml.jackson.annotation.JsonCreator static InnerCola create( Cola val) { return new InnerCola(val); } + /** + * Helper class to create a String that implements {@link FantaFlavor}. + */ record InnerString(@com.fasterxml.jackson.annotation.JsonValue String value) implements FantaFlavor {} + /** + * Creator to enable deserialization of a String. + * + * @param val the value to use + * @return a new instance of {@link InnerString}. + */ @com.fasterxml.jackson.annotation.JsonCreator static InnerString create( String val) { return new InnerString(val); } + /** + * Helper class to create a list of String that implements {@link FantaFlavor}. + */ record InnerStrings(@com.fasterxml.jackson.annotation.JsonValue List values) implements FantaFlavor {} + /** + * Creator to enable deserialization of a list of String. + * + * @param val the value to use + * @return a new instance of {@link InnerStrings}. + */ @com.fasterxml.jackson.annotation.JsonCreator static InnerStrings create( List val) { return new InnerStrings(val); } From 5055d5de9b68507983f95c40346d3e1ddc76c214 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20D=C3=BCmont?= Date: Tue, 7 Jan 2025 10:50:19 +0100 Subject: [PATCH 06/17] Update sample --- .../openapi/sample/model/FantaFlavor.java | 81 +++++++ .../sample/model/FantaFlavorOneOf.java | 229 ++++++++++++++++++ 2 files changed, 310 insertions(+) create mode 100644 datamodel/openapi/openapi-api-sample/src/main/java/com/sap/cloud/sdk/datamodel/openapi/sample/model/FantaFlavor.java create mode 100644 datamodel/openapi/openapi-api-sample/src/main/java/com/sap/cloud/sdk/datamodel/openapi/sample/model/FantaFlavorOneOf.java diff --git a/datamodel/openapi/openapi-api-sample/src/main/java/com/sap/cloud/sdk/datamodel/openapi/sample/model/FantaFlavor.java b/datamodel/openapi/openapi-api-sample/src/main/java/com/sap/cloud/sdk/datamodel/openapi/sample/model/FantaFlavor.java new file mode 100644 index 000000000..482756552 --- /dev/null +++ b/datamodel/openapi/openapi-api-sample/src/main/java/com/sap/cloud/sdk/datamodel/openapi/sample/model/FantaFlavor.java @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2025 SAP SE or an SAP affiliate company. All rights reserved. + */ + +/* + * SodaStore API + * API for managing soda products and orders in SodaStore. + * + * The version of the OpenAPI document: 1.0.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +package com.sap.cloud.sdk.datamodel.openapi.sample.model; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +/** + * FantaFlavor + */ +public interface FantaFlavor +{ + /** + * Helper class to create a Integer that implements {@link FantaFlavor}. + */ + record InnerInteger(@com.fasterxml.jackson.annotation.JsonValue Integer value) implements FantaFlavor {} + + /** + * Creator to enable deserialization of a Integer. + * + * @param val + * the value to use + * @return a new instance of {@link InnerInteger}. + */ + @com.fasterxml.jackson.annotation.JsonCreator + static InnerInteger create( Integer val ) + { + return new InnerInteger(val); + } + + /** + * Helper class to create a FantaFlavorOneOf that implements {@link FantaFlavor}. + */ + record InnerFantaFlavorOneOf(@com.fasterxml.jackson.annotation.JsonValue FantaFlavorOneOf value) implements FantaFlavor {} + + /** + * Creator to enable deserialization of a FantaFlavorOneOf. + * + * @param val + * the value to use + * @return a new instance of {@link InnerFantaFlavorOneOf}. + */ + @com.fasterxml.jackson.annotation.JsonCreator + static InnerFantaFlavorOneOf create( FantaFlavorOneOf val ) + { + return new InnerFantaFlavorOneOf(val); + } + + /** + * Helper class to create a String that implements {@link FantaFlavor}. + */ + record InnerString(@com.fasterxml.jackson.annotation.JsonValue String value) implements FantaFlavor {} + + /** + * Creator to enable deserialization of a String. + * + * @param val + * the value to use + * @return a new instance of {@link InnerString}. + */ + @com.fasterxml.jackson.annotation.JsonCreator + static InnerString create( String val ) + { + return new InnerString(val); + } + +} diff --git a/datamodel/openapi/openapi-api-sample/src/main/java/com/sap/cloud/sdk/datamodel/openapi/sample/model/FantaFlavorOneOf.java b/datamodel/openapi/openapi-api-sample/src/main/java/com/sap/cloud/sdk/datamodel/openapi/sample/model/FantaFlavorOneOf.java new file mode 100644 index 000000000..a6e59894a --- /dev/null +++ b/datamodel/openapi/openapi-api-sample/src/main/java/com/sap/cloud/sdk/datamodel/openapi/sample/model/FantaFlavorOneOf.java @@ -0,0 +1,229 @@ +/* + * Copyright (c) 2025 SAP SE or an SAP affiliate company. All rights reserved. + */ + +/* + * SodaStore API + * API for managing soda products and orders in SodaStore. + * + * The version of the OpenAPI document: 1.0.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +package com.sap.cloud.sdk.datamodel.openapi.sample.model; + +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.NoSuchElementException; +import java.util.Objects; +import java.util.Set; + +import javax.annotation.Nonnull; +import javax.annotation.Nullable; + +import com.fasterxml.jackson.annotation.JsonAnyGetter; +import com.fasterxml.jackson.annotation.JsonAnySetter; +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonProperty; + +/** + * FantaFlavorOneOf + */ +// CHECKSTYLE:OFF +public class FantaFlavorOneOf +// CHECKSTYLE:ON +{ + @JsonProperty( "intensity" ) + private Integer intensity; + + @JsonProperty( "nuance" ) + private String nuance; + + @JsonAnySetter + @JsonAnyGetter + private final Map cloudSdkCustomFields = new LinkedHashMap<>(); + + /** + * Default constructor for FantaFlavorOneOf. + */ + protected FantaFlavorOneOf() + { + } + + /** + * Set the intensity of this {@link FantaFlavorOneOf} instance and return the same instance. + * + * @param intensity + * The intensity of this {@link FantaFlavorOneOf} + * @return The same instance of this {@link FantaFlavorOneOf} class + */ + @Nonnull + public FantaFlavorOneOf intensity( @Nullable final Integer intensity ) + { + this.intensity = intensity; + return this; + } + + /** + * Get intensity + * + * @return intensity The intensity of this {@link FantaFlavorOneOf} instance. + */ + @Nonnull + public Integer getIntensity() + { + return intensity; + } + + /** + * Set the intensity of this {@link FantaFlavorOneOf} instance. + * + * @param intensity + * The intensity of this {@link FantaFlavorOneOf} + */ + public void setIntensity( @Nullable final Integer intensity ) + { + this.intensity = intensity; + } + + /** + * Set the nuance of this {@link FantaFlavorOneOf} instance and return the same instance. + * + * @param nuance + * The nuance of this {@link FantaFlavorOneOf} + * @return The same instance of this {@link FantaFlavorOneOf} class + */ + @Nonnull + public FantaFlavorOneOf nuance( @Nullable final String nuance ) + { + this.nuance = nuance; + return this; + } + + /** + * Get nuance + * + * @return nuance The nuance of this {@link FantaFlavorOneOf} instance. + */ + @Nonnull + public String getNuance() + { + return nuance; + } + + /** + * Set the nuance of this {@link FantaFlavorOneOf} instance. + * + * @param nuance + * The nuance of this {@link FantaFlavorOneOf} + */ + public void setNuance( @Nullable final String nuance ) + { + this.nuance = nuance; + } + + /** + * Get the names of the unrecognizable properties of the {@link FantaFlavorOneOf}. + * + * @return The set of properties names + */ + @JsonIgnore + @Nonnull + public Set getCustomFieldNames() + { + return cloudSdkCustomFields.keySet(); + } + + /** + * Get the value of an unrecognizable property of this {@link FantaFlavorOneOf} instance. + * + * @param name + * The name of the property + * @return The value of the property + * @throws NoSuchElementException + * If no property with the given name could be found. + */ + @Nullable + public Object getCustomField( @Nonnull final String name ) + throws NoSuchElementException + { + if( !cloudSdkCustomFields.containsKey(name) ) { + throw new NoSuchElementException("FantaFlavorOneOf has no field with name '" + name + "'."); + } + return cloudSdkCustomFields.get(name); + } + + /** + * Set an unrecognizable property of this {@link FantaFlavorOneOf} instance. If the map previously contained a + * mapping for the key, the old value is replaced by the specified value. + * + * @param customFieldName + * The name of the property + * @param customFieldValue + * The value of the property + */ + @JsonIgnore + public void setCustomField( @Nonnull String customFieldName, @Nullable Object customFieldValue ) + { + cloudSdkCustomFields.put(customFieldName, customFieldValue); + } + + @Override + public boolean equals( @Nullable final java.lang.Object o ) + { + if( this == o ) { + return true; + } + if( o == null || getClass() != o.getClass() ) { + return false; + } + final FantaFlavorOneOf fantaFlavorOneOf = (FantaFlavorOneOf) o; + return Objects.equals(this.cloudSdkCustomFields, fantaFlavorOneOf.cloudSdkCustomFields) + && Objects.equals(this.intensity, fantaFlavorOneOf.intensity) + && Objects.equals(this.nuance, fantaFlavorOneOf.nuance); + } + + @Override + public int hashCode() + { + return Objects.hash(intensity, nuance, cloudSdkCustomFields); + } + + @Override + @Nonnull + public String toString() + { + final StringBuilder sb = new StringBuilder(); + sb.append("class FantaFlavorOneOf {\n"); + sb.append(" intensity: ").append(toIndentedString(intensity)).append("\n"); + sb.append(" nuance: ").append(toIndentedString(nuance)).append("\n"); + cloudSdkCustomFields + .forEach(( k, v ) -> sb.append(" ").append(k).append(": ").append(toIndentedString(v)).append("\n")); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces (except the first line). + */ + private String toIndentedString( final java.lang.Object o ) + { + if( o == null ) { + return "null"; + } + return o.toString().replace("\n", "\n "); + } + + /** + * Create a new {@link FantaFlavorOneOf} instance. No arguments are required. + */ + public static FantaFlavorOneOf create() + { + return new FantaFlavorOneOf(); + } + +} From ef59d1b817de2026bf728bba7e6114c950b538c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20D=C3=BCmont?= Date: Tue, 7 Jan 2025 11:13:01 +0100 Subject: [PATCH 07/17] Minor code improvement; Add feature toggle "useOneOfCreators" --- .../GenerationConfigurationConverter.java | 24 ++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/datamodel/openapi/openapi-generator/src/main/java/com/sap/cloud/sdk/datamodel/openapi/generator/GenerationConfigurationConverter.java b/datamodel/openapi/openapi-generator/src/main/java/com/sap/cloud/sdk/datamodel/openapi/generator/GenerationConfigurationConverter.java index 0afe2be21..00dc3db32 100644 --- a/datamodel/openapi/openapi-generator/src/main/java/com/sap/cloud/sdk/datamodel/openapi/generator/GenerationConfigurationConverter.java +++ b/datamodel/openapi/openapi-generator/src/main/java/com/sap/cloud/sdk/datamodel/openapi/generator/GenerationConfigurationConverter.java @@ -59,7 +59,7 @@ static ClientOptInput convertGenerationConfiguration( setGlobalSettings(generationConfiguration); final var inputSpecFile = inputSpec.toString(); - final var config = createCodegenConfig(); + final var config = createCodegenConfig(generationConfiguration); config.setOutputDir(generationConfiguration.getOutputDirectory()); config.setLibrary(LIBRARY_NAME); config.setApiPackage(generationConfiguration.getApiPackage()); @@ -73,7 +73,7 @@ static ClientOptInput convertGenerationConfiguration( return clientOptInput; } - private static JavaClientCodegen createCodegenConfig() + private static JavaClientCodegen createCodegenConfig( @Nonnull final GenerationConfiguration config ) { var primitives = Set.of("String", "Integer", "Long", "Double", "Float", "Byte"); return new JavaClientCodegen() @@ -95,18 +95,28 @@ public OperationsMap postProcessOperationsWithModels( return super.postProcessOperationsWithModels(ops, allModels); } - @SuppressWarnings( { "rawtypes" } ) + @SuppressWarnings( { "rawtypes", "RedundantSuppression" } ) @Override protected void updateModelForComposedSchema( CodegenModel m, Schema schema, Map allDefinitions ) { super.updateModelForComposedSchema(m, schema, allDefinitions); + + final var checkCreators = config.getAdditionalProperties().getOrDefault("useOneOfCreators", "false"); + if( Boolean.parseBoolean(checkCreators) ) { + useCreatorsForInterfaceSubtypes(m); + } + } + + private void useCreatorsForInterfaceSubtypes( @Nonnull final CodegenModel m ) + { if( m.discriminator != null ) { return; } boolean useCreators = false; for( Set candidates : List.of(m.anyOf, m.oneOf) ) { + int nonPrimitives = 0; Set candidatesSingle = new HashSet<>(); Set candidatesMultiple = new HashSet<>(); @@ -118,9 +128,17 @@ public OperationsMap postProcessOperationsWithModels( } else { candidatesSingle.add(candidate); useCreators |= primitives.contains(candidate); + if( !primitives.contains(candidate) ) { + nonPrimitives++; + } } } if( useCreators ) { + if( nonPrimitives > 1 ) { + final var msg = + "Generating interface with mixed multiple non-primitive and primitive sub-types: {}. Deserialization may not work."; + log.warn(msg, m.name); + } candidates.clear(); var monads = Map.of("single", candidatesSingle, "multiple", candidatesMultiple); m.vendorExtensions.put("x-monads", monads); From 12d9bb4494d48724610052a6326dc140d680e6c8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20D=C3=BCmont?= Date: Tue, 7 Jan 2025 13:34:46 +0100 Subject: [PATCH 08/17] Fix test setup --- datamodel/openapi/openapi-api-sample/pom.xml | 1 + .../openapi/generator/DataModelGeneratorIntegrationTest.java | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/datamodel/openapi/openapi-api-sample/pom.xml b/datamodel/openapi/openapi-api-sample/pom.xml index 471ac956d..69af5bdd0 100644 --- a/datamodel/openapi/openapi-api-sample/pom.xml +++ b/datamodel/openapi/openapi-api-sample/pom.xml @@ -125,6 +125,7 @@ protected true + true true true diff --git a/datamodel/openapi/openapi-generator/src/test/java/com/sap/cloud/sdk/datamodel/openapi/generator/DataModelGeneratorIntegrationTest.java b/datamodel/openapi/openapi-generator/src/test/java/com/sap/cloud/sdk/datamodel/openapi/generator/DataModelGeneratorIntegrationTest.java index d2594f15e..91779e799 100644 --- a/datamodel/openapi/openapi-generator/src/test/java/com/sap/cloud/sdk/datamodel/openapi/generator/DataModelGeneratorIntegrationTest.java +++ b/datamodel/openapi/openapi-generator/src/test/java/com/sap/cloud/sdk/datamodel/openapi/generator/DataModelGeneratorIntegrationTest.java @@ -84,7 +84,7 @@ private enum TestCase true, true, 9, - Map.of("useOneOfInterfaces", "true")), + Map.of("useOneOfInterfaces", "true", "useOneOfCreators", "true")), INPUT_SPEC_WITH_BUILDER( "input-spec-with-builder", "sodastore.JSON", From 5453058adc7e001fff4c3a6257f4de228c5e2647 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20D=C3=BCmont?= Date: Thu, 9 Jan 2025 13:49:08 +0100 Subject: [PATCH 09/17] Add feature toggle for disabling additional properties --- .../GenerationConfigurationConverter.java | 64 ++++++++++++++++++- 1 file changed, 62 insertions(+), 2 deletions(-) diff --git a/datamodel/openapi/openapi-generator/src/main/java/com/sap/cloud/sdk/datamodel/openapi/generator/GenerationConfigurationConverter.java b/datamodel/openapi/openapi-generator/src/main/java/com/sap/cloud/sdk/datamodel/openapi/generator/GenerationConfigurationConverter.java index 00dc3db32..8536624a7 100644 --- a/datamodel/openapi/openapi-generator/src/main/java/com/sap/cloud/sdk/datamodel/openapi/generator/GenerationConfigurationConverter.java +++ b/datamodel/openapi/openapi-generator/src/main/java/com/sap/cloud/sdk/datamodel/openapi/generator/GenerationConfigurationConverter.java @@ -1,5 +1,8 @@ package com.sap.cloud.sdk.datamodel.openapi.generator; +import static com.sap.cloud.sdk.datamodel.openapi.generator.GenerationConfigurationConverter.CustomGeneratorProperties.STOP_ADDITIONAL_PROPERTIES; +import static com.sap.cloud.sdk.datamodel.openapi.generator.GenerationConfigurationConverter.CustomGeneratorProperties.USE_ONE_OF_CREATORS; + import java.nio.file.Path; import java.nio.file.Paths; import java.time.Year; @@ -29,6 +32,7 @@ import io.swagger.v3.oas.models.media.Schema; import io.swagger.v3.parser.core.models.AuthorizationValue; import io.swagger.v3.parser.core.models.ParseOptions; +import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; /** @@ -38,6 +42,54 @@ @Slf4j class GenerationConfigurationConverter { + /** + * Optional feature toggles, may be used internally only. + */ + @RequiredArgsConstructor + enum CustomGeneratorProperties + { + /** + * Use JsonCreator instead of sub-type deduction for oneOf and anyOf schemas. + */ + USE_ONE_OF_CREATORS("useOneOfCreators", "false"), + + /** + * Disable additional properties in generated models. They resolve to model classes extending from HashMap, + * effectively disabling serialization. Jackson by default only serializes the map entries and will ignore all + * fields from the model class. + */ + STOP_ADDITIONAL_PROPERTIES("stopAdditionalProperties", "false"); + + final String key; + final String defaultValue; + + /** + * Check if the feature is enabled. + * + * @param config + * The generation configuration. + * @return True if the feature is enabled, false otherwise. + */ + public boolean isEnabled( GenerationConfiguration config ) + { + final var value = getValue(config); + return !value.isEmpty() && !"false".equalsIgnoreCase(value.trim()); + } + + /** + * Get the value of the feature. + * + * @param config + * The generation configuration. + * @return The value of the feature. + */ + @Nonnull + public String getValue( GenerationConfiguration config ) + { + return config.getAdditionalProperties().getOrDefault(key, defaultValue); + } + } + private static final String IS_RELEASED_PROPERTY_KEY = "isReleased"; private static final String JAVA_8_PROPERTY_KEY = "java8"; private static final String DATE_LIBRARY_PROPERTY_KEY = "dateLibrary"; @@ -95,6 +147,15 @@ public OperationsMap postProcessOperationsWithModels( return super.postProcessOperationsWithModels(ops, allModels); } + @Override + protected void updateModelForObject( CodegenModel m, Schema schema ) + { + if( STOP_ADDITIONAL_PROPERTIES.isEnabled(config) ) { + schema.setAdditionalProperties(Boolean.FALSE); + } + super.updateModelForObject(m, schema); + } + @SuppressWarnings( { "rawtypes", "RedundantSuppression" } ) @Override protected @@ -103,8 +164,7 @@ public OperationsMap postProcessOperationsWithModels( { super.updateModelForComposedSchema(m, schema, allDefinitions); - final var checkCreators = config.getAdditionalProperties().getOrDefault("useOneOfCreators", "false"); - if( Boolean.parseBoolean(checkCreators) ) { + if( USE_ONE_OF_CREATORS.isEnabled(config) ) { useCreatorsForInterfaceSubtypes(m); } } From a46e81653ee981d2b61f51f9683fa26189471035 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20D=C3=BCmont?= Date: Fri, 10 Jan 2025 21:24:46 +0100 Subject: [PATCH 10/17] Add nonnull / final annotations to mustache --- .../mustache-templates/oneof_interface.mustache | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/datamodel/openapi/openapi-generator/src/main/resources/openapi-generator/mustache-templates/oneof_interface.mustache b/datamodel/openapi/openapi-generator/src/main/resources/openapi-generator/mustache-templates/oneof_interface.mustache index 87ad9fe4d..36a7ba406 100644 --- a/datamodel/openapi/openapi-generator/src/main/resources/openapi-generator/mustache-templates/oneof_interface.mustache +++ b/datamodel/openapi/openapi-generator/src/main/resources/openapi-generator/mustache-templates/oneof_interface.mustache @@ -14,7 +14,7 @@ public interface {{classname}} {{#vendorExtensions.x-implements}}{{#-first}}exte /** * Helper class to create a {{.}} that implements {@link {{classname}}}. */ - record Inner{{.}}(@com.fasterxml.jackson.annotation.JsonValue {{.}} value) implements {{classname}} {} + record Inner{{.}}(@com.fasterxml.jackson.annotation.JsonValue @Nonnull {{.}} value) implements {{classname}} {} /** * Creator to enable deserialization of a {{.}}. @@ -23,14 +23,15 @@ public interface {{classname}} {{#vendorExtensions.x-implements}}{{#-first}}exte * @return a new instance of {@link Inner{{.}}}. */ @com.fasterxml.jackson.annotation.JsonCreator - static Inner{{.}} create( {{.}} val) { return new Inner{{.}}(val); } + @Nonnull + static Inner{{.}} create( @Nonnull final {{.}} val) { return new Inner{{.}}(val); } {{/model.vendorExtensions.x-monads.single}} {{#model.vendorExtensions.x-monads.multiple}} /** * Helper class to create a list of {{.}} that implements {@link {{classname}}}. */ - record Inner{{.}}s(@com.fasterxml.jackson.annotation.JsonValue List<{{.}}> values) implements {{classname}} {} + record Inner{{.}}s(@com.fasterxml.jackson.annotation.JsonValue @Nonnull List<{{.}}> values) implements {{classname}} {} /** * Creator to enable deserialization of a list of {{.}}. @@ -39,7 +40,8 @@ public interface {{classname}} {{#vendorExtensions.x-implements}}{{#-first}}exte * @return a new instance of {@link Inner{{.}}s}. */ @com.fasterxml.jackson.annotation.JsonCreator - static Inner{{.}}s create( List<{{.}}> val) { return new Inner{{.}}s(val); } + @Nonnull + static Inner{{.}}s create( @Nonnull final List<{{.}}> val) { return new Inner{{.}}s(val); } {{/model.vendorExtensions.x-monads.multiple}} } From 75c5c270f129cecaf691747b16b5af4d13cf78a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20D=C3=BCmont?= Date: Fri, 10 Jan 2025 21:31:44 +0100 Subject: [PATCH 11/17] Update code quality --- .../GenerationConfigurationConverter.java | 74 +++---------------- .../generator/GeneratorCustomProperties.java | 48 ++++++++++++ 2 files changed, 59 insertions(+), 63 deletions(-) create mode 100644 datamodel/openapi/openapi-generator/src/main/java/com/sap/cloud/sdk/datamodel/openapi/generator/GeneratorCustomProperties.java diff --git a/datamodel/openapi/openapi-generator/src/main/java/com/sap/cloud/sdk/datamodel/openapi/generator/GenerationConfigurationConverter.java b/datamodel/openapi/openapi-generator/src/main/java/com/sap/cloud/sdk/datamodel/openapi/generator/GenerationConfigurationConverter.java index 8536624a7..101683793 100644 --- a/datamodel/openapi/openapi-generator/src/main/java/com/sap/cloud/sdk/datamodel/openapi/generator/GenerationConfigurationConverter.java +++ b/datamodel/openapi/openapi-generator/src/main/java/com/sap/cloud/sdk/datamodel/openapi/generator/GenerationConfigurationConverter.java @@ -1,7 +1,6 @@ package com.sap.cloud.sdk.datamodel.openapi.generator; -import static com.sap.cloud.sdk.datamodel.openapi.generator.GenerationConfigurationConverter.CustomGeneratorProperties.STOP_ADDITIONAL_PROPERTIES; -import static com.sap.cloud.sdk.datamodel.openapi.generator.GenerationConfigurationConverter.CustomGeneratorProperties.USE_ONE_OF_CREATORS; +import static com.sap.cloud.sdk.datamodel.openapi.generator.GeneratorCustomProperties.USE_ONE_OF_CREATORS; import java.nio.file.Path; import java.nio.file.Paths; @@ -32,7 +31,6 @@ import io.swagger.v3.oas.models.media.Schema; import io.swagger.v3.parser.core.models.AuthorizationValue; import io.swagger.v3.parser.core.models.ParseOptions; -import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; /** @@ -42,54 +40,6 @@ @Slf4j class GenerationConfigurationConverter { - /** - * Optional feature toggles, may be used internally only. - */ - @RequiredArgsConstructor - enum CustomGeneratorProperties - { - /** - * Use JsonCreator instead of sub-type deduction for oneOf and anyOf schemas. - */ - USE_ONE_OF_CREATORS("useOneOfCreators", "false"), - - /** - * Disable additional properties in generated models. They resolve to model classes extending from HashMap, - * effectively disabling serialization. Jackson by default only serializes the map entries and will ignore all - * fields from the model class. - */ - STOP_ADDITIONAL_PROPERTIES("stopAdditionalProperties", "false"); - - final String key; - final String defaultValue; - - /** - * Check if the feature is enabled. - * - * @param config - * The generation configuration. - * @return True if the feature is enabled, false otherwise. - */ - public boolean isEnabled( GenerationConfiguration config ) - { - final var value = getValue(config); - return !value.isEmpty() && !"false".equalsIgnoreCase(value.trim()); - } - - /** - * Get the value of the feature. - * - * @param config - * The generation configuration. - * @return The value of the feature. - */ - @Nonnull - public String getValue( GenerationConfiguration config ) - { - return config.getAdditionalProperties().getOrDefault(key, defaultValue); - } - } - private static final String IS_RELEASED_PROPERTY_KEY = "isReleased"; private static final String JAVA_8_PROPERTY_KEY = "java8"; private static final String DATE_LIBRARY_PROPERTY_KEY = "dateLibrary"; @@ -147,20 +97,12 @@ public OperationsMap postProcessOperationsWithModels( return super.postProcessOperationsWithModels(ops, allModels); } - @Override - protected void updateModelForObject( CodegenModel m, Schema schema ) - { - if( STOP_ADDITIONAL_PROPERTIES.isEnabled(config) ) { - schema.setAdditionalProperties(Boolean.FALSE); - } - super.updateModelForObject(m, schema); - } - @SuppressWarnings( { "rawtypes", "RedundantSuppression" } ) @Override - protected - void - updateModelForComposedSchema( CodegenModel m, Schema schema, Map allDefinitions ) + protected void updateModelForComposedSchema( + @Nonnull final CodegenModel m, + @Nonnull final Schema schema, + @Nonnull final Map allDefinitions ) { super.updateModelForComposedSchema(m, schema, allDefinitions); @@ -169,6 +111,12 @@ protected void updateModelForObject( CodegenModel m, Schema schema ) } } + /** + * Use JsonCreator for interface sub-types in case there are any primitives. + * + * @param m + * The model to update. + */ private void useCreatorsForInterfaceSubtypes( @Nonnull final CodegenModel m ) { if( m.discriminator != null ) { diff --git a/datamodel/openapi/openapi-generator/src/main/java/com/sap/cloud/sdk/datamodel/openapi/generator/GeneratorCustomProperties.java b/datamodel/openapi/openapi-generator/src/main/java/com/sap/cloud/sdk/datamodel/openapi/generator/GeneratorCustomProperties.java new file mode 100644 index 000000000..84929fb5d --- /dev/null +++ b/datamodel/openapi/openapi-generator/src/main/java/com/sap/cloud/sdk/datamodel/openapi/generator/GeneratorCustomProperties.java @@ -0,0 +1,48 @@ +package com.sap.cloud.sdk.datamodel.openapi.generator; + +import javax.annotation.Nonnull; + +import com.sap.cloud.sdk.datamodel.openapi.generator.model.GenerationConfiguration; + +import lombok.RequiredArgsConstructor; + +/** + * Optional feature toggles, may be used internally only. + */ +@RequiredArgsConstructor +enum GeneratorCustomProperties +{ + /** + * Use JsonCreator instead of sub-type deduction for oneOf and anyOf schemas. + */ + USE_ONE_OF_CREATORS("useOneOfCreators", "false"); + + private final String key; + private final String defaultValue; + + /** + * Check if the feature is enabled. + * + * @param config + * The generation configuration. + * @return True if the feature is enabled, false otherwise. + */ + public boolean isEnabled( @Nonnull final GenerationConfiguration config ) + { + final var value = getValue(config); + return !value.isEmpty() && !"false".equalsIgnoreCase(value.trim()); + } + + /** + * Get the value of the feature. + * + * @param config + * The generation configuration. + * @return The value of the feature. + */ + @Nonnull + public String getValue( @Nonnull final GenerationConfiguration config ) + { + return config.getAdditionalProperties().getOrDefault(key, defaultValue); + } +} From fe1d03c0339f522caf627bff3657e18f20bfc628 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20D=C3=BCmont?= Date: Fri, 10 Jan 2025 21:32:52 +0100 Subject: [PATCH 12/17] Update test assertions --- .../openapi/sample/model/FantaFlavor.java | 17 +++++++++++------ .../output/test/FantaFlavor.java | 15 +++++++++------ 2 files changed, 20 insertions(+), 12 deletions(-) diff --git a/datamodel/openapi/openapi-api-sample/src/main/java/com/sap/cloud/sdk/datamodel/openapi/sample/model/FantaFlavor.java b/datamodel/openapi/openapi-api-sample/src/main/java/com/sap/cloud/sdk/datamodel/openapi/sample/model/FantaFlavor.java index 482756552..0a5219022 100644 --- a/datamodel/openapi/openapi-api-sample/src/main/java/com/sap/cloud/sdk/datamodel/openapi/sample/model/FantaFlavor.java +++ b/datamodel/openapi/openapi-api-sample/src/main/java/com/sap/cloud/sdk/datamodel/openapi/sample/model/FantaFlavor.java @@ -16,6 +16,8 @@ package com.sap.cloud.sdk.datamodel.openapi.sample.model; +import javax.annotation.Nonnull; + import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonValue; @@ -27,7 +29,7 @@ public interface FantaFlavor /** * Helper class to create a Integer that implements {@link FantaFlavor}. */ - record InnerInteger(@com.fasterxml.jackson.annotation.JsonValue Integer value) implements FantaFlavor {} + record InnerInteger(@com.fasterxml.jackson.annotation.JsonValue @Nonnull Integer value) implements FantaFlavor {} /** * Creator to enable deserialization of a Integer. @@ -37,7 +39,8 @@ record InnerInteger(@com.fasterxml.jackson.annotation.JsonValue Integer value) i * @return a new instance of {@link InnerInteger}. */ @com.fasterxml.jackson.annotation.JsonCreator - static InnerInteger create( Integer val ) + @Nonnull + static InnerInteger create( @Nonnull final Integer val ) { return new InnerInteger(val); } @@ -45,7 +48,7 @@ static InnerInteger create( Integer val ) /** * Helper class to create a FantaFlavorOneOf that implements {@link FantaFlavor}. */ - record InnerFantaFlavorOneOf(@com.fasterxml.jackson.annotation.JsonValue FantaFlavorOneOf value) implements FantaFlavor {} + record InnerFantaFlavorOneOf(@com.fasterxml.jackson.annotation.JsonValue @Nonnull FantaFlavorOneOf value) implements FantaFlavor {} /** * Creator to enable deserialization of a FantaFlavorOneOf. @@ -55,7 +58,8 @@ record InnerFantaFlavorOneOf(@com.fasterxml.jackson.annotation.JsonValue FantaFl * @return a new instance of {@link InnerFantaFlavorOneOf}. */ @com.fasterxml.jackson.annotation.JsonCreator - static InnerFantaFlavorOneOf create( FantaFlavorOneOf val ) + @Nonnull + static InnerFantaFlavorOneOf create( @Nonnull final FantaFlavorOneOf val ) { return new InnerFantaFlavorOneOf(val); } @@ -63,7 +67,7 @@ static InnerFantaFlavorOneOf create( FantaFlavorOneOf val ) /** * Helper class to create a String that implements {@link FantaFlavor}. */ - record InnerString(@com.fasterxml.jackson.annotation.JsonValue String value) implements FantaFlavor {} + record InnerString(@com.fasterxml.jackson.annotation.JsonValue @Nonnull String value) implements FantaFlavor {} /** * Creator to enable deserialization of a String. @@ -73,7 +77,8 @@ record InnerString(@com.fasterxml.jackson.annotation.JsonValue String value) imp * @return a new instance of {@link InnerString}. */ @com.fasterxml.jackson.annotation.JsonCreator - static InnerString create( String val ) + @Nonnull + static InnerString create( @Nonnull final String val ) { return new InnerString(val); } diff --git a/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/oneof-interfaces-enabled/output/test/FantaFlavor.java b/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/oneof-interfaces-enabled/output/test/FantaFlavor.java index 24f08e3c5..2674f985c 100644 --- a/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/oneof-interfaces-enabled/output/test/FantaFlavor.java +++ b/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/oneof-interfaces-enabled/output/test/FantaFlavor.java @@ -44,7 +44,7 @@ public interface FantaFlavor { /** * Helper class to create a Cola that implements {@link FantaFlavor}. */ - record InnerCola(@com.fasterxml.jackson.annotation.JsonValue Cola value) implements FantaFlavor {} + record InnerCola(@com.fasterxml.jackson.annotation.JsonValue @Nonnull Cola value) implements FantaFlavor {} /** * Creator to enable deserialization of a Cola. @@ -53,12 +53,13 @@ record InnerCola(@com.fasterxml.jackson.annotation.JsonValue Cola value) impleme * @return a new instance of {@link InnerCola}. */ @com.fasterxml.jackson.annotation.JsonCreator - static InnerCola create( Cola val) { return new InnerCola(val); } + @Nonnull + static InnerCola create( @Nonnull final Cola val) { return new InnerCola(val); } /** * Helper class to create a String that implements {@link FantaFlavor}. */ - record InnerString(@com.fasterxml.jackson.annotation.JsonValue String value) implements FantaFlavor {} + record InnerString(@com.fasterxml.jackson.annotation.JsonValue @Nonnull String value) implements FantaFlavor {} /** * Creator to enable deserialization of a String. @@ -67,12 +68,13 @@ record InnerString(@com.fasterxml.jackson.annotation.JsonValue String value) imp * @return a new instance of {@link InnerString}. */ @com.fasterxml.jackson.annotation.JsonCreator - static InnerString create( String val) { return new InnerString(val); } + @Nonnull + static InnerString create( @Nonnull final String val) { return new InnerString(val); } /** * Helper class to create a list of String that implements {@link FantaFlavor}. */ - record InnerStrings(@com.fasterxml.jackson.annotation.JsonValue List values) implements FantaFlavor {} + record InnerStrings(@com.fasterxml.jackson.annotation.JsonValue @Nonnull List values) implements FantaFlavor {} /** * Creator to enable deserialization of a list of String. @@ -81,7 +83,8 @@ record InnerStrings(@com.fasterxml.jackson.annotation.JsonValue List val * @return a new instance of {@link InnerStrings}. */ @com.fasterxml.jackson.annotation.JsonCreator - static InnerStrings create( List val) { return new InnerStrings(val); } + @Nonnull + static InnerStrings create( @Nonnull final List val) { return new InnerStrings(val); } } From 6805f6cb3112bec92cfd342d511d29c151a6d073 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20D=C3=BCmont?= Date: Fri, 10 Jan 2025 21:48:56 +0100 Subject: [PATCH 13/17] Fix PMD warnings --- .../generator/GenerationConfigurationConverter.java | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/datamodel/openapi/openapi-generator/src/main/java/com/sap/cloud/sdk/datamodel/openapi/generator/GenerationConfigurationConverter.java b/datamodel/openapi/openapi-generator/src/main/java/com/sap/cloud/sdk/datamodel/openapi/generator/GenerationConfigurationConverter.java index 101683793..85ef38124 100644 --- a/datamodel/openapi/openapi-generator/src/main/java/com/sap/cloud/sdk/datamodel/openapi/generator/GenerationConfigurationConverter.java +++ b/datamodel/openapi/openapi-generator/src/main/java/com/sap/cloud/sdk/datamodel/openapi/generator/GenerationConfigurationConverter.java @@ -123,14 +123,14 @@ private void useCreatorsForInterfaceSubtypes( @Nonnull final CodegenModel m ) return; } boolean useCreators = false; - for( Set candidates : List.of(m.anyOf, m.oneOf) ) { + for( final Set candidates : List.of(m.anyOf, m.oneOf) ) { int nonPrimitives = 0; - Set candidatesSingle = new HashSet<>(); - Set candidatesMultiple = new HashSet<>(); + final var candidatesSingle = new HashSet(); + final var candidatesMultiple = new HashSet(); - for( String candidate : candidates ) { + for( final String candidate : candidates ) { if( candidate.startsWith("List<") ) { - var c1 = candidate.substring(5, candidate.length() - 1); + final var c1 = candidate.substring(5, candidate.length() - 1); candidatesMultiple.add(c1); useCreators = true; } else { @@ -148,7 +148,7 @@ private void useCreatorsForInterfaceSubtypes( @Nonnull final CodegenModel m ) log.warn(msg, m.name); } candidates.clear(); - var monads = Map.of("single", candidatesSingle, "multiple", candidatesMultiple); + final var monads = Map.of("single", candidatesSingle, "multiple", candidatesMultiple); m.vendorExtensions.put("x-monads", monads); m.vendorExtensions.put("x-is-one-of-interface", true); // enforce template usage } From d94cf19c408e9244716c3fa1e2e599a6cd601b20 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20D=C3=BCmont?= Date: Fri, 10 Jan 2025 22:14:52 +0100 Subject: [PATCH 14/17] Fix PMD warning --- .../openapi/generator/GenerationConfigurationConverter.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/datamodel/openapi/openapi-generator/src/main/java/com/sap/cloud/sdk/datamodel/openapi/generator/GenerationConfigurationConverter.java b/datamodel/openapi/openapi-generator/src/main/java/com/sap/cloud/sdk/datamodel/openapi/generator/GenerationConfigurationConverter.java index 85ef38124..adb224d86 100644 --- a/datamodel/openapi/openapi-generator/src/main/java/com/sap/cloud/sdk/datamodel/openapi/generator/GenerationConfigurationConverter.java +++ b/datamodel/openapi/openapi-generator/src/main/java/com/sap/cloud/sdk/datamodel/openapi/generator/GenerationConfigurationConverter.java @@ -77,7 +77,7 @@ static ClientOptInput convertGenerationConfiguration( private static JavaClientCodegen createCodegenConfig( @Nonnull final GenerationConfiguration config ) { - var primitives = Set.of("String", "Integer", "Long", "Double", "Float", "Byte"); + final var PRIMITIVES = Set.of("String", "Integer", "Long", "Double", "Float", "Byte"); return new JavaClientCodegen() { // Custom processor to inject "x-return-nullable" extension @@ -135,8 +135,8 @@ private void useCreatorsForInterfaceSubtypes( @Nonnull final CodegenModel m ) useCreators = true; } else { candidatesSingle.add(candidate); - useCreators |= primitives.contains(candidate); - if( !primitives.contains(candidate) ) { + useCreators |= PRIMITIVES.contains(candidate); + if( !PRIMITIVES.contains(candidate) ) { nonPrimitives++; } } From 78ccbd304840499c49b5b5d31d7e431e77889883 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20D=C3=BCmont?= Date: Fri, 10 Jan 2025 22:34:38 +0100 Subject: [PATCH 15/17] Fix PMD warning --- .../openapi/generator/GenerationConfigurationConverter.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/datamodel/openapi/openapi-generator/src/main/java/com/sap/cloud/sdk/datamodel/openapi/generator/GenerationConfigurationConverter.java b/datamodel/openapi/openapi-generator/src/main/java/com/sap/cloud/sdk/datamodel/openapi/generator/GenerationConfigurationConverter.java index adb224d86..11be5bcf7 100644 --- a/datamodel/openapi/openapi-generator/src/main/java/com/sap/cloud/sdk/datamodel/openapi/generator/GenerationConfigurationConverter.java +++ b/datamodel/openapi/openapi-generator/src/main/java/com/sap/cloud/sdk/datamodel/openapi/generator/GenerationConfigurationConverter.java @@ -77,7 +77,7 @@ static ClientOptInput convertGenerationConfiguration( private static JavaClientCodegen createCodegenConfig( @Nonnull final GenerationConfiguration config ) { - final var PRIMITIVES = Set.of("String", "Integer", "Long", "Double", "Float", "Byte"); + final var primitives = Set.of("String", "Integer", "Long", "Double", "Float", "Byte"); return new JavaClientCodegen() { // Custom processor to inject "x-return-nullable" extension @@ -135,8 +135,8 @@ private void useCreatorsForInterfaceSubtypes( @Nonnull final CodegenModel m ) useCreators = true; } else { candidatesSingle.add(candidate); - useCreators |= PRIMITIVES.contains(candidate); - if( !PRIMITIVES.contains(candidate) ) { + useCreators |= primitives.contains(candidate); + if( !primitives.contains(candidate) ) { nonPrimitives++; } } From 95d72431e61dfb6ae3530abb982279a1a87001c8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20D=C3=BCmont?= Date: Wed, 29 Jan 2025 10:27:18 +0100 Subject: [PATCH 16/17] Fix merge conflicts --- .../cloud/sdk/datamodel/openapi/sample/model/FantaFlavor.java | 1 - .../sdk/datamodel/openapi/sample/model/FantaFlavorOneOf.java | 1 - .../oneof-interfaces-enabled/output/test/FantaFlavor.java | 4 ++-- 3 files changed, 2 insertions(+), 4 deletions(-) diff --git a/datamodel/openapi/openapi-api-sample/src/main/java/com/sap/cloud/sdk/datamodel/openapi/sample/model/FantaFlavor.java b/datamodel/openapi/openapi-api-sample/src/main/java/com/sap/cloud/sdk/datamodel/openapi/sample/model/FantaFlavor.java index 0a5219022..757b26ddf 100644 --- a/datamodel/openapi/openapi-api-sample/src/main/java/com/sap/cloud/sdk/datamodel/openapi/sample/model/FantaFlavor.java +++ b/datamodel/openapi/openapi-api-sample/src/main/java/com/sap/cloud/sdk/datamodel/openapi/sample/model/FantaFlavor.java @@ -6,7 +6,6 @@ * SodaStore API * API for managing soda products and orders in SodaStore. * - * The version of the OpenAPI document: 1.0.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/datamodel/openapi/openapi-api-sample/src/main/java/com/sap/cloud/sdk/datamodel/openapi/sample/model/FantaFlavorOneOf.java b/datamodel/openapi/openapi-api-sample/src/main/java/com/sap/cloud/sdk/datamodel/openapi/sample/model/FantaFlavorOneOf.java index a6e59894a..af4b7cb22 100644 --- a/datamodel/openapi/openapi-api-sample/src/main/java/com/sap/cloud/sdk/datamodel/openapi/sample/model/FantaFlavorOneOf.java +++ b/datamodel/openapi/openapi-api-sample/src/main/java/com/sap/cloud/sdk/datamodel/openapi/sample/model/FantaFlavorOneOf.java @@ -6,7 +6,6 @@ * SodaStore API * API for managing soda products and orders in SodaStore. * - * The version of the OpenAPI document: 1.0.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/oneof-interfaces-enabled/output/test/FantaFlavor.java b/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/oneof-interfaces-enabled/output/test/FantaFlavor.java index 2674f985c..a2a8010fa 100644 --- a/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/oneof-interfaces-enabled/output/test/FantaFlavor.java +++ b/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/oneof-interfaces-enabled/output/test/FantaFlavor.java @@ -6,7 +6,6 @@ * Soda Store API * API for managing sodas in a soda store * - * The version of the OpenAPI document: 1.0.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). @@ -33,13 +32,14 @@ import com.fasterxml.jackson.annotation.JsonAnyGetter; import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonPropertyOrder; - +import com.google.common.annotations.Beta; import javax.annotation.Nonnull; import javax.annotation.Nullable; /** * FantaFlavor */ +@Beta public interface FantaFlavor { /** * Helper class to create a Cola that implements {@link FantaFlavor}. From d196f4365c3ffff9c8405e360ed2cff53e3b1682 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20D=C3=BCmont?= <22489773+newtork@users.noreply.github.com> Date: Wed, 29 Jan 2025 14:22:32 +0100 Subject: [PATCH 17/17] Update release_notes.md --- release_notes.md | 1 + 1 file changed, 1 insertion(+) diff --git a/release_notes.md b/release_notes.md index 56fe3693f..206f3727a 100644 --- a/release_notes.md +++ b/release_notes.md @@ -23,3 +23,4 @@ - Fix non-compilable code using OpenAPI generator with schema definitions having `additionalProperties: true`. Previously they would result in model classes extending `HashMap`, which disabled proper deserialization and serialization. +