[BUG][KOTLIN] Sanitize names of the adapter variables in anyOf and oneOf model template to avoid compilation errors (#19981)

* [kotlin] Sanitize one_of and any_of model variable names to avoid compilation errors (#19942)

* [kotlin] add missing validateJsonElement method to oneOf and anyOf model templates (#19942)
This commit is contained in:
Tomasz Letachowicz 2024-10-29 12:38:11 +01:00 committed by GitHub
parent 48e8375166
commit 32bf99a39f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
10 changed files with 551 additions and 33 deletions

View File

@ -83,7 +83,7 @@ import java.io.IOException
{{#anyOf}} {{#anyOf}}
{{^isArray}} {{^isArray}}
{{^vendorExtensions.x-duplicated-data-type}} {{^vendorExtensions.x-duplicated-data-type}}
val adapter{{{dataType}}} = gson.getDelegateAdapter(this, TypeToken.get({{{dataType}}}::class.java)) val adapter{{#sanitizeGeneric}}{{{dataType}}}{{/sanitizeGeneric}} = gson.getDelegateAdapter(this, TypeToken.get({{{dataType}}}::class.java))
{{/vendorExtensions.x-duplicated-data-type}} {{/vendorExtensions.x-duplicated-data-type}}
{{/isArray}} {{/isArray}}
{{#isArray}} {{#isArray}}
@ -122,7 +122,7 @@ import java.io.IOException
return return
{{/isPrimitiveType}} {{/isPrimitiveType}}
{{^isPrimitiveType}} {{^isPrimitiveType}}
val element = adapter{{{dataType}}}.toJsonTree(value.actualInstance as {{{dataType}}}?) val element = adapter{{#sanitizeGeneric}}{{{dataType}}}{{/sanitizeGeneric}}.toJsonTree(value.actualInstance as {{{dataType}}}?)
elementAdapter.write(out, element) elementAdapter.write(out, element)
return return
{{/isPrimitiveType}} {{/isPrimitiveType}}
@ -185,7 +185,7 @@ import java.io.IOException
for(element in jsonElement.getAsJsonArray()) { for(element in jsonElement.getAsJsonArray()) {
{{#items}} {{#items}}
{{#isNumber}} {{#isNumber}}
require(jsonElement.getAsJsonPrimitive().isNumber) { require(element.getAsJsonPrimitive().isNumber) {
String.format("Expected json element to be of type Number in the JSON string but got `%s`", jsonElement.toString()) String.format("Expected json element to be of type Number in the JSON string but got `%s`", jsonElement.toString())
} }
{{/isNumber}} {{/isNumber}}
@ -238,4 +238,99 @@ import java.io.IOException
}.nullSafe() as TypeAdapter<T> }.nullSafe() as TypeAdapter<T>
} }
} }
companion object {
/**
* Validates the JSON Element and throws an exception if issues found
*
* @param jsonElement JSON Element
* @throws IOException if the JSON Element is invalid with respect to {{classname}}
*/
@Throws(IOException::class)
fun validateJsonElement(jsonElement: JsonElement?) {
requireNotNull(jsonElement) {
"Provided json element must not be null"
}
var match = 0
val errorMessages = ArrayList<String>()
{{#composedSchemas}}
{{#anyOf}}
{{^vendorExtensions.x-duplicated-data-type}}
{{^hasVars}}
// validate the json string with {{{dataType}}}
try {
// validate the JSON object to see if any exception is thrown
{{^isArray}}
{{#isNumber}}
require(jsonElement.getAsJsonPrimitive().isNumber()) {
String.format("Expected json element to be of type Number in the JSON string but got `%s`", jsonElement.toString())
}
{{/isNumber}}
{{^isNumber}}
{{#isPrimitiveType}}
require(jsonElement.getAsJsonPrimitive().is{{#isBoolean}}Boolean{{/isBoolean}}{{#isString}}String{{/isString}}{{^isString}}{{^isBoolean}}Number{{/isBoolean}}{{/isString}}()) {
String.format("Expected json element to be of type {{#isBoolean}}Boolean{{/isBoolean}}{{#isString}}String{{/isString}}{{^isString}}{{^isBoolean}}Number{{/isBoolean}}{{/isString}} in the JSON string but got `%s`", jsonElement.toString())
}
{{/isPrimitiveType}}
{{/isNumber}}
{{^isNumber}}
{{^isPrimitiveType}}
{{{dataType}}}.validateJsonElement(jsonElement)
{{/isPrimitiveType}}
{{/isNumber}}
{{/isArray}}
{{#isArray}}
require(jsonElement.isJsonArray) {
String.format("Expected json element to be a array type in the JSON string but got `%s`", jsonElement.toString())
}
// validate array items
for(element in jsonElement.getAsJsonArray()) {
{{#items}}
{{#isNumber}}
require(element.getAsJsonPrimitive().isNumber) {
String.format("Expected json element to be of type Number in the JSON string but got `%s`", jsonElement.toString())
}
{{/isNumber}}
{{^isNumber}}
{{#isPrimitiveType}}
require(element.getAsJsonPrimitive().is{{#isBoolean}}Boolean{{/isBoolean}}{{#isString}}String{{/isString}}{{^isString}}{{^isBoolean}}Number{{/isBoolean}}{{/isString}}) {
String.format("Expected array items to be of type {{#isBoolean}}Boolean{{/isBoolean}}{{#isString}}String{{/isString}}{{^isString}}{{^isBoolean}}Number{{/isBoolean}}{{/isString}} in the JSON string but got `%s`", jsonElement.toString())
}
{{/isPrimitiveType}}
{{/isNumber}}
{{^isNumber}}
{{^isPrimitiveType}}
{{{dataType}}}.validateJsonElement(element)
{{/isPrimitiveType}}
{{/isNumber}}
{{/items}}
}
{{/isArray}}
match++
} catch (e: Exception) {
// Validation failed, continue
errorMessages.add(String.format("Validation for {{{dataType}}} failed with `%s`.", e.message))
}
{{/hasVars}}
{{#hasVars}}
// validate json string for {{{.}}}
try {
// validate the JSON object to see if any exception is thrown
{{.}}.validateJsonElement(jsonElement)
match++
} catch (e: Exception) {
// validation failed, continue
errorMessages.add(String.format("Validation for {{{.}}} failed with `%s`.", e.message))
}
{{/hasVars}}
{{/vendorExtensions.x-duplicated-data-type}}
{{/anyOf}}
{{/composedSchemas}}
if (match != 1) {
throw IOException(String.format("Failed validation for {{classname}}: %d classes match result, expected 1. Detailed failure message for oneOf schemas: %s. JSON: %s", match, errorMessages, jsonElement.toString()))
}
}
}
} }

View File

@ -83,7 +83,7 @@ import java.io.IOException
{{#oneOf}} {{#oneOf}}
{{^isArray}} {{^isArray}}
{{^vendorExtensions.x-duplicated-data-type}} {{^vendorExtensions.x-duplicated-data-type}}
val adapter{{{dataType}}} = gson.getDelegateAdapter(this, TypeToken.get({{{dataType}}}::class.java)) val adapter{{#sanitizeGeneric}}{{{dataType}}}{{/sanitizeGeneric}} = gson.getDelegateAdapter(this, TypeToken.get({{{dataType}}}::class.java))
{{/vendorExtensions.x-duplicated-data-type}} {{/vendorExtensions.x-duplicated-data-type}}
{{/isArray}} {{/isArray}}
{{#isArray}} {{#isArray}}
@ -122,7 +122,7 @@ import java.io.IOException
return return
{{/isPrimitiveType}} {{/isPrimitiveType}}
{{^isPrimitiveType}} {{^isPrimitiveType}}
val element = adapter{{{dataType}}}.toJsonTree(value.actualInstance as {{{dataType}}}?) val element = adapter{{#sanitizeGeneric}}{{{dataType}}}{{/sanitizeGeneric}}.toJsonTree(value.actualInstance as {{{dataType}}}?)
elementAdapter.write(out, element) elementAdapter.write(out, element)
return return
{{/isPrimitiveType}} {{/isPrimitiveType}}
@ -179,7 +179,7 @@ import java.io.IOException
for(element in jsonElement.getAsJsonArray()) { for(element in jsonElement.getAsJsonArray()) {
{{#items}} {{#items}}
{{#isNumber}} {{#isNumber}}
require(jsonElement.getAsJsonPrimitive().isNumber) { require(element.getAsJsonPrimitive().isNumber) {
String.format("Expected json element to be of type Number in the JSON string but got `%s`", jsonElement.toString()) String.format("Expected json element to be of type Number in the JSON string but got `%s`", jsonElement.toString())
} }
{{/isNumber}} {{/isNumber}}
@ -236,4 +236,99 @@ import java.io.IOException
}.nullSafe() as TypeAdapter<T> }.nullSafe() as TypeAdapter<T>
} }
} }
companion object {
/**
* Validates the JSON Element and throws an exception if issues found
*
* @param jsonElement JSON Element
* @throws IOException if the JSON Element is invalid with respect to {{classname}}
*/
@Throws(IOException::class)
fun validateJsonElement(jsonElement: JsonElement?) {
requireNotNull(jsonElement) {
"Provided json element must not be null"
}
var match = 0
val errorMessages = ArrayList<String>()
{{#composedSchemas}}
{{#oneOf}}
{{^vendorExtensions.x-duplicated-data-type}}
{{^hasVars}}
// validate the json string with {{{dataType}}}
try {
// validate the JSON object to see if any exception is thrown
{{^isArray}}
{{#isNumber}}
require(jsonElement.getAsJsonPrimitive().isNumber()) {
String.format("Expected json element to be of type Number in the JSON string but got `%s`", jsonElement.toString())
}
{{/isNumber}}
{{^isNumber}}
{{#isPrimitiveType}}
require(jsonElement.getAsJsonPrimitive().is{{#isBoolean}}Boolean{{/isBoolean}}{{#isString}}String{{/isString}}{{^isString}}{{^isBoolean}}Number{{/isBoolean}}{{/isString}}()) {
String.format("Expected json element to be of type {{#isBoolean}}Boolean{{/isBoolean}}{{#isString}}String{{/isString}}{{^isString}}{{^isBoolean}}Number{{/isBoolean}}{{/isString}} in the JSON string but got `%s`", jsonElement.toString())
}
{{/isPrimitiveType}}
{{/isNumber}}
{{^isNumber}}
{{^isPrimitiveType}}
{{{dataType}}}.validateJsonElement(jsonElement)
{{/isPrimitiveType}}
{{/isNumber}}
{{/isArray}}
{{#isArray}}
require(jsonElement.isJsonArray) {
String.format("Expected json element to be a array type in the JSON string but got `%s`", jsonElement.toString())
}
// validate array items
for(element in jsonElement.getAsJsonArray()) {
{{#items}}
{{#isNumber}}
require(jsonElement.getAsJsonPrimitive().isNumber) {
String.format("Expected json element to be of type Number in the JSON string but got `%s`", jsonElement.toString())
}
{{/isNumber}}
{{^isNumber}}
{{#isPrimitiveType}}
require(element.getAsJsonPrimitive().is{{#isBoolean}}Boolean{{/isBoolean}}{{#isString}}String{{/isString}}{{^isString}}{{^isBoolean}}Number{{/isBoolean}}{{/isString}}) {
String.format("Expected array items to be of type {{#isBoolean}}Boolean{{/isBoolean}}{{#isString}}String{{/isString}}{{^isString}}{{^isBoolean}}Number{{/isBoolean}}{{/isString}} in the JSON string but got `%s`", jsonElement.toString())
}
{{/isPrimitiveType}}
{{/isNumber}}
{{^isNumber}}
{{^isPrimitiveType}}
{{{dataType}}}.validateJsonElement(element)
{{/isPrimitiveType}}
{{/isNumber}}
{{/items}}
}
{{/isArray}}
match++
} catch (e: Exception) {
// Validation failed, continue
errorMessages.add(String.format("Validation for {{{dataType}}} failed with `%s`.", e.message))
}
{{/hasVars}}
{{#hasVars}}
// validate json string for {{{.}}}
try {
// validate the JSON object to see if any exception is thrown
{{.}}.validateJsonElement(jsonElement)
match++
} catch (e: Exception) {
// validation failed, continue
errorMessages.add(String.format("Validation for {{{.}}} failed with `%s`.", e.message))
}
{{/hasVars}}
{{/vendorExtensions.x-duplicated-data-type}}
{{/oneOf}}
{{/composedSchemas}}
if (match != 1) {
throw IOException(String.format("Failed validation for {{classname}}: %d classes match result, expected 1. Detailed failure message for oneOf schemas: %s. JSON: %s", match, errorMessages, jsonElement.toString()))
}
}
}
} }

View File

@ -0,0 +1,29 @@
package org.openapitools.codegen.kotlin;
import lombok.Getter;
import org.jetbrains.kotlin.com.intellij.openapi.util.text.Strings;
@Getter
enum ClientLibrary {
JVM_KTOR("main/kotlin"),
JVM_OKHTTP4("main/kotlin"),
JVM_SPRING_WEBCLIENT("main/kotlin"),
JVM_SPRING_RESTCLIENT("main/kotlin"),
JVM_RETROFIT2("main/kotlin"),
MULTIPLATFORM("commonMain/kotlin"),
JVM_VOLLEY("gson", "main/java"),
JVM_VERTX("main/kotlin");
private final String serializationLibrary;
private final String libraryName;
private final String sourceRoot;
ClientLibrary(String serializationLibrary, String sourceRoot) {
this.serializationLibrary = serializationLibrary;
this.sourceRoot = sourceRoot;
this.libraryName = Strings.toLowerCase(this.name()).replace("_", "-");
}
ClientLibrary(String sourceRoot) {
this("jackson", sourceRoot);
}
}

View File

@ -22,7 +22,7 @@ import static org.openapitools.codegen.TestUtils.assertFileContains;
public class KotlinClientCodegenApiTest { public class KotlinClientCodegenApiTest {
@DataProvider(name = "pathResponses") @DataProvider(name = "clientLibraries")
public Object[][] pathResponses() { public Object[][] pathResponses() {
return new Object[][]{ return new Object[][]{
{ClientLibrary.JVM_KTOR}, {ClientLibrary.JVM_KTOR},
@ -36,7 +36,7 @@ public class KotlinClientCodegenApiTest {
}; };
} }
@Test(dataProvider = "pathResponses") @Test(dataProvider = "clientLibraries")
void testPathVariableIsNotEscaped_19930(ClientLibrary library) throws IOException { void testPathVariableIsNotEscaped_19930(ClientLibrary library) throws IOException {
OpenAPI openAPI = new OpenAPIParser() OpenAPI openAPI = new OpenAPIParser()
@ -76,29 +76,4 @@ public class KotlinClientCodegenApiTest {
codegen.additionalProperties().put(KotlinClientCodegen.DATE_LIBRARY, "kotlinx-datetime"); codegen.additionalProperties().put(KotlinClientCodegen.DATE_LIBRARY, "kotlinx-datetime");
return codegen; return codegen;
} }
@Getter
private enum ClientLibrary {
JVM_KTOR("main/kotlin"),
JVM_OKHTTP4("main/kotlin"),
JVM_SPRING_WEBCLIENT("main/kotlin"),
JVM_SPRING_RESTCLIENT("main/kotlin"),
JVM_RETROFIT2("main/kotlin"),
MULTIPLATFORM("commonMain/kotlin"),
JVM_VOLLEY("gson", "main/java"),
JVM_VERTX("main/kotlin");
private final String serializationLibrary;
private final String libraryName;
private final String sourceRoot;
ClientLibrary(String serializationLibrary, String sourceRoot) {
this.serializationLibrary = serializationLibrary;
this.sourceRoot = sourceRoot;
this.libraryName = Strings.toLowerCase(this.name()).replace("_", "-");
}
ClientLibrary(String sourceRoot) {
this("jackson", sourceRoot);
}
}
} }

View File

@ -433,6 +433,66 @@ public class KotlinClientCodegenModelTest {
configAssert.assertValue(KotlinClientCodegen.FAIL_ON_UNKNOWN_PROPERTIES, codegen::isFailOnUnknownProperties, Boolean.FALSE); configAssert.assertValue(KotlinClientCodegen.FAIL_ON_UNKNOWN_PROPERTIES, codegen::isFailOnUnknownProperties, Boolean.FALSE);
} }
@DataProvider(name = "gsonClientLibraries")
public Object[][] pathResponses() {
return new Object[][]{
{ClientLibrary.JVM_KTOR},
{ClientLibrary.JVM_OKHTTP4},
{ClientLibrary.JVM_RETROFIT2},
{ClientLibrary.MULTIPLATFORM},
{ClientLibrary.JVM_VOLLEY},
{ClientLibrary.JVM_VERTX}
};
}
@Test(dataProvider = "gsonClientLibraries")
public void testLocalVariablesUseSanitizedDataTypeNamesForOneOfProperty_19942(ClientLibrary clientLibrary) throws IOException {
File output = Files.createTempDirectory("test").toFile();
String path = output.getAbsolutePath();
output.deleteOnExit();
final CodegenConfigurator configurator = new CodegenConfigurator()
.setGeneratorName("kotlin")
.setLibrary(clientLibrary.getLibraryName())
.setInputSpec("src/test/resources/3_0/issue_19942.json")
.addAdditionalProperty("omitGradleWrapper", true)
.addAdditionalProperty("serializationLibrary", "gson")
.addAdditionalProperty("dateLibrary", "kotlinx-datetime")
.addAdditionalProperty("useSpringBoot3", "true")
.addAdditionalProperty("generateOneOfAnyOfWrappers", true)
.setOutputDir(output.getAbsolutePath().replace("\\", "/"));
DefaultGenerator generator = new DefaultGenerator();
generator.opts(configurator.toClientOptInput()).generate();
TestUtils.assertFileNotContains(Paths.get(path + "/src/" + clientLibrary.getSourceRoot() + "/org/openapitools/client/models/ObjectWithComplexOneOfId.kt"),
"val adapterkotlin.String", "val adapterjava.math.BigDecimal");
}
@Test(dataProvider = "gsonClientLibraries")
public void testLocalVariablesUseSanitizedDataTypeNamesForAnyOfProperty_19942(ClientLibrary clientLibrary) throws IOException {
File output = Files.createTempDirectory("test").toFile();
String path = output.getAbsolutePath();
output.deleteOnExit();
final CodegenConfigurator configurator = new CodegenConfigurator()
.setGeneratorName("kotlin")
.setLibrary(clientLibrary.getLibraryName())
.setInputSpec("src/test/resources/3_0/issue_19942.json")
.addAdditionalProperty("omitGradleWrapper", true)
.addAdditionalProperty("serializationLibrary", "gson")
.addAdditionalProperty("dateLibrary", "kotlinx-datetime")
.addAdditionalProperty("useSpringBoot3", "true")
.addAdditionalProperty("generateOneOfAnyOfWrappers", true)
.setOutputDir(output.getAbsolutePath().replace("\\", "/"));
DefaultGenerator generator = new DefaultGenerator();
generator.opts(configurator.toClientOptInput()).generate();
TestUtils.assertFileNotContains(Paths.get(path + "/src/" + clientLibrary.getSourceRoot() + "/org/openapitools/client/models/ObjectWithComplexAnyOfId.kt"),
"val adapterkotlin.String", "val adapterjava.math.BigDecimal");
}
private static class ModelNameTest { private static class ModelNameTest {
private final String expectedName; private final String expectedName;
private final String expectedClassName; private final String expectedClassName;

View File

@ -0,0 +1,72 @@
{
"openapi": "3.0.1",
"info": {
"title": "xxxxx",
"version": "1.0"
},
"servers": [
{
"url": "https://xxxxx"
},
{
"url": "http://localhost:3000"
}
],
"paths": {
"/test": {
"get": {
"operationId": "testOneOf",
"tags": [
"testOneOf"
],
"summary": "fetches oneOf id",
"responses": {
"200": {
"description": "ok",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ObjectWithComplexOneOf"
}
}
}
}
}
}
}
},
"components" : {
"schemas": {
"ObjectWithComplexOneOf" : {
"type": "object",
"properties": {
"id": {
"oneOf": [
{
"type": "string"
},
{
"type": "number"
}
]
}
}
},
"ObjectWithComplexAnyOf" : {
"type": "object",
"properties": {
"id": {
"anyOf": [
{
"type": "string"
},
{
"type": "number"
}
]
}
}
}
}
}
}

View File

@ -111,4 +111,43 @@ data class ApiAnyOfUserOrPet(var actualInstance: Any? = null) {
}.nullSafe() as TypeAdapter<T> }.nullSafe() as TypeAdapter<T>
} }
} }
companion object {
/**
* Validates the JSON Element and throws an exception if issues found
*
* @param jsonElement JSON Element
* @throws IOException if the JSON Element is invalid with respect to ApiAnyOfUserOrPet
*/
@Throws(IOException::class)
fun validateJsonElement(jsonElement: JsonElement?) {
requireNotNull(jsonElement) {
"Provided json element must not be null"
}
var match = 0
val errorMessages = ArrayList<String>()
// validate the json string with ApiUser
try {
// validate the JSON object to see if any exception is thrown
ApiUser.validateJsonElement(jsonElement)
match++
} catch (e: Exception) {
// Validation failed, continue
errorMessages.add(String.format("Validation for ApiUser failed with `%s`.", e.message))
}
// validate the json string with ApiPet
try {
// validate the JSON object to see if any exception is thrown
ApiPet.validateJsonElement(jsonElement)
match++
} catch (e: Exception) {
// Validation failed, continue
errorMessages.add(String.format("Validation for ApiPet failed with `%s`.", e.message))
}
if (match != 1) {
throw IOException(String.format("Failed validation for ApiAnyOfUserOrPet: %d classes match result, expected 1. Detailed failure message for oneOf schemas: %s. JSON: %s", match, errorMessages, jsonElement.toString()))
}
}
}
} }

View File

@ -144,4 +144,61 @@ data class ApiAnyOfUserOrPetOrArrayString(var actualInstance: Any? = null) {
}.nullSafe() as TypeAdapter<T> }.nullSafe() as TypeAdapter<T>
} }
} }
companion object {
/**
* Validates the JSON Element and throws an exception if issues found
*
* @param jsonElement JSON Element
* @throws IOException if the JSON Element is invalid with respect to ApiAnyOfUserOrPetOrArrayString
*/
@Throws(IOException::class)
fun validateJsonElement(jsonElement: JsonElement?) {
requireNotNull(jsonElement) {
"Provided json element must not be null"
}
var match = 0
val errorMessages = ArrayList<String>()
// validate the json string with ApiUser
try {
// validate the JSON object to see if any exception is thrown
ApiUser.validateJsonElement(jsonElement)
match++
} catch (e: Exception) {
// Validation failed, continue
errorMessages.add(String.format("Validation for ApiUser failed with `%s`.", e.message))
}
// validate the json string with ApiPet
try {
// validate the JSON object to see if any exception is thrown
ApiPet.validateJsonElement(jsonElement)
match++
} catch (e: Exception) {
// Validation failed, continue
errorMessages.add(String.format("Validation for ApiPet failed with `%s`.", e.message))
}
// validate the json string with kotlin.collections.List<kotlin.String>
try {
// validate the JSON object to see if any exception is thrown
require(jsonElement.isJsonArray) {
String.format("Expected json element to be a array type in the JSON string but got `%s`", jsonElement.toString())
}
// validate array items
for(element in jsonElement.getAsJsonArray()) {
require(element.getAsJsonPrimitive().isString) {
String.format("Expected array items to be of type String in the JSON string but got `%s`", jsonElement.toString())
}
}
match++
} catch (e: Exception) {
// Validation failed, continue
errorMessages.add(String.format("Validation for kotlin.collections.List<kotlin.String> failed with `%s`.", e.message))
}
if (match != 1) {
throw IOException(String.format("Failed validation for ApiAnyOfUserOrPetOrArrayString: %d classes match result, expected 1. Detailed failure message for oneOf schemas: %s. JSON: %s", match, errorMessages, jsonElement.toString()))
}
}
}
} }

View File

@ -115,4 +115,43 @@ data class ApiUserOrPet(var actualInstance: Any? = null) {
}.nullSafe() as TypeAdapter<T> }.nullSafe() as TypeAdapter<T>
} }
} }
companion object {
/**
* Validates the JSON Element and throws an exception if issues found
*
* @param jsonElement JSON Element
* @throws IOException if the JSON Element is invalid with respect to ApiUserOrPet
*/
@Throws(IOException::class)
fun validateJsonElement(jsonElement: JsonElement?) {
requireNotNull(jsonElement) {
"Provided json element must not be null"
}
var match = 0
val errorMessages = ArrayList<String>()
// validate the json string with ApiUser
try {
// validate the JSON object to see if any exception is thrown
ApiUser.validateJsonElement(jsonElement)
match++
} catch (e: Exception) {
// Validation failed, continue
errorMessages.add(String.format("Validation for ApiUser failed with `%s`.", e.message))
}
// validate the json string with ApiPet
try {
// validate the JSON object to see if any exception is thrown
ApiPet.validateJsonElement(jsonElement)
match++
} catch (e: Exception) {
// Validation failed, continue
errorMessages.add(String.format("Validation for ApiPet failed with `%s`.", e.message))
}
if (match != 1) {
throw IOException(String.format("Failed validation for ApiUserOrPet: %d classes match result, expected 1. Detailed failure message for oneOf schemas: %s. JSON: %s", match, errorMessages, jsonElement.toString()))
}
}
}
} }

View File

@ -147,4 +147,61 @@ data class ApiUserOrPetOrArrayString(var actualInstance: Any? = null) {
}.nullSafe() as TypeAdapter<T> }.nullSafe() as TypeAdapter<T>
} }
} }
companion object {
/**
* Validates the JSON Element and throws an exception if issues found
*
* @param jsonElement JSON Element
* @throws IOException if the JSON Element is invalid with respect to ApiUserOrPetOrArrayString
*/
@Throws(IOException::class)
fun validateJsonElement(jsonElement: JsonElement?) {
requireNotNull(jsonElement) {
"Provided json element must not be null"
}
var match = 0
val errorMessages = ArrayList<String>()
// validate the json string with ApiUser
try {
// validate the JSON object to see if any exception is thrown
ApiUser.validateJsonElement(jsonElement)
match++
} catch (e: Exception) {
// Validation failed, continue
errorMessages.add(String.format("Validation for ApiUser failed with `%s`.", e.message))
}
// validate the json string with ApiPet
try {
// validate the JSON object to see if any exception is thrown
ApiPet.validateJsonElement(jsonElement)
match++
} catch (e: Exception) {
// Validation failed, continue
errorMessages.add(String.format("Validation for ApiPet failed with `%s`.", e.message))
}
// validate the json string with kotlin.collections.List<kotlin.String>
try {
// validate the JSON object to see if any exception is thrown
require(jsonElement.isJsonArray) {
String.format("Expected json element to be a array type in the JSON string but got `%s`", jsonElement.toString())
}
// validate array items
for(element in jsonElement.getAsJsonArray()) {
require(element.getAsJsonPrimitive().isString) {
String.format("Expected array items to be of type String in the JSON string but got `%s`", jsonElement.toString())
}
}
match++
} catch (e: Exception) {
// Validation failed, continue
errorMessages.add(String.format("Validation for kotlin.collections.List<kotlin.String> failed with `%s`.", e.message))
}
if (match != 1) {
throw IOException(String.format("Failed validation for ApiUserOrPetOrArrayString: %d classes match result, expected 1. Detailed failure message for oneOf schemas: %s. JSON: %s", match, errorMessages, jsonElement.toString()))
}
}
}
} }