From bc466c98301f20f37376a1057f000ca04e178276 Mon Sep 17 00:00:00 2001 From: Justin Black Date: Wed, 17 Jan 2024 11:57:47 -0800 Subject: [PATCH 1/2] dependentSchemas tests turned on in java 310 test spec --- .../3_1_0_unit_test_spec_nopaths.yaml | 225 ++++++++++++++++++ .../3_1/unit_test_spec/spec_writer.py | 3 - 2 files changed, 225 insertions(+), 3 deletions(-) diff --git a/src/test/resources/3_1/unit_test_spec/3_1_0_unit_test_spec_nopaths.yaml b/src/test/resources/3_1/unit_test_spec/3_1_0_unit_test_spec_nopaths.yaml index 6b0eb400862..b0eac1c1607 100644 --- a/src/test/resources/3_1/unit_test_spec/3_1_0_unit_test_spec_nopaths.yaml +++ b/src/test/resources/3_1/unit_test_spec/3_1_0_unit_test_spec_nopaths.yaml @@ -156,10 +156,46 @@ components: $schema: https://json-schema.org/draft/2020-12/schema contains: type: 'null' + SingleDependency: + $schema: https://json-schema.org/draft/2020-12/schema + dependentRequired: + bar: + - foo EmptyDependents: $schema: https://json-schema.org/draft/2020-12/schema dependentRequired: bar: [] + MultipleDependentsRequired: + $schema: https://json-schema.org/draft/2020-12/schema + dependentRequired: + quux: + - foo + - bar + DependentSchemasSingleDependency: + $schema: https://json-schema.org/draft/2020-12/schema + dependentSchemas: + bar: + properties: + foo: + type: integer + bar: + type: integer + DependentSchemasDependenciesWithEscapedCharacters: + $schema: https://json-schema.org/draft/2020-12/schema + dependentSchemas: + "foo\tbar": + minProperties: 4 + foo'bar: + required: + - foo"bar + DependentSchemasDependentSubschemaIncompatibleWithRoot: + properties: + foo: {} + dependentSchemas: + foo: + properties: + bar: {} + additionalProperties: false SimpleEnumValidation: $schema: https://json-schema.org/draft/2020-12/schema enum: @@ -963,6 +999,47 @@ components: - null valid: true comment: null + SingleDependency: + Neither: + description: neither + data: {} + valid: true + comment: null + Nondependant: + description: nondependant + data: + foo: 1 + valid: true + comment: null + WithDependency: + description: with dependency + data: + foo: 1 + bar: 2 + valid: true + comment: null + MissingDependency: + description: missing dependency + data: + bar: 2 + valid: false + comment: null + IgnoresArrays: + description: ignores arrays + data: + - bar + valid: true + comment: null + IgnoresStrings: + description: ignores strings + data: foobar + valid: true + comment: null + IgnoresOtherNonObjects: + description: ignores other non-objects + data: 12 + valid: true + comment: null EmptyDependents: EmptyObject: description: empty object @@ -980,6 +1057,154 @@ components: data: 1 valid: true comment: null + MultipleDependentsRequired: + Neither: + description: neither + data: {} + valid: true + comment: null + Nondependants: + description: nondependants + data: + foo: 1 + bar: 2 + valid: true + comment: null + WithDependencies: + description: with dependencies + data: + foo: 1 + bar: 2 + quux: 3 + valid: true + comment: null + MissingDependency: + description: missing dependency + data: + foo: 1 + quux: 2 + valid: false + comment: null + MissingOtherDependency: + description: missing other dependency + data: + bar: 1 + quux: 2 + valid: false + comment: null + MissingBothDependencies: + description: missing both dependencies + data: + quux: 1 + valid: false + comment: null + DependentSchemasSingleDependency: + Valid: + description: valid + data: + foo: 1 + bar: 2 + valid: true + comment: null + NoDependency: + description: no dependency + data: + foo: quux + valid: true + comment: null + WrongType: + description: wrong type + data: + foo: quux + bar: 2 + valid: false + comment: null + WrongTypeOther: + description: wrong type other + data: + foo: 2 + bar: quux + valid: false + comment: null + WrongTypeBoth: + description: wrong type both + data: + foo: quux + bar: quux + valid: false + comment: null + IgnoresArrays: + description: ignores arrays + data: + - bar + valid: true + comment: null + IgnoresStrings: + description: ignores strings + data: foobar + valid: true + comment: null + IgnoresOtherNonObjects: + description: ignores other non-objects + data: 12 + valid: true + comment: null + DependentSchemasDependenciesWithEscapedCharacters: + QuotedTab: + description: quoted tab + data: + "foo\tbar": 1 + a: 2 + b: 3 + c: 4 + valid: true + comment: null + QuotedQuote: + description: quoted quote + data: + foo'bar: + foo"bar: 1 + valid: false + comment: null + QuotedTabInvalidUnderDependentSchema: + description: quoted tab invalid under dependent schema + data: + "foo\tbar": 1 + a: 2 + valid: false + comment: null + QuotedQuoteInvalidUnderDependentSchema: + description: quoted quote invalid under dependent schema + data: + foo'bar: 1 + valid: false + comment: null + DependentSchemasDependentSubschemaIncompatibleWithRoot: + MatchesRoot: + description: matches root + data: + foo: 1 + valid: false + comment: null + MatchesDependency: + description: matches dependency + data: + bar: 1 + valid: true + comment: null + MatchesBoth: + description: matches both + data: + foo: 1 + bar: 2 + valid: false + comment: null + NoDependency: + description: no dependency + data: + baz: 1 + valid: true + comment: null SimpleEnumValidation: OneOfTheEnumIsValid: description: one of the enum is valid diff --git a/src/test/resources/3_1/unit_test_spec/spec_writer.py b/src/test/resources/3_1/unit_test_spec/spec_writer.py index bc2019c813f..81ee57e9dbe 100644 --- a/src/test/resources/3_1/unit_test_spec/spec_writer.py +++ b/src/test/resources/3_1/unit_test_spec/spec_writer.py @@ -708,9 +708,6 @@ def write_openapi_spec(): 'UniqueitemsWithAnArrayOfItems', 'UniqueitemsFalseWithAnArrayOfItems', 'UnevaluateditemsDependsOnMultipleNestedContains', - 'DependentSchemasSingleDependency', - 'DependentSchemasDependenciesWithEscapedCharacters', - 'DependentSchemasDependentSubschemaIncompatibleWithRoot', 'IgnoreIfWithoutThenOrElse', 'IfAndThenWithoutElse', 'IfAndElseWithoutThen', From e239d201a93df99b542585509a789d040426406c Mon Sep 17 00:00:00 2001 From: Justin Black Date: Wed, 17 Jan 2024 13:14:34 -0800 Subject: [PATCH 2/2] Samples regen --- .circleci/parallel.sh | 1 + docs/generators/java.md | 2 +- .../java/.openapi-generator/FILES | 1 + .../validation/DependentSchemasValidator.java | 48 ++ .../client/schemas/validation/JsonSchema.java | 8 + .../schemas/validation/JsonSchemaInfo.java | 5 + .../java/.openapi-generator/FILES | 11 + samples/client/3_1_0_unit_test/java/README.md | 5 + ...chemasDependenciesWithEscapedCharacters.md | 153 ++++ ...sDependentSubschemaIncompatibleWithRoot.md | 204 +++++ .../DependentSchemasSingleDependency.md | 135 ++++ .../schemas/MultipleDependentsRequired.md | 46 ++ .../components/schemas/SingleDependency.md | 45 ++ ...emasDependenciesWithEscapedCharacters.java | 749 ++++++++++++++++++ ...ependentSubschemaIncompatibleWithRoot.java | 560 +++++++++++++ .../DependentSchemasSingleDependency.java | 591 ++++++++++++++ .../schemas/MultipleDependentsRequired.java | 249 ++++++ .../components/schemas/SingleDependency.java | 248 ++++++ .../validation/DependentSchemasValidator.java | 48 ++ .../client/schemas/validation/JsonSchema.java | 8 + .../schemas/validation/JsonSchemaInfo.java | 5 + ...DependenciesWithEscapedCharactersTest.java | 115 +++ ...dentSubschemaIncompatibleWithRootTest.java | 93 +++ .../DependentSchemasSingleDependencyTest.java | 157 ++++ .../MultipleDependentsRequiredTest.java | 140 ++++ .../schemas/SingleDependencyTest.java | 116 +++ .../petstore/java/.openapi-generator/FILES | 1 + .../validation/DependentSchemasValidator.java | 48 ++ .../client/schemas/validation/JsonSchema.java | 8 + .../schemas/validation/JsonSchemaInfo.java | 5 + .../generators/JavaClientGenerator.java | 24 +- .../_Schema_anytypeOrMultitype.hbs | 6 +- .../schemas/SchemaClass/_Schema_map.hbs | 6 +- .../schemas/SchemaClass/_dependentSchemas.hbs | 29 + .../schemas/docschema_fields_field.hbs | 3 + .../validation/DependentSchemasValidator.hbs | 48 ++ .../schemas/validation/JsonSchema.hbs | 8 + .../schemas/validation/JsonSchemaInfo.hbs | 5 + 38 files changed, 3920 insertions(+), 14 deletions(-) create mode 100644 samples/client/3_0_3_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/DependentSchemasValidator.java create mode 100644 samples/client/3_1_0_unit_test/java/docs/components/schemas/DependentSchemasDependenciesWithEscapedCharacters.md create mode 100644 samples/client/3_1_0_unit_test/java/docs/components/schemas/DependentSchemasDependentSubschemaIncompatibleWithRoot.md create mode 100644 samples/client/3_1_0_unit_test/java/docs/components/schemas/DependentSchemasSingleDependency.md create mode 100644 samples/client/3_1_0_unit_test/java/docs/components/schemas/MultipleDependentsRequired.md create mode 100644 samples/client/3_1_0_unit_test/java/docs/components/schemas/SingleDependency.md create mode 100644 samples/client/3_1_0_unit_test/java/src/main/java/org/openapijsonschematools/client/components/schemas/DependentSchemasDependenciesWithEscapedCharacters.java create mode 100644 samples/client/3_1_0_unit_test/java/src/main/java/org/openapijsonschematools/client/components/schemas/DependentSchemasDependentSubschemaIncompatibleWithRoot.java create mode 100644 samples/client/3_1_0_unit_test/java/src/main/java/org/openapijsonschematools/client/components/schemas/DependentSchemasSingleDependency.java create mode 100644 samples/client/3_1_0_unit_test/java/src/main/java/org/openapijsonschematools/client/components/schemas/MultipleDependentsRequired.java create mode 100644 samples/client/3_1_0_unit_test/java/src/main/java/org/openapijsonschematools/client/components/schemas/SingleDependency.java create mode 100644 samples/client/3_1_0_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/DependentSchemasValidator.java create mode 100644 samples/client/3_1_0_unit_test/java/src/test/java/org/openapijsonschematools/client/components/schemas/DependentSchemasDependenciesWithEscapedCharactersTest.java create mode 100644 samples/client/3_1_0_unit_test/java/src/test/java/org/openapijsonschematools/client/components/schemas/DependentSchemasDependentSubschemaIncompatibleWithRootTest.java create mode 100644 samples/client/3_1_0_unit_test/java/src/test/java/org/openapijsonschematools/client/components/schemas/DependentSchemasSingleDependencyTest.java create mode 100644 samples/client/3_1_0_unit_test/java/src/test/java/org/openapijsonschematools/client/components/schemas/MultipleDependentsRequiredTest.java create mode 100644 samples/client/3_1_0_unit_test/java/src/test/java/org/openapijsonschematools/client/components/schemas/SingleDependencyTest.java create mode 100644 samples/client/petstore/java/src/main/java/org/openapijsonschematools/client/schemas/validation/DependentSchemasValidator.java create mode 100644 src/main/resources/java/src/main/java/packagename/components/schemas/SchemaClass/_dependentSchemas.hbs create mode 100644 src/main/resources/java/src/main/java/packagename/schemas/validation/DependentSchemasValidator.hbs diff --git a/.circleci/parallel.sh b/.circleci/parallel.sh index 0744348ffd1..963f7baae1b 100755 --- a/.circleci/parallel.sh +++ b/.circleci/parallel.sh @@ -31,6 +31,7 @@ elif [ "$JOB_ID" = "testJava17ClientSamples" ]; then (cd samples/client/petstore/java && mvn test) (cd samples/client/3_0_3_unit_test/java && mvn test) + (cd samples/client/3_1_0_unit_test/java && mvn test) else echo "Running job $JOB_ID" diff --git a/docs/generators/java.md b/docs/generators/java.md index 2129e21cbaa..62f31a5020a 100644 --- a/docs/generators/java.md +++ b/docs/generators/java.md @@ -280,7 +280,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl |Contains|✓|OAS3 |Default|✓|OAS2,OAS3 |DependentRequired|✓|OAS3 -|DependentSchemas|✗|OAS3 +|DependentSchemas|✓|OAS3 |Discriminator|✗|OAS2,OAS3 |Else|✗|OAS3 |Enum|✓|OAS2,OAS3 diff --git a/samples/client/3_0_3_unit_test/java/.openapi-generator/FILES b/samples/client/3_0_3_unit_test/java/.openapi-generator/FILES index a555be6c888..84896bf3af2 100644 --- a/samples/client/3_0_3_unit_test/java/.openapi-generator/FILES +++ b/samples/client/3_0_3_unit_test/java/.openapi-generator/FILES @@ -214,6 +214,7 @@ src/main/java/org/openapijsonschematools/client/schemas/validation/ContainsValid src/main/java/org/openapijsonschematools/client/schemas/validation/CustomIsoparser.java src/main/java/org/openapijsonschematools/client/schemas/validation/DefaultValueMethod.java src/main/java/org/openapijsonschematools/client/schemas/validation/DependentRequiredValidator.java +src/main/java/org/openapijsonschematools/client/schemas/validation/DependentSchemasValidator.java src/main/java/org/openapijsonschematools/client/schemas/validation/DoubleEnumValidator.java src/main/java/org/openapijsonschematools/client/schemas/validation/DoubleValueMethod.java src/main/java/org/openapijsonschematools/client/schemas/validation/EnumValidator.java diff --git a/samples/client/3_0_3_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/DependentSchemasValidator.java b/samples/client/3_0_3_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/DependentSchemasValidator.java new file mode 100644 index 00000000000..a689279e1e1 --- /dev/null +++ b/samples/client/3_0_3_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/DependentSchemasValidator.java @@ -0,0 +1,48 @@ +package org.openapijsonschematools.client.schemas.validation; + +import org.checkerframework.checker.nullness.qual.Nullable; + +import java.util.ArrayList; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +public class DependentSchemasValidator implements KeywordValidator { + public final Map> dependentSchemas; + + public DependentSchemasValidator(Map> dependentSchemas) { + this.dependentSchemas = dependentSchemas; + } + + @Override + public @Nullable PathToSchemasMap validate( + JsonSchema schema, + @Nullable Object arg, + ValidationMetadata validationMetadata, + @Nullable List containsPathToSchemas + ) { + if (!(arg instanceof Map mapArg)) { + return null; + } + PathToSchemasMap pathToSchemas = new PathToSchemasMap(); + Set presentProperties = new LinkedHashSet<>(); + for (Object key: mapArg.keySet()) { + if (key instanceof String) { + presentProperties.add((String) key); + } + } + for(Map.Entry> entry: dependentSchemas.entrySet()) { + String propName = entry.getKey(); + if (!presentProperties.contains(propName)) { + continue; + } + Class dependentSchemaClass = entry.getValue(); + JsonSchema dependentSchema = JsonSchemaFactory.getInstance(dependentSchemaClass); + PathToSchemasMap otherPathToSchemas = JsonSchema.validate(dependentSchema, arg, validationMetadata); + pathToSchemas.update(otherPathToSchemas); + } + return pathToSchemas; + } +} + diff --git a/samples/client/3_0_3_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/JsonSchema.java b/samples/client/3_0_3_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/JsonSchema.java index 9d7831b6225..562dc06cab0 100644 --- a/samples/client/3_0_3_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/JsonSchema.java +++ b/samples/client/3_0_3_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/JsonSchema.java @@ -51,6 +51,7 @@ public abstract class JsonSchema { public final @Nullable Integer minContains; public final @Nullable Class propertyNames; public @Nullable Map> dependentRequired; + public final @Nullable Map> dependentSchemas; private final LinkedHashMap keywordToValidator; protected JsonSchema(JsonSchemaInfo jsonSchemaInfo) { @@ -268,6 +269,13 @@ protected JsonSchema(JsonSchemaInfo jsonSchemaInfo) { new DependentRequiredValidator(this.dependentRequired) ); } + this.dependentSchemas = jsonSchemaInfo.dependentSchemas; + if (this.dependentSchemas != null) { + keywordToValidator.put( + "dependentSchemas", + new DependentSchemasValidator(this.dependentSchemas) + ); + } this.keywordToValidator = keywordToValidator; } diff --git a/samples/client/3_0_3_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/JsonSchemaInfo.java b/samples/client/3_0_3_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/JsonSchemaInfo.java index 59f51a6be72..c4f4ddf1042 100644 --- a/samples/client/3_0_3_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/JsonSchemaInfo.java +++ b/samples/client/3_0_3_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/JsonSchemaInfo.java @@ -167,4 +167,9 @@ public JsonSchemaInfo dependentRequired(Map> dependentRequir this.dependentRequired = dependentRequired; return this; } + public @Nullable Map> dependentSchemas = null; + public JsonSchemaInfo dependentSchemas(Map> dependentSchemas) { + this.dependentSchemas = dependentSchemas; + return this; + } } \ No newline at end of file diff --git a/samples/client/3_1_0_unit_test/java/.openapi-generator/FILES b/samples/client/3_1_0_unit_test/java/.openapi-generator/FILES index 610c2c86171..e959fef3770 100644 --- a/samples/client/3_1_0_unit_test/java/.openapi-generator/FILES +++ b/samples/client/3_1_0_unit_test/java/.openapi-generator/FILES @@ -26,6 +26,9 @@ docs/components/schemas/ContainsKeywordValidation.md docs/components/schemas/ContainsWithNullInstanceElements.md docs/components/schemas/DateFormat.md docs/components/schemas/DateTimeFormat.md +docs/components/schemas/DependentSchemasDependenciesWithEscapedCharacters.md +docs/components/schemas/DependentSchemasDependentSubschemaIncompatibleWithRoot.md +docs/components/schemas/DependentSchemasSingleDependency.md docs/components/schemas/DurationFormat.md docs/components/schemas/EmailFormat.md docs/components/schemas/EmptyDependents.md @@ -63,6 +66,7 @@ docs/components/schemas/MinimumValidationWithSignedInteger.md docs/components/schemas/MinitemsValidation.md docs/components/schemas/MinlengthValidation.md docs/components/schemas/MinpropertiesValidation.md +docs/components/schemas/MultipleDependentsRequired.md docs/components/schemas/MultipleTypesCanBeSpecifiedInAnArray.md docs/components/schemas/NestedAllofToCheckValidationSemantics.md docs/components/schemas/NestedAnyofToCheckValidationSemantics.md @@ -97,6 +101,7 @@ docs/components/schemas/RequiredValidation.md docs/components/schemas/RequiredWithEmptyArray.md docs/components/schemas/RequiredWithEscapedCharacters.md docs/components/schemas/SimpleEnumValidation.md +docs/components/schemas/SingleDependency.md docs/components/schemas/SmallMultipleOfLargeInteger.md docs/components/schemas/StringTypeMatchesStrings.md docs/components/schemas/TimeFormat.md @@ -141,6 +146,9 @@ src/main/java/org/openapijsonschematools/client/components/schemas/ContainsKeywo src/main/java/org/openapijsonschematools/client/components/schemas/ContainsWithNullInstanceElements.java src/main/java/org/openapijsonschematools/client/components/schemas/DateFormat.java src/main/java/org/openapijsonschematools/client/components/schemas/DateTimeFormat.java +src/main/java/org/openapijsonschematools/client/components/schemas/DependentSchemasDependenciesWithEscapedCharacters.java +src/main/java/org/openapijsonschematools/client/components/schemas/DependentSchemasDependentSubschemaIncompatibleWithRoot.java +src/main/java/org/openapijsonschematools/client/components/schemas/DependentSchemasSingleDependency.java src/main/java/org/openapijsonschematools/client/components/schemas/DurationFormat.java src/main/java/org/openapijsonschematools/client/components/schemas/EmailFormat.java src/main/java/org/openapijsonschematools/client/components/schemas/EmptyDependents.java @@ -178,6 +186,7 @@ src/main/java/org/openapijsonschematools/client/components/schemas/MinimumValida src/main/java/org/openapijsonschematools/client/components/schemas/MinitemsValidation.java src/main/java/org/openapijsonschematools/client/components/schemas/MinlengthValidation.java src/main/java/org/openapijsonschematools/client/components/schemas/MinpropertiesValidation.java +src/main/java/org/openapijsonschematools/client/components/schemas/MultipleDependentsRequired.java src/main/java/org/openapijsonschematools/client/components/schemas/MultipleTypesCanBeSpecifiedInAnArray.java src/main/java/org/openapijsonschematools/client/components/schemas/NestedAllofToCheckValidationSemantics.java src/main/java/org/openapijsonschematools/client/components/schemas/NestedAnyofToCheckValidationSemantics.java @@ -212,6 +221,7 @@ src/main/java/org/openapijsonschematools/client/components/schemas/RequiredValid src/main/java/org/openapijsonschematools/client/components/schemas/RequiredWithEmptyArray.java src/main/java/org/openapijsonschematools/client/components/schemas/RequiredWithEscapedCharacters.java src/main/java/org/openapijsonschematools/client/components/schemas/SimpleEnumValidation.java +src/main/java/org/openapijsonschematools/client/components/schemas/SingleDependency.java src/main/java/org/openapijsonschematools/client/components/schemas/SmallMultipleOfLargeInteger.java src/main/java/org/openapijsonschematools/client/components/schemas/StringTypeMatchesStrings.java src/main/java/org/openapijsonschematools/client/components/schemas/TimeFormat.java @@ -266,6 +276,7 @@ src/main/java/org/openapijsonschematools/client/schemas/validation/ContainsValid src/main/java/org/openapijsonschematools/client/schemas/validation/CustomIsoparser.java src/main/java/org/openapijsonschematools/client/schemas/validation/DefaultValueMethod.java src/main/java/org/openapijsonschematools/client/schemas/validation/DependentRequiredValidator.java +src/main/java/org/openapijsonschematools/client/schemas/validation/DependentSchemasValidator.java src/main/java/org/openapijsonschematools/client/schemas/validation/DoubleEnumValidator.java src/main/java/org/openapijsonschematools/client/schemas/validation/DoubleValueMethod.java src/main/java/org/openapijsonschematools/client/schemas/validation/EnumValidator.java diff --git a/samples/client/3_1_0_unit_test/java/README.md b/samples/client/3_1_0_unit_test/java/README.md index 6bcb419a53a..b913f62785b 100644 --- a/samples/client/3_1_0_unit_test/java/README.md +++ b/samples/client/3_1_0_unit_test/java/README.md @@ -184,6 +184,9 @@ allowed input and output types. | [ContainsWithNullInstanceElements.ContainsWithNullInstanceElements1](docs/components/schemas/ContainsWithNullInstanceElements.md#containswithnullinstanceelements1) | | | [DateFormat.DateFormat1](docs/components/schemas/DateFormat.md#dateformat1) | | | [DateTimeFormat.DateTimeFormat1](docs/components/schemas/DateTimeFormat.md#datetimeformat1) | | +| [DependentSchemasDependenciesWithEscapedCharacters.DependentSchemasDependenciesWithEscapedCharacters1](docs/components/schemas/DependentSchemasDependenciesWithEscapedCharacters.md#dependentschemasdependencieswithescapedcharacters1) | | +| [DependentSchemasDependentSubschemaIncompatibleWithRoot.DependentSchemasDependentSubschemaIncompatibleWithRoot1](docs/components/schemas/DependentSchemasDependentSubschemaIncompatibleWithRoot.md#dependentschemasdependentsubschemaincompatiblewithroot1) | | +| [DependentSchemasSingleDependency.DependentSchemasSingleDependency1](docs/components/schemas/DependentSchemasSingleDependency.md#dependentschemassingledependency1) | | | [DurationFormat.DurationFormat1](docs/components/schemas/DurationFormat.md#durationformat1) | | | [EmailFormat.EmailFormat1](docs/components/schemas/EmailFormat.md#emailformat1) | | | [EmptyDependents.EmptyDependents1](docs/components/schemas/EmptyDependents.md#emptydependents1) | | @@ -221,6 +224,7 @@ allowed input and output types. | [MinitemsValidation.MinitemsValidation1](docs/components/schemas/MinitemsValidation.md#minitemsvalidation1) | | | [MinlengthValidation.MinlengthValidation1](docs/components/schemas/MinlengthValidation.md#minlengthvalidation1) | | | [MinpropertiesValidation.MinpropertiesValidation1](docs/components/schemas/MinpropertiesValidation.md#minpropertiesvalidation1) | | +| [MultipleDependentsRequired.MultipleDependentsRequired1](docs/components/schemas/MultipleDependentsRequired.md#multipledependentsrequired1) | | | [MultipleTypesCanBeSpecifiedInAnArray.MultipleTypesCanBeSpecifiedInAnArray1](docs/components/schemas/MultipleTypesCanBeSpecifiedInAnArray.md#multipletypescanbespecifiedinanarray1) | | | [NestedAllofToCheckValidationSemantics.NestedAllofToCheckValidationSemantics1](docs/components/schemas/NestedAllofToCheckValidationSemantics.md#nestedalloftocheckvalidationsemantics1) | | | [NestedAnyofToCheckValidationSemantics.NestedAnyofToCheckValidationSemantics1](docs/components/schemas/NestedAnyofToCheckValidationSemantics.md#nestedanyoftocheckvalidationsemantics1) | | @@ -255,6 +259,7 @@ allowed input and output types. | [RequiredWithEmptyArray.RequiredWithEmptyArray1](docs/components/schemas/RequiredWithEmptyArray.md#requiredwithemptyarray1) | | | [RequiredWithEscapedCharacters.RequiredWithEscapedCharacters1](docs/components/schemas/RequiredWithEscapedCharacters.md#requiredwithescapedcharacters1) | | | [SimpleEnumValidation.SimpleEnumValidation1](docs/components/schemas/SimpleEnumValidation.md#simpleenumvalidation1) | | +| [SingleDependency.SingleDependency1](docs/components/schemas/SingleDependency.md#singledependency1) | | | [SmallMultipleOfLargeInteger.SmallMultipleOfLargeInteger1](docs/components/schemas/SmallMultipleOfLargeInteger.md#smallmultipleoflargeinteger1) | | | [StringTypeMatchesStrings.StringTypeMatchesStrings1](docs/components/schemas/StringTypeMatchesStrings.md#stringtypematchesstrings1) | | | [TimeFormat.TimeFormat1](docs/components/schemas/TimeFormat.md#timeformat1) | | diff --git a/samples/client/3_1_0_unit_test/java/docs/components/schemas/DependentSchemasDependenciesWithEscapedCharacters.md b/samples/client/3_1_0_unit_test/java/docs/components/schemas/DependentSchemasDependenciesWithEscapedCharacters.md new file mode 100644 index 00000000000..740ea6c8266 --- /dev/null +++ b/samples/client/3_1_0_unit_test/java/docs/components/schemas/DependentSchemasDependenciesWithEscapedCharacters.md @@ -0,0 +1,153 @@ +# DependentSchemasDependenciesWithEscapedCharacters +org.openapijsonschematools.client.components.schemas.DependentSchemasDependenciesWithEscapedCharacters.java +public class DependentSchemasDependenciesWithEscapedCharacters + +A class that contains necessary nested +- schema classes (which validate payloads), extends JsonSchema +- classes to store validated map payloads, extends FrozenMap +- classes to build inputs for map payloads + +## Nested Class Summary +| Modifier and Type | Class and Description | +| ----------------- | ---------------------- | +| static class | [DependentSchemasDependenciesWithEscapedCharacters.DependentSchemasDependenciesWithEscapedCharacters1](#dependentschemasdependencieswithescapedcharacters1)
schema class | +| static class | [DependentSchemasDependenciesWithEscapedCharacters.Foobar](#foobar)
schema class | +| static class | [DependentSchemasDependenciesWithEscapedCharacters.FoobarMapBuilder](#foobarmapbuilder)
builder for Map payloads | +| static class | [DependentSchemasDependenciesWithEscapedCharacters.FoobarMap](#foobarmap)
output class for Map payloads | +| static class | [DependentSchemasDependenciesWithEscapedCharacters.Footbar](#footbar)
schema class | + +## DependentSchemasDependenciesWithEscapedCharacters1 +public static class DependentSchemasDependenciesWithEscapedCharacters1
+extends JsonSchema + +A schema class that validates payloads + +### Field Summary +| Modifier and Type | Field and Description | +| ----------------- | ---------------------- | +| Map> | dependentSchemas = Map.ofEntries(
    new PropertyEntry("foo\tbar", [Footbar.class](#footbar))),
    new PropertyEntry("foo'bar", [Foobar.class](#foobar)))
)
| + +### Method Summary +| Modifier and Type | Method and Description | +| ----------------- | ---------------------- | +| String | validate(String arg, SchemaConfiguration configuration) | +| Void | validate(Void arg, SchemaConfiguration configuration) | +| int | validate(int arg, SchemaConfiguration configuration) | +| long | validate(long arg, SchemaConfiguration configuration) | +| float | validate(float arg, SchemaConfiguration configuration) | +| double | validate(double arg, SchemaConfiguration configuration) | +| boolean | validate(boolean arg, SchemaConfiguration configuration) | +| FrozenMap | validate(Map<?, ?> arg, SchemaConfiguration configuration) | +| FrozenList<@Nullable Object> | validate(List arg, SchemaConfiguration configuration) | +| @Nullable Object | validate(@Nullable Object arg, SchemaConfiguration configuration) | +## Foobar +public static class Foobar
+extends JsonSchema + +A schema class that validates payloads + +### Field Summary +| Modifier and Type | Field and Description | +| ----------------- | ---------------------- | +| Set | required = Set.of(
    "foo\"bar"
)
| + +### Method Summary +| Modifier and Type | Method and Description | +| ----------------- | ---------------------- | +| String | validate(String arg, SchemaConfiguration configuration) | +| Void | validate(Void arg, SchemaConfiguration configuration) | +| int | validate(int arg, SchemaConfiguration configuration) | +| long | validate(long arg, SchemaConfiguration configuration) | +| float | validate(float arg, SchemaConfiguration configuration) | +| double | validate(double arg, SchemaConfiguration configuration) | +| boolean | validate(boolean arg, SchemaConfiguration configuration) | +| [FoobarMap](#foobarmap) | validate([Map<?, ?>](#foobarmapbuilder) arg, SchemaConfiguration configuration) | +| FrozenList<@Nullable Object> | validate(List arg, SchemaConfiguration configuration) | +| @Nullable Object | validate(@Nullable Object arg, SchemaConfiguration configuration) | +## FoobarMap0Builder +public class FoobarMap0Builder
+builder for `Map` + +A class that builds the Map input type + +### Constructor Summary +| Constructor and Description | +| --------------------------- | +| FoobarMap0Builder(Map instance)
Creates a builder that contains the passed instance | + +### Method Summary +| Modifier and Type | Method and Description | +| ----------------- | ---------------------- | +| Map | build()
Returns map input that should be used with Schema.validate | +| [FoobarMap0Builder](#foobarmap0builder) | additionalProperty(String key, Void value) | +| [FoobarMap0Builder](#foobarmap0builder) | additionalProperty(String key, boolean value) | +| [FoobarMap0Builder](#foobarmap0builder) | additionalProperty(String key, String value) | +| [FoobarMap0Builder](#foobarmap0builder) | additionalProperty(String key, int value) | +| [FoobarMap0Builder](#foobarmap0builder) | additionalProperty(String key, float value) | +| [FoobarMap0Builder](#foobarmap0builder) | additionalProperty(String key, long value) | +| [FoobarMap0Builder](#foobarmap0builder) | additionalProperty(String key, double value) | +| [FoobarMap0Builder](#foobarmap0builder) | additionalProperty(String key, List value) | +| [FoobarMap0Builder](#foobarmap0builder) | additionalProperty(String key, Map value) | + +## FoobarMapBuilder +public class FoobarMapBuilder
+builder for `Map` + +A class that builds the Map input type + +### Constructor Summary +| Constructor and Description | +| --------------------------- | +| FoobarMapBuilder()
Creates a builder that contains an empty map | + +### Method Summary +| Modifier and Type | Method and Description | +| ----------------- | ---------------------- | +| [FoobarMap0Builder](#foobarmap0builder) | setFooReverseSolidusQuotationMarkBar(Void value) | +| [FoobarMap0Builder](#foobarmap0builder) | setFooReverseSolidusQuotationMarkBar(boolean value) | +| [FoobarMap0Builder](#foobarmap0builder) | setFooReverseSolidusQuotationMarkBar(String value) | +| [FoobarMap0Builder](#foobarmap0builder) | setFooReverseSolidusQuotationMarkBar(int value) | +| [FoobarMap0Builder](#foobarmap0builder) | setFooReverseSolidusQuotationMarkBar(float value) | +| [FoobarMap0Builder](#foobarmap0builder) | setFooReverseSolidusQuotationMarkBar(long value) | +| [FoobarMap0Builder](#foobarmap0builder) | setFooReverseSolidusQuotationMarkBar(double value) | +| [FoobarMap0Builder](#foobarmap0builder) | setFooReverseSolidusQuotationMarkBar(List value) | +| [FoobarMap0Builder](#foobarmap0builder) | setFooReverseSolidusQuotationMarkBar(Map value) | + +## FoobarMap +public static class FoobarMap
+extends FrozenMap + +A class to store validated Map payloads + +### Method Summary +| Modifier and Type | Method and Description | +| ----------------- | ---------------------- | +| static [FoobarMap](#foobarmap) | of([Map](#foobarmapbuilder) arg, SchemaConfiguration configuration) | +| @Nullable Object | get(String key)
This schema has invalid Java names so this method must be used when you access instance["foo\"bar"], | +| @Nullable Object | getAdditionalProperty(String name)
provides type safety for additional properties | + +## Footbar +public static class Footbar
+extends JsonSchema + +A schema class that validates payloads + +### Field Summary +| Modifier and Type | Field and Description | +| ----------------- | ---------------------- | +| Integer | minProperties = 4 | + +### Method Summary +| Modifier and Type | Method and Description | +| ----------------- | ---------------------- | +| String | validate(String arg, SchemaConfiguration configuration) | +| Void | validate(Void arg, SchemaConfiguration configuration) | +| int | validate(int arg, SchemaConfiguration configuration) | +| long | validate(long arg, SchemaConfiguration configuration) | +| float | validate(float arg, SchemaConfiguration configuration) | +| double | validate(double arg, SchemaConfiguration configuration) | +| boolean | validate(boolean arg, SchemaConfiguration configuration) | +| FrozenMap | validate(Map<?, ?> arg, SchemaConfiguration configuration) | +| FrozenList<@Nullable Object> | validate(List arg, SchemaConfiguration configuration) | +| @Nullable Object | validate(@Nullable Object arg, SchemaConfiguration configuration) | +[[Back to top]](#top) [[Back to Component Schemas]](../../../README.md#Component-Schemas) [[Back to README]](../../../README.md) diff --git a/samples/client/3_1_0_unit_test/java/docs/components/schemas/DependentSchemasDependentSubschemaIncompatibleWithRoot.md b/samples/client/3_1_0_unit_test/java/docs/components/schemas/DependentSchemasDependentSubschemaIncompatibleWithRoot.md new file mode 100644 index 00000000000..140be057a38 --- /dev/null +++ b/samples/client/3_1_0_unit_test/java/docs/components/schemas/DependentSchemasDependentSubschemaIncompatibleWithRoot.md @@ -0,0 +1,204 @@ +# DependentSchemasDependentSubschemaIncompatibleWithRoot +org.openapijsonschematools.client.components.schemas.DependentSchemasDependentSubschemaIncompatibleWithRoot.java +public class DependentSchemasDependentSubschemaIncompatibleWithRoot + +A class that contains necessary nested +- schema classes (which validate payloads), extends JsonSchema +- classes to store validated map payloads, extends FrozenMap +- classes to build inputs for map payloads + +## Nested Class Summary +| Modifier and Type | Class and Description | +| ----------------- | ---------------------- | +| static class | [DependentSchemasDependentSubschemaIncompatibleWithRoot.DependentSchemasDependentSubschemaIncompatibleWithRoot1](#dependentschemasdependentsubschemaincompatiblewithroot1)
schema class | +| static class | [DependentSchemasDependentSubschemaIncompatibleWithRoot.DependentSchemasDependentSubschemaIncompatibleWithRootMapBuilder](#dependentschemasdependentsubschemaincompatiblewithrootmapbuilder)
builder for Map payloads | +| static class | [DependentSchemasDependentSubschemaIncompatibleWithRoot.DependentSchemasDependentSubschemaIncompatibleWithRootMap](#dependentschemasdependentsubschemaincompatiblewithrootmap)
output class for Map payloads | +| static class | [DependentSchemasDependentSubschemaIncompatibleWithRoot.Foo](#foo)
schema class | +| static class | [DependentSchemasDependentSubschemaIncompatibleWithRoot.Foo1](#foo1)
schema class | +| static class | [DependentSchemasDependentSubschemaIncompatibleWithRoot.FooMapBuilder1](#foomapbuilder1)
builder for Map payloads | +| static class | [DependentSchemasDependentSubschemaIncompatibleWithRoot.FooMap](#foomap)
output class for Map payloads | +| static class | [DependentSchemasDependentSubschemaIncompatibleWithRoot.Bar](#bar)
schema class | +| static class | [DependentSchemasDependentSubschemaIncompatibleWithRoot.AdditionalProperties](#additionalproperties)
schema class | + +## DependentSchemasDependentSubschemaIncompatibleWithRoot1 +public static class DependentSchemasDependentSubschemaIncompatibleWithRoot1
+extends JsonSchema + +A schema class that validates payloads + +### Field Summary +| Modifier and Type | Field and Description | +| ----------------- | ---------------------- | +| Map> | properties = Map.ofEntries(
    new PropertyEntry("foo", [Foo.class](#foo)))
)
| +| Map> | dependentSchemas = Map.ofEntries(
    new PropertyEntry("foo", [Foo1.class](#foo1)))
)
| + +### Method Summary +| Modifier and Type | Method and Description | +| ----------------- | ---------------------- | +| String | validate(String arg, SchemaConfiguration configuration) | +| Void | validate(Void arg, SchemaConfiguration configuration) | +| int | validate(int arg, SchemaConfiguration configuration) | +| long | validate(long arg, SchemaConfiguration configuration) | +| float | validate(float arg, SchemaConfiguration configuration) | +| double | validate(double arg, SchemaConfiguration configuration) | +| boolean | validate(boolean arg, SchemaConfiguration configuration) | +| [DependentSchemasDependentSubschemaIncompatibleWithRootMap](#dependentschemasdependentsubschemaincompatiblewithrootmap) | validate([Map<?, ?>](#dependentschemasdependentsubschemaincompatiblewithrootmapbuilder) arg, SchemaConfiguration configuration) | +| FrozenList<@Nullable Object> | validate(List arg, SchemaConfiguration configuration) | +| @Nullable Object | validate(@Nullable Object arg, SchemaConfiguration configuration) | +## DependentSchemasDependentSubschemaIncompatibleWithRootMapBuilder +public class DependentSchemasDependentSubschemaIncompatibleWithRootMapBuilder
+builder for `Map` + +A class that builds the Map input type + +### Constructor Summary +| Constructor and Description | +| --------------------------- | +| DependentSchemasDependentSubschemaIncompatibleWithRootMapBuilder()
Creates a builder that contains an empty map | + +### Method Summary +| Modifier and Type | Method and Description | +| ----------------- | ---------------------- | +| Map | build()
Returns map input that should be used with Schema.validate | +| [DependentSchemasDependentSubschemaIncompatibleWithRootMapBuilder](#dependentschemasdependentsubschemaincompatiblewithrootmapbuilder) | foo(Void value) | +| [DependentSchemasDependentSubschemaIncompatibleWithRootMapBuilder](#dependentschemasdependentsubschemaincompatiblewithrootmapbuilder) | foo(boolean value) | +| [DependentSchemasDependentSubschemaIncompatibleWithRootMapBuilder](#dependentschemasdependentsubschemaincompatiblewithrootmapbuilder) | foo(String value) | +| [DependentSchemasDependentSubschemaIncompatibleWithRootMapBuilder](#dependentschemasdependentsubschemaincompatiblewithrootmapbuilder) | foo(int value) | +| [DependentSchemasDependentSubschemaIncompatibleWithRootMapBuilder](#dependentschemasdependentsubschemaincompatiblewithrootmapbuilder) | foo(float value) | +| [DependentSchemasDependentSubschemaIncompatibleWithRootMapBuilder](#dependentschemasdependentsubschemaincompatiblewithrootmapbuilder) | foo(long value) | +| [DependentSchemasDependentSubschemaIncompatibleWithRootMapBuilder](#dependentschemasdependentsubschemaincompatiblewithrootmapbuilder) | foo(double value) | +| [DependentSchemasDependentSubschemaIncompatibleWithRootMapBuilder](#dependentschemasdependentsubschemaincompatiblewithrootmapbuilder) | foo(List value) | +| [DependentSchemasDependentSubschemaIncompatibleWithRootMapBuilder](#dependentschemasdependentsubschemaincompatiblewithrootmapbuilder) | foo(Map value) | +| [DependentSchemasDependentSubschemaIncompatibleWithRootMapBuilder](#dependentschemasdependentsubschemaincompatiblewithrootmapbuilder) | additionalProperty(String key, Void value) | +| [DependentSchemasDependentSubschemaIncompatibleWithRootMapBuilder](#dependentschemasdependentsubschemaincompatiblewithrootmapbuilder) | additionalProperty(String key, boolean value) | +| [DependentSchemasDependentSubschemaIncompatibleWithRootMapBuilder](#dependentschemasdependentsubschemaincompatiblewithrootmapbuilder) | additionalProperty(String key, String value) | +| [DependentSchemasDependentSubschemaIncompatibleWithRootMapBuilder](#dependentschemasdependentsubschemaincompatiblewithrootmapbuilder) | additionalProperty(String key, int value) | +| [DependentSchemasDependentSubschemaIncompatibleWithRootMapBuilder](#dependentschemasdependentsubschemaincompatiblewithrootmapbuilder) | additionalProperty(String key, float value) | +| [DependentSchemasDependentSubschemaIncompatibleWithRootMapBuilder](#dependentschemasdependentsubschemaincompatiblewithrootmapbuilder) | additionalProperty(String key, long value) | +| [DependentSchemasDependentSubschemaIncompatibleWithRootMapBuilder](#dependentschemasdependentsubschemaincompatiblewithrootmapbuilder) | additionalProperty(String key, double value) | +| [DependentSchemasDependentSubschemaIncompatibleWithRootMapBuilder](#dependentschemasdependentsubschemaincompatiblewithrootmapbuilder) | additionalProperty(String key, List value) | +| [DependentSchemasDependentSubschemaIncompatibleWithRootMapBuilder](#dependentschemasdependentsubschemaincompatiblewithrootmapbuilder) | additionalProperty(String key, Map value) | + +## DependentSchemasDependentSubschemaIncompatibleWithRootMap +public static class DependentSchemasDependentSubschemaIncompatibleWithRootMap
+extends FrozenMap + +A class to store validated Map payloads + +### Method Summary +| Modifier and Type | Method and Description | +| ----------------- | ---------------------- | +| static [DependentSchemasDependentSubschemaIncompatibleWithRootMap](#dependentschemasdependentsubschemaincompatiblewithrootmap) | of([Map](#dependentschemasdependentsubschemaincompatiblewithrootmapbuilder) arg, SchemaConfiguration configuration) | +| @Nullable Object | foo()
[optional] | +| @Nullable Object | getAdditionalProperty(String name)
provides type safety for additional properties | + +## Foo +public static class Foo
+extends AnyTypeJsonSchema + +A schema class that validates payloads + +| Methods Inherited from class org.openapijsonschematools.client.schemas.AnyTypeJsonSchema | +| ------------------------------------------------------------------ | +| validate | + +## Foo1 +public static class Foo1
+extends JsonSchema + +A schema class that validates payloads + +### Code Sample +``` +import org.openapijsonschematools.client.configurations.JsonSchemaKeywordFlags; +import org.openapijsonschematools.client.configurations.SchemaConfiguration; +import org.openapijsonschematools.client.exceptions.ValidationException; +import org.openapijsonschematools.client.schemas.validation.MapUtils; +import org.openapijsonschematools.client.schemas.validation.FrozenList; +import org.openapijsonschematools.client.schemas.validation.FrozenMap; + +import java.util.Arrays; +import java.util.List; +import java.util.AbstractMap; + +static final SchemaConfiguration configuration = new SchemaConfiguration(JsonSchemaKeywordFlags.ofNone()); + +// Map validation +DependentSchemasDependentSubschemaIncompatibleWithRoot.FooMap validatedPayload = + DependentSchemasDependentSubschemaIncompatibleWithRoot.Foo1.validate( + new DependentSchemasDependentSubschemaIncompatibleWithRoot.FooMapBuilder1() + .build(), + configuration +); +``` + +### Field Summary +| Modifier and Type | Field and Description | +| ----------------- | ---------------------- | +| Set> | type = Set.of(Map.class) | +| Map> | properties = Map.ofEntries(
    new PropertyEntry("bar", [Bar.class](#bar)))
)
| +| Class | additionalProperties = [AdditionalProperties.class](#additionalproperties) | + +### Method Summary +| Modifier and Type | Method and Description | +| ----------------- | ---------------------- | +| [FooMap](#foomap) | validate([Map<?, ?>](#foomapbuilder1) arg, SchemaConfiguration configuration) | +| @Nullable Object | validate(@Nullable Object arg, SchemaConfiguration configuration) | +## FooMapBuilder1 +public class FooMapBuilder1
+builder for `Map` + +A class that builds the Map input type + +### Constructor Summary +| Constructor and Description | +| --------------------------- | +| FooMapBuilder1()
Creates a builder that contains an empty map | + +### Method Summary +| Modifier and Type | Method and Description | +| ----------------- | ---------------------- | +| Map | build()
Returns map input that should be used with Schema.validate | +| [FooMapBuilder1](#foomapbuilder1) | bar(Void value) | +| [FooMapBuilder1](#foomapbuilder1) | bar(boolean value) | +| [FooMapBuilder1](#foomapbuilder1) | bar(String value) | +| [FooMapBuilder1](#foomapbuilder1) | bar(int value) | +| [FooMapBuilder1](#foomapbuilder1) | bar(float value) | +| [FooMapBuilder1](#foomapbuilder1) | bar(long value) | +| [FooMapBuilder1](#foomapbuilder1) | bar(double value) | +| [FooMapBuilder1](#foomapbuilder1) | bar(List value) | +| [FooMapBuilder1](#foomapbuilder1) | bar(Map value) | + +## FooMap +public static class FooMap
+extends FrozenMap + +A class to store validated Map payloads + +### Method Summary +| Modifier and Type | Method and Description | +| ----------------- | ---------------------- | +| static [FooMap](#foomap) | of([Map](#foomapbuilder1) arg, SchemaConfiguration configuration) | +| @Nullable Object | bar()
[optional] | + +## Bar +public static class Bar
+extends AnyTypeJsonSchema + +A schema class that validates payloads + +| Methods Inherited from class org.openapijsonschematools.client.schemas.AnyTypeJsonSchema | +| ------------------------------------------------------------------ | +| validate | + +## AdditionalProperties +public static class AdditionalProperties
+extends NotAnyTypeJsonSchema + +A schema class that validates payloads + +| Methods Inherited from class org.openapijsonschematools.client.schemas.NotAnyTypeJsonSchema | +| ------------------------------------------------------------------ | +| validate | + +[[Back to top]](#top) [[Back to Component Schemas]](../../../README.md#Component-Schemas) [[Back to README]](../../../README.md) diff --git a/samples/client/3_1_0_unit_test/java/docs/components/schemas/DependentSchemasSingleDependency.md b/samples/client/3_1_0_unit_test/java/docs/components/schemas/DependentSchemasSingleDependency.md new file mode 100644 index 00000000000..73245186811 --- /dev/null +++ b/samples/client/3_1_0_unit_test/java/docs/components/schemas/DependentSchemasSingleDependency.md @@ -0,0 +1,135 @@ +# DependentSchemasSingleDependency +org.openapijsonschematools.client.components.schemas.DependentSchemasSingleDependency.java +public class DependentSchemasSingleDependency + +A class that contains necessary nested +- schema classes (which validate payloads), extends JsonSchema +- classes to store validated map payloads, extends FrozenMap +- classes to build inputs for map payloads + +## Nested Class Summary +| Modifier and Type | Class and Description | +| ----------------- | ---------------------- | +| static class | [DependentSchemasSingleDependency.DependentSchemasSingleDependency1](#dependentschemassingledependency1)
schema class | +| static class | [DependentSchemasSingleDependency.Bar](#bar)
schema class | +| static class | [DependentSchemasSingleDependency.BarMapBuilder1](#barmapbuilder1)
builder for Map payloads | +| static class | [DependentSchemasSingleDependency.BarMap](#barmap)
output class for Map payloads | +| static class | [DependentSchemasSingleDependency.Bar1](#bar1)
schema class | +| static class | [DependentSchemasSingleDependency.Foo](#foo)
schema class | + +## DependentSchemasSingleDependency1 +public static class DependentSchemasSingleDependency1
+extends JsonSchema + +A schema class that validates payloads + +### Field Summary +| Modifier and Type | Field and Description | +| ----------------- | ---------------------- | +| Map> | dependentSchemas = Map.ofEntries(
    new PropertyEntry("bar", [Bar.class](#bar)))
)
| + +### Method Summary +| Modifier and Type | Method and Description | +| ----------------- | ---------------------- | +| String | validate(String arg, SchemaConfiguration configuration) | +| Void | validate(Void arg, SchemaConfiguration configuration) | +| int | validate(int arg, SchemaConfiguration configuration) | +| long | validate(long arg, SchemaConfiguration configuration) | +| float | validate(float arg, SchemaConfiguration configuration) | +| double | validate(double arg, SchemaConfiguration configuration) | +| boolean | validate(boolean arg, SchemaConfiguration configuration) | +| FrozenMap | validate(Map<?, ?> arg, SchemaConfiguration configuration) | +| FrozenList<@Nullable Object> | validate(List arg, SchemaConfiguration configuration) | +| @Nullable Object | validate(@Nullable Object arg, SchemaConfiguration configuration) | +## Bar +public static class Bar
+extends JsonSchema + +A schema class that validates payloads + +### Field Summary +| Modifier and Type | Field and Description | +| ----------------- | ---------------------- | +| Map> | properties = Map.ofEntries(
    new PropertyEntry("foo", [Foo.class](#foo))),
    new PropertyEntry("bar", [Bar1.class](#bar1)))
)
| + +### Method Summary +| Modifier and Type | Method and Description | +| ----------------- | ---------------------- | +| String | validate(String arg, SchemaConfiguration configuration) | +| Void | validate(Void arg, SchemaConfiguration configuration) | +| int | validate(int arg, SchemaConfiguration configuration) | +| long | validate(long arg, SchemaConfiguration configuration) | +| float | validate(float arg, SchemaConfiguration configuration) | +| double | validate(double arg, SchemaConfiguration configuration) | +| boolean | validate(boolean arg, SchemaConfiguration configuration) | +| [BarMap](#barmap) | validate([Map<?, ?>](#barmapbuilder1) arg, SchemaConfiguration configuration) | +| FrozenList<@Nullable Object> | validate(List arg, SchemaConfiguration configuration) | +| @Nullable Object | validate(@Nullable Object arg, SchemaConfiguration configuration) | +## BarMapBuilder1 +public class BarMapBuilder1
+builder for `Map` + +A class that builds the Map input type + +### Constructor Summary +| Constructor and Description | +| --------------------------- | +| BarMapBuilder1()
Creates a builder that contains an empty map | + +### Method Summary +| Modifier and Type | Method and Description | +| ----------------- | ---------------------- | +| Map | build()
Returns map input that should be used with Schema.validate | +| [BarMapBuilder1](#barmapbuilder1) | foo(int value) | +| [BarMapBuilder1](#barmapbuilder1) | foo(float value) | +| [BarMapBuilder1](#barmapbuilder1) | foo(long value) | +| [BarMapBuilder1](#barmapbuilder1) | foo(double value) | +| [BarMapBuilder1](#barmapbuilder1) | bar(int value) | +| [BarMapBuilder1](#barmapbuilder1) | bar(float value) | +| [BarMapBuilder1](#barmapbuilder1) | bar(long value) | +| [BarMapBuilder1](#barmapbuilder1) | bar(double value) | +| [BarMapBuilder1](#barmapbuilder1) | additionalProperty(String key, Void value) | +| [BarMapBuilder1](#barmapbuilder1) | additionalProperty(String key, boolean value) | +| [BarMapBuilder1](#barmapbuilder1) | additionalProperty(String key, String value) | +| [BarMapBuilder1](#barmapbuilder1) | additionalProperty(String key, int value) | +| [BarMapBuilder1](#barmapbuilder1) | additionalProperty(String key, float value) | +| [BarMapBuilder1](#barmapbuilder1) | additionalProperty(String key, long value) | +| [BarMapBuilder1](#barmapbuilder1) | additionalProperty(String key, double value) | +| [BarMapBuilder1](#barmapbuilder1) | additionalProperty(String key, List value) | +| [BarMapBuilder1](#barmapbuilder1) | additionalProperty(String key, Map value) | + +## BarMap +public static class BarMap
+extends FrozenMap + +A class to store validated Map payloads + +### Method Summary +| Modifier and Type | Method and Description | +| ----------------- | ---------------------- | +| static [BarMap](#barmap) | of([Map](#barmapbuilder1) arg, SchemaConfiguration configuration) | +| Number | foo()
[optional] | +| Number | bar()
[optional] | +| @Nullable Object | getAdditionalProperty(String name)
provides type safety for additional properties | + +## Bar1 +public static class Bar1
+extends IntJsonSchema + +A schema class that validates payloads + +| Methods Inherited from class org.openapijsonschematools.client.schemas.IntJsonSchema | +| ------------------------------------------------------------------ | +| validate | + +## Foo +public static class Foo
+extends IntJsonSchema + +A schema class that validates payloads + +| Methods Inherited from class org.openapijsonschematools.client.schemas.IntJsonSchema | +| ------------------------------------------------------------------ | +| validate | + +[[Back to top]](#top) [[Back to Component Schemas]](../../../README.md#Component-Schemas) [[Back to README]](../../../README.md) diff --git a/samples/client/3_1_0_unit_test/java/docs/components/schemas/MultipleDependentsRequired.md b/samples/client/3_1_0_unit_test/java/docs/components/schemas/MultipleDependentsRequired.md new file mode 100644 index 00000000000..0c9736b146d --- /dev/null +++ b/samples/client/3_1_0_unit_test/java/docs/components/schemas/MultipleDependentsRequired.md @@ -0,0 +1,46 @@ +# MultipleDependentsRequired +org.openapijsonschematools.client.components.schemas.MultipleDependentsRequired.java +public class MultipleDependentsRequired + +A class that contains necessary nested +- schema classes (which validate payloads), extends JsonSchema + +## Nested Class Summary +| Modifier and Type | Class and Description | +| ----------------- | ---------------------- | +| static class | [MultipleDependentsRequired.MultipleDependentsRequired1](#multipledependentsrequired1)
schema class | + +## MultipleDependentsRequired1 +public static class MultipleDependentsRequired1
+extends JsonSchema + +A schema class that validates payloads + +### Field Summary +| Modifier and Type | Field and Description | +| ----------------- | ---------------------- | +| Map> | dependentRequired = MapUtils.makeMap(
+    new AbstractMap.SimpleEntry<>(
+        "quux",
+        SetMaker.makeSet( +            "foo",
+            "bar"
+        ) +    )
+) + | + +### Method Summary +| Modifier and Type | Method and Description | +| ----------------- | ---------------------- | +| String | validate(String arg, SchemaConfiguration configuration) | +| Void | validate(Void arg, SchemaConfiguration configuration) | +| int | validate(int arg, SchemaConfiguration configuration) | +| long | validate(long arg, SchemaConfiguration configuration) | +| float | validate(float arg, SchemaConfiguration configuration) | +| double | validate(double arg, SchemaConfiguration configuration) | +| boolean | validate(boolean arg, SchemaConfiguration configuration) | +| FrozenMap | validate(Map<?, ?> arg, SchemaConfiguration configuration) | +| FrozenList<@Nullable Object> | validate(List arg, SchemaConfiguration configuration) | +| @Nullable Object | validate(@Nullable Object arg, SchemaConfiguration configuration) | +[[Back to top]](#top) [[Back to Component Schemas]](../../../README.md#Component-Schemas) [[Back to README]](../../../README.md) diff --git a/samples/client/3_1_0_unit_test/java/docs/components/schemas/SingleDependency.md b/samples/client/3_1_0_unit_test/java/docs/components/schemas/SingleDependency.md new file mode 100644 index 00000000000..77b57e1eff4 --- /dev/null +++ b/samples/client/3_1_0_unit_test/java/docs/components/schemas/SingleDependency.md @@ -0,0 +1,45 @@ +# SingleDependency +org.openapijsonschematools.client.components.schemas.SingleDependency.java +public class SingleDependency + +A class that contains necessary nested +- schema classes (which validate payloads), extends JsonSchema + +## Nested Class Summary +| Modifier and Type | Class and Description | +| ----------------- | ---------------------- | +| static class | [SingleDependency.SingleDependency1](#singledependency1)
schema class | + +## SingleDependency1 +public static class SingleDependency1
+extends JsonSchema + +A schema class that validates payloads + +### Field Summary +| Modifier and Type | Field and Description | +| ----------------- | ---------------------- | +| Map> | dependentRequired = MapUtils.makeMap(
+    new AbstractMap.SimpleEntry<>(
+        "bar",
+        SetMaker.makeSet( +            "foo"
+        ) +    )
+) + | + +### Method Summary +| Modifier and Type | Method and Description | +| ----------------- | ---------------------- | +| String | validate(String arg, SchemaConfiguration configuration) | +| Void | validate(Void arg, SchemaConfiguration configuration) | +| int | validate(int arg, SchemaConfiguration configuration) | +| long | validate(long arg, SchemaConfiguration configuration) | +| float | validate(float arg, SchemaConfiguration configuration) | +| double | validate(double arg, SchemaConfiguration configuration) | +| boolean | validate(boolean arg, SchemaConfiguration configuration) | +| FrozenMap | validate(Map<?, ?> arg, SchemaConfiguration configuration) | +| FrozenList<@Nullable Object> | validate(List arg, SchemaConfiguration configuration) | +| @Nullable Object | validate(@Nullable Object arg, SchemaConfiguration configuration) | +[[Back to top]](#top) [[Back to Component Schemas]](../../../README.md#Component-Schemas) [[Back to README]](../../../README.md) diff --git a/samples/client/3_1_0_unit_test/java/src/main/java/org/openapijsonschematools/client/components/schemas/DependentSchemasDependenciesWithEscapedCharacters.java b/samples/client/3_1_0_unit_test/java/src/main/java/org/openapijsonschematools/client/components/schemas/DependentSchemasDependenciesWithEscapedCharacters.java new file mode 100644 index 00000000000..2376c8c24eb --- /dev/null +++ b/samples/client/3_1_0_unit_test/java/src/main/java/org/openapijsonschematools/client/components/schemas/DependentSchemasDependenciesWithEscapedCharacters.java @@ -0,0 +1,749 @@ +package org.openapijsonschematools.client.components.schemas; +import java.time.LocalDate; +import java.time.ZonedDateTime; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.LinkedHashMap; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.Set; +import java.util.UUID; +import org.checkerframework.checker.nullness.qual.Nullable; +import org.openapijsonschematools.client.configurations.JsonSchemaKeywordFlags; +import org.openapijsonschematools.client.configurations.SchemaConfiguration; +import org.openapijsonschematools.client.exceptions.InvalidAdditionalPropertyException; +import org.openapijsonschematools.client.exceptions.InvalidTypeException; +import org.openapijsonschematools.client.exceptions.UnsetPropertyException; +import org.openapijsonschematools.client.exceptions.ValidationException; +import org.openapijsonschematools.client.schemas.BaseBuilder; +import org.openapijsonschematools.client.schemas.UnsetAddPropsSetter; +import org.openapijsonschematools.client.schemas.validation.BooleanSchemaValidator; +import org.openapijsonschematools.client.schemas.validation.FrozenList; +import org.openapijsonschematools.client.schemas.validation.FrozenMap; +import org.openapijsonschematools.client.schemas.validation.JsonSchema; +import org.openapijsonschematools.client.schemas.validation.JsonSchemaInfo; +import org.openapijsonschematools.client.schemas.validation.ListSchemaValidator; +import org.openapijsonschematools.client.schemas.validation.MapSchemaValidator; +import org.openapijsonschematools.client.schemas.validation.NullSchemaValidator; +import org.openapijsonschematools.client.schemas.validation.NumberSchemaValidator; +import org.openapijsonschematools.client.schemas.validation.PathToSchemasMap; +import org.openapijsonschematools.client.schemas.validation.PropertyEntry; +import org.openapijsonschematools.client.schemas.validation.StringSchemaValidator; +import org.openapijsonschematools.client.schemas.validation.ValidationMetadata; + +public class DependentSchemasDependenciesWithEscapedCharacters { + // nest classes so all schemas and input/output classes can be public + + + public static class Footbar extends JsonSchema implements NullSchemaValidator, BooleanSchemaValidator, NumberSchemaValidator, StringSchemaValidator, ListSchemaValidator>, MapSchemaValidator> { + private static @Nullable Footbar instance = null; + + protected Footbar() { + super(new JsonSchemaInfo() + .minProperties(4) + ); + } + + public static Footbar getInstance() { + if (instance == null) { + instance = new Footbar(); + } + return instance; + } + + @Override + public Void validate(Void arg, SchemaConfiguration configuration) throws ValidationException, InvalidTypeException { + Set> pathSet = new HashSet<>(); + List pathToItem = List.of("args[0]"); + Void castArg = castToAllowedTypes(arg, pathToItem, pathSet); + SchemaConfiguration usedConfiguration = Objects.requireNonNullElseGet(configuration, () -> new SchemaConfiguration(JsonSchemaKeywordFlags.ofNone())); + PathToSchemasMap validatedPathToSchemas = new PathToSchemasMap(); + ValidationMetadata validationMetadata = new ValidationMetadata(pathToItem, usedConfiguration, validatedPathToSchemas, new LinkedHashSet<>()); + getPathToSchemas(this, castArg, validationMetadata, pathSet); + return castArg; + } + + @Override + public boolean validate(boolean arg, SchemaConfiguration configuration) throws ValidationException, InvalidTypeException { + Set> pathSet = new HashSet<>(); + List pathToItem = List.of("args[0]"); + boolean castArg = castToAllowedTypes(arg, pathToItem, pathSet); + SchemaConfiguration usedConfiguration = Objects.requireNonNullElseGet(configuration, () -> new SchemaConfiguration(JsonSchemaKeywordFlags.ofNone())); + PathToSchemasMap validatedPathToSchemas = new PathToSchemasMap(); + ValidationMetadata validationMetadata = new ValidationMetadata(pathToItem, usedConfiguration, validatedPathToSchemas, new LinkedHashSet<>()); + getPathToSchemas(this, castArg, validationMetadata, pathSet); + return castArg; + } + + @Override + public Number validate(Number arg, SchemaConfiguration configuration) throws ValidationException, InvalidTypeException { + Set> pathSet = new HashSet<>(); + List pathToItem = List.of("args[0]"); + Number castArg = castToAllowedTypes(arg, pathToItem, pathSet); + SchemaConfiguration usedConfiguration = Objects.requireNonNullElseGet(configuration, () -> new SchemaConfiguration(JsonSchemaKeywordFlags.ofNone())); + PathToSchemasMap validatedPathToSchemas = new PathToSchemasMap(); + ValidationMetadata validationMetadata = new ValidationMetadata(pathToItem, usedConfiguration, validatedPathToSchemas, new LinkedHashSet<>()); + getPathToSchemas(this, castArg, validationMetadata, pathSet); + return castArg; + } + + public int validate(int arg, SchemaConfiguration configuration) { + return (int) validate((Number) arg, configuration); + } + + public long validate(long arg, SchemaConfiguration configuration) { + return (long) validate((Number) arg, configuration); + } + + public float validate(float arg, SchemaConfiguration configuration) { + return (float) validate((Number) arg, configuration); + } + + public double validate(double arg, SchemaConfiguration configuration) { + return (double) validate((Number) arg, configuration); + } + + @Override + public String validate(String arg, SchemaConfiguration configuration) throws ValidationException, InvalidTypeException { + Set> pathSet = new HashSet<>(); + List pathToItem = List.of("args[0]"); + String castArg = castToAllowedTypes(arg, pathToItem, pathSet); + SchemaConfiguration usedConfiguration = Objects.requireNonNullElseGet(configuration, () -> new SchemaConfiguration(JsonSchemaKeywordFlags.ofNone())); + PathToSchemasMap validatedPathToSchemas = new PathToSchemasMap(); + ValidationMetadata validationMetadata = new ValidationMetadata(pathToItem, usedConfiguration, validatedPathToSchemas, new LinkedHashSet<>()); + getPathToSchemas(this, castArg, validationMetadata, pathSet); + return castArg; + } + + public String validate(LocalDate arg, SchemaConfiguration configuration) throws ValidationException { + return validate(arg.toString(), configuration); + } + + public String validate(ZonedDateTime arg, SchemaConfiguration configuration) throws ValidationException { + return validate(arg.toString(), configuration); + } + + public String validate(UUID arg, SchemaConfiguration configuration) throws ValidationException { + return validate(arg.toString(), configuration); + } + + @Override + public FrozenList<@Nullable Object> getNewInstance(List arg, List pathToItem, PathToSchemasMap pathToSchemas) { + List<@Nullable Object> items = new ArrayList<>(); + int i = 0; + for (Object item: arg) { + List itemPathToItem = new ArrayList<>(pathToItem); + itemPathToItem.add(i); + LinkedHashMap schemas = pathToSchemas.get(itemPathToItem); + if (schemas == null) { + throw new InvalidTypeException("Validation result is invalid, schemas must exist for a pathToItem"); + } + JsonSchema itemSchema = schemas.entrySet().iterator().next().getKey(); + @Nullable Object itemInstance = itemSchema.getNewInstance(item, itemPathToItem, pathToSchemas); + items.add(itemInstance); + i += 1; + } + FrozenList<@Nullable Object> newInstanceItems = new FrozenList<>(items); + return newInstanceItems; + } + + public FrozenList<@Nullable Object> validate(List arg, SchemaConfiguration configuration) throws ValidationException { + Set> pathSet = new HashSet<>(); + List pathToItem = List.of("args[0"); + List castArg = castToAllowedTypes(arg, pathToItem, pathSet); + SchemaConfiguration usedConfiguration = Objects.requireNonNullElseGet(configuration, () -> new SchemaConfiguration(JsonSchemaKeywordFlags.ofNone())); + ValidationMetadata validationMetadata = new ValidationMetadata(pathToItem, usedConfiguration, new PathToSchemasMap(), new LinkedHashSet<>()); + PathToSchemasMap pathToSchemasMap = getPathToSchemas(this, castArg, validationMetadata, pathSet); + return getNewInstance(castArg, validationMetadata.pathToItem(), pathToSchemasMap); + } + + @Override + public FrozenMap<@Nullable Object> getNewInstance(Map arg, List pathToItem, PathToSchemasMap pathToSchemas) { + LinkedHashMap properties = new LinkedHashMap<>(); + for(Map.Entry entry: arg.entrySet()) { + @Nullable Object entryKey = entry.getKey(); + if (!(entryKey instanceof String)) { + throw new InvalidTypeException("Invalid non-string key value"); + } + String propertyName = (String) entryKey; + List propertyPathToItem = new ArrayList<>(pathToItem); + propertyPathToItem.add(propertyName); + Object value = entry.getValue(); + LinkedHashMap schemas = pathToSchemas.get(propertyPathToItem); + if (schemas == null) { + throw new InvalidTypeException("Validation result is invalid, schemas must exist for a pathToItem"); + } + JsonSchema propertySchema = schemas.entrySet().iterator().next().getKey(); + @Nullable Object propertyInstance = propertySchema.getNewInstance(value, propertyPathToItem, pathToSchemas); + properties.put(propertyName, propertyInstance); + } + FrozenMap<@Nullable Object> castProperties = new FrozenMap<>(properties); + return castProperties; + } + + public FrozenMap<@Nullable Object> validate(Map arg, SchemaConfiguration configuration) throws ValidationException, InvalidTypeException { + Set> pathSet = new HashSet<>(); + List pathToItem = List.of("args[0]"); + Map castArg = castToAllowedTypes(arg, pathToItem, pathSet); + SchemaConfiguration usedConfiguration = Objects.requireNonNullElseGet(configuration, () -> new SchemaConfiguration(JsonSchemaKeywordFlags.ofNone())); + PathToSchemasMap validatedPathToSchemas = new PathToSchemasMap(); + ValidationMetadata validationMetadata = new ValidationMetadata(pathToItem, usedConfiguration, validatedPathToSchemas, new LinkedHashSet<>()); + PathToSchemasMap pathToSchemasMap = getPathToSchemas(this, castArg, validationMetadata, pathSet); + return getNewInstance(castArg, validationMetadata.pathToItem(), pathToSchemasMap); + } + + @Override + public @Nullable Object validate(@Nullable Object arg, SchemaConfiguration configuration) throws ValidationException, InvalidTypeException { + if (arg == null) { + return validate((Void) null, configuration); + } else if (arg instanceof Boolean) { + boolean boolArg = (Boolean) arg; + return validate(boolArg, configuration); + } else if (arg instanceof Number) { + return validate((Number) arg, configuration); + } else if (arg instanceof String) { + return validate((String) arg, configuration); + } else if (arg instanceof List) { + return validate((List) arg, configuration); + } else if (arg instanceof Map) { + return validate((Map) arg, configuration); + } + throw new InvalidTypeException("Invalid input type="+getClass(arg)+". It can't be validated by this schema"); + } + @Override + public @Nullable Object getNewInstance(@Nullable Object arg, List pathToItem, PathToSchemasMap pathToSchemas) throws InvalidTypeException { + if (arg == null) { + return getNewInstance((Void) null, pathToItem, pathToSchemas); + } else if (arg instanceof Boolean) { + boolean boolArg = (Boolean) arg; + return getNewInstance(boolArg, pathToItem, pathToSchemas); + } else if (arg instanceof Number) { + return getNewInstance((Number) arg, pathToItem, pathToSchemas); + } else if (arg instanceof String) { + return getNewInstance((String) arg, pathToItem, pathToSchemas); + } else if (arg instanceof List) { + return getNewInstance((List) arg, pathToItem, pathToSchemas); + } else if (arg instanceof Map) { + return getNewInstance((Map) arg, pathToItem, pathToSchemas); + } + throw new InvalidTypeException("Invalid input type="+getClass(arg)+". It can't be instantiated by this schema"); + } + } + + public static class FoobarMap extends FrozenMap<@Nullable Object> { + protected FoobarMap(FrozenMap<@Nullable Object> m) { + super(m); + } + public static final Set requiredKeys = Set.of( + "foo\"bar" + ); + public static final Set optionalKeys = Set.of(); + public static FoobarMap of(Map arg, SchemaConfiguration configuration) throws ValidationException { + return Foobar.getInstance().validate(arg, configuration); + } + + public @Nullable Object getAdditionalProperty(String name) throws UnsetPropertyException, InvalidAdditionalPropertyException { + throwIfKeyKnown(name, requiredKeys, optionalKeys); + throwIfKeyNotPresent(name); + return get(name); + } + } + + public interface SetterForFoobar1 { + Map getInstance(); + T getBuilderAfterFoobar1(Map instance); + + default T setFooReverseSolidusQuotationMarkBar(Void value) { + var instance = getInstance(); + instance.put("foo\"bar", null); + return getBuilderAfterFoobar1(instance); + } + + default T setFooReverseSolidusQuotationMarkBar(boolean value) { + var instance = getInstance(); + instance.put("foo\"bar", value); + return getBuilderAfterFoobar1(instance); + } + + default T setFooReverseSolidusQuotationMarkBar(String value) { + var instance = getInstance(); + instance.put("foo\"bar", value); + return getBuilderAfterFoobar1(instance); + } + + default T setFooReverseSolidusQuotationMarkBar(int value) { + var instance = getInstance(); + instance.put("foo\"bar", value); + return getBuilderAfterFoobar1(instance); + } + + default T setFooReverseSolidusQuotationMarkBar(float value) { + var instance = getInstance(); + instance.put("foo\"bar", value); + return getBuilderAfterFoobar1(instance); + } + + default T setFooReverseSolidusQuotationMarkBar(long value) { + var instance = getInstance(); + instance.put("foo\"bar", value); + return getBuilderAfterFoobar1(instance); + } + + default T setFooReverseSolidusQuotationMarkBar(double value) { + var instance = getInstance(); + instance.put("foo\"bar", value); + return getBuilderAfterFoobar1(instance); + } + + default T setFooReverseSolidusQuotationMarkBar(List value) { + var instance = getInstance(); + instance.put("foo\"bar", value); + return getBuilderAfterFoobar1(instance); + } + + default T setFooReverseSolidusQuotationMarkBar(Map value) { + var instance = getInstance(); + instance.put("foo\"bar", value); + return getBuilderAfterFoobar1(instance); + } + } + + public static class FoobarMap0Builder extends UnsetAddPropsSetter implements BaseBuilder<@Nullable Object> { + private final Map instance; + private static final Set knownKeys = Set.of( + "foo\"bar" + ); + public Set getKnownKeys() { + return knownKeys; + } + public FoobarMap0Builder(Map instance) { + this.instance = instance; + } + public Map build() { + return instance; + } + public Map getInstance() { + return instance; + } + public FoobarMap0Builder getBuilderAfterAdditionalProperty(Map instance) { + return this; + } + } + + public static class FoobarMapBuilder implements SetterForFoobar1 { + private final Map instance; + public FoobarMapBuilder() { + this.instance = new LinkedHashMap<>(); + } + public Map getInstance() { + return instance; + } + public FoobarMap0Builder getBuilderAfterFoobar1(Map instance) { + return new FoobarMap0Builder(instance); + } + } + + + public static class Foobar extends JsonSchema implements NullSchemaValidator, BooleanSchemaValidator, NumberSchemaValidator, StringSchemaValidator, ListSchemaValidator>, MapSchemaValidator { + private static @Nullable Foobar instance = null; + + protected Foobar() { + super(new JsonSchemaInfo() + .required(Set.of( + "foo\"bar" + )) + ); + } + + public static Foobar getInstance() { + if (instance == null) { + instance = new Foobar(); + } + return instance; + } + + @Override + public Void validate(Void arg, SchemaConfiguration configuration) throws ValidationException, InvalidTypeException { + Set> pathSet = new HashSet<>(); + List pathToItem = List.of("args[0]"); + Void castArg = castToAllowedTypes(arg, pathToItem, pathSet); + SchemaConfiguration usedConfiguration = Objects.requireNonNullElseGet(configuration, () -> new SchemaConfiguration(JsonSchemaKeywordFlags.ofNone())); + PathToSchemasMap validatedPathToSchemas = new PathToSchemasMap(); + ValidationMetadata validationMetadata = new ValidationMetadata(pathToItem, usedConfiguration, validatedPathToSchemas, new LinkedHashSet<>()); + getPathToSchemas(this, castArg, validationMetadata, pathSet); + return castArg; + } + + @Override + public boolean validate(boolean arg, SchemaConfiguration configuration) throws ValidationException, InvalidTypeException { + Set> pathSet = new HashSet<>(); + List pathToItem = List.of("args[0]"); + boolean castArg = castToAllowedTypes(arg, pathToItem, pathSet); + SchemaConfiguration usedConfiguration = Objects.requireNonNullElseGet(configuration, () -> new SchemaConfiguration(JsonSchemaKeywordFlags.ofNone())); + PathToSchemasMap validatedPathToSchemas = new PathToSchemasMap(); + ValidationMetadata validationMetadata = new ValidationMetadata(pathToItem, usedConfiguration, validatedPathToSchemas, new LinkedHashSet<>()); + getPathToSchemas(this, castArg, validationMetadata, pathSet); + return castArg; + } + + @Override + public Number validate(Number arg, SchemaConfiguration configuration) throws ValidationException, InvalidTypeException { + Set> pathSet = new HashSet<>(); + List pathToItem = List.of("args[0]"); + Number castArg = castToAllowedTypes(arg, pathToItem, pathSet); + SchemaConfiguration usedConfiguration = Objects.requireNonNullElseGet(configuration, () -> new SchemaConfiguration(JsonSchemaKeywordFlags.ofNone())); + PathToSchemasMap validatedPathToSchemas = new PathToSchemasMap(); + ValidationMetadata validationMetadata = new ValidationMetadata(pathToItem, usedConfiguration, validatedPathToSchemas, new LinkedHashSet<>()); + getPathToSchemas(this, castArg, validationMetadata, pathSet); + return castArg; + } + + public int validate(int arg, SchemaConfiguration configuration) { + return (int) validate((Number) arg, configuration); + } + + public long validate(long arg, SchemaConfiguration configuration) { + return (long) validate((Number) arg, configuration); + } + + public float validate(float arg, SchemaConfiguration configuration) { + return (float) validate((Number) arg, configuration); + } + + public double validate(double arg, SchemaConfiguration configuration) { + return (double) validate((Number) arg, configuration); + } + + @Override + public String validate(String arg, SchemaConfiguration configuration) throws ValidationException, InvalidTypeException { + Set> pathSet = new HashSet<>(); + List pathToItem = List.of("args[0]"); + String castArg = castToAllowedTypes(arg, pathToItem, pathSet); + SchemaConfiguration usedConfiguration = Objects.requireNonNullElseGet(configuration, () -> new SchemaConfiguration(JsonSchemaKeywordFlags.ofNone())); + PathToSchemasMap validatedPathToSchemas = new PathToSchemasMap(); + ValidationMetadata validationMetadata = new ValidationMetadata(pathToItem, usedConfiguration, validatedPathToSchemas, new LinkedHashSet<>()); + getPathToSchemas(this, castArg, validationMetadata, pathSet); + return castArg; + } + + public String validate(LocalDate arg, SchemaConfiguration configuration) throws ValidationException { + return validate(arg.toString(), configuration); + } + + public String validate(ZonedDateTime arg, SchemaConfiguration configuration) throws ValidationException { + return validate(arg.toString(), configuration); + } + + public String validate(UUID arg, SchemaConfiguration configuration) throws ValidationException { + return validate(arg.toString(), configuration); + } + + @Override + public FrozenList<@Nullable Object> getNewInstance(List arg, List pathToItem, PathToSchemasMap pathToSchemas) { + List<@Nullable Object> items = new ArrayList<>(); + int i = 0; + for (Object item: arg) { + List itemPathToItem = new ArrayList<>(pathToItem); + itemPathToItem.add(i); + LinkedHashMap schemas = pathToSchemas.get(itemPathToItem); + if (schemas == null) { + throw new InvalidTypeException("Validation result is invalid, schemas must exist for a pathToItem"); + } + JsonSchema itemSchema = schemas.entrySet().iterator().next().getKey(); + @Nullable Object itemInstance = itemSchema.getNewInstance(item, itemPathToItem, pathToSchemas); + items.add(itemInstance); + i += 1; + } + FrozenList<@Nullable Object> newInstanceItems = new FrozenList<>(items); + return newInstanceItems; + } + + public FrozenList<@Nullable Object> validate(List arg, SchemaConfiguration configuration) throws ValidationException { + Set> pathSet = new HashSet<>(); + List pathToItem = List.of("args[0"); + List castArg = castToAllowedTypes(arg, pathToItem, pathSet); + SchemaConfiguration usedConfiguration = Objects.requireNonNullElseGet(configuration, () -> new SchemaConfiguration(JsonSchemaKeywordFlags.ofNone())); + ValidationMetadata validationMetadata = new ValidationMetadata(pathToItem, usedConfiguration, new PathToSchemasMap(), new LinkedHashSet<>()); + PathToSchemasMap pathToSchemasMap = getPathToSchemas(this, castArg, validationMetadata, pathSet); + return getNewInstance(castArg, validationMetadata.pathToItem(), pathToSchemasMap); + } + + @Override + public FoobarMap getNewInstance(Map arg, List pathToItem, PathToSchemasMap pathToSchemas) { + LinkedHashMap properties = new LinkedHashMap<>(); + for(Map.Entry entry: arg.entrySet()) { + @Nullable Object entryKey = entry.getKey(); + if (!(entryKey instanceof String)) { + throw new InvalidTypeException("Invalid non-string key value"); + } + String propertyName = (String) entryKey; + List propertyPathToItem = new ArrayList<>(pathToItem); + propertyPathToItem.add(propertyName); + Object value = entry.getValue(); + LinkedHashMap schemas = pathToSchemas.get(propertyPathToItem); + if (schemas == null) { + throw new InvalidTypeException("Validation result is invalid, schemas must exist for a pathToItem"); + } + JsonSchema propertySchema = schemas.entrySet().iterator().next().getKey(); + @Nullable Object propertyInstance = propertySchema.getNewInstance(value, propertyPathToItem, pathToSchemas); + properties.put(propertyName, propertyInstance); + } + FrozenMap<@Nullable Object> castProperties = new FrozenMap<>(properties); + return new FoobarMap(castProperties); + } + + public FoobarMap validate(Map arg, SchemaConfiguration configuration) throws ValidationException, InvalidTypeException { + Set> pathSet = new HashSet<>(); + List pathToItem = List.of("args[0]"); + Map castArg = castToAllowedTypes(arg, pathToItem, pathSet); + SchemaConfiguration usedConfiguration = Objects.requireNonNullElseGet(configuration, () -> new SchemaConfiguration(JsonSchemaKeywordFlags.ofNone())); + PathToSchemasMap validatedPathToSchemas = new PathToSchemasMap(); + ValidationMetadata validationMetadata = new ValidationMetadata(pathToItem, usedConfiguration, validatedPathToSchemas, new LinkedHashSet<>()); + PathToSchemasMap pathToSchemasMap = getPathToSchemas(this, castArg, validationMetadata, pathSet); + return getNewInstance(castArg, validationMetadata.pathToItem(), pathToSchemasMap); + } + + @Override + public @Nullable Object validate(@Nullable Object arg, SchemaConfiguration configuration) throws ValidationException, InvalidTypeException { + if (arg == null) { + return validate((Void) null, configuration); + } else if (arg instanceof Boolean) { + boolean boolArg = (Boolean) arg; + return validate(boolArg, configuration); + } else if (arg instanceof Number) { + return validate((Number) arg, configuration); + } else if (arg instanceof String) { + return validate((String) arg, configuration); + } else if (arg instanceof List) { + return validate((List) arg, configuration); + } else if (arg instanceof Map) { + return validate((Map) arg, configuration); + } + throw new InvalidTypeException("Invalid input type="+getClass(arg)+". It can't be validated by this schema"); + } + @Override + public @Nullable Object getNewInstance(@Nullable Object arg, List pathToItem, PathToSchemasMap pathToSchemas) throws InvalidTypeException { + if (arg == null) { + return getNewInstance((Void) null, pathToItem, pathToSchemas); + } else if (arg instanceof Boolean) { + boolean boolArg = (Boolean) arg; + return getNewInstance(boolArg, pathToItem, pathToSchemas); + } else if (arg instanceof Number) { + return getNewInstance((Number) arg, pathToItem, pathToSchemas); + } else if (arg instanceof String) { + return getNewInstance((String) arg, pathToItem, pathToSchemas); + } else if (arg instanceof List) { + return getNewInstance((List) arg, pathToItem, pathToSchemas); + } else if (arg instanceof Map) { + return getNewInstance((Map) arg, pathToItem, pathToSchemas); + } + throw new InvalidTypeException("Invalid input type="+getClass(arg)+". It can't be instantiated by this schema"); + } + } + + public static class DependentSchemasDependenciesWithEscapedCharacters1 extends JsonSchema implements NullSchemaValidator, BooleanSchemaValidator, NumberSchemaValidator, StringSchemaValidator, ListSchemaValidator>, MapSchemaValidator> { + /* + NOTE: This class is auto generated by OpenAPI JSON Schema Generator. + Ref: https://github.com/openapi-json-schema-tools/openapi-json-schema-generator + + Do not edit the class manually. + */ + private static @Nullable DependentSchemasDependenciesWithEscapedCharacters1 instance = null; + + protected DependentSchemasDependenciesWithEscapedCharacters1() { + super(new JsonSchemaInfo() + .dependentSchemas(Map.ofEntries( + new PropertyEntry("foo\tbar", Footbar.class), + new PropertyEntry("foo'bar", Foobar.class) + )) + ); + } + + public static DependentSchemasDependenciesWithEscapedCharacters1 getInstance() { + if (instance == null) { + instance = new DependentSchemasDependenciesWithEscapedCharacters1(); + } + return instance; + } + + @Override + public Void validate(Void arg, SchemaConfiguration configuration) throws ValidationException, InvalidTypeException { + Set> pathSet = new HashSet<>(); + List pathToItem = List.of("args[0]"); + Void castArg = castToAllowedTypes(arg, pathToItem, pathSet); + SchemaConfiguration usedConfiguration = Objects.requireNonNullElseGet(configuration, () -> new SchemaConfiguration(JsonSchemaKeywordFlags.ofNone())); + PathToSchemasMap validatedPathToSchemas = new PathToSchemasMap(); + ValidationMetadata validationMetadata = new ValidationMetadata(pathToItem, usedConfiguration, validatedPathToSchemas, new LinkedHashSet<>()); + getPathToSchemas(this, castArg, validationMetadata, pathSet); + return castArg; + } + + @Override + public boolean validate(boolean arg, SchemaConfiguration configuration) throws ValidationException, InvalidTypeException { + Set> pathSet = new HashSet<>(); + List pathToItem = List.of("args[0]"); + boolean castArg = castToAllowedTypes(arg, pathToItem, pathSet); + SchemaConfiguration usedConfiguration = Objects.requireNonNullElseGet(configuration, () -> new SchemaConfiguration(JsonSchemaKeywordFlags.ofNone())); + PathToSchemasMap validatedPathToSchemas = new PathToSchemasMap(); + ValidationMetadata validationMetadata = new ValidationMetadata(pathToItem, usedConfiguration, validatedPathToSchemas, new LinkedHashSet<>()); + getPathToSchemas(this, castArg, validationMetadata, pathSet); + return castArg; + } + + @Override + public Number validate(Number arg, SchemaConfiguration configuration) throws ValidationException, InvalidTypeException { + Set> pathSet = new HashSet<>(); + List pathToItem = List.of("args[0]"); + Number castArg = castToAllowedTypes(arg, pathToItem, pathSet); + SchemaConfiguration usedConfiguration = Objects.requireNonNullElseGet(configuration, () -> new SchemaConfiguration(JsonSchemaKeywordFlags.ofNone())); + PathToSchemasMap validatedPathToSchemas = new PathToSchemasMap(); + ValidationMetadata validationMetadata = new ValidationMetadata(pathToItem, usedConfiguration, validatedPathToSchemas, new LinkedHashSet<>()); + getPathToSchemas(this, castArg, validationMetadata, pathSet); + return castArg; + } + + public int validate(int arg, SchemaConfiguration configuration) { + return (int) validate((Number) arg, configuration); + } + + public long validate(long arg, SchemaConfiguration configuration) { + return (long) validate((Number) arg, configuration); + } + + public float validate(float arg, SchemaConfiguration configuration) { + return (float) validate((Number) arg, configuration); + } + + public double validate(double arg, SchemaConfiguration configuration) { + return (double) validate((Number) arg, configuration); + } + + @Override + public String validate(String arg, SchemaConfiguration configuration) throws ValidationException, InvalidTypeException { + Set> pathSet = new HashSet<>(); + List pathToItem = List.of("args[0]"); + String castArg = castToAllowedTypes(arg, pathToItem, pathSet); + SchemaConfiguration usedConfiguration = Objects.requireNonNullElseGet(configuration, () -> new SchemaConfiguration(JsonSchemaKeywordFlags.ofNone())); + PathToSchemasMap validatedPathToSchemas = new PathToSchemasMap(); + ValidationMetadata validationMetadata = new ValidationMetadata(pathToItem, usedConfiguration, validatedPathToSchemas, new LinkedHashSet<>()); + getPathToSchemas(this, castArg, validationMetadata, pathSet); + return castArg; + } + + public String validate(LocalDate arg, SchemaConfiguration configuration) throws ValidationException { + return validate(arg.toString(), configuration); + } + + public String validate(ZonedDateTime arg, SchemaConfiguration configuration) throws ValidationException { + return validate(arg.toString(), configuration); + } + + public String validate(UUID arg, SchemaConfiguration configuration) throws ValidationException { + return validate(arg.toString(), configuration); + } + + @Override + public FrozenList<@Nullable Object> getNewInstance(List arg, List pathToItem, PathToSchemasMap pathToSchemas) { + List<@Nullable Object> items = new ArrayList<>(); + int i = 0; + for (Object item: arg) { + List itemPathToItem = new ArrayList<>(pathToItem); + itemPathToItem.add(i); + LinkedHashMap schemas = pathToSchemas.get(itemPathToItem); + if (schemas == null) { + throw new InvalidTypeException("Validation result is invalid, schemas must exist for a pathToItem"); + } + JsonSchema itemSchema = schemas.entrySet().iterator().next().getKey(); + @Nullable Object itemInstance = itemSchema.getNewInstance(item, itemPathToItem, pathToSchemas); + items.add(itemInstance); + i += 1; + } + FrozenList<@Nullable Object> newInstanceItems = new FrozenList<>(items); + return newInstanceItems; + } + + public FrozenList<@Nullable Object> validate(List arg, SchemaConfiguration configuration) throws ValidationException { + Set> pathSet = new HashSet<>(); + List pathToItem = List.of("args[0"); + List castArg = castToAllowedTypes(arg, pathToItem, pathSet); + SchemaConfiguration usedConfiguration = Objects.requireNonNullElseGet(configuration, () -> new SchemaConfiguration(JsonSchemaKeywordFlags.ofNone())); + ValidationMetadata validationMetadata = new ValidationMetadata(pathToItem, usedConfiguration, new PathToSchemasMap(), new LinkedHashSet<>()); + PathToSchemasMap pathToSchemasMap = getPathToSchemas(this, castArg, validationMetadata, pathSet); + return getNewInstance(castArg, validationMetadata.pathToItem(), pathToSchemasMap); + } + + @Override + public FrozenMap<@Nullable Object> getNewInstance(Map arg, List pathToItem, PathToSchemasMap pathToSchemas) { + LinkedHashMap properties = new LinkedHashMap<>(); + for(Map.Entry entry: arg.entrySet()) { + @Nullable Object entryKey = entry.getKey(); + if (!(entryKey instanceof String)) { + throw new InvalidTypeException("Invalid non-string key value"); + } + String propertyName = (String) entryKey; + List propertyPathToItem = new ArrayList<>(pathToItem); + propertyPathToItem.add(propertyName); + Object value = entry.getValue(); + LinkedHashMap schemas = pathToSchemas.get(propertyPathToItem); + if (schemas == null) { + throw new InvalidTypeException("Validation result is invalid, schemas must exist for a pathToItem"); + } + JsonSchema propertySchema = schemas.entrySet().iterator().next().getKey(); + @Nullable Object propertyInstance = propertySchema.getNewInstance(value, propertyPathToItem, pathToSchemas); + properties.put(propertyName, propertyInstance); + } + FrozenMap<@Nullable Object> castProperties = new FrozenMap<>(properties); + return castProperties; + } + + public FrozenMap<@Nullable Object> validate(Map arg, SchemaConfiguration configuration) throws ValidationException, InvalidTypeException { + Set> pathSet = new HashSet<>(); + List pathToItem = List.of("args[0]"); + Map castArg = castToAllowedTypes(arg, pathToItem, pathSet); + SchemaConfiguration usedConfiguration = Objects.requireNonNullElseGet(configuration, () -> new SchemaConfiguration(JsonSchemaKeywordFlags.ofNone())); + PathToSchemasMap validatedPathToSchemas = new PathToSchemasMap(); + ValidationMetadata validationMetadata = new ValidationMetadata(pathToItem, usedConfiguration, validatedPathToSchemas, new LinkedHashSet<>()); + PathToSchemasMap pathToSchemasMap = getPathToSchemas(this, castArg, validationMetadata, pathSet); + return getNewInstance(castArg, validationMetadata.pathToItem(), pathToSchemasMap); + } + + @Override + public @Nullable Object validate(@Nullable Object arg, SchemaConfiguration configuration) throws ValidationException, InvalidTypeException { + if (arg == null) { + return validate((Void) null, configuration); + } else if (arg instanceof Boolean) { + boolean boolArg = (Boolean) arg; + return validate(boolArg, configuration); + } else if (arg instanceof Number) { + return validate((Number) arg, configuration); + } else if (arg instanceof String) { + return validate((String) arg, configuration); + } else if (arg instanceof List) { + return validate((List) arg, configuration); + } else if (arg instanceof Map) { + return validate((Map) arg, configuration); + } + throw new InvalidTypeException("Invalid input type="+getClass(arg)+". It can't be validated by this schema"); + } + @Override + public @Nullable Object getNewInstance(@Nullable Object arg, List pathToItem, PathToSchemasMap pathToSchemas) throws InvalidTypeException { + if (arg == null) { + return getNewInstance((Void) null, pathToItem, pathToSchemas); + } else if (arg instanceof Boolean) { + boolean boolArg = (Boolean) arg; + return getNewInstance(boolArg, pathToItem, pathToSchemas); + } else if (arg instanceof Number) { + return getNewInstance((Number) arg, pathToItem, pathToSchemas); + } else if (arg instanceof String) { + return getNewInstance((String) arg, pathToItem, pathToSchemas); + } else if (arg instanceof List) { + return getNewInstance((List) arg, pathToItem, pathToSchemas); + } else if (arg instanceof Map) { + return getNewInstance((Map) arg, pathToItem, pathToSchemas); + } + throw new InvalidTypeException("Invalid input type="+getClass(arg)+". It can't be instantiated by this schema"); + } + } +} diff --git a/samples/client/3_1_0_unit_test/java/src/main/java/org/openapijsonschematools/client/components/schemas/DependentSchemasDependentSubschemaIncompatibleWithRoot.java b/samples/client/3_1_0_unit_test/java/src/main/java/org/openapijsonschematools/client/components/schemas/DependentSchemasDependentSubschemaIncompatibleWithRoot.java new file mode 100644 index 00000000000..87021a32d04 --- /dev/null +++ b/samples/client/3_1_0_unit_test/java/src/main/java/org/openapijsonschematools/client/components/schemas/DependentSchemasDependentSubschemaIncompatibleWithRoot.java @@ -0,0 +1,560 @@ +package org.openapijsonschematools.client.components.schemas; +import java.time.LocalDate; +import java.time.ZonedDateTime; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.LinkedHashMap; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.Set; +import java.util.UUID; +import org.checkerframework.checker.nullness.qual.Nullable; +import org.openapijsonschematools.client.configurations.JsonSchemaKeywordFlags; +import org.openapijsonschematools.client.configurations.SchemaConfiguration; +import org.openapijsonschematools.client.exceptions.InvalidAdditionalPropertyException; +import org.openapijsonschematools.client.exceptions.InvalidTypeException; +import org.openapijsonschematools.client.exceptions.UnsetPropertyException; +import org.openapijsonschematools.client.exceptions.ValidationException; +import org.openapijsonschematools.client.schemas.AnyTypeJsonSchema; +import org.openapijsonschematools.client.schemas.BaseBuilder; +import org.openapijsonschematools.client.schemas.NotAnyTypeJsonSchema; +import org.openapijsonschematools.client.schemas.UnsetAddPropsSetter; +import org.openapijsonschematools.client.schemas.validation.BooleanSchemaValidator; +import org.openapijsonschematools.client.schemas.validation.FrozenList; +import org.openapijsonschematools.client.schemas.validation.FrozenMap; +import org.openapijsonschematools.client.schemas.validation.JsonSchema; +import org.openapijsonschematools.client.schemas.validation.JsonSchemaInfo; +import org.openapijsonschematools.client.schemas.validation.ListSchemaValidator; +import org.openapijsonschematools.client.schemas.validation.MapSchemaValidator; +import org.openapijsonschematools.client.schemas.validation.MapUtils; +import org.openapijsonschematools.client.schemas.validation.NullSchemaValidator; +import org.openapijsonschematools.client.schemas.validation.NumberSchemaValidator; +import org.openapijsonschematools.client.schemas.validation.PathToSchemasMap; +import org.openapijsonschematools.client.schemas.validation.PropertyEntry; +import org.openapijsonschematools.client.schemas.validation.StringSchemaValidator; +import org.openapijsonschematools.client.schemas.validation.ValidationMetadata; + +public class DependentSchemasDependentSubschemaIncompatibleWithRoot { + // nest classes so all schemas and input/output classes can be public + + + public static class AdditionalProperties extends NotAnyTypeJsonSchema { + // NotAnyTypeSchema + private static @Nullable AdditionalProperties instance = null; + public static AdditionalProperties getInstance() { + if (instance == null) { + instance = new AdditionalProperties(); + } + return instance; + } + } + + + public static class Bar extends AnyTypeJsonSchema { + private static @Nullable Bar instance = null; + public static Bar getInstance() { + if (instance == null) { + instance = new Bar(); + } + return instance; + } + } + + + public static class FooMap extends FrozenMap<@Nullable Object> { + protected FooMap(FrozenMap<@Nullable Object> m) { + super(m); + } + public static final Set requiredKeys = Set.of(); + public static final Set optionalKeys = Set.of( + "bar" + ); + public static FooMap of(Map arg, SchemaConfiguration configuration) throws ValidationException { + return Foo1.getInstance().validate(arg, configuration); + } + + public @Nullable Object bar() throws UnsetPropertyException { + return getOrThrow("bar"); + } + } + + public interface SetterForBar { + Map getInstance(); + T getBuilderAfterBar(Map instance); + + default T bar(Void value) { + var instance = getInstance(); + instance.put("bar", null); + return getBuilderAfterBar(instance); + } + + default T bar(boolean value) { + var instance = getInstance(); + instance.put("bar", value); + return getBuilderAfterBar(instance); + } + + default T bar(String value) { + var instance = getInstance(); + instance.put("bar", value); + return getBuilderAfterBar(instance); + } + + default T bar(int value) { + var instance = getInstance(); + instance.put("bar", value); + return getBuilderAfterBar(instance); + } + + default T bar(float value) { + var instance = getInstance(); + instance.put("bar", value); + return getBuilderAfterBar(instance); + } + + default T bar(long value) { + var instance = getInstance(); + instance.put("bar", value); + return getBuilderAfterBar(instance); + } + + default T bar(double value) { + var instance = getInstance(); + instance.put("bar", value); + return getBuilderAfterBar(instance); + } + + default T bar(List value) { + var instance = getInstance(); + instance.put("bar", value); + return getBuilderAfterBar(instance); + } + + default T bar(Map value) { + var instance = getInstance(); + instance.put("bar", value); + return getBuilderAfterBar(instance); + } + } + + public static class FooMapBuilder1 implements BaseBuilder<@Nullable Object>, SetterForBar { + private final Map instance; + private static final Set knownKeys = Set.of( + "bar" + ); + public Set getKnownKeys() { + return knownKeys; + } + public FooMapBuilder1() { + this.instance = new LinkedHashMap<>(); + } + public Map build() { + return instance; + } + public Map getInstance() { + return instance; + } + public FooMapBuilder1 getBuilderAfterBar(Map instance) { + return this; + } + } + + + public static class Foo1 extends JsonSchema implements MapSchemaValidator { + private static @Nullable Foo1 instance = null; + + protected Foo1() { + super(new JsonSchemaInfo() + .type(Set.of(Map.class)) + .properties(Map.ofEntries( + new PropertyEntry("bar", Bar.class) + )) + .additionalProperties(AdditionalProperties.class) + ); + } + + public static Foo1 getInstance() { + if (instance == null) { + instance = new Foo1(); + } + return instance; + } + + public FooMap getNewInstance(Map arg, List pathToItem, PathToSchemasMap pathToSchemas) { + LinkedHashMap properties = new LinkedHashMap<>(); + for(Map.Entry entry: arg.entrySet()) { + @Nullable Object entryKey = entry.getKey(); + if (!(entryKey instanceof String)) { + throw new InvalidTypeException("Invalid non-string key value"); + } + String propertyName = (String) entryKey; + List propertyPathToItem = new ArrayList<>(pathToItem); + propertyPathToItem.add(propertyName); + Object value = entry.getValue(); + LinkedHashMap schemas = pathToSchemas.get(propertyPathToItem); + if (schemas == null) { + throw new InvalidTypeException("Validation result is invalid, schemas must exist for a pathToItem"); + } + JsonSchema propertySchema = schemas.entrySet().iterator().next().getKey(); + @Nullable Object propertyInstance = propertySchema.getNewInstance(value, propertyPathToItem, pathToSchemas); + properties.put(propertyName, propertyInstance); + } + FrozenMap<@Nullable Object> castProperties = new FrozenMap<>(properties); + return new FooMap(castProperties); + } + + public FooMap validate(Map arg, SchemaConfiguration configuration) throws ValidationException, InvalidTypeException { + Set> pathSet = new HashSet<>(); + List pathToItem = List.of("args[0"); + Map castArg = castToAllowedTypes(arg, pathToItem, pathSet); + SchemaConfiguration usedConfiguration = Objects.requireNonNullElseGet(configuration, () -> new SchemaConfiguration(JsonSchemaKeywordFlags.ofNone())); + ValidationMetadata validationMetadata = new ValidationMetadata(pathToItem, usedConfiguration, new PathToSchemasMap(), new LinkedHashSet<>()); + PathToSchemasMap pathToSchemasMap = getPathToSchemas(this, castArg, validationMetadata, pathSet); + return getNewInstance(castArg, validationMetadata.pathToItem(), pathToSchemasMap); + } + + + @Override + public @Nullable Object validate(@Nullable Object arg, SchemaConfiguration configuration) throws ValidationException, InvalidTypeException { + if (arg instanceof Map) { + return validate((Map) arg, configuration); + } + throw new InvalidTypeException("Invalid input type="+getClass(arg)+". It can't be validated by this schema"); + } + @Override + public @Nullable Object getNewInstance(@Nullable Object arg, List pathToItem, PathToSchemasMap pathToSchemas) throws InvalidTypeException { + if (arg instanceof Map) { + return getNewInstance((Map) arg, pathToItem, pathToSchemas); + } + throw new InvalidTypeException("Invalid input type="+getClass(arg)+". It can't be instantiated by this schema"); + } + } + + + public static class Foo extends AnyTypeJsonSchema { + private static @Nullable Foo instance = null; + public static Foo getInstance() { + if (instance == null) { + instance = new Foo(); + } + return instance; + } + } + + + public static class DependentSchemasDependentSubschemaIncompatibleWithRootMap extends FrozenMap<@Nullable Object> { + protected DependentSchemasDependentSubschemaIncompatibleWithRootMap(FrozenMap<@Nullable Object> m) { + super(m); + } + public static final Set requiredKeys = Set.of(); + public static final Set optionalKeys = Set.of( + "foo" + ); + public static DependentSchemasDependentSubschemaIncompatibleWithRootMap of(Map arg, SchemaConfiguration configuration) throws ValidationException { + return DependentSchemasDependentSubschemaIncompatibleWithRoot1.getInstance().validate(arg, configuration); + } + + public @Nullable Object foo() throws UnsetPropertyException { + return getOrThrow("foo"); + } + + public @Nullable Object getAdditionalProperty(String name) throws UnsetPropertyException, InvalidAdditionalPropertyException { + throwIfKeyKnown(name, requiredKeys, optionalKeys); + throwIfKeyNotPresent(name); + return get(name); + } + } + + public interface SetterForFoo { + Map getInstance(); + T getBuilderAfterFoo(Map instance); + + default T foo(Void value) { + var instance = getInstance(); + instance.put("foo", null); + return getBuilderAfterFoo(instance); + } + + default T foo(boolean value) { + var instance = getInstance(); + instance.put("foo", value); + return getBuilderAfterFoo(instance); + } + + default T foo(String value) { + var instance = getInstance(); + instance.put("foo", value); + return getBuilderAfterFoo(instance); + } + + default T foo(int value) { + var instance = getInstance(); + instance.put("foo", value); + return getBuilderAfterFoo(instance); + } + + default T foo(float value) { + var instance = getInstance(); + instance.put("foo", value); + return getBuilderAfterFoo(instance); + } + + default T foo(long value) { + var instance = getInstance(); + instance.put("foo", value); + return getBuilderAfterFoo(instance); + } + + default T foo(double value) { + var instance = getInstance(); + instance.put("foo", value); + return getBuilderAfterFoo(instance); + } + + default T foo(List value) { + var instance = getInstance(); + instance.put("foo", value); + return getBuilderAfterFoo(instance); + } + + default T foo(Map value) { + var instance = getInstance(); + instance.put("foo", value); + return getBuilderAfterFoo(instance); + } + } + + public static class DependentSchemasDependentSubschemaIncompatibleWithRootMapBuilder extends UnsetAddPropsSetter implements BaseBuilder<@Nullable Object>, SetterForFoo { + private final Map instance; + private static final Set knownKeys = Set.of( + "foo" + ); + public Set getKnownKeys() { + return knownKeys; + } + public DependentSchemasDependentSubschemaIncompatibleWithRootMapBuilder() { + this.instance = new LinkedHashMap<>(); + } + public Map build() { + return instance; + } + public Map getInstance() { + return instance; + } + public DependentSchemasDependentSubschemaIncompatibleWithRootMapBuilder getBuilderAfterFoo(Map instance) { + return this; + } + public DependentSchemasDependentSubschemaIncompatibleWithRootMapBuilder getBuilderAfterAdditionalProperty(Map instance) { + return this; + } + } + + + public static class DependentSchemasDependentSubschemaIncompatibleWithRoot1 extends JsonSchema implements NullSchemaValidator, BooleanSchemaValidator, NumberSchemaValidator, StringSchemaValidator, ListSchemaValidator>, MapSchemaValidator { + /* + NOTE: This class is auto generated by OpenAPI JSON Schema Generator. + Ref: https://github.com/openapi-json-schema-tools/openapi-json-schema-generator + + Do not edit the class manually. + */ + private static @Nullable DependentSchemasDependentSubschemaIncompatibleWithRoot1 instance = null; + + protected DependentSchemasDependentSubschemaIncompatibleWithRoot1() { + super(new JsonSchemaInfo() + .properties(Map.ofEntries( + new PropertyEntry("foo", Foo.class) + )) + .dependentSchemas(Map.ofEntries( + new PropertyEntry("foo", Foo1.class) + )) + ); + } + + public static DependentSchemasDependentSubschemaIncompatibleWithRoot1 getInstance() { + if (instance == null) { + instance = new DependentSchemasDependentSubschemaIncompatibleWithRoot1(); + } + return instance; + } + + @Override + public Void validate(Void arg, SchemaConfiguration configuration) throws ValidationException, InvalidTypeException { + Set> pathSet = new HashSet<>(); + List pathToItem = List.of("args[0]"); + Void castArg = castToAllowedTypes(arg, pathToItem, pathSet); + SchemaConfiguration usedConfiguration = Objects.requireNonNullElseGet(configuration, () -> new SchemaConfiguration(JsonSchemaKeywordFlags.ofNone())); + PathToSchemasMap validatedPathToSchemas = new PathToSchemasMap(); + ValidationMetadata validationMetadata = new ValidationMetadata(pathToItem, usedConfiguration, validatedPathToSchemas, new LinkedHashSet<>()); + getPathToSchemas(this, castArg, validationMetadata, pathSet); + return castArg; + } + + @Override + public boolean validate(boolean arg, SchemaConfiguration configuration) throws ValidationException, InvalidTypeException { + Set> pathSet = new HashSet<>(); + List pathToItem = List.of("args[0]"); + boolean castArg = castToAllowedTypes(arg, pathToItem, pathSet); + SchemaConfiguration usedConfiguration = Objects.requireNonNullElseGet(configuration, () -> new SchemaConfiguration(JsonSchemaKeywordFlags.ofNone())); + PathToSchemasMap validatedPathToSchemas = new PathToSchemasMap(); + ValidationMetadata validationMetadata = new ValidationMetadata(pathToItem, usedConfiguration, validatedPathToSchemas, new LinkedHashSet<>()); + getPathToSchemas(this, castArg, validationMetadata, pathSet); + return castArg; + } + + @Override + public Number validate(Number arg, SchemaConfiguration configuration) throws ValidationException, InvalidTypeException { + Set> pathSet = new HashSet<>(); + List pathToItem = List.of("args[0]"); + Number castArg = castToAllowedTypes(arg, pathToItem, pathSet); + SchemaConfiguration usedConfiguration = Objects.requireNonNullElseGet(configuration, () -> new SchemaConfiguration(JsonSchemaKeywordFlags.ofNone())); + PathToSchemasMap validatedPathToSchemas = new PathToSchemasMap(); + ValidationMetadata validationMetadata = new ValidationMetadata(pathToItem, usedConfiguration, validatedPathToSchemas, new LinkedHashSet<>()); + getPathToSchemas(this, castArg, validationMetadata, pathSet); + return castArg; + } + + public int validate(int arg, SchemaConfiguration configuration) { + return (int) validate((Number) arg, configuration); + } + + public long validate(long arg, SchemaConfiguration configuration) { + return (long) validate((Number) arg, configuration); + } + + public float validate(float arg, SchemaConfiguration configuration) { + return (float) validate((Number) arg, configuration); + } + + public double validate(double arg, SchemaConfiguration configuration) { + return (double) validate((Number) arg, configuration); + } + + @Override + public String validate(String arg, SchemaConfiguration configuration) throws ValidationException, InvalidTypeException { + Set> pathSet = new HashSet<>(); + List pathToItem = List.of("args[0]"); + String castArg = castToAllowedTypes(arg, pathToItem, pathSet); + SchemaConfiguration usedConfiguration = Objects.requireNonNullElseGet(configuration, () -> new SchemaConfiguration(JsonSchemaKeywordFlags.ofNone())); + PathToSchemasMap validatedPathToSchemas = new PathToSchemasMap(); + ValidationMetadata validationMetadata = new ValidationMetadata(pathToItem, usedConfiguration, validatedPathToSchemas, new LinkedHashSet<>()); + getPathToSchemas(this, castArg, validationMetadata, pathSet); + return castArg; + } + + public String validate(LocalDate arg, SchemaConfiguration configuration) throws ValidationException { + return validate(arg.toString(), configuration); + } + + public String validate(ZonedDateTime arg, SchemaConfiguration configuration) throws ValidationException { + return validate(arg.toString(), configuration); + } + + public String validate(UUID arg, SchemaConfiguration configuration) throws ValidationException { + return validate(arg.toString(), configuration); + } + + @Override + public FrozenList<@Nullable Object> getNewInstance(List arg, List pathToItem, PathToSchemasMap pathToSchemas) { + List<@Nullable Object> items = new ArrayList<>(); + int i = 0; + for (Object item: arg) { + List itemPathToItem = new ArrayList<>(pathToItem); + itemPathToItem.add(i); + LinkedHashMap schemas = pathToSchemas.get(itemPathToItem); + if (schemas == null) { + throw new InvalidTypeException("Validation result is invalid, schemas must exist for a pathToItem"); + } + JsonSchema itemSchema = schemas.entrySet().iterator().next().getKey(); + @Nullable Object itemInstance = itemSchema.getNewInstance(item, itemPathToItem, pathToSchemas); + items.add(itemInstance); + i += 1; + } + FrozenList<@Nullable Object> newInstanceItems = new FrozenList<>(items); + return newInstanceItems; + } + + public FrozenList<@Nullable Object> validate(List arg, SchemaConfiguration configuration) throws ValidationException { + Set> pathSet = new HashSet<>(); + List pathToItem = List.of("args[0"); + List castArg = castToAllowedTypes(arg, pathToItem, pathSet); + SchemaConfiguration usedConfiguration = Objects.requireNonNullElseGet(configuration, () -> new SchemaConfiguration(JsonSchemaKeywordFlags.ofNone())); + ValidationMetadata validationMetadata = new ValidationMetadata(pathToItem, usedConfiguration, new PathToSchemasMap(), new LinkedHashSet<>()); + PathToSchemasMap pathToSchemasMap = getPathToSchemas(this, castArg, validationMetadata, pathSet); + return getNewInstance(castArg, validationMetadata.pathToItem(), pathToSchemasMap); + } + + @Override + public DependentSchemasDependentSubschemaIncompatibleWithRootMap getNewInstance(Map arg, List pathToItem, PathToSchemasMap pathToSchemas) { + LinkedHashMap properties = new LinkedHashMap<>(); + for(Map.Entry entry: arg.entrySet()) { + @Nullable Object entryKey = entry.getKey(); + if (!(entryKey instanceof String)) { + throw new InvalidTypeException("Invalid non-string key value"); + } + String propertyName = (String) entryKey; + List propertyPathToItem = new ArrayList<>(pathToItem); + propertyPathToItem.add(propertyName); + Object value = entry.getValue(); + LinkedHashMap schemas = pathToSchemas.get(propertyPathToItem); + if (schemas == null) { + throw new InvalidTypeException("Validation result is invalid, schemas must exist for a pathToItem"); + } + JsonSchema propertySchema = schemas.entrySet().iterator().next().getKey(); + @Nullable Object propertyInstance = propertySchema.getNewInstance(value, propertyPathToItem, pathToSchemas); + properties.put(propertyName, propertyInstance); + } + FrozenMap<@Nullable Object> castProperties = new FrozenMap<>(properties); + return new DependentSchemasDependentSubschemaIncompatibleWithRootMap(castProperties); + } + + public DependentSchemasDependentSubschemaIncompatibleWithRootMap validate(Map arg, SchemaConfiguration configuration) throws ValidationException, InvalidTypeException { + Set> pathSet = new HashSet<>(); + List pathToItem = List.of("args[0]"); + Map castArg = castToAllowedTypes(arg, pathToItem, pathSet); + SchemaConfiguration usedConfiguration = Objects.requireNonNullElseGet(configuration, () -> new SchemaConfiguration(JsonSchemaKeywordFlags.ofNone())); + PathToSchemasMap validatedPathToSchemas = new PathToSchemasMap(); + ValidationMetadata validationMetadata = new ValidationMetadata(pathToItem, usedConfiguration, validatedPathToSchemas, new LinkedHashSet<>()); + PathToSchemasMap pathToSchemasMap = getPathToSchemas(this, castArg, validationMetadata, pathSet); + return getNewInstance(castArg, validationMetadata.pathToItem(), pathToSchemasMap); + } + + @Override + public @Nullable Object validate(@Nullable Object arg, SchemaConfiguration configuration) throws ValidationException, InvalidTypeException { + if (arg == null) { + return validate((Void) null, configuration); + } else if (arg instanceof Boolean) { + boolean boolArg = (Boolean) arg; + return validate(boolArg, configuration); + } else if (arg instanceof Number) { + return validate((Number) arg, configuration); + } else if (arg instanceof String) { + return validate((String) arg, configuration); + } else if (arg instanceof List) { + return validate((List) arg, configuration); + } else if (arg instanceof Map) { + return validate((Map) arg, configuration); + } + throw new InvalidTypeException("Invalid input type="+getClass(arg)+". It can't be validated by this schema"); + } + @Override + public @Nullable Object getNewInstance(@Nullable Object arg, List pathToItem, PathToSchemasMap pathToSchemas) throws InvalidTypeException { + if (arg == null) { + return getNewInstance((Void) null, pathToItem, pathToSchemas); + } else if (arg instanceof Boolean) { + boolean boolArg = (Boolean) arg; + return getNewInstance(boolArg, pathToItem, pathToSchemas); + } else if (arg instanceof Number) { + return getNewInstance((Number) arg, pathToItem, pathToSchemas); + } else if (arg instanceof String) { + return getNewInstance((String) arg, pathToItem, pathToSchemas); + } else if (arg instanceof List) { + return getNewInstance((List) arg, pathToItem, pathToSchemas); + } else if (arg instanceof Map) { + return getNewInstance((Map) arg, pathToItem, pathToSchemas); + } + throw new InvalidTypeException("Invalid input type="+getClass(arg)+". It can't be instantiated by this schema"); + } + } +} diff --git a/samples/client/3_1_0_unit_test/java/src/main/java/org/openapijsonschematools/client/components/schemas/DependentSchemasSingleDependency.java b/samples/client/3_1_0_unit_test/java/src/main/java/org/openapijsonschematools/client/components/schemas/DependentSchemasSingleDependency.java new file mode 100644 index 00000000000..04546052a49 --- /dev/null +++ b/samples/client/3_1_0_unit_test/java/src/main/java/org/openapijsonschematools/client/components/schemas/DependentSchemasSingleDependency.java @@ -0,0 +1,591 @@ +package org.openapijsonschematools.client.components.schemas; +import java.time.LocalDate; +import java.time.ZonedDateTime; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.LinkedHashMap; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.Set; +import java.util.UUID; +import org.checkerframework.checker.nullness.qual.Nullable; +import org.openapijsonschematools.client.configurations.JsonSchemaKeywordFlags; +import org.openapijsonschematools.client.configurations.SchemaConfiguration; +import org.openapijsonschematools.client.exceptions.InvalidAdditionalPropertyException; +import org.openapijsonschematools.client.exceptions.InvalidTypeException; +import org.openapijsonschematools.client.exceptions.UnsetPropertyException; +import org.openapijsonschematools.client.exceptions.ValidationException; +import org.openapijsonschematools.client.schemas.BaseBuilder; +import org.openapijsonschematools.client.schemas.IntJsonSchema; +import org.openapijsonschematools.client.schemas.UnsetAddPropsSetter; +import org.openapijsonschematools.client.schemas.validation.BooleanSchemaValidator; +import org.openapijsonschematools.client.schemas.validation.FrozenList; +import org.openapijsonschematools.client.schemas.validation.FrozenMap; +import org.openapijsonschematools.client.schemas.validation.JsonSchema; +import org.openapijsonschematools.client.schemas.validation.JsonSchemaInfo; +import org.openapijsonschematools.client.schemas.validation.ListSchemaValidator; +import org.openapijsonschematools.client.schemas.validation.MapSchemaValidator; +import org.openapijsonschematools.client.schemas.validation.NullSchemaValidator; +import org.openapijsonschematools.client.schemas.validation.NumberSchemaValidator; +import org.openapijsonschematools.client.schemas.validation.PathToSchemasMap; +import org.openapijsonschematools.client.schemas.validation.PropertyEntry; +import org.openapijsonschematools.client.schemas.validation.StringSchemaValidator; +import org.openapijsonschematools.client.schemas.validation.ValidationMetadata; + +public class DependentSchemasSingleDependency { + // nest classes so all schemas and input/output classes can be public + + + public static class Foo extends IntJsonSchema { + private static @Nullable Foo instance = null; + public static Foo getInstance() { + if (instance == null) { + instance = new Foo(); + } + return instance; + } + } + + + public static class Bar1 extends IntJsonSchema { + private static @Nullable Bar1 instance = null; + public static Bar1 getInstance() { + if (instance == null) { + instance = new Bar1(); + } + return instance; + } + } + + + public static class BarMap extends FrozenMap<@Nullable Object> { + protected BarMap(FrozenMap<@Nullable Object> m) { + super(m); + } + public static final Set requiredKeys = Set.of(); + public static final Set optionalKeys = Set.of( + "foo", + "bar" + ); + public static BarMap of(Map arg, SchemaConfiguration configuration) throws ValidationException { + return Bar.getInstance().validate(arg, configuration); + } + + public Number foo() throws UnsetPropertyException { + String key = "foo"; + throwIfKeyNotPresent(key); + @Nullable Object value = get(key); + if (!(value instanceof Number)) { + throw new InvalidTypeException("Invalid value stored for foo"); + } + return (Number) value; + } + + public Number bar() throws UnsetPropertyException { + String key = "bar"; + throwIfKeyNotPresent(key); + @Nullable Object value = get(key); + if (!(value instanceof Number)) { + throw new InvalidTypeException("Invalid value stored for bar"); + } + return (Number) value; + } + + public @Nullable Object getAdditionalProperty(String name) throws UnsetPropertyException, InvalidAdditionalPropertyException { + throwIfKeyKnown(name, requiredKeys, optionalKeys); + throwIfKeyNotPresent(name); + return get(name); + } + } + + public interface SetterForFoo { + Map getInstance(); + T getBuilderAfterFoo(Map instance); + + default T foo(int value) { + var instance = getInstance(); + instance.put("foo", value); + return getBuilderAfterFoo(instance); + } + + default T foo(float value) { + var instance = getInstance(); + instance.put("foo", value); + return getBuilderAfterFoo(instance); + } + + default T foo(long value) { + var instance = getInstance(); + instance.put("foo", value); + return getBuilderAfterFoo(instance); + } + + default T foo(double value) { + var instance = getInstance(); + instance.put("foo", value); + return getBuilderAfterFoo(instance); + } + } + + public interface SetterForBar1 { + Map getInstance(); + T getBuilderAfterBar1(Map instance); + + default T bar(int value) { + var instance = getInstance(); + instance.put("bar", value); + return getBuilderAfterBar1(instance); + } + + default T bar(float value) { + var instance = getInstance(); + instance.put("bar", value); + return getBuilderAfterBar1(instance); + } + + default T bar(long value) { + var instance = getInstance(); + instance.put("bar", value); + return getBuilderAfterBar1(instance); + } + + default T bar(double value) { + var instance = getInstance(); + instance.put("bar", value); + return getBuilderAfterBar1(instance); + } + } + + public static class BarMapBuilder1 extends UnsetAddPropsSetter implements BaseBuilder<@Nullable Object>, SetterForFoo, SetterForBar1 { + private final Map instance; + private static final Set knownKeys = Set.of( + "foo", + "bar" + ); + public Set getKnownKeys() { + return knownKeys; + } + public BarMapBuilder1() { + this.instance = new LinkedHashMap<>(); + } + public Map build() { + return instance; + } + public Map getInstance() { + return instance; + } + public BarMapBuilder1 getBuilderAfterFoo(Map instance) { + return this; + } + public BarMapBuilder1 getBuilderAfterBar1(Map instance) { + return this; + } + public BarMapBuilder1 getBuilderAfterAdditionalProperty(Map instance) { + return this; + } + } + + + public static class Bar extends JsonSchema implements NullSchemaValidator, BooleanSchemaValidator, NumberSchemaValidator, StringSchemaValidator, ListSchemaValidator>, MapSchemaValidator { + private static @Nullable Bar instance = null; + + protected Bar() { + super(new JsonSchemaInfo() + .properties(Map.ofEntries( + new PropertyEntry("foo", Foo.class), + new PropertyEntry("bar", Bar1.class) + )) + ); + } + + public static Bar getInstance() { + if (instance == null) { + instance = new Bar(); + } + return instance; + } + + @Override + public Void validate(Void arg, SchemaConfiguration configuration) throws ValidationException, InvalidTypeException { + Set> pathSet = new HashSet<>(); + List pathToItem = List.of("args[0]"); + Void castArg = castToAllowedTypes(arg, pathToItem, pathSet); + SchemaConfiguration usedConfiguration = Objects.requireNonNullElseGet(configuration, () -> new SchemaConfiguration(JsonSchemaKeywordFlags.ofNone())); + PathToSchemasMap validatedPathToSchemas = new PathToSchemasMap(); + ValidationMetadata validationMetadata = new ValidationMetadata(pathToItem, usedConfiguration, validatedPathToSchemas, new LinkedHashSet<>()); + getPathToSchemas(this, castArg, validationMetadata, pathSet); + return castArg; + } + + @Override + public boolean validate(boolean arg, SchemaConfiguration configuration) throws ValidationException, InvalidTypeException { + Set> pathSet = new HashSet<>(); + List pathToItem = List.of("args[0]"); + boolean castArg = castToAllowedTypes(arg, pathToItem, pathSet); + SchemaConfiguration usedConfiguration = Objects.requireNonNullElseGet(configuration, () -> new SchemaConfiguration(JsonSchemaKeywordFlags.ofNone())); + PathToSchemasMap validatedPathToSchemas = new PathToSchemasMap(); + ValidationMetadata validationMetadata = new ValidationMetadata(pathToItem, usedConfiguration, validatedPathToSchemas, new LinkedHashSet<>()); + getPathToSchemas(this, castArg, validationMetadata, pathSet); + return castArg; + } + + @Override + public Number validate(Number arg, SchemaConfiguration configuration) throws ValidationException, InvalidTypeException { + Set> pathSet = new HashSet<>(); + List pathToItem = List.of("args[0]"); + Number castArg = castToAllowedTypes(arg, pathToItem, pathSet); + SchemaConfiguration usedConfiguration = Objects.requireNonNullElseGet(configuration, () -> new SchemaConfiguration(JsonSchemaKeywordFlags.ofNone())); + PathToSchemasMap validatedPathToSchemas = new PathToSchemasMap(); + ValidationMetadata validationMetadata = new ValidationMetadata(pathToItem, usedConfiguration, validatedPathToSchemas, new LinkedHashSet<>()); + getPathToSchemas(this, castArg, validationMetadata, pathSet); + return castArg; + } + + public int validate(int arg, SchemaConfiguration configuration) { + return (int) validate((Number) arg, configuration); + } + + public long validate(long arg, SchemaConfiguration configuration) { + return (long) validate((Number) arg, configuration); + } + + public float validate(float arg, SchemaConfiguration configuration) { + return (float) validate((Number) arg, configuration); + } + + public double validate(double arg, SchemaConfiguration configuration) { + return (double) validate((Number) arg, configuration); + } + + @Override + public String validate(String arg, SchemaConfiguration configuration) throws ValidationException, InvalidTypeException { + Set> pathSet = new HashSet<>(); + List pathToItem = List.of("args[0]"); + String castArg = castToAllowedTypes(arg, pathToItem, pathSet); + SchemaConfiguration usedConfiguration = Objects.requireNonNullElseGet(configuration, () -> new SchemaConfiguration(JsonSchemaKeywordFlags.ofNone())); + PathToSchemasMap validatedPathToSchemas = new PathToSchemasMap(); + ValidationMetadata validationMetadata = new ValidationMetadata(pathToItem, usedConfiguration, validatedPathToSchemas, new LinkedHashSet<>()); + getPathToSchemas(this, castArg, validationMetadata, pathSet); + return castArg; + } + + public String validate(LocalDate arg, SchemaConfiguration configuration) throws ValidationException { + return validate(arg.toString(), configuration); + } + + public String validate(ZonedDateTime arg, SchemaConfiguration configuration) throws ValidationException { + return validate(arg.toString(), configuration); + } + + public String validate(UUID arg, SchemaConfiguration configuration) throws ValidationException { + return validate(arg.toString(), configuration); + } + + @Override + public FrozenList<@Nullable Object> getNewInstance(List arg, List pathToItem, PathToSchemasMap pathToSchemas) { + List<@Nullable Object> items = new ArrayList<>(); + int i = 0; + for (Object item: arg) { + List itemPathToItem = new ArrayList<>(pathToItem); + itemPathToItem.add(i); + LinkedHashMap schemas = pathToSchemas.get(itemPathToItem); + if (schemas == null) { + throw new InvalidTypeException("Validation result is invalid, schemas must exist for a pathToItem"); + } + JsonSchema itemSchema = schemas.entrySet().iterator().next().getKey(); + @Nullable Object itemInstance = itemSchema.getNewInstance(item, itemPathToItem, pathToSchemas); + items.add(itemInstance); + i += 1; + } + FrozenList<@Nullable Object> newInstanceItems = new FrozenList<>(items); + return newInstanceItems; + } + + public FrozenList<@Nullable Object> validate(List arg, SchemaConfiguration configuration) throws ValidationException { + Set> pathSet = new HashSet<>(); + List pathToItem = List.of("args[0"); + List castArg = castToAllowedTypes(arg, pathToItem, pathSet); + SchemaConfiguration usedConfiguration = Objects.requireNonNullElseGet(configuration, () -> new SchemaConfiguration(JsonSchemaKeywordFlags.ofNone())); + ValidationMetadata validationMetadata = new ValidationMetadata(pathToItem, usedConfiguration, new PathToSchemasMap(), new LinkedHashSet<>()); + PathToSchemasMap pathToSchemasMap = getPathToSchemas(this, castArg, validationMetadata, pathSet); + return getNewInstance(castArg, validationMetadata.pathToItem(), pathToSchemasMap); + } + + @Override + public BarMap getNewInstance(Map arg, List pathToItem, PathToSchemasMap pathToSchemas) { + LinkedHashMap properties = new LinkedHashMap<>(); + for(Map.Entry entry: arg.entrySet()) { + @Nullable Object entryKey = entry.getKey(); + if (!(entryKey instanceof String)) { + throw new InvalidTypeException("Invalid non-string key value"); + } + String propertyName = (String) entryKey; + List propertyPathToItem = new ArrayList<>(pathToItem); + propertyPathToItem.add(propertyName); + Object value = entry.getValue(); + LinkedHashMap schemas = pathToSchemas.get(propertyPathToItem); + if (schemas == null) { + throw new InvalidTypeException("Validation result is invalid, schemas must exist for a pathToItem"); + } + JsonSchema propertySchema = schemas.entrySet().iterator().next().getKey(); + @Nullable Object propertyInstance = propertySchema.getNewInstance(value, propertyPathToItem, pathToSchemas); + properties.put(propertyName, propertyInstance); + } + FrozenMap<@Nullable Object> castProperties = new FrozenMap<>(properties); + return new BarMap(castProperties); + } + + public BarMap validate(Map arg, SchemaConfiguration configuration) throws ValidationException, InvalidTypeException { + Set> pathSet = new HashSet<>(); + List pathToItem = List.of("args[0]"); + Map castArg = castToAllowedTypes(arg, pathToItem, pathSet); + SchemaConfiguration usedConfiguration = Objects.requireNonNullElseGet(configuration, () -> new SchemaConfiguration(JsonSchemaKeywordFlags.ofNone())); + PathToSchemasMap validatedPathToSchemas = new PathToSchemasMap(); + ValidationMetadata validationMetadata = new ValidationMetadata(pathToItem, usedConfiguration, validatedPathToSchemas, new LinkedHashSet<>()); + PathToSchemasMap pathToSchemasMap = getPathToSchemas(this, castArg, validationMetadata, pathSet); + return getNewInstance(castArg, validationMetadata.pathToItem(), pathToSchemasMap); + } + + @Override + public @Nullable Object validate(@Nullable Object arg, SchemaConfiguration configuration) throws ValidationException, InvalidTypeException { + if (arg == null) { + return validate((Void) null, configuration); + } else if (arg instanceof Boolean) { + boolean boolArg = (Boolean) arg; + return validate(boolArg, configuration); + } else if (arg instanceof Number) { + return validate((Number) arg, configuration); + } else if (arg instanceof String) { + return validate((String) arg, configuration); + } else if (arg instanceof List) { + return validate((List) arg, configuration); + } else if (arg instanceof Map) { + return validate((Map) arg, configuration); + } + throw new InvalidTypeException("Invalid input type="+getClass(arg)+". It can't be validated by this schema"); + } + @Override + public @Nullable Object getNewInstance(@Nullable Object arg, List pathToItem, PathToSchemasMap pathToSchemas) throws InvalidTypeException { + if (arg == null) { + return getNewInstance((Void) null, pathToItem, pathToSchemas); + } else if (arg instanceof Boolean) { + boolean boolArg = (Boolean) arg; + return getNewInstance(boolArg, pathToItem, pathToSchemas); + } else if (arg instanceof Number) { + return getNewInstance((Number) arg, pathToItem, pathToSchemas); + } else if (arg instanceof String) { + return getNewInstance((String) arg, pathToItem, pathToSchemas); + } else if (arg instanceof List) { + return getNewInstance((List) arg, pathToItem, pathToSchemas); + } else if (arg instanceof Map) { + return getNewInstance((Map) arg, pathToItem, pathToSchemas); + } + throw new InvalidTypeException("Invalid input type="+getClass(arg)+". It can't be instantiated by this schema"); + } + } + + public static class DependentSchemasSingleDependency1 extends JsonSchema implements NullSchemaValidator, BooleanSchemaValidator, NumberSchemaValidator, StringSchemaValidator, ListSchemaValidator>, MapSchemaValidator> { + /* + NOTE: This class is auto generated by OpenAPI JSON Schema Generator. + Ref: https://github.com/openapi-json-schema-tools/openapi-json-schema-generator + + Do not edit the class manually. + */ + private static @Nullable DependentSchemasSingleDependency1 instance = null; + + protected DependentSchemasSingleDependency1() { + super(new JsonSchemaInfo() + .dependentSchemas(Map.ofEntries( + new PropertyEntry("bar", Bar.class) + )) + ); + } + + public static DependentSchemasSingleDependency1 getInstance() { + if (instance == null) { + instance = new DependentSchemasSingleDependency1(); + } + return instance; + } + + @Override + public Void validate(Void arg, SchemaConfiguration configuration) throws ValidationException, InvalidTypeException { + Set> pathSet = new HashSet<>(); + List pathToItem = List.of("args[0]"); + Void castArg = castToAllowedTypes(arg, pathToItem, pathSet); + SchemaConfiguration usedConfiguration = Objects.requireNonNullElseGet(configuration, () -> new SchemaConfiguration(JsonSchemaKeywordFlags.ofNone())); + PathToSchemasMap validatedPathToSchemas = new PathToSchemasMap(); + ValidationMetadata validationMetadata = new ValidationMetadata(pathToItem, usedConfiguration, validatedPathToSchemas, new LinkedHashSet<>()); + getPathToSchemas(this, castArg, validationMetadata, pathSet); + return castArg; + } + + @Override + public boolean validate(boolean arg, SchemaConfiguration configuration) throws ValidationException, InvalidTypeException { + Set> pathSet = new HashSet<>(); + List pathToItem = List.of("args[0]"); + boolean castArg = castToAllowedTypes(arg, pathToItem, pathSet); + SchemaConfiguration usedConfiguration = Objects.requireNonNullElseGet(configuration, () -> new SchemaConfiguration(JsonSchemaKeywordFlags.ofNone())); + PathToSchemasMap validatedPathToSchemas = new PathToSchemasMap(); + ValidationMetadata validationMetadata = new ValidationMetadata(pathToItem, usedConfiguration, validatedPathToSchemas, new LinkedHashSet<>()); + getPathToSchemas(this, castArg, validationMetadata, pathSet); + return castArg; + } + + @Override + public Number validate(Number arg, SchemaConfiguration configuration) throws ValidationException, InvalidTypeException { + Set> pathSet = new HashSet<>(); + List pathToItem = List.of("args[0]"); + Number castArg = castToAllowedTypes(arg, pathToItem, pathSet); + SchemaConfiguration usedConfiguration = Objects.requireNonNullElseGet(configuration, () -> new SchemaConfiguration(JsonSchemaKeywordFlags.ofNone())); + PathToSchemasMap validatedPathToSchemas = new PathToSchemasMap(); + ValidationMetadata validationMetadata = new ValidationMetadata(pathToItem, usedConfiguration, validatedPathToSchemas, new LinkedHashSet<>()); + getPathToSchemas(this, castArg, validationMetadata, pathSet); + return castArg; + } + + public int validate(int arg, SchemaConfiguration configuration) { + return (int) validate((Number) arg, configuration); + } + + public long validate(long arg, SchemaConfiguration configuration) { + return (long) validate((Number) arg, configuration); + } + + public float validate(float arg, SchemaConfiguration configuration) { + return (float) validate((Number) arg, configuration); + } + + public double validate(double arg, SchemaConfiguration configuration) { + return (double) validate((Number) arg, configuration); + } + + @Override + public String validate(String arg, SchemaConfiguration configuration) throws ValidationException, InvalidTypeException { + Set> pathSet = new HashSet<>(); + List pathToItem = List.of("args[0]"); + String castArg = castToAllowedTypes(arg, pathToItem, pathSet); + SchemaConfiguration usedConfiguration = Objects.requireNonNullElseGet(configuration, () -> new SchemaConfiguration(JsonSchemaKeywordFlags.ofNone())); + PathToSchemasMap validatedPathToSchemas = new PathToSchemasMap(); + ValidationMetadata validationMetadata = new ValidationMetadata(pathToItem, usedConfiguration, validatedPathToSchemas, new LinkedHashSet<>()); + getPathToSchemas(this, castArg, validationMetadata, pathSet); + return castArg; + } + + public String validate(LocalDate arg, SchemaConfiguration configuration) throws ValidationException { + return validate(arg.toString(), configuration); + } + + public String validate(ZonedDateTime arg, SchemaConfiguration configuration) throws ValidationException { + return validate(arg.toString(), configuration); + } + + public String validate(UUID arg, SchemaConfiguration configuration) throws ValidationException { + return validate(arg.toString(), configuration); + } + + @Override + public FrozenList<@Nullable Object> getNewInstance(List arg, List pathToItem, PathToSchemasMap pathToSchemas) { + List<@Nullable Object> items = new ArrayList<>(); + int i = 0; + for (Object item: arg) { + List itemPathToItem = new ArrayList<>(pathToItem); + itemPathToItem.add(i); + LinkedHashMap schemas = pathToSchemas.get(itemPathToItem); + if (schemas == null) { + throw new InvalidTypeException("Validation result is invalid, schemas must exist for a pathToItem"); + } + JsonSchema itemSchema = schemas.entrySet().iterator().next().getKey(); + @Nullable Object itemInstance = itemSchema.getNewInstance(item, itemPathToItem, pathToSchemas); + items.add(itemInstance); + i += 1; + } + FrozenList<@Nullable Object> newInstanceItems = new FrozenList<>(items); + return newInstanceItems; + } + + public FrozenList<@Nullable Object> validate(List arg, SchemaConfiguration configuration) throws ValidationException { + Set> pathSet = new HashSet<>(); + List pathToItem = List.of("args[0"); + List castArg = castToAllowedTypes(arg, pathToItem, pathSet); + SchemaConfiguration usedConfiguration = Objects.requireNonNullElseGet(configuration, () -> new SchemaConfiguration(JsonSchemaKeywordFlags.ofNone())); + ValidationMetadata validationMetadata = new ValidationMetadata(pathToItem, usedConfiguration, new PathToSchemasMap(), new LinkedHashSet<>()); + PathToSchemasMap pathToSchemasMap = getPathToSchemas(this, castArg, validationMetadata, pathSet); + return getNewInstance(castArg, validationMetadata.pathToItem(), pathToSchemasMap); + } + + @Override + public FrozenMap<@Nullable Object> getNewInstance(Map arg, List pathToItem, PathToSchemasMap pathToSchemas) { + LinkedHashMap properties = new LinkedHashMap<>(); + for(Map.Entry entry: arg.entrySet()) { + @Nullable Object entryKey = entry.getKey(); + if (!(entryKey instanceof String)) { + throw new InvalidTypeException("Invalid non-string key value"); + } + String propertyName = (String) entryKey; + List propertyPathToItem = new ArrayList<>(pathToItem); + propertyPathToItem.add(propertyName); + Object value = entry.getValue(); + LinkedHashMap schemas = pathToSchemas.get(propertyPathToItem); + if (schemas == null) { + throw new InvalidTypeException("Validation result is invalid, schemas must exist for a pathToItem"); + } + JsonSchema propertySchema = schemas.entrySet().iterator().next().getKey(); + @Nullable Object propertyInstance = propertySchema.getNewInstance(value, propertyPathToItem, pathToSchemas); + properties.put(propertyName, propertyInstance); + } + FrozenMap<@Nullable Object> castProperties = new FrozenMap<>(properties); + return castProperties; + } + + public FrozenMap<@Nullable Object> validate(Map arg, SchemaConfiguration configuration) throws ValidationException, InvalidTypeException { + Set> pathSet = new HashSet<>(); + List pathToItem = List.of("args[0]"); + Map castArg = castToAllowedTypes(arg, pathToItem, pathSet); + SchemaConfiguration usedConfiguration = Objects.requireNonNullElseGet(configuration, () -> new SchemaConfiguration(JsonSchemaKeywordFlags.ofNone())); + PathToSchemasMap validatedPathToSchemas = new PathToSchemasMap(); + ValidationMetadata validationMetadata = new ValidationMetadata(pathToItem, usedConfiguration, validatedPathToSchemas, new LinkedHashSet<>()); + PathToSchemasMap pathToSchemasMap = getPathToSchemas(this, castArg, validationMetadata, pathSet); + return getNewInstance(castArg, validationMetadata.pathToItem(), pathToSchemasMap); + } + + @Override + public @Nullable Object validate(@Nullable Object arg, SchemaConfiguration configuration) throws ValidationException, InvalidTypeException { + if (arg == null) { + return validate((Void) null, configuration); + } else if (arg instanceof Boolean) { + boolean boolArg = (Boolean) arg; + return validate(boolArg, configuration); + } else if (arg instanceof Number) { + return validate((Number) arg, configuration); + } else if (arg instanceof String) { + return validate((String) arg, configuration); + } else if (arg instanceof List) { + return validate((List) arg, configuration); + } else if (arg instanceof Map) { + return validate((Map) arg, configuration); + } + throw new InvalidTypeException("Invalid input type="+getClass(arg)+". It can't be validated by this schema"); + } + @Override + public @Nullable Object getNewInstance(@Nullable Object arg, List pathToItem, PathToSchemasMap pathToSchemas) throws InvalidTypeException { + if (arg == null) { + return getNewInstance((Void) null, pathToItem, pathToSchemas); + } else if (arg instanceof Boolean) { + boolean boolArg = (Boolean) arg; + return getNewInstance(boolArg, pathToItem, pathToSchemas); + } else if (arg instanceof Number) { + return getNewInstance((Number) arg, pathToItem, pathToSchemas); + } else if (arg instanceof String) { + return getNewInstance((String) arg, pathToItem, pathToSchemas); + } else if (arg instanceof List) { + return getNewInstance((List) arg, pathToItem, pathToSchemas); + } else if (arg instanceof Map) { + return getNewInstance((Map) arg, pathToItem, pathToSchemas); + } + throw new InvalidTypeException("Invalid input type="+getClass(arg)+". It can't be instantiated by this schema"); + } + } +} diff --git a/samples/client/3_1_0_unit_test/java/src/main/java/org/openapijsonschematools/client/components/schemas/MultipleDependentsRequired.java b/samples/client/3_1_0_unit_test/java/src/main/java/org/openapijsonschematools/client/components/schemas/MultipleDependentsRequired.java new file mode 100644 index 00000000000..0f9fe53e24f --- /dev/null +++ b/samples/client/3_1_0_unit_test/java/src/main/java/org/openapijsonschematools/client/components/schemas/MultipleDependentsRequired.java @@ -0,0 +1,249 @@ +package org.openapijsonschematools.client.components.schemas; +import java.time.LocalDate; +import java.time.ZonedDateTime; +import java.util.AbstractMap; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.LinkedHashMap; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.Set; +import java.util.UUID; +import org.checkerframework.checker.nullness.qual.Nullable; +import org.openapijsonschematools.client.configurations.JsonSchemaKeywordFlags; +import org.openapijsonschematools.client.configurations.SchemaConfiguration; +import org.openapijsonschematools.client.exceptions.InvalidAdditionalPropertyException; +import org.openapijsonschematools.client.exceptions.InvalidTypeException; +import org.openapijsonschematools.client.exceptions.UnsetPropertyException; +import org.openapijsonschematools.client.exceptions.ValidationException; +import org.openapijsonschematools.client.schemas.SetMaker; +import org.openapijsonschematools.client.schemas.UnsetAddPropsSetter; +import org.openapijsonschematools.client.schemas.validation.BooleanSchemaValidator; +import org.openapijsonschematools.client.schemas.validation.FrozenList; +import org.openapijsonschematools.client.schemas.validation.FrozenMap; +import org.openapijsonschematools.client.schemas.validation.JsonSchema; +import org.openapijsonschematools.client.schemas.validation.JsonSchemaInfo; +import org.openapijsonschematools.client.schemas.validation.ListSchemaValidator; +import org.openapijsonschematools.client.schemas.validation.MapSchemaValidator; +import org.openapijsonschematools.client.schemas.validation.MapUtils; +import org.openapijsonschematools.client.schemas.validation.NullSchemaValidator; +import org.openapijsonschematools.client.schemas.validation.NumberSchemaValidator; +import org.openapijsonschematools.client.schemas.validation.PathToSchemasMap; +import org.openapijsonschematools.client.schemas.validation.StringSchemaValidator; +import org.openapijsonschematools.client.schemas.validation.ValidationMetadata; + +public class MultipleDependentsRequired { + // nest classes so all schemas and input/output classes can be public + + + public static class MultipleDependentsRequired1 extends JsonSchema implements NullSchemaValidator, BooleanSchemaValidator, NumberSchemaValidator, StringSchemaValidator, ListSchemaValidator>, MapSchemaValidator> { + /* + NOTE: This class is auto generated by OpenAPI JSON Schema Generator. + Ref: https://github.com/openapi-json-schema-tools/openapi-json-schema-generator + + Do not edit the class manually. + */ + private static @Nullable MultipleDependentsRequired1 instance = null; + + protected MultipleDependentsRequired1() { + super(new JsonSchemaInfo() + .dependentRequired(MapUtils.makeMap( + new AbstractMap.SimpleEntry<>( + "quux", + SetMaker.makeSet( + "foo", + "bar" + ) + ) + )) + ); + } + + public static MultipleDependentsRequired1 getInstance() { + if (instance == null) { + instance = new MultipleDependentsRequired1(); + } + return instance; + } + + @Override + public Void validate(Void arg, SchemaConfiguration configuration) throws ValidationException, InvalidTypeException { + Set> pathSet = new HashSet<>(); + List pathToItem = List.of("args[0]"); + Void castArg = castToAllowedTypes(arg, pathToItem, pathSet); + SchemaConfiguration usedConfiguration = Objects.requireNonNullElseGet(configuration, () -> new SchemaConfiguration(JsonSchemaKeywordFlags.ofNone())); + PathToSchemasMap validatedPathToSchemas = new PathToSchemasMap(); + ValidationMetadata validationMetadata = new ValidationMetadata(pathToItem, usedConfiguration, validatedPathToSchemas, new LinkedHashSet<>()); + getPathToSchemas(this, castArg, validationMetadata, pathSet); + return castArg; + } + + @Override + public boolean validate(boolean arg, SchemaConfiguration configuration) throws ValidationException, InvalidTypeException { + Set> pathSet = new HashSet<>(); + List pathToItem = List.of("args[0]"); + boolean castArg = castToAllowedTypes(arg, pathToItem, pathSet); + SchemaConfiguration usedConfiguration = Objects.requireNonNullElseGet(configuration, () -> new SchemaConfiguration(JsonSchemaKeywordFlags.ofNone())); + PathToSchemasMap validatedPathToSchemas = new PathToSchemasMap(); + ValidationMetadata validationMetadata = new ValidationMetadata(pathToItem, usedConfiguration, validatedPathToSchemas, new LinkedHashSet<>()); + getPathToSchemas(this, castArg, validationMetadata, pathSet); + return castArg; + } + + @Override + public Number validate(Number arg, SchemaConfiguration configuration) throws ValidationException, InvalidTypeException { + Set> pathSet = new HashSet<>(); + List pathToItem = List.of("args[0]"); + Number castArg = castToAllowedTypes(arg, pathToItem, pathSet); + SchemaConfiguration usedConfiguration = Objects.requireNonNullElseGet(configuration, () -> new SchemaConfiguration(JsonSchemaKeywordFlags.ofNone())); + PathToSchemasMap validatedPathToSchemas = new PathToSchemasMap(); + ValidationMetadata validationMetadata = new ValidationMetadata(pathToItem, usedConfiguration, validatedPathToSchemas, new LinkedHashSet<>()); + getPathToSchemas(this, castArg, validationMetadata, pathSet); + return castArg; + } + + public int validate(int arg, SchemaConfiguration configuration) { + return (int) validate((Number) arg, configuration); + } + + public long validate(long arg, SchemaConfiguration configuration) { + return (long) validate((Number) arg, configuration); + } + + public float validate(float arg, SchemaConfiguration configuration) { + return (float) validate((Number) arg, configuration); + } + + public double validate(double arg, SchemaConfiguration configuration) { + return (double) validate((Number) arg, configuration); + } + + @Override + public String validate(String arg, SchemaConfiguration configuration) throws ValidationException, InvalidTypeException { + Set> pathSet = new HashSet<>(); + List pathToItem = List.of("args[0]"); + String castArg = castToAllowedTypes(arg, pathToItem, pathSet); + SchemaConfiguration usedConfiguration = Objects.requireNonNullElseGet(configuration, () -> new SchemaConfiguration(JsonSchemaKeywordFlags.ofNone())); + PathToSchemasMap validatedPathToSchemas = new PathToSchemasMap(); + ValidationMetadata validationMetadata = new ValidationMetadata(pathToItem, usedConfiguration, validatedPathToSchemas, new LinkedHashSet<>()); + getPathToSchemas(this, castArg, validationMetadata, pathSet); + return castArg; + } + + public String validate(LocalDate arg, SchemaConfiguration configuration) throws ValidationException { + return validate(arg.toString(), configuration); + } + + public String validate(ZonedDateTime arg, SchemaConfiguration configuration) throws ValidationException { + return validate(arg.toString(), configuration); + } + + public String validate(UUID arg, SchemaConfiguration configuration) throws ValidationException { + return validate(arg.toString(), configuration); + } + + @Override + public FrozenList<@Nullable Object> getNewInstance(List arg, List pathToItem, PathToSchemasMap pathToSchemas) { + List<@Nullable Object> items = new ArrayList<>(); + int i = 0; + for (Object item: arg) { + List itemPathToItem = new ArrayList<>(pathToItem); + itemPathToItem.add(i); + LinkedHashMap schemas = pathToSchemas.get(itemPathToItem); + if (schemas == null) { + throw new InvalidTypeException("Validation result is invalid, schemas must exist for a pathToItem"); + } + JsonSchema itemSchema = schemas.entrySet().iterator().next().getKey(); + @Nullable Object itemInstance = itemSchema.getNewInstance(item, itemPathToItem, pathToSchemas); + items.add(itemInstance); + i += 1; + } + FrozenList<@Nullable Object> newInstanceItems = new FrozenList<>(items); + return newInstanceItems; + } + + public FrozenList<@Nullable Object> validate(List arg, SchemaConfiguration configuration) throws ValidationException { + Set> pathSet = new HashSet<>(); + List pathToItem = List.of("args[0"); + List castArg = castToAllowedTypes(arg, pathToItem, pathSet); + SchemaConfiguration usedConfiguration = Objects.requireNonNullElseGet(configuration, () -> new SchemaConfiguration(JsonSchemaKeywordFlags.ofNone())); + ValidationMetadata validationMetadata = new ValidationMetadata(pathToItem, usedConfiguration, new PathToSchemasMap(), new LinkedHashSet<>()); + PathToSchemasMap pathToSchemasMap = getPathToSchemas(this, castArg, validationMetadata, pathSet); + return getNewInstance(castArg, validationMetadata.pathToItem(), pathToSchemasMap); + } + + @Override + public FrozenMap<@Nullable Object> getNewInstance(Map arg, List pathToItem, PathToSchemasMap pathToSchemas) { + LinkedHashMap properties = new LinkedHashMap<>(); + for(Map.Entry entry: arg.entrySet()) { + @Nullable Object entryKey = entry.getKey(); + if (!(entryKey instanceof String)) { + throw new InvalidTypeException("Invalid non-string key value"); + } + String propertyName = (String) entryKey; + List propertyPathToItem = new ArrayList<>(pathToItem); + propertyPathToItem.add(propertyName); + Object value = entry.getValue(); + LinkedHashMap schemas = pathToSchemas.get(propertyPathToItem); + if (schemas == null) { + throw new InvalidTypeException("Validation result is invalid, schemas must exist for a pathToItem"); + } + JsonSchema propertySchema = schemas.entrySet().iterator().next().getKey(); + @Nullable Object propertyInstance = propertySchema.getNewInstance(value, propertyPathToItem, pathToSchemas); + properties.put(propertyName, propertyInstance); + } + FrozenMap<@Nullable Object> castProperties = new FrozenMap<>(properties); + return castProperties; + } + + public FrozenMap<@Nullable Object> validate(Map arg, SchemaConfiguration configuration) throws ValidationException, InvalidTypeException { + Set> pathSet = new HashSet<>(); + List pathToItem = List.of("args[0]"); + Map castArg = castToAllowedTypes(arg, pathToItem, pathSet); + SchemaConfiguration usedConfiguration = Objects.requireNonNullElseGet(configuration, () -> new SchemaConfiguration(JsonSchemaKeywordFlags.ofNone())); + PathToSchemasMap validatedPathToSchemas = new PathToSchemasMap(); + ValidationMetadata validationMetadata = new ValidationMetadata(pathToItem, usedConfiguration, validatedPathToSchemas, new LinkedHashSet<>()); + PathToSchemasMap pathToSchemasMap = getPathToSchemas(this, castArg, validationMetadata, pathSet); + return getNewInstance(castArg, validationMetadata.pathToItem(), pathToSchemasMap); + } + + @Override + public @Nullable Object validate(@Nullable Object arg, SchemaConfiguration configuration) throws ValidationException, InvalidTypeException { + if (arg == null) { + return validate((Void) null, configuration); + } else if (arg instanceof Boolean) { + boolean boolArg = (Boolean) arg; + return validate(boolArg, configuration); + } else if (arg instanceof Number) { + return validate((Number) arg, configuration); + } else if (arg instanceof String) { + return validate((String) arg, configuration); + } else if (arg instanceof List) { + return validate((List) arg, configuration); + } else if (arg instanceof Map) { + return validate((Map) arg, configuration); + } + throw new InvalidTypeException("Invalid input type="+getClass(arg)+". It can't be validated by this schema"); + } + @Override + public @Nullable Object getNewInstance(@Nullable Object arg, List pathToItem, PathToSchemasMap pathToSchemas) throws InvalidTypeException { + if (arg == null) { + return getNewInstance((Void) null, pathToItem, pathToSchemas); + } else if (arg instanceof Boolean) { + boolean boolArg = (Boolean) arg; + return getNewInstance(boolArg, pathToItem, pathToSchemas); + } else if (arg instanceof Number) { + return getNewInstance((Number) arg, pathToItem, pathToSchemas); + } else if (arg instanceof String) { + return getNewInstance((String) arg, pathToItem, pathToSchemas); + } else if (arg instanceof List) { + return getNewInstance((List) arg, pathToItem, pathToSchemas); + } else if (arg instanceof Map) { + return getNewInstance((Map) arg, pathToItem, pathToSchemas); + } + throw new InvalidTypeException("Invalid input type="+getClass(arg)+". It can't be instantiated by this schema"); + } + } +} diff --git a/samples/client/3_1_0_unit_test/java/src/main/java/org/openapijsonschematools/client/components/schemas/SingleDependency.java b/samples/client/3_1_0_unit_test/java/src/main/java/org/openapijsonschematools/client/components/schemas/SingleDependency.java new file mode 100644 index 00000000000..cfc9495291e --- /dev/null +++ b/samples/client/3_1_0_unit_test/java/src/main/java/org/openapijsonschematools/client/components/schemas/SingleDependency.java @@ -0,0 +1,248 @@ +package org.openapijsonschematools.client.components.schemas; +import java.time.LocalDate; +import java.time.ZonedDateTime; +import java.util.AbstractMap; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.LinkedHashMap; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.Set; +import java.util.UUID; +import org.checkerframework.checker.nullness.qual.Nullable; +import org.openapijsonschematools.client.configurations.JsonSchemaKeywordFlags; +import org.openapijsonschematools.client.configurations.SchemaConfiguration; +import org.openapijsonschematools.client.exceptions.InvalidAdditionalPropertyException; +import org.openapijsonschematools.client.exceptions.InvalidTypeException; +import org.openapijsonschematools.client.exceptions.UnsetPropertyException; +import org.openapijsonschematools.client.exceptions.ValidationException; +import org.openapijsonschematools.client.schemas.SetMaker; +import org.openapijsonschematools.client.schemas.UnsetAddPropsSetter; +import org.openapijsonschematools.client.schemas.validation.BooleanSchemaValidator; +import org.openapijsonschematools.client.schemas.validation.FrozenList; +import org.openapijsonschematools.client.schemas.validation.FrozenMap; +import org.openapijsonschematools.client.schemas.validation.JsonSchema; +import org.openapijsonschematools.client.schemas.validation.JsonSchemaInfo; +import org.openapijsonschematools.client.schemas.validation.ListSchemaValidator; +import org.openapijsonschematools.client.schemas.validation.MapSchemaValidator; +import org.openapijsonschematools.client.schemas.validation.MapUtils; +import org.openapijsonschematools.client.schemas.validation.NullSchemaValidator; +import org.openapijsonschematools.client.schemas.validation.NumberSchemaValidator; +import org.openapijsonschematools.client.schemas.validation.PathToSchemasMap; +import org.openapijsonschematools.client.schemas.validation.StringSchemaValidator; +import org.openapijsonschematools.client.schemas.validation.ValidationMetadata; + +public class SingleDependency { + // nest classes so all schemas and input/output classes can be public + + + public static class SingleDependency1 extends JsonSchema implements NullSchemaValidator, BooleanSchemaValidator, NumberSchemaValidator, StringSchemaValidator, ListSchemaValidator>, MapSchemaValidator> { + /* + NOTE: This class is auto generated by OpenAPI JSON Schema Generator. + Ref: https://github.com/openapi-json-schema-tools/openapi-json-schema-generator + + Do not edit the class manually. + */ + private static @Nullable SingleDependency1 instance = null; + + protected SingleDependency1() { + super(new JsonSchemaInfo() + .dependentRequired(MapUtils.makeMap( + new AbstractMap.SimpleEntry<>( + "bar", + SetMaker.makeSet( + "foo" + ) + ) + )) + ); + } + + public static SingleDependency1 getInstance() { + if (instance == null) { + instance = new SingleDependency1(); + } + return instance; + } + + @Override + public Void validate(Void arg, SchemaConfiguration configuration) throws ValidationException, InvalidTypeException { + Set> pathSet = new HashSet<>(); + List pathToItem = List.of("args[0]"); + Void castArg = castToAllowedTypes(arg, pathToItem, pathSet); + SchemaConfiguration usedConfiguration = Objects.requireNonNullElseGet(configuration, () -> new SchemaConfiguration(JsonSchemaKeywordFlags.ofNone())); + PathToSchemasMap validatedPathToSchemas = new PathToSchemasMap(); + ValidationMetadata validationMetadata = new ValidationMetadata(pathToItem, usedConfiguration, validatedPathToSchemas, new LinkedHashSet<>()); + getPathToSchemas(this, castArg, validationMetadata, pathSet); + return castArg; + } + + @Override + public boolean validate(boolean arg, SchemaConfiguration configuration) throws ValidationException, InvalidTypeException { + Set> pathSet = new HashSet<>(); + List pathToItem = List.of("args[0]"); + boolean castArg = castToAllowedTypes(arg, pathToItem, pathSet); + SchemaConfiguration usedConfiguration = Objects.requireNonNullElseGet(configuration, () -> new SchemaConfiguration(JsonSchemaKeywordFlags.ofNone())); + PathToSchemasMap validatedPathToSchemas = new PathToSchemasMap(); + ValidationMetadata validationMetadata = new ValidationMetadata(pathToItem, usedConfiguration, validatedPathToSchemas, new LinkedHashSet<>()); + getPathToSchemas(this, castArg, validationMetadata, pathSet); + return castArg; + } + + @Override + public Number validate(Number arg, SchemaConfiguration configuration) throws ValidationException, InvalidTypeException { + Set> pathSet = new HashSet<>(); + List pathToItem = List.of("args[0]"); + Number castArg = castToAllowedTypes(arg, pathToItem, pathSet); + SchemaConfiguration usedConfiguration = Objects.requireNonNullElseGet(configuration, () -> new SchemaConfiguration(JsonSchemaKeywordFlags.ofNone())); + PathToSchemasMap validatedPathToSchemas = new PathToSchemasMap(); + ValidationMetadata validationMetadata = new ValidationMetadata(pathToItem, usedConfiguration, validatedPathToSchemas, new LinkedHashSet<>()); + getPathToSchemas(this, castArg, validationMetadata, pathSet); + return castArg; + } + + public int validate(int arg, SchemaConfiguration configuration) { + return (int) validate((Number) arg, configuration); + } + + public long validate(long arg, SchemaConfiguration configuration) { + return (long) validate((Number) arg, configuration); + } + + public float validate(float arg, SchemaConfiguration configuration) { + return (float) validate((Number) arg, configuration); + } + + public double validate(double arg, SchemaConfiguration configuration) { + return (double) validate((Number) arg, configuration); + } + + @Override + public String validate(String arg, SchemaConfiguration configuration) throws ValidationException, InvalidTypeException { + Set> pathSet = new HashSet<>(); + List pathToItem = List.of("args[0]"); + String castArg = castToAllowedTypes(arg, pathToItem, pathSet); + SchemaConfiguration usedConfiguration = Objects.requireNonNullElseGet(configuration, () -> new SchemaConfiguration(JsonSchemaKeywordFlags.ofNone())); + PathToSchemasMap validatedPathToSchemas = new PathToSchemasMap(); + ValidationMetadata validationMetadata = new ValidationMetadata(pathToItem, usedConfiguration, validatedPathToSchemas, new LinkedHashSet<>()); + getPathToSchemas(this, castArg, validationMetadata, pathSet); + return castArg; + } + + public String validate(LocalDate arg, SchemaConfiguration configuration) throws ValidationException { + return validate(arg.toString(), configuration); + } + + public String validate(ZonedDateTime arg, SchemaConfiguration configuration) throws ValidationException { + return validate(arg.toString(), configuration); + } + + public String validate(UUID arg, SchemaConfiguration configuration) throws ValidationException { + return validate(arg.toString(), configuration); + } + + @Override + public FrozenList<@Nullable Object> getNewInstance(List arg, List pathToItem, PathToSchemasMap pathToSchemas) { + List<@Nullable Object> items = new ArrayList<>(); + int i = 0; + for (Object item: arg) { + List itemPathToItem = new ArrayList<>(pathToItem); + itemPathToItem.add(i); + LinkedHashMap schemas = pathToSchemas.get(itemPathToItem); + if (schemas == null) { + throw new InvalidTypeException("Validation result is invalid, schemas must exist for a pathToItem"); + } + JsonSchema itemSchema = schemas.entrySet().iterator().next().getKey(); + @Nullable Object itemInstance = itemSchema.getNewInstance(item, itemPathToItem, pathToSchemas); + items.add(itemInstance); + i += 1; + } + FrozenList<@Nullable Object> newInstanceItems = new FrozenList<>(items); + return newInstanceItems; + } + + public FrozenList<@Nullable Object> validate(List arg, SchemaConfiguration configuration) throws ValidationException { + Set> pathSet = new HashSet<>(); + List pathToItem = List.of("args[0"); + List castArg = castToAllowedTypes(arg, pathToItem, pathSet); + SchemaConfiguration usedConfiguration = Objects.requireNonNullElseGet(configuration, () -> new SchemaConfiguration(JsonSchemaKeywordFlags.ofNone())); + ValidationMetadata validationMetadata = new ValidationMetadata(pathToItem, usedConfiguration, new PathToSchemasMap(), new LinkedHashSet<>()); + PathToSchemasMap pathToSchemasMap = getPathToSchemas(this, castArg, validationMetadata, pathSet); + return getNewInstance(castArg, validationMetadata.pathToItem(), pathToSchemasMap); + } + + @Override + public FrozenMap<@Nullable Object> getNewInstance(Map arg, List pathToItem, PathToSchemasMap pathToSchemas) { + LinkedHashMap properties = new LinkedHashMap<>(); + for(Map.Entry entry: arg.entrySet()) { + @Nullable Object entryKey = entry.getKey(); + if (!(entryKey instanceof String)) { + throw new InvalidTypeException("Invalid non-string key value"); + } + String propertyName = (String) entryKey; + List propertyPathToItem = new ArrayList<>(pathToItem); + propertyPathToItem.add(propertyName); + Object value = entry.getValue(); + LinkedHashMap schemas = pathToSchemas.get(propertyPathToItem); + if (schemas == null) { + throw new InvalidTypeException("Validation result is invalid, schemas must exist for a pathToItem"); + } + JsonSchema propertySchema = schemas.entrySet().iterator().next().getKey(); + @Nullable Object propertyInstance = propertySchema.getNewInstance(value, propertyPathToItem, pathToSchemas); + properties.put(propertyName, propertyInstance); + } + FrozenMap<@Nullable Object> castProperties = new FrozenMap<>(properties); + return castProperties; + } + + public FrozenMap<@Nullable Object> validate(Map arg, SchemaConfiguration configuration) throws ValidationException, InvalidTypeException { + Set> pathSet = new HashSet<>(); + List pathToItem = List.of("args[0]"); + Map castArg = castToAllowedTypes(arg, pathToItem, pathSet); + SchemaConfiguration usedConfiguration = Objects.requireNonNullElseGet(configuration, () -> new SchemaConfiguration(JsonSchemaKeywordFlags.ofNone())); + PathToSchemasMap validatedPathToSchemas = new PathToSchemasMap(); + ValidationMetadata validationMetadata = new ValidationMetadata(pathToItem, usedConfiguration, validatedPathToSchemas, new LinkedHashSet<>()); + PathToSchemasMap pathToSchemasMap = getPathToSchemas(this, castArg, validationMetadata, pathSet); + return getNewInstance(castArg, validationMetadata.pathToItem(), pathToSchemasMap); + } + + @Override + public @Nullable Object validate(@Nullable Object arg, SchemaConfiguration configuration) throws ValidationException, InvalidTypeException { + if (arg == null) { + return validate((Void) null, configuration); + } else if (arg instanceof Boolean) { + boolean boolArg = (Boolean) arg; + return validate(boolArg, configuration); + } else if (arg instanceof Number) { + return validate((Number) arg, configuration); + } else if (arg instanceof String) { + return validate((String) arg, configuration); + } else if (arg instanceof List) { + return validate((List) arg, configuration); + } else if (arg instanceof Map) { + return validate((Map) arg, configuration); + } + throw new InvalidTypeException("Invalid input type="+getClass(arg)+". It can't be validated by this schema"); + } + @Override + public @Nullable Object getNewInstance(@Nullable Object arg, List pathToItem, PathToSchemasMap pathToSchemas) throws InvalidTypeException { + if (arg == null) { + return getNewInstance((Void) null, pathToItem, pathToSchemas); + } else if (arg instanceof Boolean) { + boolean boolArg = (Boolean) arg; + return getNewInstance(boolArg, pathToItem, pathToSchemas); + } else if (arg instanceof Number) { + return getNewInstance((Number) arg, pathToItem, pathToSchemas); + } else if (arg instanceof String) { + return getNewInstance((String) arg, pathToItem, pathToSchemas); + } else if (arg instanceof List) { + return getNewInstance((List) arg, pathToItem, pathToSchemas); + } else if (arg instanceof Map) { + return getNewInstance((Map) arg, pathToItem, pathToSchemas); + } + throw new InvalidTypeException("Invalid input type="+getClass(arg)+". It can't be instantiated by this schema"); + } + } +} diff --git a/samples/client/3_1_0_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/DependentSchemasValidator.java b/samples/client/3_1_0_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/DependentSchemasValidator.java new file mode 100644 index 00000000000..a689279e1e1 --- /dev/null +++ b/samples/client/3_1_0_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/DependentSchemasValidator.java @@ -0,0 +1,48 @@ +package org.openapijsonschematools.client.schemas.validation; + +import org.checkerframework.checker.nullness.qual.Nullable; + +import java.util.ArrayList; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +public class DependentSchemasValidator implements KeywordValidator { + public final Map> dependentSchemas; + + public DependentSchemasValidator(Map> dependentSchemas) { + this.dependentSchemas = dependentSchemas; + } + + @Override + public @Nullable PathToSchemasMap validate( + JsonSchema schema, + @Nullable Object arg, + ValidationMetadata validationMetadata, + @Nullable List containsPathToSchemas + ) { + if (!(arg instanceof Map mapArg)) { + return null; + } + PathToSchemasMap pathToSchemas = new PathToSchemasMap(); + Set presentProperties = new LinkedHashSet<>(); + for (Object key: mapArg.keySet()) { + if (key instanceof String) { + presentProperties.add((String) key); + } + } + for(Map.Entry> entry: dependentSchemas.entrySet()) { + String propName = entry.getKey(); + if (!presentProperties.contains(propName)) { + continue; + } + Class dependentSchemaClass = entry.getValue(); + JsonSchema dependentSchema = JsonSchemaFactory.getInstance(dependentSchemaClass); + PathToSchemasMap otherPathToSchemas = JsonSchema.validate(dependentSchema, arg, validationMetadata); + pathToSchemas.update(otherPathToSchemas); + } + return pathToSchemas; + } +} + diff --git a/samples/client/3_1_0_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/JsonSchema.java b/samples/client/3_1_0_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/JsonSchema.java index 9d7831b6225..562dc06cab0 100644 --- a/samples/client/3_1_0_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/JsonSchema.java +++ b/samples/client/3_1_0_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/JsonSchema.java @@ -51,6 +51,7 @@ public abstract class JsonSchema { public final @Nullable Integer minContains; public final @Nullable Class propertyNames; public @Nullable Map> dependentRequired; + public final @Nullable Map> dependentSchemas; private final LinkedHashMap keywordToValidator; protected JsonSchema(JsonSchemaInfo jsonSchemaInfo) { @@ -268,6 +269,13 @@ protected JsonSchema(JsonSchemaInfo jsonSchemaInfo) { new DependentRequiredValidator(this.dependentRequired) ); } + this.dependentSchemas = jsonSchemaInfo.dependentSchemas; + if (this.dependentSchemas != null) { + keywordToValidator.put( + "dependentSchemas", + new DependentSchemasValidator(this.dependentSchemas) + ); + } this.keywordToValidator = keywordToValidator; } diff --git a/samples/client/3_1_0_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/JsonSchemaInfo.java b/samples/client/3_1_0_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/JsonSchemaInfo.java index 59f51a6be72..c4f4ddf1042 100644 --- a/samples/client/3_1_0_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/JsonSchemaInfo.java +++ b/samples/client/3_1_0_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/JsonSchemaInfo.java @@ -167,4 +167,9 @@ public JsonSchemaInfo dependentRequired(Map> dependentRequir this.dependentRequired = dependentRequired; return this; } + public @Nullable Map> dependentSchemas = null; + public JsonSchemaInfo dependentSchemas(Map> dependentSchemas) { + this.dependentSchemas = dependentSchemas; + return this; + } } \ No newline at end of file diff --git a/samples/client/3_1_0_unit_test/java/src/test/java/org/openapijsonschematools/client/components/schemas/DependentSchemasDependenciesWithEscapedCharactersTest.java b/samples/client/3_1_0_unit_test/java/src/test/java/org/openapijsonschematools/client/components/schemas/DependentSchemasDependenciesWithEscapedCharactersTest.java new file mode 100644 index 00000000000..97d5a50e14d --- /dev/null +++ b/samples/client/3_1_0_unit_test/java/src/test/java/org/openapijsonschematools/client/components/schemas/DependentSchemasDependenciesWithEscapedCharactersTest.java @@ -0,0 +1,115 @@ +package org.openapijsonschematools.client.components.schemas; + +import org.junit.Assert; +import org.junit.Test; +import org.openapijsonschematools.client.configurations.JsonSchemaKeywordFlags; +import org.openapijsonschematools.client.configurations.SchemaConfiguration; +import org.openapijsonschematools.client.exceptions.ValidationException; +import org.openapijsonschematools.client.exceptions.InvalidTypeException; +import org.openapijsonschematools.client.schemas.validation.MapUtils; +import org.checkerframework.checker.nullness.qual.Nullable; + +import java.util.Arrays; +import java.util.List; +import java.util.Map; +import java.util.AbstractMap; + +public class DependentSchemasDependenciesWithEscapedCharactersTest { + static final SchemaConfiguration configuration = new SchemaConfiguration(JsonSchemaKeywordFlags.onlyFormat()); + + @Test + public void testQuotedQuoteInvalidUnderDependentSchemaFails() { + // quoted quote invalid under dependent schema + final var schema = DependentSchemasDependenciesWithEscapedCharacters.DependentSchemasDependenciesWithEscapedCharacters1.getInstance(); + try { + schema.validate( + MapUtils.makeMap( + new AbstractMap.SimpleEntry( + "foo'bar", + 1 + ) + ), + configuration + ); + throw new RuntimeException("A different exception must be thrown"); + } catch (ValidationException | InvalidTypeException ignored) { + ; + } + } + + @Test + public void testQuotedTabInvalidUnderDependentSchemaFails() { + // quoted tab invalid under dependent schema + final var schema = DependentSchemasDependenciesWithEscapedCharacters.DependentSchemasDependenciesWithEscapedCharacters1.getInstance(); + try { + schema.validate( + MapUtils.makeMap( + new AbstractMap.SimpleEntry( + "foo\tbar", + 1 + ), + new AbstractMap.SimpleEntry( + "a", + 2 + ) + ), + configuration + ); + throw new RuntimeException("A different exception must be thrown"); + } catch (ValidationException | InvalidTypeException ignored) { + ; + } + } + + @Test + public void testQuotedTabPasses() { + // quoted tab + final var schema = DependentSchemasDependenciesWithEscapedCharacters.DependentSchemasDependenciesWithEscapedCharacters1.getInstance(); + schema.validate( + MapUtils.makeMap( + new AbstractMap.SimpleEntry( + "foo\tbar", + 1 + ), + new AbstractMap.SimpleEntry( + "a", + 2 + ), + new AbstractMap.SimpleEntry( + "b", + 3 + ), + new AbstractMap.SimpleEntry( + "c", + 4 + ) + ), + configuration + ); + } + + @Test + public void testQuotedQuoteFails() { + // quoted quote + final var schema = DependentSchemasDependenciesWithEscapedCharacters.DependentSchemasDependenciesWithEscapedCharacters1.getInstance(); + try { + schema.validate( + MapUtils.makeMap( + new AbstractMap.SimpleEntry>( + "foo'bar", + MapUtils.makeMap( + new AbstractMap.SimpleEntry( + "foo\"bar", + 1 + ) + ) + ) + ), + configuration + ); + throw new RuntimeException("A different exception must be thrown"); + } catch (ValidationException | InvalidTypeException ignored) { + ; + } + } +} diff --git a/samples/client/3_1_0_unit_test/java/src/test/java/org/openapijsonschematools/client/components/schemas/DependentSchemasDependentSubschemaIncompatibleWithRootTest.java b/samples/client/3_1_0_unit_test/java/src/test/java/org/openapijsonschematools/client/components/schemas/DependentSchemasDependentSubschemaIncompatibleWithRootTest.java new file mode 100644 index 00000000000..85c57a20c0f --- /dev/null +++ b/samples/client/3_1_0_unit_test/java/src/test/java/org/openapijsonschematools/client/components/schemas/DependentSchemasDependentSubschemaIncompatibleWithRootTest.java @@ -0,0 +1,93 @@ +package org.openapijsonschematools.client.components.schemas; + +import org.junit.Assert; +import org.junit.Test; +import org.openapijsonschematools.client.configurations.JsonSchemaKeywordFlags; +import org.openapijsonschematools.client.configurations.SchemaConfiguration; +import org.openapijsonschematools.client.exceptions.ValidationException; +import org.openapijsonschematools.client.exceptions.InvalidTypeException; +import org.openapijsonschematools.client.schemas.validation.MapUtils; +import org.checkerframework.checker.nullness.qual.Nullable; + +import java.util.Arrays; +import java.util.List; +import java.util.Map; +import java.util.AbstractMap; + +public class DependentSchemasDependentSubschemaIncompatibleWithRootTest { + static final SchemaConfiguration configuration = new SchemaConfiguration(JsonSchemaKeywordFlags.onlyFormat()); + + @Test + public void testMatchesRootFails() { + // matches root + final var schema = DependentSchemasDependentSubschemaIncompatibleWithRoot.DependentSchemasDependentSubschemaIncompatibleWithRoot1.getInstance(); + try { + schema.validate( + MapUtils.makeMap( + new AbstractMap.SimpleEntry( + "foo", + 1 + ) + ), + configuration + ); + throw new RuntimeException("A different exception must be thrown"); + } catch (ValidationException | InvalidTypeException ignored) { + ; + } + } + + @Test + public void testMatchesDependencyPasses() { + // matches dependency + final var schema = DependentSchemasDependentSubschemaIncompatibleWithRoot.DependentSchemasDependentSubschemaIncompatibleWithRoot1.getInstance(); + schema.validate( + MapUtils.makeMap( + new AbstractMap.SimpleEntry( + "bar", + 1 + ) + ), + configuration + ); + } + + @Test + public void testNoDependencyPasses() { + // no dependency + final var schema = DependentSchemasDependentSubschemaIncompatibleWithRoot.DependentSchemasDependentSubschemaIncompatibleWithRoot1.getInstance(); + schema.validate( + MapUtils.makeMap( + new AbstractMap.SimpleEntry( + "baz", + 1 + ) + ), + configuration + ); + } + + @Test + public void testMatchesBothFails() { + // matches both + final var schema = DependentSchemasDependentSubschemaIncompatibleWithRoot.DependentSchemasDependentSubschemaIncompatibleWithRoot1.getInstance(); + try { + schema.validate( + MapUtils.makeMap( + new AbstractMap.SimpleEntry( + "foo", + 1 + ), + new AbstractMap.SimpleEntry( + "bar", + 2 + ) + ), + configuration + ); + throw new RuntimeException("A different exception must be thrown"); + } catch (ValidationException | InvalidTypeException ignored) { + ; + } + } +} diff --git a/samples/client/3_1_0_unit_test/java/src/test/java/org/openapijsonschematools/client/components/schemas/DependentSchemasSingleDependencyTest.java b/samples/client/3_1_0_unit_test/java/src/test/java/org/openapijsonschematools/client/components/schemas/DependentSchemasSingleDependencyTest.java new file mode 100644 index 00000000000..6c162125f0e --- /dev/null +++ b/samples/client/3_1_0_unit_test/java/src/test/java/org/openapijsonschematools/client/components/schemas/DependentSchemasSingleDependencyTest.java @@ -0,0 +1,157 @@ +package org.openapijsonschematools.client.components.schemas; + +import org.junit.Assert; +import org.junit.Test; +import org.openapijsonschematools.client.configurations.JsonSchemaKeywordFlags; +import org.openapijsonschematools.client.configurations.SchemaConfiguration; +import org.openapijsonschematools.client.exceptions.ValidationException; +import org.openapijsonschematools.client.exceptions.InvalidTypeException; +import org.openapijsonschematools.client.schemas.validation.MapUtils; +import org.checkerframework.checker.nullness.qual.Nullable; + +import java.util.Arrays; +import java.util.List; +import java.util.Map; +import java.util.AbstractMap; + +public class DependentSchemasSingleDependencyTest { + static final SchemaConfiguration configuration = new SchemaConfiguration(JsonSchemaKeywordFlags.onlyFormat()); + + @Test + public void testWrongTypeFails() { + // wrong type + final var schema = DependentSchemasSingleDependency.DependentSchemasSingleDependency1.getInstance(); + try { + schema.validate( + MapUtils.makeMap( + new AbstractMap.SimpleEntry( + "foo", + "quux" + ), + new AbstractMap.SimpleEntry( + "bar", + 2 + ) + ), + configuration + ); + throw new RuntimeException("A different exception must be thrown"); + } catch (ValidationException | InvalidTypeException ignored) { + ; + } + } + + @Test + public void testValidPasses() { + // valid + final var schema = DependentSchemasSingleDependency.DependentSchemasSingleDependency1.getInstance(); + schema.validate( + MapUtils.makeMap( + new AbstractMap.SimpleEntry( + "foo", + 1 + ), + new AbstractMap.SimpleEntry( + "bar", + 2 + ) + ), + configuration + ); + } + + @Test + public void testNoDependencyPasses() { + // no dependency + final var schema = DependentSchemasSingleDependency.DependentSchemasSingleDependency1.getInstance(); + schema.validate( + MapUtils.makeMap( + new AbstractMap.SimpleEntry( + "foo", + "quux" + ) + ), + configuration + ); + } + + @Test + public void testIgnoresOtherNonObjectsPasses() { + // ignores other non-objects + final var schema = DependentSchemasSingleDependency.DependentSchemasSingleDependency1.getInstance(); + schema.validate( + 12, + configuration + ); + } + + @Test + public void testIgnoresArraysPasses() { + // ignores arrays + final var schema = DependentSchemasSingleDependency.DependentSchemasSingleDependency1.getInstance(); + schema.validate( + Arrays.asList( + "bar" + ), + configuration + ); + } + + @Test + public void testWrongTypeBothFails() { + // wrong type both + final var schema = DependentSchemasSingleDependency.DependentSchemasSingleDependency1.getInstance(); + try { + schema.validate( + MapUtils.makeMap( + new AbstractMap.SimpleEntry( + "foo", + "quux" + ), + new AbstractMap.SimpleEntry( + "bar", + "quux" + ) + ), + configuration + ); + throw new RuntimeException("A different exception must be thrown"); + } catch (ValidationException | InvalidTypeException ignored) { + ; + } + } + + @Test + public void testIgnoresStringsPasses() { + // ignores strings + final var schema = DependentSchemasSingleDependency.DependentSchemasSingleDependency1.getInstance(); + schema.validate( + "foobar", + configuration + ); + } + + @Test + public void testWrongTypeOtherFails() { + // wrong type other + final var schema = DependentSchemasSingleDependency.DependentSchemasSingleDependency1.getInstance(); + try { + schema.validate( + MapUtils.makeMap( + new AbstractMap.SimpleEntry( + "foo", + 2 + ), + new AbstractMap.SimpleEntry( + "bar", + "quux" + ) + ), + configuration + ); + throw new RuntimeException("A different exception must be thrown"); + } catch (ValidationException | InvalidTypeException ignored) { + ; + } + } +} diff --git a/samples/client/3_1_0_unit_test/java/src/test/java/org/openapijsonschematools/client/components/schemas/MultipleDependentsRequiredTest.java b/samples/client/3_1_0_unit_test/java/src/test/java/org/openapijsonschematools/client/components/schemas/MultipleDependentsRequiredTest.java new file mode 100644 index 00000000000..bb9842bf28e --- /dev/null +++ b/samples/client/3_1_0_unit_test/java/src/test/java/org/openapijsonschematools/client/components/schemas/MultipleDependentsRequiredTest.java @@ -0,0 +1,140 @@ +package org.openapijsonschematools.client.components.schemas; + +import org.junit.Assert; +import org.junit.Test; +import org.openapijsonschematools.client.configurations.JsonSchemaKeywordFlags; +import org.openapijsonschematools.client.configurations.SchemaConfiguration; +import org.openapijsonschematools.client.exceptions.ValidationException; +import org.openapijsonschematools.client.exceptions.InvalidTypeException; +import org.openapijsonschematools.client.schemas.validation.MapUtils; +import org.checkerframework.checker.nullness.qual.Nullable; + +import java.util.Arrays; +import java.util.List; +import java.util.Map; +import java.util.AbstractMap; + +public class MultipleDependentsRequiredTest { + static final SchemaConfiguration configuration = new SchemaConfiguration(JsonSchemaKeywordFlags.onlyFormat()); + + @Test + public void testNondependantsPasses() { + // nondependants + final var schema = MultipleDependentsRequired.MultipleDependentsRequired1.getInstance(); + schema.validate( + MapUtils.makeMap( + new AbstractMap.SimpleEntry( + "foo", + 1 + ), + new AbstractMap.SimpleEntry( + "bar", + 2 + ) + ), + configuration + ); + } + + @Test + public void testMissingOtherDependencyFails() { + // missing other dependency + final var schema = MultipleDependentsRequired.MultipleDependentsRequired1.getInstance(); + try { + schema.validate( + MapUtils.makeMap( + new AbstractMap.SimpleEntry( + "bar", + 1 + ), + new AbstractMap.SimpleEntry( + "quux", + 2 + ) + ), + configuration + ); + throw new RuntimeException("A different exception must be thrown"); + } catch (ValidationException | InvalidTypeException ignored) { + ; + } + } + + @Test + public void testWithDependenciesPasses() { + // with dependencies + final var schema = MultipleDependentsRequired.MultipleDependentsRequired1.getInstance(); + schema.validate( + MapUtils.makeMap( + new AbstractMap.SimpleEntry( + "foo", + 1 + ), + new AbstractMap.SimpleEntry( + "bar", + 2 + ), + new AbstractMap.SimpleEntry( + "quux", + 3 + ) + ), + configuration + ); + } + + @Test + public void testMissingBothDependenciesFails() { + // missing both dependencies + final var schema = MultipleDependentsRequired.MultipleDependentsRequired1.getInstance(); + try { + schema.validate( + MapUtils.makeMap( + new AbstractMap.SimpleEntry( + "quux", + 1 + ) + ), + configuration + ); + throw new RuntimeException("A different exception must be thrown"); + } catch (ValidationException | InvalidTypeException ignored) { + ; + } + } + + @Test + public void testMissingDependencyFails() { + // missing dependency + final var schema = MultipleDependentsRequired.MultipleDependentsRequired1.getInstance(); + try { + schema.validate( + MapUtils.makeMap( + new AbstractMap.SimpleEntry( + "foo", + 1 + ), + new AbstractMap.SimpleEntry( + "quux", + 2 + ) + ), + configuration + ); + throw new RuntimeException("A different exception must be thrown"); + } catch (ValidationException | InvalidTypeException ignored) { + ; + } + } + + @Test + public void testNeitherPasses() { + // neither + final var schema = MultipleDependentsRequired.MultipleDependentsRequired1.getInstance(); + schema.validate( + MapUtils.makeMap( + ), + configuration + ); + } +} diff --git a/samples/client/3_1_0_unit_test/java/src/test/java/org/openapijsonschematools/client/components/schemas/SingleDependencyTest.java b/samples/client/3_1_0_unit_test/java/src/test/java/org/openapijsonschematools/client/components/schemas/SingleDependencyTest.java new file mode 100644 index 00000000000..45708f65dc8 --- /dev/null +++ b/samples/client/3_1_0_unit_test/java/src/test/java/org/openapijsonschematools/client/components/schemas/SingleDependencyTest.java @@ -0,0 +1,116 @@ +package org.openapijsonschematools.client.components.schemas; + +import org.junit.Assert; +import org.junit.Test; +import org.openapijsonschematools.client.configurations.JsonSchemaKeywordFlags; +import org.openapijsonschematools.client.configurations.SchemaConfiguration; +import org.openapijsonschematools.client.exceptions.ValidationException; +import org.openapijsonschematools.client.exceptions.InvalidTypeException; +import org.openapijsonschematools.client.schemas.validation.MapUtils; +import org.checkerframework.checker.nullness.qual.Nullable; + +import java.util.Arrays; +import java.util.List; +import java.util.Map; +import java.util.AbstractMap; + +public class SingleDependencyTest { + static final SchemaConfiguration configuration = new SchemaConfiguration(JsonSchemaKeywordFlags.onlyFormat()); + + @Test + public void testNondependantPasses() { + // nondependant + final var schema = SingleDependency.SingleDependency1.getInstance(); + schema.validate( + MapUtils.makeMap( + new AbstractMap.SimpleEntry( + "foo", + 1 + ) + ), + configuration + ); + } + + @Test + public void testWithDependencyPasses() { + // with dependency + final var schema = SingleDependency.SingleDependency1.getInstance(); + schema.validate( + MapUtils.makeMap( + new AbstractMap.SimpleEntry( + "foo", + 1 + ), + new AbstractMap.SimpleEntry( + "bar", + 2 + ) + ), + configuration + ); + } + + @Test + public void testMissingDependencyFails() { + // missing dependency + final var schema = SingleDependency.SingleDependency1.getInstance(); + try { + schema.validate( + MapUtils.makeMap( + new AbstractMap.SimpleEntry( + "bar", + 2 + ) + ), + configuration + ); + throw new RuntimeException("A different exception must be thrown"); + } catch (ValidationException | InvalidTypeException ignored) { + ; + } + } + + @Test + public void testIgnoresOtherNonObjectsPasses() { + // ignores other non-objects + final var schema = SingleDependency.SingleDependency1.getInstance(); + schema.validate( + 12, + configuration + ); + } + + @Test + public void testIgnoresArraysPasses() { + // ignores arrays + final var schema = SingleDependency.SingleDependency1.getInstance(); + schema.validate( + Arrays.asList( + "bar" + ), + configuration + ); + } + + @Test + public void testNeitherPasses() { + // neither + final var schema = SingleDependency.SingleDependency1.getInstance(); + schema.validate( + MapUtils.makeMap( + ), + configuration + ); + } + + @Test + public void testIgnoresStringsPasses() { + // ignores strings + final var schema = SingleDependency.SingleDependency1.getInstance(); + schema.validate( + "foobar", + configuration + ); + } +} diff --git a/samples/client/petstore/java/.openapi-generator/FILES b/samples/client/petstore/java/.openapi-generator/FILES index 3df4cfd1c39..1ff7ecf882a 100644 --- a/samples/client/petstore/java/.openapi-generator/FILES +++ b/samples/client/petstore/java/.openapi-generator/FILES @@ -692,6 +692,7 @@ src/main/java/org/openapijsonschematools/client/schemas/validation/ContainsValid src/main/java/org/openapijsonschematools/client/schemas/validation/CustomIsoparser.java src/main/java/org/openapijsonschematools/client/schemas/validation/DefaultValueMethod.java src/main/java/org/openapijsonschematools/client/schemas/validation/DependentRequiredValidator.java +src/main/java/org/openapijsonschematools/client/schemas/validation/DependentSchemasValidator.java src/main/java/org/openapijsonschematools/client/schemas/validation/DoubleEnumValidator.java src/main/java/org/openapijsonschematools/client/schemas/validation/DoubleValueMethod.java src/main/java/org/openapijsonschematools/client/schemas/validation/EnumValidator.java diff --git a/samples/client/petstore/java/src/main/java/org/openapijsonschematools/client/schemas/validation/DependentSchemasValidator.java b/samples/client/petstore/java/src/main/java/org/openapijsonschematools/client/schemas/validation/DependentSchemasValidator.java new file mode 100644 index 00000000000..a689279e1e1 --- /dev/null +++ b/samples/client/petstore/java/src/main/java/org/openapijsonschematools/client/schemas/validation/DependentSchemasValidator.java @@ -0,0 +1,48 @@ +package org.openapijsonschematools.client.schemas.validation; + +import org.checkerframework.checker.nullness.qual.Nullable; + +import java.util.ArrayList; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +public class DependentSchemasValidator implements KeywordValidator { + public final Map> dependentSchemas; + + public DependentSchemasValidator(Map> dependentSchemas) { + this.dependentSchemas = dependentSchemas; + } + + @Override + public @Nullable PathToSchemasMap validate( + JsonSchema schema, + @Nullable Object arg, + ValidationMetadata validationMetadata, + @Nullable List containsPathToSchemas + ) { + if (!(arg instanceof Map mapArg)) { + return null; + } + PathToSchemasMap pathToSchemas = new PathToSchemasMap(); + Set presentProperties = new LinkedHashSet<>(); + for (Object key: mapArg.keySet()) { + if (key instanceof String) { + presentProperties.add((String) key); + } + } + for(Map.Entry> entry: dependentSchemas.entrySet()) { + String propName = entry.getKey(); + if (!presentProperties.contains(propName)) { + continue; + } + Class dependentSchemaClass = entry.getValue(); + JsonSchema dependentSchema = JsonSchemaFactory.getInstance(dependentSchemaClass); + PathToSchemasMap otherPathToSchemas = JsonSchema.validate(dependentSchema, arg, validationMetadata); + pathToSchemas.update(otherPathToSchemas); + } + return pathToSchemas; + } +} + diff --git a/samples/client/petstore/java/src/main/java/org/openapijsonschematools/client/schemas/validation/JsonSchema.java b/samples/client/petstore/java/src/main/java/org/openapijsonschematools/client/schemas/validation/JsonSchema.java index 9d7831b6225..562dc06cab0 100644 --- a/samples/client/petstore/java/src/main/java/org/openapijsonschematools/client/schemas/validation/JsonSchema.java +++ b/samples/client/petstore/java/src/main/java/org/openapijsonschematools/client/schemas/validation/JsonSchema.java @@ -51,6 +51,7 @@ public abstract class JsonSchema { public final @Nullable Integer minContains; public final @Nullable Class propertyNames; public @Nullable Map> dependentRequired; + public final @Nullable Map> dependentSchemas; private final LinkedHashMap keywordToValidator; protected JsonSchema(JsonSchemaInfo jsonSchemaInfo) { @@ -268,6 +269,13 @@ protected JsonSchema(JsonSchemaInfo jsonSchemaInfo) { new DependentRequiredValidator(this.dependentRequired) ); } + this.dependentSchemas = jsonSchemaInfo.dependentSchemas; + if (this.dependentSchemas != null) { + keywordToValidator.put( + "dependentSchemas", + new DependentSchemasValidator(this.dependentSchemas) + ); + } this.keywordToValidator = keywordToValidator; } diff --git a/samples/client/petstore/java/src/main/java/org/openapijsonschematools/client/schemas/validation/JsonSchemaInfo.java b/samples/client/petstore/java/src/main/java/org/openapijsonschematools/client/schemas/validation/JsonSchemaInfo.java index 59f51a6be72..c4f4ddf1042 100644 --- a/samples/client/petstore/java/src/main/java/org/openapijsonschematools/client/schemas/validation/JsonSchemaInfo.java +++ b/samples/client/petstore/java/src/main/java/org/openapijsonschematools/client/schemas/validation/JsonSchemaInfo.java @@ -167,4 +167,9 @@ public JsonSchemaInfo dependentRequired(Map> dependentRequir this.dependentRequired = dependentRequired; return this; } + public @Nullable Map> dependentSchemas = null; + public JsonSchemaInfo dependentSchemas(Map> dependentSchemas) { + this.dependentSchemas = dependentSchemas; + return this; + } } \ No newline at end of file diff --git a/src/main/java/org/openapijsonschematools/codegen/generators/JavaClientGenerator.java b/src/main/java/org/openapijsonschematools/codegen/generators/JavaClientGenerator.java index e4ce58e2b93..4213715c9eb 100644 --- a/src/main/java/org/openapijsonschematools/codegen/generators/JavaClientGenerator.java +++ b/src/main/java/org/openapijsonschematools/codegen/generators/JavaClientGenerator.java @@ -259,7 +259,7 @@ public JavaClientGenerator() { SchemaFeature.Contains, SchemaFeature.Default, SchemaFeature.DependentRequired, - // SchemaFeature.DependentSchemas, + SchemaFeature.DependentSchemas, // SchemaFeature.Discriminator, // SchemaFeature.Else, SchemaFeature.Enum, @@ -568,6 +568,7 @@ public void processOpts() { keywordValidatorFiles.add("CustomIsoparser"); keywordValidatorFiles.add("DefaultValueMethod"); keywordValidatorFiles.add("DependentRequiredValidator"); + keywordValidatorFiles.add("DependentSchemasValidator"); keywordValidatorFiles.add("DoubleEnumValidator"); keywordValidatorFiles.add("DoubleValueMethod"); keywordValidatorFiles.add("EnumValidator"); @@ -1337,7 +1338,7 @@ public Set getImports(String sourceJsonPath, CodegenSchema schema, Featu imports.add("import "+packageName + ".schemas.validation.MapSchemaValidator;"); imports.add("import java.util.LinkedHashMap;"); imports.add("import java.util.ArrayList;"); // for validate - addPropertiesValidator(schema, imports); + addPropertiesImports(schema, imports); addRequiredValidator(schema, imports); addAllOfValidator(schema, imports); addAnyOfValidator(schema, imports); @@ -1349,6 +1350,7 @@ public Set getImports(String sourceJsonPath, CodegenSchema schema, Featu addAdditionalPropertiesImports(schema, imports); addDefaultValueImport(schema, imports); addDependentRequiredImports(schema, imports); + addDependentSchemasImports(schema, imports); if (schema.mapValueSchema != null) { imports.addAll(getDeeperImports(sourceJsonPath, schema.mapValueSchema)); } @@ -1452,13 +1454,20 @@ private void addConstImports(CodegenSchema schema, Set imports) { } } - private void addPropertiesValidator(CodegenSchema schema, Set imports) { + private void addPropertiesImports(CodegenSchema schema, Set imports) { if (schema.properties != null) { - imports.add("import "+packageName + ".schemas.validation.PropertyEntry;"); + imports.add("import " + packageName + ".schemas.validation.PropertyEntry;"); imports.add("import java.util.Map;"); imports.add("import java.util.Set;"); - imports.add("import "+packageName + ".exceptions.UnsetPropertyException;"); - imports.add("import "+packageName + ".schemas.BaseBuilder;"); + imports.add("import " + packageName + ".exceptions.UnsetPropertyException;"); + imports.add("import " + packageName + ".schemas.BaseBuilder;"); + } + } + + private void addDependentSchemasImports(CodegenSchema schema, Set imports) { + if (schema.dependentSchemas != null) { + imports.add("import " + packageName + ".schemas.validation.PropertyEntry;"); + imports.add("import java.util.Map;"); } } @@ -1559,12 +1568,13 @@ private void addMapSchemaImports(Set imports, CodegenSchema schema) { imports.add("import java.util.ArrayList;"); // for castToAllowedTypes imports.add("import java.util.LinkedHashMap;"); addRequiredValidator(schema, imports); - addPropertiesValidator(schema, imports); + addPropertiesImports(schema, imports); addAllOfValidator(schema, imports); addAnyOfValidator(schema, imports); addOneOfValidator(schema, imports); addAdditionalPropertiesImports(schema, imports); addDependentRequiredImports(schema, imports); + addDependentSchemasImports(schema, imports); } private void addListSchemaImports(Set imports, CodegenSchema schema) { diff --git a/src/main/resources/java/src/main/java/packagename/components/schemas/SchemaClass/_Schema_anytypeOrMultitype.hbs b/src/main/resources/java/src/main/java/packagename/components/schemas/SchemaClass/_Schema_anytypeOrMultitype.hbs index eb60ec24f8c..00d012bfae9 100644 --- a/src/main/resources/java/src/main/java/packagename/components/schemas/SchemaClass/_Schema_anytypeOrMultitype.hbs +++ b/src/main/resources/java/src/main/java/packagename/components/schemas/SchemaClass/_Schema_anytypeOrMultitype.hbs @@ -114,6 +114,9 @@ public static class {{jsonPathPiece.pascalCase}} extends JsonSchema implements { {{#if dependentRequired}} {{> src/main/java/packagename/components/schemas/SchemaClass/_dependentRequired }} {{/if}} + {{#if dependentSchemas}} + {{> src/main/java/packagename/components/schemas/SchemaClass/_dependentSchemas }} + {{/if}} ); } @@ -138,9 +141,6 @@ public static class {{jsonPathPiece.pascalCase}} extends JsonSchema implements { {{#if else_}} {{!> components/schemas/schema_cls/_else }} {{/if}} -{{#if dependentSchemas}} - {{!> components/schemas/schema_cls/_dependent_schemas }} -{{/if}} {{#if patternProperties}} {{!> components/schemas/schema_cls/_pattern_properties }} {{/if}} diff --git a/src/main/resources/java/src/main/java/packagename/components/schemas/SchemaClass/_Schema_map.hbs b/src/main/resources/java/src/main/java/packagename/components/schemas/SchemaClass/_Schema_map.hbs index 6371ba4c53b..bc64c46b230 100644 --- a/src/main/resources/java/src/main/java/packagename/components/schemas/SchemaClass/_Schema_map.hbs +++ b/src/main/resources/java/src/main/java/packagename/components/schemas/SchemaClass/_Schema_map.hbs @@ -53,6 +53,9 @@ public static class {{jsonPathPiece.pascalCase}} extends JsonSchema implements M {{#if dependentRequired}} {{> src/main/java/packagename/components/schemas/SchemaClass/_dependentRequired }} {{/if}} + {{#if dependentSchemas}} + {{> src/main/java/packagename/components/schemas/SchemaClass/_dependentSchemas }} + {{/if}} ); } @@ -74,9 +77,6 @@ public static class {{jsonPathPiece.pascalCase}} extends JsonSchema implements M {{#if else_}} {{!> components/schemas/schema_cls/_else }} {{/if}} - {{#if dependentSchemas}} - {{!> components/schemas/schema_cls/_dependent_schemas }} - {{/if}} {{#if patternProperties}} {{!> components/schemas/schema_cls/_pattern_properties }} {{/if}} diff --git a/src/main/resources/java/src/main/java/packagename/components/schemas/SchemaClass/_dependentSchemas.hbs b/src/main/resources/java/src/main/java/packagename/components/schemas/SchemaClass/_dependentSchemas.hbs new file mode 100644 index 00000000000..0ed7ecdef8a --- /dev/null +++ b/src/main/resources/java/src/main/java/packagename/components/schemas/SchemaClass/_dependentSchemas.hbs @@ -0,0 +1,29 @@ +{{#if forDocs}} +dependentSchemas = Map.ofEntries(
+ {{~#each dependentSchemas}} + {{#if refInfo.refClass}} + {{#if refInfo.refModule}} +    new PropertyEntry("{{{@key.original}}}", [{{refInfo.refModule}}.{{refInfo.refClass}}.class]({{docRoot}}{{refInfo.ref.pathFromDocRoot}}.md#{{refInfo.ref.jsonPathPiece.kebabCase}})){{#unless @last}},{{/unless}}
+ {{~else}} +    new PropertyEntry("{{{@key.original}}}", [{{refInfo.refClass}}.class](#{{refInfo.ref.jsonPathPiece.kebabCase}}))){{#unless @last}},{{/unless}}
+ {{~/if}} + {{else}} +    new PropertyEntry("{{{@key.original}}}", [{{jsonPathPiece.pascalCase}}.class](#{{jsonPathPiece.kebabCase}}))){{#unless @last}},{{/unless}}
+ {{~/if}} + {{/each}} +)
+{{~else}} +.dependentSchemas(Map.ofEntries( + {{#each dependentSchemas}} + {{#if refInfo.refClass}} + {{#if refInfo.refModule}} + new PropertyEntry("{{{@key.original}}}", {{refInfo.refModule}}.{{refInfo.refClass}}.class){{#unless @last}},{{/unless}} + {{else}} + new PropertyEntry("{{{@key.original}}}", {{refInfo.refClass}}.class){{#unless @last}},{{/unless}} + {{/if}} + {{else}} + new PropertyEntry("{{{@key.original}}}", {{jsonPathPiece.pascalCase}}.class){{#unless @last}},{{/unless}} + {{/if}} + {{/each}} +)) +{{/if}} \ No newline at end of file diff --git a/src/main/resources/java/src/main/java/packagename/components/schemas/docschema_fields_field.hbs b/src/main/resources/java/src/main/java/packagename/components/schemas/docschema_fields_field.hbs index d7aaacda855..83eebd3db96 100644 --- a/src/main/resources/java/src/main/java/packagename/components/schemas/docschema_fields_field.hbs +++ b/src/main/resources/java/src/main/java/packagename/components/schemas/docschema_fields_field.hbs @@ -88,3 +88,6 @@ {{#if dependentRequired}} | Map> | {{> src/main/java/packagename/components/schemas/SchemaClass/_dependentRequired }} | {{/if}} +{{#if dependentSchemas}} +| Map> | {{> src/main/java/packagename/components/schemas/SchemaClass/_dependentSchemas }} | +{{/if}} diff --git a/src/main/resources/java/src/main/java/packagename/schemas/validation/DependentSchemasValidator.hbs b/src/main/resources/java/src/main/java/packagename/schemas/validation/DependentSchemasValidator.hbs new file mode 100644 index 00000000000..63b71af44d3 --- /dev/null +++ b/src/main/resources/java/src/main/java/packagename/schemas/validation/DependentSchemasValidator.hbs @@ -0,0 +1,48 @@ +package {{{packageName}}}.schemas.validation; + +import org.checkerframework.checker.nullness.qual.Nullable; + +import java.util.ArrayList; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +public class DependentSchemasValidator implements KeywordValidator { + public final Map> dependentSchemas; + + public DependentSchemasValidator(Map> dependentSchemas) { + this.dependentSchemas = dependentSchemas; + } + + @Override + public @Nullable PathToSchemasMap validate( + JsonSchema schema, + @Nullable Object arg, + ValidationMetadata validationMetadata, + @Nullable List containsPathToSchemas + ) { + if (!(arg instanceof Map mapArg)) { + return null; + } + PathToSchemasMap pathToSchemas = new PathToSchemasMap(); + Set presentProperties = new LinkedHashSet<>(); + for (Object key: mapArg.keySet()) { + if (key instanceof String) { + presentProperties.add((String) key); + } + } + for(Map.Entry> entry: dependentSchemas.entrySet()) { + String propName = entry.getKey(); + if (!presentProperties.contains(propName)) { + continue; + } + Class dependentSchemaClass = entry.getValue(); + JsonSchema dependentSchema = JsonSchemaFactory.getInstance(dependentSchemaClass); + PathToSchemasMap otherPathToSchemas = JsonSchema.validate(dependentSchema, arg, validationMetadata); + pathToSchemas.update(otherPathToSchemas); + } + return pathToSchemas; + } +} + diff --git a/src/main/resources/java/src/main/java/packagename/schemas/validation/JsonSchema.hbs b/src/main/resources/java/src/main/java/packagename/schemas/validation/JsonSchema.hbs index a18be460d45..d473bea8a76 100644 --- a/src/main/resources/java/src/main/java/packagename/schemas/validation/JsonSchema.hbs +++ b/src/main/resources/java/src/main/java/packagename/schemas/validation/JsonSchema.hbs @@ -51,6 +51,7 @@ public abstract class JsonSchema { public final @Nullable Integer minContains; public final @Nullable Class propertyNames; public @Nullable Map> dependentRequired; + public final @Nullable Map> dependentSchemas; private final LinkedHashMap keywordToValidator; protected JsonSchema(JsonSchemaInfo jsonSchemaInfo) { @@ -268,6 +269,13 @@ public abstract class JsonSchema { new DependentRequiredValidator(this.dependentRequired) ); } + this.dependentSchemas = jsonSchemaInfo.dependentSchemas; + if (this.dependentSchemas != null) { + keywordToValidator.put( + "dependentSchemas", + new DependentSchemasValidator(this.dependentSchemas) + ); + } this.keywordToValidator = keywordToValidator; } diff --git a/src/main/resources/java/src/main/java/packagename/schemas/validation/JsonSchemaInfo.hbs b/src/main/resources/java/src/main/java/packagename/schemas/validation/JsonSchemaInfo.hbs index 0f17554d0f2..36a24aaa12b 100644 --- a/src/main/resources/java/src/main/java/packagename/schemas/validation/JsonSchemaInfo.hbs +++ b/src/main/resources/java/src/main/java/packagename/schemas/validation/JsonSchemaInfo.hbs @@ -167,4 +167,9 @@ public class JsonSchemaInfo { this.dependentRequired = dependentRequired; return this; } + public @Nullable Map> dependentSchemas = null; + public JsonSchemaInfo dependentSchemas(Map> dependentSchemas) { + this.dependentSchemas = dependentSchemas; + return this; + } } \ No newline at end of file