diff --git a/datamodel/openapi/openapi-generator/src/main/java/com/sap/cloud/sdk/datamodel/openapi/generator/CustomJavaClientCodegen.java b/datamodel/openapi/openapi-generator/src/main/java/com/sap/cloud/sdk/datamodel/openapi/generator/CustomJavaClientCodegen.java index df7980261..720e6b47e 100644 --- a/datamodel/openapi/openapi-generator/src/main/java/com/sap/cloud/sdk/datamodel/openapi/generator/CustomJavaClientCodegen.java +++ b/datamodel/openapi/openapi-generator/src/main/java/com/sap/cloud/sdk/datamodel/openapi/generator/CustomJavaClientCodegen.java @@ -1,10 +1,16 @@ package com.sap.cloud.sdk.datamodel.openapi.generator; import static com.sap.cloud.sdk.datamodel.openapi.generator.GeneratorCustomProperties.FIX_REDUNDANT_IS_BOOLEAN_PREFIX; +import static com.sap.cloud.sdk.datamodel.openapi.generator.GeneratorCustomProperties.FIX_REMOVE_UNUSED_COMPONENTS; +import static com.sap.cloud.sdk.datamodel.openapi.generator.GeneratorCustomProperties.USE_EXCLUDE_PATHS; +import static com.sap.cloud.sdk.datamodel.openapi.generator.GeneratorCustomProperties.USE_EXCLUDE_PROPERTIES; import static com.sap.cloud.sdk.datamodel.openapi.generator.GeneratorCustomProperties.USE_FLOAT_ARRAYS; import static com.sap.cloud.sdk.datamodel.openapi.generator.GeneratorCustomProperties.USE_ONE_OF_CREATORS; +import java.util.Arrays; import java.util.HashSet; +import java.util.LinkedHashSet; +import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Set; @@ -23,9 +29,11 @@ import com.sap.cloud.sdk.datamodel.openapi.generator.model.GenerationConfiguration; +import io.swagger.v3.oas.models.OpenAPI; import io.swagger.v3.oas.models.media.Schema; import lombok.extern.slf4j.Slf4j; +@SuppressWarnings( "PMD.TooManyStaticImports" ) @Slf4j class CustomJavaClientCodegen extends JavaClientCodegen { @@ -38,6 +46,33 @@ public CustomJavaClientCodegen( @Nonnull final GenerationConfiguration config ) this.config = config; } + @Override + public void preprocessOpenAPI( @Nonnull final OpenAPI openAPI ) + { + if( USE_EXCLUDE_PROPERTIES.isEnabled(config) ) { + final String[] exclusions = USE_EXCLUDE_PROPERTIES.getValue(config).trim().split("[,\\s]+"); + for( final String exclusion : exclusions ) { + final String[] split = exclusion.split("\\.", 2); + preprocessRemoveProperty(openAPI, split[0], split[1]); + } + } + + if( USE_EXCLUDE_PATHS.isEnabled(config) ) { + final String[] exclusions = USE_EXCLUDE_PATHS.getValue(config).trim().split("[,\\s]+"); + for( final String exclusion : exclusions ) { + if( !openAPI.getPaths().keySet().remove(exclusion) ) { + log.error("Could not remove path {}", exclusion); + } + } + } + + super.preprocessOpenAPI(openAPI); + + if( FIX_REMOVE_UNUSED_COMPONENTS.isEnabled(config) ) { + preprocessRemoveRedundancies(openAPI); + } + } + @Override protected void @@ -104,6 +139,124 @@ protected void updateModelForComposedSchema( } } + /** + * Remove property from specification. + * + * @param openAPI + * The OpenAPI specification to update. + * @param schemaName + * The name of the schema to update. + * @param propertyName + * The name of the property to remove. + */ + @SuppressWarnings( { "rawtypes", "unchecked", "ReplaceInefficientStreamCount" } ) + private void preprocessRemoveProperty( + @Nonnull final OpenAPI openAPI, + @Nonnull final String schemaName, + @Nonnull final String propertyName ) + { + final var schema = openAPI.getComponents().getSchemas().get(schemaName); + if( schema == null ) { + log.error("Could not find schema {} to remove property {} from.", schemaName, propertyName); + return; + } + boolean removed = false; + + final Predicate remove = + s -> s != null && s.getProperties() != null && s.getProperties().remove(propertyName) != null; + final var schemasQueued = new LinkedList(); + final var schemasDone = new HashSet(); + schemasQueued.add(schema); + + while( !schemasQueued.isEmpty() ) { + final var s = schemasQueued.remove(); + if( s == null || !schemasDone.add(s) ) { + continue; + } + // check removal of direct schema property + removed |= remove.test(s); + + // check for allOf, anyOf, oneOf + for( final List list : Arrays.asList(s.getAllOf(), s.getAnyOf(), s.getOneOf()) ) { + if( list != null ) { + schemasQueued.addAll(list); + } + } + } + if( !removed ) { + log.error("Could not remove property {} from schema {}.", propertyName, schemaName); + } + } + + /** + * Remove unused schema components. + * + * @param openAPI + * The OpenAPI specification to update. + */ + @SuppressWarnings( { "rawtypes", "unchecked" } ) + private void preprocessRemoveRedundancies( @Nonnull final OpenAPI openAPI ) + { + final var queue = new LinkedList(); + final var done = new HashSet(); + final var refs = new LinkedHashSet(); + final var pattern = Pattern.compile("\\$ref: #/components/schemas/(\\w+)"); + + // find and queue schemas nested in paths + for( final var path : openAPI.getPaths().values() ) { + final var m = pattern.matcher(path.toString()); + while( m.find() ) { + final var name = m.group(1); + final var schema = openAPI.getComponents().getSchemas().get(name); + queue.add(schema); + refs.add(m.group(0).split(" ")[1]); + } + } + + while( !queue.isEmpty() ) { + final var s = queue.remove(); + if( s == null || !done.add(s) ) { + continue; + } + + // check for $ref attribute + final var ref = s.get$ref(); + if( ref != null ) { + refs.add(ref); + final var refName = ref.substring(ref.lastIndexOf('/') + 1); + queue.add(openAPI.getComponents().getSchemas().get(refName)); + } + + // check for direct properties + if( s.getProperties() != null ) { + for( final var s1 : s.getProperties().values() ) { + queue.add((Schema) s1); + } + } + + // check for array items + if( s.getItems() != null ) { + queue.add(s.getItems()); + } + + // check for allOf, anyOf, oneOf + for( final List list : Arrays.asList(s.getAllOf(), s.getAnyOf(), s.getOneOf()) ) { + if( list != null ) { + queue.addAll(list); + } + } + } + + // remove all schemas that have not been marked "used" + openAPI.getComponents().getSchemas().keySet().removeIf(schema -> { + if( !refs.contains("#/components/schemas/" + schema) ) { + log.info("Removing unused schema {}", schema); + return true; + } + return false; + }); + } + /** * Use JsonCreator for interface sub-types in case there are any primitives. * 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 index a3229ac6b..8c64fea0d 100644 --- 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 @@ -25,7 +25,22 @@ enum GeneratorCustomProperties /** * Use float arrays instead of big-decimal lists. */ - USE_FLOAT_ARRAYS("useFloatArrays", "false"); + USE_FLOAT_ARRAYS("useFloatArrays", "false"), + + /** + * Exclude generation of properties, e.g. `schemaName1.propertyNameA, schemaName2.propertyNameB`. + */ + USE_EXCLUDE_PROPERTIES("excludeProperties", "false"), + + /** + * Exclude generation of APIs that match a provided path, e.g. `/api/v1/health, /deployments/{id}/completions`. + */ + USE_EXCLUDE_PATHS("excludePaths", "false"), + + /** + * Remove schema components that are unused, before generating them. + */ + FIX_REMOVE_UNUSED_COMPONENTS("removeUnusedComponents", "false"); private final String key; private final String defaultValue; 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 cdba26a0a..21e3401db 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 @@ -1,5 +1,7 @@ package com.sap.cloud.sdk.datamodel.openapi.generator; +import static java.util.Map.entry; + import static org.assertj.core.api.Assertions.assertThat; import java.nio.file.Files; @@ -55,6 +57,20 @@ private enum TestCase true, 6, Map.of()), + PARTIAL_GENERATION( + "partial-generation", + "sodastore.json", + "com.sap.cloud.sdk.services.builder.api", + "com.sap.cloud.sdk.services.builder.model", + ApiMaturity.RELEASED, + true, + true, + 4, + Map + .ofEntries( + entry("excludePaths", "/sodas,/foobar/{baz}"), + entry("excludeProperties", "Foo.bar,Soda.embedding,Soda.flavor,UpdateSoda.flavor,SodaWithFoo.foo"), + entry("removeUnusedComponents", "true"))), INPUT_SPEC_WITH_UPPERCASE_FILE_EXTENSION( "input-spec-with-uppercase-file-extension", "sodastore.JSON", @@ -207,7 +223,7 @@ void generateDataModelForComparison( final TestCase testCase ) testCase.additionalProperties.forEach(generationConfiguration::additionalProperty); GenerationConfiguration build = generationConfiguration.build(); - new DataModelGenerator().generateDataModel(build); + new DataModelGenerator().generateDataModel(build).onFailure(Throwable::printStackTrace); } private static Path getInputDirectory( final TestCase testCase ) diff --git a/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/partial-generation/input/sodastore.json b/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/partial-generation/input/sodastore.json new file mode 100644 index 000000000..b629185c6 --- /dev/null +++ b/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/partial-generation/input/sodastore.json @@ -0,0 +1,261 @@ +{ + "openapi": "3.0.0", + "info": { + "title": "Soda Store API", + "version": "1.0.0", + "description": "API for managing sodas in a soda store" + }, + "paths": { + "/sodas": { + "get": { + "summary": "Get a list of all sodas", + "x-sap-cloud-sdk-api-name": "AwesomeSodas", + "operationId": "getSodas", + "responses": { + "200": { + "description": "A list of sodas", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Soda" + } + } + } + } + } + } + }, + "post": { + "summary": "Add a new soda to the store", + "x-sap-cloud-sdk-api-name": "AwesomeSoda", + "operationId": "addSoda", + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/NewSoda" + } + } + } + }, + "responses": { + "201": { + "description": "The newly added soda", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Soda" + } + } + } + } + } + } + }, + "/sodas/{sodaId}": { + "get": { + "summary": "Get details of a specific soda", + "operationId": "getSodaById", + "parameters": [ + { + "name": "sodaId", + "in": "path", + "description": "ID of the soda to retrieve", + "required": true, + "schema": { + "type": "integer", + "format": "int64" + } + } + ], + "responses": { + "200": { + "description": "The requested soda", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SodaWithFoo" + } + } + } + }, + "404": { + "description": "Soda not found" + } + } + }, + "put": { + "summary": "Update details of a specific soda", + "operationId": "updateSodaById", + "parameters": [ + { + "name": "sodaId", + "in": "path", + "description": "ID of the soda to update", + "required": true, + "schema": { + "type": "integer", + "format": "int64" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UpdateSoda" + } + } + } + }, + "responses": { + "200": { + "description": "The updated soda", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Soda" + } + } + } + }, + "404": { + "description": "Soda not found" + } + } + }, + "delete": { + "summary": "Delete a specific soda from the store", + "operationId": "deleteSodaById", + "parameters": [ + { + "name": "sodaId", + "in": "path", + "description": "ID of the soda to delete", + "required": true, + "schema": { + "type": "integer", + "format": "int64" + } + } + ], + "responses": { + "204": { + "description": "Soda successfully deleted" + }, + "404": { + "description": "Soda not found" + } + } + } + } + }, + "components": { + "schemas": { + "Soda": { + "type": "object", + "properties": { + "id": { + "type": "integer", + "format": "int64" + }, + "name": { + "type": "string" + }, + "brand": { + "type": "string" + }, + "isAvailable": { + "type": "boolean" + }, + "flavor": { + "type": "string" + }, + "price": { + "type": "number", + "format": "float" + }, + "embedding":{ + "type": "array", + "items": { + "type": "number" + } + } + }, + "required": ["name", "brand", "flavor", "price", "embedding"] + }, + "NewSoda": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "brand": { + "type": "string" + }, + "zero": { + "type": "boolean" + }, + "since": { + "type": "string", + "format": "date" + }, + "flavor": { + "type": "string" + }, + "price": { + "type": "number", + "format": "float" + } + }, + "required": ["name", "brand", "flavor", "price"] + }, + "SodaWithFoo": { + "allOf": [ + { + "$ref": "#/components/schemas/Soda" + }, + { + "type": "object", + "properties": { + "foo": { + "type": "integer", + "format": "int64", + "example": 123 + } + } + } + ] + }, + "UpdateSoda": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "zero": { + "type": "boolean" + }, + "since": { + "type": "string", + "format": "date" + }, + "brand": { + "type": "string" + }, + "flavor": { + "type": "string" + }, + "price": { + "type": "number", + "format": "float" + } + } + } + } + } +} diff --git a/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/partial-generation/output/com/sap/cloud/sdk/services/builder/api/DefaultApi.java b/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/partial-generation/output/com/sap/cloud/sdk/services/builder/api/DefaultApi.java new file mode 100644 index 000000000..79cbab1df --- /dev/null +++ b/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/partial-generation/output/com/sap/cloud/sdk/services/builder/api/DefaultApi.java @@ -0,0 +1,192 @@ +/* + * Copyright (c) 2025 SAP SE or an SAP affiliate company. All rights reserved. + */ + +package com.sap.cloud.sdk.services.builder.api; + +import com.sap.cloud.sdk.services.openapi.core.OpenApiRequestException; +import com.sap.cloud.sdk.services.openapi.core.OpenApiResponse; +import com.sap.cloud.sdk.services.openapi.core.AbstractOpenApiService; +import com.sap.cloud.sdk.services.openapi.apiclient.ApiClient; + +import com.sap.cloud.sdk.services.builder.model.Soda; +import com.sap.cloud.sdk.services.builder.model.SodaWithFoo; +import com.sap.cloud.sdk.services.builder.model.UpdateSoda; + +import java.util.HashMap; +import java.util.List; +import java.util.Locale; +import java.util.Map; + +import org.springframework.util.LinkedMultiValueMap; +import org.springframework.util.MultiValueMap; +import org.springframework.web.util.UriComponentsBuilder; +import org.springframework.core.ParameterizedTypeReference; +import org.springframework.core.io.FileSystemResource; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpMethod; +import org.springframework.http.MediaType; + +import javax.annotation.Nonnull; +import javax.annotation.Nullable; +import com.google.common.annotations.Beta; + +import com.sap.cloud.sdk.cloudplatform.connectivity.Destination; + +/** + * Soda Store API in version 1.0.0. + * + * API for managing sodas in a soda store + */ +public class DefaultApi extends AbstractOpenApiService { + /** + * Instantiates this API class to invoke operations on the Soda Store API. + * + * @param httpDestination The destination that API should be used with + */ + public DefaultApi( @Nonnull final Destination httpDestination ) + { + super(httpDestination); + } + + /** + * Instantiates this API class to invoke operations on the Soda Store API based on a given {@link ApiClient}. + * + * @param apiClient + * ApiClient to invoke the API on + */ + @Beta + public DefaultApi( @Nonnull final ApiClient apiClient ) + { + super(apiClient); + } + + /** + *

Delete a specific soda from the store

+ *

+ *

204 - Soda successfully deleted + *

404 - Soda not found + * @param sodaId + * ID of the soda to delete + * @return An OpenApiResponse containing the status code of the HttpResponse. + * @throws OpenApiRequestException if an error occurs while attempting to invoke the API + */ + @Nonnull + public OpenApiResponse deleteSodaById( @Nonnull final Long sodaId) throws OpenApiRequestException { + final Object localVarPostBody = null; + + // verify the required parameter 'sodaId' is set + if (sodaId == null) { + throw new OpenApiRequestException("Missing the required parameter 'sodaId' when calling deleteSodaById"); + } + + // create path and map variables + final Map localVarPathParams = new HashMap(); + localVarPathParams.put("sodaId", sodaId); + final String localVarPath = UriComponentsBuilder.fromPath("/sodas/{sodaId}").buildAndExpand(localVarPathParams).toUriString(); + + final MultiValueMap localVarQueryParams = new LinkedMultiValueMap(); + final HttpHeaders localVarHeaderParams = new HttpHeaders(); + final MultiValueMap localVarFormParams = new LinkedMultiValueMap(); + + final String[] localVarAccepts = { }; + final List localVarAccept = apiClient.selectHeaderAccept(localVarAccepts); + final String[] localVarContentTypes = { }; + final MediaType localVarContentType = apiClient.selectHeaderContentType(localVarContentTypes); + + final String[] localVarAuthNames = new String[] { }; + + final ParameterizedTypeReference localVarReturnType = new ParameterizedTypeReference() {}; + apiClient.invokeAPI(localVarPath, HttpMethod.DELETE, localVarQueryParams, localVarPostBody, localVarHeaderParams, localVarFormParams, localVarAccept, localVarContentType, localVarAuthNames, localVarReturnType); + return new OpenApiResponse(apiClient); + } + /** + *

Get details of a specific soda

+ *

+ *

200 - The requested soda + *

404 - Soda not found + * @param sodaId + * ID of the soda to retrieve + * @return SodaWithFoo + * @throws OpenApiRequestException if an error occurs while attempting to invoke the API + */ + @Nonnull + public SodaWithFoo getSodaById( @Nonnull final Long sodaId) throws OpenApiRequestException { + final Object localVarPostBody = null; + + // verify the required parameter 'sodaId' is set + if (sodaId == null) { + throw new OpenApiRequestException("Missing the required parameter 'sodaId' when calling getSodaById"); + } + + // create path and map variables + final Map localVarPathParams = new HashMap(); + localVarPathParams.put("sodaId", sodaId); + final String localVarPath = UriComponentsBuilder.fromPath("/sodas/{sodaId}").buildAndExpand(localVarPathParams).toUriString(); + + final MultiValueMap localVarQueryParams = new LinkedMultiValueMap(); + final HttpHeaders localVarHeaderParams = new HttpHeaders(); + final MultiValueMap localVarFormParams = new LinkedMultiValueMap(); + + final String[] localVarAccepts = { + "application/json" + }; + final List localVarAccept = apiClient.selectHeaderAccept(localVarAccepts); + final String[] localVarContentTypes = { }; + final MediaType localVarContentType = apiClient.selectHeaderContentType(localVarContentTypes); + + final String[] localVarAuthNames = new String[] { }; + + final ParameterizedTypeReference localVarReturnType = new ParameterizedTypeReference() {}; + return apiClient.invokeAPI(localVarPath, HttpMethod.GET, localVarQueryParams, localVarPostBody, localVarHeaderParams, localVarFormParams, localVarAccept, localVarContentType, localVarAuthNames, localVarReturnType); + } + /** + *

Update details of a specific soda

+ *

+ *

200 - The updated soda + *

404 - Soda not found + * @param sodaId + * ID of the soda to update + * @param updateSoda + * The value for the parameter updateSoda + * @return Soda + * @throws OpenApiRequestException if an error occurs while attempting to invoke the API + */ + @Nonnull + public Soda updateSodaById( @Nonnull final Long sodaId, @Nonnull final UpdateSoda updateSoda) throws OpenApiRequestException { + final Object localVarPostBody = updateSoda; + + // verify the required parameter 'sodaId' is set + if (sodaId == null) { + throw new OpenApiRequestException("Missing the required parameter 'sodaId' when calling updateSodaById"); + } + + // verify the required parameter 'updateSoda' is set + if (updateSoda == null) { + throw new OpenApiRequestException("Missing the required parameter 'updateSoda' when calling updateSodaById"); + } + + // create path and map variables + final Map localVarPathParams = new HashMap(); + localVarPathParams.put("sodaId", sodaId); + final String localVarPath = UriComponentsBuilder.fromPath("/sodas/{sodaId}").buildAndExpand(localVarPathParams).toUriString(); + + final MultiValueMap localVarQueryParams = new LinkedMultiValueMap(); + final HttpHeaders localVarHeaderParams = new HttpHeaders(); + final MultiValueMap localVarFormParams = new LinkedMultiValueMap(); + + final String[] localVarAccepts = { + "application/json" + }; + final List localVarAccept = apiClient.selectHeaderAccept(localVarAccepts); + final String[] localVarContentTypes = { + "application/json" + }; + final MediaType localVarContentType = apiClient.selectHeaderContentType(localVarContentTypes); + + final String[] localVarAuthNames = new String[] { }; + + final ParameterizedTypeReference localVarReturnType = new ParameterizedTypeReference() {}; + return apiClient.invokeAPI(localVarPath, HttpMethod.PUT, localVarQueryParams, localVarPostBody, localVarHeaderParams, localVarFormParams, localVarAccept, localVarContentType, localVarAuthNames, localVarReturnType); + } +} diff --git a/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/partial-generation/output/com/sap/cloud/sdk/services/builder/model/Soda.java b/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/partial-generation/output/com/sap/cloud/sdk/services/builder/model/Soda.java new file mode 100644 index 000000000..4b5d5f26b --- /dev/null +++ b/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/partial-generation/output/com/sap/cloud/sdk/services/builder/model/Soda.java @@ -0,0 +1,313 @@ +/* + * Copyright (c) 2025 SAP SE or an SAP affiliate company. All rights reserved. + */ + +/* + * Soda Store API + * API for managing sodas in a soda store + * + * + * + * 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.services.builder.model; + +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 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; + +/** + * Soda + */ +// CHECKSTYLE:OFF +public class Soda +// CHECKSTYLE:ON +{ + @JsonProperty("id") + private Long id; + + @JsonProperty("name") + private String name; + + @JsonProperty("brand") + private String brand; + + @JsonProperty("isAvailable") + private Boolean isAvailable; + + @JsonProperty("price") + private Float price; + + @JsonAnySetter + @JsonAnyGetter + private final Map cloudSdkCustomFields = new LinkedHashMap<>(); + + /** + * Set the id of this {@link Soda} instance and return the same instance. + * + * @param id The id of this {@link Soda} + * @return The same instance of this {@link Soda} class + */ + @Nonnull public Soda id( @Nullable final Long id) { + this.id = id; + return this; + } + + /** + * Get id + * @return id The id of this {@link Soda} instance. + */ + @Nonnull + public Long getId() { + return id; + } + + /** + * Set the id of this {@link Soda} instance. + * + * @param id The id of this {@link Soda} + */ + public void setId( @Nullable final Long id) { + this.id = id; + } + + /** + * Set the name of this {@link Soda} instance and return the same instance. + * + * @param name The name of this {@link Soda} + * @return The same instance of this {@link Soda} class + */ + @Nonnull public Soda name( @Nonnull final String name) { + this.name = name; + return this; + } + + /** + * Get name + * @return name The name of this {@link Soda} instance. + */ + @Nonnull + public String getName() { + return name; + } + + /** + * Set the name of this {@link Soda} instance. + * + * @param name The name of this {@link Soda} + */ + public void setName( @Nonnull final String name) { + this.name = name; + } + + /** + * Set the brand of this {@link Soda} instance and return the same instance. + * + * @param brand The brand of this {@link Soda} + * @return The same instance of this {@link Soda} class + */ + @Nonnull public Soda brand( @Nonnull final String brand) { + this.brand = brand; + return this; + } + + /** + * Get brand + * @return brand The brand of this {@link Soda} instance. + */ + @Nonnull + public String getBrand() { + return brand; + } + + /** + * Set the brand of this {@link Soda} instance. + * + * @param brand The brand of this {@link Soda} + */ + public void setBrand( @Nonnull final String brand) { + this.brand = brand; + } + + /** + * Set the isAvailable of this {@link Soda} instance and return the same instance. + * + * @param isAvailable The isAvailable of this {@link Soda} + * @return The same instance of this {@link Soda} class + */ + @Nonnull public Soda isAvailable( @Nullable final Boolean isAvailable) { + this.isAvailable = isAvailable; + return this; + } + + /** + * Get isAvailable + * @return isAvailable The isAvailable of this {@link Soda} instance. + */ + @Nonnull + public Boolean isIsAvailable() { + return isAvailable; + } + + /** + * Set the isAvailable of this {@link Soda} instance. + * + * @param isAvailable The isAvailable of this {@link Soda} + */ + public void setIsAvailable( @Nullable final Boolean isAvailable) { + this.isAvailable = isAvailable; + } + + /** + * Set the price of this {@link Soda} instance and return the same instance. + * + * @param price The price of this {@link Soda} + * @return The same instance of this {@link Soda} class + */ + @Nonnull public Soda price( @Nonnull final Float price) { + this.price = price; + return this; + } + + /** + * Get price + * @return price The price of this {@link Soda} instance. + */ + @Nonnull + public Float getPrice() { + return price; + } + + /** + * Set the price of this {@link Soda} instance. + * + * @param price The price of this {@link Soda} + */ + public void setPrice( @Nonnull final Float price) { + this.price = price; + } + + /** + * Get the names of the unrecognizable properties of the {@link Soda}. + * @return The set of properties names + */ + @JsonIgnore + @Nonnull + public Set getCustomFieldNames() { + return cloudSdkCustomFields.keySet(); + } + + /** + * Get the value of an unrecognizable property of this {@link Soda} instance. + * @deprecated Use {@link #toMap()} instead. + * @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 + @Deprecated + public Object getCustomField( @Nonnull final String name ) throws NoSuchElementException { + if( !cloudSdkCustomFields.containsKey(name) ) { + throw new NoSuchElementException("Soda has no field with name '" + name + "'."); + } + return cloudSdkCustomFields.get(name); + } + + /** + * Get the value of all properties of this {@link Soda} instance including unrecognized properties. + * + * @return The map of all properties + */ + @JsonIgnore + @Nonnull + public Map toMap() + { + final Map declaredFields = new LinkedHashMap<>(cloudSdkCustomFields); + if( id != null ) declaredFields.put("id", id); + if( name != null ) declaredFields.put("name", name); + if( brand != null ) declaredFields.put("brand", brand); + if( isAvailable != null ) declaredFields.put("isAvailable", isAvailable); + if( price != null ) declaredFields.put("price", price); + return declaredFields; + } + + /** + * Set an unrecognizable property of this {@link Soda} 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 Soda soda = (Soda) o; + return Objects.equals(this.cloudSdkCustomFields, soda.cloudSdkCustomFields) && + Objects.equals(this.id, soda.id) && + Objects.equals(this.name, soda.name) && + Objects.equals(this.brand, soda.brand) && + Objects.equals(this.isAvailable, soda.isAvailable) && + Objects.equals(this.price, soda.price); + } + + @Override + public int hashCode() { + return Objects.hash(id, name, brand, isAvailable, price, cloudSdkCustomFields); + } + + @Override + @Nonnull public String toString() { + final StringBuilder sb = new StringBuilder(); + sb.append("class Soda {\n"); + sb.append(" id: ").append(toIndentedString(id)).append("\n"); + sb.append(" name: ").append(toIndentedString(name)).append("\n"); + sb.append(" brand: ").append(toIndentedString(brand)).append("\n"); + sb.append(" isAvailable: ").append(toIndentedString(isAvailable)).append("\n"); + sb.append(" price: ").append(toIndentedString(price)).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 "); + } + +} + diff --git a/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/partial-generation/output/com/sap/cloud/sdk/services/builder/model/SodaWithFoo.java b/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/partial-generation/output/com/sap/cloud/sdk/services/builder/model/SodaWithFoo.java new file mode 100644 index 000000000..a428c2901 --- /dev/null +++ b/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/partial-generation/output/com/sap/cloud/sdk/services/builder/model/SodaWithFoo.java @@ -0,0 +1,313 @@ +/* + * Copyright (c) 2025 SAP SE or an SAP affiliate company. All rights reserved. + */ + +/* + * Soda Store API + * API for managing sodas in a soda store + * + * + * + * 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.services.builder.model; + +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 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; + +/** + * SodaWithFoo + */ +// CHECKSTYLE:OFF +public class SodaWithFoo +// CHECKSTYLE:ON +{ + @JsonProperty("id") + private Long id; + + @JsonProperty("name") + private String name; + + @JsonProperty("brand") + private String brand; + + @JsonProperty("isAvailable") + private Boolean isAvailable; + + @JsonProperty("price") + private Float price; + + @JsonAnySetter + @JsonAnyGetter + private final Map cloudSdkCustomFields = new LinkedHashMap<>(); + + /** + * Set the id of this {@link SodaWithFoo} instance and return the same instance. + * + * @param id The id of this {@link SodaWithFoo} + * @return The same instance of this {@link SodaWithFoo} class + */ + @Nonnull public SodaWithFoo id( @Nullable final Long id) { + this.id = id; + return this; + } + + /** + * Get id + * @return id The id of this {@link SodaWithFoo} instance. + */ + @Nonnull + public Long getId() { + return id; + } + + /** + * Set the id of this {@link SodaWithFoo} instance. + * + * @param id The id of this {@link SodaWithFoo} + */ + public void setId( @Nullable final Long id) { + this.id = id; + } + + /** + * Set the name of this {@link SodaWithFoo} instance and return the same instance. + * + * @param name The name of this {@link SodaWithFoo} + * @return The same instance of this {@link SodaWithFoo} class + */ + @Nonnull public SodaWithFoo name( @Nonnull final String name) { + this.name = name; + return this; + } + + /** + * Get name + * @return name The name of this {@link SodaWithFoo} instance. + */ + @Nonnull + public String getName() { + return name; + } + + /** + * Set the name of this {@link SodaWithFoo} instance. + * + * @param name The name of this {@link SodaWithFoo} + */ + public void setName( @Nonnull final String name) { + this.name = name; + } + + /** + * Set the brand of this {@link SodaWithFoo} instance and return the same instance. + * + * @param brand The brand of this {@link SodaWithFoo} + * @return The same instance of this {@link SodaWithFoo} class + */ + @Nonnull public SodaWithFoo brand( @Nonnull final String brand) { + this.brand = brand; + return this; + } + + /** + * Get brand + * @return brand The brand of this {@link SodaWithFoo} instance. + */ + @Nonnull + public String getBrand() { + return brand; + } + + /** + * Set the brand of this {@link SodaWithFoo} instance. + * + * @param brand The brand of this {@link SodaWithFoo} + */ + public void setBrand( @Nonnull final String brand) { + this.brand = brand; + } + + /** + * Set the isAvailable of this {@link SodaWithFoo} instance and return the same instance. + * + * @param isAvailable The isAvailable of this {@link SodaWithFoo} + * @return The same instance of this {@link SodaWithFoo} class + */ + @Nonnull public SodaWithFoo isAvailable( @Nullable final Boolean isAvailable) { + this.isAvailable = isAvailable; + return this; + } + + /** + * Get isAvailable + * @return isAvailable The isAvailable of this {@link SodaWithFoo} instance. + */ + @Nonnull + public Boolean isIsAvailable() { + return isAvailable; + } + + /** + * Set the isAvailable of this {@link SodaWithFoo} instance. + * + * @param isAvailable The isAvailable of this {@link SodaWithFoo} + */ + public void setIsAvailable( @Nullable final Boolean isAvailable) { + this.isAvailable = isAvailable; + } + + /** + * Set the price of this {@link SodaWithFoo} instance and return the same instance. + * + * @param price The price of this {@link SodaWithFoo} + * @return The same instance of this {@link SodaWithFoo} class + */ + @Nonnull public SodaWithFoo price( @Nonnull final Float price) { + this.price = price; + return this; + } + + /** + * Get price + * @return price The price of this {@link SodaWithFoo} instance. + */ + @Nonnull + public Float getPrice() { + return price; + } + + /** + * Set the price of this {@link SodaWithFoo} instance. + * + * @param price The price of this {@link SodaWithFoo} + */ + public void setPrice( @Nonnull final Float price) { + this.price = price; + } + + /** + * Get the names of the unrecognizable properties of the {@link SodaWithFoo}. + * @return The set of properties names + */ + @JsonIgnore + @Nonnull + public Set getCustomFieldNames() { + return cloudSdkCustomFields.keySet(); + } + + /** + * Get the value of an unrecognizable property of this {@link SodaWithFoo} instance. + * @deprecated Use {@link #toMap()} instead. + * @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 + @Deprecated + public Object getCustomField( @Nonnull final String name ) throws NoSuchElementException { + if( !cloudSdkCustomFields.containsKey(name) ) { + throw new NoSuchElementException("SodaWithFoo has no field with name '" + name + "'."); + } + return cloudSdkCustomFields.get(name); + } + + /** + * Get the value of all properties of this {@link SodaWithFoo} instance including unrecognized properties. + * + * @return The map of all properties + */ + @JsonIgnore + @Nonnull + public Map toMap() + { + final Map declaredFields = new LinkedHashMap<>(cloudSdkCustomFields); + if( id != null ) declaredFields.put("id", id); + if( name != null ) declaredFields.put("name", name); + if( brand != null ) declaredFields.put("brand", brand); + if( isAvailable != null ) declaredFields.put("isAvailable", isAvailable); + if( price != null ) declaredFields.put("price", price); + return declaredFields; + } + + /** + * Set an unrecognizable property of this {@link SodaWithFoo} 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 SodaWithFoo sodaWithFoo = (SodaWithFoo) o; + return Objects.equals(this.cloudSdkCustomFields, sodaWithFoo.cloudSdkCustomFields) && + Objects.equals(this.id, sodaWithFoo.id) && + Objects.equals(this.name, sodaWithFoo.name) && + Objects.equals(this.brand, sodaWithFoo.brand) && + Objects.equals(this.isAvailable, sodaWithFoo.isAvailable) && + Objects.equals(this.price, sodaWithFoo.price); + } + + @Override + public int hashCode() { + return Objects.hash(id, name, brand, isAvailable, price, cloudSdkCustomFields); + } + + @Override + @Nonnull public String toString() { + final StringBuilder sb = new StringBuilder(); + sb.append("class SodaWithFoo {\n"); + sb.append(" id: ").append(toIndentedString(id)).append("\n"); + sb.append(" name: ").append(toIndentedString(name)).append("\n"); + sb.append(" brand: ").append(toIndentedString(brand)).append("\n"); + sb.append(" isAvailable: ").append(toIndentedString(isAvailable)).append("\n"); + sb.append(" price: ").append(toIndentedString(price)).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 "); + } + +} + diff --git a/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/partial-generation/output/com/sap/cloud/sdk/services/builder/model/UpdateSoda.java b/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/partial-generation/output/com/sap/cloud/sdk/services/builder/model/UpdateSoda.java new file mode 100644 index 000000000..1a9904edc --- /dev/null +++ b/datamodel/openapi/openapi-generator/src/test/resources/DataModelGeneratorIntegrationTest/partial-generation/output/com/sap/cloud/sdk/services/builder/model/UpdateSoda.java @@ -0,0 +1,314 @@ +/* + * Copyright (c) 2025 SAP SE or an SAP affiliate company. All rights reserved. + */ + +/* + * Soda Store API + * API for managing sodas in a soda store + * + * + * + * 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.services.builder.model; + +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.time.LocalDate; +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; + +/** + * UpdateSoda + */ +// CHECKSTYLE:OFF +public class UpdateSoda +// CHECKSTYLE:ON +{ + @JsonProperty("name") + private String name; + + @JsonProperty("zero") + private Boolean zero; + + @JsonProperty("since") + private LocalDate since; + + @JsonProperty("brand") + private String brand; + + @JsonProperty("price") + private Float price; + + @JsonAnySetter + @JsonAnyGetter + private final Map cloudSdkCustomFields = new LinkedHashMap<>(); + + /** + * Set the name of this {@link UpdateSoda} instance and return the same instance. + * + * @param name The name of this {@link UpdateSoda} + * @return The same instance of this {@link UpdateSoda} class + */ + @Nonnull public UpdateSoda name( @Nullable final String name) { + this.name = name; + return this; + } + + /** + * Get name + * @return name The name of this {@link UpdateSoda} instance. + */ + @Nonnull + public String getName() { + return name; + } + + /** + * Set the name of this {@link UpdateSoda} instance. + * + * @param name The name of this {@link UpdateSoda} + */ + public void setName( @Nullable final String name) { + this.name = name; + } + + /** + * Set the zero of this {@link UpdateSoda} instance and return the same instance. + * + * @param zero The zero of this {@link UpdateSoda} + * @return The same instance of this {@link UpdateSoda} class + */ + @Nonnull public UpdateSoda zero( @Nullable final Boolean zero) { + this.zero = zero; + return this; + } + + /** + * Get zero + * @return zero The zero of this {@link UpdateSoda} instance. + */ + @Nonnull + public Boolean isZero() { + return zero; + } + + /** + * Set the zero of this {@link UpdateSoda} instance. + * + * @param zero The zero of this {@link UpdateSoda} + */ + public void setZero( @Nullable final Boolean zero) { + this.zero = zero; + } + + /** + * Set the since of this {@link UpdateSoda} instance and return the same instance. + * + * @param since The since of this {@link UpdateSoda} + * @return The same instance of this {@link UpdateSoda} class + */ + @Nonnull public UpdateSoda since( @Nullable final LocalDate since) { + this.since = since; + return this; + } + + /** + * Get since + * @return since The since of this {@link UpdateSoda} instance. + */ + @Nonnull + public LocalDate getSince() { + return since; + } + + /** + * Set the since of this {@link UpdateSoda} instance. + * + * @param since The since of this {@link UpdateSoda} + */ + public void setSince( @Nullable final LocalDate since) { + this.since = since; + } + + /** + * Set the brand of this {@link UpdateSoda} instance and return the same instance. + * + * @param brand The brand of this {@link UpdateSoda} + * @return The same instance of this {@link UpdateSoda} class + */ + @Nonnull public UpdateSoda brand( @Nullable final String brand) { + this.brand = brand; + return this; + } + + /** + * Get brand + * @return brand The brand of this {@link UpdateSoda} instance. + */ + @Nonnull + public String getBrand() { + return brand; + } + + /** + * Set the brand of this {@link UpdateSoda} instance. + * + * @param brand The brand of this {@link UpdateSoda} + */ + public void setBrand( @Nullable final String brand) { + this.brand = brand; + } + + /** + * Set the price of this {@link UpdateSoda} instance and return the same instance. + * + * @param price The price of this {@link UpdateSoda} + * @return The same instance of this {@link UpdateSoda} class + */ + @Nonnull public UpdateSoda price( @Nullable final Float price) { + this.price = price; + return this; + } + + /** + * Get price + * @return price The price of this {@link UpdateSoda} instance. + */ + @Nonnull + public Float getPrice() { + return price; + } + + /** + * Set the price of this {@link UpdateSoda} instance. + * + * @param price The price of this {@link UpdateSoda} + */ + public void setPrice( @Nullable final Float price) { + this.price = price; + } + + /** + * Get the names of the unrecognizable properties of the {@link UpdateSoda}. + * @return The set of properties names + */ + @JsonIgnore + @Nonnull + public Set getCustomFieldNames() { + return cloudSdkCustomFields.keySet(); + } + + /** + * Get the value of an unrecognizable property of this {@link UpdateSoda} instance. + * @deprecated Use {@link #toMap()} instead. + * @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 + @Deprecated + public Object getCustomField( @Nonnull final String name ) throws NoSuchElementException { + if( !cloudSdkCustomFields.containsKey(name) ) { + throw new NoSuchElementException("UpdateSoda has no field with name '" + name + "'."); + } + return cloudSdkCustomFields.get(name); + } + + /** + * Get the value of all properties of this {@link UpdateSoda} instance including unrecognized properties. + * + * @return The map of all properties + */ + @JsonIgnore + @Nonnull + public Map toMap() + { + final Map declaredFields = new LinkedHashMap<>(cloudSdkCustomFields); + if( name != null ) declaredFields.put("name", name); + if( zero != null ) declaredFields.put("zero", zero); + if( since != null ) declaredFields.put("since", since); + if( brand != null ) declaredFields.put("brand", brand); + if( price != null ) declaredFields.put("price", price); + return declaredFields; + } + + /** + * Set an unrecognizable property of this {@link UpdateSoda} 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 UpdateSoda updateSoda = (UpdateSoda) o; + return Objects.equals(this.cloudSdkCustomFields, updateSoda.cloudSdkCustomFields) && + Objects.equals(this.name, updateSoda.name) && + Objects.equals(this.zero, updateSoda.zero) && + Objects.equals(this.since, updateSoda.since) && + Objects.equals(this.brand, updateSoda.brand) && + Objects.equals(this.price, updateSoda.price); + } + + @Override + public int hashCode() { + return Objects.hash(name, zero, since, brand, price, cloudSdkCustomFields); + } + + @Override + @Nonnull public String toString() { + final StringBuilder sb = new StringBuilder(); + sb.append("class UpdateSoda {\n"); + sb.append(" name: ").append(toIndentedString(name)).append("\n"); + sb.append(" zero: ").append(toIndentedString(zero)).append("\n"); + sb.append(" since: ").append(toIndentedString(since)).append("\n"); + sb.append(" brand: ").append(toIndentedString(brand)).append("\n"); + sb.append(" price: ").append(toIndentedString(price)).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 "); + } + +} +