diff --git a/modules/openapi-generator/src/test/resources/3_0/java/petstore-with-fake-endpoints-models-for-testing-okhttp-gson.yaml b/modules/openapi-generator/src/test/resources/3_0/java/petstore-with-fake-endpoints-models-for-testing-okhttp-gson.yaml index f4c8dad31d2..4d44d00b329 100644 --- a/modules/openapi-generator/src/test/resources/3_0/java/petstore-with-fake-endpoints-models-for-testing-okhttp-gson.yaml +++ b/modules/openapi-generator/src/test/resources/3_0/java/petstore-with-fake-endpoints-models-for-testing-okhttp-gson.yaml @@ -2600,6 +2600,8 @@ components: Scalar: description: Values of scalar type oneOf: + - type: string + format: uuid - type: string maxLength: 1089 - type: number @@ -2607,6 +2609,8 @@ components: ScalarAnyOf: description: Values of scalar type using anyOf anyOf: + - type: string + format: uuid - type: string maxLength: 1089 - type: number diff --git a/samples/client/petstore/java/okhttp-gson/api/openapi.yaml b/samples/client/petstore/java/okhttp-gson/api/openapi.yaml index c0ff5254e61..f21b84165a8 100644 --- a/samples/client/petstore/java/okhttp-gson/api/openapi.yaml +++ b/samples/client/petstore/java/okhttp-gson/api/openapi.yaml @@ -2715,7 +2715,7 @@ components: description: Value object example: name: variable_1 - value: Scalar + value: 046b6c7f-0b8a-43b9-b35d-6489e6daee91 properties: name: example: variable_1 @@ -2732,12 +2732,16 @@ components: Scalar: description: Values of scalar type oneOf: + - format: uuid + type: string - maxLength: 1089 type: string - type: number - type: boolean ScalarAnyOf: anyOf: + - format: uuid + type: string - maxLength: 1089 type: string - type: number diff --git a/samples/client/petstore/java/okhttp-gson/src/main/java/org/openapitools/client/model/Scalar.java b/samples/client/petstore/java/okhttp-gson/src/main/java/org/openapitools/client/model/Scalar.java index 2a36043d6c4..c1d9002d5c3 100644 --- a/samples/client/petstore/java/okhttp-gson/src/main/java/org/openapitools/client/model/Scalar.java +++ b/samples/client/petstore/java/okhttp-gson/src/main/java/org/openapitools/client/model/Scalar.java @@ -15,6 +15,7 @@ package org.openapitools.client.model; import java.util.Objects; import java.math.BigDecimal; +import java.util.UUID; @@ -63,6 +64,7 @@ public class Scalar extends AbstractOpenApiSchema { return null; // this class only serializes 'Scalar' and its subtypes } final TypeAdapter elementAdapter = gson.getAdapter(JsonElement.class); + final TypeAdapter adapterUUID = gson.getDelegateAdapter(this, TypeToken.get(UUID.class)); final TypeAdapter adapterString = gson.getDelegateAdapter(this, TypeToken.get(String.class)); final TypeAdapter adapterBigDecimal = gson.getDelegateAdapter(this, TypeToken.get(BigDecimal.class)); final TypeAdapter adapterBoolean = gson.getDelegateAdapter(this, TypeToken.get(Boolean.class)); @@ -75,6 +77,12 @@ public class Scalar extends AbstractOpenApiSchema { return; } + // check if the actual instance is of the type `UUID` + if (value.getActualInstance() instanceof UUID) { + JsonElement element = adapterUUID.toJsonTree((UUID)value.getActualInstance()); + elementAdapter.write(out, element); + return; + } // check if the actual instance is of the type `String` if (value.getActualInstance() instanceof String) { JsonPrimitive primitive = adapterString.toJsonTree((String)value.getActualInstance()).getAsJsonPrimitive(); @@ -93,7 +101,7 @@ public class Scalar extends AbstractOpenApiSchema { elementAdapter.write(out, primitive); return; } - throw new IOException("Failed to serialize as the type doesn't match oneOf schemas: BigDecimal, Boolean, String"); + throw new IOException("Failed to serialize as the type doesn't match oneOf schemas: BigDecimal, Boolean, String, UUID"); } @Override @@ -105,6 +113,18 @@ public class Scalar extends AbstractOpenApiSchema { ArrayList errorMessages = new ArrayList<>(); TypeAdapter actualAdapter = elementAdapter; + // deserialize UUID + try { + // validate the JSON object to see if any exception is thrown + UUID.fromString(jsonElement.getAsString()); + actualAdapter = adapterUUID; + match++; + log.log(Level.FINER, "Input data matches schema 'UUID'"); + } catch (Exception e) { + // deserialization failed, continue + errorMessages.add(String.format("Deserialization for UUID failed with `%s`.", e.getMessage())); + log.log(Level.FINER, "Input data does not match schema 'UUID'", e); + } // deserialize String try { // validate the JSON object to see if any exception is thrown @@ -173,6 +193,7 @@ public class Scalar extends AbstractOpenApiSchema { } static { + schemas.put("UUID", UUID.class); schemas.put("String", String.class); schemas.put("BigDecimal", BigDecimal.class); schemas.put("Boolean", Boolean.class); @@ -186,12 +207,17 @@ public class Scalar extends AbstractOpenApiSchema { /** * Set the instance that matches the oneOf child schema, check * the instance parameter is valid against the oneOf child schemas: - * BigDecimal, Boolean, String + * BigDecimal, Boolean, String, UUID * * It could be an instance of the 'oneOf' schemas. */ @Override public void setActualInstance(Object instance) { + if (instance instanceof UUID) { + super.setActualInstance(instance); + return; + } + if (instance instanceof String) { super.setActualInstance(instance); return; @@ -207,14 +233,14 @@ public class Scalar extends AbstractOpenApiSchema { return; } - throw new RuntimeException("Invalid instance type. Must be BigDecimal, Boolean, String"); + throw new RuntimeException("Invalid instance type. Must be BigDecimal, Boolean, String, UUID"); } /** * Get the actual instance, which can be the following: - * BigDecimal, Boolean, String + * BigDecimal, Boolean, String, UUID * - * @return The actual instance (BigDecimal, Boolean, String) + * @return The actual instance (BigDecimal, Boolean, String, UUID) */ @SuppressWarnings("unchecked") @Override @@ -222,6 +248,17 @@ public class Scalar extends AbstractOpenApiSchema { return super.getActualInstance(); } + /** + * Get the actual instance of `UUID`. If the actual instance is not `UUID`, + * the ClassCastException will be thrown. + * + * @return The actual instance of `UUID` + * @throws ClassCastException if the instance is not `UUID` + */ + public UUID getUUID() throws ClassCastException { + return (UUID)super.getActualInstance(); + } + /** * Get the actual instance of `String`. If the actual instance is not `String`, * the ClassCastException will be thrown. @@ -265,6 +302,14 @@ public class Scalar extends AbstractOpenApiSchema { // validate oneOf schemas one by one int validCount = 0; ArrayList errorMessages = new ArrayList<>(); + // validate the json string with UUID + try { + UUID.fromString(jsonElement.getAsString()); + validCount++; + } catch (Exception e) { + errorMessages.add(String.format("Deserialization for UUID failed with `%s`.", e.getMessage())); + // continue to the next one + } // validate the json string with String try { if (!jsonElement.getAsJsonPrimitive().isString()) { @@ -296,7 +341,7 @@ public class Scalar extends AbstractOpenApiSchema { // continue to the next one } if (validCount != 1) { - throw new IOException(String.format("The JSON string is invalid for Scalar with oneOf schemas: BigDecimal, Boolean, String. %d class(es) match the result, expected 1. Detailed failure message for oneOf schemas: %s. JSON: %s", validCount, errorMessages, jsonElement.toString())); + throw new IOException(String.format("The JSON string is invalid for Scalar with oneOf schemas: BigDecimal, Boolean, String, UUID. %d class(es) match the result, expected 1. Detailed failure message for oneOf schemas: %s. JSON: %s", validCount, errorMessages, jsonElement.toString())); } } diff --git a/samples/client/petstore/java/okhttp-gson/src/main/java/org/openapitools/client/model/ScalarAnyOf.java b/samples/client/petstore/java/okhttp-gson/src/main/java/org/openapitools/client/model/ScalarAnyOf.java index a79de259e94..92d13892493 100644 --- a/samples/client/petstore/java/okhttp-gson/src/main/java/org/openapitools/client/model/ScalarAnyOf.java +++ b/samples/client/petstore/java/okhttp-gson/src/main/java/org/openapitools/client/model/ScalarAnyOf.java @@ -15,6 +15,7 @@ package org.openapitools.client.model; import java.util.Objects; import java.math.BigDecimal; +import java.util.UUID; @@ -63,6 +64,7 @@ public class ScalarAnyOf extends AbstractOpenApiSchema { return null; // this class only serializes 'ScalarAnyOf' and its subtypes } final TypeAdapter elementAdapter = gson.getAdapter(JsonElement.class); + final TypeAdapter adapterUUID = gson.getDelegateAdapter(this, TypeToken.get(UUID.class)); final TypeAdapter adapterString = gson.getDelegateAdapter(this, TypeToken.get(String.class)); final TypeAdapter adapterBigDecimal = gson.getDelegateAdapter(this, TypeToken.get(BigDecimal.class)); final TypeAdapter adapterBoolean = gson.getDelegateAdapter(this, TypeToken.get(Boolean.class)); @@ -75,6 +77,12 @@ public class ScalarAnyOf extends AbstractOpenApiSchema { return; } + // check if the actual instance is of the type `UUID` + if (value.getActualInstance() instanceof UUID) { + JsonElement element = adapterUUID.toJsonTree((UUID)value.getActualInstance()); + elementAdapter.write(out, element); + return; + } // check if the actual instance is of the type `String` if (value.getActualInstance() instanceof String) { JsonPrimitive primitive = adapterString.toJsonTree((String)value.getActualInstance()).getAsJsonPrimitive(); @@ -93,7 +101,7 @@ public class ScalarAnyOf extends AbstractOpenApiSchema { elementAdapter.write(out, primitive); return; } - throw new IOException("Failed to serialize as the type doesn't match anyOf schemas: BigDecimal, Boolean, String"); + throw new IOException("Failed to serialize as the type doesn't match anyOf schemas: BigDecimal, Boolean, String, UUID"); } @Override @@ -104,6 +112,19 @@ public class ScalarAnyOf extends AbstractOpenApiSchema { ArrayList errorMessages = new ArrayList<>(); TypeAdapter actualAdapter = elementAdapter; + // deserialize UUID + try { + // validate the JSON object to see if any exception is thrown + UUID.fromString(jsonElement.getAsString()); + actualAdapter = adapterUUID; + ScalarAnyOf ret = new ScalarAnyOf(); + ret.setActualInstance(actualAdapter.fromJsonTree(jsonElement)); + return ret; + } catch (Exception e) { + // deserialization failed, continue + errorMessages.add(String.format("Deserialization for UUID failed with `%s`.", e.getMessage())); + log.log(Level.FINER, "Input data does not match schema 'UUID'", e); + } // deserialize String try { // validate the JSON object to see if any exception is thrown @@ -169,6 +190,7 @@ public class ScalarAnyOf extends AbstractOpenApiSchema { } static { + schemas.put("UUID", UUID.class); schemas.put("String", String.class); schemas.put("BigDecimal", BigDecimal.class); schemas.put("Boolean", Boolean.class); @@ -182,12 +204,17 @@ public class ScalarAnyOf extends AbstractOpenApiSchema { /** * Set the instance that matches the anyOf child schema, check * the instance parameter is valid against the anyOf child schemas: - * BigDecimal, Boolean, String + * BigDecimal, Boolean, String, UUID * * It could be an instance of the 'anyOf' schemas. */ @Override public void setActualInstance(Object instance) { + if (instance instanceof UUID) { + super.setActualInstance(instance); + return; + } + if (instance instanceof String) { super.setActualInstance(instance); return; @@ -203,14 +230,14 @@ public class ScalarAnyOf extends AbstractOpenApiSchema { return; } - throw new RuntimeException("Invalid instance type. Must be BigDecimal, Boolean, String"); + throw new RuntimeException("Invalid instance type. Must be BigDecimal, Boolean, String, UUID"); } /** * Get the actual instance, which can be the following: - * BigDecimal, Boolean, String + * BigDecimal, Boolean, String, UUID * - * @return The actual instance (BigDecimal, Boolean, String) + * @return The actual instance (BigDecimal, Boolean, String, UUID) */ @SuppressWarnings("unchecked") @Override @@ -218,6 +245,17 @@ public class ScalarAnyOf extends AbstractOpenApiSchema { return super.getActualInstance(); } + /** + * Get the actual instance of `UUID`. If the actual instance is not `UUID`, + * the ClassCastException will be thrown. + * + * @return The actual instance of `UUID` + * @throws ClassCastException if the instance is not `UUID` + */ + public UUID getUUID() throws ClassCastException { + return (UUID)super.getActualInstance(); + } + /** * Get the actual instance of `String`. If the actual instance is not `String`, * the ClassCastException will be thrown. @@ -260,6 +298,14 @@ public class ScalarAnyOf extends AbstractOpenApiSchema { public static void validateJsonElement(JsonElement jsonElement) throws IOException { // validate anyOf schemas one by one ArrayList errorMessages = new ArrayList<>(); + // validate the json string with UUID + try { + UUID.fromString(jsonElement.getAsString()); + return; + } catch (Exception e) { + errorMessages.add(String.format("Deserialization for UUID failed with `%s`.", e.getMessage())); + // continue to the next one + } // validate the json string with String try { if (!jsonElement.getAsJsonPrimitive().isString()) { @@ -290,7 +336,7 @@ public class ScalarAnyOf extends AbstractOpenApiSchema { errorMessages.add(String.format("Deserialization for Boolean failed with `%s`.", e.getMessage())); // continue to the next one } - throw new IOException(String.format("The JSON string is invalid for ScalarAnyOf with anyOf schemas: BigDecimal, Boolean, String. no class match the result, expected at least 1. Detailed failure message for anyOf schemas: %s. JSON: %s", errorMessages, jsonElement.toString())); + throw new IOException(String.format("The JSON string is invalid for ScalarAnyOf with anyOf schemas: BigDecimal, Boolean, String, UUID. no class match the result, expected at least 1. Detailed failure message for anyOf schemas: %s. JSON: %s", errorMessages, jsonElement.toString())); } /**