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 71a63653d18..97d6064455a 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 @@ -271,6 +271,7 @@ src/main/java/org/openapijsonschematools/client/schemas/validation/StringValueMe src/main/java/org/openapijsonschematools/client/schemas/validation/TypeValidator.java src/main/java/org/openapijsonschematools/client/schemas/validation/UniqueItemsValidator.java src/main/java/org/openapijsonschematools/client/schemas/validation/UnsetAnyTypeJsonSchema.java +src/main/java/org/openapijsonschematools/client/schemas/validation/ValidationData.java src/main/java/org/openapijsonschematools/client/schemas/validation/ValidationMetadata.java src/main/java/org/openapijsonschematools/client/servers/Server0.java src/main/java/org/openapijsonschematools/client/servers/ServerWithVariables.java diff --git a/samples/client/3_0_3_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/AdditionalPropertiesValidator.java b/samples/client/3_0_3_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/AdditionalPropertiesValidator.java index fd6fa6a4d29..2548452a115 100644 --- a/samples/client/3_0_3_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/AdditionalPropertiesValidator.java +++ b/samples/client/3_0_3_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/AdditionalPropertiesValidator.java @@ -8,22 +8,15 @@ import java.util.Set; public class AdditionalPropertiesValidator implements KeywordValidator { - public final Class additionalProperties; - - public AdditionalPropertiesValidator(Class additionalProperties) { - this.additionalProperties = additionalProperties; - } - @Override public @Nullable PathToSchemasMap validate( - JsonSchema schema, - @Nullable Object arg, - ValidationMetadata validationMetadata, - @Nullable List containsPathToSchemas, - @Nullable PathToSchemasMap patternPropertiesPathToSchemas, - @Nullable PathToSchemasMap ifPathToSchemas + ValidationData data ) { - if (!(arg instanceof Map mapArg)) { + if (!(data.arg() instanceof Map mapArg)) { + return null; + } + var additionalProperties = data.schema().additionalProperties; + if (additionalProperties == null) { return null; } Set presentAdditionalProperties = new LinkedHashSet<>(); @@ -32,22 +25,23 @@ public AdditionalPropertiesValidator(Class additionalPrope presentAdditionalProperties.add((String) key); } } - if (schema.properties != null) { - presentAdditionalProperties.removeAll(schema.properties.keySet()); + var properties = data.schema().properties; + if (properties != null) { + presentAdditionalProperties.removeAll(properties.keySet()); } PathToSchemasMap pathToSchemas = new PathToSchemasMap(); for(String addPropName: presentAdditionalProperties) { @Nullable Object propValue = mapArg.get(addPropName); - List propPathToItem = new ArrayList<>(validationMetadata.pathToItem()); + List propPathToItem = new ArrayList<>(data.validationMetadata().pathToItem()); propPathToItem.add(addPropName); - if (patternPropertiesPathToSchemas != null && patternPropertiesPathToSchemas.containsKey(propPathToItem)) { + if (data.patternPropertiesPathToSchemas() != null && data.patternPropertiesPathToSchemas().containsKey(propPathToItem)) { continue; } ValidationMetadata propValidationMetadata = new ValidationMetadata( propPathToItem, - validationMetadata.configuration(), - validationMetadata.validatedPathToSchemas(), - validationMetadata.seenClasses() + data.validationMetadata().configuration(), + data.validationMetadata().validatedPathToSchemas(), + data.validationMetadata().seenClasses() ); JsonSchema addPropsSchema = JsonSchemaFactory.getInstance(additionalProperties); if (propValidationMetadata.validationRanEarlier(addPropsSchema)) { diff --git a/samples/client/3_0_3_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/AllOfValidator.java b/samples/client/3_0_3_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/AllOfValidator.java index 313e2d97446..583017ea6b5 100644 --- a/samples/client/3_0_3_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/AllOfValidator.java +++ b/samples/client/3_0_3_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/AllOfValidator.java @@ -1,32 +1,21 @@ package org.openapijsonschematools.client.schemas.validation; import org.checkerframework.checker.nullness.qual.Nullable; -import java.util.List; - public class AllOfValidator implements KeywordValidator { - public final List> allOf; - - public AllOfValidator(List> allOf) { - this.allOf = allOf; - } - @Override public @Nullable PathToSchemasMap validate( - JsonSchema schema, - @Nullable Object arg, - ValidationMetadata validationMetadata, - @Nullable List containsPathToSchemas, - @Nullable PathToSchemasMap patternPropertiesPathToSchemas, - @Nullable PathToSchemasMap ifPathToSchemas + ValidationData data ) { + var allOf = data.schema().allOf; + if (allOf == null) { + return null; + } PathToSchemasMap pathToSchemas = new PathToSchemasMap(); for(Class allOfClass: allOf) { JsonSchema allOfSchema = JsonSchemaFactory.getInstance(allOfClass); - PathToSchemasMap otherPathToSchemas = JsonSchema.validate(allOfSchema, arg, validationMetadata); + PathToSchemasMap otherPathToSchemas = JsonSchema.validate(allOfSchema, data.arg(), data.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/AnyOfValidator.java b/samples/client/3_0_3_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/AnyOfValidator.java index a4754dda464..062fa2eecdc 100644 --- a/samples/client/3_0_3_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/AnyOfValidator.java +++ b/samples/client/3_0_3_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/AnyOfValidator.java @@ -7,25 +7,18 @@ import java.util.List; public class AnyOfValidator implements KeywordValidator { - public final List> anyOf; - - public AnyOfValidator(List> anyOf) { - this.anyOf = anyOf; - } - @Override public @Nullable PathToSchemasMap validate( - JsonSchema schema, - @Nullable Object arg, - ValidationMetadata validationMetadata, - @Nullable List containsPathToSchemas, - @Nullable PathToSchemasMap patternPropertiesPathToSchemas, - @Nullable PathToSchemasMap ifPathToSchemas + ValidationData data ) { + var anyOf = data.schema().anyOf; + if (anyOf == null) { + return null; + } PathToSchemasMap pathToSchemas = new PathToSchemasMap(); List> validatedAnyOfClasses = new ArrayList<>(); for(Class anyOfClass: anyOf) { - if (anyOfClass == schema.getClass()) { + if (anyOfClass == data.schema().getClass()) { /* optimistically assume that schema will pass validation do not invoke _validate on it because that is recursive @@ -35,7 +28,7 @@ public AnyOfValidator(List> anyOf) { } try { JsonSchema anyOfSchema = JsonSchemaFactory.getInstance(anyOfClass); - PathToSchemasMap otherPathToSchemas = JsonSchema.validate(anyOfSchema, arg, validationMetadata); + PathToSchemasMap otherPathToSchemas = JsonSchema.validate(anyOfSchema, data.arg(), data.validationMetadata()); validatedAnyOfClasses.add(anyOfClass); pathToSchemas.update(otherPathToSchemas); } catch (ValidationException e) { @@ -43,7 +36,7 @@ public AnyOfValidator(List> anyOf) { } } if (validatedAnyOfClasses.isEmpty()) { - throw new ValidationException("Invalid inputs given to generate an instance of "+schema.getClass()+". None "+ + throw new ValidationException("Invalid inputs given to generate an instance of "+data.schema().getClass()+". None "+ "of the anyOf schemas matched the input data." ); } diff --git a/samples/client/3_0_3_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/ConstValidator.java b/samples/client/3_0_3_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/ConstValidator.java index f797c68ab2e..6409a23e5ca 100644 --- a/samples/client/3_0_3_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/ConstValidator.java +++ b/samples/client/3_0_3_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/ConstValidator.java @@ -4,27 +4,19 @@ import org.checkerframework.checker.nullness.qual.Nullable; import java.math.BigDecimal; -import java.util.List; import java.util.Objects; public class ConstValidator extends BigDecimalValidator implements KeywordValidator { - public final @Nullable Object constValue; - - public ConstValidator(@Nullable Object constValue) { - this.constValue = constValue; - } - @Override public @Nullable PathToSchemasMap validate( - JsonSchema schema, - @Nullable Object arg, - ValidationMetadata validationMetadata, - @Nullable List containsPathToSchemas, - @Nullable PathToSchemasMap patternPropertiesPathToSchemas, - @Nullable PathToSchemasMap ifPathToSchemas + ValidationData data ) { - if (arg instanceof Number) { - BigDecimal castArg = getBigDecimal((Number) arg); + if (!data.schema().constValueSet) { + return null; + } + var constValue = data.schema().constValue; + if (data.arg() instanceof Number numberArg) { + BigDecimal castArg = getBigDecimal(numberArg); if (Objects.equals(castArg, constValue)) { return null; } @@ -32,10 +24,10 @@ public ConstValidator(@Nullable Object constValue) { return null; } } else { - if (Objects.equals(arg, constValue)) { + if (Objects.equals(data.arg(), constValue)) { return null; } } - throw new ValidationException("Invalid value "+arg+" was not equal to const "+constValue); + throw new ValidationException("Invalid value "+data.arg()+" was not equal to const "+constValue); } -} +} \ No newline at end of file diff --git a/samples/client/3_0_3_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/ContainsValidator.java b/samples/client/3_0_3_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/ContainsValidator.java index deaa878d5af..fbfd1c9c700 100644 --- a/samples/client/3_0_3_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/ContainsValidator.java +++ b/samples/client/3_0_3_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/ContainsValidator.java @@ -3,32 +3,21 @@ import org.checkerframework.checker.nullness.qual.Nullable; import org.openapijsonschematools.client.exceptions.ValidationException; -import java.util.ArrayList; import java.util.List; public class ContainsValidator implements KeywordValidator { - public final Class contains; - - public ContainsValidator(Class contains) { - this.contains = contains; - } - @Override public @Nullable PathToSchemasMap validate( - JsonSchema schema, - @Nullable Object arg, - ValidationMetadata validationMetadata, - @Nullable List containsPathToSchemas, - @Nullable PathToSchemasMap patternPropertiesPathToSchemas, - @Nullable PathToSchemasMap ifPathToSchemas + ValidationData data ) { - if (!(arg instanceof List)) { + if (!(data.arg() instanceof List)) { return null; } + var containsPathToSchemas = data.containsPathToSchemas(); if (containsPathToSchemas == null || containsPathToSchemas.isEmpty()) { throw new ValidationException( - "Validation failed for contains keyword in class="+schema.getClass() - + " at pathToItem="+validationMetadata.pathToItem()+". No " + "Validation failed for contains keyword in class="+data.schema().getClass() + + " at pathToItem="+data.validationMetadata().pathToItem()+". No " + "items validated to the contains schema." ); } @@ -38,42 +27,4 @@ public ContainsValidator(Class contains) { } return pathToSchemas; } - - public List getContainsPathToSchemas( - @Nullable Object arg, - ValidationMetadata validationMetadata - ) { - if (!(arg instanceof List)) { - return new ArrayList<>(); - } - @Nullable List containsPathToSchemas = new ArrayList<>(); - int i = 0; - for(Object itemValue: (List) arg) { - PathToSchemasMap thesePathToSchemas = new PathToSchemasMap(); - List itemPathToItem = new ArrayList<>(validationMetadata.pathToItem()); - itemPathToItem.add(i); - ValidationMetadata itemValidationMetadata = new ValidationMetadata( - itemPathToItem, - validationMetadata.configuration(), - validationMetadata.validatedPathToSchemas(), - validationMetadata.seenClasses() - ); - JsonSchema containsSchema = JsonSchemaFactory.getInstance(contains); - if (itemValidationMetadata.validationRanEarlier(containsSchema)) { - // todo add_deeper_validated_schemas - containsPathToSchemas.add(thesePathToSchemas); - i += 1; - continue; - } - - try { - PathToSchemasMap otherPathToSchemas = JsonSchema.validate( - containsSchema, itemValue, itemValidationMetadata); - containsPathToSchemas.add(otherPathToSchemas); - } catch (ValidationException ignored) { - ; - } - } - return containsPathToSchemas; - } } \ No newline at end of file diff --git a/samples/client/3_0_3_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/DependentRequiredValidator.java b/samples/client/3_0_3_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/DependentRequiredValidator.java index a5e92887928..77b21ca801d 100644 --- a/samples/client/3_0_3_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/DependentRequiredValidator.java +++ b/samples/client/3_0_3_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/DependentRequiredValidator.java @@ -4,35 +4,27 @@ import org.openapijsonschematools.client.exceptions.ValidationException; import java.util.HashSet; -import java.util.List; import java.util.Map; import java.util.Set; public class DependentRequiredValidator implements KeywordValidator { - public final Map> dependentRequired; - - public DependentRequiredValidator(Map> dependentRequired) { - this.dependentRequired = dependentRequired; - } - @Override public @Nullable PathToSchemasMap validate( - JsonSchema schema, - @Nullable Object arg, - ValidationMetadata validationMetadata, - @Nullable List containsPathToSchemas, - @Nullable PathToSchemasMap patternPropertiesPathToSchemas, - @Nullable PathToSchemasMap ifPathToSchemas + ValidationData data ) { - if (!(arg instanceof Map)) { + if (!(data.arg() instanceof Map mapArg)) { + return null; + } + var dependentRequired = data.schema().dependentRequired; + if (dependentRequired == null) { return null; } for (Map.Entry> entry: dependentRequired.entrySet()) { - if (!((Map) arg).containsKey(entry.getKey())) { + if (!mapArg.containsKey(entry.getKey())) { continue; } Set missingKeys = new HashSet<>(entry.getValue()); - for (Object objKey: ((Map) arg).keySet()) { + for (Object objKey: mapArg.keySet()) { if (objKey instanceof String key) { missingKeys.remove(key); } @@ -42,7 +34,7 @@ public DependentRequiredValidator(Map> dependentRequired) { } throw new ValidationException( "Validation failed for dependentRequired because these_keys="+missingKeys+" are "+ - "missing at pathToItem="+validationMetadata.pathToItem()+" in class "+schema.getClass() + "missing at pathToItem="+data.validationMetadata().pathToItem()+" in class "+data.schema().getClass() ); } return null; 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 index 0ffa3b351ca..940157d3b48 100644 --- 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 @@ -2,29 +2,20 @@ 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, - @Nullable PathToSchemasMap patternPropertiesPathToSchemas, - @Nullable PathToSchemasMap ifPathToSchemas + ValidationData data ) { - if (!(arg instanceof Map mapArg)) { + if (!(data.arg() instanceof Map mapArg)) { + return null; + } + var dependentSchemas = data.schema().dependentSchemas; + if (dependentSchemas == null) { return null; } PathToSchemasMap pathToSchemas = new PathToSchemasMap(); @@ -41,10 +32,9 @@ public DependentSchemasValidator(Map> depend } Class dependentSchemaClass = entry.getValue(); JsonSchema dependentSchema = JsonSchemaFactory.getInstance(dependentSchemaClass); - PathToSchemasMap otherPathToSchemas = JsonSchema.validate(dependentSchema, arg, validationMetadata); + PathToSchemasMap otherPathToSchemas = JsonSchema.validate(dependentSchema, mapArg, data.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/EnumValidator.java b/samples/client/3_0_3_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/EnumValidator.java index 6cc9459e1a8..8af756619bd 100644 --- a/samples/client/3_0_3_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/EnumValidator.java +++ b/samples/client/3_0_3_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/EnumValidator.java @@ -4,36 +4,28 @@ import org.checkerframework.checker.nullness.qual.Nullable; import java.math.BigDecimal; -import java.util.List; import java.util.Set; public class EnumValidator extends BigDecimalValidator implements KeywordValidator { - public final Set<@Nullable Object> enumValues; - - public EnumValidator(Set<@Nullable Object> enumValues) { - this.enumValues = enumValues; - } - @SuppressWarnings("nullness") - private boolean enumContainsArg(@Nullable Object arg){ + private static boolean enumContainsArg(Set<@Nullable Object> enumValues, @Nullable Object arg){ return enumValues.contains(arg); } @Override public @Nullable PathToSchemasMap validate( - JsonSchema schema, - @Nullable Object arg, - ValidationMetadata validationMetadata, - @Nullable List containsPathToSchemas, - @Nullable PathToSchemasMap patternPropertiesPathToSchemas, - @Nullable PathToSchemasMap ifPathToSchemas + ValidationData data ) { + var enumValues = data.schema().enumValues; + if (enumValues == null) { + return null; + } if (enumValues.isEmpty()) { throw new ValidationException("No value can match enum because enum is empty"); } - if (arg instanceof Number) { - BigDecimal castArg = getBigDecimal((Number) arg); - if (enumContainsArg(castArg)) { + if (data.arg() instanceof Number numberArg) { + BigDecimal castArg = getBigDecimal(numberArg); + if (enumContainsArg(enumValues, castArg)) { return null; } for (Object enumValue: enumValues) { @@ -42,10 +34,10 @@ private boolean enumContainsArg(@Nullable Object arg){ } } } else { - if (enumContainsArg(arg)) { + if (enumContainsArg(enumValues, data.arg())) { return null; } } - throw new ValidationException("Invalid value "+arg+" was not one of the allowed enum "+enumValues); + throw new ValidationException("Invalid value "+data.arg()+" was not one of the allowed enum "+enumValues); } } diff --git a/samples/client/3_0_3_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/ExclusiveMaximumValidator.java b/samples/client/3_0_3_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/ExclusiveMaximumValidator.java index 432d5b0f4de..7d05ff65546 100644 --- a/samples/client/3_0_3_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/ExclusiveMaximumValidator.java +++ b/samples/client/3_0_3_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/ExclusiveMaximumValidator.java @@ -3,48 +3,39 @@ import org.openapijsonschematools.client.exceptions.ValidationException; import org.checkerframework.checker.nullness.qual.Nullable; -import java.util.List; - public class ExclusiveMaximumValidator implements KeywordValidator { - public final Number exclusiveMaximum; - - public ExclusiveMaximumValidator(Number exclusiveMaximum) { - this.exclusiveMaximum = exclusiveMaximum; - } - @Override public @Nullable PathToSchemasMap validate( - JsonSchema schema, - @Nullable Object arg, - ValidationMetadata validationMetadata, - @Nullable List containsPathToSchemas, - @Nullable PathToSchemasMap patternPropertiesPathToSchemas, - @Nullable PathToSchemasMap ifPathToSchemas + ValidationData data ) { - if (!(arg instanceof Number)) { + var exclusiveMaximum = data.schema().exclusiveMaximum; + if (exclusiveMaximum == null) { + return null; + } + if (!(data.arg() instanceof Number)) { return null; } - String msg = "Value " + arg + " is invalid because it is >= the exclusiveMaximum of " + exclusiveMaximum; - if (arg instanceof Integer) { - if (((Integer) arg).compareTo(exclusiveMaximum.intValue()) > -1) { + String msg = "Value " + data.arg() + " is invalid because it is >= the exclusiveMaximum of " + exclusiveMaximum; + if (data.arg() instanceof Integer intArg) { + if (intArg.compareTo(exclusiveMaximum.intValue()) > -1) { throw new ValidationException(msg); } return null; } - if (arg instanceof Long) { - if (((Long) arg).compareTo(exclusiveMaximum.longValue()) > -1) { + if (data.arg() instanceof Long longArg) { + if (longArg.compareTo(exclusiveMaximum.longValue()) > -1) { throw new ValidationException(msg); } return null; } - if (arg instanceof Float) { - if (((Float) arg).compareTo(exclusiveMaximum.floatValue()) > -1) { + if (data.arg() instanceof Float floatArg) { + if (floatArg.compareTo(exclusiveMaximum.floatValue()) > -1) { throw new ValidationException(msg); } return null; } - if (arg instanceof Double) { - if (((Double) arg).compareTo(exclusiveMaximum.doubleValue()) > -1) { + if (data.arg() instanceof Double doubleArg) { + if (doubleArg.compareTo(exclusiveMaximum.doubleValue()) > -1) { throw new ValidationException(msg); } return null; diff --git a/samples/client/3_0_3_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/ExclusiveMinimumValidator.java b/samples/client/3_0_3_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/ExclusiveMinimumValidator.java index d60c96f8325..73eb1e547c3 100644 --- a/samples/client/3_0_3_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/ExclusiveMinimumValidator.java +++ b/samples/client/3_0_3_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/ExclusiveMinimumValidator.java @@ -3,48 +3,39 @@ import org.openapijsonschematools.client.exceptions.ValidationException; import org.checkerframework.checker.nullness.qual.Nullable; -import java.util.List; - public class ExclusiveMinimumValidator implements KeywordValidator { - public final Number exclusiveMinimum; - - public ExclusiveMinimumValidator(Number exclusiveMinimum) { - this.exclusiveMinimum = exclusiveMinimum; - } - @Override public @Nullable PathToSchemasMap validate( - JsonSchema schema, - @Nullable Object arg, - ValidationMetadata validationMetadata, - @Nullable List containsPathToSchemas, - @Nullable PathToSchemasMap patternPropertiesPathToSchemas, - @Nullable PathToSchemasMap ifPathToSchemas + ValidationData data ) { - if (!(arg instanceof Number)) { + var exclusiveMinimum = data.schema().exclusiveMinimum; + if (exclusiveMinimum == null) { + return null; + } + if (!(data.arg() instanceof Number)) { return null; } - String msg = "Value " + arg + " is invalid because it is <= the exclusiveMinimum of " + exclusiveMinimum; - if (arg instanceof Integer) { - if (((Integer) arg).compareTo(exclusiveMinimum.intValue()) < 1) { + String msg = "Value " + data.arg() + " is invalid because it is <= the exclusiveMinimum of " + exclusiveMinimum; + if (data.arg() instanceof Integer intArg) { + if (intArg.compareTo(exclusiveMinimum.intValue()) < 1) { throw new ValidationException(msg); } return null; } - if (arg instanceof Long) { - if (((Long) arg).compareTo(exclusiveMinimum.longValue()) < 1) { + if (data.arg() instanceof Long longArg) { + if (longArg.compareTo(exclusiveMinimum.longValue()) < 1) { throw new ValidationException(msg); } return null; } - if (arg instanceof Float) { - if (((Float) arg).compareTo(exclusiveMinimum.floatValue()) < 1) { + if (data.arg() instanceof Float floatArg) { + if (floatArg.compareTo(exclusiveMinimum.floatValue()) < 1) { throw new ValidationException(msg); } return null; } - if (arg instanceof Double) { - if (((Double) arg).compareTo(exclusiveMinimum.doubleValue()) < 1) { + if (data.arg() instanceof Double doubleArg) { + if (doubleArg.compareTo(exclusiveMinimum.doubleValue()) < 1) { throw new ValidationException(msg); } return null; diff --git a/samples/client/3_0_3_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/FormatValidator.java b/samples/client/3_0_3_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/FormatValidator.java index d782f2ce4a2..c1ca45e44f3 100644 --- a/samples/client/3_0_3_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/FormatValidator.java +++ b/samples/client/3_0_3_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/FormatValidator.java @@ -6,16 +6,9 @@ import java.math.BigDecimal; import java.math.BigInteger; import java.time.format.DateTimeParseException; -import java.util.List; import java.util.UUID; public class FormatValidator implements KeywordValidator { - public final String format; - - public FormatValidator(String format) { - this.format = format; - } - private final static BigInteger int32InclusiveMinimum = BigInteger.valueOf(-2147483648L); private final static BigInteger int32InclusiveMaximum = BigInteger.valueOf(2147483647L); private final static BigInteger int64InclusiveMinimum = BigInteger.valueOf(-9223372036854775808L); @@ -25,12 +18,12 @@ public FormatValidator(String format) { private final static BigDecimal doubleInclusiveMinimum = BigDecimal.valueOf(-1.7976931348623157E+308d); private final static BigDecimal doubleInclusiveMaximum = BigDecimal.valueOf(1.7976931348623157E+308d); - private Void validateNumericFormat(Number arg, ValidationMetadata validationMetadata) { + private static void validateNumericFormat(Number arg, ValidationMetadata validationMetadata, String format) { if (format.startsWith("int")) { // there is a json schema test where 1.0 validates as an integer BigInteger intArg; if (arg instanceof Float || arg instanceof Double) { - Double doubleArg; + double doubleArg; if (arg instanceof Float) { doubleArg = arg.doubleValue(); } else { @@ -60,20 +53,17 @@ private Void validateNumericFormat(Number arg, ValidationMetadata validationMeta "Invalid value " + arg + " for format int32 at " + validationMetadata.pathToItem() ); } - return null; } else if (format.equals("int64")) { if (intArg.compareTo(int64InclusiveMinimum) < 0 || intArg.compareTo(int64InclusiveMaximum) > 0) { throw new ValidationException( "Invalid value " + arg + " for format int64 at " + validationMetadata.pathToItem() ); } - return null; } - return null; } else if (format.equals("float") || format.equals("double")) { BigDecimal decimalArg; if (arg instanceof Float) { - decimalArg = new BigDecimal((Float) arg); + decimalArg = BigDecimal.valueOf(arg.doubleValue()); } else if (arg instanceof Double) { decimalArg = BigDecimal.valueOf((Double) arg); } else { @@ -85,83 +75,81 @@ private Void validateNumericFormat(Number arg, ValidationMetadata validationMeta "Invalid value "+arg+" for format float at "+validationMetadata.pathToItem() ); } - return null; - } else if (format.equals("double")) { + } else { if (decimalArg.compareTo(doubleInclusiveMinimum) < 0 || decimalArg.compareTo(doubleInclusiveMaximum) > 0 ){ throw new ValidationException( "Invalid value "+arg+" for format double at "+validationMetadata.pathToItem() ); } - return null; } } - return null; } - private Void validateStringFormat(String arg, ValidationMetadata validationMetadata) { - if (format.equals("uuid")) { - try { - UUID.fromString(arg); - } catch (IllegalArgumentException e) { - throw new ValidationException( - "Value cannot be converted to a UUID. Invalid value "+ - arg+" for format uuid at "+validationMetadata.pathToItem() - ); + private static void validateStringFormat(String arg, ValidationMetadata validationMetadata, String format) { + switch (format) { + case "uuid" -> { + try { + UUID.fromString(arg); + } catch (IllegalArgumentException e) { + throw new ValidationException( + "Value cannot be converted to a UUID. Invalid value " + + arg + " for format uuid at " + validationMetadata.pathToItem() + ); + } } - return null; - } else if (format.equals("number")) { - try { - new BigDecimal(arg); - } catch (NumberFormatException e) { - throw new ValidationException( - "Value cannot be converted to a decimal. Invalid value "+ - arg+" for format number at "+validationMetadata.pathToItem() - ); + case "number" -> { + try { + new BigDecimal(arg); + } catch (NumberFormatException e) { + throw new ValidationException( + "Value cannot be converted to a decimal. Invalid value " + + arg + " for format number at " + validationMetadata.pathToItem() + ); + } } - return null; - } else if (format.equals("date")) { - try { - new CustomIsoparser().parseIsodate(arg); - } catch (DateTimeParseException e) { - throw new ValidationException( - "Value does not conform to the required ISO-8601 date format. "+ - "Invalid value "+arg+" for format date at "+validationMetadata.pathToItem() - ); + case "date" -> { + try { + new CustomIsoparser().parseIsodate(arg); + } catch (DateTimeParseException e) { + throw new ValidationException( + "Value does not conform to the required ISO-8601 date format. " + + "Invalid value " + arg + " for format date at " + validationMetadata.pathToItem() + ); + } } - return null; - } else if (format.equals("date-time")) { - try { - new CustomIsoparser().parseIsodatetime(arg); - } catch (DateTimeParseException e) { - throw new ValidationException( - "Value does not conform to the required ISO-8601 datetime format. "+ - "Invalid value "+arg+" for format datetime at "+validationMetadata.pathToItem() - ); + case "date-time" -> { + try { + new CustomIsoparser().parseIsodatetime(arg); + } catch (DateTimeParseException e) { + throw new ValidationException( + "Value does not conform to the required ISO-8601 datetime format. " + + "Invalid value " + arg + " for format datetime at " + validationMetadata.pathToItem() + ); + } } - return null; } - return null; } @Override public @Nullable PathToSchemasMap validate( - JsonSchema schema, - @Nullable Object arg, - ValidationMetadata validationMetadata, - @Nullable List containsPathToSchemas, - @Nullable PathToSchemasMap patternPropertiesPathToSchemas, - @Nullable PathToSchemasMap ifPathToSchemas + ValidationData data ) { - if (arg instanceof Number) { + var format = data.schema().format; + if (format == null) { + return null; + } + if (data.arg() instanceof Number numberArg) { validateNumericFormat( - (Number) arg, - validationMetadata + numberArg, + data.validationMetadata(), + format ); return null; - } else if (arg instanceof String) { + } else if (data.arg() instanceof String stringArg) { validateStringFormat( - (String) arg, - validationMetadata + stringArg, + data.validationMetadata(), + format ); return null; } diff --git a/samples/client/3_0_3_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/IfValidator.java b/samples/client/3_0_3_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/IfValidator.java index e1634bd1b00..b145ab8007a 100644 --- a/samples/client/3_0_3_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/IfValidator.java +++ b/samples/client/3_0_3_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/IfValidator.java @@ -1,33 +1,18 @@ package org.openapijsonschematools.client.schemas.validation; import org.openapijsonschematools.client.exceptions.ValidationException; -import org.openapijsonschematools.client.exceptions.InvalidTypeException; import org.checkerframework.checker.nullness.qual.Nullable; -import java.util.ArrayList; -import java.util.LinkedHashMap; -import java.util.LinkedHashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; - public class IfValidator implements KeywordValidator { - public final Class ifSchema; - - public IfValidator(Class ifSchema) { - this.ifSchema = ifSchema; - } - @Override public @Nullable PathToSchemasMap validate( - JsonSchema schema, - @Nullable Object arg, - ValidationMetadata validationMetadata, - @Nullable List containsPathToSchemas, - @Nullable PathToSchemasMap patternPropertiesPathToSchemas, - @Nullable PathToSchemasMap ifPathToSchemas + ValidationData data ) { - if (ifPathToSchemas == null) { + var ifSchema = data.schema().ifSchema; + if (ifSchema == null) { + return null; + } + if (data.ifPathToSchemas() == null) { throw new ValidationException("Invalid type for ifPathToSchemas"); } /* @@ -40,17 +25,4 @@ public IfValidator(Class ifSchema) { */ return null; } - - public PathToSchemasMap getIfPathToSchemas( - @Nullable Object arg, - ValidationMetadata validationMetadata - ) { - JsonSchema ifSchemaInstance = JsonSchemaFactory.getInstance(ifSchema); - PathToSchemasMap pathToSchemas = new PathToSchemasMap(); - try { - var otherPathToSchemas = JsonSchema.validate(ifSchemaInstance, arg, validationMetadata); - pathToSchemas.update(otherPathToSchemas); - } catch (ValidationException | InvalidTypeException ignored) {} - return pathToSchemas; - } } diff --git a/samples/client/3_0_3_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/ItemsValidator.java b/samples/client/3_0_3_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/ItemsValidator.java index 5d146ab250c..5bd194d47a9 100644 --- a/samples/client/3_0_3_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/ItemsValidator.java +++ b/samples/client/3_0_3_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/ItemsValidator.java @@ -6,38 +6,31 @@ import java.util.List; public class ItemsValidator implements KeywordValidator { - public final Class items; - - public ItemsValidator(Class items) { - this.items = items; - } - @Override public @Nullable PathToSchemasMap validate( - JsonSchema schema, - @Nullable Object arg, - ValidationMetadata validationMetadata, - @Nullable List containsPathToSchemas, - @Nullable PathToSchemasMap patternPropertiesPathToSchemas, - @Nullable PathToSchemasMap ifPathToSchemas + ValidationData data ) { - if (!(arg instanceof List listArg)) { + var items = data.schema().items; + if (items == null) { + return null; + } + if (!(data.arg() instanceof List listArg)) { return null; } if (listArg.isEmpty()) { return null; } PathToSchemasMap pathToSchemas = new PathToSchemasMap(); - int minIndex = schema.prefixItems != null ? schema.prefixItems.size() : 0; + int minIndex = data.schema().prefixItems != null ? data.schema().prefixItems.size() : 0; JsonSchema itemsSchema = JsonSchemaFactory.getInstance(items); for(int i = minIndex; i < listArg.size(); i++) { - List itemPathToItem = new ArrayList<>(validationMetadata.pathToItem()); + List itemPathToItem = new ArrayList<>(data.validationMetadata().pathToItem()); itemPathToItem.add(i); ValidationMetadata itemValidationMetadata = new ValidationMetadata( itemPathToItem, - validationMetadata.configuration(), - validationMetadata.validatedPathToSchemas(), - validationMetadata.seenClasses() + data.validationMetadata().configuration(), + data.validationMetadata().validatedPathToSchemas(), + data.validationMetadata().seenClasses() ); if (itemValidationMetadata.validationRanEarlier(itemsSchema)) { // todo add_deeper_validated_schemas 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 551c586665c..db33a080218 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 @@ -50,10 +50,10 @@ public abstract class JsonSchema { public final @Nullable Integer maxContains; public final @Nullable Integer minContains; public final @Nullable Class propertyNames; - public @Nullable Map> dependentRequired; + public final @Nullable Map> dependentRequired; public final @Nullable Map> dependentSchemas; - public @Nullable Map> patternProperties; - public @Nullable List> prefixItems; + public final @Nullable Map> patternProperties; + public final @Nullable List> prefixItems; public final @Nullable Class ifSchema; private final LinkedHashMap keywordToValidator; @@ -61,244 +61,142 @@ protected JsonSchema(JsonSchemaInfo jsonSchemaInfo) { LinkedHashMap keywordToValidator = new LinkedHashMap<>(); this.type = jsonSchemaInfo.type; if (this.type != null) { - keywordToValidator.put( - "type", - new TypeValidator(this.type) - ); + keywordToValidator.put("type", new TypeValidator()); } this.format = jsonSchemaInfo.format; if (this.format != null) { - keywordToValidator.put( - "format", - new FormatValidator(this.format) - ); + keywordToValidator.put("format", new FormatValidator()); } this.items = jsonSchemaInfo.items; if (this.items != null) { - keywordToValidator.put( - "items", - new ItemsValidator(this.items) - ); + keywordToValidator.put("items", new ItemsValidator()); } this.properties = jsonSchemaInfo.properties; if (this.properties != null) { - keywordToValidator.put( - "properties", - new PropertiesValidator(this.properties) - ); + keywordToValidator.put("properties", new PropertiesValidator()); } this.required = jsonSchemaInfo.required; if (this.required != null) { - keywordToValidator.put( - "required", - new RequiredValidator(this.required) - ); + keywordToValidator.put("required", new RequiredValidator()); } this.exclusiveMaximum = jsonSchemaInfo.exclusiveMaximum; if (this.exclusiveMaximum != null) { - keywordToValidator.put( - "exclusiveMaximum", - new ExclusiveMaximumValidator(this.exclusiveMaximum) - ); + keywordToValidator.put("exclusiveMaximum", new ExclusiveMaximumValidator()); } this.exclusiveMinimum = jsonSchemaInfo.exclusiveMinimum; if (this.exclusiveMinimum != null) { - keywordToValidator.put( - "exclusiveMinimum", - new ExclusiveMinimumValidator(this.exclusiveMinimum) - ); + keywordToValidator.put("exclusiveMinimum", new ExclusiveMinimumValidator()); } this.maxItems = jsonSchemaInfo.maxItems; if (this.maxItems != null) { - keywordToValidator.put( - "maxItems", - new MaxItemsValidator(this.maxItems) - ); + keywordToValidator.put("maxItems", new MaxItemsValidator()); } this.minItems = jsonSchemaInfo.minItems; if (this.minItems != null) { - keywordToValidator.put( - "minItems", - new MinItemsValidator(this.minItems) - ); + keywordToValidator.put("minItems", new MinItemsValidator()); } this.maxLength = jsonSchemaInfo.maxLength; if (this.maxLength != null) { - keywordToValidator.put( - "maxLength", - new MaxLengthValidator(this.maxLength) - ); + keywordToValidator.put("maxLength", new MaxLengthValidator()); } this.minLength = jsonSchemaInfo.minLength; if (this.minLength != null) { - keywordToValidator.put( - "minLength", - new MinLengthValidator(this.minLength) - ); + keywordToValidator.put("minLength", new MinLengthValidator()); } this.maxProperties = jsonSchemaInfo.maxProperties; if (this.maxProperties != null) { - keywordToValidator.put( - "maxProperties", - new MaxPropertiesValidator(this.maxProperties) - ); + keywordToValidator.put("maxProperties", new MaxPropertiesValidator()); } this.minProperties = jsonSchemaInfo.minProperties; if (this.minProperties != null) { - keywordToValidator.put( - "minProperties", - new MinPropertiesValidator(this.minProperties) - ); + keywordToValidator.put("minProperties", new MinPropertiesValidator()); } this.maximum = jsonSchemaInfo.maximum; if (this.maximum != null) { - keywordToValidator.put( - "maximum", - new MaximumValidator(this.maximum) - ); + keywordToValidator.put("maximum", new MaximumValidator()); } this.minimum = jsonSchemaInfo.minimum; if (this.minimum != null) { - keywordToValidator.put( - "minimum", - new MinimumValidator(this.minimum) - ); + keywordToValidator.put("minimum", new MinimumValidator()); } this.multipleOf = jsonSchemaInfo.multipleOf; if (this.multipleOf != null) { - keywordToValidator.put( - "multipleOf", - new MultipleOfValidator(this.multipleOf) - ); + keywordToValidator.put("multipleOf", new MultipleOfValidator()); } this.additionalProperties = jsonSchemaInfo.additionalProperties; if (this.additionalProperties != null) { - keywordToValidator.put( - "additionalProperties", - new AdditionalPropertiesValidator(this.additionalProperties) - ); + keywordToValidator.put("additionalProperties", new AdditionalPropertiesValidator()); } this.allOf = jsonSchemaInfo.allOf; if (this.allOf != null) { - keywordToValidator.put( - "allOf", - new AllOfValidator(this.allOf) - ); + keywordToValidator.put("allOf", new AllOfValidator()); } this.anyOf = jsonSchemaInfo.anyOf; if (this.anyOf != null) { - keywordToValidator.put( - "anyOf", - new AnyOfValidator(this.anyOf) - ); + keywordToValidator.put("anyOf", new AnyOfValidator()); } this.oneOf = jsonSchemaInfo.oneOf; if (this.oneOf != null) { - keywordToValidator.put( - "oneOf", - new OneOfValidator(this.oneOf) - ); + keywordToValidator.put("oneOf", new OneOfValidator()); } this.not = jsonSchemaInfo.not; if (this.not != null) { - keywordToValidator.put( - "not", - new NotValidator(this.not) - ); + keywordToValidator.put("not", new NotValidator()); } this.uniqueItems = jsonSchemaInfo.uniqueItems; if (this.uniqueItems != null) { - keywordToValidator.put( - "uniqueItems", - new UniqueItemsValidator(this.uniqueItems) - ); + keywordToValidator.put("uniqueItems", new UniqueItemsValidator()); } this.enumValues = jsonSchemaInfo.enumValues; if (this.enumValues != null) { - keywordToValidator.put( - "enum", - new EnumValidator(this.enumValues) - ); + keywordToValidator.put("enum", new EnumValidator()); } this.pattern = jsonSchemaInfo.pattern; if (this.pattern != null) { - keywordToValidator.put( - "pattern", - new PatternValidator(this.pattern) - ); + keywordToValidator.put("pattern", new PatternValidator()); } this.defaultValue = jsonSchemaInfo.defaultValue; this.defaultValueSet = jsonSchemaInfo.defaultValueSet; this.constValue = jsonSchemaInfo.constValue; this.constValueSet = jsonSchemaInfo.constValueSet; if (this.constValueSet) { - keywordToValidator.put( - "const", - new ConstValidator(this.constValue) - ); + keywordToValidator.put("const", new ConstValidator()); } this.contains = jsonSchemaInfo.contains; if (this.contains != null) { - keywordToValidator.put( - "contains", - new ContainsValidator(this.contains) - ); + keywordToValidator.put("contains", new ContainsValidator()); } this.maxContains = jsonSchemaInfo.maxContains; if (this.maxContains != null) { - keywordToValidator.put( - "maxContains", - new MaxContainsValidator(this.maxContains) - ); + keywordToValidator.put("maxContains", new MaxContainsValidator()); } this.minContains = jsonSchemaInfo.minContains; if (this.minContains != null) { - keywordToValidator.put( - "minContains", - new MinContainsValidator(this.minContains) - ); + keywordToValidator.put("minContains", new MinContainsValidator()); } this.propertyNames = jsonSchemaInfo.propertyNames; if (this.propertyNames != null) { - keywordToValidator.put( - "propertyNames", - new PropertyNamesValidator(this.propertyNames) - ); + keywordToValidator.put("propertyNames", new PropertyNamesValidator()); } this.dependentRequired = jsonSchemaInfo.dependentRequired; if (this.dependentRequired != null) { - keywordToValidator.put( - "dependentRequired", - new DependentRequiredValidator(this.dependentRequired) - ); + keywordToValidator.put("dependentRequired", new DependentRequiredValidator()); } this.dependentSchemas = jsonSchemaInfo.dependentSchemas; if (this.dependentSchemas != null) { - keywordToValidator.put( - "dependentSchemas", - new DependentSchemasValidator(this.dependentSchemas) - ); + keywordToValidator.put("dependentSchemas", new DependentSchemasValidator()); } this.patternProperties = jsonSchemaInfo.patternProperties; if (this.patternProperties != null) { - keywordToValidator.put( - "patternProperties", - new PatternPropertiesValidator(this.patternProperties) - ); + keywordToValidator.put("patternProperties", new PatternPropertiesValidator()); } this.prefixItems = jsonSchemaInfo.prefixItems; if (this.prefixItems != null) { - keywordToValidator.put( - "prefixItems", - new PrefixItemsValidator(this.prefixItems) - ); + keywordToValidator.put("prefixItems", new PrefixItemsValidator()); } this.ifSchema = jsonSchemaInfo.ifSchema; if (this.ifSchema != null) { - keywordToValidator.put( - "if", - new IfValidator(this.ifSchema) - ); + keywordToValidator.put("if", new IfValidator()); } this.keywordToValidator = keywordToValidator; } @@ -306,6 +204,93 @@ protected JsonSchema(JsonSchemaInfo jsonSchemaInfo) { public abstract @Nullable Object getNewInstance(@Nullable Object arg, List pathToItem, PathToSchemasMap pathToSchemas) throws InvalidTypeException; public abstract @Nullable Object validate(@Nullable Object arg, SchemaConfiguration configuration) throws InvalidTypeException, ValidationException; + private List getContainsPathToSchemas( + @Nullable Object arg, + ValidationMetadata validationMetadata + ) { + if (!(arg instanceof List listArg) || contains == null) { + return new ArrayList<>(); + } + JsonSchema containsSchema = JsonSchemaFactory.getInstance(contains); + @Nullable List containsPathToSchemas = new ArrayList<>(); + int i = 0; + for(Object itemValue: listArg) { + PathToSchemasMap thesePathToSchemas = new PathToSchemasMap(); + List itemPathToItem = new ArrayList<>(validationMetadata.pathToItem()); + itemPathToItem.add(i); + ValidationMetadata itemValidationMetadata = new ValidationMetadata( + itemPathToItem, + validationMetadata.configuration(), + validationMetadata.validatedPathToSchemas(), + validationMetadata.seenClasses() + ); + if (itemValidationMetadata.validationRanEarlier(containsSchema)) { + // todo add_deeper_validated_schemas + containsPathToSchemas.add(thesePathToSchemas); + i += 1; + continue; + } + + try { + PathToSchemasMap otherPathToSchemas = JsonSchema.validate( + containsSchema, itemValue, itemValidationMetadata); + containsPathToSchemas.add(otherPathToSchemas); + } catch (ValidationException ignored) {} + } + return containsPathToSchemas; + } + + private PathToSchemasMap getPatternPropertiesPathToSchemas( + @Nullable Object arg, + ValidationMetadata validationMetadata + ) { + if (!(arg instanceof Map mapArg) || patternProperties == null) { + return new PathToSchemasMap(); + } + PathToSchemasMap pathToSchemas = new PathToSchemasMap(); + for (Map.Entry entry: mapArg.entrySet()) { + Object entryKey = entry.getKey(); + if (!(entryKey instanceof String key)) { + throw new InvalidTypeException("Invalid non-string type for map key"); + } + List propPathToItem = new ArrayList<>(validationMetadata.pathToItem()); + propPathToItem.add(key); + ValidationMetadata propValidationMetadata = new ValidationMetadata( + propPathToItem, + validationMetadata.configuration(), + validationMetadata.validatedPathToSchemas(), + validationMetadata.seenClasses() + ); + for (Map.Entry> patternPropEntry: patternProperties.entrySet()) { + if (!patternPropEntry.getKey().matcher(key).find()) { + continue; + } + + Class patternPropClass = patternPropEntry.getValue(); + JsonSchema patternPropSchema = JsonSchemaFactory.getInstance(patternPropClass); + PathToSchemasMap otherPathToSchemas = JsonSchema.validate(patternPropSchema, entry.getValue(), propValidationMetadata); + pathToSchemas.update(otherPathToSchemas); + } + } + return pathToSchemas; + } + + private PathToSchemasMap getIfPathToSchemas( + @Nullable Object arg, + ValidationMetadata validationMetadata + ) { + if (ifSchema == null) { + return new PathToSchemasMap(); + } + JsonSchema ifSchemaInstance = JsonSchemaFactory.getInstance(ifSchema); + PathToSchemasMap pathToSchemas = new PathToSchemasMap(); + try { + var otherPathToSchemas = JsonSchema.validate(ifSchemaInstance, arg, validationMetadata); + pathToSchemas.update(otherPathToSchemas); + } catch (ValidationException | InvalidTypeException ignored) {} + return pathToSchemas; + } + public static PathToSchemasMap validate( JsonSchema jsonSchema, @Nullable Object arg, @@ -315,19 +300,16 @@ public static PathToSchemasMap validate( PathToSchemasMap pathToSchemas = new PathToSchemasMap(); LinkedHashMap thisKeywordToValidator = jsonSchema.keywordToValidator; @Nullable List containsPathToSchemas = null; - KeywordValidator containsValidator = thisKeywordToValidator.get("contains"); - if (containsValidator != null) { - containsPathToSchemas = containsValidator.getContainsPathToSchemas(arg, validationMetadata); + if (thisKeywordToValidator.containsKey("contains")) { + containsPathToSchemas = jsonSchema.getContainsPathToSchemas(arg, validationMetadata); } @Nullable PathToSchemasMap patternPropertiesPathToSchemas = null; - KeywordValidator patternPropertiesValidator = thisKeywordToValidator.get("patternProperties"); - if (patternPropertiesValidator != null) { - patternPropertiesPathToSchemas = patternPropertiesValidator.getPatternPropertiesPathToSchemas(arg, validationMetadata); + if (thisKeywordToValidator.containsKey("patternProperties")) { + patternPropertiesPathToSchemas = jsonSchema.getPatternPropertiesPathToSchemas(arg, validationMetadata); } @Nullable PathToSchemasMap ifPathToSchemas = null; - KeywordValidator ifValidator = thisKeywordToValidator.get("if"); - if (ifValidator != null) { - ifPathToSchemas = ifValidator.getIfPathToSchemas(arg, validationMetadata); + if (thisKeywordToValidator.containsKey("if")) { + ifPathToSchemas = jsonSchema.getIfPathToSchemas(arg, validationMetadata); } for (Map.Entry entry: thisKeywordToValidator.entrySet()) { String jsonKeyword = entry.getKey(); @@ -338,7 +320,7 @@ public static PathToSchemasMap validate( } } KeywordValidator validator = entry.getValue(); - @Nullable PathToSchemasMap otherPathToSchemas = validator.validate( + ValidationData data = new ValidationData( jsonSchema, arg, validationMetadata, @@ -346,6 +328,7 @@ public static PathToSchemasMap validate( patternPropertiesPathToSchemas, ifPathToSchemas ); + @Nullable PathToSchemasMap otherPathToSchemas = validator.validate(data); if (otherPathToSchemas == null) { continue; } @@ -401,10 +384,9 @@ protected List castToAllowedTypes(List arg, List pathToItem, Set argFixed = new LinkedHashMap<>(); for (Map.Entry entry: arg.entrySet()) { @Nullable Object entryKey = entry.getKey(); - if (!(entryKey instanceof String)) { + if (!(entryKey instanceof String key)) { throw new InvalidTypeException("Invalid non-string key value"); } - String key = (String) entryKey; Object val = entry.getValue(); List newPathToItem = new ArrayList<>(pathToItem); newPathToItem.add(key); diff --git a/samples/client/3_0_3_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/KeywordValidator.java b/samples/client/3_0_3_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/KeywordValidator.java index 41b4b85eb2e..8a2bd782505 100644 --- a/samples/client/3_0_3_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/KeywordValidator.java +++ b/samples/client/3_0_3_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/KeywordValidator.java @@ -3,37 +3,9 @@ import org.openapijsonschematools.client.exceptions.ValidationException; import org.checkerframework.checker.nullness.qual.Nullable; -import java.util.ArrayList; -import java.util.List; - +@FunctionalInterface public interface KeywordValidator { @Nullable PathToSchemasMap validate( - JsonSchema schema, - @Nullable Object arg, - ValidationMetadata validationMetadata, - @Nullable List containsPathToSchemas, - @Nullable PathToSchemasMap patternPropertiesPathToSchemas, - @Nullable PathToSchemasMap ifPathToSchemas + ValidationData data ) throws ValidationException; - - default List getContainsPathToSchemas( - @Nullable Object arg, - ValidationMetadata validationMetadata - ) { - return new ArrayList<>(); - } - - default PathToSchemasMap getPatternPropertiesPathToSchemas( - @Nullable Object arg, - ValidationMetadata validationMetadata - ) { - return new PathToSchemasMap(); - } - - default PathToSchemasMap getIfPathToSchemas( - @Nullable Object arg, - ValidationMetadata validationMetadata - ) { - return new PathToSchemasMap(); - } } \ No newline at end of file diff --git a/samples/client/3_0_3_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/MaxContainsValidator.java b/samples/client/3_0_3_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/MaxContainsValidator.java index 25482139fab..9e9b3b92c18 100644 --- a/samples/client/3_0_3_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/MaxContainsValidator.java +++ b/samples/client/3_0_3_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/MaxContainsValidator.java @@ -6,31 +6,25 @@ import java.util.List; public class MaxContainsValidator implements KeywordValidator { - public final int maxContains; - - public MaxContainsValidator(int maxContains) { - this.maxContains = maxContains; - } - @Override public @Nullable PathToSchemasMap validate( - JsonSchema schema, - @Nullable Object arg, - ValidationMetadata validationMetadata, - @Nullable List containsPathToSchemas, - @Nullable PathToSchemasMap patternPropertiesPathToSchemas, - @Nullable PathToSchemasMap ifPathToSchemas + ValidationData data ) { - if (!(arg instanceof List)) { + var maxContains = data.schema().maxContains; + if (maxContains == null) { + return null; + } + if (!(data.arg() instanceof List)) { return null; } + var containsPathToSchemas = data.containsPathToSchemas(); if (containsPathToSchemas == null) { return null; } if (containsPathToSchemas.size() > maxContains) { throw new ValidationException( - "Validation failed for maxContains keyword in class="+schema.getClass()+ - " at pathToItem="+validationMetadata.pathToItem()+". Too many items validated to the contains schema." + "Validation failed for maxContains keyword in class="+data.schema().getClass()+ + " at pathToItem="+data.validationMetadata().pathToItem()+". Too many items validated to the contains schema." ); } return null; diff --git a/samples/client/3_0_3_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/MaxItemsValidator.java b/samples/client/3_0_3_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/MaxItemsValidator.java index bda6fb43ece..98ed5cb4ff4 100644 --- a/samples/client/3_0_3_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/MaxItemsValidator.java +++ b/samples/client/3_0_3_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/MaxItemsValidator.java @@ -6,26 +6,19 @@ import java.util.List; public class MaxItemsValidator implements KeywordValidator { - public final int maxItems; - - public MaxItemsValidator(int maxItems) { - this.maxItems = maxItems; - } - @Override public @Nullable PathToSchemasMap validate( - JsonSchema schema, - @Nullable Object arg, - ValidationMetadata validationMetadata, - @Nullable List containsPathToSchemas, - @Nullable PathToSchemasMap patternPropertiesPathToSchemas, - @Nullable PathToSchemasMap ifPathToSchemas + ValidationData data ) { - if (!(arg instanceof List)) { + var maxItems = data.schema().maxItems; + if (maxItems == null) { + return null; + } + if (!(data.arg() instanceof List listArg)) { return null; } - if (((List) arg).size() > maxItems) { - throw new ValidationException("Value " + arg + " is invalid because has > the maxItems of " + maxItems); + if (listArg.size() > maxItems) { + throw new ValidationException("Value " + listArg + " is invalid because has > the maxItems of " + maxItems); } return null; } diff --git a/samples/client/3_0_3_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/MaxLengthValidator.java b/samples/client/3_0_3_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/MaxLengthValidator.java index 1a78623e0f4..08d91666c5d 100644 --- a/samples/client/3_0_3_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/MaxLengthValidator.java +++ b/samples/client/3_0_3_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/MaxLengthValidator.java @@ -3,30 +3,21 @@ import org.openapijsonschematools.client.exceptions.ValidationException; import org.checkerframework.checker.nullness.qual.Nullable; -import java.util.List; - public class MaxLengthValidator extends LengthValidator implements KeywordValidator { - public final int maxLength; - - public MaxLengthValidator(int maxLength) { - this.maxLength = maxLength; - } - @Override public @Nullable PathToSchemasMap validate( - JsonSchema schema, - @Nullable Object arg, - ValidationMetadata validationMetadata, - @Nullable List containsPathToSchemas, - @Nullable PathToSchemasMap patternPropertiesPathToSchemas, - @Nullable PathToSchemasMap ifPathToSchemas + ValidationData data ) { - if (!(arg instanceof String)) { + var maxLength = data.schema().maxLength; + if (maxLength == null) { + return null; + } + if (!(data.arg() instanceof String stringArg)) { return null; } - int length = getLength((String) arg); + int length = getLength(stringArg); if (length > maxLength) { - throw new ValidationException("Value " + arg + " is invalid because has > the maxLength of " + maxLength); + throw new ValidationException("Value " + stringArg + " is invalid because has > the maxLength of " + maxLength); } return null; } diff --git a/samples/client/3_0_3_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/MaxPropertiesValidator.java b/samples/client/3_0_3_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/MaxPropertiesValidator.java index 5928ec588ac..d117f1688e2 100644 --- a/samples/client/3_0_3_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/MaxPropertiesValidator.java +++ b/samples/client/3_0_3_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/MaxPropertiesValidator.java @@ -3,30 +3,22 @@ import org.openapijsonschematools.client.exceptions.ValidationException; import org.checkerframework.checker.nullness.qual.Nullable; -import java.util.List; import java.util.Map; public class MaxPropertiesValidator implements KeywordValidator { - public final int maxProperties; - - public MaxPropertiesValidator(int maxProperties) { - this.maxProperties = maxProperties; - } - @Override public @Nullable PathToSchemasMap validate( - JsonSchema schema, - @Nullable Object arg, - ValidationMetadata validationMetadata, - @Nullable List containsPathToSchemas, - @Nullable PathToSchemasMap patternPropertiesPathToSchemas, - @Nullable PathToSchemasMap ifPathToSchemas + ValidationData data ) { - if (!(arg instanceof Map)) { + var maxProperties = data.schema().maxProperties; + if (maxProperties == null) { + return null; + } + if (!(data.arg() instanceof Map mapArg)) { return null; } - if (((Map) arg).size() > maxProperties) { - throw new ValidationException("Value " + arg + " is invalid because has > the maxProperties of " + maxProperties); + if (mapArg.size() > maxProperties) { + throw new ValidationException("Value " + mapArg + " is invalid because has > the maxProperties of " + maxProperties); } return null; } diff --git a/samples/client/3_0_3_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/MaximumValidator.java b/samples/client/3_0_3_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/MaximumValidator.java index 25faceb4022..702f09686dc 100644 --- a/samples/client/3_0_3_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/MaximumValidator.java +++ b/samples/client/3_0_3_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/MaximumValidator.java @@ -3,52 +3,43 @@ import org.openapijsonschematools.client.exceptions.ValidationException; import org.checkerframework.checker.nullness.qual.Nullable; -import java.util.List; - public class MaximumValidator implements KeywordValidator { - public final Number maximum; - - public MaximumValidator(Number maximum) { - this.maximum = maximum; - } - @Override public @Nullable PathToSchemasMap validate( - JsonSchema schema, - @Nullable Object arg, - ValidationMetadata validationMetadata, - @Nullable List containsPathToSchemas, - @Nullable PathToSchemasMap patternPropertiesPathToSchemas, - @Nullable PathToSchemasMap ifPathToSchemas + ValidationData data ) { - if (!(arg instanceof Number)) { + var maximum = data.schema().maximum; + if (maximum == null) { + return null; + } + if (!(data.arg() instanceof Number)) { return null; } - String msg = "Value " + arg + " is invalid because it is > the maximum of " + maximum; - if (arg instanceof Integer) { - if (((Integer) arg).compareTo(maximum.intValue()) == 1) { + String msg = "Value " + data.arg() + " is invalid because it is > the maximum of " + maximum; + if (data.arg() instanceof Integer intArg) { + if (intArg.compareTo(maximum.intValue()) > 0) { throw new ValidationException(msg); } return null; } - if (arg instanceof Long) { - if (((Long) arg).compareTo(maximum.longValue()) == 1) { + if (data.arg() instanceof Long longArg) { + if (longArg.compareTo(maximum.longValue()) > 0) { throw new ValidationException(msg); } return null; } - if (arg instanceof Float) { - if (((Float) arg).compareTo(maximum.floatValue()) == 1) { + if (data.arg() instanceof Float floatArg) { + if (floatArg.compareTo(maximum.floatValue()) > 0) { throw new ValidationException(msg); } return null; } - if (arg instanceof Double) { - if (((Double) arg).compareTo(maximum.doubleValue()) == 1) { + if (data.arg() instanceof Double doubleArg) { + if (doubleArg.compareTo(maximum.doubleValue()) > 0) { throw new ValidationException(msg); } return null; } return null; } -} +} \ No newline at end of file diff --git a/samples/client/3_0_3_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/MinContainsValidator.java b/samples/client/3_0_3_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/MinContainsValidator.java index 2f34127155e..1827e95cc83 100644 --- a/samples/client/3_0_3_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/MinContainsValidator.java +++ b/samples/client/3_0_3_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/MinContainsValidator.java @@ -6,31 +6,24 @@ import java.util.List; public class MinContainsValidator implements KeywordValidator { - public final int minContains; - - public MinContainsValidator(int minContains) { - this.minContains = minContains; - } - @Override public @Nullable PathToSchemasMap validate( - JsonSchema schema, - @Nullable Object arg, - ValidationMetadata validationMetadata, - @Nullable List containsPathToSchemas, - @Nullable PathToSchemasMap patternPropertiesPathToSchemas, - @Nullable PathToSchemasMap ifPathToSchemas + ValidationData data ) { - if (!(arg instanceof List)) { + var minContains = data.schema().minContains; + if (minContains == null) { + return null; + } + if (!(data.arg() instanceof List)) { return null; } - if (containsPathToSchemas == null) { + if (data.containsPathToSchemas() == null) { return null; } - if (containsPathToSchemas.size() < minContains) { + if (data.containsPathToSchemas().size() < minContains) { throw new ValidationException( - "Validation failed for minContains keyword in class="+schema.getClass()+ - " at pathToItem="+validationMetadata.pathToItem()+". Too few items validated to the contains schema." + "Validation failed for minContains keyword in class="+data.schema().getClass()+ + " at pathToItem="+data.validationMetadata().pathToItem()+". Too few items validated to the contains schema." ); } return null; diff --git a/samples/client/3_0_3_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/MinItemsValidator.java b/samples/client/3_0_3_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/MinItemsValidator.java index 7c46cbe8f94..d1933ca7750 100644 --- a/samples/client/3_0_3_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/MinItemsValidator.java +++ b/samples/client/3_0_3_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/MinItemsValidator.java @@ -6,26 +6,19 @@ import java.util.List; public class MinItemsValidator implements KeywordValidator { - public final int minItems; - - public MinItemsValidator(int minItems) { - this.minItems = minItems; - } - @Override public @Nullable PathToSchemasMap validate( - JsonSchema schema, - @Nullable Object arg, - ValidationMetadata validationMetadata, - @Nullable List containsPathToSchemas, - @Nullable PathToSchemasMap patternPropertiesPathToSchemas, - @Nullable PathToSchemasMap ifPathToSchemas + ValidationData data ) { - if (!(arg instanceof List)) { + var minItems = data.schema().minItems; + if (minItems == null) { + return null; + } + if (!(data.arg() instanceof List listArg)) { return null; } - if (((List) arg).size() < minItems) { - throw new ValidationException("Value " + arg + " is invalid because has < the minItems of " + minItems); + if (listArg.size() < minItems) { + throw new ValidationException("Value " + listArg + " is invalid because has < the minItems of " + minItems); } return null; } diff --git a/samples/client/3_0_3_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/MinLengthValidator.java b/samples/client/3_0_3_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/MinLengthValidator.java index 7c92205a9cf..1defdc891e3 100644 --- a/samples/client/3_0_3_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/MinLengthValidator.java +++ b/samples/client/3_0_3_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/MinLengthValidator.java @@ -3,31 +3,22 @@ import org.openapijsonschematools.client.exceptions.ValidationException; import org.checkerframework.checker.nullness.qual.Nullable; -import java.util.List; - public class MinLengthValidator extends LengthValidator implements KeywordValidator { - public final int minLength; - - public MinLengthValidator(int minLength) { - this.minLength = minLength; - } - @Override public @Nullable PathToSchemasMap validate( - JsonSchema schema, - @Nullable Object arg, - ValidationMetadata validationMetadata, - @Nullable List containsPathToSchemas, - @Nullable PathToSchemasMap patternPropertiesPathToSchemas, - @Nullable PathToSchemasMap ifPathToSchemas + ValidationData data ) { - if (!(arg instanceof String)) { + var minLength = data.schema().minLength; + if (minLength == null) { + return null; + } + if (!(data.arg() instanceof String stringArg)) { return null; } - int length = getLength((String) arg); + int length = getLength(stringArg); if (length < minLength) { - throw new ValidationException("Value " + arg + " is invalid because has < the minLength of " + minLength); + throw new ValidationException("Value " + stringArg + " is invalid because has < the minLength of " + minLength); } return null; } -} +} \ No newline at end of file diff --git a/samples/client/3_0_3_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/MinPropertiesValidator.java b/samples/client/3_0_3_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/MinPropertiesValidator.java index c52b16000d8..c0b99e7fb7d 100644 --- a/samples/client/3_0_3_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/MinPropertiesValidator.java +++ b/samples/client/3_0_3_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/MinPropertiesValidator.java @@ -3,30 +3,22 @@ import org.openapijsonschematools.client.exceptions.ValidationException; import org.checkerframework.checker.nullness.qual.Nullable; -import java.util.List; import java.util.Map; public class MinPropertiesValidator implements KeywordValidator { - public final int minProperties; - - public MinPropertiesValidator(int minProperties) { - this.minProperties = minProperties; - } - @Override public @Nullable PathToSchemasMap validate( - JsonSchema schema, - @Nullable Object arg, - ValidationMetadata validationMetadata, - @Nullable List containsPathToSchemas, - @Nullable PathToSchemasMap patternPropertiesPathToSchemas, - @Nullable PathToSchemasMap ifPathToSchemas + ValidationData data ) { - if (!(arg instanceof Map)) { + var minProperties = data.schema().minProperties; + if (minProperties == null) { + return null; + } + if (!(data.arg() instanceof Map mapArg)) { return null; } - if (((Map) arg).size() < minProperties) { - throw new ValidationException("Value " + arg + " is invalid because has < the minProperties of " + minProperties); + if (mapArg.size() < minProperties) { + throw new ValidationException("Value " + mapArg + " is invalid because has < the minProperties of " + minProperties); } return null; } diff --git a/samples/client/3_0_3_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/MinimumValidator.java b/samples/client/3_0_3_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/MinimumValidator.java index dec192d47df..3b539120e42 100644 --- a/samples/client/3_0_3_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/MinimumValidator.java +++ b/samples/client/3_0_3_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/MinimumValidator.java @@ -3,48 +3,39 @@ import org.openapijsonschematools.client.exceptions.ValidationException; import org.checkerframework.checker.nullness.qual.Nullable; -import java.util.List; - public class MinimumValidator implements KeywordValidator { - public final Number minimum; - - public MinimumValidator(Number minimum) { - this.minimum = minimum; - } - @Override public @Nullable PathToSchemasMap validate( - JsonSchema schema, - @Nullable Object arg, - ValidationMetadata validationMetadata, - @Nullable List containsPathToSchemas, - @Nullable PathToSchemasMap patternPropertiesPathToSchemas, - @Nullable PathToSchemasMap ifPathToSchemas + ValidationData data ) { - if (!(arg instanceof Number)) { + var minimum = data.schema().minimum; + if (minimum == null) { + return null; + } + if (!(data.arg() instanceof Number)) { return null; } - String msg = "Value " + arg + " is invalid because it is < the minimum of " + minimum; - if (arg instanceof Integer) { - if (((Integer) arg).compareTo(minimum.intValue()) == -1) { + String msg = "Value " + data.arg() + " is invalid because it is < the minimum of " + minimum; + if (data.arg() instanceof Integer intArg) { + if (intArg.compareTo(minimum.intValue()) < 0) { throw new ValidationException(msg); } return null; } - if (arg instanceof Long) { - if (((Long) arg).compareTo(minimum.longValue()) == -1) { + if (data.arg() instanceof Long longArg) { + if (longArg.compareTo(minimum.longValue()) < 0) { throw new ValidationException(msg); } return null; } - if (arg instanceof Float) { - if (((Float) arg).compareTo(minimum.floatValue()) == -1) { + if (data.arg() instanceof Float floatArg) { + if (floatArg.compareTo(minimum.floatValue()) < 0) { throw new ValidationException(msg); } return null; } - if (arg instanceof Double) { - if (((Double) arg).compareTo(minimum.doubleValue()) == -1) { + if (data.arg() instanceof Double doubleArg) { + if (doubleArg.compareTo(minimum.doubleValue()) < 0) { throw new ValidationException(msg); } return null; diff --git a/samples/client/3_0_3_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/MultipleOfValidator.java b/samples/client/3_0_3_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/MultipleOfValidator.java index 15230b54275..eebc07a0f10 100644 --- a/samples/client/3_0_3_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/MultipleOfValidator.java +++ b/samples/client/3_0_3_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/MultipleOfValidator.java @@ -3,33 +3,25 @@ import org.openapijsonschematools.client.exceptions.ValidationException; import org.checkerframework.checker.nullness.qual.Nullable; -import java.util.List; import java.math.BigDecimal; public class MultipleOfValidator extends BigDecimalValidator implements KeywordValidator { - public final BigDecimal multipleOf; - - public MultipleOfValidator(BigDecimal multipleOf) { - this.multipleOf = multipleOf; - } - @Override public @Nullable PathToSchemasMap validate( - JsonSchema schema, - @Nullable Object arg, - ValidationMetadata validationMetadata, - @Nullable List containsPathToSchemas, - @Nullable PathToSchemasMap patternPropertiesPathToSchemas, - @Nullable PathToSchemasMap ifPathToSchemas + ValidationData data ) { - if (!(arg instanceof Number)) { + var multipleOf = data.schema().multipleOf; + if (multipleOf == null) { + return null; + } + if (!(data.arg() instanceof Number numberArg)) { return null; } - BigDecimal castArg = getBigDecimal((Number) arg); - String msg = "Value " + arg + " is invalid because it is not a multiple of " + multipleOf; + BigDecimal castArg = getBigDecimal(numberArg); + String msg = "Value " + numberArg + " is invalid because it is not a multiple of " + multipleOf; if (castArg.remainder(multipleOf).compareTo(BigDecimal.ZERO) != 0) { throw new ValidationException(msg); } return null; } -} +} \ No newline at end of file diff --git a/samples/client/3_0_3_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/NotValidator.java b/samples/client/3_0_3_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/NotValidator.java index 507c7f40fbc..aa61be1b624 100644 --- a/samples/client/3_0_3_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/NotValidator.java +++ b/samples/client/3_0_3_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/NotValidator.java @@ -3,39 +3,25 @@ import org.openapijsonschematools.client.exceptions.ValidationException; import org.checkerframework.checker.nullness.qual.Nullable; -import java.util.ArrayList; -import java.util.LinkedHashMap; -import java.util.LinkedHashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; - public class NotValidator implements KeywordValidator { - public final Class not; - - public NotValidator(Class not) { - this.not = not; - } - @Override public @Nullable PathToSchemasMap validate( - JsonSchema schema, - @Nullable Object arg, - ValidationMetadata validationMetadata, - @Nullable List containsPathToSchemas, - @Nullable PathToSchemasMap patternPropertiesPathToSchemas, - @Nullable PathToSchemasMap ifPathToSchemas + ValidationData data ) { + var not = data.schema().not; + if (not == null) { + return null; + } PathToSchemasMap pathToSchemas; try { JsonSchema notSchema = JsonSchemaFactory.getInstance(not); - pathToSchemas = JsonSchema.validate(notSchema, arg, validationMetadata); + pathToSchemas = JsonSchema.validate(notSchema, data.arg(), data.validationMetadata()); } catch (ValidationException e) { return null; } if (!pathToSchemas.isEmpty()) { throw new ValidationException( - "Invalid value "+arg+" was passed in to "+schema.getClass()+". "+ + "Invalid value "+data.arg()+" was passed in to "+data.schema().getClass()+". "+ "Value is invalid because it is disallowed by not "+not ); } diff --git a/samples/client/3_0_3_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/OneOfValidator.java b/samples/client/3_0_3_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/OneOfValidator.java index 5bc4bbd297b..f84f7796a8c 100644 --- a/samples/client/3_0_3_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/OneOfValidator.java +++ b/samples/client/3_0_3_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/OneOfValidator.java @@ -7,25 +7,18 @@ import java.util.List; public class OneOfValidator implements KeywordValidator { - public final List> oneOf; - - public OneOfValidator(List> oneOf) { - this.oneOf = oneOf; - } - @Override public @Nullable PathToSchemasMap validate( - JsonSchema schema, - @Nullable Object arg, - ValidationMetadata validationMetadata, - @Nullable List containsPathToSchemas, - @Nullable PathToSchemasMap patternPropertiesPathToSchemas, - @Nullable PathToSchemasMap ifPathToSchemas + ValidationData data ) { + var oneOf = data.schema().oneOf; + if (oneOf == null) { + return null; + } PathToSchemasMap pathToSchemas = new PathToSchemasMap(); List> validatedOneOfClasses = new ArrayList<>(); for(Class oneOfClass: oneOf) { - if (oneOfClass == schema.getClass()) { + if (oneOfClass == data.schema().getClass()) { /* optimistically assume that schema will pass validation do not invoke validate on it because that is recursive @@ -35,7 +28,7 @@ public OneOfValidator(List> oneOf) { } try { JsonSchema oneOfSchema = JsonSchemaFactory.getInstance(oneOfClass); - PathToSchemasMap otherPathToSchemas = JsonSchema.validate(oneOfSchema, arg, validationMetadata); + PathToSchemasMap otherPathToSchemas = JsonSchema.validate(oneOfSchema, data.arg(), data.validationMetadata()); validatedOneOfClasses.add(oneOfClass); pathToSchemas.update(otherPathToSchemas); } catch (ValidationException e) { @@ -43,12 +36,12 @@ public OneOfValidator(List> oneOf) { } } if (validatedOneOfClasses.isEmpty()) { - throw new ValidationException("Invalid inputs given to generate an instance of "+schema.getClass()+". None "+ + throw new ValidationException("Invalid inputs given to generate an instance of "+data.schema().getClass()+". None "+ "of the oneOf schemas matched the input data." ); } if (validatedOneOfClasses.size() > 1) { - throw new ValidationException("Invalid inputs given to generate an instance of "+schema.getClass()+". Multiple "+ + throw new ValidationException("Invalid inputs given to generate an instance of "+data.schema().getClass()+". Multiple "+ "oneOf schemas validated the data, but a max of one is allowed." ); } diff --git a/samples/client/3_0_3_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/PatternPropertiesValidator.java b/samples/client/3_0_3_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/PatternPropertiesValidator.java index 6104329139f..9e951e23ed2 100644 --- a/samples/client/3_0_3_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/PatternPropertiesValidator.java +++ b/samples/client/3_0_3_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/PatternPropertiesValidator.java @@ -1,68 +1,21 @@ package org.openapijsonschematools.client.schemas.validation; import org.checkerframework.checker.nullness.qual.Nullable; -import org.openapijsonschematools.client.exceptions.InvalidTypeException; -import java.util.ArrayList; -import java.util.List; import java.util.Map; -import java.util.regex.Pattern; public class PatternPropertiesValidator implements KeywordValidator { - public final Map> patternProperties; - - public PatternPropertiesValidator(Map> patternProperties) { - this.patternProperties = patternProperties; - } - @Override public @Nullable PathToSchemasMap validate( - JsonSchema schema, - @Nullable Object arg, - ValidationMetadata validationMetadata, - @Nullable List containsPathToSchemas, - @Nullable PathToSchemasMap patternPropertiesPathToSchemas, - @Nullable PathToSchemasMap ifPathToSchemas + ValidationData data ) { - if (!(arg instanceof Map)) { + var patternProperties = data.schema().patternProperties; + if (patternProperties == null) { return null; } - return patternPropertiesPathToSchemas; - } - - public PathToSchemasMap getPatternPropertiesPathToSchemas( - @Nullable Object arg, - ValidationMetadata validationMetadata - ) { - if (!(arg instanceof Map mapArg)) { - return new PathToSchemasMap(); - } - PathToSchemasMap pathToSchemas = new PathToSchemasMap(); - for (Map.Entry entry: mapArg.entrySet()) { - Object entryKey = entry.getKey(); - if (!(entryKey instanceof String key)) { - throw new InvalidTypeException("Invalid non-string type for map key"); - } - List propPathToItem = new ArrayList<>(validationMetadata.pathToItem()); - propPathToItem.add(key); - ValidationMetadata propValidationMetadata = new ValidationMetadata( - propPathToItem, - validationMetadata.configuration(), - validationMetadata.validatedPathToSchemas(), - validationMetadata.seenClasses() - ); - for (Map.Entry> patternPropEntry: patternProperties.entrySet()) { - if (!patternPropEntry.getKey().matcher(key).find()) { - continue; - } - - Class patternPropClass = patternPropEntry.getValue(); - JsonSchema patternPropSchema = JsonSchemaFactory.getInstance(patternPropClass); - PathToSchemasMap otherPathToSchemas = JsonSchema.validate(patternPropSchema, entry.getValue(), propValidationMetadata); - pathToSchemas.update(otherPathToSchemas); - } + if (!(data.arg() instanceof Map)) { + return null; } - return pathToSchemas; + return data.patternPropertiesPathToSchemas(); } } - diff --git a/samples/client/3_0_3_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/PatternValidator.java b/samples/client/3_0_3_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/PatternValidator.java index 37e7a545711..eceeb19e311 100644 --- a/samples/client/3_0_3_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/PatternValidator.java +++ b/samples/client/3_0_3_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/PatternValidator.java @@ -3,31 +3,21 @@ import org.openapijsonschematools.client.exceptions.ValidationException; import org.checkerframework.checker.nullness.qual.Nullable; -import java.util.List; -import java.util.regex.Pattern; - public class PatternValidator implements KeywordValidator { - public final Pattern pattern; - - public PatternValidator(Pattern pattern) { - this.pattern = pattern; - } - @Override public @Nullable PathToSchemasMap validate( - JsonSchema schema, - @Nullable Object arg, - ValidationMetadata validationMetadata, - @Nullable List containsPathToSchemas, - @Nullable PathToSchemasMap patternPropertiesPathToSchemas, - @Nullable PathToSchemasMap ifPathToSchemas + ValidationData data ) { - if (!(arg instanceof String)) { + var pattern = data.schema().pattern; + if (pattern == null) { + return null; + } + if (!(data.arg() instanceof String stringArg)) { return null; } - if (!pattern.matcher((String) arg).find()) { - throw new ValidationException("Invalid value "+arg+" did not find a match for pattern "+pattern); + if (!pattern.matcher(stringArg).find()) { + throw new ValidationException("Invalid value "+stringArg+" did not find a match for pattern "+pattern); } return null; } -} +} \ No newline at end of file diff --git a/samples/client/3_0_3_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/PrefixItemsValidator.java b/samples/client/3_0_3_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/PrefixItemsValidator.java index a8b2bda2a21..00e5b17607b 100644 --- a/samples/client/3_0_3_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/PrefixItemsValidator.java +++ b/samples/client/3_0_3_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/PrefixItemsValidator.java @@ -6,22 +6,15 @@ import java.util.List; public class PrefixItemsValidator implements KeywordValidator { - public final List> prefixItems; - - public PrefixItemsValidator(List> prefixItems) { - this.prefixItems = prefixItems; - } - @Override public @Nullable PathToSchemasMap validate( - JsonSchema schema, - @Nullable Object arg, - ValidationMetadata validationMetadata, - @Nullable List containsPathToSchemas, - @Nullable PathToSchemasMap patternPropertiesPathToSchemas, - @Nullable PathToSchemasMap ifPathToSchemas + ValidationData data ) { - if (!(arg instanceof List listArg)) { + var prefixItems = data.schema().prefixItems; + if (prefixItems == null) { + return null; + } + if (!(data.arg() instanceof List listArg)) { return null; } if (listArg.isEmpty()) { @@ -30,13 +23,13 @@ public PrefixItemsValidator(List> prefixItems) { PathToSchemasMap pathToSchemas = new PathToSchemasMap(); int maxIndex = Math.min(listArg.size(), prefixItems.size()); for (int i=0; i < maxIndex; i++) { - List itemPathToItem = new ArrayList<>(validationMetadata.pathToItem()); + List itemPathToItem = new ArrayList<>(data.validationMetadata().pathToItem()); itemPathToItem.add(i); ValidationMetadata itemValidationMetadata = new ValidationMetadata( itemPathToItem, - validationMetadata.configuration(), - validationMetadata.validatedPathToSchemas(), - validationMetadata.seenClasses() + data.validationMetadata().configuration(), + data.validationMetadata().validatedPathToSchemas(), + data.validationMetadata().seenClasses() ); JsonSchema itemsSchema = JsonSchemaFactory.getInstance(prefixItems.get(i)); PathToSchemasMap otherPathToSchemas = JsonSchema.validate(itemsSchema, listArg.get(i), itemValidationMetadata); diff --git a/samples/client/3_0_3_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/PropertiesValidator.java b/samples/client/3_0_3_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/PropertiesValidator.java index 9b7d50b28d8..17bccdd666a 100644 --- a/samples/client/3_0_3_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/PropertiesValidator.java +++ b/samples/client/3_0_3_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/PropertiesValidator.java @@ -9,22 +9,15 @@ import java.util.Set; public class PropertiesValidator implements KeywordValidator { - public final Map> properties; - - public PropertiesValidator(Map> properties) { - this.properties = properties; - } - @Override public @Nullable PathToSchemasMap validate( - JsonSchema schema, - @Nullable Object arg, - ValidationMetadata validationMetadata, - @Nullable List containsPathToSchemas, - @Nullable PathToSchemasMap patternPropertiesPathToSchemas, - @Nullable PathToSchemasMap ifPathToSchemas + ValidationData data ) { - if (!(arg instanceof Map mapArg)) { + var properties = data.schema().properties; + if (properties == null) { + return null; + } + if (!(data.arg() instanceof Map mapArg)) { return null; } PathToSchemasMap pathToSchemas = new PathToSchemasMap(); @@ -39,14 +32,14 @@ public PropertiesValidator(Map> properties) if (!presentProperties.contains(propName)) { continue; } - @Nullable Object propValue = ((Map) arg).get(propName); - List propPathToItem = new ArrayList<>(validationMetadata.pathToItem()); + @Nullable Object propValue = mapArg.get(propName); + List propPathToItem = new ArrayList<>(data.validationMetadata().pathToItem()); propPathToItem.add(propName); ValidationMetadata propValidationMetadata = new ValidationMetadata( propPathToItem, - validationMetadata.configuration(), - validationMetadata.validatedPathToSchemas(), - validationMetadata.seenClasses() + data.validationMetadata().configuration(), + data.validationMetadata().validatedPathToSchemas(), + data.validationMetadata().seenClasses() ); Class propClass = entry.getValue(); JsonSchema propSchema = JsonSchemaFactory.getInstance(propClass); @@ -60,4 +53,3 @@ public PropertiesValidator(Map> properties) return pathToSchemas; } } - diff --git a/samples/client/3_0_3_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/PropertyNamesValidator.java b/samples/client/3_0_3_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/PropertyNamesValidator.java index 5154911d484..55ea80b0382 100644 --- a/samples/client/3_0_3_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/PropertyNamesValidator.java +++ b/samples/client/3_0_3_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/PropertyNamesValidator.java @@ -7,34 +7,27 @@ import java.util.Map; public class PropertyNamesValidator implements KeywordValidator { - public final Class propertyNames; - - public PropertyNamesValidator(Class propertyNames) { - this.propertyNames = propertyNames; - } - @Override public @Nullable PathToSchemasMap validate( - JsonSchema schema, - @Nullable Object arg, - ValidationMetadata validationMetadata, - @Nullable List containsPathToSchemas, - @Nullable PathToSchemasMap patternPropertiesPathToSchemas, - @Nullable PathToSchemasMap ifPathToSchemas + ValidationData data ) { - if (!(arg instanceof Map)) { + var propertyNames = data.schema().propertyNames; + if (propertyNames == null) { + return null; + } + if (!(data.arg() instanceof Map mapArg)) { return null; } JsonSchema propertyNamesSchema = JsonSchemaFactory.getInstance(propertyNames); - for (Object objKey: ((Map) arg).keySet()) { + for (Object objKey: mapArg.keySet()) { if (objKey instanceof String key) { - List propPathToItem = new ArrayList<>(validationMetadata.pathToItem()); + List propPathToItem = new ArrayList<>(data.validationMetadata().pathToItem()); propPathToItem.add(key); ValidationMetadata keyValidationMetadata = new ValidationMetadata( propPathToItem, - validationMetadata.configuration(), - validationMetadata.validatedPathToSchemas(), - validationMetadata.seenClasses() + data.validationMetadata().configuration(), + data.validationMetadata().validatedPathToSchemas(), + data.validationMetadata().seenClasses() ); JsonSchema.validate(propertyNamesSchema, key, keyValidationMetadata); } diff --git a/samples/client/3_0_3_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/RequiredValidator.java b/samples/client/3_0_3_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/RequiredValidator.java index f68aef2b87a..f2e1a8ecde8 100644 --- a/samples/client/3_0_3_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/RequiredValidator.java +++ b/samples/client/3_0_3_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/RequiredValidator.java @@ -9,26 +9,19 @@ import java.util.Set; public class RequiredValidator implements KeywordValidator { - public final Set required; - - public RequiredValidator(Set required) { - this.required = required; - } - @Override public @Nullable PathToSchemasMap validate( - JsonSchema schema, - @Nullable Object arg, - ValidationMetadata validationMetadata, - @Nullable List containsPathToSchemas, - @Nullable PathToSchemasMap patternPropertiesPathToSchemas, - @Nullable PathToSchemasMap ifPathToSchemas + ValidationData data ) { - if (!(arg instanceof Map)) { + var required = data.schema().required; + if (required == null) { + return null; + } + if (!(data.arg() instanceof Map mapArg)) { return null; } Set missingRequiredProperties = new HashSet<>(required); - for (Object key: ((Map) arg).keySet()) { + for (Object key: mapArg.keySet()) { if (key instanceof String) { missingRequiredProperties.remove(key); } @@ -40,7 +33,7 @@ public RequiredValidator(Set required) { pluralChar = "s"; } throw new ValidationException( - schema.getClass()+" is missing "+missingRequiredProperties.size()+" required argument"+pluralChar+": "+missingReqProps + data.schema().getClass()+" is missing "+missingRequiredProperties.size()+" required argument"+pluralChar+": "+missingReqProps ); } return null; diff --git a/samples/client/3_0_3_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/TypeValidator.java b/samples/client/3_0_3_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/TypeValidator.java index f1fcd9d5cdd..bb4133a770e 100644 --- a/samples/client/3_0_3_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/TypeValidator.java +++ b/samples/client/3_0_3_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/TypeValidator.java @@ -5,25 +5,18 @@ import java.util.List; import java.util.Map; -import java.util.Set; public class TypeValidator implements KeywordValidator { - public final Set> type; - - public TypeValidator(Set> type) { - this.type = type; - } - @Override public @Nullable PathToSchemasMap validate( - JsonSchema schema, - @Nullable Object arg, - ValidationMetadata validationMetadata, - @Nullable List containsPathToSchemas, - @Nullable PathToSchemasMap patternPropertiesPathToSchemas, - @Nullable PathToSchemasMap ifPathToSchemas + ValidationData data ) { + var type = data.schema().type; + if (type == null) { + return null; + } Class argClass; + var arg = data.arg(); if (arg == null) { argClass = Void.class; } else if (arg instanceof List) { diff --git a/samples/client/3_0_3_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/UniqueItemsValidator.java b/samples/client/3_0_3_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/UniqueItemsValidator.java index 4cdbbe01060..a42a7d60b60 100644 --- a/samples/client/3_0_3_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/UniqueItemsValidator.java +++ b/samples/client/3_0_3_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/UniqueItemsValidator.java @@ -8,29 +8,22 @@ import java.util.Set; public class UniqueItemsValidator implements KeywordValidator { - public final boolean uniqueItems; - - public UniqueItemsValidator(boolean uniqueItems) { - this.uniqueItems = uniqueItems; - } - @Override public @Nullable PathToSchemasMap validate( - JsonSchema schema, - @Nullable Object arg, - ValidationMetadata validationMetadata, - @Nullable List containsPathToSchemas, - @Nullable PathToSchemasMap patternPropertiesPathToSchemas, - @Nullable PathToSchemasMap ifPathToSchemas + ValidationData data ) { - if (!(arg instanceof List)) { + var uniqueItems = data.schema().uniqueItems; + if (uniqueItems == null) { + return null; + } + if (!(data.arg() instanceof List listArg)) { return null; } if (!uniqueItems) { return null; } Set<@Nullable Object> seenItems = new HashSet<>(); - for (@Nullable Object item: (List) arg) { + for (@Nullable Object item: listArg) { int startingSeenItemsSize = seenItems.size(); seenItems.add(item); if (seenItems.size() == startingSeenItemsSize) { diff --git a/samples/client/3_0_3_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/ValidationData.java b/samples/client/3_0_3_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/ValidationData.java new file mode 100644 index 00000000000..55cb65fe9ef --- /dev/null +++ b/samples/client/3_0_3_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/ValidationData.java @@ -0,0 +1,22 @@ +package org.openapijsonschematools.client.schemas.validation; + +import org.checkerframework.checker.nullness.qual.Nullable; + +import java.util.List; + +public record ValidationData( + JsonSchema schema, + @Nullable Object arg, + ValidationMetadata validationMetadata, + @Nullable List containsPathToSchemas, + @Nullable PathToSchemasMap patternPropertiesPathToSchemas, + @Nullable PathToSchemasMap ifPathToSchemas +) { + public ValidationData( + JsonSchema schema, + @Nullable Object arg, + ValidationMetadata validationMetadata + ) { + this(schema, arg, validationMetadata, null, null, null); + } +} \ No newline at end of file diff --git a/samples/client/3_0_3_unit_test/java/src/test/java/org/openapijsonschematools/client/schemas/validation/AdditionalPropertiesValidatorTest.java b/samples/client/3_0_3_unit_test/java/src/test/java/org/openapijsonschematools/client/schemas/validation/AdditionalPropertiesValidatorTest.java index 7e6d7d09535..f98e0a7d529 100644 --- a/samples/client/3_0_3_unit_test/java/src/test/java/org/openapijsonschematools/client/schemas/validation/AdditionalPropertiesValidatorTest.java +++ b/samples/client/3_0_3_unit_test/java/src/test/java/org/openapijsonschematools/client/schemas/validation/AdditionalPropertiesValidatorTest.java @@ -26,6 +26,7 @@ private ObjectWithPropsSchema() { .properties(Map.ofEntries( new PropertyEntry("someString", StringJsonSchema.class) )) + .additionalProperties(StringJsonSchema.class) ); } @@ -73,14 +74,13 @@ public void testCorrectPropertySucceeds() { mutableMap.put("someString", "abc"); mutableMap.put("someAddProp", "def"); FrozenMap arg = new FrozenMap<>(mutableMap); - final AdditionalPropertiesValidator validator = new AdditionalPropertiesValidator(StringJsonSchema.class); + final AdditionalPropertiesValidator validator = new AdditionalPropertiesValidator(); PathToSchemasMap pathToSchemas = validator.validate( - ObjectWithPropsSchema.getInstance(), - arg, - validationMetadata, - new ArrayList<>(), - new PathToSchemasMap(), - new PathToSchemasMap() + new ValidationData( + ObjectWithPropsSchema.getInstance(), + arg, + validationMetadata + ) ); if (pathToSchemas == null) { throw new RuntimeException("Invalid null value for pathToSchemas for this test case"); @@ -105,14 +105,13 @@ public void testNotApplicableTypeReturnsNull() { new PathToSchemasMap(), new LinkedHashSet<>() ); - final AdditionalPropertiesValidator validator = new AdditionalPropertiesValidator(StringJsonSchema.class); + final AdditionalPropertiesValidator validator = new AdditionalPropertiesValidator(); PathToSchemasMap pathToSchemas = validator.validate( - MapJsonSchema.getInstance(), - 1, - validationMetadata, - new ArrayList<>(), - new PathToSchemasMap(), - new PathToSchemasMap() + new ValidationData( + MapJsonSchema.getInstance(), + 1, + validationMetadata + ) ); assertNull(pathToSchemas); } @@ -130,14 +129,13 @@ public void testIncorrectPropertyValueFails() { mutableMap.put("someString", "abc"); mutableMap.put("someAddProp", 1); FrozenMap arg = new FrozenMap<>(mutableMap); - final AdditionalPropertiesValidator validator = new AdditionalPropertiesValidator(StringJsonSchema.class); + final AdditionalPropertiesValidator validator = new AdditionalPropertiesValidator(); Assert.assertThrows(ValidationException.class, () -> validator.validate( - ObjectWithPropsSchema.getInstance(), - arg, - validationMetadata, - new ArrayList<>(), - new PathToSchemasMap(), - new PathToSchemasMap() + new ValidationData( + ObjectWithPropsSchema.getInstance(), + arg, + validationMetadata + ) )); } } \ No newline at end of file diff --git a/samples/client/3_0_3_unit_test/java/src/test/java/org/openapijsonschematools/client/schemas/validation/FormatValidatorTest.java b/samples/client/3_0_3_unit_test/java/src/test/java/org/openapijsonschematools/client/schemas/validation/FormatValidatorTest.java index 87a6bafc05f..db31df87dd9 100644 --- a/samples/client/3_0_3_unit_test/java/src/test/java/org/openapijsonschematools/client/schemas/validation/FormatValidatorTest.java +++ b/samples/client/3_0_3_unit_test/java/src/test/java/org/openapijsonschematools/client/schemas/validation/FormatValidatorTest.java @@ -6,8 +6,14 @@ import org.openapijsonschematools.client.configurations.JsonSchemaKeywordFlags; import org.openapijsonschematools.client.configurations.SchemaConfiguration; import org.openapijsonschematools.client.exceptions.ValidationException; -import org.openapijsonschematools.client.schemas.NumberJsonSchema; -import org.openapijsonschematools.client.schemas.StringJsonSchema; +import org.openapijsonschematools.client.schemas.IntJsonSchema; +import org.openapijsonschematools.client.schemas.Int32JsonSchema; +import org.openapijsonschematools.client.schemas.Int64JsonSchema; +import org.openapijsonschematools.client.schemas.FloatJsonSchema; +import org.openapijsonschematools.client.schemas.DoubleJsonSchema; +import org.openapijsonschematools.client.schemas.DecimalJsonSchema; +import org.openapijsonschematools.client.schemas.DateJsonSchema; +import org.openapijsonschematools.client.schemas.DateTimeJsonSchema; import java.math.BigDecimal; import java.math.BigInteger; @@ -29,354 +35,328 @@ private void assertNull(@Nullable Object object) { @Test public void testIntFormatSucceedsWithFloat() { - final FormatValidator validator = new FormatValidator("int"); + final FormatValidator validator = new FormatValidator(); PathToSchemasMap pathToSchemasMap = validator.validate( - NumberJsonSchema.getInstance(), - 1.0f, - validationMetadata, - new ArrayList<>(), - new PathToSchemasMap(), - new PathToSchemasMap() + new ValidationData( + IntJsonSchema.getInstance(), + 1.0f, + validationMetadata + ) ); assertNull(pathToSchemasMap); } @Test public void testIntFormatFailsWithFloat() { - final FormatValidator validator = new FormatValidator("int"); + final FormatValidator validator = new FormatValidator(); Assert.assertThrows(ValidationException.class, () -> validator.validate( - NumberJsonSchema.getInstance(), - 3.14f, - validationMetadata, - new ArrayList<>(), - new PathToSchemasMap(), - new PathToSchemasMap() + new ValidationData( + IntJsonSchema.getInstance(), + 3.14f, + validationMetadata + ) )); } @Test public void testIntFormatSucceedsWithInt() { - final FormatValidator validator = new FormatValidator("int"); + final FormatValidator validator = new FormatValidator(); PathToSchemasMap pathToSchemasMap = validator.validate( - NumberJsonSchema.getInstance(), - 1, - validationMetadata, - new ArrayList<>(), - new PathToSchemasMap(), - new PathToSchemasMap() + new ValidationData( + IntJsonSchema.getInstance(), + 1, + validationMetadata + ) ); assertNull(pathToSchemasMap); } @Test public void testInt32UnderMinFails() { - final FormatValidator validator = new FormatValidator("int32"); + final FormatValidator validator = new FormatValidator(); Assert.assertThrows(ValidationException.class, () -> validator.validate( - NumberJsonSchema.getInstance(), - -2147483649L, - validationMetadata, - new ArrayList<>(), - new PathToSchemasMap(), - new PathToSchemasMap() + new ValidationData( + Int32JsonSchema.getInstance(), + -2147483649L, + validationMetadata + ) )); } @Test public void testInt32InclusiveMinSucceeds() { - final FormatValidator validator = new FormatValidator("int32"); + final FormatValidator validator = new FormatValidator(); PathToSchemasMap pathToSchemasMap = validator.validate( - NumberJsonSchema.getInstance(), - -2147483648, - validationMetadata, - new ArrayList<>(), - new PathToSchemasMap(), - new PathToSchemasMap() + new ValidationData( + Int32JsonSchema.getInstance(), + -2147483648, + validationMetadata + ) ); assertNull(pathToSchemasMap); } @Test public void testInt32InclusiveMaxSucceeds() { - final FormatValidator validator = new FormatValidator("int32"); + final FormatValidator validator = new FormatValidator(); PathToSchemasMap pathToSchemasMap = validator.validate( - NumberJsonSchema.getInstance(), - 2147483647, - validationMetadata, - new ArrayList<>(), - new PathToSchemasMap(), - new PathToSchemasMap() + new ValidationData( + Int32JsonSchema.getInstance(), + 2147483647, + validationMetadata + ) ); assertNull(pathToSchemasMap); } @Test public void testInt32OverMaxFails() { - final FormatValidator validator = new FormatValidator("int32"); + final FormatValidator validator = new FormatValidator(); Assert.assertThrows(ValidationException.class, () -> validator.validate( - NumberJsonSchema.getInstance(), - 2147483648L, - validationMetadata, - new ArrayList<>(), - new PathToSchemasMap(), - new PathToSchemasMap() + new ValidationData( + Int32JsonSchema.getInstance(), + 2147483648L, + validationMetadata + ) )); } @Test public void testInt64UnderMinFails() { - final FormatValidator validator = new FormatValidator("int64"); + final FormatValidator validator = new FormatValidator(); Assert.assertThrows(ValidationException.class, () -> validator.validate( - NumberJsonSchema.getInstance(), - new BigInteger("-9223372036854775809"), - validationMetadata, - new ArrayList<>(), - new PathToSchemasMap(), - new PathToSchemasMap() + new ValidationData( + Int64JsonSchema.getInstance(), + new BigInteger("-9223372036854775809"), + validationMetadata + ) )); } @Test public void testInt64InclusiveMinSucceeds() { - final FormatValidator validator = new FormatValidator("int64"); + final FormatValidator validator = new FormatValidator(); PathToSchemasMap pathToSchemasMap = validator.validate( - NumberJsonSchema.getInstance(), - -9223372036854775808L, - validationMetadata, - new ArrayList<>(), - new PathToSchemasMap(), - new PathToSchemasMap() + new ValidationData( + Int64JsonSchema.getInstance(), + -9223372036854775808L, + validationMetadata + ) ); assertNull(pathToSchemasMap); } @Test public void testInt64InclusiveMaxSucceeds() { - final FormatValidator validator = new FormatValidator("int64"); + final FormatValidator validator = new FormatValidator(); PathToSchemasMap pathToSchemasMap = validator.validate( - NumberJsonSchema.getInstance(), - 9223372036854775807L, - validationMetadata, - new ArrayList<>(), - new PathToSchemasMap(), - new PathToSchemasMap() + new ValidationData( + Int64JsonSchema.getInstance(), + 9223372036854775807L, + validationMetadata + ) ); assertNull(pathToSchemasMap); } @Test public void testInt64OverMaxFails() { - final FormatValidator validator = new FormatValidator("int64"); + final FormatValidator validator = new FormatValidator(); Assert.assertThrows(ValidationException.class, () -> validator.validate( - NumberJsonSchema.getInstance(), - new BigInteger("9223372036854775808"), - validationMetadata, - new ArrayList<>(), - new PathToSchemasMap(), - new PathToSchemasMap() + new ValidationData( + Int64JsonSchema.getInstance(), + new BigInteger("9223372036854775808"), + validationMetadata + ) )); } @Test public void testFloatUnderMinFails() { - final FormatValidator validator = new FormatValidator("float"); + final FormatValidator validator = new FormatValidator(); Assert.assertThrows(ValidationException.class, () -> validator.validate( - NumberJsonSchema.getInstance(), - -3.402823466385289e+38d, - validationMetadata, - new ArrayList<>(), - new PathToSchemasMap(), - new PathToSchemasMap() + new ValidationData( + FloatJsonSchema.getInstance(), + -3.402823466385289e+38d, + validationMetadata + ) )); } @Test public void testFloatInclusiveMinSucceeds() { - final FormatValidator validator = new FormatValidator("float"); + final FormatValidator validator = new FormatValidator(); PathToSchemasMap pathToSchemasMap = validator.validate( - NumberJsonSchema.getInstance(), - -3.4028234663852886e+38f, - validationMetadata, - new ArrayList<>(), - new PathToSchemasMap(), - new PathToSchemasMap() + new ValidationData( + FloatJsonSchema.getInstance(), + -3.4028234663852886e+38f, + validationMetadata + ) ); assertNull(pathToSchemasMap); } @Test public void testFloatInclusiveMaxSucceeds() { - final FormatValidator validator = new FormatValidator("float"); + final FormatValidator validator = new FormatValidator(); PathToSchemasMap pathToSchemasMap = validator.validate( - NumberJsonSchema.getInstance(), - 3.4028234663852886e+38f, - validationMetadata, - new ArrayList<>(), - new PathToSchemasMap(), - new PathToSchemasMap() + new ValidationData( + FloatJsonSchema.getInstance(), + 3.4028234663852886e+38f, + validationMetadata + ) ); assertNull(pathToSchemasMap); } @Test public void testFloatOverMaxFails() { - final FormatValidator validator = new FormatValidator("float"); + final FormatValidator validator = new FormatValidator(); Assert.assertThrows(ValidationException.class, () -> validator.validate( - NumberJsonSchema.getInstance(), - 3.402823466385289e+38d, - validationMetadata, - new ArrayList<>(), - new PathToSchemasMap(), - new PathToSchemasMap() + new ValidationData( + FloatJsonSchema.getInstance(), + 3.402823466385289e+38d, + validationMetadata + ) )); } @Test public void testDoubleUnderMinFails() { - final FormatValidator validator = new FormatValidator("double"); + final FormatValidator validator = new FormatValidator(); Assert.assertThrows(ValidationException.class, () -> validator.validate( - NumberJsonSchema.getInstance(), - new BigDecimal("-1.7976931348623157082e+308"), - validationMetadata, - new ArrayList<>(), - new PathToSchemasMap(), - new PathToSchemasMap() + new ValidationData( + DoubleJsonSchema.getInstance(), + new BigDecimal("-1.7976931348623157082e+308"), + validationMetadata + ) )); } @Test public void testDoubleInclusiveMinSucceeds() { - final FormatValidator validator = new FormatValidator("double"); + final FormatValidator validator = new FormatValidator(); PathToSchemasMap pathToSchemasMap = validator.validate( - NumberJsonSchema.getInstance(), - -1.7976931348623157E+308d, - validationMetadata, - new ArrayList<>(), - new PathToSchemasMap(), - new PathToSchemasMap() + new ValidationData( + DoubleJsonSchema.getInstance(), + -1.7976931348623157E+308d, + validationMetadata + ) ); assertNull(pathToSchemasMap); } @Test public void testDoubleInclusiveMaxSucceeds() { - final FormatValidator validator = new FormatValidator("double"); + final FormatValidator validator = new FormatValidator(); PathToSchemasMap pathToSchemasMap = validator.validate( - NumberJsonSchema.getInstance(), - 1.7976931348623157E+308d, - validationMetadata, - new ArrayList<>(), - new PathToSchemasMap(), - new PathToSchemasMap() + new ValidationData( + DoubleJsonSchema.getInstance(), + 1.7976931348623157E+308d, + validationMetadata + ) ); assertNull(pathToSchemasMap); } @Test public void testDoubleOverMaxFails() { - final FormatValidator validator = new FormatValidator("double"); + final FormatValidator validator = new FormatValidator(); Assert.assertThrows(ValidationException.class, () -> validator.validate( - NumberJsonSchema.getInstance(), - new BigDecimal("1.7976931348623157082e+308"), - validationMetadata, - new ArrayList<>(), - new PathToSchemasMap(), - new PathToSchemasMap() + new ValidationData( + DoubleJsonSchema.getInstance(), + new BigDecimal("1.7976931348623157082e+308"), + validationMetadata + ) )); } @Test public void testInvalidNumberStringFails() { - final FormatValidator validator = new FormatValidator("number"); + final FormatValidator validator = new FormatValidator(); Assert.assertThrows(ValidationException.class, () -> validator.validate( - NumberJsonSchema.getInstance(), - "abc", - validationMetadata, - new ArrayList<>(), - new PathToSchemasMap(), - new PathToSchemasMap() + new ValidationData( + DecimalJsonSchema.getInstance(), + "abc", + validationMetadata + ) )); } @Test public void testValidFloatNumberStringSucceeds() { - final FormatValidator validator = new FormatValidator("number"); + final FormatValidator validator = new FormatValidator(); PathToSchemasMap pathToSchemasMap = validator.validate( - NumberJsonSchema.getInstance(), - "3.14", - validationMetadata, - new ArrayList<>(), - new PathToSchemasMap(), - new PathToSchemasMap() + new ValidationData( + DecimalJsonSchema.getInstance(), + "3.14", + validationMetadata + ) ); assertNull(pathToSchemasMap); } @Test public void testValidIntNumberStringSucceeds() { - final FormatValidator validator = new FormatValidator("number"); + final FormatValidator validator = new FormatValidator(); PathToSchemasMap pathToSchemasMap = validator.validate( - NumberJsonSchema.getInstance(), - "1", - validationMetadata, - new ArrayList<>(), - new PathToSchemasMap(), - new PathToSchemasMap() + new ValidationData( + DecimalJsonSchema.getInstance(), + "1", + validationMetadata + ) ); assertNull(pathToSchemasMap); } @Test public void testInvalidDateStringFails() { - final FormatValidator validator = new FormatValidator("date"); + final FormatValidator validator = new FormatValidator(); Assert.assertThrows(ValidationException.class, () -> validator.validate( - StringJsonSchema.getInstance(), - "abc", - validationMetadata, - new ArrayList<>(), - new PathToSchemasMap(), - new PathToSchemasMap() + new ValidationData( + DateJsonSchema.getInstance(), + "abc", + validationMetadata + ) )); } @Test public void testValidDateStringSucceeds() { - final FormatValidator validator = new FormatValidator("date"); + final FormatValidator validator = new FormatValidator(); PathToSchemasMap pathToSchemasMap = validator.validate( - StringJsonSchema.getInstance(), - "2017-01-20", - validationMetadata, - new ArrayList<>(), - new PathToSchemasMap(), - new PathToSchemasMap() + new ValidationData( + DateJsonSchema.getInstance(), + "2017-01-20", + validationMetadata + ) ); assertNull(pathToSchemasMap); } @Test public void testInvalidDateTimeStringFails() { - final FormatValidator validator = new FormatValidator("date-time"); + final FormatValidator validator = new FormatValidator(); Assert.assertThrows(ValidationException.class, () -> validator.validate( - StringJsonSchema.getInstance(), - "abc", - validationMetadata, - new ArrayList<>(), - new PathToSchemasMap(), - new PathToSchemasMap() + new ValidationData( + DateTimeJsonSchema.getInstance(), + "abc", + validationMetadata + ) )); } @Test public void testValidDateTimeStringSucceeds() { - final FormatValidator validator = new FormatValidator("date-time"); + final FormatValidator validator = new FormatValidator(); PathToSchemasMap pathToSchemasMap = validator.validate( - StringJsonSchema.getInstance(), - "2017-07-21T17:32:28Z", - validationMetadata, - new ArrayList<>(), - new PathToSchemasMap(), - new PathToSchemasMap() + new ValidationData( + DateTimeJsonSchema.getInstance(), + "2017-07-21T17:32:28Z", + validationMetadata + ) ); assertNull(pathToSchemasMap); } diff --git a/samples/client/3_0_3_unit_test/java/src/test/java/org/openapijsonschematools/client/schemas/validation/ItemsValidatorTest.java b/samples/client/3_0_3_unit_test/java/src/test/java/org/openapijsonschematools/client/schemas/validation/ItemsValidatorTest.java index f9c539091f3..b16a91e3919 100644 --- a/samples/client/3_0_3_unit_test/java/src/test/java/org/openapijsonschematools/client/schemas/validation/ItemsValidatorTest.java +++ b/samples/client/3_0_3_unit_test/java/src/test/java/org/openapijsonschematools/client/schemas/validation/ItemsValidatorTest.java @@ -5,14 +5,15 @@ import org.junit.Test; import org.openapijsonschematools.client.configurations.JsonSchemaKeywordFlags; import org.openapijsonschematools.client.configurations.SchemaConfiguration; -import org.openapijsonschematools.client.schemas.ListJsonSchema; import org.openapijsonschematools.client.schemas.StringJsonSchema; +import org.openapijsonschematools.client.exceptions.InvalidTypeException; import org.openapijsonschematools.client.exceptions.ValidationException; import java.util.ArrayList; import java.util.LinkedHashMap; import java.util.LinkedHashSet; import java.util.List; +import java.util.Set; public class ItemsValidatorTest { @SuppressWarnings("nullness") @@ -20,6 +21,31 @@ private void assertNull(@Nullable Object object) { Assert.assertNull(object); } + public static class ArrayWithItemsSchema extends JsonSchema { + public ArrayWithItemsSchema() { + super(new JsonSchemaInfo() + .type(Set.of(List.class)) + .items(StringJsonSchema.class) + ); + } + + @Override + public Object getNewInstance(@Nullable Object arg, List pathToItem, PathToSchemasMap pathToSchemas) { + if (arg instanceof List listArg) { + return getNewInstance(listArg, pathToItem, pathToSchemas); + } + throw new InvalidTypeException("Invalid input type="+getClass(arg)+". It can't be instantiated by this schema"); + } + + @Override + public @Nullable Object validate(@Nullable Object arg, SchemaConfiguration configuration) throws InvalidTypeException, ValidationException { + if (arg instanceof List listArg) { + return validate(listArg, configuration); + } + throw new InvalidTypeException("Invalid input type="+getClass(arg)+". It can't be validated by this schema"); + } + } + @Test public void testCorrectItemsSucceeds() { List pathToItem = List.of("args[0]"); @@ -32,14 +58,13 @@ public void testCorrectItemsSucceeds() { List mutableList = new ArrayList<>(); mutableList.add("a"); FrozenList arg = new FrozenList<>(mutableList); - final ItemsValidator validator = new ItemsValidator(StringJsonSchema.class); + final ItemsValidator validator = new ItemsValidator(); PathToSchemasMap pathToSchemas = validator.validate( - ListJsonSchema.getInstance(), - arg, - validationMetadata, - new ArrayList<>(), - new PathToSchemasMap(), - new PathToSchemasMap() + new ValidationData( + new ArrayWithItemsSchema(), + arg, + validationMetadata + ) ); if (pathToSchemas == null) { throw new RuntimeException("Invalid null value in pathToSchemas for this test case"); @@ -64,14 +89,13 @@ public void testNotApplicableTypeReturnsNull() { new PathToSchemasMap(), new LinkedHashSet<>() ); - final ItemsValidator validator = new ItemsValidator(StringJsonSchema.class); + final ItemsValidator validator = new ItemsValidator(); PathToSchemasMap pathToSchemas = validator.validate( - ListJsonSchema.getInstance(), - 1, - validationMetadata, - new ArrayList<>(), - new PathToSchemasMap(), - new PathToSchemasMap() + new ValidationData( + new ArrayWithItemsSchema(), + 1, + validationMetadata + ) ); assertNull(pathToSchemas); } @@ -88,14 +112,13 @@ public void testIncorrectItemFails() { List mutableList = new ArrayList<>(); mutableList.add(1); FrozenList arg = new FrozenList<>(mutableList); - final ItemsValidator validator = new ItemsValidator(StringJsonSchema.class); + final ItemsValidator validator = new ItemsValidator(); Assert.assertThrows(ValidationException.class, () -> validator.validate( - ListJsonSchema.getInstance(), - arg, - validationMetadata, - new ArrayList<>(), - new PathToSchemasMap(), - new PathToSchemasMap() + new ValidationData( + new ArrayWithItemsSchema(), + arg, + validationMetadata + ) )); } -} +} \ No newline at end of file diff --git a/samples/client/3_0_3_unit_test/java/src/test/java/org/openapijsonschematools/client/schemas/validation/PropertiesValidatorTest.java b/samples/client/3_0_3_unit_test/java/src/test/java/org/openapijsonschematools/client/schemas/validation/PropertiesValidatorTest.java index ea58d090f1f..9431d06708f 100644 --- a/samples/client/3_0_3_unit_test/java/src/test/java/org/openapijsonschematools/client/schemas/validation/PropertiesValidatorTest.java +++ b/samples/client/3_0_3_unit_test/java/src/test/java/org/openapijsonschematools/client/schemas/validation/PropertiesValidatorTest.java @@ -5,7 +5,7 @@ import org.junit.Test; import org.openapijsonschematools.client.configurations.JsonSchemaKeywordFlags; import org.openapijsonschematools.client.configurations.SchemaConfiguration; -import org.openapijsonschematools.client.schemas.MapJsonSchema; +import org.openapijsonschematools.client.exceptions.InvalidTypeException; import org.openapijsonschematools.client.schemas.StringJsonSchema; import org.openapijsonschematools.client.exceptions.ValidationException; @@ -14,8 +14,37 @@ import java.util.LinkedHashSet; import java.util.List; import java.util.Map; +import java.util.Set; public class PropertiesValidatorTest { + public static class ObjectWithPropsSchema extends JsonSchema { + private ObjectWithPropsSchema() { + super(new JsonSchemaInfo() + .type(Set.of(Map.class)) + .properties(Map.ofEntries( + new PropertyEntry("someString", StringJsonSchema.class) + )) + ); + + } + + @Override + public Object getNewInstance(@Nullable Object arg, List pathToItem, PathToSchemasMap pathToSchemas) { + if (arg instanceof Map mapArg) { + return getNewInstance(mapArg, pathToItem, pathToSchemas); + } + throw new InvalidTypeException("Invalid input type="+getClass(arg)+". It can't be instantiated by this schema"); + } + + @Override + public @Nullable Object validate(@Nullable Object arg, SchemaConfiguration configuration) throws InvalidTypeException, ValidationException { + if (arg instanceof Map mapArg) { + return validate(mapArg, configuration); + } + throw new InvalidTypeException("Invalid input type="+getClass(arg)+". It can't be validated by this schema"); + } + } + @SuppressWarnings("nullness") private void assertNull(@Nullable Object object) { Assert.assertNull(object); @@ -23,10 +52,7 @@ private void assertNull(@Nullable Object object) { @Test public void testCorrectPropertySucceeds() { - Map> properties = new LinkedHashMap<>(); - properties.put("someString", StringJsonSchema.class); - - final PropertiesValidator validator = new PropertiesValidator(properties); + final PropertiesValidator validator = new PropertiesValidator(); List pathToItem = List.of("args[0]"); ValidationMetadata validationMetadata = new ValidationMetadata( pathToItem, @@ -38,12 +64,11 @@ public void testCorrectPropertySucceeds() { mutableMap.put("someString", "abc"); FrozenMap arg = new FrozenMap<>(mutableMap); PathToSchemasMap pathToSchemas = validator.validate( - MapJsonSchema.getInstance(), - arg, - validationMetadata, - new ArrayList<>(), - new PathToSchemasMap(), - new PathToSchemasMap() + new ValidationData( + new ObjectWithPropsSchema(), + arg, + validationMetadata + ) ); if (pathToSchemas == null) { throw new RuntimeException("Invalid null value for pathToSchemas for this test case"); @@ -60,10 +85,7 @@ public void testCorrectPropertySucceeds() { @Test public void testNotApplicableTypeReturnsNull() { - Map> properties = new LinkedHashMap<>(); - properties.put("someString", StringJsonSchema.class); - - final PropertiesValidator validator = new PropertiesValidator(properties); + final PropertiesValidator validator = new PropertiesValidator(); List pathToItem = List.of("args[0]"); ValidationMetadata validationMetadata = new ValidationMetadata( pathToItem, @@ -72,22 +94,18 @@ public void testNotApplicableTypeReturnsNull() { new LinkedHashSet<>() ); PathToSchemasMap pathToSchemas = validator.validate( - MapJsonSchema.getInstance(), - 1, - validationMetadata, - new ArrayList<>(), - new PathToSchemasMap(), - new PathToSchemasMap() + new ValidationData( + new ObjectWithPropsSchema(), + 1, + validationMetadata + ) ); assertNull(pathToSchemas); } @Test public void testIncorrectPropertyValueFails() { - Map> properties = new LinkedHashMap<>(); - properties.put("someString", StringJsonSchema.class); - - final PropertiesValidator validator = new PropertiesValidator(properties); + final PropertiesValidator validator = new PropertiesValidator(); List pathToItem = List.of("args[0]"); ValidationMetadata validationMetadata = new ValidationMetadata( pathToItem, @@ -99,12 +117,11 @@ public void testIncorrectPropertyValueFails() { mutableMap.put("someString", 1); FrozenMap arg = new FrozenMap<>(mutableMap); Assert.assertThrows(ValidationException.class, () -> validator.validate( - MapJsonSchema.getInstance(), - arg, - validationMetadata, - new ArrayList<>(), - new PathToSchemasMap(), - new PathToSchemasMap() + new ValidationData( + new ObjectWithPropsSchema(), + arg, + validationMetadata + ) )); } } \ No newline at end of file diff --git a/samples/client/3_0_3_unit_test/java/src/test/java/org/openapijsonschematools/client/schemas/validation/RequiredValidatorTest.java b/samples/client/3_0_3_unit_test/java/src/test/java/org/openapijsonschematools/client/schemas/validation/RequiredValidatorTest.java index 2c26d7c7954..d2264b9a967 100644 --- a/samples/client/3_0_3_unit_test/java/src/test/java/org/openapijsonschematools/client/schemas/validation/RequiredValidatorTest.java +++ b/samples/client/3_0_3_unit_test/java/src/test/java/org/openapijsonschematools/client/schemas/validation/RequiredValidatorTest.java @@ -5,16 +5,42 @@ import org.junit.Test; import org.openapijsonschematools.client.configurations.JsonSchemaKeywordFlags; import org.openapijsonschematools.client.configurations.SchemaConfiguration; +import org.openapijsonschematools.client.exceptions.InvalidTypeException; import org.openapijsonschematools.client.exceptions.ValidationException; -import org.openapijsonschematools.client.schemas.MapJsonSchema; -import java.util.ArrayList; import java.util.LinkedHashMap; import java.util.LinkedHashSet; import java.util.List; +import java.util.Map; import java.util.Set; public class RequiredValidatorTest { + public static class ObjectWithRequiredSchema extends JsonSchema { + private ObjectWithRequiredSchema() { + super(new JsonSchemaInfo() + .type(Set.of(Map.class)) + .required(Set.of("someString")) + ); + + } + + @Override + public Object getNewInstance(@Nullable Object arg, List pathToItem, PathToSchemasMap pathToSchemas) { + if (arg instanceof Map mapArg) { + return getNewInstance(mapArg, pathToItem, pathToSchemas); + } + throw new InvalidTypeException("Invalid input type="+getClass(arg)+". It can't be instantiated by this schema"); + } + + @Override + public @Nullable Object validate(@Nullable Object arg, SchemaConfiguration configuration) throws InvalidTypeException, ValidationException { + if (arg instanceof Map mapArg) { + return validate(mapArg, configuration); + } + throw new InvalidTypeException("Invalid input type="+getClass(arg)+". It can't be validated by this schema"); + } + } + @SuppressWarnings("nullness") private void assertNull(@Nullable Object object) { Assert.assertNull(object); @@ -22,9 +48,6 @@ private void assertNull(@Nullable Object object) { @Test public void testCorrectPropertySucceeds() { - Set requiredProperties = new LinkedHashSet<>(); - requiredProperties.add("someString"); - List pathToItem = List.of("args[0]"); ValidationMetadata validationMetadata = new ValidationMetadata( pathToItem, @@ -35,23 +58,19 @@ public void testCorrectPropertySucceeds() { LinkedHashMap mutableMap = new LinkedHashMap<>(); mutableMap.put("someString", "abc"); FrozenMap arg = new FrozenMap<>(mutableMap); - final RequiredValidator validator = new RequiredValidator(requiredProperties); + final RequiredValidator validator = new RequiredValidator(); PathToSchemasMap pathToSchemas = validator.validate( - MapJsonSchema.getInstance(), - arg, - validationMetadata, - new ArrayList<>(), - new PathToSchemasMap(), - new PathToSchemasMap() + new ValidationData( + new ObjectWithRequiredSchema(), + arg, + validationMetadata + ) ); assertNull(pathToSchemas); } @Test public void testNotApplicableTypeReturnsNull() { - Set requiredProperties = new LinkedHashSet<>(); - requiredProperties.add("someString"); - List pathToItem = List.of("args[0]"); ValidationMetadata validationMetadata = new ValidationMetadata( pathToItem, @@ -59,23 +78,19 @@ public void testNotApplicableTypeReturnsNull() { new PathToSchemasMap(), new LinkedHashSet<>() ); - final RequiredValidator validator = new RequiredValidator(requiredProperties); + final RequiredValidator validator = new RequiredValidator(); PathToSchemasMap pathToSchemas = validator.validate( - MapJsonSchema.getInstance(), - 1, - validationMetadata, - new ArrayList<>(), - new PathToSchemasMap(), - new PathToSchemasMap() + new ValidationData( + new ObjectWithRequiredSchema(), + 1, + validationMetadata + ) ); assertNull(pathToSchemas); } @Test public void testIncorrectPropertyFails() { - Set requiredProperties = new LinkedHashSet<>(); - requiredProperties.add("someString"); - List pathToItem = List.of("args[0]"); ValidationMetadata validationMetadata = new ValidationMetadata( pathToItem, @@ -86,14 +101,13 @@ public void testIncorrectPropertyFails() { LinkedHashMap mutableMap = new LinkedHashMap<>(); mutableMap.put("aDifferentProp", 1); FrozenMap arg = new FrozenMap<>(mutableMap); - final RequiredValidator validator = new RequiredValidator(requiredProperties); + final RequiredValidator validator = new RequiredValidator(); Assert.assertThrows(ValidationException.class, () -> validator.validate( - MapJsonSchema.getInstance(), - arg, - validationMetadata, - new ArrayList<>(), - new PathToSchemasMap(), - new PathToSchemasMap() + new ValidationData( + new ObjectWithRequiredSchema(), + arg, + validationMetadata + ) )); } } \ No newline at end of file diff --git a/samples/client/3_0_3_unit_test/java/src/test/java/org/openapijsonschematools/client/schemas/validation/TypeValidatorTest.java b/samples/client/3_0_3_unit_test/java/src/test/java/org/openapijsonschematools/client/schemas/validation/TypeValidatorTest.java index 48433e51455..78a48b6374f 100644 --- a/samples/client/3_0_3_unit_test/java/src/test/java/org/openapijsonschematools/client/schemas/validation/TypeValidatorTest.java +++ b/samples/client/3_0_3_unit_test/java/src/test/java/org/openapijsonschematools/client/schemas/validation/TypeValidatorTest.java @@ -19,9 +19,7 @@ private void assertNull(@Nullable Object object) { @Test public void testValidateSucceeds() { - LinkedHashSet> type = new LinkedHashSet<>(); - type.add(String.class); - final TypeValidator validator = new TypeValidator(type); + final TypeValidator validator = new TypeValidator(); ValidationMetadata validationMetadata = new ValidationMetadata( new ArrayList<>(), new SchemaConfiguration(JsonSchemaKeywordFlags.ofNone()), @@ -29,21 +27,18 @@ public void testValidateSucceeds() { new LinkedHashSet<>() ); @Nullable PathToSchemasMap pathToSchemasMap = validator.validate( - StringJsonSchema.getInstance(), - "hi", - validationMetadata, - new ArrayList<>(), - new PathToSchemasMap(), - new PathToSchemasMap() + new ValidationData( + StringJsonSchema.getInstance(), + "hi", + validationMetadata + ) ); assertNull(pathToSchemasMap); } @Test public void testValidateFailsIntIsNotString() { - LinkedHashSet> type = new LinkedHashSet<>(); - type.add(String.class); - final TypeValidator validator = new TypeValidator(type); + final TypeValidator validator = new TypeValidator(); ValidationMetadata validationMetadata = new ValidationMetadata( new ArrayList<>(), new SchemaConfiguration(JsonSchemaKeywordFlags.ofNone()), @@ -51,12 +46,11 @@ public void testValidateFailsIntIsNotString() { new LinkedHashSet<>() ); Assert.assertThrows(ValidationException.class, () -> validator.validate( - StringJsonSchema.getInstance(), - 1, - validationMetadata, - new ArrayList<>(), - new PathToSchemasMap(), - new PathToSchemasMap() + new ValidationData( + StringJsonSchema.getInstance(), + 1, + validationMetadata + ) )); } } \ 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 bf90fe85e5e..55e58d75011 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 @@ -359,6 +359,7 @@ src/main/java/org/openapijsonschematools/client/schemas/validation/StringValueMe src/main/java/org/openapijsonschematools/client/schemas/validation/TypeValidator.java src/main/java/org/openapijsonschematools/client/schemas/validation/UniqueItemsValidator.java src/main/java/org/openapijsonschematools/client/schemas/validation/UnsetAnyTypeJsonSchema.java +src/main/java/org/openapijsonschematools/client/schemas/validation/ValidationData.java src/main/java/org/openapijsonschematools/client/schemas/validation/ValidationMetadata.java src/main/java/org/openapijsonschematools/client/servers/Server0.java src/main/java/org/openapijsonschematools/client/servers/ServerWithVariables.java diff --git a/samples/client/3_1_0_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/AdditionalPropertiesValidator.java b/samples/client/3_1_0_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/AdditionalPropertiesValidator.java index fd6fa6a4d29..2548452a115 100644 --- a/samples/client/3_1_0_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/AdditionalPropertiesValidator.java +++ b/samples/client/3_1_0_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/AdditionalPropertiesValidator.java @@ -8,22 +8,15 @@ import java.util.Set; public class AdditionalPropertiesValidator implements KeywordValidator { - public final Class additionalProperties; - - public AdditionalPropertiesValidator(Class additionalProperties) { - this.additionalProperties = additionalProperties; - } - @Override public @Nullable PathToSchemasMap validate( - JsonSchema schema, - @Nullable Object arg, - ValidationMetadata validationMetadata, - @Nullable List containsPathToSchemas, - @Nullable PathToSchemasMap patternPropertiesPathToSchemas, - @Nullable PathToSchemasMap ifPathToSchemas + ValidationData data ) { - if (!(arg instanceof Map mapArg)) { + if (!(data.arg() instanceof Map mapArg)) { + return null; + } + var additionalProperties = data.schema().additionalProperties; + if (additionalProperties == null) { return null; } Set presentAdditionalProperties = new LinkedHashSet<>(); @@ -32,22 +25,23 @@ public AdditionalPropertiesValidator(Class additionalPrope presentAdditionalProperties.add((String) key); } } - if (schema.properties != null) { - presentAdditionalProperties.removeAll(schema.properties.keySet()); + var properties = data.schema().properties; + if (properties != null) { + presentAdditionalProperties.removeAll(properties.keySet()); } PathToSchemasMap pathToSchemas = new PathToSchemasMap(); for(String addPropName: presentAdditionalProperties) { @Nullable Object propValue = mapArg.get(addPropName); - List propPathToItem = new ArrayList<>(validationMetadata.pathToItem()); + List propPathToItem = new ArrayList<>(data.validationMetadata().pathToItem()); propPathToItem.add(addPropName); - if (patternPropertiesPathToSchemas != null && patternPropertiesPathToSchemas.containsKey(propPathToItem)) { + if (data.patternPropertiesPathToSchemas() != null && data.patternPropertiesPathToSchemas().containsKey(propPathToItem)) { continue; } ValidationMetadata propValidationMetadata = new ValidationMetadata( propPathToItem, - validationMetadata.configuration(), - validationMetadata.validatedPathToSchemas(), - validationMetadata.seenClasses() + data.validationMetadata().configuration(), + data.validationMetadata().validatedPathToSchemas(), + data.validationMetadata().seenClasses() ); JsonSchema addPropsSchema = JsonSchemaFactory.getInstance(additionalProperties); if (propValidationMetadata.validationRanEarlier(addPropsSchema)) { diff --git a/samples/client/3_1_0_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/AllOfValidator.java b/samples/client/3_1_0_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/AllOfValidator.java index 313e2d97446..583017ea6b5 100644 --- a/samples/client/3_1_0_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/AllOfValidator.java +++ b/samples/client/3_1_0_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/AllOfValidator.java @@ -1,32 +1,21 @@ package org.openapijsonschematools.client.schemas.validation; import org.checkerframework.checker.nullness.qual.Nullable; -import java.util.List; - public class AllOfValidator implements KeywordValidator { - public final List> allOf; - - public AllOfValidator(List> allOf) { - this.allOf = allOf; - } - @Override public @Nullable PathToSchemasMap validate( - JsonSchema schema, - @Nullable Object arg, - ValidationMetadata validationMetadata, - @Nullable List containsPathToSchemas, - @Nullable PathToSchemasMap patternPropertiesPathToSchemas, - @Nullable PathToSchemasMap ifPathToSchemas + ValidationData data ) { + var allOf = data.schema().allOf; + if (allOf == null) { + return null; + } PathToSchemasMap pathToSchemas = new PathToSchemasMap(); for(Class allOfClass: allOf) { JsonSchema allOfSchema = JsonSchemaFactory.getInstance(allOfClass); - PathToSchemasMap otherPathToSchemas = JsonSchema.validate(allOfSchema, arg, validationMetadata); + PathToSchemasMap otherPathToSchemas = JsonSchema.validate(allOfSchema, data.arg(), data.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/AnyOfValidator.java b/samples/client/3_1_0_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/AnyOfValidator.java index a4754dda464..062fa2eecdc 100644 --- a/samples/client/3_1_0_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/AnyOfValidator.java +++ b/samples/client/3_1_0_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/AnyOfValidator.java @@ -7,25 +7,18 @@ import java.util.List; public class AnyOfValidator implements KeywordValidator { - public final List> anyOf; - - public AnyOfValidator(List> anyOf) { - this.anyOf = anyOf; - } - @Override public @Nullable PathToSchemasMap validate( - JsonSchema schema, - @Nullable Object arg, - ValidationMetadata validationMetadata, - @Nullable List containsPathToSchemas, - @Nullable PathToSchemasMap patternPropertiesPathToSchemas, - @Nullable PathToSchemasMap ifPathToSchemas + ValidationData data ) { + var anyOf = data.schema().anyOf; + if (anyOf == null) { + return null; + } PathToSchemasMap pathToSchemas = new PathToSchemasMap(); List> validatedAnyOfClasses = new ArrayList<>(); for(Class anyOfClass: anyOf) { - if (anyOfClass == schema.getClass()) { + if (anyOfClass == data.schema().getClass()) { /* optimistically assume that schema will pass validation do not invoke _validate on it because that is recursive @@ -35,7 +28,7 @@ public AnyOfValidator(List> anyOf) { } try { JsonSchema anyOfSchema = JsonSchemaFactory.getInstance(anyOfClass); - PathToSchemasMap otherPathToSchemas = JsonSchema.validate(anyOfSchema, arg, validationMetadata); + PathToSchemasMap otherPathToSchemas = JsonSchema.validate(anyOfSchema, data.arg(), data.validationMetadata()); validatedAnyOfClasses.add(anyOfClass); pathToSchemas.update(otherPathToSchemas); } catch (ValidationException e) { @@ -43,7 +36,7 @@ public AnyOfValidator(List> anyOf) { } } if (validatedAnyOfClasses.isEmpty()) { - throw new ValidationException("Invalid inputs given to generate an instance of "+schema.getClass()+". None "+ + throw new ValidationException("Invalid inputs given to generate an instance of "+data.schema().getClass()+". None "+ "of the anyOf schemas matched the input data." ); } diff --git a/samples/client/3_1_0_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/ConstValidator.java b/samples/client/3_1_0_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/ConstValidator.java index f797c68ab2e..6409a23e5ca 100644 --- a/samples/client/3_1_0_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/ConstValidator.java +++ b/samples/client/3_1_0_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/ConstValidator.java @@ -4,27 +4,19 @@ import org.checkerframework.checker.nullness.qual.Nullable; import java.math.BigDecimal; -import java.util.List; import java.util.Objects; public class ConstValidator extends BigDecimalValidator implements KeywordValidator { - public final @Nullable Object constValue; - - public ConstValidator(@Nullable Object constValue) { - this.constValue = constValue; - } - @Override public @Nullable PathToSchemasMap validate( - JsonSchema schema, - @Nullable Object arg, - ValidationMetadata validationMetadata, - @Nullable List containsPathToSchemas, - @Nullable PathToSchemasMap patternPropertiesPathToSchemas, - @Nullable PathToSchemasMap ifPathToSchemas + ValidationData data ) { - if (arg instanceof Number) { - BigDecimal castArg = getBigDecimal((Number) arg); + if (!data.schema().constValueSet) { + return null; + } + var constValue = data.schema().constValue; + if (data.arg() instanceof Number numberArg) { + BigDecimal castArg = getBigDecimal(numberArg); if (Objects.equals(castArg, constValue)) { return null; } @@ -32,10 +24,10 @@ public ConstValidator(@Nullable Object constValue) { return null; } } else { - if (Objects.equals(arg, constValue)) { + if (Objects.equals(data.arg(), constValue)) { return null; } } - throw new ValidationException("Invalid value "+arg+" was not equal to const "+constValue); + throw new ValidationException("Invalid value "+data.arg()+" was not equal to const "+constValue); } -} +} \ No newline at end of file diff --git a/samples/client/3_1_0_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/ContainsValidator.java b/samples/client/3_1_0_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/ContainsValidator.java index deaa878d5af..fbfd1c9c700 100644 --- a/samples/client/3_1_0_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/ContainsValidator.java +++ b/samples/client/3_1_0_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/ContainsValidator.java @@ -3,32 +3,21 @@ import org.checkerframework.checker.nullness.qual.Nullable; import org.openapijsonschematools.client.exceptions.ValidationException; -import java.util.ArrayList; import java.util.List; public class ContainsValidator implements KeywordValidator { - public final Class contains; - - public ContainsValidator(Class contains) { - this.contains = contains; - } - @Override public @Nullable PathToSchemasMap validate( - JsonSchema schema, - @Nullable Object arg, - ValidationMetadata validationMetadata, - @Nullable List containsPathToSchemas, - @Nullable PathToSchemasMap patternPropertiesPathToSchemas, - @Nullable PathToSchemasMap ifPathToSchemas + ValidationData data ) { - if (!(arg instanceof List)) { + if (!(data.arg() instanceof List)) { return null; } + var containsPathToSchemas = data.containsPathToSchemas(); if (containsPathToSchemas == null || containsPathToSchemas.isEmpty()) { throw new ValidationException( - "Validation failed for contains keyword in class="+schema.getClass() - + " at pathToItem="+validationMetadata.pathToItem()+". No " + "Validation failed for contains keyword in class="+data.schema().getClass() + + " at pathToItem="+data.validationMetadata().pathToItem()+". No " + "items validated to the contains schema." ); } @@ -38,42 +27,4 @@ public ContainsValidator(Class contains) { } return pathToSchemas; } - - public List getContainsPathToSchemas( - @Nullable Object arg, - ValidationMetadata validationMetadata - ) { - if (!(arg instanceof List)) { - return new ArrayList<>(); - } - @Nullable List containsPathToSchemas = new ArrayList<>(); - int i = 0; - for(Object itemValue: (List) arg) { - PathToSchemasMap thesePathToSchemas = new PathToSchemasMap(); - List itemPathToItem = new ArrayList<>(validationMetadata.pathToItem()); - itemPathToItem.add(i); - ValidationMetadata itemValidationMetadata = new ValidationMetadata( - itemPathToItem, - validationMetadata.configuration(), - validationMetadata.validatedPathToSchemas(), - validationMetadata.seenClasses() - ); - JsonSchema containsSchema = JsonSchemaFactory.getInstance(contains); - if (itemValidationMetadata.validationRanEarlier(containsSchema)) { - // todo add_deeper_validated_schemas - containsPathToSchemas.add(thesePathToSchemas); - i += 1; - continue; - } - - try { - PathToSchemasMap otherPathToSchemas = JsonSchema.validate( - containsSchema, itemValue, itemValidationMetadata); - containsPathToSchemas.add(otherPathToSchemas); - } catch (ValidationException ignored) { - ; - } - } - return containsPathToSchemas; - } } \ No newline at end of file diff --git a/samples/client/3_1_0_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/DependentRequiredValidator.java b/samples/client/3_1_0_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/DependentRequiredValidator.java index a5e92887928..77b21ca801d 100644 --- a/samples/client/3_1_0_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/DependentRequiredValidator.java +++ b/samples/client/3_1_0_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/DependentRequiredValidator.java @@ -4,35 +4,27 @@ import org.openapijsonschematools.client.exceptions.ValidationException; import java.util.HashSet; -import java.util.List; import java.util.Map; import java.util.Set; public class DependentRequiredValidator implements KeywordValidator { - public final Map> dependentRequired; - - public DependentRequiredValidator(Map> dependentRequired) { - this.dependentRequired = dependentRequired; - } - @Override public @Nullable PathToSchemasMap validate( - JsonSchema schema, - @Nullable Object arg, - ValidationMetadata validationMetadata, - @Nullable List containsPathToSchemas, - @Nullable PathToSchemasMap patternPropertiesPathToSchemas, - @Nullable PathToSchemasMap ifPathToSchemas + ValidationData data ) { - if (!(arg instanceof Map)) { + if (!(data.arg() instanceof Map mapArg)) { + return null; + } + var dependentRequired = data.schema().dependentRequired; + if (dependentRequired == null) { return null; } for (Map.Entry> entry: dependentRequired.entrySet()) { - if (!((Map) arg).containsKey(entry.getKey())) { + if (!mapArg.containsKey(entry.getKey())) { continue; } Set missingKeys = new HashSet<>(entry.getValue()); - for (Object objKey: ((Map) arg).keySet()) { + for (Object objKey: mapArg.keySet()) { if (objKey instanceof String key) { missingKeys.remove(key); } @@ -42,7 +34,7 @@ public DependentRequiredValidator(Map> dependentRequired) { } throw new ValidationException( "Validation failed for dependentRequired because these_keys="+missingKeys+" are "+ - "missing at pathToItem="+validationMetadata.pathToItem()+" in class "+schema.getClass() + "missing at pathToItem="+data.validationMetadata().pathToItem()+" in class "+data.schema().getClass() ); } return null; 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 index 0ffa3b351ca..940157d3b48 100644 --- 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 @@ -2,29 +2,20 @@ 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, - @Nullable PathToSchemasMap patternPropertiesPathToSchemas, - @Nullable PathToSchemasMap ifPathToSchemas + ValidationData data ) { - if (!(arg instanceof Map mapArg)) { + if (!(data.arg() instanceof Map mapArg)) { + return null; + } + var dependentSchemas = data.schema().dependentSchemas; + if (dependentSchemas == null) { return null; } PathToSchemasMap pathToSchemas = new PathToSchemasMap(); @@ -41,10 +32,9 @@ public DependentSchemasValidator(Map> depend } Class dependentSchemaClass = entry.getValue(); JsonSchema dependentSchema = JsonSchemaFactory.getInstance(dependentSchemaClass); - PathToSchemasMap otherPathToSchemas = JsonSchema.validate(dependentSchema, arg, validationMetadata); + PathToSchemasMap otherPathToSchemas = JsonSchema.validate(dependentSchema, mapArg, data.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/EnumValidator.java b/samples/client/3_1_0_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/EnumValidator.java index 6cc9459e1a8..8af756619bd 100644 --- a/samples/client/3_1_0_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/EnumValidator.java +++ b/samples/client/3_1_0_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/EnumValidator.java @@ -4,36 +4,28 @@ import org.checkerframework.checker.nullness.qual.Nullable; import java.math.BigDecimal; -import java.util.List; import java.util.Set; public class EnumValidator extends BigDecimalValidator implements KeywordValidator { - public final Set<@Nullable Object> enumValues; - - public EnumValidator(Set<@Nullable Object> enumValues) { - this.enumValues = enumValues; - } - @SuppressWarnings("nullness") - private boolean enumContainsArg(@Nullable Object arg){ + private static boolean enumContainsArg(Set<@Nullable Object> enumValues, @Nullable Object arg){ return enumValues.contains(arg); } @Override public @Nullable PathToSchemasMap validate( - JsonSchema schema, - @Nullable Object arg, - ValidationMetadata validationMetadata, - @Nullable List containsPathToSchemas, - @Nullable PathToSchemasMap patternPropertiesPathToSchemas, - @Nullable PathToSchemasMap ifPathToSchemas + ValidationData data ) { + var enumValues = data.schema().enumValues; + if (enumValues == null) { + return null; + } if (enumValues.isEmpty()) { throw new ValidationException("No value can match enum because enum is empty"); } - if (arg instanceof Number) { - BigDecimal castArg = getBigDecimal((Number) arg); - if (enumContainsArg(castArg)) { + if (data.arg() instanceof Number numberArg) { + BigDecimal castArg = getBigDecimal(numberArg); + if (enumContainsArg(enumValues, castArg)) { return null; } for (Object enumValue: enumValues) { @@ -42,10 +34,10 @@ private boolean enumContainsArg(@Nullable Object arg){ } } } else { - if (enumContainsArg(arg)) { + if (enumContainsArg(enumValues, data.arg())) { return null; } } - throw new ValidationException("Invalid value "+arg+" was not one of the allowed enum "+enumValues); + throw new ValidationException("Invalid value "+data.arg()+" was not one of the allowed enum "+enumValues); } } diff --git a/samples/client/3_1_0_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/ExclusiveMaximumValidator.java b/samples/client/3_1_0_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/ExclusiveMaximumValidator.java index 432d5b0f4de..7d05ff65546 100644 --- a/samples/client/3_1_0_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/ExclusiveMaximumValidator.java +++ b/samples/client/3_1_0_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/ExclusiveMaximumValidator.java @@ -3,48 +3,39 @@ import org.openapijsonschematools.client.exceptions.ValidationException; import org.checkerframework.checker.nullness.qual.Nullable; -import java.util.List; - public class ExclusiveMaximumValidator implements KeywordValidator { - public final Number exclusiveMaximum; - - public ExclusiveMaximumValidator(Number exclusiveMaximum) { - this.exclusiveMaximum = exclusiveMaximum; - } - @Override public @Nullable PathToSchemasMap validate( - JsonSchema schema, - @Nullable Object arg, - ValidationMetadata validationMetadata, - @Nullable List containsPathToSchemas, - @Nullable PathToSchemasMap patternPropertiesPathToSchemas, - @Nullable PathToSchemasMap ifPathToSchemas + ValidationData data ) { - if (!(arg instanceof Number)) { + var exclusiveMaximum = data.schema().exclusiveMaximum; + if (exclusiveMaximum == null) { + return null; + } + if (!(data.arg() instanceof Number)) { return null; } - String msg = "Value " + arg + " is invalid because it is >= the exclusiveMaximum of " + exclusiveMaximum; - if (arg instanceof Integer) { - if (((Integer) arg).compareTo(exclusiveMaximum.intValue()) > -1) { + String msg = "Value " + data.arg() + " is invalid because it is >= the exclusiveMaximum of " + exclusiveMaximum; + if (data.arg() instanceof Integer intArg) { + if (intArg.compareTo(exclusiveMaximum.intValue()) > -1) { throw new ValidationException(msg); } return null; } - if (arg instanceof Long) { - if (((Long) arg).compareTo(exclusiveMaximum.longValue()) > -1) { + if (data.arg() instanceof Long longArg) { + if (longArg.compareTo(exclusiveMaximum.longValue()) > -1) { throw new ValidationException(msg); } return null; } - if (arg instanceof Float) { - if (((Float) arg).compareTo(exclusiveMaximum.floatValue()) > -1) { + if (data.arg() instanceof Float floatArg) { + if (floatArg.compareTo(exclusiveMaximum.floatValue()) > -1) { throw new ValidationException(msg); } return null; } - if (arg instanceof Double) { - if (((Double) arg).compareTo(exclusiveMaximum.doubleValue()) > -1) { + if (data.arg() instanceof Double doubleArg) { + if (doubleArg.compareTo(exclusiveMaximum.doubleValue()) > -1) { throw new ValidationException(msg); } return null; diff --git a/samples/client/3_1_0_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/ExclusiveMinimumValidator.java b/samples/client/3_1_0_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/ExclusiveMinimumValidator.java index d60c96f8325..73eb1e547c3 100644 --- a/samples/client/3_1_0_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/ExclusiveMinimumValidator.java +++ b/samples/client/3_1_0_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/ExclusiveMinimumValidator.java @@ -3,48 +3,39 @@ import org.openapijsonschematools.client.exceptions.ValidationException; import org.checkerframework.checker.nullness.qual.Nullable; -import java.util.List; - public class ExclusiveMinimumValidator implements KeywordValidator { - public final Number exclusiveMinimum; - - public ExclusiveMinimumValidator(Number exclusiveMinimum) { - this.exclusiveMinimum = exclusiveMinimum; - } - @Override public @Nullable PathToSchemasMap validate( - JsonSchema schema, - @Nullable Object arg, - ValidationMetadata validationMetadata, - @Nullable List containsPathToSchemas, - @Nullable PathToSchemasMap patternPropertiesPathToSchemas, - @Nullable PathToSchemasMap ifPathToSchemas + ValidationData data ) { - if (!(arg instanceof Number)) { + var exclusiveMinimum = data.schema().exclusiveMinimum; + if (exclusiveMinimum == null) { + return null; + } + if (!(data.arg() instanceof Number)) { return null; } - String msg = "Value " + arg + " is invalid because it is <= the exclusiveMinimum of " + exclusiveMinimum; - if (arg instanceof Integer) { - if (((Integer) arg).compareTo(exclusiveMinimum.intValue()) < 1) { + String msg = "Value " + data.arg() + " is invalid because it is <= the exclusiveMinimum of " + exclusiveMinimum; + if (data.arg() instanceof Integer intArg) { + if (intArg.compareTo(exclusiveMinimum.intValue()) < 1) { throw new ValidationException(msg); } return null; } - if (arg instanceof Long) { - if (((Long) arg).compareTo(exclusiveMinimum.longValue()) < 1) { + if (data.arg() instanceof Long longArg) { + if (longArg.compareTo(exclusiveMinimum.longValue()) < 1) { throw new ValidationException(msg); } return null; } - if (arg instanceof Float) { - if (((Float) arg).compareTo(exclusiveMinimum.floatValue()) < 1) { + if (data.arg() instanceof Float floatArg) { + if (floatArg.compareTo(exclusiveMinimum.floatValue()) < 1) { throw new ValidationException(msg); } return null; } - if (arg instanceof Double) { - if (((Double) arg).compareTo(exclusiveMinimum.doubleValue()) < 1) { + if (data.arg() instanceof Double doubleArg) { + if (doubleArg.compareTo(exclusiveMinimum.doubleValue()) < 1) { throw new ValidationException(msg); } return null; diff --git a/samples/client/3_1_0_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/FormatValidator.java b/samples/client/3_1_0_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/FormatValidator.java index d782f2ce4a2..c1ca45e44f3 100644 --- a/samples/client/3_1_0_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/FormatValidator.java +++ b/samples/client/3_1_0_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/FormatValidator.java @@ -6,16 +6,9 @@ import java.math.BigDecimal; import java.math.BigInteger; import java.time.format.DateTimeParseException; -import java.util.List; import java.util.UUID; public class FormatValidator implements KeywordValidator { - public final String format; - - public FormatValidator(String format) { - this.format = format; - } - private final static BigInteger int32InclusiveMinimum = BigInteger.valueOf(-2147483648L); private final static BigInteger int32InclusiveMaximum = BigInteger.valueOf(2147483647L); private final static BigInteger int64InclusiveMinimum = BigInteger.valueOf(-9223372036854775808L); @@ -25,12 +18,12 @@ public FormatValidator(String format) { private final static BigDecimal doubleInclusiveMinimum = BigDecimal.valueOf(-1.7976931348623157E+308d); private final static BigDecimal doubleInclusiveMaximum = BigDecimal.valueOf(1.7976931348623157E+308d); - private Void validateNumericFormat(Number arg, ValidationMetadata validationMetadata) { + private static void validateNumericFormat(Number arg, ValidationMetadata validationMetadata, String format) { if (format.startsWith("int")) { // there is a json schema test where 1.0 validates as an integer BigInteger intArg; if (arg instanceof Float || arg instanceof Double) { - Double doubleArg; + double doubleArg; if (arg instanceof Float) { doubleArg = arg.doubleValue(); } else { @@ -60,20 +53,17 @@ private Void validateNumericFormat(Number arg, ValidationMetadata validationMeta "Invalid value " + arg + " for format int32 at " + validationMetadata.pathToItem() ); } - return null; } else if (format.equals("int64")) { if (intArg.compareTo(int64InclusiveMinimum) < 0 || intArg.compareTo(int64InclusiveMaximum) > 0) { throw new ValidationException( "Invalid value " + arg + " for format int64 at " + validationMetadata.pathToItem() ); } - return null; } - return null; } else if (format.equals("float") || format.equals("double")) { BigDecimal decimalArg; if (arg instanceof Float) { - decimalArg = new BigDecimal((Float) arg); + decimalArg = BigDecimal.valueOf(arg.doubleValue()); } else if (arg instanceof Double) { decimalArg = BigDecimal.valueOf((Double) arg); } else { @@ -85,83 +75,81 @@ private Void validateNumericFormat(Number arg, ValidationMetadata validationMeta "Invalid value "+arg+" for format float at "+validationMetadata.pathToItem() ); } - return null; - } else if (format.equals("double")) { + } else { if (decimalArg.compareTo(doubleInclusiveMinimum) < 0 || decimalArg.compareTo(doubleInclusiveMaximum) > 0 ){ throw new ValidationException( "Invalid value "+arg+" for format double at "+validationMetadata.pathToItem() ); } - return null; } } - return null; } - private Void validateStringFormat(String arg, ValidationMetadata validationMetadata) { - if (format.equals("uuid")) { - try { - UUID.fromString(arg); - } catch (IllegalArgumentException e) { - throw new ValidationException( - "Value cannot be converted to a UUID. Invalid value "+ - arg+" for format uuid at "+validationMetadata.pathToItem() - ); + private static void validateStringFormat(String arg, ValidationMetadata validationMetadata, String format) { + switch (format) { + case "uuid" -> { + try { + UUID.fromString(arg); + } catch (IllegalArgumentException e) { + throw new ValidationException( + "Value cannot be converted to a UUID. Invalid value " + + arg + " for format uuid at " + validationMetadata.pathToItem() + ); + } } - return null; - } else if (format.equals("number")) { - try { - new BigDecimal(arg); - } catch (NumberFormatException e) { - throw new ValidationException( - "Value cannot be converted to a decimal. Invalid value "+ - arg+" for format number at "+validationMetadata.pathToItem() - ); + case "number" -> { + try { + new BigDecimal(arg); + } catch (NumberFormatException e) { + throw new ValidationException( + "Value cannot be converted to a decimal. Invalid value " + + arg + " for format number at " + validationMetadata.pathToItem() + ); + } } - return null; - } else if (format.equals("date")) { - try { - new CustomIsoparser().parseIsodate(arg); - } catch (DateTimeParseException e) { - throw new ValidationException( - "Value does not conform to the required ISO-8601 date format. "+ - "Invalid value "+arg+" for format date at "+validationMetadata.pathToItem() - ); + case "date" -> { + try { + new CustomIsoparser().parseIsodate(arg); + } catch (DateTimeParseException e) { + throw new ValidationException( + "Value does not conform to the required ISO-8601 date format. " + + "Invalid value " + arg + " for format date at " + validationMetadata.pathToItem() + ); + } } - return null; - } else if (format.equals("date-time")) { - try { - new CustomIsoparser().parseIsodatetime(arg); - } catch (DateTimeParseException e) { - throw new ValidationException( - "Value does not conform to the required ISO-8601 datetime format. "+ - "Invalid value "+arg+" for format datetime at "+validationMetadata.pathToItem() - ); + case "date-time" -> { + try { + new CustomIsoparser().parseIsodatetime(arg); + } catch (DateTimeParseException e) { + throw new ValidationException( + "Value does not conform to the required ISO-8601 datetime format. " + + "Invalid value " + arg + " for format datetime at " + validationMetadata.pathToItem() + ); + } } - return null; } - return null; } @Override public @Nullable PathToSchemasMap validate( - JsonSchema schema, - @Nullable Object arg, - ValidationMetadata validationMetadata, - @Nullable List containsPathToSchemas, - @Nullable PathToSchemasMap patternPropertiesPathToSchemas, - @Nullable PathToSchemasMap ifPathToSchemas + ValidationData data ) { - if (arg instanceof Number) { + var format = data.schema().format; + if (format == null) { + return null; + } + if (data.arg() instanceof Number numberArg) { validateNumericFormat( - (Number) arg, - validationMetadata + numberArg, + data.validationMetadata(), + format ); return null; - } else if (arg instanceof String) { + } else if (data.arg() instanceof String stringArg) { validateStringFormat( - (String) arg, - validationMetadata + stringArg, + data.validationMetadata(), + format ); return null; } diff --git a/samples/client/3_1_0_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/IfValidator.java b/samples/client/3_1_0_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/IfValidator.java index e1634bd1b00..b145ab8007a 100644 --- a/samples/client/3_1_0_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/IfValidator.java +++ b/samples/client/3_1_0_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/IfValidator.java @@ -1,33 +1,18 @@ package org.openapijsonschematools.client.schemas.validation; import org.openapijsonschematools.client.exceptions.ValidationException; -import org.openapijsonschematools.client.exceptions.InvalidTypeException; import org.checkerframework.checker.nullness.qual.Nullable; -import java.util.ArrayList; -import java.util.LinkedHashMap; -import java.util.LinkedHashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; - public class IfValidator implements KeywordValidator { - public final Class ifSchema; - - public IfValidator(Class ifSchema) { - this.ifSchema = ifSchema; - } - @Override public @Nullable PathToSchemasMap validate( - JsonSchema schema, - @Nullable Object arg, - ValidationMetadata validationMetadata, - @Nullable List containsPathToSchemas, - @Nullable PathToSchemasMap patternPropertiesPathToSchemas, - @Nullable PathToSchemasMap ifPathToSchemas + ValidationData data ) { - if (ifPathToSchemas == null) { + var ifSchema = data.schema().ifSchema; + if (ifSchema == null) { + return null; + } + if (data.ifPathToSchemas() == null) { throw new ValidationException("Invalid type for ifPathToSchemas"); } /* @@ -40,17 +25,4 @@ public IfValidator(Class ifSchema) { */ return null; } - - public PathToSchemasMap getIfPathToSchemas( - @Nullable Object arg, - ValidationMetadata validationMetadata - ) { - JsonSchema ifSchemaInstance = JsonSchemaFactory.getInstance(ifSchema); - PathToSchemasMap pathToSchemas = new PathToSchemasMap(); - try { - var otherPathToSchemas = JsonSchema.validate(ifSchemaInstance, arg, validationMetadata); - pathToSchemas.update(otherPathToSchemas); - } catch (ValidationException | InvalidTypeException ignored) {} - return pathToSchemas; - } } diff --git a/samples/client/3_1_0_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/ItemsValidator.java b/samples/client/3_1_0_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/ItemsValidator.java index 5d146ab250c..5bd194d47a9 100644 --- a/samples/client/3_1_0_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/ItemsValidator.java +++ b/samples/client/3_1_0_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/ItemsValidator.java @@ -6,38 +6,31 @@ import java.util.List; public class ItemsValidator implements KeywordValidator { - public final Class items; - - public ItemsValidator(Class items) { - this.items = items; - } - @Override public @Nullable PathToSchemasMap validate( - JsonSchema schema, - @Nullable Object arg, - ValidationMetadata validationMetadata, - @Nullable List containsPathToSchemas, - @Nullable PathToSchemasMap patternPropertiesPathToSchemas, - @Nullable PathToSchemasMap ifPathToSchemas + ValidationData data ) { - if (!(arg instanceof List listArg)) { + var items = data.schema().items; + if (items == null) { + return null; + } + if (!(data.arg() instanceof List listArg)) { return null; } if (listArg.isEmpty()) { return null; } PathToSchemasMap pathToSchemas = new PathToSchemasMap(); - int minIndex = schema.prefixItems != null ? schema.prefixItems.size() : 0; + int minIndex = data.schema().prefixItems != null ? data.schema().prefixItems.size() : 0; JsonSchema itemsSchema = JsonSchemaFactory.getInstance(items); for(int i = minIndex; i < listArg.size(); i++) { - List itemPathToItem = new ArrayList<>(validationMetadata.pathToItem()); + List itemPathToItem = new ArrayList<>(data.validationMetadata().pathToItem()); itemPathToItem.add(i); ValidationMetadata itemValidationMetadata = new ValidationMetadata( itemPathToItem, - validationMetadata.configuration(), - validationMetadata.validatedPathToSchemas(), - validationMetadata.seenClasses() + data.validationMetadata().configuration(), + data.validationMetadata().validatedPathToSchemas(), + data.validationMetadata().seenClasses() ); if (itemValidationMetadata.validationRanEarlier(itemsSchema)) { // todo add_deeper_validated_schemas 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 551c586665c..db33a080218 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 @@ -50,10 +50,10 @@ public abstract class JsonSchema { public final @Nullable Integer maxContains; public final @Nullable Integer minContains; public final @Nullable Class propertyNames; - public @Nullable Map> dependentRequired; + public final @Nullable Map> dependentRequired; public final @Nullable Map> dependentSchemas; - public @Nullable Map> patternProperties; - public @Nullable List> prefixItems; + public final @Nullable Map> patternProperties; + public final @Nullable List> prefixItems; public final @Nullable Class ifSchema; private final LinkedHashMap keywordToValidator; @@ -61,244 +61,142 @@ protected JsonSchema(JsonSchemaInfo jsonSchemaInfo) { LinkedHashMap keywordToValidator = new LinkedHashMap<>(); this.type = jsonSchemaInfo.type; if (this.type != null) { - keywordToValidator.put( - "type", - new TypeValidator(this.type) - ); + keywordToValidator.put("type", new TypeValidator()); } this.format = jsonSchemaInfo.format; if (this.format != null) { - keywordToValidator.put( - "format", - new FormatValidator(this.format) - ); + keywordToValidator.put("format", new FormatValidator()); } this.items = jsonSchemaInfo.items; if (this.items != null) { - keywordToValidator.put( - "items", - new ItemsValidator(this.items) - ); + keywordToValidator.put("items", new ItemsValidator()); } this.properties = jsonSchemaInfo.properties; if (this.properties != null) { - keywordToValidator.put( - "properties", - new PropertiesValidator(this.properties) - ); + keywordToValidator.put("properties", new PropertiesValidator()); } this.required = jsonSchemaInfo.required; if (this.required != null) { - keywordToValidator.put( - "required", - new RequiredValidator(this.required) - ); + keywordToValidator.put("required", new RequiredValidator()); } this.exclusiveMaximum = jsonSchemaInfo.exclusiveMaximum; if (this.exclusiveMaximum != null) { - keywordToValidator.put( - "exclusiveMaximum", - new ExclusiveMaximumValidator(this.exclusiveMaximum) - ); + keywordToValidator.put("exclusiveMaximum", new ExclusiveMaximumValidator()); } this.exclusiveMinimum = jsonSchemaInfo.exclusiveMinimum; if (this.exclusiveMinimum != null) { - keywordToValidator.put( - "exclusiveMinimum", - new ExclusiveMinimumValidator(this.exclusiveMinimum) - ); + keywordToValidator.put("exclusiveMinimum", new ExclusiveMinimumValidator()); } this.maxItems = jsonSchemaInfo.maxItems; if (this.maxItems != null) { - keywordToValidator.put( - "maxItems", - new MaxItemsValidator(this.maxItems) - ); + keywordToValidator.put("maxItems", new MaxItemsValidator()); } this.minItems = jsonSchemaInfo.minItems; if (this.minItems != null) { - keywordToValidator.put( - "minItems", - new MinItemsValidator(this.minItems) - ); + keywordToValidator.put("minItems", new MinItemsValidator()); } this.maxLength = jsonSchemaInfo.maxLength; if (this.maxLength != null) { - keywordToValidator.put( - "maxLength", - new MaxLengthValidator(this.maxLength) - ); + keywordToValidator.put("maxLength", new MaxLengthValidator()); } this.minLength = jsonSchemaInfo.minLength; if (this.minLength != null) { - keywordToValidator.put( - "minLength", - new MinLengthValidator(this.minLength) - ); + keywordToValidator.put("minLength", new MinLengthValidator()); } this.maxProperties = jsonSchemaInfo.maxProperties; if (this.maxProperties != null) { - keywordToValidator.put( - "maxProperties", - new MaxPropertiesValidator(this.maxProperties) - ); + keywordToValidator.put("maxProperties", new MaxPropertiesValidator()); } this.minProperties = jsonSchemaInfo.minProperties; if (this.minProperties != null) { - keywordToValidator.put( - "minProperties", - new MinPropertiesValidator(this.minProperties) - ); + keywordToValidator.put("minProperties", new MinPropertiesValidator()); } this.maximum = jsonSchemaInfo.maximum; if (this.maximum != null) { - keywordToValidator.put( - "maximum", - new MaximumValidator(this.maximum) - ); + keywordToValidator.put("maximum", new MaximumValidator()); } this.minimum = jsonSchemaInfo.minimum; if (this.minimum != null) { - keywordToValidator.put( - "minimum", - new MinimumValidator(this.minimum) - ); + keywordToValidator.put("minimum", new MinimumValidator()); } this.multipleOf = jsonSchemaInfo.multipleOf; if (this.multipleOf != null) { - keywordToValidator.put( - "multipleOf", - new MultipleOfValidator(this.multipleOf) - ); + keywordToValidator.put("multipleOf", new MultipleOfValidator()); } this.additionalProperties = jsonSchemaInfo.additionalProperties; if (this.additionalProperties != null) { - keywordToValidator.put( - "additionalProperties", - new AdditionalPropertiesValidator(this.additionalProperties) - ); + keywordToValidator.put("additionalProperties", new AdditionalPropertiesValidator()); } this.allOf = jsonSchemaInfo.allOf; if (this.allOf != null) { - keywordToValidator.put( - "allOf", - new AllOfValidator(this.allOf) - ); + keywordToValidator.put("allOf", new AllOfValidator()); } this.anyOf = jsonSchemaInfo.anyOf; if (this.anyOf != null) { - keywordToValidator.put( - "anyOf", - new AnyOfValidator(this.anyOf) - ); + keywordToValidator.put("anyOf", new AnyOfValidator()); } this.oneOf = jsonSchemaInfo.oneOf; if (this.oneOf != null) { - keywordToValidator.put( - "oneOf", - new OneOfValidator(this.oneOf) - ); + keywordToValidator.put("oneOf", new OneOfValidator()); } this.not = jsonSchemaInfo.not; if (this.not != null) { - keywordToValidator.put( - "not", - new NotValidator(this.not) - ); + keywordToValidator.put("not", new NotValidator()); } this.uniqueItems = jsonSchemaInfo.uniqueItems; if (this.uniqueItems != null) { - keywordToValidator.put( - "uniqueItems", - new UniqueItemsValidator(this.uniqueItems) - ); + keywordToValidator.put("uniqueItems", new UniqueItemsValidator()); } this.enumValues = jsonSchemaInfo.enumValues; if (this.enumValues != null) { - keywordToValidator.put( - "enum", - new EnumValidator(this.enumValues) - ); + keywordToValidator.put("enum", new EnumValidator()); } this.pattern = jsonSchemaInfo.pattern; if (this.pattern != null) { - keywordToValidator.put( - "pattern", - new PatternValidator(this.pattern) - ); + keywordToValidator.put("pattern", new PatternValidator()); } this.defaultValue = jsonSchemaInfo.defaultValue; this.defaultValueSet = jsonSchemaInfo.defaultValueSet; this.constValue = jsonSchemaInfo.constValue; this.constValueSet = jsonSchemaInfo.constValueSet; if (this.constValueSet) { - keywordToValidator.put( - "const", - new ConstValidator(this.constValue) - ); + keywordToValidator.put("const", new ConstValidator()); } this.contains = jsonSchemaInfo.contains; if (this.contains != null) { - keywordToValidator.put( - "contains", - new ContainsValidator(this.contains) - ); + keywordToValidator.put("contains", new ContainsValidator()); } this.maxContains = jsonSchemaInfo.maxContains; if (this.maxContains != null) { - keywordToValidator.put( - "maxContains", - new MaxContainsValidator(this.maxContains) - ); + keywordToValidator.put("maxContains", new MaxContainsValidator()); } this.minContains = jsonSchemaInfo.minContains; if (this.minContains != null) { - keywordToValidator.put( - "minContains", - new MinContainsValidator(this.minContains) - ); + keywordToValidator.put("minContains", new MinContainsValidator()); } this.propertyNames = jsonSchemaInfo.propertyNames; if (this.propertyNames != null) { - keywordToValidator.put( - "propertyNames", - new PropertyNamesValidator(this.propertyNames) - ); + keywordToValidator.put("propertyNames", new PropertyNamesValidator()); } this.dependentRequired = jsonSchemaInfo.dependentRequired; if (this.dependentRequired != null) { - keywordToValidator.put( - "dependentRequired", - new DependentRequiredValidator(this.dependentRequired) - ); + keywordToValidator.put("dependentRequired", new DependentRequiredValidator()); } this.dependentSchemas = jsonSchemaInfo.dependentSchemas; if (this.dependentSchemas != null) { - keywordToValidator.put( - "dependentSchemas", - new DependentSchemasValidator(this.dependentSchemas) - ); + keywordToValidator.put("dependentSchemas", new DependentSchemasValidator()); } this.patternProperties = jsonSchemaInfo.patternProperties; if (this.patternProperties != null) { - keywordToValidator.put( - "patternProperties", - new PatternPropertiesValidator(this.patternProperties) - ); + keywordToValidator.put("patternProperties", new PatternPropertiesValidator()); } this.prefixItems = jsonSchemaInfo.prefixItems; if (this.prefixItems != null) { - keywordToValidator.put( - "prefixItems", - new PrefixItemsValidator(this.prefixItems) - ); + keywordToValidator.put("prefixItems", new PrefixItemsValidator()); } this.ifSchema = jsonSchemaInfo.ifSchema; if (this.ifSchema != null) { - keywordToValidator.put( - "if", - new IfValidator(this.ifSchema) - ); + keywordToValidator.put("if", new IfValidator()); } this.keywordToValidator = keywordToValidator; } @@ -306,6 +204,93 @@ protected JsonSchema(JsonSchemaInfo jsonSchemaInfo) { public abstract @Nullable Object getNewInstance(@Nullable Object arg, List pathToItem, PathToSchemasMap pathToSchemas) throws InvalidTypeException; public abstract @Nullable Object validate(@Nullable Object arg, SchemaConfiguration configuration) throws InvalidTypeException, ValidationException; + private List getContainsPathToSchemas( + @Nullable Object arg, + ValidationMetadata validationMetadata + ) { + if (!(arg instanceof List listArg) || contains == null) { + return new ArrayList<>(); + } + JsonSchema containsSchema = JsonSchemaFactory.getInstance(contains); + @Nullable List containsPathToSchemas = new ArrayList<>(); + int i = 0; + for(Object itemValue: listArg) { + PathToSchemasMap thesePathToSchemas = new PathToSchemasMap(); + List itemPathToItem = new ArrayList<>(validationMetadata.pathToItem()); + itemPathToItem.add(i); + ValidationMetadata itemValidationMetadata = new ValidationMetadata( + itemPathToItem, + validationMetadata.configuration(), + validationMetadata.validatedPathToSchemas(), + validationMetadata.seenClasses() + ); + if (itemValidationMetadata.validationRanEarlier(containsSchema)) { + // todo add_deeper_validated_schemas + containsPathToSchemas.add(thesePathToSchemas); + i += 1; + continue; + } + + try { + PathToSchemasMap otherPathToSchemas = JsonSchema.validate( + containsSchema, itemValue, itemValidationMetadata); + containsPathToSchemas.add(otherPathToSchemas); + } catch (ValidationException ignored) {} + } + return containsPathToSchemas; + } + + private PathToSchemasMap getPatternPropertiesPathToSchemas( + @Nullable Object arg, + ValidationMetadata validationMetadata + ) { + if (!(arg instanceof Map mapArg) || patternProperties == null) { + return new PathToSchemasMap(); + } + PathToSchemasMap pathToSchemas = new PathToSchemasMap(); + for (Map.Entry entry: mapArg.entrySet()) { + Object entryKey = entry.getKey(); + if (!(entryKey instanceof String key)) { + throw new InvalidTypeException("Invalid non-string type for map key"); + } + List propPathToItem = new ArrayList<>(validationMetadata.pathToItem()); + propPathToItem.add(key); + ValidationMetadata propValidationMetadata = new ValidationMetadata( + propPathToItem, + validationMetadata.configuration(), + validationMetadata.validatedPathToSchemas(), + validationMetadata.seenClasses() + ); + for (Map.Entry> patternPropEntry: patternProperties.entrySet()) { + if (!patternPropEntry.getKey().matcher(key).find()) { + continue; + } + + Class patternPropClass = patternPropEntry.getValue(); + JsonSchema patternPropSchema = JsonSchemaFactory.getInstance(patternPropClass); + PathToSchemasMap otherPathToSchemas = JsonSchema.validate(patternPropSchema, entry.getValue(), propValidationMetadata); + pathToSchemas.update(otherPathToSchemas); + } + } + return pathToSchemas; + } + + private PathToSchemasMap getIfPathToSchemas( + @Nullable Object arg, + ValidationMetadata validationMetadata + ) { + if (ifSchema == null) { + return new PathToSchemasMap(); + } + JsonSchema ifSchemaInstance = JsonSchemaFactory.getInstance(ifSchema); + PathToSchemasMap pathToSchemas = new PathToSchemasMap(); + try { + var otherPathToSchemas = JsonSchema.validate(ifSchemaInstance, arg, validationMetadata); + pathToSchemas.update(otherPathToSchemas); + } catch (ValidationException | InvalidTypeException ignored) {} + return pathToSchemas; + } + public static PathToSchemasMap validate( JsonSchema jsonSchema, @Nullable Object arg, @@ -315,19 +300,16 @@ public static PathToSchemasMap validate( PathToSchemasMap pathToSchemas = new PathToSchemasMap(); LinkedHashMap thisKeywordToValidator = jsonSchema.keywordToValidator; @Nullable List containsPathToSchemas = null; - KeywordValidator containsValidator = thisKeywordToValidator.get("contains"); - if (containsValidator != null) { - containsPathToSchemas = containsValidator.getContainsPathToSchemas(arg, validationMetadata); + if (thisKeywordToValidator.containsKey("contains")) { + containsPathToSchemas = jsonSchema.getContainsPathToSchemas(arg, validationMetadata); } @Nullable PathToSchemasMap patternPropertiesPathToSchemas = null; - KeywordValidator patternPropertiesValidator = thisKeywordToValidator.get("patternProperties"); - if (patternPropertiesValidator != null) { - patternPropertiesPathToSchemas = patternPropertiesValidator.getPatternPropertiesPathToSchemas(arg, validationMetadata); + if (thisKeywordToValidator.containsKey("patternProperties")) { + patternPropertiesPathToSchemas = jsonSchema.getPatternPropertiesPathToSchemas(arg, validationMetadata); } @Nullable PathToSchemasMap ifPathToSchemas = null; - KeywordValidator ifValidator = thisKeywordToValidator.get("if"); - if (ifValidator != null) { - ifPathToSchemas = ifValidator.getIfPathToSchemas(arg, validationMetadata); + if (thisKeywordToValidator.containsKey("if")) { + ifPathToSchemas = jsonSchema.getIfPathToSchemas(arg, validationMetadata); } for (Map.Entry entry: thisKeywordToValidator.entrySet()) { String jsonKeyword = entry.getKey(); @@ -338,7 +320,7 @@ public static PathToSchemasMap validate( } } KeywordValidator validator = entry.getValue(); - @Nullable PathToSchemasMap otherPathToSchemas = validator.validate( + ValidationData data = new ValidationData( jsonSchema, arg, validationMetadata, @@ -346,6 +328,7 @@ public static PathToSchemasMap validate( patternPropertiesPathToSchemas, ifPathToSchemas ); + @Nullable PathToSchemasMap otherPathToSchemas = validator.validate(data); if (otherPathToSchemas == null) { continue; } @@ -401,10 +384,9 @@ protected List castToAllowedTypes(List arg, List pathToItem, Set argFixed = new LinkedHashMap<>(); for (Map.Entry entry: arg.entrySet()) { @Nullable Object entryKey = entry.getKey(); - if (!(entryKey instanceof String)) { + if (!(entryKey instanceof String key)) { throw new InvalidTypeException("Invalid non-string key value"); } - String key = (String) entryKey; Object val = entry.getValue(); List newPathToItem = new ArrayList<>(pathToItem); newPathToItem.add(key); diff --git a/samples/client/3_1_0_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/KeywordValidator.java b/samples/client/3_1_0_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/KeywordValidator.java index 41b4b85eb2e..8a2bd782505 100644 --- a/samples/client/3_1_0_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/KeywordValidator.java +++ b/samples/client/3_1_0_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/KeywordValidator.java @@ -3,37 +3,9 @@ import org.openapijsonschematools.client.exceptions.ValidationException; import org.checkerframework.checker.nullness.qual.Nullable; -import java.util.ArrayList; -import java.util.List; - +@FunctionalInterface public interface KeywordValidator { @Nullable PathToSchemasMap validate( - JsonSchema schema, - @Nullable Object arg, - ValidationMetadata validationMetadata, - @Nullable List containsPathToSchemas, - @Nullable PathToSchemasMap patternPropertiesPathToSchemas, - @Nullable PathToSchemasMap ifPathToSchemas + ValidationData data ) throws ValidationException; - - default List getContainsPathToSchemas( - @Nullable Object arg, - ValidationMetadata validationMetadata - ) { - return new ArrayList<>(); - } - - default PathToSchemasMap getPatternPropertiesPathToSchemas( - @Nullable Object arg, - ValidationMetadata validationMetadata - ) { - return new PathToSchemasMap(); - } - - default PathToSchemasMap getIfPathToSchemas( - @Nullable Object arg, - ValidationMetadata validationMetadata - ) { - return new PathToSchemasMap(); - } } \ No newline at end of file diff --git a/samples/client/3_1_0_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/MaxContainsValidator.java b/samples/client/3_1_0_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/MaxContainsValidator.java index 25482139fab..9e9b3b92c18 100644 --- a/samples/client/3_1_0_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/MaxContainsValidator.java +++ b/samples/client/3_1_0_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/MaxContainsValidator.java @@ -6,31 +6,25 @@ import java.util.List; public class MaxContainsValidator implements KeywordValidator { - public final int maxContains; - - public MaxContainsValidator(int maxContains) { - this.maxContains = maxContains; - } - @Override public @Nullable PathToSchemasMap validate( - JsonSchema schema, - @Nullable Object arg, - ValidationMetadata validationMetadata, - @Nullable List containsPathToSchemas, - @Nullable PathToSchemasMap patternPropertiesPathToSchemas, - @Nullable PathToSchemasMap ifPathToSchemas + ValidationData data ) { - if (!(arg instanceof List)) { + var maxContains = data.schema().maxContains; + if (maxContains == null) { + return null; + } + if (!(data.arg() instanceof List)) { return null; } + var containsPathToSchemas = data.containsPathToSchemas(); if (containsPathToSchemas == null) { return null; } if (containsPathToSchemas.size() > maxContains) { throw new ValidationException( - "Validation failed for maxContains keyword in class="+schema.getClass()+ - " at pathToItem="+validationMetadata.pathToItem()+". Too many items validated to the contains schema." + "Validation failed for maxContains keyword in class="+data.schema().getClass()+ + " at pathToItem="+data.validationMetadata().pathToItem()+". Too many items validated to the contains schema." ); } return null; diff --git a/samples/client/3_1_0_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/MaxItemsValidator.java b/samples/client/3_1_0_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/MaxItemsValidator.java index bda6fb43ece..98ed5cb4ff4 100644 --- a/samples/client/3_1_0_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/MaxItemsValidator.java +++ b/samples/client/3_1_0_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/MaxItemsValidator.java @@ -6,26 +6,19 @@ import java.util.List; public class MaxItemsValidator implements KeywordValidator { - public final int maxItems; - - public MaxItemsValidator(int maxItems) { - this.maxItems = maxItems; - } - @Override public @Nullable PathToSchemasMap validate( - JsonSchema schema, - @Nullable Object arg, - ValidationMetadata validationMetadata, - @Nullable List containsPathToSchemas, - @Nullable PathToSchemasMap patternPropertiesPathToSchemas, - @Nullable PathToSchemasMap ifPathToSchemas + ValidationData data ) { - if (!(arg instanceof List)) { + var maxItems = data.schema().maxItems; + if (maxItems == null) { + return null; + } + if (!(data.arg() instanceof List listArg)) { return null; } - if (((List) arg).size() > maxItems) { - throw new ValidationException("Value " + arg + " is invalid because has > the maxItems of " + maxItems); + if (listArg.size() > maxItems) { + throw new ValidationException("Value " + listArg + " is invalid because has > the maxItems of " + maxItems); } return null; } diff --git a/samples/client/3_1_0_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/MaxLengthValidator.java b/samples/client/3_1_0_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/MaxLengthValidator.java index 1a78623e0f4..08d91666c5d 100644 --- a/samples/client/3_1_0_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/MaxLengthValidator.java +++ b/samples/client/3_1_0_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/MaxLengthValidator.java @@ -3,30 +3,21 @@ import org.openapijsonschematools.client.exceptions.ValidationException; import org.checkerframework.checker.nullness.qual.Nullable; -import java.util.List; - public class MaxLengthValidator extends LengthValidator implements KeywordValidator { - public final int maxLength; - - public MaxLengthValidator(int maxLength) { - this.maxLength = maxLength; - } - @Override public @Nullable PathToSchemasMap validate( - JsonSchema schema, - @Nullable Object arg, - ValidationMetadata validationMetadata, - @Nullable List containsPathToSchemas, - @Nullable PathToSchemasMap patternPropertiesPathToSchemas, - @Nullable PathToSchemasMap ifPathToSchemas + ValidationData data ) { - if (!(arg instanceof String)) { + var maxLength = data.schema().maxLength; + if (maxLength == null) { + return null; + } + if (!(data.arg() instanceof String stringArg)) { return null; } - int length = getLength((String) arg); + int length = getLength(stringArg); if (length > maxLength) { - throw new ValidationException("Value " + arg + " is invalid because has > the maxLength of " + maxLength); + throw new ValidationException("Value " + stringArg + " is invalid because has > the maxLength of " + maxLength); } return null; } diff --git a/samples/client/3_1_0_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/MaxPropertiesValidator.java b/samples/client/3_1_0_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/MaxPropertiesValidator.java index 5928ec588ac..d117f1688e2 100644 --- a/samples/client/3_1_0_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/MaxPropertiesValidator.java +++ b/samples/client/3_1_0_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/MaxPropertiesValidator.java @@ -3,30 +3,22 @@ import org.openapijsonschematools.client.exceptions.ValidationException; import org.checkerframework.checker.nullness.qual.Nullable; -import java.util.List; import java.util.Map; public class MaxPropertiesValidator implements KeywordValidator { - public final int maxProperties; - - public MaxPropertiesValidator(int maxProperties) { - this.maxProperties = maxProperties; - } - @Override public @Nullable PathToSchemasMap validate( - JsonSchema schema, - @Nullable Object arg, - ValidationMetadata validationMetadata, - @Nullable List containsPathToSchemas, - @Nullable PathToSchemasMap patternPropertiesPathToSchemas, - @Nullable PathToSchemasMap ifPathToSchemas + ValidationData data ) { - if (!(arg instanceof Map)) { + var maxProperties = data.schema().maxProperties; + if (maxProperties == null) { + return null; + } + if (!(data.arg() instanceof Map mapArg)) { return null; } - if (((Map) arg).size() > maxProperties) { - throw new ValidationException("Value " + arg + " is invalid because has > the maxProperties of " + maxProperties); + if (mapArg.size() > maxProperties) { + throw new ValidationException("Value " + mapArg + " is invalid because has > the maxProperties of " + maxProperties); } return null; } diff --git a/samples/client/3_1_0_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/MaximumValidator.java b/samples/client/3_1_0_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/MaximumValidator.java index 25faceb4022..702f09686dc 100644 --- a/samples/client/3_1_0_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/MaximumValidator.java +++ b/samples/client/3_1_0_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/MaximumValidator.java @@ -3,52 +3,43 @@ import org.openapijsonschematools.client.exceptions.ValidationException; import org.checkerframework.checker.nullness.qual.Nullable; -import java.util.List; - public class MaximumValidator implements KeywordValidator { - public final Number maximum; - - public MaximumValidator(Number maximum) { - this.maximum = maximum; - } - @Override public @Nullable PathToSchemasMap validate( - JsonSchema schema, - @Nullable Object arg, - ValidationMetadata validationMetadata, - @Nullable List containsPathToSchemas, - @Nullable PathToSchemasMap patternPropertiesPathToSchemas, - @Nullable PathToSchemasMap ifPathToSchemas + ValidationData data ) { - if (!(arg instanceof Number)) { + var maximum = data.schema().maximum; + if (maximum == null) { + return null; + } + if (!(data.arg() instanceof Number)) { return null; } - String msg = "Value " + arg + " is invalid because it is > the maximum of " + maximum; - if (arg instanceof Integer) { - if (((Integer) arg).compareTo(maximum.intValue()) == 1) { + String msg = "Value " + data.arg() + " is invalid because it is > the maximum of " + maximum; + if (data.arg() instanceof Integer intArg) { + if (intArg.compareTo(maximum.intValue()) > 0) { throw new ValidationException(msg); } return null; } - if (arg instanceof Long) { - if (((Long) arg).compareTo(maximum.longValue()) == 1) { + if (data.arg() instanceof Long longArg) { + if (longArg.compareTo(maximum.longValue()) > 0) { throw new ValidationException(msg); } return null; } - if (arg instanceof Float) { - if (((Float) arg).compareTo(maximum.floatValue()) == 1) { + if (data.arg() instanceof Float floatArg) { + if (floatArg.compareTo(maximum.floatValue()) > 0) { throw new ValidationException(msg); } return null; } - if (arg instanceof Double) { - if (((Double) arg).compareTo(maximum.doubleValue()) == 1) { + if (data.arg() instanceof Double doubleArg) { + if (doubleArg.compareTo(maximum.doubleValue()) > 0) { throw new ValidationException(msg); } return null; } return null; } -} +} \ No newline at end of file diff --git a/samples/client/3_1_0_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/MinContainsValidator.java b/samples/client/3_1_0_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/MinContainsValidator.java index 2f34127155e..1827e95cc83 100644 --- a/samples/client/3_1_0_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/MinContainsValidator.java +++ b/samples/client/3_1_0_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/MinContainsValidator.java @@ -6,31 +6,24 @@ import java.util.List; public class MinContainsValidator implements KeywordValidator { - public final int minContains; - - public MinContainsValidator(int minContains) { - this.minContains = minContains; - } - @Override public @Nullable PathToSchemasMap validate( - JsonSchema schema, - @Nullable Object arg, - ValidationMetadata validationMetadata, - @Nullable List containsPathToSchemas, - @Nullable PathToSchemasMap patternPropertiesPathToSchemas, - @Nullable PathToSchemasMap ifPathToSchemas + ValidationData data ) { - if (!(arg instanceof List)) { + var minContains = data.schema().minContains; + if (minContains == null) { + return null; + } + if (!(data.arg() instanceof List)) { return null; } - if (containsPathToSchemas == null) { + if (data.containsPathToSchemas() == null) { return null; } - if (containsPathToSchemas.size() < minContains) { + if (data.containsPathToSchemas().size() < minContains) { throw new ValidationException( - "Validation failed for minContains keyword in class="+schema.getClass()+ - " at pathToItem="+validationMetadata.pathToItem()+". Too few items validated to the contains schema." + "Validation failed for minContains keyword in class="+data.schema().getClass()+ + " at pathToItem="+data.validationMetadata().pathToItem()+". Too few items validated to the contains schema." ); } return null; diff --git a/samples/client/3_1_0_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/MinItemsValidator.java b/samples/client/3_1_0_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/MinItemsValidator.java index 7c46cbe8f94..d1933ca7750 100644 --- a/samples/client/3_1_0_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/MinItemsValidator.java +++ b/samples/client/3_1_0_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/MinItemsValidator.java @@ -6,26 +6,19 @@ import java.util.List; public class MinItemsValidator implements KeywordValidator { - public final int minItems; - - public MinItemsValidator(int minItems) { - this.minItems = minItems; - } - @Override public @Nullable PathToSchemasMap validate( - JsonSchema schema, - @Nullable Object arg, - ValidationMetadata validationMetadata, - @Nullable List containsPathToSchemas, - @Nullable PathToSchemasMap patternPropertiesPathToSchemas, - @Nullable PathToSchemasMap ifPathToSchemas + ValidationData data ) { - if (!(arg instanceof List)) { + var minItems = data.schema().minItems; + if (minItems == null) { + return null; + } + if (!(data.arg() instanceof List listArg)) { return null; } - if (((List) arg).size() < minItems) { - throw new ValidationException("Value " + arg + " is invalid because has < the minItems of " + minItems); + if (listArg.size() < minItems) { + throw new ValidationException("Value " + listArg + " is invalid because has < the minItems of " + minItems); } return null; } diff --git a/samples/client/3_1_0_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/MinLengthValidator.java b/samples/client/3_1_0_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/MinLengthValidator.java index 7c92205a9cf..1defdc891e3 100644 --- a/samples/client/3_1_0_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/MinLengthValidator.java +++ b/samples/client/3_1_0_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/MinLengthValidator.java @@ -3,31 +3,22 @@ import org.openapijsonschematools.client.exceptions.ValidationException; import org.checkerframework.checker.nullness.qual.Nullable; -import java.util.List; - public class MinLengthValidator extends LengthValidator implements KeywordValidator { - public final int minLength; - - public MinLengthValidator(int minLength) { - this.minLength = minLength; - } - @Override public @Nullable PathToSchemasMap validate( - JsonSchema schema, - @Nullable Object arg, - ValidationMetadata validationMetadata, - @Nullable List containsPathToSchemas, - @Nullable PathToSchemasMap patternPropertiesPathToSchemas, - @Nullable PathToSchemasMap ifPathToSchemas + ValidationData data ) { - if (!(arg instanceof String)) { + var minLength = data.schema().minLength; + if (minLength == null) { + return null; + } + if (!(data.arg() instanceof String stringArg)) { return null; } - int length = getLength((String) arg); + int length = getLength(stringArg); if (length < minLength) { - throw new ValidationException("Value " + arg + " is invalid because has < the minLength of " + minLength); + throw new ValidationException("Value " + stringArg + " is invalid because has < the minLength of " + minLength); } return null; } -} +} \ No newline at end of file diff --git a/samples/client/3_1_0_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/MinPropertiesValidator.java b/samples/client/3_1_0_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/MinPropertiesValidator.java index c52b16000d8..c0b99e7fb7d 100644 --- a/samples/client/3_1_0_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/MinPropertiesValidator.java +++ b/samples/client/3_1_0_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/MinPropertiesValidator.java @@ -3,30 +3,22 @@ import org.openapijsonschematools.client.exceptions.ValidationException; import org.checkerframework.checker.nullness.qual.Nullable; -import java.util.List; import java.util.Map; public class MinPropertiesValidator implements KeywordValidator { - public final int minProperties; - - public MinPropertiesValidator(int minProperties) { - this.minProperties = minProperties; - } - @Override public @Nullable PathToSchemasMap validate( - JsonSchema schema, - @Nullable Object arg, - ValidationMetadata validationMetadata, - @Nullable List containsPathToSchemas, - @Nullable PathToSchemasMap patternPropertiesPathToSchemas, - @Nullable PathToSchemasMap ifPathToSchemas + ValidationData data ) { - if (!(arg instanceof Map)) { + var minProperties = data.schema().minProperties; + if (minProperties == null) { + return null; + } + if (!(data.arg() instanceof Map mapArg)) { return null; } - if (((Map) arg).size() < minProperties) { - throw new ValidationException("Value " + arg + " is invalid because has < the minProperties of " + minProperties); + if (mapArg.size() < minProperties) { + throw new ValidationException("Value " + mapArg + " is invalid because has < the minProperties of " + minProperties); } return null; } diff --git a/samples/client/3_1_0_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/MinimumValidator.java b/samples/client/3_1_0_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/MinimumValidator.java index dec192d47df..3b539120e42 100644 --- a/samples/client/3_1_0_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/MinimumValidator.java +++ b/samples/client/3_1_0_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/MinimumValidator.java @@ -3,48 +3,39 @@ import org.openapijsonschematools.client.exceptions.ValidationException; import org.checkerframework.checker.nullness.qual.Nullable; -import java.util.List; - public class MinimumValidator implements KeywordValidator { - public final Number minimum; - - public MinimumValidator(Number minimum) { - this.minimum = minimum; - } - @Override public @Nullable PathToSchemasMap validate( - JsonSchema schema, - @Nullable Object arg, - ValidationMetadata validationMetadata, - @Nullable List containsPathToSchemas, - @Nullable PathToSchemasMap patternPropertiesPathToSchemas, - @Nullable PathToSchemasMap ifPathToSchemas + ValidationData data ) { - if (!(arg instanceof Number)) { + var minimum = data.schema().minimum; + if (minimum == null) { + return null; + } + if (!(data.arg() instanceof Number)) { return null; } - String msg = "Value " + arg + " is invalid because it is < the minimum of " + minimum; - if (arg instanceof Integer) { - if (((Integer) arg).compareTo(minimum.intValue()) == -1) { + String msg = "Value " + data.arg() + " is invalid because it is < the minimum of " + minimum; + if (data.arg() instanceof Integer intArg) { + if (intArg.compareTo(minimum.intValue()) < 0) { throw new ValidationException(msg); } return null; } - if (arg instanceof Long) { - if (((Long) arg).compareTo(minimum.longValue()) == -1) { + if (data.arg() instanceof Long longArg) { + if (longArg.compareTo(minimum.longValue()) < 0) { throw new ValidationException(msg); } return null; } - if (arg instanceof Float) { - if (((Float) arg).compareTo(minimum.floatValue()) == -1) { + if (data.arg() instanceof Float floatArg) { + if (floatArg.compareTo(minimum.floatValue()) < 0) { throw new ValidationException(msg); } return null; } - if (arg instanceof Double) { - if (((Double) arg).compareTo(minimum.doubleValue()) == -1) { + if (data.arg() instanceof Double doubleArg) { + if (doubleArg.compareTo(minimum.doubleValue()) < 0) { throw new ValidationException(msg); } return null; diff --git a/samples/client/3_1_0_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/MultipleOfValidator.java b/samples/client/3_1_0_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/MultipleOfValidator.java index 15230b54275..eebc07a0f10 100644 --- a/samples/client/3_1_0_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/MultipleOfValidator.java +++ b/samples/client/3_1_0_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/MultipleOfValidator.java @@ -3,33 +3,25 @@ import org.openapijsonschematools.client.exceptions.ValidationException; import org.checkerframework.checker.nullness.qual.Nullable; -import java.util.List; import java.math.BigDecimal; public class MultipleOfValidator extends BigDecimalValidator implements KeywordValidator { - public final BigDecimal multipleOf; - - public MultipleOfValidator(BigDecimal multipleOf) { - this.multipleOf = multipleOf; - } - @Override public @Nullable PathToSchemasMap validate( - JsonSchema schema, - @Nullable Object arg, - ValidationMetadata validationMetadata, - @Nullable List containsPathToSchemas, - @Nullable PathToSchemasMap patternPropertiesPathToSchemas, - @Nullable PathToSchemasMap ifPathToSchemas + ValidationData data ) { - if (!(arg instanceof Number)) { + var multipleOf = data.schema().multipleOf; + if (multipleOf == null) { + return null; + } + if (!(data.arg() instanceof Number numberArg)) { return null; } - BigDecimal castArg = getBigDecimal((Number) arg); - String msg = "Value " + arg + " is invalid because it is not a multiple of " + multipleOf; + BigDecimal castArg = getBigDecimal(numberArg); + String msg = "Value " + numberArg + " is invalid because it is not a multiple of " + multipleOf; if (castArg.remainder(multipleOf).compareTo(BigDecimal.ZERO) != 0) { throw new ValidationException(msg); } return null; } -} +} \ No newline at end of file diff --git a/samples/client/3_1_0_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/NotValidator.java b/samples/client/3_1_0_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/NotValidator.java index 507c7f40fbc..aa61be1b624 100644 --- a/samples/client/3_1_0_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/NotValidator.java +++ b/samples/client/3_1_0_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/NotValidator.java @@ -3,39 +3,25 @@ import org.openapijsonschematools.client.exceptions.ValidationException; import org.checkerframework.checker.nullness.qual.Nullable; -import java.util.ArrayList; -import java.util.LinkedHashMap; -import java.util.LinkedHashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; - public class NotValidator implements KeywordValidator { - public final Class not; - - public NotValidator(Class not) { - this.not = not; - } - @Override public @Nullable PathToSchemasMap validate( - JsonSchema schema, - @Nullable Object arg, - ValidationMetadata validationMetadata, - @Nullable List containsPathToSchemas, - @Nullable PathToSchemasMap patternPropertiesPathToSchemas, - @Nullable PathToSchemasMap ifPathToSchemas + ValidationData data ) { + var not = data.schema().not; + if (not == null) { + return null; + } PathToSchemasMap pathToSchemas; try { JsonSchema notSchema = JsonSchemaFactory.getInstance(not); - pathToSchemas = JsonSchema.validate(notSchema, arg, validationMetadata); + pathToSchemas = JsonSchema.validate(notSchema, data.arg(), data.validationMetadata()); } catch (ValidationException e) { return null; } if (!pathToSchemas.isEmpty()) { throw new ValidationException( - "Invalid value "+arg+" was passed in to "+schema.getClass()+". "+ + "Invalid value "+data.arg()+" was passed in to "+data.schema().getClass()+". "+ "Value is invalid because it is disallowed by not "+not ); } diff --git a/samples/client/3_1_0_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/OneOfValidator.java b/samples/client/3_1_0_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/OneOfValidator.java index 5bc4bbd297b..f84f7796a8c 100644 --- a/samples/client/3_1_0_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/OneOfValidator.java +++ b/samples/client/3_1_0_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/OneOfValidator.java @@ -7,25 +7,18 @@ import java.util.List; public class OneOfValidator implements KeywordValidator { - public final List> oneOf; - - public OneOfValidator(List> oneOf) { - this.oneOf = oneOf; - } - @Override public @Nullable PathToSchemasMap validate( - JsonSchema schema, - @Nullable Object arg, - ValidationMetadata validationMetadata, - @Nullable List containsPathToSchemas, - @Nullable PathToSchemasMap patternPropertiesPathToSchemas, - @Nullable PathToSchemasMap ifPathToSchemas + ValidationData data ) { + var oneOf = data.schema().oneOf; + if (oneOf == null) { + return null; + } PathToSchemasMap pathToSchemas = new PathToSchemasMap(); List> validatedOneOfClasses = new ArrayList<>(); for(Class oneOfClass: oneOf) { - if (oneOfClass == schema.getClass()) { + if (oneOfClass == data.schema().getClass()) { /* optimistically assume that schema will pass validation do not invoke validate on it because that is recursive @@ -35,7 +28,7 @@ public OneOfValidator(List> oneOf) { } try { JsonSchema oneOfSchema = JsonSchemaFactory.getInstance(oneOfClass); - PathToSchemasMap otherPathToSchemas = JsonSchema.validate(oneOfSchema, arg, validationMetadata); + PathToSchemasMap otherPathToSchemas = JsonSchema.validate(oneOfSchema, data.arg(), data.validationMetadata()); validatedOneOfClasses.add(oneOfClass); pathToSchemas.update(otherPathToSchemas); } catch (ValidationException e) { @@ -43,12 +36,12 @@ public OneOfValidator(List> oneOf) { } } if (validatedOneOfClasses.isEmpty()) { - throw new ValidationException("Invalid inputs given to generate an instance of "+schema.getClass()+". None "+ + throw new ValidationException("Invalid inputs given to generate an instance of "+data.schema().getClass()+". None "+ "of the oneOf schemas matched the input data." ); } if (validatedOneOfClasses.size() > 1) { - throw new ValidationException("Invalid inputs given to generate an instance of "+schema.getClass()+". Multiple "+ + throw new ValidationException("Invalid inputs given to generate an instance of "+data.schema().getClass()+". Multiple "+ "oneOf schemas validated the data, but a max of one is allowed." ); } diff --git a/samples/client/3_1_0_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/PatternPropertiesValidator.java b/samples/client/3_1_0_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/PatternPropertiesValidator.java index 6104329139f..9e951e23ed2 100644 --- a/samples/client/3_1_0_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/PatternPropertiesValidator.java +++ b/samples/client/3_1_0_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/PatternPropertiesValidator.java @@ -1,68 +1,21 @@ package org.openapijsonschematools.client.schemas.validation; import org.checkerframework.checker.nullness.qual.Nullable; -import org.openapijsonschematools.client.exceptions.InvalidTypeException; -import java.util.ArrayList; -import java.util.List; import java.util.Map; -import java.util.regex.Pattern; public class PatternPropertiesValidator implements KeywordValidator { - public final Map> patternProperties; - - public PatternPropertiesValidator(Map> patternProperties) { - this.patternProperties = patternProperties; - } - @Override public @Nullable PathToSchemasMap validate( - JsonSchema schema, - @Nullable Object arg, - ValidationMetadata validationMetadata, - @Nullable List containsPathToSchemas, - @Nullable PathToSchemasMap patternPropertiesPathToSchemas, - @Nullable PathToSchemasMap ifPathToSchemas + ValidationData data ) { - if (!(arg instanceof Map)) { + var patternProperties = data.schema().patternProperties; + if (patternProperties == null) { return null; } - return patternPropertiesPathToSchemas; - } - - public PathToSchemasMap getPatternPropertiesPathToSchemas( - @Nullable Object arg, - ValidationMetadata validationMetadata - ) { - if (!(arg instanceof Map mapArg)) { - return new PathToSchemasMap(); - } - PathToSchemasMap pathToSchemas = new PathToSchemasMap(); - for (Map.Entry entry: mapArg.entrySet()) { - Object entryKey = entry.getKey(); - if (!(entryKey instanceof String key)) { - throw new InvalidTypeException("Invalid non-string type for map key"); - } - List propPathToItem = new ArrayList<>(validationMetadata.pathToItem()); - propPathToItem.add(key); - ValidationMetadata propValidationMetadata = new ValidationMetadata( - propPathToItem, - validationMetadata.configuration(), - validationMetadata.validatedPathToSchemas(), - validationMetadata.seenClasses() - ); - for (Map.Entry> patternPropEntry: patternProperties.entrySet()) { - if (!patternPropEntry.getKey().matcher(key).find()) { - continue; - } - - Class patternPropClass = patternPropEntry.getValue(); - JsonSchema patternPropSchema = JsonSchemaFactory.getInstance(patternPropClass); - PathToSchemasMap otherPathToSchemas = JsonSchema.validate(patternPropSchema, entry.getValue(), propValidationMetadata); - pathToSchemas.update(otherPathToSchemas); - } + if (!(data.arg() instanceof Map)) { + return null; } - return pathToSchemas; + return data.patternPropertiesPathToSchemas(); } } - diff --git a/samples/client/3_1_0_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/PatternValidator.java b/samples/client/3_1_0_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/PatternValidator.java index 37e7a545711..eceeb19e311 100644 --- a/samples/client/3_1_0_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/PatternValidator.java +++ b/samples/client/3_1_0_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/PatternValidator.java @@ -3,31 +3,21 @@ import org.openapijsonschematools.client.exceptions.ValidationException; import org.checkerframework.checker.nullness.qual.Nullable; -import java.util.List; -import java.util.regex.Pattern; - public class PatternValidator implements KeywordValidator { - public final Pattern pattern; - - public PatternValidator(Pattern pattern) { - this.pattern = pattern; - } - @Override public @Nullable PathToSchemasMap validate( - JsonSchema schema, - @Nullable Object arg, - ValidationMetadata validationMetadata, - @Nullable List containsPathToSchemas, - @Nullable PathToSchemasMap patternPropertiesPathToSchemas, - @Nullable PathToSchemasMap ifPathToSchemas + ValidationData data ) { - if (!(arg instanceof String)) { + var pattern = data.schema().pattern; + if (pattern == null) { + return null; + } + if (!(data.arg() instanceof String stringArg)) { return null; } - if (!pattern.matcher((String) arg).find()) { - throw new ValidationException("Invalid value "+arg+" did not find a match for pattern "+pattern); + if (!pattern.matcher(stringArg).find()) { + throw new ValidationException("Invalid value "+stringArg+" did not find a match for pattern "+pattern); } return null; } -} +} \ No newline at end of file diff --git a/samples/client/3_1_0_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/PrefixItemsValidator.java b/samples/client/3_1_0_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/PrefixItemsValidator.java index a8b2bda2a21..00e5b17607b 100644 --- a/samples/client/3_1_0_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/PrefixItemsValidator.java +++ b/samples/client/3_1_0_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/PrefixItemsValidator.java @@ -6,22 +6,15 @@ import java.util.List; public class PrefixItemsValidator implements KeywordValidator { - public final List> prefixItems; - - public PrefixItemsValidator(List> prefixItems) { - this.prefixItems = prefixItems; - } - @Override public @Nullable PathToSchemasMap validate( - JsonSchema schema, - @Nullable Object arg, - ValidationMetadata validationMetadata, - @Nullable List containsPathToSchemas, - @Nullable PathToSchemasMap patternPropertiesPathToSchemas, - @Nullable PathToSchemasMap ifPathToSchemas + ValidationData data ) { - if (!(arg instanceof List listArg)) { + var prefixItems = data.schema().prefixItems; + if (prefixItems == null) { + return null; + } + if (!(data.arg() instanceof List listArg)) { return null; } if (listArg.isEmpty()) { @@ -30,13 +23,13 @@ public PrefixItemsValidator(List> prefixItems) { PathToSchemasMap pathToSchemas = new PathToSchemasMap(); int maxIndex = Math.min(listArg.size(), prefixItems.size()); for (int i=0; i < maxIndex; i++) { - List itemPathToItem = new ArrayList<>(validationMetadata.pathToItem()); + List itemPathToItem = new ArrayList<>(data.validationMetadata().pathToItem()); itemPathToItem.add(i); ValidationMetadata itemValidationMetadata = new ValidationMetadata( itemPathToItem, - validationMetadata.configuration(), - validationMetadata.validatedPathToSchemas(), - validationMetadata.seenClasses() + data.validationMetadata().configuration(), + data.validationMetadata().validatedPathToSchemas(), + data.validationMetadata().seenClasses() ); JsonSchema itemsSchema = JsonSchemaFactory.getInstance(prefixItems.get(i)); PathToSchemasMap otherPathToSchemas = JsonSchema.validate(itemsSchema, listArg.get(i), itemValidationMetadata); diff --git a/samples/client/3_1_0_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/PropertiesValidator.java b/samples/client/3_1_0_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/PropertiesValidator.java index 9b7d50b28d8..17bccdd666a 100644 --- a/samples/client/3_1_0_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/PropertiesValidator.java +++ b/samples/client/3_1_0_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/PropertiesValidator.java @@ -9,22 +9,15 @@ import java.util.Set; public class PropertiesValidator implements KeywordValidator { - public final Map> properties; - - public PropertiesValidator(Map> properties) { - this.properties = properties; - } - @Override public @Nullable PathToSchemasMap validate( - JsonSchema schema, - @Nullable Object arg, - ValidationMetadata validationMetadata, - @Nullable List containsPathToSchemas, - @Nullable PathToSchemasMap patternPropertiesPathToSchemas, - @Nullable PathToSchemasMap ifPathToSchemas + ValidationData data ) { - if (!(arg instanceof Map mapArg)) { + var properties = data.schema().properties; + if (properties == null) { + return null; + } + if (!(data.arg() instanceof Map mapArg)) { return null; } PathToSchemasMap pathToSchemas = new PathToSchemasMap(); @@ -39,14 +32,14 @@ public PropertiesValidator(Map> properties) if (!presentProperties.contains(propName)) { continue; } - @Nullable Object propValue = ((Map) arg).get(propName); - List propPathToItem = new ArrayList<>(validationMetadata.pathToItem()); + @Nullable Object propValue = mapArg.get(propName); + List propPathToItem = new ArrayList<>(data.validationMetadata().pathToItem()); propPathToItem.add(propName); ValidationMetadata propValidationMetadata = new ValidationMetadata( propPathToItem, - validationMetadata.configuration(), - validationMetadata.validatedPathToSchemas(), - validationMetadata.seenClasses() + data.validationMetadata().configuration(), + data.validationMetadata().validatedPathToSchemas(), + data.validationMetadata().seenClasses() ); Class propClass = entry.getValue(); JsonSchema propSchema = JsonSchemaFactory.getInstance(propClass); @@ -60,4 +53,3 @@ public PropertiesValidator(Map> properties) return pathToSchemas; } } - diff --git a/samples/client/3_1_0_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/PropertyNamesValidator.java b/samples/client/3_1_0_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/PropertyNamesValidator.java index 5154911d484..55ea80b0382 100644 --- a/samples/client/3_1_0_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/PropertyNamesValidator.java +++ b/samples/client/3_1_0_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/PropertyNamesValidator.java @@ -7,34 +7,27 @@ import java.util.Map; public class PropertyNamesValidator implements KeywordValidator { - public final Class propertyNames; - - public PropertyNamesValidator(Class propertyNames) { - this.propertyNames = propertyNames; - } - @Override public @Nullable PathToSchemasMap validate( - JsonSchema schema, - @Nullable Object arg, - ValidationMetadata validationMetadata, - @Nullable List containsPathToSchemas, - @Nullable PathToSchemasMap patternPropertiesPathToSchemas, - @Nullable PathToSchemasMap ifPathToSchemas + ValidationData data ) { - if (!(arg instanceof Map)) { + var propertyNames = data.schema().propertyNames; + if (propertyNames == null) { + return null; + } + if (!(data.arg() instanceof Map mapArg)) { return null; } JsonSchema propertyNamesSchema = JsonSchemaFactory.getInstance(propertyNames); - for (Object objKey: ((Map) arg).keySet()) { + for (Object objKey: mapArg.keySet()) { if (objKey instanceof String key) { - List propPathToItem = new ArrayList<>(validationMetadata.pathToItem()); + List propPathToItem = new ArrayList<>(data.validationMetadata().pathToItem()); propPathToItem.add(key); ValidationMetadata keyValidationMetadata = new ValidationMetadata( propPathToItem, - validationMetadata.configuration(), - validationMetadata.validatedPathToSchemas(), - validationMetadata.seenClasses() + data.validationMetadata().configuration(), + data.validationMetadata().validatedPathToSchemas(), + data.validationMetadata().seenClasses() ); JsonSchema.validate(propertyNamesSchema, key, keyValidationMetadata); } diff --git a/samples/client/3_1_0_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/RequiredValidator.java b/samples/client/3_1_0_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/RequiredValidator.java index f68aef2b87a..f2e1a8ecde8 100644 --- a/samples/client/3_1_0_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/RequiredValidator.java +++ b/samples/client/3_1_0_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/RequiredValidator.java @@ -9,26 +9,19 @@ import java.util.Set; public class RequiredValidator implements KeywordValidator { - public final Set required; - - public RequiredValidator(Set required) { - this.required = required; - } - @Override public @Nullable PathToSchemasMap validate( - JsonSchema schema, - @Nullable Object arg, - ValidationMetadata validationMetadata, - @Nullable List containsPathToSchemas, - @Nullable PathToSchemasMap patternPropertiesPathToSchemas, - @Nullable PathToSchemasMap ifPathToSchemas + ValidationData data ) { - if (!(arg instanceof Map)) { + var required = data.schema().required; + if (required == null) { + return null; + } + if (!(data.arg() instanceof Map mapArg)) { return null; } Set missingRequiredProperties = new HashSet<>(required); - for (Object key: ((Map) arg).keySet()) { + for (Object key: mapArg.keySet()) { if (key instanceof String) { missingRequiredProperties.remove(key); } @@ -40,7 +33,7 @@ public RequiredValidator(Set required) { pluralChar = "s"; } throw new ValidationException( - schema.getClass()+" is missing "+missingRequiredProperties.size()+" required argument"+pluralChar+": "+missingReqProps + data.schema().getClass()+" is missing "+missingRequiredProperties.size()+" required argument"+pluralChar+": "+missingReqProps ); } return null; diff --git a/samples/client/3_1_0_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/TypeValidator.java b/samples/client/3_1_0_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/TypeValidator.java index f1fcd9d5cdd..bb4133a770e 100644 --- a/samples/client/3_1_0_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/TypeValidator.java +++ b/samples/client/3_1_0_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/TypeValidator.java @@ -5,25 +5,18 @@ import java.util.List; import java.util.Map; -import java.util.Set; public class TypeValidator implements KeywordValidator { - public final Set> type; - - public TypeValidator(Set> type) { - this.type = type; - } - @Override public @Nullable PathToSchemasMap validate( - JsonSchema schema, - @Nullable Object arg, - ValidationMetadata validationMetadata, - @Nullable List containsPathToSchemas, - @Nullable PathToSchemasMap patternPropertiesPathToSchemas, - @Nullable PathToSchemasMap ifPathToSchemas + ValidationData data ) { + var type = data.schema().type; + if (type == null) { + return null; + } Class argClass; + var arg = data.arg(); if (arg == null) { argClass = Void.class; } else if (arg instanceof List) { diff --git a/samples/client/3_1_0_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/UniqueItemsValidator.java b/samples/client/3_1_0_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/UniqueItemsValidator.java index 4cdbbe01060..a42a7d60b60 100644 --- a/samples/client/3_1_0_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/UniqueItemsValidator.java +++ b/samples/client/3_1_0_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/UniqueItemsValidator.java @@ -8,29 +8,22 @@ import java.util.Set; public class UniqueItemsValidator implements KeywordValidator { - public final boolean uniqueItems; - - public UniqueItemsValidator(boolean uniqueItems) { - this.uniqueItems = uniqueItems; - } - @Override public @Nullable PathToSchemasMap validate( - JsonSchema schema, - @Nullable Object arg, - ValidationMetadata validationMetadata, - @Nullable List containsPathToSchemas, - @Nullable PathToSchemasMap patternPropertiesPathToSchemas, - @Nullable PathToSchemasMap ifPathToSchemas + ValidationData data ) { - if (!(arg instanceof List)) { + var uniqueItems = data.schema().uniqueItems; + if (uniqueItems == null) { + return null; + } + if (!(data.arg() instanceof List listArg)) { return null; } if (!uniqueItems) { return null; } Set<@Nullable Object> seenItems = new HashSet<>(); - for (@Nullable Object item: (List) arg) { + for (@Nullable Object item: listArg) { int startingSeenItemsSize = seenItems.size(); seenItems.add(item); if (seenItems.size() == startingSeenItemsSize) { diff --git a/samples/client/3_1_0_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/ValidationData.java b/samples/client/3_1_0_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/ValidationData.java new file mode 100644 index 00000000000..55cb65fe9ef --- /dev/null +++ b/samples/client/3_1_0_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/ValidationData.java @@ -0,0 +1,22 @@ +package org.openapijsonschematools.client.schemas.validation; + +import org.checkerframework.checker.nullness.qual.Nullable; + +import java.util.List; + +public record ValidationData( + JsonSchema schema, + @Nullable Object arg, + ValidationMetadata validationMetadata, + @Nullable List containsPathToSchemas, + @Nullable PathToSchemasMap patternPropertiesPathToSchemas, + @Nullable PathToSchemasMap ifPathToSchemas +) { + public ValidationData( + JsonSchema schema, + @Nullable Object arg, + ValidationMetadata validationMetadata + ) { + this(schema, arg, validationMetadata, null, null, null); + } +} \ No newline at end of file diff --git a/samples/client/3_1_0_unit_test/java/src/test/java/org/openapijsonschematools/client/schemas/validation/AdditionalPropertiesValidatorTest.java b/samples/client/3_1_0_unit_test/java/src/test/java/org/openapijsonschematools/client/schemas/validation/AdditionalPropertiesValidatorTest.java index 7e6d7d09535..f98e0a7d529 100644 --- a/samples/client/3_1_0_unit_test/java/src/test/java/org/openapijsonschematools/client/schemas/validation/AdditionalPropertiesValidatorTest.java +++ b/samples/client/3_1_0_unit_test/java/src/test/java/org/openapijsonschematools/client/schemas/validation/AdditionalPropertiesValidatorTest.java @@ -26,6 +26,7 @@ private ObjectWithPropsSchema() { .properties(Map.ofEntries( new PropertyEntry("someString", StringJsonSchema.class) )) + .additionalProperties(StringJsonSchema.class) ); } @@ -73,14 +74,13 @@ public void testCorrectPropertySucceeds() { mutableMap.put("someString", "abc"); mutableMap.put("someAddProp", "def"); FrozenMap arg = new FrozenMap<>(mutableMap); - final AdditionalPropertiesValidator validator = new AdditionalPropertiesValidator(StringJsonSchema.class); + final AdditionalPropertiesValidator validator = new AdditionalPropertiesValidator(); PathToSchemasMap pathToSchemas = validator.validate( - ObjectWithPropsSchema.getInstance(), - arg, - validationMetadata, - new ArrayList<>(), - new PathToSchemasMap(), - new PathToSchemasMap() + new ValidationData( + ObjectWithPropsSchema.getInstance(), + arg, + validationMetadata + ) ); if (pathToSchemas == null) { throw new RuntimeException("Invalid null value for pathToSchemas for this test case"); @@ -105,14 +105,13 @@ public void testNotApplicableTypeReturnsNull() { new PathToSchemasMap(), new LinkedHashSet<>() ); - final AdditionalPropertiesValidator validator = new AdditionalPropertiesValidator(StringJsonSchema.class); + final AdditionalPropertiesValidator validator = new AdditionalPropertiesValidator(); PathToSchemasMap pathToSchemas = validator.validate( - MapJsonSchema.getInstance(), - 1, - validationMetadata, - new ArrayList<>(), - new PathToSchemasMap(), - new PathToSchemasMap() + new ValidationData( + MapJsonSchema.getInstance(), + 1, + validationMetadata + ) ); assertNull(pathToSchemas); } @@ -130,14 +129,13 @@ public void testIncorrectPropertyValueFails() { mutableMap.put("someString", "abc"); mutableMap.put("someAddProp", 1); FrozenMap arg = new FrozenMap<>(mutableMap); - final AdditionalPropertiesValidator validator = new AdditionalPropertiesValidator(StringJsonSchema.class); + final AdditionalPropertiesValidator validator = new AdditionalPropertiesValidator(); Assert.assertThrows(ValidationException.class, () -> validator.validate( - ObjectWithPropsSchema.getInstance(), - arg, - validationMetadata, - new ArrayList<>(), - new PathToSchemasMap(), - new PathToSchemasMap() + new ValidationData( + ObjectWithPropsSchema.getInstance(), + arg, + validationMetadata + ) )); } } \ No newline at end of file diff --git a/samples/client/3_1_0_unit_test/java/src/test/java/org/openapijsonschematools/client/schemas/validation/FormatValidatorTest.java b/samples/client/3_1_0_unit_test/java/src/test/java/org/openapijsonschematools/client/schemas/validation/FormatValidatorTest.java index 87a6bafc05f..db31df87dd9 100644 --- a/samples/client/3_1_0_unit_test/java/src/test/java/org/openapijsonschematools/client/schemas/validation/FormatValidatorTest.java +++ b/samples/client/3_1_0_unit_test/java/src/test/java/org/openapijsonschematools/client/schemas/validation/FormatValidatorTest.java @@ -6,8 +6,14 @@ import org.openapijsonschematools.client.configurations.JsonSchemaKeywordFlags; import org.openapijsonschematools.client.configurations.SchemaConfiguration; import org.openapijsonschematools.client.exceptions.ValidationException; -import org.openapijsonschematools.client.schemas.NumberJsonSchema; -import org.openapijsonschematools.client.schemas.StringJsonSchema; +import org.openapijsonschematools.client.schemas.IntJsonSchema; +import org.openapijsonschematools.client.schemas.Int32JsonSchema; +import org.openapijsonschematools.client.schemas.Int64JsonSchema; +import org.openapijsonschematools.client.schemas.FloatJsonSchema; +import org.openapijsonschematools.client.schemas.DoubleJsonSchema; +import org.openapijsonschematools.client.schemas.DecimalJsonSchema; +import org.openapijsonschematools.client.schemas.DateJsonSchema; +import org.openapijsonschematools.client.schemas.DateTimeJsonSchema; import java.math.BigDecimal; import java.math.BigInteger; @@ -29,354 +35,328 @@ private void assertNull(@Nullable Object object) { @Test public void testIntFormatSucceedsWithFloat() { - final FormatValidator validator = new FormatValidator("int"); + final FormatValidator validator = new FormatValidator(); PathToSchemasMap pathToSchemasMap = validator.validate( - NumberJsonSchema.getInstance(), - 1.0f, - validationMetadata, - new ArrayList<>(), - new PathToSchemasMap(), - new PathToSchemasMap() + new ValidationData( + IntJsonSchema.getInstance(), + 1.0f, + validationMetadata + ) ); assertNull(pathToSchemasMap); } @Test public void testIntFormatFailsWithFloat() { - final FormatValidator validator = new FormatValidator("int"); + final FormatValidator validator = new FormatValidator(); Assert.assertThrows(ValidationException.class, () -> validator.validate( - NumberJsonSchema.getInstance(), - 3.14f, - validationMetadata, - new ArrayList<>(), - new PathToSchemasMap(), - new PathToSchemasMap() + new ValidationData( + IntJsonSchema.getInstance(), + 3.14f, + validationMetadata + ) )); } @Test public void testIntFormatSucceedsWithInt() { - final FormatValidator validator = new FormatValidator("int"); + final FormatValidator validator = new FormatValidator(); PathToSchemasMap pathToSchemasMap = validator.validate( - NumberJsonSchema.getInstance(), - 1, - validationMetadata, - new ArrayList<>(), - new PathToSchemasMap(), - new PathToSchemasMap() + new ValidationData( + IntJsonSchema.getInstance(), + 1, + validationMetadata + ) ); assertNull(pathToSchemasMap); } @Test public void testInt32UnderMinFails() { - final FormatValidator validator = new FormatValidator("int32"); + final FormatValidator validator = new FormatValidator(); Assert.assertThrows(ValidationException.class, () -> validator.validate( - NumberJsonSchema.getInstance(), - -2147483649L, - validationMetadata, - new ArrayList<>(), - new PathToSchemasMap(), - new PathToSchemasMap() + new ValidationData( + Int32JsonSchema.getInstance(), + -2147483649L, + validationMetadata + ) )); } @Test public void testInt32InclusiveMinSucceeds() { - final FormatValidator validator = new FormatValidator("int32"); + final FormatValidator validator = new FormatValidator(); PathToSchemasMap pathToSchemasMap = validator.validate( - NumberJsonSchema.getInstance(), - -2147483648, - validationMetadata, - new ArrayList<>(), - new PathToSchemasMap(), - new PathToSchemasMap() + new ValidationData( + Int32JsonSchema.getInstance(), + -2147483648, + validationMetadata + ) ); assertNull(pathToSchemasMap); } @Test public void testInt32InclusiveMaxSucceeds() { - final FormatValidator validator = new FormatValidator("int32"); + final FormatValidator validator = new FormatValidator(); PathToSchemasMap pathToSchemasMap = validator.validate( - NumberJsonSchema.getInstance(), - 2147483647, - validationMetadata, - new ArrayList<>(), - new PathToSchemasMap(), - new PathToSchemasMap() + new ValidationData( + Int32JsonSchema.getInstance(), + 2147483647, + validationMetadata + ) ); assertNull(pathToSchemasMap); } @Test public void testInt32OverMaxFails() { - final FormatValidator validator = new FormatValidator("int32"); + final FormatValidator validator = new FormatValidator(); Assert.assertThrows(ValidationException.class, () -> validator.validate( - NumberJsonSchema.getInstance(), - 2147483648L, - validationMetadata, - new ArrayList<>(), - new PathToSchemasMap(), - new PathToSchemasMap() + new ValidationData( + Int32JsonSchema.getInstance(), + 2147483648L, + validationMetadata + ) )); } @Test public void testInt64UnderMinFails() { - final FormatValidator validator = new FormatValidator("int64"); + final FormatValidator validator = new FormatValidator(); Assert.assertThrows(ValidationException.class, () -> validator.validate( - NumberJsonSchema.getInstance(), - new BigInteger("-9223372036854775809"), - validationMetadata, - new ArrayList<>(), - new PathToSchemasMap(), - new PathToSchemasMap() + new ValidationData( + Int64JsonSchema.getInstance(), + new BigInteger("-9223372036854775809"), + validationMetadata + ) )); } @Test public void testInt64InclusiveMinSucceeds() { - final FormatValidator validator = new FormatValidator("int64"); + final FormatValidator validator = new FormatValidator(); PathToSchemasMap pathToSchemasMap = validator.validate( - NumberJsonSchema.getInstance(), - -9223372036854775808L, - validationMetadata, - new ArrayList<>(), - new PathToSchemasMap(), - new PathToSchemasMap() + new ValidationData( + Int64JsonSchema.getInstance(), + -9223372036854775808L, + validationMetadata + ) ); assertNull(pathToSchemasMap); } @Test public void testInt64InclusiveMaxSucceeds() { - final FormatValidator validator = new FormatValidator("int64"); + final FormatValidator validator = new FormatValidator(); PathToSchemasMap pathToSchemasMap = validator.validate( - NumberJsonSchema.getInstance(), - 9223372036854775807L, - validationMetadata, - new ArrayList<>(), - new PathToSchemasMap(), - new PathToSchemasMap() + new ValidationData( + Int64JsonSchema.getInstance(), + 9223372036854775807L, + validationMetadata + ) ); assertNull(pathToSchemasMap); } @Test public void testInt64OverMaxFails() { - final FormatValidator validator = new FormatValidator("int64"); + final FormatValidator validator = new FormatValidator(); Assert.assertThrows(ValidationException.class, () -> validator.validate( - NumberJsonSchema.getInstance(), - new BigInteger("9223372036854775808"), - validationMetadata, - new ArrayList<>(), - new PathToSchemasMap(), - new PathToSchemasMap() + new ValidationData( + Int64JsonSchema.getInstance(), + new BigInteger("9223372036854775808"), + validationMetadata + ) )); } @Test public void testFloatUnderMinFails() { - final FormatValidator validator = new FormatValidator("float"); + final FormatValidator validator = new FormatValidator(); Assert.assertThrows(ValidationException.class, () -> validator.validate( - NumberJsonSchema.getInstance(), - -3.402823466385289e+38d, - validationMetadata, - new ArrayList<>(), - new PathToSchemasMap(), - new PathToSchemasMap() + new ValidationData( + FloatJsonSchema.getInstance(), + -3.402823466385289e+38d, + validationMetadata + ) )); } @Test public void testFloatInclusiveMinSucceeds() { - final FormatValidator validator = new FormatValidator("float"); + final FormatValidator validator = new FormatValidator(); PathToSchemasMap pathToSchemasMap = validator.validate( - NumberJsonSchema.getInstance(), - -3.4028234663852886e+38f, - validationMetadata, - new ArrayList<>(), - new PathToSchemasMap(), - new PathToSchemasMap() + new ValidationData( + FloatJsonSchema.getInstance(), + -3.4028234663852886e+38f, + validationMetadata + ) ); assertNull(pathToSchemasMap); } @Test public void testFloatInclusiveMaxSucceeds() { - final FormatValidator validator = new FormatValidator("float"); + final FormatValidator validator = new FormatValidator(); PathToSchemasMap pathToSchemasMap = validator.validate( - NumberJsonSchema.getInstance(), - 3.4028234663852886e+38f, - validationMetadata, - new ArrayList<>(), - new PathToSchemasMap(), - new PathToSchemasMap() + new ValidationData( + FloatJsonSchema.getInstance(), + 3.4028234663852886e+38f, + validationMetadata + ) ); assertNull(pathToSchemasMap); } @Test public void testFloatOverMaxFails() { - final FormatValidator validator = new FormatValidator("float"); + final FormatValidator validator = new FormatValidator(); Assert.assertThrows(ValidationException.class, () -> validator.validate( - NumberJsonSchema.getInstance(), - 3.402823466385289e+38d, - validationMetadata, - new ArrayList<>(), - new PathToSchemasMap(), - new PathToSchemasMap() + new ValidationData( + FloatJsonSchema.getInstance(), + 3.402823466385289e+38d, + validationMetadata + ) )); } @Test public void testDoubleUnderMinFails() { - final FormatValidator validator = new FormatValidator("double"); + final FormatValidator validator = new FormatValidator(); Assert.assertThrows(ValidationException.class, () -> validator.validate( - NumberJsonSchema.getInstance(), - new BigDecimal("-1.7976931348623157082e+308"), - validationMetadata, - new ArrayList<>(), - new PathToSchemasMap(), - new PathToSchemasMap() + new ValidationData( + DoubleJsonSchema.getInstance(), + new BigDecimal("-1.7976931348623157082e+308"), + validationMetadata + ) )); } @Test public void testDoubleInclusiveMinSucceeds() { - final FormatValidator validator = new FormatValidator("double"); + final FormatValidator validator = new FormatValidator(); PathToSchemasMap pathToSchemasMap = validator.validate( - NumberJsonSchema.getInstance(), - -1.7976931348623157E+308d, - validationMetadata, - new ArrayList<>(), - new PathToSchemasMap(), - new PathToSchemasMap() + new ValidationData( + DoubleJsonSchema.getInstance(), + -1.7976931348623157E+308d, + validationMetadata + ) ); assertNull(pathToSchemasMap); } @Test public void testDoubleInclusiveMaxSucceeds() { - final FormatValidator validator = new FormatValidator("double"); + final FormatValidator validator = new FormatValidator(); PathToSchemasMap pathToSchemasMap = validator.validate( - NumberJsonSchema.getInstance(), - 1.7976931348623157E+308d, - validationMetadata, - new ArrayList<>(), - new PathToSchemasMap(), - new PathToSchemasMap() + new ValidationData( + DoubleJsonSchema.getInstance(), + 1.7976931348623157E+308d, + validationMetadata + ) ); assertNull(pathToSchemasMap); } @Test public void testDoubleOverMaxFails() { - final FormatValidator validator = new FormatValidator("double"); + final FormatValidator validator = new FormatValidator(); Assert.assertThrows(ValidationException.class, () -> validator.validate( - NumberJsonSchema.getInstance(), - new BigDecimal("1.7976931348623157082e+308"), - validationMetadata, - new ArrayList<>(), - new PathToSchemasMap(), - new PathToSchemasMap() + new ValidationData( + DoubleJsonSchema.getInstance(), + new BigDecimal("1.7976931348623157082e+308"), + validationMetadata + ) )); } @Test public void testInvalidNumberStringFails() { - final FormatValidator validator = new FormatValidator("number"); + final FormatValidator validator = new FormatValidator(); Assert.assertThrows(ValidationException.class, () -> validator.validate( - NumberJsonSchema.getInstance(), - "abc", - validationMetadata, - new ArrayList<>(), - new PathToSchemasMap(), - new PathToSchemasMap() + new ValidationData( + DecimalJsonSchema.getInstance(), + "abc", + validationMetadata + ) )); } @Test public void testValidFloatNumberStringSucceeds() { - final FormatValidator validator = new FormatValidator("number"); + final FormatValidator validator = new FormatValidator(); PathToSchemasMap pathToSchemasMap = validator.validate( - NumberJsonSchema.getInstance(), - "3.14", - validationMetadata, - new ArrayList<>(), - new PathToSchemasMap(), - new PathToSchemasMap() + new ValidationData( + DecimalJsonSchema.getInstance(), + "3.14", + validationMetadata + ) ); assertNull(pathToSchemasMap); } @Test public void testValidIntNumberStringSucceeds() { - final FormatValidator validator = new FormatValidator("number"); + final FormatValidator validator = new FormatValidator(); PathToSchemasMap pathToSchemasMap = validator.validate( - NumberJsonSchema.getInstance(), - "1", - validationMetadata, - new ArrayList<>(), - new PathToSchemasMap(), - new PathToSchemasMap() + new ValidationData( + DecimalJsonSchema.getInstance(), + "1", + validationMetadata + ) ); assertNull(pathToSchemasMap); } @Test public void testInvalidDateStringFails() { - final FormatValidator validator = new FormatValidator("date"); + final FormatValidator validator = new FormatValidator(); Assert.assertThrows(ValidationException.class, () -> validator.validate( - StringJsonSchema.getInstance(), - "abc", - validationMetadata, - new ArrayList<>(), - new PathToSchemasMap(), - new PathToSchemasMap() + new ValidationData( + DateJsonSchema.getInstance(), + "abc", + validationMetadata + ) )); } @Test public void testValidDateStringSucceeds() { - final FormatValidator validator = new FormatValidator("date"); + final FormatValidator validator = new FormatValidator(); PathToSchemasMap pathToSchemasMap = validator.validate( - StringJsonSchema.getInstance(), - "2017-01-20", - validationMetadata, - new ArrayList<>(), - new PathToSchemasMap(), - new PathToSchemasMap() + new ValidationData( + DateJsonSchema.getInstance(), + "2017-01-20", + validationMetadata + ) ); assertNull(pathToSchemasMap); } @Test public void testInvalidDateTimeStringFails() { - final FormatValidator validator = new FormatValidator("date-time"); + final FormatValidator validator = new FormatValidator(); Assert.assertThrows(ValidationException.class, () -> validator.validate( - StringJsonSchema.getInstance(), - "abc", - validationMetadata, - new ArrayList<>(), - new PathToSchemasMap(), - new PathToSchemasMap() + new ValidationData( + DateTimeJsonSchema.getInstance(), + "abc", + validationMetadata + ) )); } @Test public void testValidDateTimeStringSucceeds() { - final FormatValidator validator = new FormatValidator("date-time"); + final FormatValidator validator = new FormatValidator(); PathToSchemasMap pathToSchemasMap = validator.validate( - StringJsonSchema.getInstance(), - "2017-07-21T17:32:28Z", - validationMetadata, - new ArrayList<>(), - new PathToSchemasMap(), - new PathToSchemasMap() + new ValidationData( + DateTimeJsonSchema.getInstance(), + "2017-07-21T17:32:28Z", + validationMetadata + ) ); assertNull(pathToSchemasMap); } diff --git a/samples/client/3_1_0_unit_test/java/src/test/java/org/openapijsonschematools/client/schemas/validation/ItemsValidatorTest.java b/samples/client/3_1_0_unit_test/java/src/test/java/org/openapijsonschematools/client/schemas/validation/ItemsValidatorTest.java index f9c539091f3..b16a91e3919 100644 --- a/samples/client/3_1_0_unit_test/java/src/test/java/org/openapijsonschematools/client/schemas/validation/ItemsValidatorTest.java +++ b/samples/client/3_1_0_unit_test/java/src/test/java/org/openapijsonschematools/client/schemas/validation/ItemsValidatorTest.java @@ -5,14 +5,15 @@ import org.junit.Test; import org.openapijsonschematools.client.configurations.JsonSchemaKeywordFlags; import org.openapijsonschematools.client.configurations.SchemaConfiguration; -import org.openapijsonschematools.client.schemas.ListJsonSchema; import org.openapijsonschematools.client.schemas.StringJsonSchema; +import org.openapijsonschematools.client.exceptions.InvalidTypeException; import org.openapijsonschematools.client.exceptions.ValidationException; import java.util.ArrayList; import java.util.LinkedHashMap; import java.util.LinkedHashSet; import java.util.List; +import java.util.Set; public class ItemsValidatorTest { @SuppressWarnings("nullness") @@ -20,6 +21,31 @@ private void assertNull(@Nullable Object object) { Assert.assertNull(object); } + public static class ArrayWithItemsSchema extends JsonSchema { + public ArrayWithItemsSchema() { + super(new JsonSchemaInfo() + .type(Set.of(List.class)) + .items(StringJsonSchema.class) + ); + } + + @Override + public Object getNewInstance(@Nullable Object arg, List pathToItem, PathToSchemasMap pathToSchemas) { + if (arg instanceof List listArg) { + return getNewInstance(listArg, pathToItem, pathToSchemas); + } + throw new InvalidTypeException("Invalid input type="+getClass(arg)+". It can't be instantiated by this schema"); + } + + @Override + public @Nullable Object validate(@Nullable Object arg, SchemaConfiguration configuration) throws InvalidTypeException, ValidationException { + if (arg instanceof List listArg) { + return validate(listArg, configuration); + } + throw new InvalidTypeException("Invalid input type="+getClass(arg)+". It can't be validated by this schema"); + } + } + @Test public void testCorrectItemsSucceeds() { List pathToItem = List.of("args[0]"); @@ -32,14 +58,13 @@ public void testCorrectItemsSucceeds() { List mutableList = new ArrayList<>(); mutableList.add("a"); FrozenList arg = new FrozenList<>(mutableList); - final ItemsValidator validator = new ItemsValidator(StringJsonSchema.class); + final ItemsValidator validator = new ItemsValidator(); PathToSchemasMap pathToSchemas = validator.validate( - ListJsonSchema.getInstance(), - arg, - validationMetadata, - new ArrayList<>(), - new PathToSchemasMap(), - new PathToSchemasMap() + new ValidationData( + new ArrayWithItemsSchema(), + arg, + validationMetadata + ) ); if (pathToSchemas == null) { throw new RuntimeException("Invalid null value in pathToSchemas for this test case"); @@ -64,14 +89,13 @@ public void testNotApplicableTypeReturnsNull() { new PathToSchemasMap(), new LinkedHashSet<>() ); - final ItemsValidator validator = new ItemsValidator(StringJsonSchema.class); + final ItemsValidator validator = new ItemsValidator(); PathToSchemasMap pathToSchemas = validator.validate( - ListJsonSchema.getInstance(), - 1, - validationMetadata, - new ArrayList<>(), - new PathToSchemasMap(), - new PathToSchemasMap() + new ValidationData( + new ArrayWithItemsSchema(), + 1, + validationMetadata + ) ); assertNull(pathToSchemas); } @@ -88,14 +112,13 @@ public void testIncorrectItemFails() { List mutableList = new ArrayList<>(); mutableList.add(1); FrozenList arg = new FrozenList<>(mutableList); - final ItemsValidator validator = new ItemsValidator(StringJsonSchema.class); + final ItemsValidator validator = new ItemsValidator(); Assert.assertThrows(ValidationException.class, () -> validator.validate( - ListJsonSchema.getInstance(), - arg, - validationMetadata, - new ArrayList<>(), - new PathToSchemasMap(), - new PathToSchemasMap() + new ValidationData( + new ArrayWithItemsSchema(), + arg, + validationMetadata + ) )); } -} +} \ No newline at end of file diff --git a/samples/client/3_1_0_unit_test/java/src/test/java/org/openapijsonschematools/client/schemas/validation/PropertiesValidatorTest.java b/samples/client/3_1_0_unit_test/java/src/test/java/org/openapijsonschematools/client/schemas/validation/PropertiesValidatorTest.java index ea58d090f1f..9431d06708f 100644 --- a/samples/client/3_1_0_unit_test/java/src/test/java/org/openapijsonschematools/client/schemas/validation/PropertiesValidatorTest.java +++ b/samples/client/3_1_0_unit_test/java/src/test/java/org/openapijsonschematools/client/schemas/validation/PropertiesValidatorTest.java @@ -5,7 +5,7 @@ import org.junit.Test; import org.openapijsonschematools.client.configurations.JsonSchemaKeywordFlags; import org.openapijsonschematools.client.configurations.SchemaConfiguration; -import org.openapijsonschematools.client.schemas.MapJsonSchema; +import org.openapijsonschematools.client.exceptions.InvalidTypeException; import org.openapijsonschematools.client.schemas.StringJsonSchema; import org.openapijsonschematools.client.exceptions.ValidationException; @@ -14,8 +14,37 @@ import java.util.LinkedHashSet; import java.util.List; import java.util.Map; +import java.util.Set; public class PropertiesValidatorTest { + public static class ObjectWithPropsSchema extends JsonSchema { + private ObjectWithPropsSchema() { + super(new JsonSchemaInfo() + .type(Set.of(Map.class)) + .properties(Map.ofEntries( + new PropertyEntry("someString", StringJsonSchema.class) + )) + ); + + } + + @Override + public Object getNewInstance(@Nullable Object arg, List pathToItem, PathToSchemasMap pathToSchemas) { + if (arg instanceof Map mapArg) { + return getNewInstance(mapArg, pathToItem, pathToSchemas); + } + throw new InvalidTypeException("Invalid input type="+getClass(arg)+". It can't be instantiated by this schema"); + } + + @Override + public @Nullable Object validate(@Nullable Object arg, SchemaConfiguration configuration) throws InvalidTypeException, ValidationException { + if (arg instanceof Map mapArg) { + return validate(mapArg, configuration); + } + throw new InvalidTypeException("Invalid input type="+getClass(arg)+". It can't be validated by this schema"); + } + } + @SuppressWarnings("nullness") private void assertNull(@Nullable Object object) { Assert.assertNull(object); @@ -23,10 +52,7 @@ private void assertNull(@Nullable Object object) { @Test public void testCorrectPropertySucceeds() { - Map> properties = new LinkedHashMap<>(); - properties.put("someString", StringJsonSchema.class); - - final PropertiesValidator validator = new PropertiesValidator(properties); + final PropertiesValidator validator = new PropertiesValidator(); List pathToItem = List.of("args[0]"); ValidationMetadata validationMetadata = new ValidationMetadata( pathToItem, @@ -38,12 +64,11 @@ public void testCorrectPropertySucceeds() { mutableMap.put("someString", "abc"); FrozenMap arg = new FrozenMap<>(mutableMap); PathToSchemasMap pathToSchemas = validator.validate( - MapJsonSchema.getInstance(), - arg, - validationMetadata, - new ArrayList<>(), - new PathToSchemasMap(), - new PathToSchemasMap() + new ValidationData( + new ObjectWithPropsSchema(), + arg, + validationMetadata + ) ); if (pathToSchemas == null) { throw new RuntimeException("Invalid null value for pathToSchemas for this test case"); @@ -60,10 +85,7 @@ public void testCorrectPropertySucceeds() { @Test public void testNotApplicableTypeReturnsNull() { - Map> properties = new LinkedHashMap<>(); - properties.put("someString", StringJsonSchema.class); - - final PropertiesValidator validator = new PropertiesValidator(properties); + final PropertiesValidator validator = new PropertiesValidator(); List pathToItem = List.of("args[0]"); ValidationMetadata validationMetadata = new ValidationMetadata( pathToItem, @@ -72,22 +94,18 @@ public void testNotApplicableTypeReturnsNull() { new LinkedHashSet<>() ); PathToSchemasMap pathToSchemas = validator.validate( - MapJsonSchema.getInstance(), - 1, - validationMetadata, - new ArrayList<>(), - new PathToSchemasMap(), - new PathToSchemasMap() + new ValidationData( + new ObjectWithPropsSchema(), + 1, + validationMetadata + ) ); assertNull(pathToSchemas); } @Test public void testIncorrectPropertyValueFails() { - Map> properties = new LinkedHashMap<>(); - properties.put("someString", StringJsonSchema.class); - - final PropertiesValidator validator = new PropertiesValidator(properties); + final PropertiesValidator validator = new PropertiesValidator(); List pathToItem = List.of("args[0]"); ValidationMetadata validationMetadata = new ValidationMetadata( pathToItem, @@ -99,12 +117,11 @@ public void testIncorrectPropertyValueFails() { mutableMap.put("someString", 1); FrozenMap arg = new FrozenMap<>(mutableMap); Assert.assertThrows(ValidationException.class, () -> validator.validate( - MapJsonSchema.getInstance(), - arg, - validationMetadata, - new ArrayList<>(), - new PathToSchemasMap(), - new PathToSchemasMap() + new ValidationData( + new ObjectWithPropsSchema(), + arg, + validationMetadata + ) )); } } \ No newline at end of file diff --git a/samples/client/3_1_0_unit_test/java/src/test/java/org/openapijsonschematools/client/schemas/validation/RequiredValidatorTest.java b/samples/client/3_1_0_unit_test/java/src/test/java/org/openapijsonschematools/client/schemas/validation/RequiredValidatorTest.java index 2c26d7c7954..d2264b9a967 100644 --- a/samples/client/3_1_0_unit_test/java/src/test/java/org/openapijsonschematools/client/schemas/validation/RequiredValidatorTest.java +++ b/samples/client/3_1_0_unit_test/java/src/test/java/org/openapijsonschematools/client/schemas/validation/RequiredValidatorTest.java @@ -5,16 +5,42 @@ import org.junit.Test; import org.openapijsonschematools.client.configurations.JsonSchemaKeywordFlags; import org.openapijsonschematools.client.configurations.SchemaConfiguration; +import org.openapijsonschematools.client.exceptions.InvalidTypeException; import org.openapijsonschematools.client.exceptions.ValidationException; -import org.openapijsonschematools.client.schemas.MapJsonSchema; -import java.util.ArrayList; import java.util.LinkedHashMap; import java.util.LinkedHashSet; import java.util.List; +import java.util.Map; import java.util.Set; public class RequiredValidatorTest { + public static class ObjectWithRequiredSchema extends JsonSchema { + private ObjectWithRequiredSchema() { + super(new JsonSchemaInfo() + .type(Set.of(Map.class)) + .required(Set.of("someString")) + ); + + } + + @Override + public Object getNewInstance(@Nullable Object arg, List pathToItem, PathToSchemasMap pathToSchemas) { + if (arg instanceof Map mapArg) { + return getNewInstance(mapArg, pathToItem, pathToSchemas); + } + throw new InvalidTypeException("Invalid input type="+getClass(arg)+". It can't be instantiated by this schema"); + } + + @Override + public @Nullable Object validate(@Nullable Object arg, SchemaConfiguration configuration) throws InvalidTypeException, ValidationException { + if (arg instanceof Map mapArg) { + return validate(mapArg, configuration); + } + throw new InvalidTypeException("Invalid input type="+getClass(arg)+". It can't be validated by this schema"); + } + } + @SuppressWarnings("nullness") private void assertNull(@Nullable Object object) { Assert.assertNull(object); @@ -22,9 +48,6 @@ private void assertNull(@Nullable Object object) { @Test public void testCorrectPropertySucceeds() { - Set requiredProperties = new LinkedHashSet<>(); - requiredProperties.add("someString"); - List pathToItem = List.of("args[0]"); ValidationMetadata validationMetadata = new ValidationMetadata( pathToItem, @@ -35,23 +58,19 @@ public void testCorrectPropertySucceeds() { LinkedHashMap mutableMap = new LinkedHashMap<>(); mutableMap.put("someString", "abc"); FrozenMap arg = new FrozenMap<>(mutableMap); - final RequiredValidator validator = new RequiredValidator(requiredProperties); + final RequiredValidator validator = new RequiredValidator(); PathToSchemasMap pathToSchemas = validator.validate( - MapJsonSchema.getInstance(), - arg, - validationMetadata, - new ArrayList<>(), - new PathToSchemasMap(), - new PathToSchemasMap() + new ValidationData( + new ObjectWithRequiredSchema(), + arg, + validationMetadata + ) ); assertNull(pathToSchemas); } @Test public void testNotApplicableTypeReturnsNull() { - Set requiredProperties = new LinkedHashSet<>(); - requiredProperties.add("someString"); - List pathToItem = List.of("args[0]"); ValidationMetadata validationMetadata = new ValidationMetadata( pathToItem, @@ -59,23 +78,19 @@ public void testNotApplicableTypeReturnsNull() { new PathToSchemasMap(), new LinkedHashSet<>() ); - final RequiredValidator validator = new RequiredValidator(requiredProperties); + final RequiredValidator validator = new RequiredValidator(); PathToSchemasMap pathToSchemas = validator.validate( - MapJsonSchema.getInstance(), - 1, - validationMetadata, - new ArrayList<>(), - new PathToSchemasMap(), - new PathToSchemasMap() + new ValidationData( + new ObjectWithRequiredSchema(), + 1, + validationMetadata + ) ); assertNull(pathToSchemas); } @Test public void testIncorrectPropertyFails() { - Set requiredProperties = new LinkedHashSet<>(); - requiredProperties.add("someString"); - List pathToItem = List.of("args[0]"); ValidationMetadata validationMetadata = new ValidationMetadata( pathToItem, @@ -86,14 +101,13 @@ public void testIncorrectPropertyFails() { LinkedHashMap mutableMap = new LinkedHashMap<>(); mutableMap.put("aDifferentProp", 1); FrozenMap arg = new FrozenMap<>(mutableMap); - final RequiredValidator validator = new RequiredValidator(requiredProperties); + final RequiredValidator validator = new RequiredValidator(); Assert.assertThrows(ValidationException.class, () -> validator.validate( - MapJsonSchema.getInstance(), - arg, - validationMetadata, - new ArrayList<>(), - new PathToSchemasMap(), - new PathToSchemasMap() + new ValidationData( + new ObjectWithRequiredSchema(), + arg, + validationMetadata + ) )); } } \ No newline at end of file diff --git a/samples/client/3_1_0_unit_test/java/src/test/java/org/openapijsonschematools/client/schemas/validation/TypeValidatorTest.java b/samples/client/3_1_0_unit_test/java/src/test/java/org/openapijsonschematools/client/schemas/validation/TypeValidatorTest.java index 48433e51455..78a48b6374f 100644 --- a/samples/client/3_1_0_unit_test/java/src/test/java/org/openapijsonschematools/client/schemas/validation/TypeValidatorTest.java +++ b/samples/client/3_1_0_unit_test/java/src/test/java/org/openapijsonschematools/client/schemas/validation/TypeValidatorTest.java @@ -19,9 +19,7 @@ private void assertNull(@Nullable Object object) { @Test public void testValidateSucceeds() { - LinkedHashSet> type = new LinkedHashSet<>(); - type.add(String.class); - final TypeValidator validator = new TypeValidator(type); + final TypeValidator validator = new TypeValidator(); ValidationMetadata validationMetadata = new ValidationMetadata( new ArrayList<>(), new SchemaConfiguration(JsonSchemaKeywordFlags.ofNone()), @@ -29,21 +27,18 @@ public void testValidateSucceeds() { new LinkedHashSet<>() ); @Nullable PathToSchemasMap pathToSchemasMap = validator.validate( - StringJsonSchema.getInstance(), - "hi", - validationMetadata, - new ArrayList<>(), - new PathToSchemasMap(), - new PathToSchemasMap() + new ValidationData( + StringJsonSchema.getInstance(), + "hi", + validationMetadata + ) ); assertNull(pathToSchemasMap); } @Test public void testValidateFailsIntIsNotString() { - LinkedHashSet> type = new LinkedHashSet<>(); - type.add(String.class); - final TypeValidator validator = new TypeValidator(type); + final TypeValidator validator = new TypeValidator(); ValidationMetadata validationMetadata = new ValidationMetadata( new ArrayList<>(), new SchemaConfiguration(JsonSchemaKeywordFlags.ofNone()), @@ -51,12 +46,11 @@ public void testValidateFailsIntIsNotString() { new LinkedHashSet<>() ); Assert.assertThrows(ValidationException.class, () -> validator.validate( - StringJsonSchema.getInstance(), - 1, - validationMetadata, - new ArrayList<>(), - new PathToSchemasMap(), - new PathToSchemasMap() + new ValidationData( + StringJsonSchema.getInstance(), + 1, + validationMetadata + ) )); } } \ No newline at end of file diff --git a/samples/client/petstore/java/.openapi-generator/FILES b/samples/client/petstore/java/.openapi-generator/FILES index eaed21fc5cf..17d35aacbd5 100644 --- a/samples/client/petstore/java/.openapi-generator/FILES +++ b/samples/client/petstore/java/.openapi-generator/FILES @@ -749,6 +749,7 @@ src/main/java/org/openapijsonschematools/client/schemas/validation/StringValueMe src/main/java/org/openapijsonschematools/client/schemas/validation/TypeValidator.java src/main/java/org/openapijsonschematools/client/schemas/validation/UniqueItemsValidator.java src/main/java/org/openapijsonschematools/client/schemas/validation/UnsetAnyTypeJsonSchema.java +src/main/java/org/openapijsonschematools/client/schemas/validation/ValidationData.java src/main/java/org/openapijsonschematools/client/schemas/validation/ValidationMetadata.java src/main/java/org/openapijsonschematools/client/servers/Server0.java src/main/java/org/openapijsonschematools/client/servers/Server1.java diff --git a/samples/client/petstore/java/src/main/java/org/openapijsonschematools/client/schemas/validation/AdditionalPropertiesValidator.java b/samples/client/petstore/java/src/main/java/org/openapijsonschematools/client/schemas/validation/AdditionalPropertiesValidator.java index fd6fa6a4d29..2548452a115 100644 --- a/samples/client/petstore/java/src/main/java/org/openapijsonschematools/client/schemas/validation/AdditionalPropertiesValidator.java +++ b/samples/client/petstore/java/src/main/java/org/openapijsonschematools/client/schemas/validation/AdditionalPropertiesValidator.java @@ -8,22 +8,15 @@ import java.util.Set; public class AdditionalPropertiesValidator implements KeywordValidator { - public final Class additionalProperties; - - public AdditionalPropertiesValidator(Class additionalProperties) { - this.additionalProperties = additionalProperties; - } - @Override public @Nullable PathToSchemasMap validate( - JsonSchema schema, - @Nullable Object arg, - ValidationMetadata validationMetadata, - @Nullable List containsPathToSchemas, - @Nullable PathToSchemasMap patternPropertiesPathToSchemas, - @Nullable PathToSchemasMap ifPathToSchemas + ValidationData data ) { - if (!(arg instanceof Map mapArg)) { + if (!(data.arg() instanceof Map mapArg)) { + return null; + } + var additionalProperties = data.schema().additionalProperties; + if (additionalProperties == null) { return null; } Set presentAdditionalProperties = new LinkedHashSet<>(); @@ -32,22 +25,23 @@ public AdditionalPropertiesValidator(Class additionalPrope presentAdditionalProperties.add((String) key); } } - if (schema.properties != null) { - presentAdditionalProperties.removeAll(schema.properties.keySet()); + var properties = data.schema().properties; + if (properties != null) { + presentAdditionalProperties.removeAll(properties.keySet()); } PathToSchemasMap pathToSchemas = new PathToSchemasMap(); for(String addPropName: presentAdditionalProperties) { @Nullable Object propValue = mapArg.get(addPropName); - List propPathToItem = new ArrayList<>(validationMetadata.pathToItem()); + List propPathToItem = new ArrayList<>(data.validationMetadata().pathToItem()); propPathToItem.add(addPropName); - if (patternPropertiesPathToSchemas != null && patternPropertiesPathToSchemas.containsKey(propPathToItem)) { + if (data.patternPropertiesPathToSchemas() != null && data.patternPropertiesPathToSchemas().containsKey(propPathToItem)) { continue; } ValidationMetadata propValidationMetadata = new ValidationMetadata( propPathToItem, - validationMetadata.configuration(), - validationMetadata.validatedPathToSchemas(), - validationMetadata.seenClasses() + data.validationMetadata().configuration(), + data.validationMetadata().validatedPathToSchemas(), + data.validationMetadata().seenClasses() ); JsonSchema addPropsSchema = JsonSchemaFactory.getInstance(additionalProperties); if (propValidationMetadata.validationRanEarlier(addPropsSchema)) { diff --git a/samples/client/petstore/java/src/main/java/org/openapijsonschematools/client/schemas/validation/AllOfValidator.java b/samples/client/petstore/java/src/main/java/org/openapijsonschematools/client/schemas/validation/AllOfValidator.java index 313e2d97446..583017ea6b5 100644 --- a/samples/client/petstore/java/src/main/java/org/openapijsonschematools/client/schemas/validation/AllOfValidator.java +++ b/samples/client/petstore/java/src/main/java/org/openapijsonschematools/client/schemas/validation/AllOfValidator.java @@ -1,32 +1,21 @@ package org.openapijsonschematools.client.schemas.validation; import org.checkerframework.checker.nullness.qual.Nullable; -import java.util.List; - public class AllOfValidator implements KeywordValidator { - public final List> allOf; - - public AllOfValidator(List> allOf) { - this.allOf = allOf; - } - @Override public @Nullable PathToSchemasMap validate( - JsonSchema schema, - @Nullable Object arg, - ValidationMetadata validationMetadata, - @Nullable List containsPathToSchemas, - @Nullable PathToSchemasMap patternPropertiesPathToSchemas, - @Nullable PathToSchemasMap ifPathToSchemas + ValidationData data ) { + var allOf = data.schema().allOf; + if (allOf == null) { + return null; + } PathToSchemasMap pathToSchemas = new PathToSchemasMap(); for(Class allOfClass: allOf) { JsonSchema allOfSchema = JsonSchemaFactory.getInstance(allOfClass); - PathToSchemasMap otherPathToSchemas = JsonSchema.validate(allOfSchema, arg, validationMetadata); + PathToSchemasMap otherPathToSchemas = JsonSchema.validate(allOfSchema, data.arg(), data.validationMetadata()); pathToSchemas.update(otherPathToSchemas); } return pathToSchemas; } - - } diff --git a/samples/client/petstore/java/src/main/java/org/openapijsonschematools/client/schemas/validation/AnyOfValidator.java b/samples/client/petstore/java/src/main/java/org/openapijsonschematools/client/schemas/validation/AnyOfValidator.java index a4754dda464..062fa2eecdc 100644 --- a/samples/client/petstore/java/src/main/java/org/openapijsonschematools/client/schemas/validation/AnyOfValidator.java +++ b/samples/client/petstore/java/src/main/java/org/openapijsonschematools/client/schemas/validation/AnyOfValidator.java @@ -7,25 +7,18 @@ import java.util.List; public class AnyOfValidator implements KeywordValidator { - public final List> anyOf; - - public AnyOfValidator(List> anyOf) { - this.anyOf = anyOf; - } - @Override public @Nullable PathToSchemasMap validate( - JsonSchema schema, - @Nullable Object arg, - ValidationMetadata validationMetadata, - @Nullable List containsPathToSchemas, - @Nullable PathToSchemasMap patternPropertiesPathToSchemas, - @Nullable PathToSchemasMap ifPathToSchemas + ValidationData data ) { + var anyOf = data.schema().anyOf; + if (anyOf == null) { + return null; + } PathToSchemasMap pathToSchemas = new PathToSchemasMap(); List> validatedAnyOfClasses = new ArrayList<>(); for(Class anyOfClass: anyOf) { - if (anyOfClass == schema.getClass()) { + if (anyOfClass == data.schema().getClass()) { /* optimistically assume that schema will pass validation do not invoke _validate on it because that is recursive @@ -35,7 +28,7 @@ public AnyOfValidator(List> anyOf) { } try { JsonSchema anyOfSchema = JsonSchemaFactory.getInstance(anyOfClass); - PathToSchemasMap otherPathToSchemas = JsonSchema.validate(anyOfSchema, arg, validationMetadata); + PathToSchemasMap otherPathToSchemas = JsonSchema.validate(anyOfSchema, data.arg(), data.validationMetadata()); validatedAnyOfClasses.add(anyOfClass); pathToSchemas.update(otherPathToSchemas); } catch (ValidationException e) { @@ -43,7 +36,7 @@ public AnyOfValidator(List> anyOf) { } } if (validatedAnyOfClasses.isEmpty()) { - throw new ValidationException("Invalid inputs given to generate an instance of "+schema.getClass()+". None "+ + throw new ValidationException("Invalid inputs given to generate an instance of "+data.schema().getClass()+". None "+ "of the anyOf schemas matched the input data." ); } diff --git a/samples/client/petstore/java/src/main/java/org/openapijsonschematools/client/schemas/validation/ConstValidator.java b/samples/client/petstore/java/src/main/java/org/openapijsonschematools/client/schemas/validation/ConstValidator.java index f797c68ab2e..6409a23e5ca 100644 --- a/samples/client/petstore/java/src/main/java/org/openapijsonschematools/client/schemas/validation/ConstValidator.java +++ b/samples/client/petstore/java/src/main/java/org/openapijsonschematools/client/schemas/validation/ConstValidator.java @@ -4,27 +4,19 @@ import org.checkerframework.checker.nullness.qual.Nullable; import java.math.BigDecimal; -import java.util.List; import java.util.Objects; public class ConstValidator extends BigDecimalValidator implements KeywordValidator { - public final @Nullable Object constValue; - - public ConstValidator(@Nullable Object constValue) { - this.constValue = constValue; - } - @Override public @Nullable PathToSchemasMap validate( - JsonSchema schema, - @Nullable Object arg, - ValidationMetadata validationMetadata, - @Nullable List containsPathToSchemas, - @Nullable PathToSchemasMap patternPropertiesPathToSchemas, - @Nullable PathToSchemasMap ifPathToSchemas + ValidationData data ) { - if (arg instanceof Number) { - BigDecimal castArg = getBigDecimal((Number) arg); + if (!data.schema().constValueSet) { + return null; + } + var constValue = data.schema().constValue; + if (data.arg() instanceof Number numberArg) { + BigDecimal castArg = getBigDecimal(numberArg); if (Objects.equals(castArg, constValue)) { return null; } @@ -32,10 +24,10 @@ public ConstValidator(@Nullable Object constValue) { return null; } } else { - if (Objects.equals(arg, constValue)) { + if (Objects.equals(data.arg(), constValue)) { return null; } } - throw new ValidationException("Invalid value "+arg+" was not equal to const "+constValue); + throw new ValidationException("Invalid value "+data.arg()+" was not equal to const "+constValue); } -} +} \ No newline at end of file diff --git a/samples/client/petstore/java/src/main/java/org/openapijsonschematools/client/schemas/validation/ContainsValidator.java b/samples/client/petstore/java/src/main/java/org/openapijsonschematools/client/schemas/validation/ContainsValidator.java index deaa878d5af..fbfd1c9c700 100644 --- a/samples/client/petstore/java/src/main/java/org/openapijsonschematools/client/schemas/validation/ContainsValidator.java +++ b/samples/client/petstore/java/src/main/java/org/openapijsonschematools/client/schemas/validation/ContainsValidator.java @@ -3,32 +3,21 @@ import org.checkerframework.checker.nullness.qual.Nullable; import org.openapijsonschematools.client.exceptions.ValidationException; -import java.util.ArrayList; import java.util.List; public class ContainsValidator implements KeywordValidator { - public final Class contains; - - public ContainsValidator(Class contains) { - this.contains = contains; - } - @Override public @Nullable PathToSchemasMap validate( - JsonSchema schema, - @Nullable Object arg, - ValidationMetadata validationMetadata, - @Nullable List containsPathToSchemas, - @Nullable PathToSchemasMap patternPropertiesPathToSchemas, - @Nullable PathToSchemasMap ifPathToSchemas + ValidationData data ) { - if (!(arg instanceof List)) { + if (!(data.arg() instanceof List)) { return null; } + var containsPathToSchemas = data.containsPathToSchemas(); if (containsPathToSchemas == null || containsPathToSchemas.isEmpty()) { throw new ValidationException( - "Validation failed for contains keyword in class="+schema.getClass() - + " at pathToItem="+validationMetadata.pathToItem()+". No " + "Validation failed for contains keyword in class="+data.schema().getClass() + + " at pathToItem="+data.validationMetadata().pathToItem()+". No " + "items validated to the contains schema." ); } @@ -38,42 +27,4 @@ public ContainsValidator(Class contains) { } return pathToSchemas; } - - public List getContainsPathToSchemas( - @Nullable Object arg, - ValidationMetadata validationMetadata - ) { - if (!(arg instanceof List)) { - return new ArrayList<>(); - } - @Nullable List containsPathToSchemas = new ArrayList<>(); - int i = 0; - for(Object itemValue: (List) arg) { - PathToSchemasMap thesePathToSchemas = new PathToSchemasMap(); - List itemPathToItem = new ArrayList<>(validationMetadata.pathToItem()); - itemPathToItem.add(i); - ValidationMetadata itemValidationMetadata = new ValidationMetadata( - itemPathToItem, - validationMetadata.configuration(), - validationMetadata.validatedPathToSchemas(), - validationMetadata.seenClasses() - ); - JsonSchema containsSchema = JsonSchemaFactory.getInstance(contains); - if (itemValidationMetadata.validationRanEarlier(containsSchema)) { - // todo add_deeper_validated_schemas - containsPathToSchemas.add(thesePathToSchemas); - i += 1; - continue; - } - - try { - PathToSchemasMap otherPathToSchemas = JsonSchema.validate( - containsSchema, itemValue, itemValidationMetadata); - containsPathToSchemas.add(otherPathToSchemas); - } catch (ValidationException ignored) { - ; - } - } - return containsPathToSchemas; - } } \ No newline at end of file diff --git a/samples/client/petstore/java/src/main/java/org/openapijsonschematools/client/schemas/validation/DependentRequiredValidator.java b/samples/client/petstore/java/src/main/java/org/openapijsonschematools/client/schemas/validation/DependentRequiredValidator.java index a5e92887928..77b21ca801d 100644 --- a/samples/client/petstore/java/src/main/java/org/openapijsonschematools/client/schemas/validation/DependentRequiredValidator.java +++ b/samples/client/petstore/java/src/main/java/org/openapijsonschematools/client/schemas/validation/DependentRequiredValidator.java @@ -4,35 +4,27 @@ import org.openapijsonschematools.client.exceptions.ValidationException; import java.util.HashSet; -import java.util.List; import java.util.Map; import java.util.Set; public class DependentRequiredValidator implements KeywordValidator { - public final Map> dependentRequired; - - public DependentRequiredValidator(Map> dependentRequired) { - this.dependentRequired = dependentRequired; - } - @Override public @Nullable PathToSchemasMap validate( - JsonSchema schema, - @Nullable Object arg, - ValidationMetadata validationMetadata, - @Nullable List containsPathToSchemas, - @Nullable PathToSchemasMap patternPropertiesPathToSchemas, - @Nullable PathToSchemasMap ifPathToSchemas + ValidationData data ) { - if (!(arg instanceof Map)) { + if (!(data.arg() instanceof Map mapArg)) { + return null; + } + var dependentRequired = data.schema().dependentRequired; + if (dependentRequired == null) { return null; } for (Map.Entry> entry: dependentRequired.entrySet()) { - if (!((Map) arg).containsKey(entry.getKey())) { + if (!mapArg.containsKey(entry.getKey())) { continue; } Set missingKeys = new HashSet<>(entry.getValue()); - for (Object objKey: ((Map) arg).keySet()) { + for (Object objKey: mapArg.keySet()) { if (objKey instanceof String key) { missingKeys.remove(key); } @@ -42,7 +34,7 @@ public DependentRequiredValidator(Map> dependentRequired) { } throw new ValidationException( "Validation failed for dependentRequired because these_keys="+missingKeys+" are "+ - "missing at pathToItem="+validationMetadata.pathToItem()+" in class "+schema.getClass() + "missing at pathToItem="+data.validationMetadata().pathToItem()+" in class "+data.schema().getClass() ); } return null; 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 index 0ffa3b351ca..940157d3b48 100644 --- 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 @@ -2,29 +2,20 @@ 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, - @Nullable PathToSchemasMap patternPropertiesPathToSchemas, - @Nullable PathToSchemasMap ifPathToSchemas + ValidationData data ) { - if (!(arg instanceof Map mapArg)) { + if (!(data.arg() instanceof Map mapArg)) { + return null; + } + var dependentSchemas = data.schema().dependentSchemas; + if (dependentSchemas == null) { return null; } PathToSchemasMap pathToSchemas = new PathToSchemasMap(); @@ -41,10 +32,9 @@ public DependentSchemasValidator(Map> depend } Class dependentSchemaClass = entry.getValue(); JsonSchema dependentSchema = JsonSchemaFactory.getInstance(dependentSchemaClass); - PathToSchemasMap otherPathToSchemas = JsonSchema.validate(dependentSchema, arg, validationMetadata); + PathToSchemasMap otherPathToSchemas = JsonSchema.validate(dependentSchema, mapArg, data.validationMetadata()); pathToSchemas.update(otherPathToSchemas); } return pathToSchemas; } } - diff --git a/samples/client/petstore/java/src/main/java/org/openapijsonschematools/client/schemas/validation/EnumValidator.java b/samples/client/petstore/java/src/main/java/org/openapijsonschematools/client/schemas/validation/EnumValidator.java index 6cc9459e1a8..8af756619bd 100644 --- a/samples/client/petstore/java/src/main/java/org/openapijsonschematools/client/schemas/validation/EnumValidator.java +++ b/samples/client/petstore/java/src/main/java/org/openapijsonschematools/client/schemas/validation/EnumValidator.java @@ -4,36 +4,28 @@ import org.checkerframework.checker.nullness.qual.Nullable; import java.math.BigDecimal; -import java.util.List; import java.util.Set; public class EnumValidator extends BigDecimalValidator implements KeywordValidator { - public final Set<@Nullable Object> enumValues; - - public EnumValidator(Set<@Nullable Object> enumValues) { - this.enumValues = enumValues; - } - @SuppressWarnings("nullness") - private boolean enumContainsArg(@Nullable Object arg){ + private static boolean enumContainsArg(Set<@Nullable Object> enumValues, @Nullable Object arg){ return enumValues.contains(arg); } @Override public @Nullable PathToSchemasMap validate( - JsonSchema schema, - @Nullable Object arg, - ValidationMetadata validationMetadata, - @Nullable List containsPathToSchemas, - @Nullable PathToSchemasMap patternPropertiesPathToSchemas, - @Nullable PathToSchemasMap ifPathToSchemas + ValidationData data ) { + var enumValues = data.schema().enumValues; + if (enumValues == null) { + return null; + } if (enumValues.isEmpty()) { throw new ValidationException("No value can match enum because enum is empty"); } - if (arg instanceof Number) { - BigDecimal castArg = getBigDecimal((Number) arg); - if (enumContainsArg(castArg)) { + if (data.arg() instanceof Number numberArg) { + BigDecimal castArg = getBigDecimal(numberArg); + if (enumContainsArg(enumValues, castArg)) { return null; } for (Object enumValue: enumValues) { @@ -42,10 +34,10 @@ private boolean enumContainsArg(@Nullable Object arg){ } } } else { - if (enumContainsArg(arg)) { + if (enumContainsArg(enumValues, data.arg())) { return null; } } - throw new ValidationException("Invalid value "+arg+" was not one of the allowed enum "+enumValues); + throw new ValidationException("Invalid value "+data.arg()+" was not one of the allowed enum "+enumValues); } } diff --git a/samples/client/petstore/java/src/main/java/org/openapijsonschematools/client/schemas/validation/ExclusiveMaximumValidator.java b/samples/client/petstore/java/src/main/java/org/openapijsonschematools/client/schemas/validation/ExclusiveMaximumValidator.java index 432d5b0f4de..7d05ff65546 100644 --- a/samples/client/petstore/java/src/main/java/org/openapijsonschematools/client/schemas/validation/ExclusiveMaximumValidator.java +++ b/samples/client/petstore/java/src/main/java/org/openapijsonschematools/client/schemas/validation/ExclusiveMaximumValidator.java @@ -3,48 +3,39 @@ import org.openapijsonschematools.client.exceptions.ValidationException; import org.checkerframework.checker.nullness.qual.Nullable; -import java.util.List; - public class ExclusiveMaximumValidator implements KeywordValidator { - public final Number exclusiveMaximum; - - public ExclusiveMaximumValidator(Number exclusiveMaximum) { - this.exclusiveMaximum = exclusiveMaximum; - } - @Override public @Nullable PathToSchemasMap validate( - JsonSchema schema, - @Nullable Object arg, - ValidationMetadata validationMetadata, - @Nullable List containsPathToSchemas, - @Nullable PathToSchemasMap patternPropertiesPathToSchemas, - @Nullable PathToSchemasMap ifPathToSchemas + ValidationData data ) { - if (!(arg instanceof Number)) { + var exclusiveMaximum = data.schema().exclusiveMaximum; + if (exclusiveMaximum == null) { + return null; + } + if (!(data.arg() instanceof Number)) { return null; } - String msg = "Value " + arg + " is invalid because it is >= the exclusiveMaximum of " + exclusiveMaximum; - if (arg instanceof Integer) { - if (((Integer) arg).compareTo(exclusiveMaximum.intValue()) > -1) { + String msg = "Value " + data.arg() + " is invalid because it is >= the exclusiveMaximum of " + exclusiveMaximum; + if (data.arg() instanceof Integer intArg) { + if (intArg.compareTo(exclusiveMaximum.intValue()) > -1) { throw new ValidationException(msg); } return null; } - if (arg instanceof Long) { - if (((Long) arg).compareTo(exclusiveMaximum.longValue()) > -1) { + if (data.arg() instanceof Long longArg) { + if (longArg.compareTo(exclusiveMaximum.longValue()) > -1) { throw new ValidationException(msg); } return null; } - if (arg instanceof Float) { - if (((Float) arg).compareTo(exclusiveMaximum.floatValue()) > -1) { + if (data.arg() instanceof Float floatArg) { + if (floatArg.compareTo(exclusiveMaximum.floatValue()) > -1) { throw new ValidationException(msg); } return null; } - if (arg instanceof Double) { - if (((Double) arg).compareTo(exclusiveMaximum.doubleValue()) > -1) { + if (data.arg() instanceof Double doubleArg) { + if (doubleArg.compareTo(exclusiveMaximum.doubleValue()) > -1) { throw new ValidationException(msg); } return null; diff --git a/samples/client/petstore/java/src/main/java/org/openapijsonschematools/client/schemas/validation/ExclusiveMinimumValidator.java b/samples/client/petstore/java/src/main/java/org/openapijsonschematools/client/schemas/validation/ExclusiveMinimumValidator.java index d60c96f8325..73eb1e547c3 100644 --- a/samples/client/petstore/java/src/main/java/org/openapijsonschematools/client/schemas/validation/ExclusiveMinimumValidator.java +++ b/samples/client/petstore/java/src/main/java/org/openapijsonschematools/client/schemas/validation/ExclusiveMinimumValidator.java @@ -3,48 +3,39 @@ import org.openapijsonschematools.client.exceptions.ValidationException; import org.checkerframework.checker.nullness.qual.Nullable; -import java.util.List; - public class ExclusiveMinimumValidator implements KeywordValidator { - public final Number exclusiveMinimum; - - public ExclusiveMinimumValidator(Number exclusiveMinimum) { - this.exclusiveMinimum = exclusiveMinimum; - } - @Override public @Nullable PathToSchemasMap validate( - JsonSchema schema, - @Nullable Object arg, - ValidationMetadata validationMetadata, - @Nullable List containsPathToSchemas, - @Nullable PathToSchemasMap patternPropertiesPathToSchemas, - @Nullable PathToSchemasMap ifPathToSchemas + ValidationData data ) { - if (!(arg instanceof Number)) { + var exclusiveMinimum = data.schema().exclusiveMinimum; + if (exclusiveMinimum == null) { + return null; + } + if (!(data.arg() instanceof Number)) { return null; } - String msg = "Value " + arg + " is invalid because it is <= the exclusiveMinimum of " + exclusiveMinimum; - if (arg instanceof Integer) { - if (((Integer) arg).compareTo(exclusiveMinimum.intValue()) < 1) { + String msg = "Value " + data.arg() + " is invalid because it is <= the exclusiveMinimum of " + exclusiveMinimum; + if (data.arg() instanceof Integer intArg) { + if (intArg.compareTo(exclusiveMinimum.intValue()) < 1) { throw new ValidationException(msg); } return null; } - if (arg instanceof Long) { - if (((Long) arg).compareTo(exclusiveMinimum.longValue()) < 1) { + if (data.arg() instanceof Long longArg) { + if (longArg.compareTo(exclusiveMinimum.longValue()) < 1) { throw new ValidationException(msg); } return null; } - if (arg instanceof Float) { - if (((Float) arg).compareTo(exclusiveMinimum.floatValue()) < 1) { + if (data.arg() instanceof Float floatArg) { + if (floatArg.compareTo(exclusiveMinimum.floatValue()) < 1) { throw new ValidationException(msg); } return null; } - if (arg instanceof Double) { - if (((Double) arg).compareTo(exclusiveMinimum.doubleValue()) < 1) { + if (data.arg() instanceof Double doubleArg) { + if (doubleArg.compareTo(exclusiveMinimum.doubleValue()) < 1) { throw new ValidationException(msg); } return null; diff --git a/samples/client/petstore/java/src/main/java/org/openapijsonschematools/client/schemas/validation/FormatValidator.java b/samples/client/petstore/java/src/main/java/org/openapijsonschematools/client/schemas/validation/FormatValidator.java index d782f2ce4a2..c1ca45e44f3 100644 --- a/samples/client/petstore/java/src/main/java/org/openapijsonschematools/client/schemas/validation/FormatValidator.java +++ b/samples/client/petstore/java/src/main/java/org/openapijsonschematools/client/schemas/validation/FormatValidator.java @@ -6,16 +6,9 @@ import java.math.BigDecimal; import java.math.BigInteger; import java.time.format.DateTimeParseException; -import java.util.List; import java.util.UUID; public class FormatValidator implements KeywordValidator { - public final String format; - - public FormatValidator(String format) { - this.format = format; - } - private final static BigInteger int32InclusiveMinimum = BigInteger.valueOf(-2147483648L); private final static BigInteger int32InclusiveMaximum = BigInteger.valueOf(2147483647L); private final static BigInteger int64InclusiveMinimum = BigInteger.valueOf(-9223372036854775808L); @@ -25,12 +18,12 @@ public FormatValidator(String format) { private final static BigDecimal doubleInclusiveMinimum = BigDecimal.valueOf(-1.7976931348623157E+308d); private final static BigDecimal doubleInclusiveMaximum = BigDecimal.valueOf(1.7976931348623157E+308d); - private Void validateNumericFormat(Number arg, ValidationMetadata validationMetadata) { + private static void validateNumericFormat(Number arg, ValidationMetadata validationMetadata, String format) { if (format.startsWith("int")) { // there is a json schema test where 1.0 validates as an integer BigInteger intArg; if (arg instanceof Float || arg instanceof Double) { - Double doubleArg; + double doubleArg; if (arg instanceof Float) { doubleArg = arg.doubleValue(); } else { @@ -60,20 +53,17 @@ private Void validateNumericFormat(Number arg, ValidationMetadata validationMeta "Invalid value " + arg + " for format int32 at " + validationMetadata.pathToItem() ); } - return null; } else if (format.equals("int64")) { if (intArg.compareTo(int64InclusiveMinimum) < 0 || intArg.compareTo(int64InclusiveMaximum) > 0) { throw new ValidationException( "Invalid value " + arg + " for format int64 at " + validationMetadata.pathToItem() ); } - return null; } - return null; } else if (format.equals("float") || format.equals("double")) { BigDecimal decimalArg; if (arg instanceof Float) { - decimalArg = new BigDecimal((Float) arg); + decimalArg = BigDecimal.valueOf(arg.doubleValue()); } else if (arg instanceof Double) { decimalArg = BigDecimal.valueOf((Double) arg); } else { @@ -85,83 +75,81 @@ private Void validateNumericFormat(Number arg, ValidationMetadata validationMeta "Invalid value "+arg+" for format float at "+validationMetadata.pathToItem() ); } - return null; - } else if (format.equals("double")) { + } else { if (decimalArg.compareTo(doubleInclusiveMinimum) < 0 || decimalArg.compareTo(doubleInclusiveMaximum) > 0 ){ throw new ValidationException( "Invalid value "+arg+" for format double at "+validationMetadata.pathToItem() ); } - return null; } } - return null; } - private Void validateStringFormat(String arg, ValidationMetadata validationMetadata) { - if (format.equals("uuid")) { - try { - UUID.fromString(arg); - } catch (IllegalArgumentException e) { - throw new ValidationException( - "Value cannot be converted to a UUID. Invalid value "+ - arg+" for format uuid at "+validationMetadata.pathToItem() - ); + private static void validateStringFormat(String arg, ValidationMetadata validationMetadata, String format) { + switch (format) { + case "uuid" -> { + try { + UUID.fromString(arg); + } catch (IllegalArgumentException e) { + throw new ValidationException( + "Value cannot be converted to a UUID. Invalid value " + + arg + " for format uuid at " + validationMetadata.pathToItem() + ); + } } - return null; - } else if (format.equals("number")) { - try { - new BigDecimal(arg); - } catch (NumberFormatException e) { - throw new ValidationException( - "Value cannot be converted to a decimal. Invalid value "+ - arg+" for format number at "+validationMetadata.pathToItem() - ); + case "number" -> { + try { + new BigDecimal(arg); + } catch (NumberFormatException e) { + throw new ValidationException( + "Value cannot be converted to a decimal. Invalid value " + + arg + " for format number at " + validationMetadata.pathToItem() + ); + } } - return null; - } else if (format.equals("date")) { - try { - new CustomIsoparser().parseIsodate(arg); - } catch (DateTimeParseException e) { - throw new ValidationException( - "Value does not conform to the required ISO-8601 date format. "+ - "Invalid value "+arg+" for format date at "+validationMetadata.pathToItem() - ); + case "date" -> { + try { + new CustomIsoparser().parseIsodate(arg); + } catch (DateTimeParseException e) { + throw new ValidationException( + "Value does not conform to the required ISO-8601 date format. " + + "Invalid value " + arg + " for format date at " + validationMetadata.pathToItem() + ); + } } - return null; - } else if (format.equals("date-time")) { - try { - new CustomIsoparser().parseIsodatetime(arg); - } catch (DateTimeParseException e) { - throw new ValidationException( - "Value does not conform to the required ISO-8601 datetime format. "+ - "Invalid value "+arg+" for format datetime at "+validationMetadata.pathToItem() - ); + case "date-time" -> { + try { + new CustomIsoparser().parseIsodatetime(arg); + } catch (DateTimeParseException e) { + throw new ValidationException( + "Value does not conform to the required ISO-8601 datetime format. " + + "Invalid value " + arg + " for format datetime at " + validationMetadata.pathToItem() + ); + } } - return null; } - return null; } @Override public @Nullable PathToSchemasMap validate( - JsonSchema schema, - @Nullable Object arg, - ValidationMetadata validationMetadata, - @Nullable List containsPathToSchemas, - @Nullable PathToSchemasMap patternPropertiesPathToSchemas, - @Nullable PathToSchemasMap ifPathToSchemas + ValidationData data ) { - if (arg instanceof Number) { + var format = data.schema().format; + if (format == null) { + return null; + } + if (data.arg() instanceof Number numberArg) { validateNumericFormat( - (Number) arg, - validationMetadata + numberArg, + data.validationMetadata(), + format ); return null; - } else if (arg instanceof String) { + } else if (data.arg() instanceof String stringArg) { validateStringFormat( - (String) arg, - validationMetadata + stringArg, + data.validationMetadata(), + format ); return null; } diff --git a/samples/client/petstore/java/src/main/java/org/openapijsonschematools/client/schemas/validation/IfValidator.java b/samples/client/petstore/java/src/main/java/org/openapijsonschematools/client/schemas/validation/IfValidator.java index e1634bd1b00..b145ab8007a 100644 --- a/samples/client/petstore/java/src/main/java/org/openapijsonschematools/client/schemas/validation/IfValidator.java +++ b/samples/client/petstore/java/src/main/java/org/openapijsonschematools/client/schemas/validation/IfValidator.java @@ -1,33 +1,18 @@ package org.openapijsonschematools.client.schemas.validation; import org.openapijsonschematools.client.exceptions.ValidationException; -import org.openapijsonschematools.client.exceptions.InvalidTypeException; import org.checkerframework.checker.nullness.qual.Nullable; -import java.util.ArrayList; -import java.util.LinkedHashMap; -import java.util.LinkedHashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; - public class IfValidator implements KeywordValidator { - public final Class ifSchema; - - public IfValidator(Class ifSchema) { - this.ifSchema = ifSchema; - } - @Override public @Nullable PathToSchemasMap validate( - JsonSchema schema, - @Nullable Object arg, - ValidationMetadata validationMetadata, - @Nullable List containsPathToSchemas, - @Nullable PathToSchemasMap patternPropertiesPathToSchemas, - @Nullable PathToSchemasMap ifPathToSchemas + ValidationData data ) { - if (ifPathToSchemas == null) { + var ifSchema = data.schema().ifSchema; + if (ifSchema == null) { + return null; + } + if (data.ifPathToSchemas() == null) { throw new ValidationException("Invalid type for ifPathToSchemas"); } /* @@ -40,17 +25,4 @@ public IfValidator(Class ifSchema) { */ return null; } - - public PathToSchemasMap getIfPathToSchemas( - @Nullable Object arg, - ValidationMetadata validationMetadata - ) { - JsonSchema ifSchemaInstance = JsonSchemaFactory.getInstance(ifSchema); - PathToSchemasMap pathToSchemas = new PathToSchemasMap(); - try { - var otherPathToSchemas = JsonSchema.validate(ifSchemaInstance, arg, validationMetadata); - pathToSchemas.update(otherPathToSchemas); - } catch (ValidationException | InvalidTypeException ignored) {} - return pathToSchemas; - } } diff --git a/samples/client/petstore/java/src/main/java/org/openapijsonschematools/client/schemas/validation/ItemsValidator.java b/samples/client/petstore/java/src/main/java/org/openapijsonschematools/client/schemas/validation/ItemsValidator.java index 5d146ab250c..5bd194d47a9 100644 --- a/samples/client/petstore/java/src/main/java/org/openapijsonschematools/client/schemas/validation/ItemsValidator.java +++ b/samples/client/petstore/java/src/main/java/org/openapijsonschematools/client/schemas/validation/ItemsValidator.java @@ -6,38 +6,31 @@ import java.util.List; public class ItemsValidator implements KeywordValidator { - public final Class items; - - public ItemsValidator(Class items) { - this.items = items; - } - @Override public @Nullable PathToSchemasMap validate( - JsonSchema schema, - @Nullable Object arg, - ValidationMetadata validationMetadata, - @Nullable List containsPathToSchemas, - @Nullable PathToSchemasMap patternPropertiesPathToSchemas, - @Nullable PathToSchemasMap ifPathToSchemas + ValidationData data ) { - if (!(arg instanceof List listArg)) { + var items = data.schema().items; + if (items == null) { + return null; + } + if (!(data.arg() instanceof List listArg)) { return null; } if (listArg.isEmpty()) { return null; } PathToSchemasMap pathToSchemas = new PathToSchemasMap(); - int minIndex = schema.prefixItems != null ? schema.prefixItems.size() : 0; + int minIndex = data.schema().prefixItems != null ? data.schema().prefixItems.size() : 0; JsonSchema itemsSchema = JsonSchemaFactory.getInstance(items); for(int i = minIndex; i < listArg.size(); i++) { - List itemPathToItem = new ArrayList<>(validationMetadata.pathToItem()); + List itemPathToItem = new ArrayList<>(data.validationMetadata().pathToItem()); itemPathToItem.add(i); ValidationMetadata itemValidationMetadata = new ValidationMetadata( itemPathToItem, - validationMetadata.configuration(), - validationMetadata.validatedPathToSchemas(), - validationMetadata.seenClasses() + data.validationMetadata().configuration(), + data.validationMetadata().validatedPathToSchemas(), + data.validationMetadata().seenClasses() ); if (itemValidationMetadata.validationRanEarlier(itemsSchema)) { // todo add_deeper_validated_schemas 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 551c586665c..db33a080218 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 @@ -50,10 +50,10 @@ public abstract class JsonSchema { public final @Nullable Integer maxContains; public final @Nullable Integer minContains; public final @Nullable Class propertyNames; - public @Nullable Map> dependentRequired; + public final @Nullable Map> dependentRequired; public final @Nullable Map> dependentSchemas; - public @Nullable Map> patternProperties; - public @Nullable List> prefixItems; + public final @Nullable Map> patternProperties; + public final @Nullable List> prefixItems; public final @Nullable Class ifSchema; private final LinkedHashMap keywordToValidator; @@ -61,244 +61,142 @@ protected JsonSchema(JsonSchemaInfo jsonSchemaInfo) { LinkedHashMap keywordToValidator = new LinkedHashMap<>(); this.type = jsonSchemaInfo.type; if (this.type != null) { - keywordToValidator.put( - "type", - new TypeValidator(this.type) - ); + keywordToValidator.put("type", new TypeValidator()); } this.format = jsonSchemaInfo.format; if (this.format != null) { - keywordToValidator.put( - "format", - new FormatValidator(this.format) - ); + keywordToValidator.put("format", new FormatValidator()); } this.items = jsonSchemaInfo.items; if (this.items != null) { - keywordToValidator.put( - "items", - new ItemsValidator(this.items) - ); + keywordToValidator.put("items", new ItemsValidator()); } this.properties = jsonSchemaInfo.properties; if (this.properties != null) { - keywordToValidator.put( - "properties", - new PropertiesValidator(this.properties) - ); + keywordToValidator.put("properties", new PropertiesValidator()); } this.required = jsonSchemaInfo.required; if (this.required != null) { - keywordToValidator.put( - "required", - new RequiredValidator(this.required) - ); + keywordToValidator.put("required", new RequiredValidator()); } this.exclusiveMaximum = jsonSchemaInfo.exclusiveMaximum; if (this.exclusiveMaximum != null) { - keywordToValidator.put( - "exclusiveMaximum", - new ExclusiveMaximumValidator(this.exclusiveMaximum) - ); + keywordToValidator.put("exclusiveMaximum", new ExclusiveMaximumValidator()); } this.exclusiveMinimum = jsonSchemaInfo.exclusiveMinimum; if (this.exclusiveMinimum != null) { - keywordToValidator.put( - "exclusiveMinimum", - new ExclusiveMinimumValidator(this.exclusiveMinimum) - ); + keywordToValidator.put("exclusiveMinimum", new ExclusiveMinimumValidator()); } this.maxItems = jsonSchemaInfo.maxItems; if (this.maxItems != null) { - keywordToValidator.put( - "maxItems", - new MaxItemsValidator(this.maxItems) - ); + keywordToValidator.put("maxItems", new MaxItemsValidator()); } this.minItems = jsonSchemaInfo.minItems; if (this.minItems != null) { - keywordToValidator.put( - "minItems", - new MinItemsValidator(this.minItems) - ); + keywordToValidator.put("minItems", new MinItemsValidator()); } this.maxLength = jsonSchemaInfo.maxLength; if (this.maxLength != null) { - keywordToValidator.put( - "maxLength", - new MaxLengthValidator(this.maxLength) - ); + keywordToValidator.put("maxLength", new MaxLengthValidator()); } this.minLength = jsonSchemaInfo.minLength; if (this.minLength != null) { - keywordToValidator.put( - "minLength", - new MinLengthValidator(this.minLength) - ); + keywordToValidator.put("minLength", new MinLengthValidator()); } this.maxProperties = jsonSchemaInfo.maxProperties; if (this.maxProperties != null) { - keywordToValidator.put( - "maxProperties", - new MaxPropertiesValidator(this.maxProperties) - ); + keywordToValidator.put("maxProperties", new MaxPropertiesValidator()); } this.minProperties = jsonSchemaInfo.minProperties; if (this.minProperties != null) { - keywordToValidator.put( - "minProperties", - new MinPropertiesValidator(this.minProperties) - ); + keywordToValidator.put("minProperties", new MinPropertiesValidator()); } this.maximum = jsonSchemaInfo.maximum; if (this.maximum != null) { - keywordToValidator.put( - "maximum", - new MaximumValidator(this.maximum) - ); + keywordToValidator.put("maximum", new MaximumValidator()); } this.minimum = jsonSchemaInfo.minimum; if (this.minimum != null) { - keywordToValidator.put( - "minimum", - new MinimumValidator(this.minimum) - ); + keywordToValidator.put("minimum", new MinimumValidator()); } this.multipleOf = jsonSchemaInfo.multipleOf; if (this.multipleOf != null) { - keywordToValidator.put( - "multipleOf", - new MultipleOfValidator(this.multipleOf) - ); + keywordToValidator.put("multipleOf", new MultipleOfValidator()); } this.additionalProperties = jsonSchemaInfo.additionalProperties; if (this.additionalProperties != null) { - keywordToValidator.put( - "additionalProperties", - new AdditionalPropertiesValidator(this.additionalProperties) - ); + keywordToValidator.put("additionalProperties", new AdditionalPropertiesValidator()); } this.allOf = jsonSchemaInfo.allOf; if (this.allOf != null) { - keywordToValidator.put( - "allOf", - new AllOfValidator(this.allOf) - ); + keywordToValidator.put("allOf", new AllOfValidator()); } this.anyOf = jsonSchemaInfo.anyOf; if (this.anyOf != null) { - keywordToValidator.put( - "anyOf", - new AnyOfValidator(this.anyOf) - ); + keywordToValidator.put("anyOf", new AnyOfValidator()); } this.oneOf = jsonSchemaInfo.oneOf; if (this.oneOf != null) { - keywordToValidator.put( - "oneOf", - new OneOfValidator(this.oneOf) - ); + keywordToValidator.put("oneOf", new OneOfValidator()); } this.not = jsonSchemaInfo.not; if (this.not != null) { - keywordToValidator.put( - "not", - new NotValidator(this.not) - ); + keywordToValidator.put("not", new NotValidator()); } this.uniqueItems = jsonSchemaInfo.uniqueItems; if (this.uniqueItems != null) { - keywordToValidator.put( - "uniqueItems", - new UniqueItemsValidator(this.uniqueItems) - ); + keywordToValidator.put("uniqueItems", new UniqueItemsValidator()); } this.enumValues = jsonSchemaInfo.enumValues; if (this.enumValues != null) { - keywordToValidator.put( - "enum", - new EnumValidator(this.enumValues) - ); + keywordToValidator.put("enum", new EnumValidator()); } this.pattern = jsonSchemaInfo.pattern; if (this.pattern != null) { - keywordToValidator.put( - "pattern", - new PatternValidator(this.pattern) - ); + keywordToValidator.put("pattern", new PatternValidator()); } this.defaultValue = jsonSchemaInfo.defaultValue; this.defaultValueSet = jsonSchemaInfo.defaultValueSet; this.constValue = jsonSchemaInfo.constValue; this.constValueSet = jsonSchemaInfo.constValueSet; if (this.constValueSet) { - keywordToValidator.put( - "const", - new ConstValidator(this.constValue) - ); + keywordToValidator.put("const", new ConstValidator()); } this.contains = jsonSchemaInfo.contains; if (this.contains != null) { - keywordToValidator.put( - "contains", - new ContainsValidator(this.contains) - ); + keywordToValidator.put("contains", new ContainsValidator()); } this.maxContains = jsonSchemaInfo.maxContains; if (this.maxContains != null) { - keywordToValidator.put( - "maxContains", - new MaxContainsValidator(this.maxContains) - ); + keywordToValidator.put("maxContains", new MaxContainsValidator()); } this.minContains = jsonSchemaInfo.minContains; if (this.minContains != null) { - keywordToValidator.put( - "minContains", - new MinContainsValidator(this.minContains) - ); + keywordToValidator.put("minContains", new MinContainsValidator()); } this.propertyNames = jsonSchemaInfo.propertyNames; if (this.propertyNames != null) { - keywordToValidator.put( - "propertyNames", - new PropertyNamesValidator(this.propertyNames) - ); + keywordToValidator.put("propertyNames", new PropertyNamesValidator()); } this.dependentRequired = jsonSchemaInfo.dependentRequired; if (this.dependentRequired != null) { - keywordToValidator.put( - "dependentRequired", - new DependentRequiredValidator(this.dependentRequired) - ); + keywordToValidator.put("dependentRequired", new DependentRequiredValidator()); } this.dependentSchemas = jsonSchemaInfo.dependentSchemas; if (this.dependentSchemas != null) { - keywordToValidator.put( - "dependentSchemas", - new DependentSchemasValidator(this.dependentSchemas) - ); + keywordToValidator.put("dependentSchemas", new DependentSchemasValidator()); } this.patternProperties = jsonSchemaInfo.patternProperties; if (this.patternProperties != null) { - keywordToValidator.put( - "patternProperties", - new PatternPropertiesValidator(this.patternProperties) - ); + keywordToValidator.put("patternProperties", new PatternPropertiesValidator()); } this.prefixItems = jsonSchemaInfo.prefixItems; if (this.prefixItems != null) { - keywordToValidator.put( - "prefixItems", - new PrefixItemsValidator(this.prefixItems) - ); + keywordToValidator.put("prefixItems", new PrefixItemsValidator()); } this.ifSchema = jsonSchemaInfo.ifSchema; if (this.ifSchema != null) { - keywordToValidator.put( - "if", - new IfValidator(this.ifSchema) - ); + keywordToValidator.put("if", new IfValidator()); } this.keywordToValidator = keywordToValidator; } @@ -306,6 +204,93 @@ protected JsonSchema(JsonSchemaInfo jsonSchemaInfo) { public abstract @Nullable Object getNewInstance(@Nullable Object arg, List pathToItem, PathToSchemasMap pathToSchemas) throws InvalidTypeException; public abstract @Nullable Object validate(@Nullable Object arg, SchemaConfiguration configuration) throws InvalidTypeException, ValidationException; + private List getContainsPathToSchemas( + @Nullable Object arg, + ValidationMetadata validationMetadata + ) { + if (!(arg instanceof List listArg) || contains == null) { + return new ArrayList<>(); + } + JsonSchema containsSchema = JsonSchemaFactory.getInstance(contains); + @Nullable List containsPathToSchemas = new ArrayList<>(); + int i = 0; + for(Object itemValue: listArg) { + PathToSchemasMap thesePathToSchemas = new PathToSchemasMap(); + List itemPathToItem = new ArrayList<>(validationMetadata.pathToItem()); + itemPathToItem.add(i); + ValidationMetadata itemValidationMetadata = new ValidationMetadata( + itemPathToItem, + validationMetadata.configuration(), + validationMetadata.validatedPathToSchemas(), + validationMetadata.seenClasses() + ); + if (itemValidationMetadata.validationRanEarlier(containsSchema)) { + // todo add_deeper_validated_schemas + containsPathToSchemas.add(thesePathToSchemas); + i += 1; + continue; + } + + try { + PathToSchemasMap otherPathToSchemas = JsonSchema.validate( + containsSchema, itemValue, itemValidationMetadata); + containsPathToSchemas.add(otherPathToSchemas); + } catch (ValidationException ignored) {} + } + return containsPathToSchemas; + } + + private PathToSchemasMap getPatternPropertiesPathToSchemas( + @Nullable Object arg, + ValidationMetadata validationMetadata + ) { + if (!(arg instanceof Map mapArg) || patternProperties == null) { + return new PathToSchemasMap(); + } + PathToSchemasMap pathToSchemas = new PathToSchemasMap(); + for (Map.Entry entry: mapArg.entrySet()) { + Object entryKey = entry.getKey(); + if (!(entryKey instanceof String key)) { + throw new InvalidTypeException("Invalid non-string type for map key"); + } + List propPathToItem = new ArrayList<>(validationMetadata.pathToItem()); + propPathToItem.add(key); + ValidationMetadata propValidationMetadata = new ValidationMetadata( + propPathToItem, + validationMetadata.configuration(), + validationMetadata.validatedPathToSchemas(), + validationMetadata.seenClasses() + ); + for (Map.Entry> patternPropEntry: patternProperties.entrySet()) { + if (!patternPropEntry.getKey().matcher(key).find()) { + continue; + } + + Class patternPropClass = patternPropEntry.getValue(); + JsonSchema patternPropSchema = JsonSchemaFactory.getInstance(patternPropClass); + PathToSchemasMap otherPathToSchemas = JsonSchema.validate(patternPropSchema, entry.getValue(), propValidationMetadata); + pathToSchemas.update(otherPathToSchemas); + } + } + return pathToSchemas; + } + + private PathToSchemasMap getIfPathToSchemas( + @Nullable Object arg, + ValidationMetadata validationMetadata + ) { + if (ifSchema == null) { + return new PathToSchemasMap(); + } + JsonSchema ifSchemaInstance = JsonSchemaFactory.getInstance(ifSchema); + PathToSchemasMap pathToSchemas = new PathToSchemasMap(); + try { + var otherPathToSchemas = JsonSchema.validate(ifSchemaInstance, arg, validationMetadata); + pathToSchemas.update(otherPathToSchemas); + } catch (ValidationException | InvalidTypeException ignored) {} + return pathToSchemas; + } + public static PathToSchemasMap validate( JsonSchema jsonSchema, @Nullable Object arg, @@ -315,19 +300,16 @@ public static PathToSchemasMap validate( PathToSchemasMap pathToSchemas = new PathToSchemasMap(); LinkedHashMap thisKeywordToValidator = jsonSchema.keywordToValidator; @Nullable List containsPathToSchemas = null; - KeywordValidator containsValidator = thisKeywordToValidator.get("contains"); - if (containsValidator != null) { - containsPathToSchemas = containsValidator.getContainsPathToSchemas(arg, validationMetadata); + if (thisKeywordToValidator.containsKey("contains")) { + containsPathToSchemas = jsonSchema.getContainsPathToSchemas(arg, validationMetadata); } @Nullable PathToSchemasMap patternPropertiesPathToSchemas = null; - KeywordValidator patternPropertiesValidator = thisKeywordToValidator.get("patternProperties"); - if (patternPropertiesValidator != null) { - patternPropertiesPathToSchemas = patternPropertiesValidator.getPatternPropertiesPathToSchemas(arg, validationMetadata); + if (thisKeywordToValidator.containsKey("patternProperties")) { + patternPropertiesPathToSchemas = jsonSchema.getPatternPropertiesPathToSchemas(arg, validationMetadata); } @Nullable PathToSchemasMap ifPathToSchemas = null; - KeywordValidator ifValidator = thisKeywordToValidator.get("if"); - if (ifValidator != null) { - ifPathToSchemas = ifValidator.getIfPathToSchemas(arg, validationMetadata); + if (thisKeywordToValidator.containsKey("if")) { + ifPathToSchemas = jsonSchema.getIfPathToSchemas(arg, validationMetadata); } for (Map.Entry entry: thisKeywordToValidator.entrySet()) { String jsonKeyword = entry.getKey(); @@ -338,7 +320,7 @@ public static PathToSchemasMap validate( } } KeywordValidator validator = entry.getValue(); - @Nullable PathToSchemasMap otherPathToSchemas = validator.validate( + ValidationData data = new ValidationData( jsonSchema, arg, validationMetadata, @@ -346,6 +328,7 @@ public static PathToSchemasMap validate( patternPropertiesPathToSchemas, ifPathToSchemas ); + @Nullable PathToSchemasMap otherPathToSchemas = validator.validate(data); if (otherPathToSchemas == null) { continue; } @@ -401,10 +384,9 @@ protected List castToAllowedTypes(List arg, List pathToItem, Set argFixed = new LinkedHashMap<>(); for (Map.Entry entry: arg.entrySet()) { @Nullable Object entryKey = entry.getKey(); - if (!(entryKey instanceof String)) { + if (!(entryKey instanceof String key)) { throw new InvalidTypeException("Invalid non-string key value"); } - String key = (String) entryKey; Object val = entry.getValue(); List newPathToItem = new ArrayList<>(pathToItem); newPathToItem.add(key); diff --git a/samples/client/petstore/java/src/main/java/org/openapijsonschematools/client/schemas/validation/KeywordValidator.java b/samples/client/petstore/java/src/main/java/org/openapijsonschematools/client/schemas/validation/KeywordValidator.java index 41b4b85eb2e..8a2bd782505 100644 --- a/samples/client/petstore/java/src/main/java/org/openapijsonschematools/client/schemas/validation/KeywordValidator.java +++ b/samples/client/petstore/java/src/main/java/org/openapijsonschematools/client/schemas/validation/KeywordValidator.java @@ -3,37 +3,9 @@ import org.openapijsonschematools.client.exceptions.ValidationException; import org.checkerframework.checker.nullness.qual.Nullable; -import java.util.ArrayList; -import java.util.List; - +@FunctionalInterface public interface KeywordValidator { @Nullable PathToSchemasMap validate( - JsonSchema schema, - @Nullable Object arg, - ValidationMetadata validationMetadata, - @Nullable List containsPathToSchemas, - @Nullable PathToSchemasMap patternPropertiesPathToSchemas, - @Nullable PathToSchemasMap ifPathToSchemas + ValidationData data ) throws ValidationException; - - default List getContainsPathToSchemas( - @Nullable Object arg, - ValidationMetadata validationMetadata - ) { - return new ArrayList<>(); - } - - default PathToSchemasMap getPatternPropertiesPathToSchemas( - @Nullable Object arg, - ValidationMetadata validationMetadata - ) { - return new PathToSchemasMap(); - } - - default PathToSchemasMap getIfPathToSchemas( - @Nullable Object arg, - ValidationMetadata validationMetadata - ) { - return new PathToSchemasMap(); - } } \ No newline at end of file diff --git a/samples/client/petstore/java/src/main/java/org/openapijsonschematools/client/schemas/validation/MaxContainsValidator.java b/samples/client/petstore/java/src/main/java/org/openapijsonschematools/client/schemas/validation/MaxContainsValidator.java index 25482139fab..9e9b3b92c18 100644 --- a/samples/client/petstore/java/src/main/java/org/openapijsonschematools/client/schemas/validation/MaxContainsValidator.java +++ b/samples/client/petstore/java/src/main/java/org/openapijsonschematools/client/schemas/validation/MaxContainsValidator.java @@ -6,31 +6,25 @@ import java.util.List; public class MaxContainsValidator implements KeywordValidator { - public final int maxContains; - - public MaxContainsValidator(int maxContains) { - this.maxContains = maxContains; - } - @Override public @Nullable PathToSchemasMap validate( - JsonSchema schema, - @Nullable Object arg, - ValidationMetadata validationMetadata, - @Nullable List containsPathToSchemas, - @Nullable PathToSchemasMap patternPropertiesPathToSchemas, - @Nullable PathToSchemasMap ifPathToSchemas + ValidationData data ) { - if (!(arg instanceof List)) { + var maxContains = data.schema().maxContains; + if (maxContains == null) { + return null; + } + if (!(data.arg() instanceof List)) { return null; } + var containsPathToSchemas = data.containsPathToSchemas(); if (containsPathToSchemas == null) { return null; } if (containsPathToSchemas.size() > maxContains) { throw new ValidationException( - "Validation failed for maxContains keyword in class="+schema.getClass()+ - " at pathToItem="+validationMetadata.pathToItem()+". Too many items validated to the contains schema." + "Validation failed for maxContains keyword in class="+data.schema().getClass()+ + " at pathToItem="+data.validationMetadata().pathToItem()+". Too many items validated to the contains schema." ); } return null; diff --git a/samples/client/petstore/java/src/main/java/org/openapijsonschematools/client/schemas/validation/MaxItemsValidator.java b/samples/client/petstore/java/src/main/java/org/openapijsonschematools/client/schemas/validation/MaxItemsValidator.java index bda6fb43ece..98ed5cb4ff4 100644 --- a/samples/client/petstore/java/src/main/java/org/openapijsonschematools/client/schemas/validation/MaxItemsValidator.java +++ b/samples/client/petstore/java/src/main/java/org/openapijsonschematools/client/schemas/validation/MaxItemsValidator.java @@ -6,26 +6,19 @@ import java.util.List; public class MaxItemsValidator implements KeywordValidator { - public final int maxItems; - - public MaxItemsValidator(int maxItems) { - this.maxItems = maxItems; - } - @Override public @Nullable PathToSchemasMap validate( - JsonSchema schema, - @Nullable Object arg, - ValidationMetadata validationMetadata, - @Nullable List containsPathToSchemas, - @Nullable PathToSchemasMap patternPropertiesPathToSchemas, - @Nullable PathToSchemasMap ifPathToSchemas + ValidationData data ) { - if (!(arg instanceof List)) { + var maxItems = data.schema().maxItems; + if (maxItems == null) { + return null; + } + if (!(data.arg() instanceof List listArg)) { return null; } - if (((List) arg).size() > maxItems) { - throw new ValidationException("Value " + arg + " is invalid because has > the maxItems of " + maxItems); + if (listArg.size() > maxItems) { + throw new ValidationException("Value " + listArg + " is invalid because has > the maxItems of " + maxItems); } return null; } diff --git a/samples/client/petstore/java/src/main/java/org/openapijsonschematools/client/schemas/validation/MaxLengthValidator.java b/samples/client/petstore/java/src/main/java/org/openapijsonschematools/client/schemas/validation/MaxLengthValidator.java index 1a78623e0f4..08d91666c5d 100644 --- a/samples/client/petstore/java/src/main/java/org/openapijsonschematools/client/schemas/validation/MaxLengthValidator.java +++ b/samples/client/petstore/java/src/main/java/org/openapijsonschematools/client/schemas/validation/MaxLengthValidator.java @@ -3,30 +3,21 @@ import org.openapijsonschematools.client.exceptions.ValidationException; import org.checkerframework.checker.nullness.qual.Nullable; -import java.util.List; - public class MaxLengthValidator extends LengthValidator implements KeywordValidator { - public final int maxLength; - - public MaxLengthValidator(int maxLength) { - this.maxLength = maxLength; - } - @Override public @Nullable PathToSchemasMap validate( - JsonSchema schema, - @Nullable Object arg, - ValidationMetadata validationMetadata, - @Nullable List containsPathToSchemas, - @Nullable PathToSchemasMap patternPropertiesPathToSchemas, - @Nullable PathToSchemasMap ifPathToSchemas + ValidationData data ) { - if (!(arg instanceof String)) { + var maxLength = data.schema().maxLength; + if (maxLength == null) { + return null; + } + if (!(data.arg() instanceof String stringArg)) { return null; } - int length = getLength((String) arg); + int length = getLength(stringArg); if (length > maxLength) { - throw new ValidationException("Value " + arg + " is invalid because has > the maxLength of " + maxLength); + throw new ValidationException("Value " + stringArg + " is invalid because has > the maxLength of " + maxLength); } return null; } diff --git a/samples/client/petstore/java/src/main/java/org/openapijsonschematools/client/schemas/validation/MaxPropertiesValidator.java b/samples/client/petstore/java/src/main/java/org/openapijsonschematools/client/schemas/validation/MaxPropertiesValidator.java index 5928ec588ac..d117f1688e2 100644 --- a/samples/client/petstore/java/src/main/java/org/openapijsonschematools/client/schemas/validation/MaxPropertiesValidator.java +++ b/samples/client/petstore/java/src/main/java/org/openapijsonschematools/client/schemas/validation/MaxPropertiesValidator.java @@ -3,30 +3,22 @@ import org.openapijsonschematools.client.exceptions.ValidationException; import org.checkerframework.checker.nullness.qual.Nullable; -import java.util.List; import java.util.Map; public class MaxPropertiesValidator implements KeywordValidator { - public final int maxProperties; - - public MaxPropertiesValidator(int maxProperties) { - this.maxProperties = maxProperties; - } - @Override public @Nullable PathToSchemasMap validate( - JsonSchema schema, - @Nullable Object arg, - ValidationMetadata validationMetadata, - @Nullable List containsPathToSchemas, - @Nullable PathToSchemasMap patternPropertiesPathToSchemas, - @Nullable PathToSchemasMap ifPathToSchemas + ValidationData data ) { - if (!(arg instanceof Map)) { + var maxProperties = data.schema().maxProperties; + if (maxProperties == null) { + return null; + } + if (!(data.arg() instanceof Map mapArg)) { return null; } - if (((Map) arg).size() > maxProperties) { - throw new ValidationException("Value " + arg + " is invalid because has > the maxProperties of " + maxProperties); + if (mapArg.size() > maxProperties) { + throw new ValidationException("Value " + mapArg + " is invalid because has > the maxProperties of " + maxProperties); } return null; } diff --git a/samples/client/petstore/java/src/main/java/org/openapijsonschematools/client/schemas/validation/MaximumValidator.java b/samples/client/petstore/java/src/main/java/org/openapijsonschematools/client/schemas/validation/MaximumValidator.java index 25faceb4022..702f09686dc 100644 --- a/samples/client/petstore/java/src/main/java/org/openapijsonschematools/client/schemas/validation/MaximumValidator.java +++ b/samples/client/petstore/java/src/main/java/org/openapijsonschematools/client/schemas/validation/MaximumValidator.java @@ -3,52 +3,43 @@ import org.openapijsonschematools.client.exceptions.ValidationException; import org.checkerframework.checker.nullness.qual.Nullable; -import java.util.List; - public class MaximumValidator implements KeywordValidator { - public final Number maximum; - - public MaximumValidator(Number maximum) { - this.maximum = maximum; - } - @Override public @Nullable PathToSchemasMap validate( - JsonSchema schema, - @Nullable Object arg, - ValidationMetadata validationMetadata, - @Nullable List containsPathToSchemas, - @Nullable PathToSchemasMap patternPropertiesPathToSchemas, - @Nullable PathToSchemasMap ifPathToSchemas + ValidationData data ) { - if (!(arg instanceof Number)) { + var maximum = data.schema().maximum; + if (maximum == null) { + return null; + } + if (!(data.arg() instanceof Number)) { return null; } - String msg = "Value " + arg + " is invalid because it is > the maximum of " + maximum; - if (arg instanceof Integer) { - if (((Integer) arg).compareTo(maximum.intValue()) == 1) { + String msg = "Value " + data.arg() + " is invalid because it is > the maximum of " + maximum; + if (data.arg() instanceof Integer intArg) { + if (intArg.compareTo(maximum.intValue()) > 0) { throw new ValidationException(msg); } return null; } - if (arg instanceof Long) { - if (((Long) arg).compareTo(maximum.longValue()) == 1) { + if (data.arg() instanceof Long longArg) { + if (longArg.compareTo(maximum.longValue()) > 0) { throw new ValidationException(msg); } return null; } - if (arg instanceof Float) { - if (((Float) arg).compareTo(maximum.floatValue()) == 1) { + if (data.arg() instanceof Float floatArg) { + if (floatArg.compareTo(maximum.floatValue()) > 0) { throw new ValidationException(msg); } return null; } - if (arg instanceof Double) { - if (((Double) arg).compareTo(maximum.doubleValue()) == 1) { + if (data.arg() instanceof Double doubleArg) { + if (doubleArg.compareTo(maximum.doubleValue()) > 0) { throw new ValidationException(msg); } return null; } return null; } -} +} \ No newline at end of file diff --git a/samples/client/petstore/java/src/main/java/org/openapijsonschematools/client/schemas/validation/MinContainsValidator.java b/samples/client/petstore/java/src/main/java/org/openapijsonschematools/client/schemas/validation/MinContainsValidator.java index 2f34127155e..1827e95cc83 100644 --- a/samples/client/petstore/java/src/main/java/org/openapijsonschematools/client/schemas/validation/MinContainsValidator.java +++ b/samples/client/petstore/java/src/main/java/org/openapijsonschematools/client/schemas/validation/MinContainsValidator.java @@ -6,31 +6,24 @@ import java.util.List; public class MinContainsValidator implements KeywordValidator { - public final int minContains; - - public MinContainsValidator(int minContains) { - this.minContains = minContains; - } - @Override public @Nullable PathToSchemasMap validate( - JsonSchema schema, - @Nullable Object arg, - ValidationMetadata validationMetadata, - @Nullable List containsPathToSchemas, - @Nullable PathToSchemasMap patternPropertiesPathToSchemas, - @Nullable PathToSchemasMap ifPathToSchemas + ValidationData data ) { - if (!(arg instanceof List)) { + var minContains = data.schema().minContains; + if (minContains == null) { + return null; + } + if (!(data.arg() instanceof List)) { return null; } - if (containsPathToSchemas == null) { + if (data.containsPathToSchemas() == null) { return null; } - if (containsPathToSchemas.size() < minContains) { + if (data.containsPathToSchemas().size() < minContains) { throw new ValidationException( - "Validation failed for minContains keyword in class="+schema.getClass()+ - " at pathToItem="+validationMetadata.pathToItem()+". Too few items validated to the contains schema." + "Validation failed for minContains keyword in class="+data.schema().getClass()+ + " at pathToItem="+data.validationMetadata().pathToItem()+". Too few items validated to the contains schema." ); } return null; diff --git a/samples/client/petstore/java/src/main/java/org/openapijsonschematools/client/schemas/validation/MinItemsValidator.java b/samples/client/petstore/java/src/main/java/org/openapijsonschematools/client/schemas/validation/MinItemsValidator.java index 7c46cbe8f94..d1933ca7750 100644 --- a/samples/client/petstore/java/src/main/java/org/openapijsonschematools/client/schemas/validation/MinItemsValidator.java +++ b/samples/client/petstore/java/src/main/java/org/openapijsonschematools/client/schemas/validation/MinItemsValidator.java @@ -6,26 +6,19 @@ import java.util.List; public class MinItemsValidator implements KeywordValidator { - public final int minItems; - - public MinItemsValidator(int minItems) { - this.minItems = minItems; - } - @Override public @Nullable PathToSchemasMap validate( - JsonSchema schema, - @Nullable Object arg, - ValidationMetadata validationMetadata, - @Nullable List containsPathToSchemas, - @Nullable PathToSchemasMap patternPropertiesPathToSchemas, - @Nullable PathToSchemasMap ifPathToSchemas + ValidationData data ) { - if (!(arg instanceof List)) { + var minItems = data.schema().minItems; + if (minItems == null) { + return null; + } + if (!(data.arg() instanceof List listArg)) { return null; } - if (((List) arg).size() < minItems) { - throw new ValidationException("Value " + arg + " is invalid because has < the minItems of " + minItems); + if (listArg.size() < minItems) { + throw new ValidationException("Value " + listArg + " is invalid because has < the minItems of " + minItems); } return null; } diff --git a/samples/client/petstore/java/src/main/java/org/openapijsonschematools/client/schemas/validation/MinLengthValidator.java b/samples/client/petstore/java/src/main/java/org/openapijsonschematools/client/schemas/validation/MinLengthValidator.java index 7c92205a9cf..1defdc891e3 100644 --- a/samples/client/petstore/java/src/main/java/org/openapijsonschematools/client/schemas/validation/MinLengthValidator.java +++ b/samples/client/petstore/java/src/main/java/org/openapijsonschematools/client/schemas/validation/MinLengthValidator.java @@ -3,31 +3,22 @@ import org.openapijsonschematools.client.exceptions.ValidationException; import org.checkerframework.checker.nullness.qual.Nullable; -import java.util.List; - public class MinLengthValidator extends LengthValidator implements KeywordValidator { - public final int minLength; - - public MinLengthValidator(int minLength) { - this.minLength = minLength; - } - @Override public @Nullable PathToSchemasMap validate( - JsonSchema schema, - @Nullable Object arg, - ValidationMetadata validationMetadata, - @Nullable List containsPathToSchemas, - @Nullable PathToSchemasMap patternPropertiesPathToSchemas, - @Nullable PathToSchemasMap ifPathToSchemas + ValidationData data ) { - if (!(arg instanceof String)) { + var minLength = data.schema().minLength; + if (minLength == null) { + return null; + } + if (!(data.arg() instanceof String stringArg)) { return null; } - int length = getLength((String) arg); + int length = getLength(stringArg); if (length < minLength) { - throw new ValidationException("Value " + arg + " is invalid because has < the minLength of " + minLength); + throw new ValidationException("Value " + stringArg + " is invalid because has < the minLength of " + minLength); } return null; } -} +} \ No newline at end of file diff --git a/samples/client/petstore/java/src/main/java/org/openapijsonschematools/client/schemas/validation/MinPropertiesValidator.java b/samples/client/petstore/java/src/main/java/org/openapijsonschematools/client/schemas/validation/MinPropertiesValidator.java index c52b16000d8..c0b99e7fb7d 100644 --- a/samples/client/petstore/java/src/main/java/org/openapijsonschematools/client/schemas/validation/MinPropertiesValidator.java +++ b/samples/client/petstore/java/src/main/java/org/openapijsonschematools/client/schemas/validation/MinPropertiesValidator.java @@ -3,30 +3,22 @@ import org.openapijsonschematools.client.exceptions.ValidationException; import org.checkerframework.checker.nullness.qual.Nullable; -import java.util.List; import java.util.Map; public class MinPropertiesValidator implements KeywordValidator { - public final int minProperties; - - public MinPropertiesValidator(int minProperties) { - this.minProperties = minProperties; - } - @Override public @Nullable PathToSchemasMap validate( - JsonSchema schema, - @Nullable Object arg, - ValidationMetadata validationMetadata, - @Nullable List containsPathToSchemas, - @Nullable PathToSchemasMap patternPropertiesPathToSchemas, - @Nullable PathToSchemasMap ifPathToSchemas + ValidationData data ) { - if (!(arg instanceof Map)) { + var minProperties = data.schema().minProperties; + if (minProperties == null) { + return null; + } + if (!(data.arg() instanceof Map mapArg)) { return null; } - if (((Map) arg).size() < minProperties) { - throw new ValidationException("Value " + arg + " is invalid because has < the minProperties of " + minProperties); + if (mapArg.size() < minProperties) { + throw new ValidationException("Value " + mapArg + " is invalid because has < the minProperties of " + minProperties); } return null; } diff --git a/samples/client/petstore/java/src/main/java/org/openapijsonschematools/client/schemas/validation/MinimumValidator.java b/samples/client/petstore/java/src/main/java/org/openapijsonschematools/client/schemas/validation/MinimumValidator.java index dec192d47df..3b539120e42 100644 --- a/samples/client/petstore/java/src/main/java/org/openapijsonschematools/client/schemas/validation/MinimumValidator.java +++ b/samples/client/petstore/java/src/main/java/org/openapijsonschematools/client/schemas/validation/MinimumValidator.java @@ -3,48 +3,39 @@ import org.openapijsonschematools.client.exceptions.ValidationException; import org.checkerframework.checker.nullness.qual.Nullable; -import java.util.List; - public class MinimumValidator implements KeywordValidator { - public final Number minimum; - - public MinimumValidator(Number minimum) { - this.minimum = minimum; - } - @Override public @Nullable PathToSchemasMap validate( - JsonSchema schema, - @Nullable Object arg, - ValidationMetadata validationMetadata, - @Nullable List containsPathToSchemas, - @Nullable PathToSchemasMap patternPropertiesPathToSchemas, - @Nullable PathToSchemasMap ifPathToSchemas + ValidationData data ) { - if (!(arg instanceof Number)) { + var minimum = data.schema().minimum; + if (minimum == null) { + return null; + } + if (!(data.arg() instanceof Number)) { return null; } - String msg = "Value " + arg + " is invalid because it is < the minimum of " + minimum; - if (arg instanceof Integer) { - if (((Integer) arg).compareTo(minimum.intValue()) == -1) { + String msg = "Value " + data.arg() + " is invalid because it is < the minimum of " + minimum; + if (data.arg() instanceof Integer intArg) { + if (intArg.compareTo(minimum.intValue()) < 0) { throw new ValidationException(msg); } return null; } - if (arg instanceof Long) { - if (((Long) arg).compareTo(minimum.longValue()) == -1) { + if (data.arg() instanceof Long longArg) { + if (longArg.compareTo(minimum.longValue()) < 0) { throw new ValidationException(msg); } return null; } - if (arg instanceof Float) { - if (((Float) arg).compareTo(minimum.floatValue()) == -1) { + if (data.arg() instanceof Float floatArg) { + if (floatArg.compareTo(minimum.floatValue()) < 0) { throw new ValidationException(msg); } return null; } - if (arg instanceof Double) { - if (((Double) arg).compareTo(minimum.doubleValue()) == -1) { + if (data.arg() instanceof Double doubleArg) { + if (doubleArg.compareTo(minimum.doubleValue()) < 0) { throw new ValidationException(msg); } return null; diff --git a/samples/client/petstore/java/src/main/java/org/openapijsonschematools/client/schemas/validation/MultipleOfValidator.java b/samples/client/petstore/java/src/main/java/org/openapijsonschematools/client/schemas/validation/MultipleOfValidator.java index 15230b54275..eebc07a0f10 100644 --- a/samples/client/petstore/java/src/main/java/org/openapijsonschematools/client/schemas/validation/MultipleOfValidator.java +++ b/samples/client/petstore/java/src/main/java/org/openapijsonschematools/client/schemas/validation/MultipleOfValidator.java @@ -3,33 +3,25 @@ import org.openapijsonschematools.client.exceptions.ValidationException; import org.checkerframework.checker.nullness.qual.Nullable; -import java.util.List; import java.math.BigDecimal; public class MultipleOfValidator extends BigDecimalValidator implements KeywordValidator { - public final BigDecimal multipleOf; - - public MultipleOfValidator(BigDecimal multipleOf) { - this.multipleOf = multipleOf; - } - @Override public @Nullable PathToSchemasMap validate( - JsonSchema schema, - @Nullable Object arg, - ValidationMetadata validationMetadata, - @Nullable List containsPathToSchemas, - @Nullable PathToSchemasMap patternPropertiesPathToSchemas, - @Nullable PathToSchemasMap ifPathToSchemas + ValidationData data ) { - if (!(arg instanceof Number)) { + var multipleOf = data.schema().multipleOf; + if (multipleOf == null) { + return null; + } + if (!(data.arg() instanceof Number numberArg)) { return null; } - BigDecimal castArg = getBigDecimal((Number) arg); - String msg = "Value " + arg + " is invalid because it is not a multiple of " + multipleOf; + BigDecimal castArg = getBigDecimal(numberArg); + String msg = "Value " + numberArg + " is invalid because it is not a multiple of " + multipleOf; if (castArg.remainder(multipleOf).compareTo(BigDecimal.ZERO) != 0) { throw new ValidationException(msg); } return null; } -} +} \ No newline at end of file diff --git a/samples/client/petstore/java/src/main/java/org/openapijsonschematools/client/schemas/validation/NotValidator.java b/samples/client/petstore/java/src/main/java/org/openapijsonschematools/client/schemas/validation/NotValidator.java index 507c7f40fbc..aa61be1b624 100644 --- a/samples/client/petstore/java/src/main/java/org/openapijsonschematools/client/schemas/validation/NotValidator.java +++ b/samples/client/petstore/java/src/main/java/org/openapijsonschematools/client/schemas/validation/NotValidator.java @@ -3,39 +3,25 @@ import org.openapijsonschematools.client.exceptions.ValidationException; import org.checkerframework.checker.nullness.qual.Nullable; -import java.util.ArrayList; -import java.util.LinkedHashMap; -import java.util.LinkedHashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; - public class NotValidator implements KeywordValidator { - public final Class not; - - public NotValidator(Class not) { - this.not = not; - } - @Override public @Nullable PathToSchemasMap validate( - JsonSchema schema, - @Nullable Object arg, - ValidationMetadata validationMetadata, - @Nullable List containsPathToSchemas, - @Nullable PathToSchemasMap patternPropertiesPathToSchemas, - @Nullable PathToSchemasMap ifPathToSchemas + ValidationData data ) { + var not = data.schema().not; + if (not == null) { + return null; + } PathToSchemasMap pathToSchemas; try { JsonSchema notSchema = JsonSchemaFactory.getInstance(not); - pathToSchemas = JsonSchema.validate(notSchema, arg, validationMetadata); + pathToSchemas = JsonSchema.validate(notSchema, data.arg(), data.validationMetadata()); } catch (ValidationException e) { return null; } if (!pathToSchemas.isEmpty()) { throw new ValidationException( - "Invalid value "+arg+" was passed in to "+schema.getClass()+". "+ + "Invalid value "+data.arg()+" was passed in to "+data.schema().getClass()+". "+ "Value is invalid because it is disallowed by not "+not ); } diff --git a/samples/client/petstore/java/src/main/java/org/openapijsonschematools/client/schemas/validation/OneOfValidator.java b/samples/client/petstore/java/src/main/java/org/openapijsonschematools/client/schemas/validation/OneOfValidator.java index 5bc4bbd297b..f84f7796a8c 100644 --- a/samples/client/petstore/java/src/main/java/org/openapijsonschematools/client/schemas/validation/OneOfValidator.java +++ b/samples/client/petstore/java/src/main/java/org/openapijsonschematools/client/schemas/validation/OneOfValidator.java @@ -7,25 +7,18 @@ import java.util.List; public class OneOfValidator implements KeywordValidator { - public final List> oneOf; - - public OneOfValidator(List> oneOf) { - this.oneOf = oneOf; - } - @Override public @Nullable PathToSchemasMap validate( - JsonSchema schema, - @Nullable Object arg, - ValidationMetadata validationMetadata, - @Nullable List containsPathToSchemas, - @Nullable PathToSchemasMap patternPropertiesPathToSchemas, - @Nullable PathToSchemasMap ifPathToSchemas + ValidationData data ) { + var oneOf = data.schema().oneOf; + if (oneOf == null) { + return null; + } PathToSchemasMap pathToSchemas = new PathToSchemasMap(); List> validatedOneOfClasses = new ArrayList<>(); for(Class oneOfClass: oneOf) { - if (oneOfClass == schema.getClass()) { + if (oneOfClass == data.schema().getClass()) { /* optimistically assume that schema will pass validation do not invoke validate on it because that is recursive @@ -35,7 +28,7 @@ public OneOfValidator(List> oneOf) { } try { JsonSchema oneOfSchema = JsonSchemaFactory.getInstance(oneOfClass); - PathToSchemasMap otherPathToSchemas = JsonSchema.validate(oneOfSchema, arg, validationMetadata); + PathToSchemasMap otherPathToSchemas = JsonSchema.validate(oneOfSchema, data.arg(), data.validationMetadata()); validatedOneOfClasses.add(oneOfClass); pathToSchemas.update(otherPathToSchemas); } catch (ValidationException e) { @@ -43,12 +36,12 @@ public OneOfValidator(List> oneOf) { } } if (validatedOneOfClasses.isEmpty()) { - throw new ValidationException("Invalid inputs given to generate an instance of "+schema.getClass()+". None "+ + throw new ValidationException("Invalid inputs given to generate an instance of "+data.schema().getClass()+". None "+ "of the oneOf schemas matched the input data." ); } if (validatedOneOfClasses.size() > 1) { - throw new ValidationException("Invalid inputs given to generate an instance of "+schema.getClass()+". Multiple "+ + throw new ValidationException("Invalid inputs given to generate an instance of "+data.schema().getClass()+". Multiple "+ "oneOf schemas validated the data, but a max of one is allowed." ); } diff --git a/samples/client/petstore/java/src/main/java/org/openapijsonschematools/client/schemas/validation/PatternPropertiesValidator.java b/samples/client/petstore/java/src/main/java/org/openapijsonschematools/client/schemas/validation/PatternPropertiesValidator.java index 6104329139f..9e951e23ed2 100644 --- a/samples/client/petstore/java/src/main/java/org/openapijsonschematools/client/schemas/validation/PatternPropertiesValidator.java +++ b/samples/client/petstore/java/src/main/java/org/openapijsonschematools/client/schemas/validation/PatternPropertiesValidator.java @@ -1,68 +1,21 @@ package org.openapijsonschematools.client.schemas.validation; import org.checkerframework.checker.nullness.qual.Nullable; -import org.openapijsonschematools.client.exceptions.InvalidTypeException; -import java.util.ArrayList; -import java.util.List; import java.util.Map; -import java.util.regex.Pattern; public class PatternPropertiesValidator implements KeywordValidator { - public final Map> patternProperties; - - public PatternPropertiesValidator(Map> patternProperties) { - this.patternProperties = patternProperties; - } - @Override public @Nullable PathToSchemasMap validate( - JsonSchema schema, - @Nullable Object arg, - ValidationMetadata validationMetadata, - @Nullable List containsPathToSchemas, - @Nullable PathToSchemasMap patternPropertiesPathToSchemas, - @Nullable PathToSchemasMap ifPathToSchemas + ValidationData data ) { - if (!(arg instanceof Map)) { + var patternProperties = data.schema().patternProperties; + if (patternProperties == null) { return null; } - return patternPropertiesPathToSchemas; - } - - public PathToSchemasMap getPatternPropertiesPathToSchemas( - @Nullable Object arg, - ValidationMetadata validationMetadata - ) { - if (!(arg instanceof Map mapArg)) { - return new PathToSchemasMap(); - } - PathToSchemasMap pathToSchemas = new PathToSchemasMap(); - for (Map.Entry entry: mapArg.entrySet()) { - Object entryKey = entry.getKey(); - if (!(entryKey instanceof String key)) { - throw new InvalidTypeException("Invalid non-string type for map key"); - } - List propPathToItem = new ArrayList<>(validationMetadata.pathToItem()); - propPathToItem.add(key); - ValidationMetadata propValidationMetadata = new ValidationMetadata( - propPathToItem, - validationMetadata.configuration(), - validationMetadata.validatedPathToSchemas(), - validationMetadata.seenClasses() - ); - for (Map.Entry> patternPropEntry: patternProperties.entrySet()) { - if (!patternPropEntry.getKey().matcher(key).find()) { - continue; - } - - Class patternPropClass = patternPropEntry.getValue(); - JsonSchema patternPropSchema = JsonSchemaFactory.getInstance(patternPropClass); - PathToSchemasMap otherPathToSchemas = JsonSchema.validate(patternPropSchema, entry.getValue(), propValidationMetadata); - pathToSchemas.update(otherPathToSchemas); - } + if (!(data.arg() instanceof Map)) { + return null; } - return pathToSchemas; + return data.patternPropertiesPathToSchemas(); } } - diff --git a/samples/client/petstore/java/src/main/java/org/openapijsonschematools/client/schemas/validation/PatternValidator.java b/samples/client/petstore/java/src/main/java/org/openapijsonschematools/client/schemas/validation/PatternValidator.java index 37e7a545711..eceeb19e311 100644 --- a/samples/client/petstore/java/src/main/java/org/openapijsonschematools/client/schemas/validation/PatternValidator.java +++ b/samples/client/petstore/java/src/main/java/org/openapijsonschematools/client/schemas/validation/PatternValidator.java @@ -3,31 +3,21 @@ import org.openapijsonschematools.client.exceptions.ValidationException; import org.checkerframework.checker.nullness.qual.Nullable; -import java.util.List; -import java.util.regex.Pattern; - public class PatternValidator implements KeywordValidator { - public final Pattern pattern; - - public PatternValidator(Pattern pattern) { - this.pattern = pattern; - } - @Override public @Nullable PathToSchemasMap validate( - JsonSchema schema, - @Nullable Object arg, - ValidationMetadata validationMetadata, - @Nullable List containsPathToSchemas, - @Nullable PathToSchemasMap patternPropertiesPathToSchemas, - @Nullable PathToSchemasMap ifPathToSchemas + ValidationData data ) { - if (!(arg instanceof String)) { + var pattern = data.schema().pattern; + if (pattern == null) { + return null; + } + if (!(data.arg() instanceof String stringArg)) { return null; } - if (!pattern.matcher((String) arg).find()) { - throw new ValidationException("Invalid value "+arg+" did not find a match for pattern "+pattern); + if (!pattern.matcher(stringArg).find()) { + throw new ValidationException("Invalid value "+stringArg+" did not find a match for pattern "+pattern); } return null; } -} +} \ No newline at end of file diff --git a/samples/client/petstore/java/src/main/java/org/openapijsonschematools/client/schemas/validation/PrefixItemsValidator.java b/samples/client/petstore/java/src/main/java/org/openapijsonschematools/client/schemas/validation/PrefixItemsValidator.java index a8b2bda2a21..00e5b17607b 100644 --- a/samples/client/petstore/java/src/main/java/org/openapijsonschematools/client/schemas/validation/PrefixItemsValidator.java +++ b/samples/client/petstore/java/src/main/java/org/openapijsonschematools/client/schemas/validation/PrefixItemsValidator.java @@ -6,22 +6,15 @@ import java.util.List; public class PrefixItemsValidator implements KeywordValidator { - public final List> prefixItems; - - public PrefixItemsValidator(List> prefixItems) { - this.prefixItems = prefixItems; - } - @Override public @Nullable PathToSchemasMap validate( - JsonSchema schema, - @Nullable Object arg, - ValidationMetadata validationMetadata, - @Nullable List containsPathToSchemas, - @Nullable PathToSchemasMap patternPropertiesPathToSchemas, - @Nullable PathToSchemasMap ifPathToSchemas + ValidationData data ) { - if (!(arg instanceof List listArg)) { + var prefixItems = data.schema().prefixItems; + if (prefixItems == null) { + return null; + } + if (!(data.arg() instanceof List listArg)) { return null; } if (listArg.isEmpty()) { @@ -30,13 +23,13 @@ public PrefixItemsValidator(List> prefixItems) { PathToSchemasMap pathToSchemas = new PathToSchemasMap(); int maxIndex = Math.min(listArg.size(), prefixItems.size()); for (int i=0; i < maxIndex; i++) { - List itemPathToItem = new ArrayList<>(validationMetadata.pathToItem()); + List itemPathToItem = new ArrayList<>(data.validationMetadata().pathToItem()); itemPathToItem.add(i); ValidationMetadata itemValidationMetadata = new ValidationMetadata( itemPathToItem, - validationMetadata.configuration(), - validationMetadata.validatedPathToSchemas(), - validationMetadata.seenClasses() + data.validationMetadata().configuration(), + data.validationMetadata().validatedPathToSchemas(), + data.validationMetadata().seenClasses() ); JsonSchema itemsSchema = JsonSchemaFactory.getInstance(prefixItems.get(i)); PathToSchemasMap otherPathToSchemas = JsonSchema.validate(itemsSchema, listArg.get(i), itemValidationMetadata); diff --git a/samples/client/petstore/java/src/main/java/org/openapijsonschematools/client/schemas/validation/PropertiesValidator.java b/samples/client/petstore/java/src/main/java/org/openapijsonschematools/client/schemas/validation/PropertiesValidator.java index 9b7d50b28d8..17bccdd666a 100644 --- a/samples/client/petstore/java/src/main/java/org/openapijsonschematools/client/schemas/validation/PropertiesValidator.java +++ b/samples/client/petstore/java/src/main/java/org/openapijsonschematools/client/schemas/validation/PropertiesValidator.java @@ -9,22 +9,15 @@ import java.util.Set; public class PropertiesValidator implements KeywordValidator { - public final Map> properties; - - public PropertiesValidator(Map> properties) { - this.properties = properties; - } - @Override public @Nullable PathToSchemasMap validate( - JsonSchema schema, - @Nullable Object arg, - ValidationMetadata validationMetadata, - @Nullable List containsPathToSchemas, - @Nullable PathToSchemasMap patternPropertiesPathToSchemas, - @Nullable PathToSchemasMap ifPathToSchemas + ValidationData data ) { - if (!(arg instanceof Map mapArg)) { + var properties = data.schema().properties; + if (properties == null) { + return null; + } + if (!(data.arg() instanceof Map mapArg)) { return null; } PathToSchemasMap pathToSchemas = new PathToSchemasMap(); @@ -39,14 +32,14 @@ public PropertiesValidator(Map> properties) if (!presentProperties.contains(propName)) { continue; } - @Nullable Object propValue = ((Map) arg).get(propName); - List propPathToItem = new ArrayList<>(validationMetadata.pathToItem()); + @Nullable Object propValue = mapArg.get(propName); + List propPathToItem = new ArrayList<>(data.validationMetadata().pathToItem()); propPathToItem.add(propName); ValidationMetadata propValidationMetadata = new ValidationMetadata( propPathToItem, - validationMetadata.configuration(), - validationMetadata.validatedPathToSchemas(), - validationMetadata.seenClasses() + data.validationMetadata().configuration(), + data.validationMetadata().validatedPathToSchemas(), + data.validationMetadata().seenClasses() ); Class propClass = entry.getValue(); JsonSchema propSchema = JsonSchemaFactory.getInstance(propClass); @@ -60,4 +53,3 @@ public PropertiesValidator(Map> properties) return pathToSchemas; } } - diff --git a/samples/client/petstore/java/src/main/java/org/openapijsonschematools/client/schemas/validation/PropertyNamesValidator.java b/samples/client/petstore/java/src/main/java/org/openapijsonschematools/client/schemas/validation/PropertyNamesValidator.java index 5154911d484..55ea80b0382 100644 --- a/samples/client/petstore/java/src/main/java/org/openapijsonschematools/client/schemas/validation/PropertyNamesValidator.java +++ b/samples/client/petstore/java/src/main/java/org/openapijsonschematools/client/schemas/validation/PropertyNamesValidator.java @@ -7,34 +7,27 @@ import java.util.Map; public class PropertyNamesValidator implements KeywordValidator { - public final Class propertyNames; - - public PropertyNamesValidator(Class propertyNames) { - this.propertyNames = propertyNames; - } - @Override public @Nullable PathToSchemasMap validate( - JsonSchema schema, - @Nullable Object arg, - ValidationMetadata validationMetadata, - @Nullable List containsPathToSchemas, - @Nullable PathToSchemasMap patternPropertiesPathToSchemas, - @Nullable PathToSchemasMap ifPathToSchemas + ValidationData data ) { - if (!(arg instanceof Map)) { + var propertyNames = data.schema().propertyNames; + if (propertyNames == null) { + return null; + } + if (!(data.arg() instanceof Map mapArg)) { return null; } JsonSchema propertyNamesSchema = JsonSchemaFactory.getInstance(propertyNames); - for (Object objKey: ((Map) arg).keySet()) { + for (Object objKey: mapArg.keySet()) { if (objKey instanceof String key) { - List propPathToItem = new ArrayList<>(validationMetadata.pathToItem()); + List propPathToItem = new ArrayList<>(data.validationMetadata().pathToItem()); propPathToItem.add(key); ValidationMetadata keyValidationMetadata = new ValidationMetadata( propPathToItem, - validationMetadata.configuration(), - validationMetadata.validatedPathToSchemas(), - validationMetadata.seenClasses() + data.validationMetadata().configuration(), + data.validationMetadata().validatedPathToSchemas(), + data.validationMetadata().seenClasses() ); JsonSchema.validate(propertyNamesSchema, key, keyValidationMetadata); } diff --git a/samples/client/petstore/java/src/main/java/org/openapijsonschematools/client/schemas/validation/RequiredValidator.java b/samples/client/petstore/java/src/main/java/org/openapijsonschematools/client/schemas/validation/RequiredValidator.java index f68aef2b87a..f2e1a8ecde8 100644 --- a/samples/client/petstore/java/src/main/java/org/openapijsonschematools/client/schemas/validation/RequiredValidator.java +++ b/samples/client/petstore/java/src/main/java/org/openapijsonschematools/client/schemas/validation/RequiredValidator.java @@ -9,26 +9,19 @@ import java.util.Set; public class RequiredValidator implements KeywordValidator { - public final Set required; - - public RequiredValidator(Set required) { - this.required = required; - } - @Override public @Nullable PathToSchemasMap validate( - JsonSchema schema, - @Nullable Object arg, - ValidationMetadata validationMetadata, - @Nullable List containsPathToSchemas, - @Nullable PathToSchemasMap patternPropertiesPathToSchemas, - @Nullable PathToSchemasMap ifPathToSchemas + ValidationData data ) { - if (!(arg instanceof Map)) { + var required = data.schema().required; + if (required == null) { + return null; + } + if (!(data.arg() instanceof Map mapArg)) { return null; } Set missingRequiredProperties = new HashSet<>(required); - for (Object key: ((Map) arg).keySet()) { + for (Object key: mapArg.keySet()) { if (key instanceof String) { missingRequiredProperties.remove(key); } @@ -40,7 +33,7 @@ public RequiredValidator(Set required) { pluralChar = "s"; } throw new ValidationException( - schema.getClass()+" is missing "+missingRequiredProperties.size()+" required argument"+pluralChar+": "+missingReqProps + data.schema().getClass()+" is missing "+missingRequiredProperties.size()+" required argument"+pluralChar+": "+missingReqProps ); } return null; diff --git a/samples/client/petstore/java/src/main/java/org/openapijsonschematools/client/schemas/validation/TypeValidator.java b/samples/client/petstore/java/src/main/java/org/openapijsonschematools/client/schemas/validation/TypeValidator.java index f1fcd9d5cdd..bb4133a770e 100644 --- a/samples/client/petstore/java/src/main/java/org/openapijsonschematools/client/schemas/validation/TypeValidator.java +++ b/samples/client/petstore/java/src/main/java/org/openapijsonschematools/client/schemas/validation/TypeValidator.java @@ -5,25 +5,18 @@ import java.util.List; import java.util.Map; -import java.util.Set; public class TypeValidator implements KeywordValidator { - public final Set> type; - - public TypeValidator(Set> type) { - this.type = type; - } - @Override public @Nullable PathToSchemasMap validate( - JsonSchema schema, - @Nullable Object arg, - ValidationMetadata validationMetadata, - @Nullable List containsPathToSchemas, - @Nullable PathToSchemasMap patternPropertiesPathToSchemas, - @Nullable PathToSchemasMap ifPathToSchemas + ValidationData data ) { + var type = data.schema().type; + if (type == null) { + return null; + } Class argClass; + var arg = data.arg(); if (arg == null) { argClass = Void.class; } else if (arg instanceof List) { diff --git a/samples/client/petstore/java/src/main/java/org/openapijsonschematools/client/schemas/validation/UniqueItemsValidator.java b/samples/client/petstore/java/src/main/java/org/openapijsonschematools/client/schemas/validation/UniqueItemsValidator.java index 4cdbbe01060..a42a7d60b60 100644 --- a/samples/client/petstore/java/src/main/java/org/openapijsonschematools/client/schemas/validation/UniqueItemsValidator.java +++ b/samples/client/petstore/java/src/main/java/org/openapijsonschematools/client/schemas/validation/UniqueItemsValidator.java @@ -8,29 +8,22 @@ import java.util.Set; public class UniqueItemsValidator implements KeywordValidator { - public final boolean uniqueItems; - - public UniqueItemsValidator(boolean uniqueItems) { - this.uniqueItems = uniqueItems; - } - @Override public @Nullable PathToSchemasMap validate( - JsonSchema schema, - @Nullable Object arg, - ValidationMetadata validationMetadata, - @Nullable List containsPathToSchemas, - @Nullable PathToSchemasMap patternPropertiesPathToSchemas, - @Nullable PathToSchemasMap ifPathToSchemas + ValidationData data ) { - if (!(arg instanceof List)) { + var uniqueItems = data.schema().uniqueItems; + if (uniqueItems == null) { + return null; + } + if (!(data.arg() instanceof List listArg)) { return null; } if (!uniqueItems) { return null; } Set<@Nullable Object> seenItems = new HashSet<>(); - for (@Nullable Object item: (List) arg) { + for (@Nullable Object item: listArg) { int startingSeenItemsSize = seenItems.size(); seenItems.add(item); if (seenItems.size() == startingSeenItemsSize) { diff --git a/samples/client/petstore/java/src/main/java/org/openapijsonschematools/client/schemas/validation/ValidationData.java b/samples/client/petstore/java/src/main/java/org/openapijsonschematools/client/schemas/validation/ValidationData.java new file mode 100644 index 00000000000..55cb65fe9ef --- /dev/null +++ b/samples/client/petstore/java/src/main/java/org/openapijsonschematools/client/schemas/validation/ValidationData.java @@ -0,0 +1,22 @@ +package org.openapijsonschematools.client.schemas.validation; + +import org.checkerframework.checker.nullness.qual.Nullable; + +import java.util.List; + +public record ValidationData( + JsonSchema schema, + @Nullable Object arg, + ValidationMetadata validationMetadata, + @Nullable List containsPathToSchemas, + @Nullable PathToSchemasMap patternPropertiesPathToSchemas, + @Nullable PathToSchemasMap ifPathToSchemas +) { + public ValidationData( + JsonSchema schema, + @Nullable Object arg, + ValidationMetadata validationMetadata + ) { + this(schema, arg, validationMetadata, null, null, null); + } +} \ No newline at end of file diff --git a/samples/client/petstore/java/src/test/java/org/openapijsonschematools/client/schemas/validation/AdditionalPropertiesValidatorTest.java b/samples/client/petstore/java/src/test/java/org/openapijsonschematools/client/schemas/validation/AdditionalPropertiesValidatorTest.java index 7e6d7d09535..f98e0a7d529 100644 --- a/samples/client/petstore/java/src/test/java/org/openapijsonschematools/client/schemas/validation/AdditionalPropertiesValidatorTest.java +++ b/samples/client/petstore/java/src/test/java/org/openapijsonschematools/client/schemas/validation/AdditionalPropertiesValidatorTest.java @@ -26,6 +26,7 @@ private ObjectWithPropsSchema() { .properties(Map.ofEntries( new PropertyEntry("someString", StringJsonSchema.class) )) + .additionalProperties(StringJsonSchema.class) ); } @@ -73,14 +74,13 @@ public void testCorrectPropertySucceeds() { mutableMap.put("someString", "abc"); mutableMap.put("someAddProp", "def"); FrozenMap arg = new FrozenMap<>(mutableMap); - final AdditionalPropertiesValidator validator = new AdditionalPropertiesValidator(StringJsonSchema.class); + final AdditionalPropertiesValidator validator = new AdditionalPropertiesValidator(); PathToSchemasMap pathToSchemas = validator.validate( - ObjectWithPropsSchema.getInstance(), - arg, - validationMetadata, - new ArrayList<>(), - new PathToSchemasMap(), - new PathToSchemasMap() + new ValidationData( + ObjectWithPropsSchema.getInstance(), + arg, + validationMetadata + ) ); if (pathToSchemas == null) { throw new RuntimeException("Invalid null value for pathToSchemas for this test case"); @@ -105,14 +105,13 @@ public void testNotApplicableTypeReturnsNull() { new PathToSchemasMap(), new LinkedHashSet<>() ); - final AdditionalPropertiesValidator validator = new AdditionalPropertiesValidator(StringJsonSchema.class); + final AdditionalPropertiesValidator validator = new AdditionalPropertiesValidator(); PathToSchemasMap pathToSchemas = validator.validate( - MapJsonSchema.getInstance(), - 1, - validationMetadata, - new ArrayList<>(), - new PathToSchemasMap(), - new PathToSchemasMap() + new ValidationData( + MapJsonSchema.getInstance(), + 1, + validationMetadata + ) ); assertNull(pathToSchemas); } @@ -130,14 +129,13 @@ public void testIncorrectPropertyValueFails() { mutableMap.put("someString", "abc"); mutableMap.put("someAddProp", 1); FrozenMap arg = new FrozenMap<>(mutableMap); - final AdditionalPropertiesValidator validator = new AdditionalPropertiesValidator(StringJsonSchema.class); + final AdditionalPropertiesValidator validator = new AdditionalPropertiesValidator(); Assert.assertThrows(ValidationException.class, () -> validator.validate( - ObjectWithPropsSchema.getInstance(), - arg, - validationMetadata, - new ArrayList<>(), - new PathToSchemasMap(), - new PathToSchemasMap() + new ValidationData( + ObjectWithPropsSchema.getInstance(), + arg, + validationMetadata + ) )); } } \ No newline at end of file diff --git a/samples/client/petstore/java/src/test/java/org/openapijsonschematools/client/schemas/validation/FormatValidatorTest.java b/samples/client/petstore/java/src/test/java/org/openapijsonschematools/client/schemas/validation/FormatValidatorTest.java index 87a6bafc05f..db31df87dd9 100644 --- a/samples/client/petstore/java/src/test/java/org/openapijsonschematools/client/schemas/validation/FormatValidatorTest.java +++ b/samples/client/petstore/java/src/test/java/org/openapijsonschematools/client/schemas/validation/FormatValidatorTest.java @@ -6,8 +6,14 @@ import org.openapijsonschematools.client.configurations.JsonSchemaKeywordFlags; import org.openapijsonschematools.client.configurations.SchemaConfiguration; import org.openapijsonschematools.client.exceptions.ValidationException; -import org.openapijsonschematools.client.schemas.NumberJsonSchema; -import org.openapijsonschematools.client.schemas.StringJsonSchema; +import org.openapijsonschematools.client.schemas.IntJsonSchema; +import org.openapijsonschematools.client.schemas.Int32JsonSchema; +import org.openapijsonschematools.client.schemas.Int64JsonSchema; +import org.openapijsonschematools.client.schemas.FloatJsonSchema; +import org.openapijsonschematools.client.schemas.DoubleJsonSchema; +import org.openapijsonschematools.client.schemas.DecimalJsonSchema; +import org.openapijsonschematools.client.schemas.DateJsonSchema; +import org.openapijsonschematools.client.schemas.DateTimeJsonSchema; import java.math.BigDecimal; import java.math.BigInteger; @@ -29,354 +35,328 @@ private void assertNull(@Nullable Object object) { @Test public void testIntFormatSucceedsWithFloat() { - final FormatValidator validator = new FormatValidator("int"); + final FormatValidator validator = new FormatValidator(); PathToSchemasMap pathToSchemasMap = validator.validate( - NumberJsonSchema.getInstance(), - 1.0f, - validationMetadata, - new ArrayList<>(), - new PathToSchemasMap(), - new PathToSchemasMap() + new ValidationData( + IntJsonSchema.getInstance(), + 1.0f, + validationMetadata + ) ); assertNull(pathToSchemasMap); } @Test public void testIntFormatFailsWithFloat() { - final FormatValidator validator = new FormatValidator("int"); + final FormatValidator validator = new FormatValidator(); Assert.assertThrows(ValidationException.class, () -> validator.validate( - NumberJsonSchema.getInstance(), - 3.14f, - validationMetadata, - new ArrayList<>(), - new PathToSchemasMap(), - new PathToSchemasMap() + new ValidationData( + IntJsonSchema.getInstance(), + 3.14f, + validationMetadata + ) )); } @Test public void testIntFormatSucceedsWithInt() { - final FormatValidator validator = new FormatValidator("int"); + final FormatValidator validator = new FormatValidator(); PathToSchemasMap pathToSchemasMap = validator.validate( - NumberJsonSchema.getInstance(), - 1, - validationMetadata, - new ArrayList<>(), - new PathToSchemasMap(), - new PathToSchemasMap() + new ValidationData( + IntJsonSchema.getInstance(), + 1, + validationMetadata + ) ); assertNull(pathToSchemasMap); } @Test public void testInt32UnderMinFails() { - final FormatValidator validator = new FormatValidator("int32"); + final FormatValidator validator = new FormatValidator(); Assert.assertThrows(ValidationException.class, () -> validator.validate( - NumberJsonSchema.getInstance(), - -2147483649L, - validationMetadata, - new ArrayList<>(), - new PathToSchemasMap(), - new PathToSchemasMap() + new ValidationData( + Int32JsonSchema.getInstance(), + -2147483649L, + validationMetadata + ) )); } @Test public void testInt32InclusiveMinSucceeds() { - final FormatValidator validator = new FormatValidator("int32"); + final FormatValidator validator = new FormatValidator(); PathToSchemasMap pathToSchemasMap = validator.validate( - NumberJsonSchema.getInstance(), - -2147483648, - validationMetadata, - new ArrayList<>(), - new PathToSchemasMap(), - new PathToSchemasMap() + new ValidationData( + Int32JsonSchema.getInstance(), + -2147483648, + validationMetadata + ) ); assertNull(pathToSchemasMap); } @Test public void testInt32InclusiveMaxSucceeds() { - final FormatValidator validator = new FormatValidator("int32"); + final FormatValidator validator = new FormatValidator(); PathToSchemasMap pathToSchemasMap = validator.validate( - NumberJsonSchema.getInstance(), - 2147483647, - validationMetadata, - new ArrayList<>(), - new PathToSchemasMap(), - new PathToSchemasMap() + new ValidationData( + Int32JsonSchema.getInstance(), + 2147483647, + validationMetadata + ) ); assertNull(pathToSchemasMap); } @Test public void testInt32OverMaxFails() { - final FormatValidator validator = new FormatValidator("int32"); + final FormatValidator validator = new FormatValidator(); Assert.assertThrows(ValidationException.class, () -> validator.validate( - NumberJsonSchema.getInstance(), - 2147483648L, - validationMetadata, - new ArrayList<>(), - new PathToSchemasMap(), - new PathToSchemasMap() + new ValidationData( + Int32JsonSchema.getInstance(), + 2147483648L, + validationMetadata + ) )); } @Test public void testInt64UnderMinFails() { - final FormatValidator validator = new FormatValidator("int64"); + final FormatValidator validator = new FormatValidator(); Assert.assertThrows(ValidationException.class, () -> validator.validate( - NumberJsonSchema.getInstance(), - new BigInteger("-9223372036854775809"), - validationMetadata, - new ArrayList<>(), - new PathToSchemasMap(), - new PathToSchemasMap() + new ValidationData( + Int64JsonSchema.getInstance(), + new BigInteger("-9223372036854775809"), + validationMetadata + ) )); } @Test public void testInt64InclusiveMinSucceeds() { - final FormatValidator validator = new FormatValidator("int64"); + final FormatValidator validator = new FormatValidator(); PathToSchemasMap pathToSchemasMap = validator.validate( - NumberJsonSchema.getInstance(), - -9223372036854775808L, - validationMetadata, - new ArrayList<>(), - new PathToSchemasMap(), - new PathToSchemasMap() + new ValidationData( + Int64JsonSchema.getInstance(), + -9223372036854775808L, + validationMetadata + ) ); assertNull(pathToSchemasMap); } @Test public void testInt64InclusiveMaxSucceeds() { - final FormatValidator validator = new FormatValidator("int64"); + final FormatValidator validator = new FormatValidator(); PathToSchemasMap pathToSchemasMap = validator.validate( - NumberJsonSchema.getInstance(), - 9223372036854775807L, - validationMetadata, - new ArrayList<>(), - new PathToSchemasMap(), - new PathToSchemasMap() + new ValidationData( + Int64JsonSchema.getInstance(), + 9223372036854775807L, + validationMetadata + ) ); assertNull(pathToSchemasMap); } @Test public void testInt64OverMaxFails() { - final FormatValidator validator = new FormatValidator("int64"); + final FormatValidator validator = new FormatValidator(); Assert.assertThrows(ValidationException.class, () -> validator.validate( - NumberJsonSchema.getInstance(), - new BigInteger("9223372036854775808"), - validationMetadata, - new ArrayList<>(), - new PathToSchemasMap(), - new PathToSchemasMap() + new ValidationData( + Int64JsonSchema.getInstance(), + new BigInteger("9223372036854775808"), + validationMetadata + ) )); } @Test public void testFloatUnderMinFails() { - final FormatValidator validator = new FormatValidator("float"); + final FormatValidator validator = new FormatValidator(); Assert.assertThrows(ValidationException.class, () -> validator.validate( - NumberJsonSchema.getInstance(), - -3.402823466385289e+38d, - validationMetadata, - new ArrayList<>(), - new PathToSchemasMap(), - new PathToSchemasMap() + new ValidationData( + FloatJsonSchema.getInstance(), + -3.402823466385289e+38d, + validationMetadata + ) )); } @Test public void testFloatInclusiveMinSucceeds() { - final FormatValidator validator = new FormatValidator("float"); + final FormatValidator validator = new FormatValidator(); PathToSchemasMap pathToSchemasMap = validator.validate( - NumberJsonSchema.getInstance(), - -3.4028234663852886e+38f, - validationMetadata, - new ArrayList<>(), - new PathToSchemasMap(), - new PathToSchemasMap() + new ValidationData( + FloatJsonSchema.getInstance(), + -3.4028234663852886e+38f, + validationMetadata + ) ); assertNull(pathToSchemasMap); } @Test public void testFloatInclusiveMaxSucceeds() { - final FormatValidator validator = new FormatValidator("float"); + final FormatValidator validator = new FormatValidator(); PathToSchemasMap pathToSchemasMap = validator.validate( - NumberJsonSchema.getInstance(), - 3.4028234663852886e+38f, - validationMetadata, - new ArrayList<>(), - new PathToSchemasMap(), - new PathToSchemasMap() + new ValidationData( + FloatJsonSchema.getInstance(), + 3.4028234663852886e+38f, + validationMetadata + ) ); assertNull(pathToSchemasMap); } @Test public void testFloatOverMaxFails() { - final FormatValidator validator = new FormatValidator("float"); + final FormatValidator validator = new FormatValidator(); Assert.assertThrows(ValidationException.class, () -> validator.validate( - NumberJsonSchema.getInstance(), - 3.402823466385289e+38d, - validationMetadata, - new ArrayList<>(), - new PathToSchemasMap(), - new PathToSchemasMap() + new ValidationData( + FloatJsonSchema.getInstance(), + 3.402823466385289e+38d, + validationMetadata + ) )); } @Test public void testDoubleUnderMinFails() { - final FormatValidator validator = new FormatValidator("double"); + final FormatValidator validator = new FormatValidator(); Assert.assertThrows(ValidationException.class, () -> validator.validate( - NumberJsonSchema.getInstance(), - new BigDecimal("-1.7976931348623157082e+308"), - validationMetadata, - new ArrayList<>(), - new PathToSchemasMap(), - new PathToSchemasMap() + new ValidationData( + DoubleJsonSchema.getInstance(), + new BigDecimal("-1.7976931348623157082e+308"), + validationMetadata + ) )); } @Test public void testDoubleInclusiveMinSucceeds() { - final FormatValidator validator = new FormatValidator("double"); + final FormatValidator validator = new FormatValidator(); PathToSchemasMap pathToSchemasMap = validator.validate( - NumberJsonSchema.getInstance(), - -1.7976931348623157E+308d, - validationMetadata, - new ArrayList<>(), - new PathToSchemasMap(), - new PathToSchemasMap() + new ValidationData( + DoubleJsonSchema.getInstance(), + -1.7976931348623157E+308d, + validationMetadata + ) ); assertNull(pathToSchemasMap); } @Test public void testDoubleInclusiveMaxSucceeds() { - final FormatValidator validator = new FormatValidator("double"); + final FormatValidator validator = new FormatValidator(); PathToSchemasMap pathToSchemasMap = validator.validate( - NumberJsonSchema.getInstance(), - 1.7976931348623157E+308d, - validationMetadata, - new ArrayList<>(), - new PathToSchemasMap(), - new PathToSchemasMap() + new ValidationData( + DoubleJsonSchema.getInstance(), + 1.7976931348623157E+308d, + validationMetadata + ) ); assertNull(pathToSchemasMap); } @Test public void testDoubleOverMaxFails() { - final FormatValidator validator = new FormatValidator("double"); + final FormatValidator validator = new FormatValidator(); Assert.assertThrows(ValidationException.class, () -> validator.validate( - NumberJsonSchema.getInstance(), - new BigDecimal("1.7976931348623157082e+308"), - validationMetadata, - new ArrayList<>(), - new PathToSchemasMap(), - new PathToSchemasMap() + new ValidationData( + DoubleJsonSchema.getInstance(), + new BigDecimal("1.7976931348623157082e+308"), + validationMetadata + ) )); } @Test public void testInvalidNumberStringFails() { - final FormatValidator validator = new FormatValidator("number"); + final FormatValidator validator = new FormatValidator(); Assert.assertThrows(ValidationException.class, () -> validator.validate( - NumberJsonSchema.getInstance(), - "abc", - validationMetadata, - new ArrayList<>(), - new PathToSchemasMap(), - new PathToSchemasMap() + new ValidationData( + DecimalJsonSchema.getInstance(), + "abc", + validationMetadata + ) )); } @Test public void testValidFloatNumberStringSucceeds() { - final FormatValidator validator = new FormatValidator("number"); + final FormatValidator validator = new FormatValidator(); PathToSchemasMap pathToSchemasMap = validator.validate( - NumberJsonSchema.getInstance(), - "3.14", - validationMetadata, - new ArrayList<>(), - new PathToSchemasMap(), - new PathToSchemasMap() + new ValidationData( + DecimalJsonSchema.getInstance(), + "3.14", + validationMetadata + ) ); assertNull(pathToSchemasMap); } @Test public void testValidIntNumberStringSucceeds() { - final FormatValidator validator = new FormatValidator("number"); + final FormatValidator validator = new FormatValidator(); PathToSchemasMap pathToSchemasMap = validator.validate( - NumberJsonSchema.getInstance(), - "1", - validationMetadata, - new ArrayList<>(), - new PathToSchemasMap(), - new PathToSchemasMap() + new ValidationData( + DecimalJsonSchema.getInstance(), + "1", + validationMetadata + ) ); assertNull(pathToSchemasMap); } @Test public void testInvalidDateStringFails() { - final FormatValidator validator = new FormatValidator("date"); + final FormatValidator validator = new FormatValidator(); Assert.assertThrows(ValidationException.class, () -> validator.validate( - StringJsonSchema.getInstance(), - "abc", - validationMetadata, - new ArrayList<>(), - new PathToSchemasMap(), - new PathToSchemasMap() + new ValidationData( + DateJsonSchema.getInstance(), + "abc", + validationMetadata + ) )); } @Test public void testValidDateStringSucceeds() { - final FormatValidator validator = new FormatValidator("date"); + final FormatValidator validator = new FormatValidator(); PathToSchemasMap pathToSchemasMap = validator.validate( - StringJsonSchema.getInstance(), - "2017-01-20", - validationMetadata, - new ArrayList<>(), - new PathToSchemasMap(), - new PathToSchemasMap() + new ValidationData( + DateJsonSchema.getInstance(), + "2017-01-20", + validationMetadata + ) ); assertNull(pathToSchemasMap); } @Test public void testInvalidDateTimeStringFails() { - final FormatValidator validator = new FormatValidator("date-time"); + final FormatValidator validator = new FormatValidator(); Assert.assertThrows(ValidationException.class, () -> validator.validate( - StringJsonSchema.getInstance(), - "abc", - validationMetadata, - new ArrayList<>(), - new PathToSchemasMap(), - new PathToSchemasMap() + new ValidationData( + DateTimeJsonSchema.getInstance(), + "abc", + validationMetadata + ) )); } @Test public void testValidDateTimeStringSucceeds() { - final FormatValidator validator = new FormatValidator("date-time"); + final FormatValidator validator = new FormatValidator(); PathToSchemasMap pathToSchemasMap = validator.validate( - StringJsonSchema.getInstance(), - "2017-07-21T17:32:28Z", - validationMetadata, - new ArrayList<>(), - new PathToSchemasMap(), - new PathToSchemasMap() + new ValidationData( + DateTimeJsonSchema.getInstance(), + "2017-07-21T17:32:28Z", + validationMetadata + ) ); assertNull(pathToSchemasMap); } diff --git a/samples/client/petstore/java/src/test/java/org/openapijsonschematools/client/schemas/validation/ItemsValidatorTest.java b/samples/client/petstore/java/src/test/java/org/openapijsonschematools/client/schemas/validation/ItemsValidatorTest.java index f9c539091f3..b16a91e3919 100644 --- a/samples/client/petstore/java/src/test/java/org/openapijsonschematools/client/schemas/validation/ItemsValidatorTest.java +++ b/samples/client/petstore/java/src/test/java/org/openapijsonschematools/client/schemas/validation/ItemsValidatorTest.java @@ -5,14 +5,15 @@ import org.junit.Test; import org.openapijsonschematools.client.configurations.JsonSchemaKeywordFlags; import org.openapijsonschematools.client.configurations.SchemaConfiguration; -import org.openapijsonschematools.client.schemas.ListJsonSchema; import org.openapijsonschematools.client.schemas.StringJsonSchema; +import org.openapijsonschematools.client.exceptions.InvalidTypeException; import org.openapijsonschematools.client.exceptions.ValidationException; import java.util.ArrayList; import java.util.LinkedHashMap; import java.util.LinkedHashSet; import java.util.List; +import java.util.Set; public class ItemsValidatorTest { @SuppressWarnings("nullness") @@ -20,6 +21,31 @@ private void assertNull(@Nullable Object object) { Assert.assertNull(object); } + public static class ArrayWithItemsSchema extends JsonSchema { + public ArrayWithItemsSchema() { + super(new JsonSchemaInfo() + .type(Set.of(List.class)) + .items(StringJsonSchema.class) + ); + } + + @Override + public Object getNewInstance(@Nullable Object arg, List pathToItem, PathToSchemasMap pathToSchemas) { + if (arg instanceof List listArg) { + return getNewInstance(listArg, pathToItem, pathToSchemas); + } + throw new InvalidTypeException("Invalid input type="+getClass(arg)+". It can't be instantiated by this schema"); + } + + @Override + public @Nullable Object validate(@Nullable Object arg, SchemaConfiguration configuration) throws InvalidTypeException, ValidationException { + if (arg instanceof List listArg) { + return validate(listArg, configuration); + } + throw new InvalidTypeException("Invalid input type="+getClass(arg)+". It can't be validated by this schema"); + } + } + @Test public void testCorrectItemsSucceeds() { List pathToItem = List.of("args[0]"); @@ -32,14 +58,13 @@ public void testCorrectItemsSucceeds() { List mutableList = new ArrayList<>(); mutableList.add("a"); FrozenList arg = new FrozenList<>(mutableList); - final ItemsValidator validator = new ItemsValidator(StringJsonSchema.class); + final ItemsValidator validator = new ItemsValidator(); PathToSchemasMap pathToSchemas = validator.validate( - ListJsonSchema.getInstance(), - arg, - validationMetadata, - new ArrayList<>(), - new PathToSchemasMap(), - new PathToSchemasMap() + new ValidationData( + new ArrayWithItemsSchema(), + arg, + validationMetadata + ) ); if (pathToSchemas == null) { throw new RuntimeException("Invalid null value in pathToSchemas for this test case"); @@ -64,14 +89,13 @@ public void testNotApplicableTypeReturnsNull() { new PathToSchemasMap(), new LinkedHashSet<>() ); - final ItemsValidator validator = new ItemsValidator(StringJsonSchema.class); + final ItemsValidator validator = new ItemsValidator(); PathToSchemasMap pathToSchemas = validator.validate( - ListJsonSchema.getInstance(), - 1, - validationMetadata, - new ArrayList<>(), - new PathToSchemasMap(), - new PathToSchemasMap() + new ValidationData( + new ArrayWithItemsSchema(), + 1, + validationMetadata + ) ); assertNull(pathToSchemas); } @@ -88,14 +112,13 @@ public void testIncorrectItemFails() { List mutableList = new ArrayList<>(); mutableList.add(1); FrozenList arg = new FrozenList<>(mutableList); - final ItemsValidator validator = new ItemsValidator(StringJsonSchema.class); + final ItemsValidator validator = new ItemsValidator(); Assert.assertThrows(ValidationException.class, () -> validator.validate( - ListJsonSchema.getInstance(), - arg, - validationMetadata, - new ArrayList<>(), - new PathToSchemasMap(), - new PathToSchemasMap() + new ValidationData( + new ArrayWithItemsSchema(), + arg, + validationMetadata + ) )); } -} +} \ No newline at end of file diff --git a/samples/client/petstore/java/src/test/java/org/openapijsonschematools/client/schemas/validation/PropertiesValidatorTest.java b/samples/client/petstore/java/src/test/java/org/openapijsonschematools/client/schemas/validation/PropertiesValidatorTest.java index ea58d090f1f..9431d06708f 100644 --- a/samples/client/petstore/java/src/test/java/org/openapijsonschematools/client/schemas/validation/PropertiesValidatorTest.java +++ b/samples/client/petstore/java/src/test/java/org/openapijsonschematools/client/schemas/validation/PropertiesValidatorTest.java @@ -5,7 +5,7 @@ import org.junit.Test; import org.openapijsonschematools.client.configurations.JsonSchemaKeywordFlags; import org.openapijsonschematools.client.configurations.SchemaConfiguration; -import org.openapijsonschematools.client.schemas.MapJsonSchema; +import org.openapijsonschematools.client.exceptions.InvalidTypeException; import org.openapijsonschematools.client.schemas.StringJsonSchema; import org.openapijsonschematools.client.exceptions.ValidationException; @@ -14,8 +14,37 @@ import java.util.LinkedHashSet; import java.util.List; import java.util.Map; +import java.util.Set; public class PropertiesValidatorTest { + public static class ObjectWithPropsSchema extends JsonSchema { + private ObjectWithPropsSchema() { + super(new JsonSchemaInfo() + .type(Set.of(Map.class)) + .properties(Map.ofEntries( + new PropertyEntry("someString", StringJsonSchema.class) + )) + ); + + } + + @Override + public Object getNewInstance(@Nullable Object arg, List pathToItem, PathToSchemasMap pathToSchemas) { + if (arg instanceof Map mapArg) { + return getNewInstance(mapArg, pathToItem, pathToSchemas); + } + throw new InvalidTypeException("Invalid input type="+getClass(arg)+". It can't be instantiated by this schema"); + } + + @Override + public @Nullable Object validate(@Nullable Object arg, SchemaConfiguration configuration) throws InvalidTypeException, ValidationException { + if (arg instanceof Map mapArg) { + return validate(mapArg, configuration); + } + throw new InvalidTypeException("Invalid input type="+getClass(arg)+". It can't be validated by this schema"); + } + } + @SuppressWarnings("nullness") private void assertNull(@Nullable Object object) { Assert.assertNull(object); @@ -23,10 +52,7 @@ private void assertNull(@Nullable Object object) { @Test public void testCorrectPropertySucceeds() { - Map> properties = new LinkedHashMap<>(); - properties.put("someString", StringJsonSchema.class); - - final PropertiesValidator validator = new PropertiesValidator(properties); + final PropertiesValidator validator = new PropertiesValidator(); List pathToItem = List.of("args[0]"); ValidationMetadata validationMetadata = new ValidationMetadata( pathToItem, @@ -38,12 +64,11 @@ public void testCorrectPropertySucceeds() { mutableMap.put("someString", "abc"); FrozenMap arg = new FrozenMap<>(mutableMap); PathToSchemasMap pathToSchemas = validator.validate( - MapJsonSchema.getInstance(), - arg, - validationMetadata, - new ArrayList<>(), - new PathToSchemasMap(), - new PathToSchemasMap() + new ValidationData( + new ObjectWithPropsSchema(), + arg, + validationMetadata + ) ); if (pathToSchemas == null) { throw new RuntimeException("Invalid null value for pathToSchemas for this test case"); @@ -60,10 +85,7 @@ public void testCorrectPropertySucceeds() { @Test public void testNotApplicableTypeReturnsNull() { - Map> properties = new LinkedHashMap<>(); - properties.put("someString", StringJsonSchema.class); - - final PropertiesValidator validator = new PropertiesValidator(properties); + final PropertiesValidator validator = new PropertiesValidator(); List pathToItem = List.of("args[0]"); ValidationMetadata validationMetadata = new ValidationMetadata( pathToItem, @@ -72,22 +94,18 @@ public void testNotApplicableTypeReturnsNull() { new LinkedHashSet<>() ); PathToSchemasMap pathToSchemas = validator.validate( - MapJsonSchema.getInstance(), - 1, - validationMetadata, - new ArrayList<>(), - new PathToSchemasMap(), - new PathToSchemasMap() + new ValidationData( + new ObjectWithPropsSchema(), + 1, + validationMetadata + ) ); assertNull(pathToSchemas); } @Test public void testIncorrectPropertyValueFails() { - Map> properties = new LinkedHashMap<>(); - properties.put("someString", StringJsonSchema.class); - - final PropertiesValidator validator = new PropertiesValidator(properties); + final PropertiesValidator validator = new PropertiesValidator(); List pathToItem = List.of("args[0]"); ValidationMetadata validationMetadata = new ValidationMetadata( pathToItem, @@ -99,12 +117,11 @@ public void testIncorrectPropertyValueFails() { mutableMap.put("someString", 1); FrozenMap arg = new FrozenMap<>(mutableMap); Assert.assertThrows(ValidationException.class, () -> validator.validate( - MapJsonSchema.getInstance(), - arg, - validationMetadata, - new ArrayList<>(), - new PathToSchemasMap(), - new PathToSchemasMap() + new ValidationData( + new ObjectWithPropsSchema(), + arg, + validationMetadata + ) )); } } \ No newline at end of file diff --git a/samples/client/petstore/java/src/test/java/org/openapijsonschematools/client/schemas/validation/RequiredValidatorTest.java b/samples/client/petstore/java/src/test/java/org/openapijsonschematools/client/schemas/validation/RequiredValidatorTest.java index 2c26d7c7954..d2264b9a967 100644 --- a/samples/client/petstore/java/src/test/java/org/openapijsonschematools/client/schemas/validation/RequiredValidatorTest.java +++ b/samples/client/petstore/java/src/test/java/org/openapijsonschematools/client/schemas/validation/RequiredValidatorTest.java @@ -5,16 +5,42 @@ import org.junit.Test; import org.openapijsonschematools.client.configurations.JsonSchemaKeywordFlags; import org.openapijsonschematools.client.configurations.SchemaConfiguration; +import org.openapijsonschematools.client.exceptions.InvalidTypeException; import org.openapijsonschematools.client.exceptions.ValidationException; -import org.openapijsonschematools.client.schemas.MapJsonSchema; -import java.util.ArrayList; import java.util.LinkedHashMap; import java.util.LinkedHashSet; import java.util.List; +import java.util.Map; import java.util.Set; public class RequiredValidatorTest { + public static class ObjectWithRequiredSchema extends JsonSchema { + private ObjectWithRequiredSchema() { + super(new JsonSchemaInfo() + .type(Set.of(Map.class)) + .required(Set.of("someString")) + ); + + } + + @Override + public Object getNewInstance(@Nullable Object arg, List pathToItem, PathToSchemasMap pathToSchemas) { + if (arg instanceof Map mapArg) { + return getNewInstance(mapArg, pathToItem, pathToSchemas); + } + throw new InvalidTypeException("Invalid input type="+getClass(arg)+". It can't be instantiated by this schema"); + } + + @Override + public @Nullable Object validate(@Nullable Object arg, SchemaConfiguration configuration) throws InvalidTypeException, ValidationException { + if (arg instanceof Map mapArg) { + return validate(mapArg, configuration); + } + throw new InvalidTypeException("Invalid input type="+getClass(arg)+". It can't be validated by this schema"); + } + } + @SuppressWarnings("nullness") private void assertNull(@Nullable Object object) { Assert.assertNull(object); @@ -22,9 +48,6 @@ private void assertNull(@Nullable Object object) { @Test public void testCorrectPropertySucceeds() { - Set requiredProperties = new LinkedHashSet<>(); - requiredProperties.add("someString"); - List pathToItem = List.of("args[0]"); ValidationMetadata validationMetadata = new ValidationMetadata( pathToItem, @@ -35,23 +58,19 @@ public void testCorrectPropertySucceeds() { LinkedHashMap mutableMap = new LinkedHashMap<>(); mutableMap.put("someString", "abc"); FrozenMap arg = new FrozenMap<>(mutableMap); - final RequiredValidator validator = new RequiredValidator(requiredProperties); + final RequiredValidator validator = new RequiredValidator(); PathToSchemasMap pathToSchemas = validator.validate( - MapJsonSchema.getInstance(), - arg, - validationMetadata, - new ArrayList<>(), - new PathToSchemasMap(), - new PathToSchemasMap() + new ValidationData( + new ObjectWithRequiredSchema(), + arg, + validationMetadata + ) ); assertNull(pathToSchemas); } @Test public void testNotApplicableTypeReturnsNull() { - Set requiredProperties = new LinkedHashSet<>(); - requiredProperties.add("someString"); - List pathToItem = List.of("args[0]"); ValidationMetadata validationMetadata = new ValidationMetadata( pathToItem, @@ -59,23 +78,19 @@ public void testNotApplicableTypeReturnsNull() { new PathToSchemasMap(), new LinkedHashSet<>() ); - final RequiredValidator validator = new RequiredValidator(requiredProperties); + final RequiredValidator validator = new RequiredValidator(); PathToSchemasMap pathToSchemas = validator.validate( - MapJsonSchema.getInstance(), - 1, - validationMetadata, - new ArrayList<>(), - new PathToSchemasMap(), - new PathToSchemasMap() + new ValidationData( + new ObjectWithRequiredSchema(), + 1, + validationMetadata + ) ); assertNull(pathToSchemas); } @Test public void testIncorrectPropertyFails() { - Set requiredProperties = new LinkedHashSet<>(); - requiredProperties.add("someString"); - List pathToItem = List.of("args[0]"); ValidationMetadata validationMetadata = new ValidationMetadata( pathToItem, @@ -86,14 +101,13 @@ public void testIncorrectPropertyFails() { LinkedHashMap mutableMap = new LinkedHashMap<>(); mutableMap.put("aDifferentProp", 1); FrozenMap arg = new FrozenMap<>(mutableMap); - final RequiredValidator validator = new RequiredValidator(requiredProperties); + final RequiredValidator validator = new RequiredValidator(); Assert.assertThrows(ValidationException.class, () -> validator.validate( - MapJsonSchema.getInstance(), - arg, - validationMetadata, - new ArrayList<>(), - new PathToSchemasMap(), - new PathToSchemasMap() + new ValidationData( + new ObjectWithRequiredSchema(), + arg, + validationMetadata + ) )); } } \ No newline at end of file diff --git a/samples/client/petstore/java/src/test/java/org/openapijsonschematools/client/schemas/validation/TypeValidatorTest.java b/samples/client/petstore/java/src/test/java/org/openapijsonschematools/client/schemas/validation/TypeValidatorTest.java index 48433e51455..78a48b6374f 100644 --- a/samples/client/petstore/java/src/test/java/org/openapijsonschematools/client/schemas/validation/TypeValidatorTest.java +++ b/samples/client/petstore/java/src/test/java/org/openapijsonschematools/client/schemas/validation/TypeValidatorTest.java @@ -19,9 +19,7 @@ private void assertNull(@Nullable Object object) { @Test public void testValidateSucceeds() { - LinkedHashSet> type = new LinkedHashSet<>(); - type.add(String.class); - final TypeValidator validator = new TypeValidator(type); + final TypeValidator validator = new TypeValidator(); ValidationMetadata validationMetadata = new ValidationMetadata( new ArrayList<>(), new SchemaConfiguration(JsonSchemaKeywordFlags.ofNone()), @@ -29,21 +27,18 @@ public void testValidateSucceeds() { new LinkedHashSet<>() ); @Nullable PathToSchemasMap pathToSchemasMap = validator.validate( - StringJsonSchema.getInstance(), - "hi", - validationMetadata, - new ArrayList<>(), - new PathToSchemasMap(), - new PathToSchemasMap() + new ValidationData( + StringJsonSchema.getInstance(), + "hi", + validationMetadata + ) ); assertNull(pathToSchemasMap); } @Test public void testValidateFailsIntIsNotString() { - LinkedHashSet> type = new LinkedHashSet<>(); - type.add(String.class); - final TypeValidator validator = new TypeValidator(type); + final TypeValidator validator = new TypeValidator(); ValidationMetadata validationMetadata = new ValidationMetadata( new ArrayList<>(), new SchemaConfiguration(JsonSchemaKeywordFlags.ofNone()), @@ -51,12 +46,11 @@ public void testValidateFailsIntIsNotString() { new LinkedHashSet<>() ); Assert.assertThrows(ValidationException.class, () -> validator.validate( - StringJsonSchema.getInstance(), - 1, - validationMetadata, - new ArrayList<>(), - new PathToSchemasMap(), - new PathToSchemasMap() + new ValidationData( + StringJsonSchema.getInstance(), + 1, + validationMetadata + ) )); } } \ 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 b2aadbde0fc..4f6b21d2543 100644 --- a/src/main/java/org/openapijsonschematools/codegen/generators/JavaClientGenerator.java +++ b/src/main/java/org/openapijsonschematools/codegen/generators/JavaClientGenerator.java @@ -625,6 +625,7 @@ public void processOpts() { keywordValidatorFiles.add("TypeValidator"); keywordValidatorFiles.add("UniqueItemsValidator"); keywordValidatorFiles.add("UnsetAnyTypeJsonSchema"); + keywordValidatorFiles.add("ValidationData"); keywordValidatorFiles.add("ValidationMetadata"); for (String keywordValidatorFile: keywordValidatorFiles) { supportingFiles.add(new SupportingFile( diff --git a/src/main/resources/java/src/main/java/packagename/schemas/validation/AdditionalPropertiesValidator.hbs b/src/main/resources/java/src/main/java/packagename/schemas/validation/AdditionalPropertiesValidator.hbs index 643b6496c4b..4afe7f25942 100644 --- a/src/main/resources/java/src/main/java/packagename/schemas/validation/AdditionalPropertiesValidator.hbs +++ b/src/main/resources/java/src/main/java/packagename/schemas/validation/AdditionalPropertiesValidator.hbs @@ -8,22 +8,15 @@ import java.util.Map; import java.util.Set; public class AdditionalPropertiesValidator implements KeywordValidator { - public final Class additionalProperties; - - public AdditionalPropertiesValidator(Class additionalProperties) { - this.additionalProperties = additionalProperties; - } - @Override public @Nullable PathToSchemasMap validate( - JsonSchema schema, - @Nullable Object arg, - ValidationMetadata validationMetadata, - @Nullable List containsPathToSchemas, - @Nullable PathToSchemasMap patternPropertiesPathToSchemas, - @Nullable PathToSchemasMap ifPathToSchemas + ValidationData data ) { - if (!(arg instanceof Map mapArg)) { + if (!(data.arg() instanceof Map mapArg)) { + return null; + } + var additionalProperties = data.schema().additionalProperties; + if (additionalProperties == null) { return null; } Set presentAdditionalProperties = new LinkedHashSet<>(); @@ -32,22 +25,23 @@ public class AdditionalPropertiesValidator implements KeywordValidator { presentAdditionalProperties.add((String) key); } } - if (schema.properties != null) { - presentAdditionalProperties.removeAll(schema.properties.keySet()); + var properties = data.schema().properties; + if (properties != null) { + presentAdditionalProperties.removeAll(properties.keySet()); } PathToSchemasMap pathToSchemas = new PathToSchemasMap(); for(String addPropName: presentAdditionalProperties) { @Nullable Object propValue = mapArg.get(addPropName); - List propPathToItem = new ArrayList<>(validationMetadata.pathToItem()); + List propPathToItem = new ArrayList<>(data.validationMetadata().pathToItem()); propPathToItem.add(addPropName); - if (patternPropertiesPathToSchemas != null && patternPropertiesPathToSchemas.containsKey(propPathToItem)) { + if (data.patternPropertiesPathToSchemas() != null && data.patternPropertiesPathToSchemas().containsKey(propPathToItem)) { continue; } ValidationMetadata propValidationMetadata = new ValidationMetadata( propPathToItem, - validationMetadata.configuration(), - validationMetadata.validatedPathToSchemas(), - validationMetadata.seenClasses() + data.validationMetadata().configuration(), + data.validationMetadata().validatedPathToSchemas(), + data.validationMetadata().seenClasses() ); JsonSchema addPropsSchema = JsonSchemaFactory.getInstance(additionalProperties); if (propValidationMetadata.validationRanEarlier(addPropsSchema)) { diff --git a/src/main/resources/java/src/main/java/packagename/schemas/validation/AllOfValidator.hbs b/src/main/resources/java/src/main/java/packagename/schemas/validation/AllOfValidator.hbs index 505d16c9096..6ae68f5c87c 100644 --- a/src/main/resources/java/src/main/java/packagename/schemas/validation/AllOfValidator.hbs +++ b/src/main/resources/java/src/main/java/packagename/schemas/validation/AllOfValidator.hbs @@ -1,32 +1,21 @@ package {{{packageName}}}.schemas.validation; import org.checkerframework.checker.nullness.qual.Nullable; -import java.util.List; - public class AllOfValidator implements KeywordValidator { - public final List> allOf; - - public AllOfValidator(List> allOf) { - this.allOf = allOf; - } - @Override public @Nullable PathToSchemasMap validate( - JsonSchema schema, - @Nullable Object arg, - ValidationMetadata validationMetadata, - @Nullable List containsPathToSchemas, - @Nullable PathToSchemasMap patternPropertiesPathToSchemas, - @Nullable PathToSchemasMap ifPathToSchemas + ValidationData data ) { + var allOf = data.schema().allOf; + if (allOf == null) { + return null; + } PathToSchemasMap pathToSchemas = new PathToSchemasMap(); for(Class allOfClass: allOf) { JsonSchema allOfSchema = JsonSchemaFactory.getInstance(allOfClass); - PathToSchemasMap otherPathToSchemas = JsonSchema.validate(allOfSchema, arg, validationMetadata); + PathToSchemasMap otherPathToSchemas = JsonSchema.validate(allOfSchema, data.arg(), data.validationMetadata()); pathToSchemas.update(otherPathToSchemas); } return pathToSchemas; } - - } diff --git a/src/main/resources/java/src/main/java/packagename/schemas/validation/AnyOfValidator.hbs b/src/main/resources/java/src/main/java/packagename/schemas/validation/AnyOfValidator.hbs index 5c838eea6e8..bfd75e7433b 100644 --- a/src/main/resources/java/src/main/java/packagename/schemas/validation/AnyOfValidator.hbs +++ b/src/main/resources/java/src/main/java/packagename/schemas/validation/AnyOfValidator.hbs @@ -7,25 +7,18 @@ import java.util.ArrayList; import java.util.List; public class AnyOfValidator implements KeywordValidator { - public final List> anyOf; - - public AnyOfValidator(List> anyOf) { - this.anyOf = anyOf; - } - @Override public @Nullable PathToSchemasMap validate( - JsonSchema schema, - @Nullable Object arg, - ValidationMetadata validationMetadata, - @Nullable List containsPathToSchemas, - @Nullable PathToSchemasMap patternPropertiesPathToSchemas, - @Nullable PathToSchemasMap ifPathToSchemas + ValidationData data ) { + var anyOf = data.schema().anyOf; + if (anyOf == null) { + return null; + } PathToSchemasMap pathToSchemas = new PathToSchemasMap(); List> validatedAnyOfClasses = new ArrayList<>(); for(Class anyOfClass: anyOf) { - if (anyOfClass == schema.getClass()) { + if (anyOfClass == data.schema().getClass()) { /* optimistically assume that schema will pass validation do not invoke _validate on it because that is recursive @@ -35,7 +28,7 @@ public class AnyOfValidator implements KeywordValidator { } try { JsonSchema anyOfSchema = JsonSchemaFactory.getInstance(anyOfClass); - PathToSchemasMap otherPathToSchemas = JsonSchema.validate(anyOfSchema, arg, validationMetadata); + PathToSchemasMap otherPathToSchemas = JsonSchema.validate(anyOfSchema, data.arg(), data.validationMetadata()); validatedAnyOfClasses.add(anyOfClass); pathToSchemas.update(otherPathToSchemas); } catch (ValidationException e) { @@ -43,7 +36,7 @@ public class AnyOfValidator implements KeywordValidator { } } if (validatedAnyOfClasses.isEmpty()) { - throw new ValidationException("Invalid inputs given to generate an instance of "+schema.getClass()+". None "+ + throw new ValidationException("Invalid inputs given to generate an instance of "+data.schema().getClass()+". None "+ "of the anyOf schemas matched the input data." ); } diff --git a/src/main/resources/java/src/main/java/packagename/schemas/validation/ConstValidator.hbs b/src/main/resources/java/src/main/java/packagename/schemas/validation/ConstValidator.hbs index 26874dbc717..bd74714857c 100644 --- a/src/main/resources/java/src/main/java/packagename/schemas/validation/ConstValidator.hbs +++ b/src/main/resources/java/src/main/java/packagename/schemas/validation/ConstValidator.hbs @@ -4,27 +4,19 @@ import {{{packageName}}}.exceptions.ValidationException; import org.checkerframework.checker.nullness.qual.Nullable; import java.math.BigDecimal; -import java.util.List; import java.util.Objects; public class ConstValidator extends BigDecimalValidator implements KeywordValidator { - public final @Nullable Object constValue; - - public ConstValidator(@Nullable Object constValue) { - this.constValue = constValue; - } - @Override public @Nullable PathToSchemasMap validate( - JsonSchema schema, - @Nullable Object arg, - ValidationMetadata validationMetadata, - @Nullable List containsPathToSchemas, - @Nullable PathToSchemasMap patternPropertiesPathToSchemas, - @Nullable PathToSchemasMap ifPathToSchemas + ValidationData data ) { - if (arg instanceof Number) { - BigDecimal castArg = getBigDecimal((Number) arg); + if (!data.schema().constValueSet) { + return null; + } + var constValue = data.schema().constValue; + if (data.arg() instanceof Number numberArg) { + BigDecimal castArg = getBigDecimal(numberArg); if (Objects.equals(castArg, constValue)) { return null; } @@ -32,10 +24,10 @@ public class ConstValidator extends BigDecimalValidator implements KeywordValida return null; } } else { - if (Objects.equals(arg, constValue)) { + if (Objects.equals(data.arg(), constValue)) { return null; } } - throw new ValidationException("Invalid value "+arg+" was not equal to const "+constValue); + throw new ValidationException("Invalid value "+data.arg()+" was not equal to const "+constValue); } -} +} \ No newline at end of file diff --git a/src/main/resources/java/src/main/java/packagename/schemas/validation/ContainsValidator.hbs b/src/main/resources/java/src/main/java/packagename/schemas/validation/ContainsValidator.hbs index 664d34edcf5..727dd1b9e5f 100644 --- a/src/main/resources/java/src/main/java/packagename/schemas/validation/ContainsValidator.hbs +++ b/src/main/resources/java/src/main/java/packagename/schemas/validation/ContainsValidator.hbs @@ -3,32 +3,21 @@ package {{{packageName}}}.schemas.validation; import org.checkerframework.checker.nullness.qual.Nullable; import {{{packageName}}}.exceptions.ValidationException; -import java.util.ArrayList; import java.util.List; public class ContainsValidator implements KeywordValidator { - public final Class contains; - - public ContainsValidator(Class contains) { - this.contains = contains; - } - @Override public @Nullable PathToSchemasMap validate( - JsonSchema schema, - @Nullable Object arg, - ValidationMetadata validationMetadata, - @Nullable List containsPathToSchemas, - @Nullable PathToSchemasMap patternPropertiesPathToSchemas, - @Nullable PathToSchemasMap ifPathToSchemas + ValidationData data ) { - if (!(arg instanceof List)) { + if (!(data.arg() instanceof List)) { return null; } + var containsPathToSchemas = data.containsPathToSchemas(); if (containsPathToSchemas == null || containsPathToSchemas.isEmpty()) { throw new ValidationException( - "Validation failed for contains keyword in class="+schema.getClass() - + " at pathToItem="+validationMetadata.pathToItem()+". No " + "Validation failed for contains keyword in class="+data.schema().getClass() + + " at pathToItem="+data.validationMetadata().pathToItem()+". No " + "items validated to the contains schema." ); } @@ -38,42 +27,4 @@ public class ContainsValidator implements KeywordValidator { } return pathToSchemas; } - - public List getContainsPathToSchemas( - @Nullable Object arg, - ValidationMetadata validationMetadata - ) { - if (!(arg instanceof List)) { - return new ArrayList<>(); - } - @Nullable List containsPathToSchemas = new ArrayList<>(); - int i = 0; - for(Object itemValue: (List) arg) { - PathToSchemasMap thesePathToSchemas = new PathToSchemasMap(); - List itemPathToItem = new ArrayList<>(validationMetadata.pathToItem()); - itemPathToItem.add(i); - ValidationMetadata itemValidationMetadata = new ValidationMetadata( - itemPathToItem, - validationMetadata.configuration(), - validationMetadata.validatedPathToSchemas(), - validationMetadata.seenClasses() - ); - JsonSchema containsSchema = JsonSchemaFactory.getInstance(contains); - if (itemValidationMetadata.validationRanEarlier(containsSchema)) { - // todo add_deeper_validated_schemas - containsPathToSchemas.add(thesePathToSchemas); - i += 1; - continue; - } - - try { - PathToSchemasMap otherPathToSchemas = JsonSchema.validate( - containsSchema, itemValue, itemValidationMetadata); - containsPathToSchemas.add(otherPathToSchemas); - } catch (ValidationException ignored) { - ; - } - } - return containsPathToSchemas; - } } \ No newline at end of file diff --git a/src/main/resources/java/src/main/java/packagename/schemas/validation/DependentRequiredValidator.hbs b/src/main/resources/java/src/main/java/packagename/schemas/validation/DependentRequiredValidator.hbs index d100dddd2af..c304af27833 100644 --- a/src/main/resources/java/src/main/java/packagename/schemas/validation/DependentRequiredValidator.hbs +++ b/src/main/resources/java/src/main/java/packagename/schemas/validation/DependentRequiredValidator.hbs @@ -4,35 +4,27 @@ import org.checkerframework.checker.nullness.qual.Nullable; import {{{packageName}}}.exceptions.ValidationException; import java.util.HashSet; -import java.util.List; import java.util.Map; import java.util.Set; public class DependentRequiredValidator implements KeywordValidator { - public final Map> dependentRequired; - - public DependentRequiredValidator(Map> dependentRequired) { - this.dependentRequired = dependentRequired; - } - @Override public @Nullable PathToSchemasMap validate( - JsonSchema schema, - @Nullable Object arg, - ValidationMetadata validationMetadata, - @Nullable List containsPathToSchemas, - @Nullable PathToSchemasMap patternPropertiesPathToSchemas, - @Nullable PathToSchemasMap ifPathToSchemas + ValidationData data ) { - if (!(arg instanceof Map)) { + if (!(data.arg() instanceof Map mapArg)) { + return null; + } + var dependentRequired = data.schema().dependentRequired; + if (dependentRequired == null) { return null; } for (Map.Entry> entry: dependentRequired.entrySet()) { - if (!((Map) arg).containsKey(entry.getKey())) { + if (!mapArg.containsKey(entry.getKey())) { continue; } Set missingKeys = new HashSet<>(entry.getValue()); - for (Object objKey: ((Map) arg).keySet()) { + for (Object objKey: mapArg.keySet()) { if (objKey instanceof String key) { missingKeys.remove(key); } @@ -42,7 +34,7 @@ public class DependentRequiredValidator implements KeywordValidator { } throw new ValidationException( "Validation failed for dependentRequired because these_keys="+missingKeys+" are "+ - "missing at pathToItem="+validationMetadata.pathToItem()+" in class "+schema.getClass() + "missing at pathToItem="+data.validationMetadata().pathToItem()+" in class "+data.schema().getClass() ); } return null; 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 index 5e78857a6f8..79715b86929 100644 --- 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 @@ -2,29 +2,20 @@ 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, - @Nullable PathToSchemasMap patternPropertiesPathToSchemas, - @Nullable PathToSchemasMap ifPathToSchemas + ValidationData data ) { - if (!(arg instanceof Map mapArg)) { + if (!(data.arg() instanceof Map mapArg)) { + return null; + } + var dependentSchemas = data.schema().dependentSchemas; + if (dependentSchemas == null) { return null; } PathToSchemasMap pathToSchemas = new PathToSchemasMap(); @@ -41,10 +32,9 @@ public class DependentSchemasValidator implements KeywordValidator { } Class dependentSchemaClass = entry.getValue(); JsonSchema dependentSchema = JsonSchemaFactory.getInstance(dependentSchemaClass); - PathToSchemasMap otherPathToSchemas = JsonSchema.validate(dependentSchema, arg, validationMetadata); + PathToSchemasMap otherPathToSchemas = JsonSchema.validate(dependentSchema, mapArg, data.validationMetadata()); pathToSchemas.update(otherPathToSchemas); } return pathToSchemas; } } - diff --git a/src/main/resources/java/src/main/java/packagename/schemas/validation/EnumValidator.hbs b/src/main/resources/java/src/main/java/packagename/schemas/validation/EnumValidator.hbs index 9ebbb8359be..f3cc251e9c7 100644 --- a/src/main/resources/java/src/main/java/packagename/schemas/validation/EnumValidator.hbs +++ b/src/main/resources/java/src/main/java/packagename/schemas/validation/EnumValidator.hbs @@ -4,36 +4,28 @@ import {{{packageName}}}.exceptions.ValidationException; import org.checkerframework.checker.nullness.qual.Nullable; import java.math.BigDecimal; -import java.util.List; import java.util.Set; public class EnumValidator extends BigDecimalValidator implements KeywordValidator { - public final Set<@Nullable Object> enumValues; - - public EnumValidator(Set<@Nullable Object> enumValues) { - this.enumValues = enumValues; - } - @SuppressWarnings("nullness") - private boolean enumContainsArg(@Nullable Object arg){ + private static boolean enumContainsArg(Set<@Nullable Object> enumValues, @Nullable Object arg){ return enumValues.contains(arg); } @Override public @Nullable PathToSchemasMap validate( - JsonSchema schema, - @Nullable Object arg, - ValidationMetadata validationMetadata, - @Nullable List containsPathToSchemas, - @Nullable PathToSchemasMap patternPropertiesPathToSchemas, - @Nullable PathToSchemasMap ifPathToSchemas + ValidationData data ) { + var enumValues = data.schema().enumValues; + if (enumValues == null) { + return null; + } if (enumValues.isEmpty()) { throw new ValidationException("No value can match enum because enum is empty"); } - if (arg instanceof Number) { - BigDecimal castArg = getBigDecimal((Number) arg); - if (enumContainsArg(castArg)) { + if (data.arg() instanceof Number numberArg) { + BigDecimal castArg = getBigDecimal(numberArg); + if (enumContainsArg(enumValues, castArg)) { return null; } for (Object enumValue: enumValues) { @@ -42,10 +34,10 @@ public class EnumValidator extends BigDecimalValidator implements KeywordValidat } } } else { - if (enumContainsArg(arg)) { + if (enumContainsArg(enumValues, data.arg())) { return null; } } - throw new ValidationException("Invalid value "+arg+" was not one of the allowed enum "+enumValues); + throw new ValidationException("Invalid value "+data.arg()+" was not one of the allowed enum "+enumValues); } } diff --git a/src/main/resources/java/src/main/java/packagename/schemas/validation/ExclusiveMaximumValidator.hbs b/src/main/resources/java/src/main/java/packagename/schemas/validation/ExclusiveMaximumValidator.hbs index 933c3bbd8fe..56b8965aedc 100644 --- a/src/main/resources/java/src/main/java/packagename/schemas/validation/ExclusiveMaximumValidator.hbs +++ b/src/main/resources/java/src/main/java/packagename/schemas/validation/ExclusiveMaximumValidator.hbs @@ -3,48 +3,39 @@ package {{{packageName}}}.schemas.validation; import {{{packageName}}}.exceptions.ValidationException; import org.checkerframework.checker.nullness.qual.Nullable; -import java.util.List; - public class ExclusiveMaximumValidator implements KeywordValidator { - public final Number exclusiveMaximum; - - public ExclusiveMaximumValidator(Number exclusiveMaximum) { - this.exclusiveMaximum = exclusiveMaximum; - } - @Override public @Nullable PathToSchemasMap validate( - JsonSchema schema, - @Nullable Object arg, - ValidationMetadata validationMetadata, - @Nullable List containsPathToSchemas, - @Nullable PathToSchemasMap patternPropertiesPathToSchemas, - @Nullable PathToSchemasMap ifPathToSchemas + ValidationData data ) { - if (!(arg instanceof Number)) { + var exclusiveMaximum = data.schema().exclusiveMaximum; + if (exclusiveMaximum == null) { + return null; + } + if (!(data.arg() instanceof Number)) { return null; } - String msg = "Value " + arg + " is invalid because it is >= the exclusiveMaximum of " + exclusiveMaximum; - if (arg instanceof Integer) { - if (((Integer) arg).compareTo(exclusiveMaximum.intValue()) > -1) { + String msg = "Value " + data.arg() + " is invalid because it is >= the exclusiveMaximum of " + exclusiveMaximum; + if (data.arg() instanceof Integer intArg) { + if (intArg.compareTo(exclusiveMaximum.intValue()) > -1) { throw new ValidationException(msg); } return null; } - if (arg instanceof Long) { - if (((Long) arg).compareTo(exclusiveMaximum.longValue()) > -1) { + if (data.arg() instanceof Long longArg) { + if (longArg.compareTo(exclusiveMaximum.longValue()) > -1) { throw new ValidationException(msg); } return null; } - if (arg instanceof Float) { - if (((Float) arg).compareTo(exclusiveMaximum.floatValue()) > -1) { + if (data.arg() instanceof Float floatArg) { + if (floatArg.compareTo(exclusiveMaximum.floatValue()) > -1) { throw new ValidationException(msg); } return null; } - if (arg instanceof Double) { - if (((Double) arg).compareTo(exclusiveMaximum.doubleValue()) > -1) { + if (data.arg() instanceof Double doubleArg) { + if (doubleArg.compareTo(exclusiveMaximum.doubleValue()) > -1) { throw new ValidationException(msg); } return null; diff --git a/src/main/resources/java/src/main/java/packagename/schemas/validation/ExclusiveMinimumValidator.hbs b/src/main/resources/java/src/main/java/packagename/schemas/validation/ExclusiveMinimumValidator.hbs index 8b6ddb286c5..aad41595215 100644 --- a/src/main/resources/java/src/main/java/packagename/schemas/validation/ExclusiveMinimumValidator.hbs +++ b/src/main/resources/java/src/main/java/packagename/schemas/validation/ExclusiveMinimumValidator.hbs @@ -3,48 +3,39 @@ package {{{packageName}}}.schemas.validation; import {{{packageName}}}.exceptions.ValidationException; import org.checkerframework.checker.nullness.qual.Nullable; -import java.util.List; - public class ExclusiveMinimumValidator implements KeywordValidator { - public final Number exclusiveMinimum; - - public ExclusiveMinimumValidator(Number exclusiveMinimum) { - this.exclusiveMinimum = exclusiveMinimum; - } - @Override public @Nullable PathToSchemasMap validate( - JsonSchema schema, - @Nullable Object arg, - ValidationMetadata validationMetadata, - @Nullable List containsPathToSchemas, - @Nullable PathToSchemasMap patternPropertiesPathToSchemas, - @Nullable PathToSchemasMap ifPathToSchemas + ValidationData data ) { - if (!(arg instanceof Number)) { + var exclusiveMinimum = data.schema().exclusiveMinimum; + if (exclusiveMinimum == null) { + return null; + } + if (!(data.arg() instanceof Number)) { return null; } - String msg = "Value " + arg + " is invalid because it is <= the exclusiveMinimum of " + exclusiveMinimum; - if (arg instanceof Integer) { - if (((Integer) arg).compareTo(exclusiveMinimum.intValue()) < 1) { + String msg = "Value " + data.arg() + " is invalid because it is <= the exclusiveMinimum of " + exclusiveMinimum; + if (data.arg() instanceof Integer intArg) { + if (intArg.compareTo(exclusiveMinimum.intValue()) < 1) { throw new ValidationException(msg); } return null; } - if (arg instanceof Long) { - if (((Long) arg).compareTo(exclusiveMinimum.longValue()) < 1) { + if (data.arg() instanceof Long longArg) { + if (longArg.compareTo(exclusiveMinimum.longValue()) < 1) { throw new ValidationException(msg); } return null; } - if (arg instanceof Float) { - if (((Float) arg).compareTo(exclusiveMinimum.floatValue()) < 1) { + if (data.arg() instanceof Float floatArg) { + if (floatArg.compareTo(exclusiveMinimum.floatValue()) < 1) { throw new ValidationException(msg); } return null; } - if (arg instanceof Double) { - if (((Double) arg).compareTo(exclusiveMinimum.doubleValue()) < 1) { + if (data.arg() instanceof Double doubleArg) { + if (doubleArg.compareTo(exclusiveMinimum.doubleValue()) < 1) { throw new ValidationException(msg); } return null; diff --git a/src/main/resources/java/src/main/java/packagename/schemas/validation/FormatValidator.hbs b/src/main/resources/java/src/main/java/packagename/schemas/validation/FormatValidator.hbs index e3a03aebd6a..859da3127df 100644 --- a/src/main/resources/java/src/main/java/packagename/schemas/validation/FormatValidator.hbs +++ b/src/main/resources/java/src/main/java/packagename/schemas/validation/FormatValidator.hbs @@ -6,16 +6,9 @@ import org.checkerframework.checker.nullness.qual.Nullable; import java.math.BigDecimal; import java.math.BigInteger; import java.time.format.DateTimeParseException; -import java.util.List; import java.util.UUID; public class FormatValidator implements KeywordValidator { - public final String format; - - public FormatValidator(String format) { - this.format = format; - } - private final static BigInteger int32InclusiveMinimum = BigInteger.valueOf(-2147483648L); private final static BigInteger int32InclusiveMaximum = BigInteger.valueOf(2147483647L); private final static BigInteger int64InclusiveMinimum = BigInteger.valueOf(-9223372036854775808L); @@ -25,12 +18,12 @@ public class FormatValidator implements KeywordValidator { private final static BigDecimal doubleInclusiveMinimum = BigDecimal.valueOf(-1.7976931348623157E+308d); private final static BigDecimal doubleInclusiveMaximum = BigDecimal.valueOf(1.7976931348623157E+308d); - private Void validateNumericFormat(Number arg, ValidationMetadata validationMetadata) { + private static void validateNumericFormat(Number arg, ValidationMetadata validationMetadata, String format) { if (format.startsWith("int")) { // there is a json schema test where 1.0 validates as an integer BigInteger intArg; if (arg instanceof Float || arg instanceof Double) { - Double doubleArg; + double doubleArg; if (arg instanceof Float) { doubleArg = arg.doubleValue(); } else { @@ -60,20 +53,17 @@ public class FormatValidator implements KeywordValidator { "Invalid value " + arg + " for format int32 at " + validationMetadata.pathToItem() ); } - return null; } else if (format.equals("int64")) { if (intArg.compareTo(int64InclusiveMinimum) < 0 || intArg.compareTo(int64InclusiveMaximum) > 0) { throw new ValidationException( "Invalid value " + arg + " for format int64 at " + validationMetadata.pathToItem() ); } - return null; } - return null; } else if (format.equals("float") || format.equals("double")) { BigDecimal decimalArg; if (arg instanceof Float) { - decimalArg = new BigDecimal((Float) arg); + decimalArg = BigDecimal.valueOf(arg.doubleValue()); } else if (arg instanceof Double) { decimalArg = BigDecimal.valueOf((Double) arg); } else { @@ -85,83 +75,81 @@ public class FormatValidator implements KeywordValidator { "Invalid value "+arg+" for format float at "+validationMetadata.pathToItem() ); } - return null; - } else if (format.equals("double")) { + } else { if (decimalArg.compareTo(doubleInclusiveMinimum) < 0 || decimalArg.compareTo(doubleInclusiveMaximum) > 0 ){ throw new ValidationException( "Invalid value "+arg+" for format double at "+validationMetadata.pathToItem() ); } - return null; } } - return null; } - private Void validateStringFormat(String arg, ValidationMetadata validationMetadata) { - if (format.equals("uuid")) { - try { - UUID.fromString(arg); - } catch (IllegalArgumentException e) { - throw new ValidationException( - "Value cannot be converted to a UUID. Invalid value "+ - arg+" for format uuid at "+validationMetadata.pathToItem() - ); + private static void validateStringFormat(String arg, ValidationMetadata validationMetadata, String format) { + switch (format) { + case "uuid" -> { + try { + UUID.fromString(arg); + } catch (IllegalArgumentException e) { + throw new ValidationException( + "Value cannot be converted to a UUID. Invalid value " + + arg + " for format uuid at " + validationMetadata.pathToItem() + ); + } } - return null; - } else if (format.equals("number")) { - try { - new BigDecimal(arg); - } catch (NumberFormatException e) { - throw new ValidationException( - "Value cannot be converted to a decimal. Invalid value "+ - arg+" for format number at "+validationMetadata.pathToItem() - ); + case "number" -> { + try { + new BigDecimal(arg); + } catch (NumberFormatException e) { + throw new ValidationException( + "Value cannot be converted to a decimal. Invalid value " + + arg + " for format number at " + validationMetadata.pathToItem() + ); + } } - return null; - } else if (format.equals("date")) { - try { - new CustomIsoparser().parseIsodate(arg); - } catch (DateTimeParseException e) { - throw new ValidationException( - "Value does not conform to the required ISO-8601 date format. "+ - "Invalid value "+arg+" for format date at "+validationMetadata.pathToItem() - ); + case "date" -> { + try { + new CustomIsoparser().parseIsodate(arg); + } catch (DateTimeParseException e) { + throw new ValidationException( + "Value does not conform to the required ISO-8601 date format. " + + "Invalid value " + arg + " for format date at " + validationMetadata.pathToItem() + ); + } } - return null; - } else if (format.equals("date-time")) { - try { - new CustomIsoparser().parseIsodatetime(arg); - } catch (DateTimeParseException e) { - throw new ValidationException( - "Value does not conform to the required ISO-8601 datetime format. "+ - "Invalid value "+arg+" for format datetime at "+validationMetadata.pathToItem() - ); + case "date-time" -> { + try { + new CustomIsoparser().parseIsodatetime(arg); + } catch (DateTimeParseException e) { + throw new ValidationException( + "Value does not conform to the required ISO-8601 datetime format. " + + "Invalid value " + arg + " for format datetime at " + validationMetadata.pathToItem() + ); + } } - return null; } - return null; } @Override public @Nullable PathToSchemasMap validate( - JsonSchema schema, - @Nullable Object arg, - ValidationMetadata validationMetadata, - @Nullable List containsPathToSchemas, - @Nullable PathToSchemasMap patternPropertiesPathToSchemas, - @Nullable PathToSchemasMap ifPathToSchemas + ValidationData data ) { - if (arg instanceof Number) { + var format = data.schema().format; + if (format == null) { + return null; + } + if (data.arg() instanceof Number numberArg) { validateNumericFormat( - (Number) arg, - validationMetadata + numberArg, + data.validationMetadata(), + format ); return null; - } else if (arg instanceof String) { + } else if (data.arg() instanceof String stringArg) { validateStringFormat( - (String) arg, - validationMetadata + stringArg, + data.validationMetadata(), + format ); return null; } diff --git a/src/main/resources/java/src/main/java/packagename/schemas/validation/IfValidator.hbs b/src/main/resources/java/src/main/java/packagename/schemas/validation/IfValidator.hbs index 5b174883b2b..f96f1770d7d 100644 --- a/src/main/resources/java/src/main/java/packagename/schemas/validation/IfValidator.hbs +++ b/src/main/resources/java/src/main/java/packagename/schemas/validation/IfValidator.hbs @@ -1,33 +1,18 @@ package {{{packageName}}}.schemas.validation; import {{{packageName}}}.exceptions.ValidationException; -import {{{packageName}}}.exceptions.InvalidTypeException; import org.checkerframework.checker.nullness.qual.Nullable; -import java.util.ArrayList; -import java.util.LinkedHashMap; -import java.util.LinkedHashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; - public class IfValidator implements KeywordValidator { - public final Class ifSchema; - - public IfValidator(Class ifSchema) { - this.ifSchema = ifSchema; - } - @Override public @Nullable PathToSchemasMap validate( - JsonSchema schema, - @Nullable Object arg, - ValidationMetadata validationMetadata, - @Nullable List containsPathToSchemas, - @Nullable PathToSchemasMap patternPropertiesPathToSchemas, - @Nullable PathToSchemasMap ifPathToSchemas + ValidationData data ) { - if (ifPathToSchemas == null) { + var ifSchema = data.schema().ifSchema; + if (ifSchema == null) { + return null; + } + if (data.ifPathToSchemas() == null) { throw new ValidationException("Invalid type for ifPathToSchemas"); } /* @@ -40,17 +25,4 @@ public class IfValidator implements KeywordValidator { */ return null; } - - public PathToSchemasMap getIfPathToSchemas( - @Nullable Object arg, - ValidationMetadata validationMetadata - ) { - JsonSchema ifSchemaInstance = JsonSchemaFactory.getInstance(ifSchema); - PathToSchemasMap pathToSchemas = new PathToSchemasMap(); - try { - var otherPathToSchemas = JsonSchema.validate(ifSchemaInstance, arg, validationMetadata); - pathToSchemas.update(otherPathToSchemas); - } catch (ValidationException | InvalidTypeException ignored) {} - return pathToSchemas; - } } diff --git a/src/main/resources/java/src/main/java/packagename/schemas/validation/ItemsValidator.hbs b/src/main/resources/java/src/main/java/packagename/schemas/validation/ItemsValidator.hbs index 8f97f9bff13..fe4ca51f048 100644 --- a/src/main/resources/java/src/main/java/packagename/schemas/validation/ItemsValidator.hbs +++ b/src/main/resources/java/src/main/java/packagename/schemas/validation/ItemsValidator.hbs @@ -6,38 +6,31 @@ import java.util.ArrayList; import java.util.List; public class ItemsValidator implements KeywordValidator { - public final Class items; - - public ItemsValidator(Class items) { - this.items = items; - } - @Override public @Nullable PathToSchemasMap validate( - JsonSchema schema, - @Nullable Object arg, - ValidationMetadata validationMetadata, - @Nullable List containsPathToSchemas, - @Nullable PathToSchemasMap patternPropertiesPathToSchemas, - @Nullable PathToSchemasMap ifPathToSchemas + ValidationData data ) { - if (!(arg instanceof List listArg)) { + var items = data.schema().items; + if (items == null) { + return null; + } + if (!(data.arg() instanceof List listArg)) { return null; } if (listArg.isEmpty()) { return null; } PathToSchemasMap pathToSchemas = new PathToSchemasMap(); - int minIndex = schema.prefixItems != null ? schema.prefixItems.size() : 0; + int minIndex = data.schema().prefixItems != null ? data.schema().prefixItems.size() : 0; JsonSchema itemsSchema = JsonSchemaFactory.getInstance(items); for(int i = minIndex; i < listArg.size(); i++) { - List itemPathToItem = new ArrayList<>(validationMetadata.pathToItem()); + List itemPathToItem = new ArrayList<>(data.validationMetadata().pathToItem()); itemPathToItem.add(i); ValidationMetadata itemValidationMetadata = new ValidationMetadata( itemPathToItem, - validationMetadata.configuration(), - validationMetadata.validatedPathToSchemas(), - validationMetadata.seenClasses() + data.validationMetadata().configuration(), + data.validationMetadata().validatedPathToSchemas(), + data.validationMetadata().seenClasses() ); if (itemValidationMetadata.validationRanEarlier(itemsSchema)) { // todo add_deeper_validated_schemas 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 e0af16453e0..8dee0c40f0b 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 @@ -50,10 +50,10 @@ public abstract class JsonSchema { public final @Nullable Integer maxContains; public final @Nullable Integer minContains; public final @Nullable Class propertyNames; - public @Nullable Map> dependentRequired; + public final @Nullable Map> dependentRequired; public final @Nullable Map> dependentSchemas; - public @Nullable Map> patternProperties; - public @Nullable List> prefixItems; + public final @Nullable Map> patternProperties; + public final @Nullable List> prefixItems; public final @Nullable Class ifSchema; private final LinkedHashMap keywordToValidator; @@ -61,244 +61,142 @@ public abstract class JsonSchema { LinkedHashMap keywordToValidator = new LinkedHashMap<>(); this.type = jsonSchemaInfo.type; if (this.type != null) { - keywordToValidator.put( - "type", - new TypeValidator(this.type) - ); + keywordToValidator.put("type", new TypeValidator()); } this.format = jsonSchemaInfo.format; if (this.format != null) { - keywordToValidator.put( - "format", - new FormatValidator(this.format) - ); + keywordToValidator.put("format", new FormatValidator()); } this.items = jsonSchemaInfo.items; if (this.items != null) { - keywordToValidator.put( - "items", - new ItemsValidator(this.items) - ); + keywordToValidator.put("items", new ItemsValidator()); } this.properties = jsonSchemaInfo.properties; if (this.properties != null) { - keywordToValidator.put( - "properties", - new PropertiesValidator(this.properties) - ); + keywordToValidator.put("properties", new PropertiesValidator()); } this.required = jsonSchemaInfo.required; if (this.required != null) { - keywordToValidator.put( - "required", - new RequiredValidator(this.required) - ); + keywordToValidator.put("required", new RequiredValidator()); } this.exclusiveMaximum = jsonSchemaInfo.exclusiveMaximum; if (this.exclusiveMaximum != null) { - keywordToValidator.put( - "exclusiveMaximum", - new ExclusiveMaximumValidator(this.exclusiveMaximum) - ); + keywordToValidator.put("exclusiveMaximum", new ExclusiveMaximumValidator()); } this.exclusiveMinimum = jsonSchemaInfo.exclusiveMinimum; if (this.exclusiveMinimum != null) { - keywordToValidator.put( - "exclusiveMinimum", - new ExclusiveMinimumValidator(this.exclusiveMinimum) - ); + keywordToValidator.put("exclusiveMinimum", new ExclusiveMinimumValidator()); } this.maxItems = jsonSchemaInfo.maxItems; if (this.maxItems != null) { - keywordToValidator.put( - "maxItems", - new MaxItemsValidator(this.maxItems) - ); + keywordToValidator.put("maxItems", new MaxItemsValidator()); } this.minItems = jsonSchemaInfo.minItems; if (this.minItems != null) { - keywordToValidator.put( - "minItems", - new MinItemsValidator(this.minItems) - ); + keywordToValidator.put("minItems", new MinItemsValidator()); } this.maxLength = jsonSchemaInfo.maxLength; if (this.maxLength != null) { - keywordToValidator.put( - "maxLength", - new MaxLengthValidator(this.maxLength) - ); + keywordToValidator.put("maxLength", new MaxLengthValidator()); } this.minLength = jsonSchemaInfo.minLength; if (this.minLength != null) { - keywordToValidator.put( - "minLength", - new MinLengthValidator(this.minLength) - ); + keywordToValidator.put("minLength", new MinLengthValidator()); } this.maxProperties = jsonSchemaInfo.maxProperties; if (this.maxProperties != null) { - keywordToValidator.put( - "maxProperties", - new MaxPropertiesValidator(this.maxProperties) - ); + keywordToValidator.put("maxProperties", new MaxPropertiesValidator()); } this.minProperties = jsonSchemaInfo.minProperties; if (this.minProperties != null) { - keywordToValidator.put( - "minProperties", - new MinPropertiesValidator(this.minProperties) - ); + keywordToValidator.put("minProperties", new MinPropertiesValidator()); } this.maximum = jsonSchemaInfo.maximum; if (this.maximum != null) { - keywordToValidator.put( - "maximum", - new MaximumValidator(this.maximum) - ); + keywordToValidator.put("maximum", new MaximumValidator()); } this.minimum = jsonSchemaInfo.minimum; if (this.minimum != null) { - keywordToValidator.put( - "minimum", - new MinimumValidator(this.minimum) - ); + keywordToValidator.put("minimum", new MinimumValidator()); } this.multipleOf = jsonSchemaInfo.multipleOf; if (this.multipleOf != null) { - keywordToValidator.put( - "multipleOf", - new MultipleOfValidator(this.multipleOf) - ); + keywordToValidator.put("multipleOf", new MultipleOfValidator()); } this.additionalProperties = jsonSchemaInfo.additionalProperties; if (this.additionalProperties != null) { - keywordToValidator.put( - "additionalProperties", - new AdditionalPropertiesValidator(this.additionalProperties) - ); + keywordToValidator.put("additionalProperties", new AdditionalPropertiesValidator()); } this.allOf = jsonSchemaInfo.allOf; if (this.allOf != null) { - keywordToValidator.put( - "allOf", - new AllOfValidator(this.allOf) - ); + keywordToValidator.put("allOf", new AllOfValidator()); } this.anyOf = jsonSchemaInfo.anyOf; if (this.anyOf != null) { - keywordToValidator.put( - "anyOf", - new AnyOfValidator(this.anyOf) - ); + keywordToValidator.put("anyOf", new AnyOfValidator()); } this.oneOf = jsonSchemaInfo.oneOf; if (this.oneOf != null) { - keywordToValidator.put( - "oneOf", - new OneOfValidator(this.oneOf) - ); + keywordToValidator.put("oneOf", new OneOfValidator()); } this.not = jsonSchemaInfo.not; if (this.not != null) { - keywordToValidator.put( - "not", - new NotValidator(this.not) - ); + keywordToValidator.put("not", new NotValidator()); } this.uniqueItems = jsonSchemaInfo.uniqueItems; if (this.uniqueItems != null) { - keywordToValidator.put( - "uniqueItems", - new UniqueItemsValidator(this.uniqueItems) - ); + keywordToValidator.put("uniqueItems", new UniqueItemsValidator()); } this.enumValues = jsonSchemaInfo.enumValues; if (this.enumValues != null) { - keywordToValidator.put( - "enum", - new EnumValidator(this.enumValues) - ); + keywordToValidator.put("enum", new EnumValidator()); } this.pattern = jsonSchemaInfo.pattern; if (this.pattern != null) { - keywordToValidator.put( - "pattern", - new PatternValidator(this.pattern) - ); + keywordToValidator.put("pattern", new PatternValidator()); } this.defaultValue = jsonSchemaInfo.defaultValue; this.defaultValueSet = jsonSchemaInfo.defaultValueSet; this.constValue = jsonSchemaInfo.constValue; this.constValueSet = jsonSchemaInfo.constValueSet; if (this.constValueSet) { - keywordToValidator.put( - "const", - new ConstValidator(this.constValue) - ); + keywordToValidator.put("const", new ConstValidator()); } this.contains = jsonSchemaInfo.contains; if (this.contains != null) { - keywordToValidator.put( - "contains", - new ContainsValidator(this.contains) - ); + keywordToValidator.put("contains", new ContainsValidator()); } this.maxContains = jsonSchemaInfo.maxContains; if (this.maxContains != null) { - keywordToValidator.put( - "maxContains", - new MaxContainsValidator(this.maxContains) - ); + keywordToValidator.put("maxContains", new MaxContainsValidator()); } this.minContains = jsonSchemaInfo.minContains; if (this.minContains != null) { - keywordToValidator.put( - "minContains", - new MinContainsValidator(this.minContains) - ); + keywordToValidator.put("minContains", new MinContainsValidator()); } this.propertyNames = jsonSchemaInfo.propertyNames; if (this.propertyNames != null) { - keywordToValidator.put( - "propertyNames", - new PropertyNamesValidator(this.propertyNames) - ); + keywordToValidator.put("propertyNames", new PropertyNamesValidator()); } this.dependentRequired = jsonSchemaInfo.dependentRequired; if (this.dependentRequired != null) { - keywordToValidator.put( - "dependentRequired", - new DependentRequiredValidator(this.dependentRequired) - ); + keywordToValidator.put("dependentRequired", new DependentRequiredValidator()); } this.dependentSchemas = jsonSchemaInfo.dependentSchemas; if (this.dependentSchemas != null) { - keywordToValidator.put( - "dependentSchemas", - new DependentSchemasValidator(this.dependentSchemas) - ); + keywordToValidator.put("dependentSchemas", new DependentSchemasValidator()); } this.patternProperties = jsonSchemaInfo.patternProperties; if (this.patternProperties != null) { - keywordToValidator.put( - "patternProperties", - new PatternPropertiesValidator(this.patternProperties) - ); + keywordToValidator.put("patternProperties", new PatternPropertiesValidator()); } this.prefixItems = jsonSchemaInfo.prefixItems; if (this.prefixItems != null) { - keywordToValidator.put( - "prefixItems", - new PrefixItemsValidator(this.prefixItems) - ); + keywordToValidator.put("prefixItems", new PrefixItemsValidator()); } this.ifSchema = jsonSchemaInfo.ifSchema; if (this.ifSchema != null) { - keywordToValidator.put( - "if", - new IfValidator(this.ifSchema) - ); + keywordToValidator.put("if", new IfValidator()); } this.keywordToValidator = keywordToValidator; } @@ -306,6 +204,93 @@ public abstract class JsonSchema { public abstract @Nullable Object getNewInstance(@Nullable Object arg, List pathToItem, PathToSchemasMap pathToSchemas) throws InvalidTypeException; public abstract @Nullable Object validate(@Nullable Object arg, SchemaConfiguration configuration) throws InvalidTypeException, ValidationException; + private List getContainsPathToSchemas( + @Nullable Object arg, + ValidationMetadata validationMetadata + ) { + if (!(arg instanceof List listArg) || contains == null) { + return new ArrayList<>(); + } + JsonSchema containsSchema = JsonSchemaFactory.getInstance(contains); + @Nullable List containsPathToSchemas = new ArrayList<>(); + int i = 0; + for(Object itemValue: listArg) { + PathToSchemasMap thesePathToSchemas = new PathToSchemasMap(); + List itemPathToItem = new ArrayList<>(validationMetadata.pathToItem()); + itemPathToItem.add(i); + ValidationMetadata itemValidationMetadata = new ValidationMetadata( + itemPathToItem, + validationMetadata.configuration(), + validationMetadata.validatedPathToSchemas(), + validationMetadata.seenClasses() + ); + if (itemValidationMetadata.validationRanEarlier(containsSchema)) { + // todo add_deeper_validated_schemas + containsPathToSchemas.add(thesePathToSchemas); + i += 1; + continue; + } + + try { + PathToSchemasMap otherPathToSchemas = JsonSchema.validate( + containsSchema, itemValue, itemValidationMetadata); + containsPathToSchemas.add(otherPathToSchemas); + } catch (ValidationException ignored) {} + } + return containsPathToSchemas; + } + + private PathToSchemasMap getPatternPropertiesPathToSchemas( + @Nullable Object arg, + ValidationMetadata validationMetadata + ) { + if (!(arg instanceof Map mapArg) || patternProperties == null) { + return new PathToSchemasMap(); + } + PathToSchemasMap pathToSchemas = new PathToSchemasMap(); + for (Map.Entry entry: mapArg.entrySet()) { + Object entryKey = entry.getKey(); + if (!(entryKey instanceof String key)) { + throw new InvalidTypeException("Invalid non-string type for map key"); + } + List propPathToItem = new ArrayList<>(validationMetadata.pathToItem()); + propPathToItem.add(key); + ValidationMetadata propValidationMetadata = new ValidationMetadata( + propPathToItem, + validationMetadata.configuration(), + validationMetadata.validatedPathToSchemas(), + validationMetadata.seenClasses() + ); + for (Map.Entry> patternPropEntry: patternProperties.entrySet()) { + if (!patternPropEntry.getKey().matcher(key).find()) { + continue; + } + + Class patternPropClass = patternPropEntry.getValue(); + JsonSchema patternPropSchema = JsonSchemaFactory.getInstance(patternPropClass); + PathToSchemasMap otherPathToSchemas = JsonSchema.validate(patternPropSchema, entry.getValue(), propValidationMetadata); + pathToSchemas.update(otherPathToSchemas); + } + } + return pathToSchemas; + } + + private PathToSchemasMap getIfPathToSchemas( + @Nullable Object arg, + ValidationMetadata validationMetadata + ) { + if (ifSchema == null) { + return new PathToSchemasMap(); + } + JsonSchema ifSchemaInstance = JsonSchemaFactory.getInstance(ifSchema); + PathToSchemasMap pathToSchemas = new PathToSchemasMap(); + try { + var otherPathToSchemas = JsonSchema.validate(ifSchemaInstance, arg, validationMetadata); + pathToSchemas.update(otherPathToSchemas); + } catch (ValidationException | InvalidTypeException ignored) {} + return pathToSchemas; + } + public static PathToSchemasMap validate( JsonSchema jsonSchema, @Nullable Object arg, @@ -315,19 +300,16 @@ public abstract class JsonSchema { PathToSchemasMap pathToSchemas = new PathToSchemasMap(); LinkedHashMap thisKeywordToValidator = jsonSchema.keywordToValidator; @Nullable List containsPathToSchemas = null; - KeywordValidator containsValidator = thisKeywordToValidator.get("contains"); - if (containsValidator != null) { - containsPathToSchemas = containsValidator.getContainsPathToSchemas(arg, validationMetadata); + if (thisKeywordToValidator.containsKey("contains")) { + containsPathToSchemas = jsonSchema.getContainsPathToSchemas(arg, validationMetadata); } @Nullable PathToSchemasMap patternPropertiesPathToSchemas = null; - KeywordValidator patternPropertiesValidator = thisKeywordToValidator.get("patternProperties"); - if (patternPropertiesValidator != null) { - patternPropertiesPathToSchemas = patternPropertiesValidator.getPatternPropertiesPathToSchemas(arg, validationMetadata); + if (thisKeywordToValidator.containsKey("patternProperties")) { + patternPropertiesPathToSchemas = jsonSchema.getPatternPropertiesPathToSchemas(arg, validationMetadata); } @Nullable PathToSchemasMap ifPathToSchemas = null; - KeywordValidator ifValidator = thisKeywordToValidator.get("if"); - if (ifValidator != null) { - ifPathToSchemas = ifValidator.getIfPathToSchemas(arg, validationMetadata); + if (thisKeywordToValidator.containsKey("if")) { + ifPathToSchemas = jsonSchema.getIfPathToSchemas(arg, validationMetadata); } for (Map.Entry entry: thisKeywordToValidator.entrySet()) { String jsonKeyword = entry.getKey(); @@ -338,7 +320,7 @@ public abstract class JsonSchema { } } KeywordValidator validator = entry.getValue(); - @Nullable PathToSchemasMap otherPathToSchemas = validator.validate( + ValidationData data = new ValidationData( jsonSchema, arg, validationMetadata, @@ -346,6 +328,7 @@ public abstract class JsonSchema { patternPropertiesPathToSchemas, ifPathToSchemas ); + @Nullable PathToSchemasMap otherPathToSchemas = validator.validate(data); if (otherPathToSchemas == null) { continue; } @@ -401,10 +384,9 @@ public abstract class JsonSchema { LinkedHashMap argFixed = new LinkedHashMap<>(); for (Map.Entry entry: arg.entrySet()) { @Nullable Object entryKey = entry.getKey(); - if (!(entryKey instanceof String)) { + if (!(entryKey instanceof String key)) { throw new InvalidTypeException("Invalid non-string key value"); } - String key = (String) entryKey; Object val = entry.getValue(); List newPathToItem = new ArrayList<>(pathToItem); newPathToItem.add(key); diff --git a/src/main/resources/java/src/main/java/packagename/schemas/validation/KeywordValidator.hbs b/src/main/resources/java/src/main/java/packagename/schemas/validation/KeywordValidator.hbs index 381228b3282..b95cc5d5fc2 100644 --- a/src/main/resources/java/src/main/java/packagename/schemas/validation/KeywordValidator.hbs +++ b/src/main/resources/java/src/main/java/packagename/schemas/validation/KeywordValidator.hbs @@ -3,37 +3,9 @@ package {{{packageName}}}.schemas.validation; import {{{packageName}}}.exceptions.ValidationException; import org.checkerframework.checker.nullness.qual.Nullable; -import java.util.ArrayList; -import java.util.List; - +@FunctionalInterface public interface KeywordValidator { @Nullable PathToSchemasMap validate( - JsonSchema schema, - @Nullable Object arg, - ValidationMetadata validationMetadata, - @Nullable List containsPathToSchemas, - @Nullable PathToSchemasMap patternPropertiesPathToSchemas, - @Nullable PathToSchemasMap ifPathToSchemas + ValidationData data ) throws ValidationException; - - default List getContainsPathToSchemas( - @Nullable Object arg, - ValidationMetadata validationMetadata - ) { - return new ArrayList<>(); - } - - default PathToSchemasMap getPatternPropertiesPathToSchemas( - @Nullable Object arg, - ValidationMetadata validationMetadata - ) { - return new PathToSchemasMap(); - } - - default PathToSchemasMap getIfPathToSchemas( - @Nullable Object arg, - ValidationMetadata validationMetadata - ) { - return new PathToSchemasMap(); - } } \ No newline at end of file diff --git a/src/main/resources/java/src/main/java/packagename/schemas/validation/MaxContainsValidator.hbs b/src/main/resources/java/src/main/java/packagename/schemas/validation/MaxContainsValidator.hbs index 4308f9e46e9..f2ba459cec9 100644 --- a/src/main/resources/java/src/main/java/packagename/schemas/validation/MaxContainsValidator.hbs +++ b/src/main/resources/java/src/main/java/packagename/schemas/validation/MaxContainsValidator.hbs @@ -6,31 +6,25 @@ import {{{packageName}}}.exceptions.ValidationException; import java.util.List; public class MaxContainsValidator implements KeywordValidator { - public final int maxContains; - - public MaxContainsValidator(int maxContains) { - this.maxContains = maxContains; - } - @Override public @Nullable PathToSchemasMap validate( - JsonSchema schema, - @Nullable Object arg, - ValidationMetadata validationMetadata, - @Nullable List containsPathToSchemas, - @Nullable PathToSchemasMap patternPropertiesPathToSchemas, - @Nullable PathToSchemasMap ifPathToSchemas + ValidationData data ) { - if (!(arg instanceof List)) { + var maxContains = data.schema().maxContains; + if (maxContains == null) { + return null; + } + if (!(data.arg() instanceof List)) { return null; } + var containsPathToSchemas = data.containsPathToSchemas(); if (containsPathToSchemas == null) { return null; } if (containsPathToSchemas.size() > maxContains) { throw new ValidationException( - "Validation failed for maxContains keyword in class="+schema.getClass()+ - " at pathToItem="+validationMetadata.pathToItem()+". Too many items validated to the contains schema." + "Validation failed for maxContains keyword in class="+data.schema().getClass()+ + " at pathToItem="+data.validationMetadata().pathToItem()+". Too many items validated to the contains schema." ); } return null; diff --git a/src/main/resources/java/src/main/java/packagename/schemas/validation/MaxItemsValidator.hbs b/src/main/resources/java/src/main/java/packagename/schemas/validation/MaxItemsValidator.hbs index 98591a67fd0..f557904e3c4 100644 --- a/src/main/resources/java/src/main/java/packagename/schemas/validation/MaxItemsValidator.hbs +++ b/src/main/resources/java/src/main/java/packagename/schemas/validation/MaxItemsValidator.hbs @@ -6,26 +6,19 @@ import org.checkerframework.checker.nullness.qual.Nullable; import java.util.List; public class MaxItemsValidator implements KeywordValidator { - public final int maxItems; - - public MaxItemsValidator(int maxItems) { - this.maxItems = maxItems; - } - @Override public @Nullable PathToSchemasMap validate( - JsonSchema schema, - @Nullable Object arg, - ValidationMetadata validationMetadata, - @Nullable List containsPathToSchemas, - @Nullable PathToSchemasMap patternPropertiesPathToSchemas, - @Nullable PathToSchemasMap ifPathToSchemas + ValidationData data ) { - if (!(arg instanceof List)) { + var maxItems = data.schema().maxItems; + if (maxItems == null) { + return null; + } + if (!(data.arg() instanceof List listArg)) { return null; } - if (((List) arg).size() > maxItems) { - throw new ValidationException("Value " + arg + " is invalid because has > the maxItems of " + maxItems); + if (listArg.size() > maxItems) { + throw new ValidationException("Value " + listArg + " is invalid because has > the maxItems of " + maxItems); } return null; } diff --git a/src/main/resources/java/src/main/java/packagename/schemas/validation/MaxLengthValidator.hbs b/src/main/resources/java/src/main/java/packagename/schemas/validation/MaxLengthValidator.hbs index fb970be06fb..ab2fb133e14 100644 --- a/src/main/resources/java/src/main/java/packagename/schemas/validation/MaxLengthValidator.hbs +++ b/src/main/resources/java/src/main/java/packagename/schemas/validation/MaxLengthValidator.hbs @@ -3,30 +3,21 @@ package {{{packageName}}}.schemas.validation; import {{{packageName}}}.exceptions.ValidationException; import org.checkerframework.checker.nullness.qual.Nullable; -import java.util.List; - public class MaxLengthValidator extends LengthValidator implements KeywordValidator { - public final int maxLength; - - public MaxLengthValidator(int maxLength) { - this.maxLength = maxLength; - } - @Override public @Nullable PathToSchemasMap validate( - JsonSchema schema, - @Nullable Object arg, - ValidationMetadata validationMetadata, - @Nullable List containsPathToSchemas, - @Nullable PathToSchemasMap patternPropertiesPathToSchemas, - @Nullable PathToSchemasMap ifPathToSchemas + ValidationData data ) { - if (!(arg instanceof String)) { + var maxLength = data.schema().maxLength; + if (maxLength == null) { + return null; + } + if (!(data.arg() instanceof String stringArg)) { return null; } - int length = getLength((String) arg); + int length = getLength(stringArg); if (length > maxLength) { - throw new ValidationException("Value " + arg + " is invalid because has > the maxLength of " + maxLength); + throw new ValidationException("Value " + stringArg + " is invalid because has > the maxLength of " + maxLength); } return null; } diff --git a/src/main/resources/java/src/main/java/packagename/schemas/validation/MaxPropertiesValidator.hbs b/src/main/resources/java/src/main/java/packagename/schemas/validation/MaxPropertiesValidator.hbs index c3c398dd1e7..79087edd170 100644 --- a/src/main/resources/java/src/main/java/packagename/schemas/validation/MaxPropertiesValidator.hbs +++ b/src/main/resources/java/src/main/java/packagename/schemas/validation/MaxPropertiesValidator.hbs @@ -3,30 +3,22 @@ package {{{packageName}}}.schemas.validation; import {{{packageName}}}.exceptions.ValidationException; import org.checkerframework.checker.nullness.qual.Nullable; -import java.util.List; import java.util.Map; public class MaxPropertiesValidator implements KeywordValidator { - public final int maxProperties; - - public MaxPropertiesValidator(int maxProperties) { - this.maxProperties = maxProperties; - } - @Override public @Nullable PathToSchemasMap validate( - JsonSchema schema, - @Nullable Object arg, - ValidationMetadata validationMetadata, - @Nullable List containsPathToSchemas, - @Nullable PathToSchemasMap patternPropertiesPathToSchemas, - @Nullable PathToSchemasMap ifPathToSchemas + ValidationData data ) { - if (!(arg instanceof Map)) { + var maxProperties = data.schema().maxProperties; + if (maxProperties == null) { + return null; + } + if (!(data.arg() instanceof Map mapArg)) { return null; } - if (((Map) arg).size() > maxProperties) { - throw new ValidationException("Value " + arg + " is invalid because has > the maxProperties of " + maxProperties); + if (mapArg.size() > maxProperties) { + throw new ValidationException("Value " + mapArg + " is invalid because has > the maxProperties of " + maxProperties); } return null; } diff --git a/src/main/resources/java/src/main/java/packagename/schemas/validation/MaximumValidator.hbs b/src/main/resources/java/src/main/java/packagename/schemas/validation/MaximumValidator.hbs index 67afa868a6f..809692b04c3 100644 --- a/src/main/resources/java/src/main/java/packagename/schemas/validation/MaximumValidator.hbs +++ b/src/main/resources/java/src/main/java/packagename/schemas/validation/MaximumValidator.hbs @@ -3,52 +3,43 @@ package {{{packageName}}}.schemas.validation; import {{{packageName}}}.exceptions.ValidationException; import org.checkerframework.checker.nullness.qual.Nullable; -import java.util.List; - public class MaximumValidator implements KeywordValidator { - public final Number maximum; - - public MaximumValidator(Number maximum) { - this.maximum = maximum; - } - @Override public @Nullable PathToSchemasMap validate( - JsonSchema schema, - @Nullable Object arg, - ValidationMetadata validationMetadata, - @Nullable List containsPathToSchemas, - @Nullable PathToSchemasMap patternPropertiesPathToSchemas, - @Nullable PathToSchemasMap ifPathToSchemas + ValidationData data ) { - if (!(arg instanceof Number)) { + var maximum = data.schema().maximum; + if (maximum == null) { + return null; + } + if (!(data.arg() instanceof Number)) { return null; } - String msg = "Value " + arg + " is invalid because it is > the maximum of " + maximum; - if (arg instanceof Integer) { - if (((Integer) arg).compareTo(maximum.intValue()) == 1) { + String msg = "Value " + data.arg() + " is invalid because it is > the maximum of " + maximum; + if (data.arg() instanceof Integer intArg) { + if (intArg.compareTo(maximum.intValue()) > 0) { throw new ValidationException(msg); } return null; } - if (arg instanceof Long) { - if (((Long) arg).compareTo(maximum.longValue()) == 1) { + if (data.arg() instanceof Long longArg) { + if (longArg.compareTo(maximum.longValue()) > 0) { throw new ValidationException(msg); } return null; } - if (arg instanceof Float) { - if (((Float) arg).compareTo(maximum.floatValue()) == 1) { + if (data.arg() instanceof Float floatArg) { + if (floatArg.compareTo(maximum.floatValue()) > 0) { throw new ValidationException(msg); } return null; } - if (arg instanceof Double) { - if (((Double) arg).compareTo(maximum.doubleValue()) == 1) { + if (data.arg() instanceof Double doubleArg) { + if (doubleArg.compareTo(maximum.doubleValue()) > 0) { throw new ValidationException(msg); } return null; } return null; } -} +} \ No newline at end of file diff --git a/src/main/resources/java/src/main/java/packagename/schemas/validation/MinContainsValidator.hbs b/src/main/resources/java/src/main/java/packagename/schemas/validation/MinContainsValidator.hbs index 0dfa4ff0795..7ab9c6d7c82 100644 --- a/src/main/resources/java/src/main/java/packagename/schemas/validation/MinContainsValidator.hbs +++ b/src/main/resources/java/src/main/java/packagename/schemas/validation/MinContainsValidator.hbs @@ -6,31 +6,24 @@ import {{{packageName}}}.exceptions.ValidationException; import java.util.List; public class MinContainsValidator implements KeywordValidator { - public final int minContains; - - public MinContainsValidator(int minContains) { - this.minContains = minContains; - } - @Override public @Nullable PathToSchemasMap validate( - JsonSchema schema, - @Nullable Object arg, - ValidationMetadata validationMetadata, - @Nullable List containsPathToSchemas, - @Nullable PathToSchemasMap patternPropertiesPathToSchemas, - @Nullable PathToSchemasMap ifPathToSchemas + ValidationData data ) { - if (!(arg instanceof List)) { + var minContains = data.schema().minContains; + if (minContains == null) { + return null; + } + if (!(data.arg() instanceof List)) { return null; } - if (containsPathToSchemas == null) { + if (data.containsPathToSchemas() == null) { return null; } - if (containsPathToSchemas.size() < minContains) { + if (data.containsPathToSchemas().size() < minContains) { throw new ValidationException( - "Validation failed for minContains keyword in class="+schema.getClass()+ - " at pathToItem="+validationMetadata.pathToItem()+". Too few items validated to the contains schema." + "Validation failed for minContains keyword in class="+data.schema().getClass()+ + " at pathToItem="+data.validationMetadata().pathToItem()+". Too few items validated to the contains schema." ); } return null; diff --git a/src/main/resources/java/src/main/java/packagename/schemas/validation/MinItemsValidator.hbs b/src/main/resources/java/src/main/java/packagename/schemas/validation/MinItemsValidator.hbs index 9216734c461..d65ca58eb65 100644 --- a/src/main/resources/java/src/main/java/packagename/schemas/validation/MinItemsValidator.hbs +++ b/src/main/resources/java/src/main/java/packagename/schemas/validation/MinItemsValidator.hbs @@ -6,26 +6,19 @@ import org.checkerframework.checker.nullness.qual.Nullable; import java.util.List; public class MinItemsValidator implements KeywordValidator { - public final int minItems; - - public MinItemsValidator(int minItems) { - this.minItems = minItems; - } - @Override public @Nullable PathToSchemasMap validate( - JsonSchema schema, - @Nullable Object arg, - ValidationMetadata validationMetadata, - @Nullable List containsPathToSchemas, - @Nullable PathToSchemasMap patternPropertiesPathToSchemas, - @Nullable PathToSchemasMap ifPathToSchemas + ValidationData data ) { - if (!(arg instanceof List)) { + var minItems = data.schema().minItems; + if (minItems == null) { + return null; + } + if (!(data.arg() instanceof List listArg)) { return null; } - if (((List) arg).size() < minItems) { - throw new ValidationException("Value " + arg + " is invalid because has < the minItems of " + minItems); + if (listArg.size() < minItems) { + throw new ValidationException("Value " + listArg + " is invalid because has < the minItems of " + minItems); } return null; } diff --git a/src/main/resources/java/src/main/java/packagename/schemas/validation/MinLengthValidator.hbs b/src/main/resources/java/src/main/java/packagename/schemas/validation/MinLengthValidator.hbs index 925f83e5a3c..24badcaa03c 100644 --- a/src/main/resources/java/src/main/java/packagename/schemas/validation/MinLengthValidator.hbs +++ b/src/main/resources/java/src/main/java/packagename/schemas/validation/MinLengthValidator.hbs @@ -3,31 +3,22 @@ package {{{packageName}}}.schemas.validation; import {{{packageName}}}.exceptions.ValidationException; import org.checkerframework.checker.nullness.qual.Nullable; -import java.util.List; - public class MinLengthValidator extends LengthValidator implements KeywordValidator { - public final int minLength; - - public MinLengthValidator(int minLength) { - this.minLength = minLength; - } - @Override public @Nullable PathToSchemasMap validate( - JsonSchema schema, - @Nullable Object arg, - ValidationMetadata validationMetadata, - @Nullable List containsPathToSchemas, - @Nullable PathToSchemasMap patternPropertiesPathToSchemas, - @Nullable PathToSchemasMap ifPathToSchemas + ValidationData data ) { - if (!(arg instanceof String)) { + var minLength = data.schema().minLength; + if (minLength == null) { + return null; + } + if (!(data.arg() instanceof String stringArg)) { return null; } - int length = getLength((String) arg); + int length = getLength(stringArg); if (length < minLength) { - throw new ValidationException("Value " + arg + " is invalid because has < the minLength of " + minLength); + throw new ValidationException("Value " + stringArg + " is invalid because has < the minLength of " + minLength); } return null; } -} +} \ No newline at end of file diff --git a/src/main/resources/java/src/main/java/packagename/schemas/validation/MinPropertiesValidator.hbs b/src/main/resources/java/src/main/java/packagename/schemas/validation/MinPropertiesValidator.hbs index 80ea144457f..30d0790416a 100644 --- a/src/main/resources/java/src/main/java/packagename/schemas/validation/MinPropertiesValidator.hbs +++ b/src/main/resources/java/src/main/java/packagename/schemas/validation/MinPropertiesValidator.hbs @@ -3,30 +3,22 @@ package {{{packageName}}}.schemas.validation; import {{{packageName}}}.exceptions.ValidationException; import org.checkerframework.checker.nullness.qual.Nullable; -import java.util.List; import java.util.Map; public class MinPropertiesValidator implements KeywordValidator { - public final int minProperties; - - public MinPropertiesValidator(int minProperties) { - this.minProperties = minProperties; - } - @Override public @Nullable PathToSchemasMap validate( - JsonSchema schema, - @Nullable Object arg, - ValidationMetadata validationMetadata, - @Nullable List containsPathToSchemas, - @Nullable PathToSchemasMap patternPropertiesPathToSchemas, - @Nullable PathToSchemasMap ifPathToSchemas + ValidationData data ) { - if (!(arg instanceof Map)) { + var minProperties = data.schema().minProperties; + if (minProperties == null) { + return null; + } + if (!(data.arg() instanceof Map mapArg)) { return null; } - if (((Map) arg).size() < minProperties) { - throw new ValidationException("Value " + arg + " is invalid because has < the minProperties of " + minProperties); + if (mapArg.size() < minProperties) { + throw new ValidationException("Value " + mapArg + " is invalid because has < the minProperties of " + minProperties); } return null; } diff --git a/src/main/resources/java/src/main/java/packagename/schemas/validation/MinimumValidator.hbs b/src/main/resources/java/src/main/java/packagename/schemas/validation/MinimumValidator.hbs index 55b9ed98cc2..b096b0de71f 100644 --- a/src/main/resources/java/src/main/java/packagename/schemas/validation/MinimumValidator.hbs +++ b/src/main/resources/java/src/main/java/packagename/schemas/validation/MinimumValidator.hbs @@ -3,48 +3,39 @@ package {{{packageName}}}.schemas.validation; import {{{packageName}}}.exceptions.ValidationException; import org.checkerframework.checker.nullness.qual.Nullable; -import java.util.List; - public class MinimumValidator implements KeywordValidator { - public final Number minimum; - - public MinimumValidator(Number minimum) { - this.minimum = minimum; - } - @Override public @Nullable PathToSchemasMap validate( - JsonSchema schema, - @Nullable Object arg, - ValidationMetadata validationMetadata, - @Nullable List containsPathToSchemas, - @Nullable PathToSchemasMap patternPropertiesPathToSchemas, - @Nullable PathToSchemasMap ifPathToSchemas + ValidationData data ) { - if (!(arg instanceof Number)) { + var minimum = data.schema().minimum; + if (minimum == null) { + return null; + } + if (!(data.arg() instanceof Number)) { return null; } - String msg = "Value " + arg + " is invalid because it is < the minimum of " + minimum; - if (arg instanceof Integer) { - if (((Integer) arg).compareTo(minimum.intValue()) == -1) { + String msg = "Value " + data.arg() + " is invalid because it is < the minimum of " + minimum; + if (data.arg() instanceof Integer intArg) { + if (intArg.compareTo(minimum.intValue()) < 0) { throw new ValidationException(msg); } return null; } - if (arg instanceof Long) { - if (((Long) arg).compareTo(minimum.longValue()) == -1) { + if (data.arg() instanceof Long longArg) { + if (longArg.compareTo(minimum.longValue()) < 0) { throw new ValidationException(msg); } return null; } - if (arg instanceof Float) { - if (((Float) arg).compareTo(minimum.floatValue()) == -1) { + if (data.arg() instanceof Float floatArg) { + if (floatArg.compareTo(minimum.floatValue()) < 0) { throw new ValidationException(msg); } return null; } - if (arg instanceof Double) { - if (((Double) arg).compareTo(minimum.doubleValue()) == -1) { + if (data.arg() instanceof Double doubleArg) { + if (doubleArg.compareTo(minimum.doubleValue()) < 0) { throw new ValidationException(msg); } return null; diff --git a/src/main/resources/java/src/main/java/packagename/schemas/validation/MultipleOfValidator.hbs b/src/main/resources/java/src/main/java/packagename/schemas/validation/MultipleOfValidator.hbs index df3ed47bfc3..3151dfda95b 100644 --- a/src/main/resources/java/src/main/java/packagename/schemas/validation/MultipleOfValidator.hbs +++ b/src/main/resources/java/src/main/java/packagename/schemas/validation/MultipleOfValidator.hbs @@ -3,33 +3,25 @@ package {{{packageName}}}.schemas.validation; import {{{packageName}}}.exceptions.ValidationException; import org.checkerframework.checker.nullness.qual.Nullable; -import java.util.List; import java.math.BigDecimal; public class MultipleOfValidator extends BigDecimalValidator implements KeywordValidator { - public final BigDecimal multipleOf; - - public MultipleOfValidator(BigDecimal multipleOf) { - this.multipleOf = multipleOf; - } - @Override public @Nullable PathToSchemasMap validate( - JsonSchema schema, - @Nullable Object arg, - ValidationMetadata validationMetadata, - @Nullable List containsPathToSchemas, - @Nullable PathToSchemasMap patternPropertiesPathToSchemas, - @Nullable PathToSchemasMap ifPathToSchemas + ValidationData data ) { - if (!(arg instanceof Number)) { + var multipleOf = data.schema().multipleOf; + if (multipleOf == null) { + return null; + } + if (!(data.arg() instanceof Number numberArg)) { return null; } - BigDecimal castArg = getBigDecimal((Number) arg); - String msg = "Value " + arg + " is invalid because it is not a multiple of " + multipleOf; + BigDecimal castArg = getBigDecimal(numberArg); + String msg = "Value " + numberArg + " is invalid because it is not a multiple of " + multipleOf; if (castArg.remainder(multipleOf).compareTo(BigDecimal.ZERO) != 0) { throw new ValidationException(msg); } return null; } -} +} \ No newline at end of file diff --git a/src/main/resources/java/src/main/java/packagename/schemas/validation/NotValidator.hbs b/src/main/resources/java/src/main/java/packagename/schemas/validation/NotValidator.hbs index 3ac7c4b3507..665d13f253f 100644 --- a/src/main/resources/java/src/main/java/packagename/schemas/validation/NotValidator.hbs +++ b/src/main/resources/java/src/main/java/packagename/schemas/validation/NotValidator.hbs @@ -3,39 +3,25 @@ package {{{packageName}}}.schemas.validation; import {{{packageName}}}.exceptions.ValidationException; import org.checkerframework.checker.nullness.qual.Nullable; -import java.util.ArrayList; -import java.util.LinkedHashMap; -import java.util.LinkedHashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; - public class NotValidator implements KeywordValidator { - public final Class not; - - public NotValidator(Class not) { - this.not = not; - } - @Override public @Nullable PathToSchemasMap validate( - JsonSchema schema, - @Nullable Object arg, - ValidationMetadata validationMetadata, - @Nullable List containsPathToSchemas, - @Nullable PathToSchemasMap patternPropertiesPathToSchemas, - @Nullable PathToSchemasMap ifPathToSchemas + ValidationData data ) { + var not = data.schema().not; + if (not == null) { + return null; + } PathToSchemasMap pathToSchemas; try { JsonSchema notSchema = JsonSchemaFactory.getInstance(not); - pathToSchemas = JsonSchema.validate(notSchema, arg, validationMetadata); + pathToSchemas = JsonSchema.validate(notSchema, data.arg(), data.validationMetadata()); } catch (ValidationException e) { return null; } if (!pathToSchemas.isEmpty()) { throw new ValidationException( - "Invalid value "+arg+" was passed in to "+schema.getClass()+". "+ + "Invalid value "+data.arg()+" was passed in to "+data.schema().getClass()+". "+ "Value is invalid because it is disallowed by not "+not ); } diff --git a/src/main/resources/java/src/main/java/packagename/schemas/validation/OneOfValidator.hbs b/src/main/resources/java/src/main/java/packagename/schemas/validation/OneOfValidator.hbs index a55f2f7b8ab..2ce2f630251 100644 --- a/src/main/resources/java/src/main/java/packagename/schemas/validation/OneOfValidator.hbs +++ b/src/main/resources/java/src/main/java/packagename/schemas/validation/OneOfValidator.hbs @@ -7,25 +7,18 @@ import java.util.ArrayList; import java.util.List; public class OneOfValidator implements KeywordValidator { - public final List> oneOf; - - public OneOfValidator(List> oneOf) { - this.oneOf = oneOf; - } - @Override public @Nullable PathToSchemasMap validate( - JsonSchema schema, - @Nullable Object arg, - ValidationMetadata validationMetadata, - @Nullable List containsPathToSchemas, - @Nullable PathToSchemasMap patternPropertiesPathToSchemas, - @Nullable PathToSchemasMap ifPathToSchemas + ValidationData data ) { + var oneOf = data.schema().oneOf; + if (oneOf == null) { + return null; + } PathToSchemasMap pathToSchemas = new PathToSchemasMap(); List> validatedOneOfClasses = new ArrayList<>(); for(Class oneOfClass: oneOf) { - if (oneOfClass == schema.getClass()) { + if (oneOfClass == data.schema().getClass()) { /* optimistically assume that schema will pass validation do not invoke validate on it because that is recursive @@ -35,7 +28,7 @@ public class OneOfValidator implements KeywordValidator { } try { JsonSchema oneOfSchema = JsonSchemaFactory.getInstance(oneOfClass); - PathToSchemasMap otherPathToSchemas = JsonSchema.validate(oneOfSchema, arg, validationMetadata); + PathToSchemasMap otherPathToSchemas = JsonSchema.validate(oneOfSchema, data.arg(), data.validationMetadata()); validatedOneOfClasses.add(oneOfClass); pathToSchemas.update(otherPathToSchemas); } catch (ValidationException e) { @@ -43,12 +36,12 @@ public class OneOfValidator implements KeywordValidator { } } if (validatedOneOfClasses.isEmpty()) { - throw new ValidationException("Invalid inputs given to generate an instance of "+schema.getClass()+". None "+ + throw new ValidationException("Invalid inputs given to generate an instance of "+data.schema().getClass()+". None "+ "of the oneOf schemas matched the input data." ); } if (validatedOneOfClasses.size() > 1) { - throw new ValidationException("Invalid inputs given to generate an instance of "+schema.getClass()+". Multiple "+ + throw new ValidationException("Invalid inputs given to generate an instance of "+data.schema().getClass()+". Multiple "+ "oneOf schemas validated the data, but a max of one is allowed." ); } diff --git a/src/main/resources/java/src/main/java/packagename/schemas/validation/PatternPropertiesValidator.hbs b/src/main/resources/java/src/main/java/packagename/schemas/validation/PatternPropertiesValidator.hbs index b67f6f1c97e..a3d8ffa424c 100644 --- a/src/main/resources/java/src/main/java/packagename/schemas/validation/PatternPropertiesValidator.hbs +++ b/src/main/resources/java/src/main/java/packagename/schemas/validation/PatternPropertiesValidator.hbs @@ -1,68 +1,21 @@ package {{{packageName}}}.schemas.validation; import org.checkerframework.checker.nullness.qual.Nullable; -import {{{packageName}}}.exceptions.InvalidTypeException; -import java.util.ArrayList; -import java.util.List; import java.util.Map; -import java.util.regex.Pattern; public class PatternPropertiesValidator implements KeywordValidator { - public final Map> patternProperties; - - public PatternPropertiesValidator(Map> patternProperties) { - this.patternProperties = patternProperties; - } - @Override public @Nullable PathToSchemasMap validate( - JsonSchema schema, - @Nullable Object arg, - ValidationMetadata validationMetadata, - @Nullable List containsPathToSchemas, - @Nullable PathToSchemasMap patternPropertiesPathToSchemas, - @Nullable PathToSchemasMap ifPathToSchemas + ValidationData data ) { - if (!(arg instanceof Map)) { + var patternProperties = data.schema().patternProperties; + if (patternProperties == null) { return null; } - return patternPropertiesPathToSchemas; - } - - public PathToSchemasMap getPatternPropertiesPathToSchemas( - @Nullable Object arg, - ValidationMetadata validationMetadata - ) { - if (!(arg instanceof Map mapArg)) { - return new PathToSchemasMap(); - } - PathToSchemasMap pathToSchemas = new PathToSchemasMap(); - for (Map.Entry entry: mapArg.entrySet()) { - Object entryKey = entry.getKey(); - if (!(entryKey instanceof String key)) { - throw new InvalidTypeException("Invalid non-string type for map key"); - } - List propPathToItem = new ArrayList<>(validationMetadata.pathToItem()); - propPathToItem.add(key); - ValidationMetadata propValidationMetadata = new ValidationMetadata( - propPathToItem, - validationMetadata.configuration(), - validationMetadata.validatedPathToSchemas(), - validationMetadata.seenClasses() - ); - for (Map.Entry> patternPropEntry: patternProperties.entrySet()) { - if (!patternPropEntry.getKey().matcher(key).find()) { - continue; - } - - Class patternPropClass = patternPropEntry.getValue(); - JsonSchema patternPropSchema = JsonSchemaFactory.getInstance(patternPropClass); - PathToSchemasMap otherPathToSchemas = JsonSchema.validate(patternPropSchema, entry.getValue(), propValidationMetadata); - pathToSchemas.update(otherPathToSchemas); - } + if (!(data.arg() instanceof Map)) { + return null; } - return pathToSchemas; + return data.patternPropertiesPathToSchemas(); } } - diff --git a/src/main/resources/java/src/main/java/packagename/schemas/validation/PatternValidator.hbs b/src/main/resources/java/src/main/java/packagename/schemas/validation/PatternValidator.hbs index 6cdc7f21a77..e020d585618 100644 --- a/src/main/resources/java/src/main/java/packagename/schemas/validation/PatternValidator.hbs +++ b/src/main/resources/java/src/main/java/packagename/schemas/validation/PatternValidator.hbs @@ -3,31 +3,21 @@ package {{{packageName}}}.schemas.validation; import {{{packageName}}}.exceptions.ValidationException; import org.checkerframework.checker.nullness.qual.Nullable; -import java.util.List; -import java.util.regex.Pattern; - public class PatternValidator implements KeywordValidator { - public final Pattern pattern; - - public PatternValidator(Pattern pattern) { - this.pattern = pattern; - } - @Override public @Nullable PathToSchemasMap validate( - JsonSchema schema, - @Nullable Object arg, - ValidationMetadata validationMetadata, - @Nullable List containsPathToSchemas, - @Nullable PathToSchemasMap patternPropertiesPathToSchemas, - @Nullable PathToSchemasMap ifPathToSchemas + ValidationData data ) { - if (!(arg instanceof String)) { + var pattern = data.schema().pattern; + if (pattern == null) { + return null; + } + if (!(data.arg() instanceof String stringArg)) { return null; } - if (!pattern.matcher((String) arg).find()) { - throw new ValidationException("Invalid value "+arg+" did not find a match for pattern "+pattern); + if (!pattern.matcher(stringArg).find()) { + throw new ValidationException("Invalid value "+stringArg+" did not find a match for pattern "+pattern); } return null; } -} +} \ No newline at end of file diff --git a/src/main/resources/java/src/main/java/packagename/schemas/validation/PrefixItemsValidator.hbs b/src/main/resources/java/src/main/java/packagename/schemas/validation/PrefixItemsValidator.hbs index a938edfd38b..a13b4211a6e 100644 --- a/src/main/resources/java/src/main/java/packagename/schemas/validation/PrefixItemsValidator.hbs +++ b/src/main/resources/java/src/main/java/packagename/schemas/validation/PrefixItemsValidator.hbs @@ -6,22 +6,15 @@ import java.util.ArrayList; import java.util.List; public class PrefixItemsValidator implements KeywordValidator { - public final List> prefixItems; - - public PrefixItemsValidator(List> prefixItems) { - this.prefixItems = prefixItems; - } - @Override public @Nullable PathToSchemasMap validate( - JsonSchema schema, - @Nullable Object arg, - ValidationMetadata validationMetadata, - @Nullable List containsPathToSchemas, - @Nullable PathToSchemasMap patternPropertiesPathToSchemas, - @Nullable PathToSchemasMap ifPathToSchemas + ValidationData data ) { - if (!(arg instanceof List listArg)) { + var prefixItems = data.schema().prefixItems; + if (prefixItems == null) { + return null; + } + if (!(data.arg() instanceof List listArg)) { return null; } if (listArg.isEmpty()) { @@ -30,13 +23,13 @@ public class PrefixItemsValidator implements KeywordValidator { PathToSchemasMap pathToSchemas = new PathToSchemasMap(); int maxIndex = Math.min(listArg.size(), prefixItems.size()); for (int i=0; i < maxIndex; i++) { - List itemPathToItem = new ArrayList<>(validationMetadata.pathToItem()); + List itemPathToItem = new ArrayList<>(data.validationMetadata().pathToItem()); itemPathToItem.add(i); ValidationMetadata itemValidationMetadata = new ValidationMetadata( itemPathToItem, - validationMetadata.configuration(), - validationMetadata.validatedPathToSchemas(), - validationMetadata.seenClasses() + data.validationMetadata().configuration(), + data.validationMetadata().validatedPathToSchemas(), + data.validationMetadata().seenClasses() ); JsonSchema itemsSchema = JsonSchemaFactory.getInstance(prefixItems.get(i)); PathToSchemasMap otherPathToSchemas = JsonSchema.validate(itemsSchema, listArg.get(i), itemValidationMetadata); diff --git a/src/main/resources/java/src/main/java/packagename/schemas/validation/PropertiesValidator.hbs b/src/main/resources/java/src/main/java/packagename/schemas/validation/PropertiesValidator.hbs index 0a60eefd072..d2dc11f8ec1 100644 --- a/src/main/resources/java/src/main/java/packagename/schemas/validation/PropertiesValidator.hbs +++ b/src/main/resources/java/src/main/java/packagename/schemas/validation/PropertiesValidator.hbs @@ -9,22 +9,15 @@ import java.util.Map; import java.util.Set; public class PropertiesValidator implements KeywordValidator { - public final Map> properties; - - public PropertiesValidator(Map> properties) { - this.properties = properties; - } - @Override public @Nullable PathToSchemasMap validate( - JsonSchema schema, - @Nullable Object arg, - ValidationMetadata validationMetadata, - @Nullable List containsPathToSchemas, - @Nullable PathToSchemasMap patternPropertiesPathToSchemas, - @Nullable PathToSchemasMap ifPathToSchemas + ValidationData data ) { - if (!(arg instanceof Map mapArg)) { + var properties = data.schema().properties; + if (properties == null) { + return null; + } + if (!(data.arg() instanceof Map mapArg)) { return null; } PathToSchemasMap pathToSchemas = new PathToSchemasMap(); @@ -39,14 +32,14 @@ public class PropertiesValidator implements KeywordValidator { if (!presentProperties.contains(propName)) { continue; } - @Nullable Object propValue = ((Map) arg).get(propName); - List propPathToItem = new ArrayList<>(validationMetadata.pathToItem()); + @Nullable Object propValue = mapArg.get(propName); + List propPathToItem = new ArrayList<>(data.validationMetadata().pathToItem()); propPathToItem.add(propName); ValidationMetadata propValidationMetadata = new ValidationMetadata( propPathToItem, - validationMetadata.configuration(), - validationMetadata.validatedPathToSchemas(), - validationMetadata.seenClasses() + data.validationMetadata().configuration(), + data.validationMetadata().validatedPathToSchemas(), + data.validationMetadata().seenClasses() ); Class propClass = entry.getValue(); JsonSchema propSchema = JsonSchemaFactory.getInstance(propClass); @@ -60,4 +53,3 @@ public class PropertiesValidator implements KeywordValidator { return pathToSchemas; } } - diff --git a/src/main/resources/java/src/main/java/packagename/schemas/validation/PropertyNamesValidator.hbs b/src/main/resources/java/src/main/java/packagename/schemas/validation/PropertyNamesValidator.hbs index adeea3fe3bf..4777695d0f6 100644 --- a/src/main/resources/java/src/main/java/packagename/schemas/validation/PropertyNamesValidator.hbs +++ b/src/main/resources/java/src/main/java/packagename/schemas/validation/PropertyNamesValidator.hbs @@ -7,34 +7,27 @@ import java.util.List; import java.util.Map; public class PropertyNamesValidator implements KeywordValidator { - public final Class propertyNames; - - public PropertyNamesValidator(Class propertyNames) { - this.propertyNames = propertyNames; - } - @Override public @Nullable PathToSchemasMap validate( - JsonSchema schema, - @Nullable Object arg, - ValidationMetadata validationMetadata, - @Nullable List containsPathToSchemas, - @Nullable PathToSchemasMap patternPropertiesPathToSchemas, - @Nullable PathToSchemasMap ifPathToSchemas + ValidationData data ) { - if (!(arg instanceof Map)) { + var propertyNames = data.schema().propertyNames; + if (propertyNames == null) { + return null; + } + if (!(data.arg() instanceof Map mapArg)) { return null; } JsonSchema propertyNamesSchema = JsonSchemaFactory.getInstance(propertyNames); - for (Object objKey: ((Map) arg).keySet()) { + for (Object objKey: mapArg.keySet()) { if (objKey instanceof String key) { - List propPathToItem = new ArrayList<>(validationMetadata.pathToItem()); + List propPathToItem = new ArrayList<>(data.validationMetadata().pathToItem()); propPathToItem.add(key); ValidationMetadata keyValidationMetadata = new ValidationMetadata( propPathToItem, - validationMetadata.configuration(), - validationMetadata.validatedPathToSchemas(), - validationMetadata.seenClasses() + data.validationMetadata().configuration(), + data.validationMetadata().validatedPathToSchemas(), + data.validationMetadata().seenClasses() ); JsonSchema.validate(propertyNamesSchema, key, keyValidationMetadata); } diff --git a/src/main/resources/java/src/main/java/packagename/schemas/validation/RequiredValidator.hbs b/src/main/resources/java/src/main/java/packagename/schemas/validation/RequiredValidator.hbs index 33d8e66bf6d..eb6854827f9 100644 --- a/src/main/resources/java/src/main/java/packagename/schemas/validation/RequiredValidator.hbs +++ b/src/main/resources/java/src/main/java/packagename/schemas/validation/RequiredValidator.hbs @@ -9,26 +9,19 @@ import java.util.Map; import java.util.Set; public class RequiredValidator implements KeywordValidator { - public final Set required; - - public RequiredValidator(Set required) { - this.required = required; - } - @Override public @Nullable PathToSchemasMap validate( - JsonSchema schema, - @Nullable Object arg, - ValidationMetadata validationMetadata, - @Nullable List containsPathToSchemas, - @Nullable PathToSchemasMap patternPropertiesPathToSchemas, - @Nullable PathToSchemasMap ifPathToSchemas + ValidationData data ) { - if (!(arg instanceof Map)) { + var required = data.schema().required; + if (required == null) { + return null; + } + if (!(data.arg() instanceof Map mapArg)) { return null; } Set missingRequiredProperties = new HashSet<>(required); - for (Object key: ((Map) arg).keySet()) { + for (Object key: mapArg.keySet()) { if (key instanceof String) { missingRequiredProperties.remove(key); } @@ -40,7 +33,7 @@ public class RequiredValidator implements KeywordValidator { pluralChar = "s"; } throw new ValidationException( - schema.getClass()+" is missing "+missingRequiredProperties.size()+" required argument"+pluralChar+": "+missingReqProps + data.schema().getClass()+" is missing "+missingRequiredProperties.size()+" required argument"+pluralChar+": "+missingReqProps ); } return null; diff --git a/src/main/resources/java/src/main/java/packagename/schemas/validation/TypeValidator.hbs b/src/main/resources/java/src/main/java/packagename/schemas/validation/TypeValidator.hbs index c8d37de1477..0fab57d0561 100644 --- a/src/main/resources/java/src/main/java/packagename/schemas/validation/TypeValidator.hbs +++ b/src/main/resources/java/src/main/java/packagename/schemas/validation/TypeValidator.hbs @@ -5,25 +5,18 @@ import org.checkerframework.checker.nullness.qual.Nullable; import java.util.List; import java.util.Map; -import java.util.Set; public class TypeValidator implements KeywordValidator { - public final Set> type; - - public TypeValidator(Set> type) { - this.type = type; - } - @Override public @Nullable PathToSchemasMap validate( - JsonSchema schema, - @Nullable Object arg, - ValidationMetadata validationMetadata, - @Nullable List containsPathToSchemas, - @Nullable PathToSchemasMap patternPropertiesPathToSchemas, - @Nullable PathToSchemasMap ifPathToSchemas + ValidationData data ) { + var type = data.schema().type; + if (type == null) { + return null; + } Class argClass; + var arg = data.arg(); if (arg == null) { argClass = Void.class; } else if (arg instanceof List) { diff --git a/src/main/resources/java/src/main/java/packagename/schemas/validation/UniqueItemsValidator.hbs b/src/main/resources/java/src/main/java/packagename/schemas/validation/UniqueItemsValidator.hbs index 06bce39321b..fca9e17c2e5 100644 --- a/src/main/resources/java/src/main/java/packagename/schemas/validation/UniqueItemsValidator.hbs +++ b/src/main/resources/java/src/main/java/packagename/schemas/validation/UniqueItemsValidator.hbs @@ -8,29 +8,22 @@ import java.util.List; import java.util.Set; public class UniqueItemsValidator implements KeywordValidator { - public final boolean uniqueItems; - - public UniqueItemsValidator(boolean uniqueItems) { - this.uniqueItems = uniqueItems; - } - @Override public @Nullable PathToSchemasMap validate( - JsonSchema schema, - @Nullable Object arg, - ValidationMetadata validationMetadata, - @Nullable List containsPathToSchemas, - @Nullable PathToSchemasMap patternPropertiesPathToSchemas, - @Nullable PathToSchemasMap ifPathToSchemas + ValidationData data ) { - if (!(arg instanceof List)) { + var uniqueItems = data.schema().uniqueItems; + if (uniqueItems == null) { + return null; + } + if (!(data.arg() instanceof List listArg)) { return null; } if (!uniqueItems) { return null; } Set<@Nullable Object> seenItems = new HashSet<>(); - for (@Nullable Object item: (List) arg) { + for (@Nullable Object item: listArg) { int startingSeenItemsSize = seenItems.size(); seenItems.add(item); if (seenItems.size() == startingSeenItemsSize) { diff --git a/src/main/resources/java/src/main/java/packagename/schemas/validation/ValidationData.hbs b/src/main/resources/java/src/main/java/packagename/schemas/validation/ValidationData.hbs new file mode 100644 index 00000000000..55cb65fe9ef --- /dev/null +++ b/src/main/resources/java/src/main/java/packagename/schemas/validation/ValidationData.hbs @@ -0,0 +1,22 @@ +package org.openapijsonschematools.client.schemas.validation; + +import org.checkerframework.checker.nullness.qual.Nullable; + +import java.util.List; + +public record ValidationData( + JsonSchema schema, + @Nullable Object arg, + ValidationMetadata validationMetadata, + @Nullable List containsPathToSchemas, + @Nullable PathToSchemasMap patternPropertiesPathToSchemas, + @Nullable PathToSchemasMap ifPathToSchemas +) { + public ValidationData( + JsonSchema schema, + @Nullable Object arg, + ValidationMetadata validationMetadata + ) { + this(schema, arg, validationMetadata, null, null, null); + } +} \ No newline at end of file diff --git a/src/main/resources/java/src/test/java/packagename/schemas/validation/AdditionalPropertiesValidatorTest.hbs b/src/main/resources/java/src/test/java/packagename/schemas/validation/AdditionalPropertiesValidatorTest.hbs index 2e1a80bc048..fa2fcf78638 100644 --- a/src/main/resources/java/src/test/java/packagename/schemas/validation/AdditionalPropertiesValidatorTest.hbs +++ b/src/main/resources/java/src/test/java/packagename/schemas/validation/AdditionalPropertiesValidatorTest.hbs @@ -26,6 +26,7 @@ public class AdditionalPropertiesValidatorTest { .properties(Map.ofEntries( new PropertyEntry("someString", StringJsonSchema.class) )) + .additionalProperties(StringJsonSchema.class) ); } @@ -73,14 +74,13 @@ public class AdditionalPropertiesValidatorTest { mutableMap.put("someString", "abc"); mutableMap.put("someAddProp", "def"); FrozenMap arg = new FrozenMap<>(mutableMap); - final AdditionalPropertiesValidator validator = new AdditionalPropertiesValidator(StringJsonSchema.class); + final AdditionalPropertiesValidator validator = new AdditionalPropertiesValidator(); PathToSchemasMap pathToSchemas = validator.validate( - ObjectWithPropsSchema.getInstance(), - arg, - validationMetadata, - new ArrayList<>(), - new PathToSchemasMap(), - new PathToSchemasMap() + new ValidationData( + ObjectWithPropsSchema.getInstance(), + arg, + validationMetadata + ) ); if (pathToSchemas == null) { throw new RuntimeException("Invalid null value for pathToSchemas for this test case"); @@ -105,14 +105,13 @@ public class AdditionalPropertiesValidatorTest { new PathToSchemasMap(), new LinkedHashSet<>() ); - final AdditionalPropertiesValidator validator = new AdditionalPropertiesValidator(StringJsonSchema.class); + final AdditionalPropertiesValidator validator = new AdditionalPropertiesValidator(); PathToSchemasMap pathToSchemas = validator.validate( - MapJsonSchema.getInstance(), - 1, - validationMetadata, - new ArrayList<>(), - new PathToSchemasMap(), - new PathToSchemasMap() + new ValidationData( + MapJsonSchema.getInstance(), + 1, + validationMetadata + ) ); assertNull(pathToSchemas); } @@ -130,14 +129,13 @@ public class AdditionalPropertiesValidatorTest { mutableMap.put("someString", "abc"); mutableMap.put("someAddProp", 1); FrozenMap arg = new FrozenMap<>(mutableMap); - final AdditionalPropertiesValidator validator = new AdditionalPropertiesValidator(StringJsonSchema.class); + final AdditionalPropertiesValidator validator = new AdditionalPropertiesValidator(); Assert.assertThrows(ValidationException.class, () -> validator.validate( - ObjectWithPropsSchema.getInstance(), - arg, - validationMetadata, - new ArrayList<>(), - new PathToSchemasMap(), - new PathToSchemasMap() + new ValidationData( + ObjectWithPropsSchema.getInstance(), + arg, + validationMetadata + ) )); } } \ No newline at end of file diff --git a/src/main/resources/java/src/test/java/packagename/schemas/validation/FormatValidatorTest.hbs b/src/main/resources/java/src/test/java/packagename/schemas/validation/FormatValidatorTest.hbs index c9027395af2..9b91cf32a07 100644 --- a/src/main/resources/java/src/test/java/packagename/schemas/validation/FormatValidatorTest.hbs +++ b/src/main/resources/java/src/test/java/packagename/schemas/validation/FormatValidatorTest.hbs @@ -6,8 +6,14 @@ import org.junit.Test; import {{{packageName}}}.configurations.JsonSchemaKeywordFlags; import {{{packageName}}}.configurations.SchemaConfiguration; import {{{packageName}}}.exceptions.ValidationException; -import {{{packageName}}}.schemas.NumberJsonSchema; -import {{{packageName}}}.schemas.StringJsonSchema; +import {{{packageName}}}.schemas.IntJsonSchema; +import {{{packageName}}}.schemas.Int32JsonSchema; +import {{{packageName}}}.schemas.Int64JsonSchema; +import {{{packageName}}}.schemas.FloatJsonSchema; +import {{{packageName}}}.schemas.DoubleJsonSchema; +import {{{packageName}}}.schemas.DecimalJsonSchema; +import {{{packageName}}}.schemas.DateJsonSchema; +import {{{packageName}}}.schemas.DateTimeJsonSchema; import java.math.BigDecimal; import java.math.BigInteger; @@ -29,354 +35,328 @@ public class FormatValidatorTest { @Test public void testIntFormatSucceedsWithFloat() { - final FormatValidator validator = new FormatValidator("int"); + final FormatValidator validator = new FormatValidator(); PathToSchemasMap pathToSchemasMap = validator.validate( - NumberJsonSchema.getInstance(), - 1.0f, - validationMetadata, - new ArrayList<>(), - new PathToSchemasMap(), - new PathToSchemasMap() + new ValidationData( + IntJsonSchema.getInstance(), + 1.0f, + validationMetadata + ) ); assertNull(pathToSchemasMap); } @Test public void testIntFormatFailsWithFloat() { - final FormatValidator validator = new FormatValidator("int"); + final FormatValidator validator = new FormatValidator(); Assert.assertThrows(ValidationException.class, () -> validator.validate( - NumberJsonSchema.getInstance(), - 3.14f, - validationMetadata, - new ArrayList<>(), - new PathToSchemasMap(), - new PathToSchemasMap() + new ValidationData( + IntJsonSchema.getInstance(), + 3.14f, + validationMetadata + ) )); } @Test public void testIntFormatSucceedsWithInt() { - final FormatValidator validator = new FormatValidator("int"); + final FormatValidator validator = new FormatValidator(); PathToSchemasMap pathToSchemasMap = validator.validate( - NumberJsonSchema.getInstance(), - 1, - validationMetadata, - new ArrayList<>(), - new PathToSchemasMap(), - new PathToSchemasMap() + new ValidationData( + IntJsonSchema.getInstance(), + 1, + validationMetadata + ) ); assertNull(pathToSchemasMap); } @Test public void testInt32UnderMinFails() { - final FormatValidator validator = new FormatValidator("int32"); + final FormatValidator validator = new FormatValidator(); Assert.assertThrows(ValidationException.class, () -> validator.validate( - NumberJsonSchema.getInstance(), - -2147483649L, - validationMetadata, - new ArrayList<>(), - new PathToSchemasMap(), - new PathToSchemasMap() + new ValidationData( + Int32JsonSchema.getInstance(), + -2147483649L, + validationMetadata + ) )); } @Test public void testInt32InclusiveMinSucceeds() { - final FormatValidator validator = new FormatValidator("int32"); + final FormatValidator validator = new FormatValidator(); PathToSchemasMap pathToSchemasMap = validator.validate( - NumberJsonSchema.getInstance(), - -2147483648, - validationMetadata, - new ArrayList<>(), - new PathToSchemasMap(), - new PathToSchemasMap() + new ValidationData( + Int32JsonSchema.getInstance(), + -2147483648, + validationMetadata + ) ); assertNull(pathToSchemasMap); } @Test public void testInt32InclusiveMaxSucceeds() { - final FormatValidator validator = new FormatValidator("int32"); + final FormatValidator validator = new FormatValidator(); PathToSchemasMap pathToSchemasMap = validator.validate( - NumberJsonSchema.getInstance(), - 2147483647, - validationMetadata, - new ArrayList<>(), - new PathToSchemasMap(), - new PathToSchemasMap() + new ValidationData( + Int32JsonSchema.getInstance(), + 2147483647, + validationMetadata + ) ); assertNull(pathToSchemasMap); } @Test public void testInt32OverMaxFails() { - final FormatValidator validator = new FormatValidator("int32"); + final FormatValidator validator = new FormatValidator(); Assert.assertThrows(ValidationException.class, () -> validator.validate( - NumberJsonSchema.getInstance(), - 2147483648L, - validationMetadata, - new ArrayList<>(), - new PathToSchemasMap(), - new PathToSchemasMap() + new ValidationData( + Int32JsonSchema.getInstance(), + 2147483648L, + validationMetadata + ) )); } @Test public void testInt64UnderMinFails() { - final FormatValidator validator = new FormatValidator("int64"); + final FormatValidator validator = new FormatValidator(); Assert.assertThrows(ValidationException.class, () -> validator.validate( - NumberJsonSchema.getInstance(), - new BigInteger("-9223372036854775809"), - validationMetadata, - new ArrayList<>(), - new PathToSchemasMap(), - new PathToSchemasMap() + new ValidationData( + Int64JsonSchema.getInstance(), + new BigInteger("-9223372036854775809"), + validationMetadata + ) )); } @Test public void testInt64InclusiveMinSucceeds() { - final FormatValidator validator = new FormatValidator("int64"); + final FormatValidator validator = new FormatValidator(); PathToSchemasMap pathToSchemasMap = validator.validate( - NumberJsonSchema.getInstance(), - -9223372036854775808L, - validationMetadata, - new ArrayList<>(), - new PathToSchemasMap(), - new PathToSchemasMap() + new ValidationData( + Int64JsonSchema.getInstance(), + -9223372036854775808L, + validationMetadata + ) ); assertNull(pathToSchemasMap); } @Test public void testInt64InclusiveMaxSucceeds() { - final FormatValidator validator = new FormatValidator("int64"); + final FormatValidator validator = new FormatValidator(); PathToSchemasMap pathToSchemasMap = validator.validate( - NumberJsonSchema.getInstance(), - 9223372036854775807L, - validationMetadata, - new ArrayList<>(), - new PathToSchemasMap(), - new PathToSchemasMap() + new ValidationData( + Int64JsonSchema.getInstance(), + 9223372036854775807L, + validationMetadata + ) ); assertNull(pathToSchemasMap); } @Test public void testInt64OverMaxFails() { - final FormatValidator validator = new FormatValidator("int64"); + final FormatValidator validator = new FormatValidator(); Assert.assertThrows(ValidationException.class, () -> validator.validate( - NumberJsonSchema.getInstance(), - new BigInteger("9223372036854775808"), - validationMetadata, - new ArrayList<>(), - new PathToSchemasMap(), - new PathToSchemasMap() + new ValidationData( + Int64JsonSchema.getInstance(), + new BigInteger("9223372036854775808"), + validationMetadata + ) )); } @Test public void testFloatUnderMinFails() { - final FormatValidator validator = new FormatValidator("float"); + final FormatValidator validator = new FormatValidator(); Assert.assertThrows(ValidationException.class, () -> validator.validate( - NumberJsonSchema.getInstance(), - -3.402823466385289e+38d, - validationMetadata, - new ArrayList<>(), - new PathToSchemasMap(), - new PathToSchemasMap() + new ValidationData( + FloatJsonSchema.getInstance(), + -3.402823466385289e+38d, + validationMetadata + ) )); } @Test public void testFloatInclusiveMinSucceeds() { - final FormatValidator validator = new FormatValidator("float"); + final FormatValidator validator = new FormatValidator(); PathToSchemasMap pathToSchemasMap = validator.validate( - NumberJsonSchema.getInstance(), - -3.4028234663852886e+38f, - validationMetadata, - new ArrayList<>(), - new PathToSchemasMap(), - new PathToSchemasMap() + new ValidationData( + FloatJsonSchema.getInstance(), + -3.4028234663852886e+38f, + validationMetadata + ) ); assertNull(pathToSchemasMap); } @Test public void testFloatInclusiveMaxSucceeds() { - final FormatValidator validator = new FormatValidator("float"); + final FormatValidator validator = new FormatValidator(); PathToSchemasMap pathToSchemasMap = validator.validate( - NumberJsonSchema.getInstance(), - 3.4028234663852886e+38f, - validationMetadata, - new ArrayList<>(), - new PathToSchemasMap(), - new PathToSchemasMap() + new ValidationData( + FloatJsonSchema.getInstance(), + 3.4028234663852886e+38f, + validationMetadata + ) ); assertNull(pathToSchemasMap); } @Test public void testFloatOverMaxFails() { - final FormatValidator validator = new FormatValidator("float"); + final FormatValidator validator = new FormatValidator(); Assert.assertThrows(ValidationException.class, () -> validator.validate( - NumberJsonSchema.getInstance(), - 3.402823466385289e+38d, - validationMetadata, - new ArrayList<>(), - new PathToSchemasMap(), - new PathToSchemasMap() + new ValidationData( + FloatJsonSchema.getInstance(), + 3.402823466385289e+38d, + validationMetadata + ) )); } @Test public void testDoubleUnderMinFails() { - final FormatValidator validator = new FormatValidator("double"); + final FormatValidator validator = new FormatValidator(); Assert.assertThrows(ValidationException.class, () -> validator.validate( - NumberJsonSchema.getInstance(), - new BigDecimal("-1.7976931348623157082e+308"), - validationMetadata, - new ArrayList<>(), - new PathToSchemasMap(), - new PathToSchemasMap() + new ValidationData( + DoubleJsonSchema.getInstance(), + new BigDecimal("-1.7976931348623157082e+308"), + validationMetadata + ) )); } @Test public void testDoubleInclusiveMinSucceeds() { - final FormatValidator validator = new FormatValidator("double"); + final FormatValidator validator = new FormatValidator(); PathToSchemasMap pathToSchemasMap = validator.validate( - NumberJsonSchema.getInstance(), - -1.7976931348623157E+308d, - validationMetadata, - new ArrayList<>(), - new PathToSchemasMap(), - new PathToSchemasMap() + new ValidationData( + DoubleJsonSchema.getInstance(), + -1.7976931348623157E+308d, + validationMetadata + ) ); assertNull(pathToSchemasMap); } @Test public void testDoubleInclusiveMaxSucceeds() { - final FormatValidator validator = new FormatValidator("double"); + final FormatValidator validator = new FormatValidator(); PathToSchemasMap pathToSchemasMap = validator.validate( - NumberJsonSchema.getInstance(), - 1.7976931348623157E+308d, - validationMetadata, - new ArrayList<>(), - new PathToSchemasMap(), - new PathToSchemasMap() + new ValidationData( + DoubleJsonSchema.getInstance(), + 1.7976931348623157E+308d, + validationMetadata + ) ); assertNull(pathToSchemasMap); } @Test public void testDoubleOverMaxFails() { - final FormatValidator validator = new FormatValidator("double"); + final FormatValidator validator = new FormatValidator(); Assert.assertThrows(ValidationException.class, () -> validator.validate( - NumberJsonSchema.getInstance(), - new BigDecimal("1.7976931348623157082e+308"), - validationMetadata, - new ArrayList<>(), - new PathToSchemasMap(), - new PathToSchemasMap() + new ValidationData( + DoubleJsonSchema.getInstance(), + new BigDecimal("1.7976931348623157082e+308"), + validationMetadata + ) )); } @Test public void testInvalidNumberStringFails() { - final FormatValidator validator = new FormatValidator("number"); + final FormatValidator validator = new FormatValidator(); Assert.assertThrows(ValidationException.class, () -> validator.validate( - NumberJsonSchema.getInstance(), - "abc", - validationMetadata, - new ArrayList<>(), - new PathToSchemasMap(), - new PathToSchemasMap() + new ValidationData( + DecimalJsonSchema.getInstance(), + "abc", + validationMetadata + ) )); } @Test public void testValidFloatNumberStringSucceeds() { - final FormatValidator validator = new FormatValidator("number"); + final FormatValidator validator = new FormatValidator(); PathToSchemasMap pathToSchemasMap = validator.validate( - NumberJsonSchema.getInstance(), - "3.14", - validationMetadata, - new ArrayList<>(), - new PathToSchemasMap(), - new PathToSchemasMap() + new ValidationData( + DecimalJsonSchema.getInstance(), + "3.14", + validationMetadata + ) ); assertNull(pathToSchemasMap); } @Test public void testValidIntNumberStringSucceeds() { - final FormatValidator validator = new FormatValidator("number"); + final FormatValidator validator = new FormatValidator(); PathToSchemasMap pathToSchemasMap = validator.validate( - NumberJsonSchema.getInstance(), - "1", - validationMetadata, - new ArrayList<>(), - new PathToSchemasMap(), - new PathToSchemasMap() + new ValidationData( + DecimalJsonSchema.getInstance(), + "1", + validationMetadata + ) ); assertNull(pathToSchemasMap); } @Test public void testInvalidDateStringFails() { - final FormatValidator validator = new FormatValidator("date"); + final FormatValidator validator = new FormatValidator(); Assert.assertThrows(ValidationException.class, () -> validator.validate( - StringJsonSchema.getInstance(), - "abc", - validationMetadata, - new ArrayList<>(), - new PathToSchemasMap(), - new PathToSchemasMap() + new ValidationData( + DateJsonSchema.getInstance(), + "abc", + validationMetadata + ) )); } @Test public void testValidDateStringSucceeds() { - final FormatValidator validator = new FormatValidator("date"); + final FormatValidator validator = new FormatValidator(); PathToSchemasMap pathToSchemasMap = validator.validate( - StringJsonSchema.getInstance(), - "2017-01-20", - validationMetadata, - new ArrayList<>(), - new PathToSchemasMap(), - new PathToSchemasMap() + new ValidationData( + DateJsonSchema.getInstance(), + "2017-01-20", + validationMetadata + ) ); assertNull(pathToSchemasMap); } @Test public void testInvalidDateTimeStringFails() { - final FormatValidator validator = new FormatValidator("date-time"); + final FormatValidator validator = new FormatValidator(); Assert.assertThrows(ValidationException.class, () -> validator.validate( - StringJsonSchema.getInstance(), - "abc", - validationMetadata, - new ArrayList<>(), - new PathToSchemasMap(), - new PathToSchemasMap() + new ValidationData( + DateTimeJsonSchema.getInstance(), + "abc", + validationMetadata + ) )); } @Test public void testValidDateTimeStringSucceeds() { - final FormatValidator validator = new FormatValidator("date-time"); + final FormatValidator validator = new FormatValidator(); PathToSchemasMap pathToSchemasMap = validator.validate( - StringJsonSchema.getInstance(), - "2017-07-21T17:32:28Z", - validationMetadata, - new ArrayList<>(), - new PathToSchemasMap(), - new PathToSchemasMap() + new ValidationData( + DateTimeJsonSchema.getInstance(), + "2017-07-21T17:32:28Z", + validationMetadata + ) ); assertNull(pathToSchemasMap); } diff --git a/src/main/resources/java/src/test/java/packagename/schemas/validation/ItemsValidatorTest.hbs b/src/main/resources/java/src/test/java/packagename/schemas/validation/ItemsValidatorTest.hbs index 84f2ebfc8b3..9fd1924fee1 100644 --- a/src/main/resources/java/src/test/java/packagename/schemas/validation/ItemsValidatorTest.hbs +++ b/src/main/resources/java/src/test/java/packagename/schemas/validation/ItemsValidatorTest.hbs @@ -5,14 +5,15 @@ import org.junit.Assert; import org.junit.Test; import {{{packageName}}}.configurations.JsonSchemaKeywordFlags; import {{{packageName}}}.configurations.SchemaConfiguration; -import {{{packageName}}}.schemas.ListJsonSchema; import {{{packageName}}}.schemas.StringJsonSchema; +import {{{packageName}}}.exceptions.InvalidTypeException; import {{{packageName}}}.exceptions.ValidationException; import java.util.ArrayList; import java.util.LinkedHashMap; import java.util.LinkedHashSet; import java.util.List; +import java.util.Set; public class ItemsValidatorTest { @SuppressWarnings("nullness") @@ -20,6 +21,31 @@ public class ItemsValidatorTest { Assert.assertNull(object); } + public static class ArrayWithItemsSchema extends JsonSchema { + public ArrayWithItemsSchema() { + super(new JsonSchemaInfo() + .type(Set.of(List.class)) + .items(StringJsonSchema.class) + ); + } + + @Override + public Object getNewInstance(@Nullable Object arg, List pathToItem, PathToSchemasMap pathToSchemas) { + if (arg instanceof List listArg) { + return getNewInstance(listArg, pathToItem, pathToSchemas); + } + throw new InvalidTypeException("Invalid input type="+getClass(arg)+". It can't be instantiated by this schema"); + } + + @Override + public @Nullable Object validate(@Nullable Object arg, SchemaConfiguration configuration) throws InvalidTypeException, ValidationException { + if (arg instanceof List listArg) { + return validate(listArg, configuration); + } + throw new InvalidTypeException("Invalid input type="+getClass(arg)+". It can't be validated by this schema"); + } + } + @Test public void testCorrectItemsSucceeds() { List pathToItem = List.of("args[0]"); @@ -32,14 +58,13 @@ public class ItemsValidatorTest { List mutableList = new ArrayList<>(); mutableList.add("a"); FrozenList arg = new FrozenList<>(mutableList); - final ItemsValidator validator = new ItemsValidator(StringJsonSchema.class); + final ItemsValidator validator = new ItemsValidator(); PathToSchemasMap pathToSchemas = validator.validate( - ListJsonSchema.getInstance(), - arg, - validationMetadata, - new ArrayList<>(), - new PathToSchemasMap(), - new PathToSchemasMap() + new ValidationData( + new ArrayWithItemsSchema(), + arg, + validationMetadata + ) ); if (pathToSchemas == null) { throw new RuntimeException("Invalid null value in pathToSchemas for this test case"); @@ -64,14 +89,13 @@ public class ItemsValidatorTest { new PathToSchemasMap(), new LinkedHashSet<>() ); - final ItemsValidator validator = new ItemsValidator(StringJsonSchema.class); + final ItemsValidator validator = new ItemsValidator(); PathToSchemasMap pathToSchemas = validator.validate( - ListJsonSchema.getInstance(), - 1, - validationMetadata, - new ArrayList<>(), - new PathToSchemasMap(), - new PathToSchemasMap() + new ValidationData( + new ArrayWithItemsSchema(), + 1, + validationMetadata + ) ); assertNull(pathToSchemas); } @@ -88,14 +112,13 @@ public class ItemsValidatorTest { List mutableList = new ArrayList<>(); mutableList.add(1); FrozenList arg = new FrozenList<>(mutableList); - final ItemsValidator validator = new ItemsValidator(StringJsonSchema.class); + final ItemsValidator validator = new ItemsValidator(); Assert.assertThrows(ValidationException.class, () -> validator.validate( - ListJsonSchema.getInstance(), - arg, - validationMetadata, - new ArrayList<>(), - new PathToSchemasMap(), - new PathToSchemasMap() + new ValidationData( + new ArrayWithItemsSchema(), + arg, + validationMetadata + ) )); } -} +} \ No newline at end of file diff --git a/src/main/resources/java/src/test/java/packagename/schemas/validation/PropertiesValidatorTest.hbs b/src/main/resources/java/src/test/java/packagename/schemas/validation/PropertiesValidatorTest.hbs index 05c565fabb9..96bb3482923 100644 --- a/src/main/resources/java/src/test/java/packagename/schemas/validation/PropertiesValidatorTest.hbs +++ b/src/main/resources/java/src/test/java/packagename/schemas/validation/PropertiesValidatorTest.hbs @@ -5,7 +5,7 @@ import org.junit.Assert; import org.junit.Test; import {{{packageName}}}.configurations.JsonSchemaKeywordFlags; import {{{packageName}}}.configurations.SchemaConfiguration; -import {{{packageName}}}.schemas.MapJsonSchema; +import {{{packageName}}}.exceptions.InvalidTypeException; import {{{packageName}}}.schemas.StringJsonSchema; import {{{packageName}}}.exceptions.ValidationException; @@ -14,8 +14,37 @@ import java.util.LinkedHashMap; import java.util.LinkedHashSet; import java.util.List; import java.util.Map; +import java.util.Set; public class PropertiesValidatorTest { + public static class ObjectWithPropsSchema extends JsonSchema { + private ObjectWithPropsSchema() { + super(new JsonSchemaInfo() + .type(Set.of(Map.class)) + .properties(Map.ofEntries( + new PropertyEntry("someString", StringJsonSchema.class) + )) + ); + + } + + @Override + public Object getNewInstance(@Nullable Object arg, List pathToItem, PathToSchemasMap pathToSchemas) { + if (arg instanceof Map mapArg) { + return getNewInstance(mapArg, pathToItem, pathToSchemas); + } + throw new InvalidTypeException("Invalid input type="+getClass(arg)+". It can't be instantiated by this schema"); + } + + @Override + public @Nullable Object validate(@Nullable Object arg, SchemaConfiguration configuration) throws InvalidTypeException, ValidationException { + if (arg instanceof Map mapArg) { + return validate(mapArg, configuration); + } + throw new InvalidTypeException("Invalid input type="+getClass(arg)+". It can't be validated by this schema"); + } + } + @SuppressWarnings("nullness") private void assertNull(@Nullable Object object) { Assert.assertNull(object); @@ -23,10 +52,7 @@ public class PropertiesValidatorTest { @Test public void testCorrectPropertySucceeds() { - Map> properties = new LinkedHashMap<>(); - properties.put("someString", StringJsonSchema.class); - - final PropertiesValidator validator = new PropertiesValidator(properties); + final PropertiesValidator validator = new PropertiesValidator(); List pathToItem = List.of("args[0]"); ValidationMetadata validationMetadata = new ValidationMetadata( pathToItem, @@ -38,12 +64,11 @@ public class PropertiesValidatorTest { mutableMap.put("someString", "abc"); FrozenMap arg = new FrozenMap<>(mutableMap); PathToSchemasMap pathToSchemas = validator.validate( - MapJsonSchema.getInstance(), - arg, - validationMetadata, - new ArrayList<>(), - new PathToSchemasMap(), - new PathToSchemasMap() + new ValidationData( + new ObjectWithPropsSchema(), + arg, + validationMetadata + ) ); if (pathToSchemas == null) { throw new RuntimeException("Invalid null value for pathToSchemas for this test case"); @@ -60,10 +85,7 @@ public class PropertiesValidatorTest { @Test public void testNotApplicableTypeReturnsNull() { - Map> properties = new LinkedHashMap<>(); - properties.put("someString", StringJsonSchema.class); - - final PropertiesValidator validator = new PropertiesValidator(properties); + final PropertiesValidator validator = new PropertiesValidator(); List pathToItem = List.of("args[0]"); ValidationMetadata validationMetadata = new ValidationMetadata( pathToItem, @@ -72,22 +94,18 @@ public class PropertiesValidatorTest { new LinkedHashSet<>() ); PathToSchemasMap pathToSchemas = validator.validate( - MapJsonSchema.getInstance(), - 1, - validationMetadata, - new ArrayList<>(), - new PathToSchemasMap(), - new PathToSchemasMap() + new ValidationData( + new ObjectWithPropsSchema(), + 1, + validationMetadata + ) ); assertNull(pathToSchemas); } @Test public void testIncorrectPropertyValueFails() { - Map> properties = new LinkedHashMap<>(); - properties.put("someString", StringJsonSchema.class); - - final PropertiesValidator validator = new PropertiesValidator(properties); + final PropertiesValidator validator = new PropertiesValidator(); List pathToItem = List.of("args[0]"); ValidationMetadata validationMetadata = new ValidationMetadata( pathToItem, @@ -99,12 +117,11 @@ public class PropertiesValidatorTest { mutableMap.put("someString", 1); FrozenMap arg = new FrozenMap<>(mutableMap); Assert.assertThrows(ValidationException.class, () -> validator.validate( - MapJsonSchema.getInstance(), - arg, - validationMetadata, - new ArrayList<>(), - new PathToSchemasMap(), - new PathToSchemasMap() + new ValidationData( + new ObjectWithPropsSchema(), + arg, + validationMetadata + ) )); } } \ No newline at end of file diff --git a/src/main/resources/java/src/test/java/packagename/schemas/validation/RequiredValidatorTest.hbs b/src/main/resources/java/src/test/java/packagename/schemas/validation/RequiredValidatorTest.hbs index 746409eff44..d18574778b4 100644 --- a/src/main/resources/java/src/test/java/packagename/schemas/validation/RequiredValidatorTest.hbs +++ b/src/main/resources/java/src/test/java/packagename/schemas/validation/RequiredValidatorTest.hbs @@ -5,16 +5,42 @@ import org.junit.Assert; import org.junit.Test; import {{{packageName}}}.configurations.JsonSchemaKeywordFlags; import {{{packageName}}}.configurations.SchemaConfiguration; +import {{{packageName}}}.exceptions.InvalidTypeException; import {{{packageName}}}.exceptions.ValidationException; -import {{{packageName}}}.schemas.MapJsonSchema; -import java.util.ArrayList; import java.util.LinkedHashMap; import java.util.LinkedHashSet; import java.util.List; +import java.util.Map; import java.util.Set; public class RequiredValidatorTest { + public static class ObjectWithRequiredSchema extends JsonSchema { + private ObjectWithRequiredSchema() { + super(new JsonSchemaInfo() + .type(Set.of(Map.class)) + .required(Set.of("someString")) + ); + + } + + @Override + public Object getNewInstance(@Nullable Object arg, List pathToItem, PathToSchemasMap pathToSchemas) { + if (arg instanceof Map mapArg) { + return getNewInstance(mapArg, pathToItem, pathToSchemas); + } + throw new InvalidTypeException("Invalid input type="+getClass(arg)+". It can't be instantiated by this schema"); + } + + @Override + public @Nullable Object validate(@Nullable Object arg, SchemaConfiguration configuration) throws InvalidTypeException, ValidationException { + if (arg instanceof Map mapArg) { + return validate(mapArg, configuration); + } + throw new InvalidTypeException("Invalid input type="+getClass(arg)+". It can't be validated by this schema"); + } + } + @SuppressWarnings("nullness") private void assertNull(@Nullable Object object) { Assert.assertNull(object); @@ -22,9 +48,6 @@ public class RequiredValidatorTest { @Test public void testCorrectPropertySucceeds() { - Set requiredProperties = new LinkedHashSet<>(); - requiredProperties.add("someString"); - List pathToItem = List.of("args[0]"); ValidationMetadata validationMetadata = new ValidationMetadata( pathToItem, @@ -35,23 +58,19 @@ public class RequiredValidatorTest { LinkedHashMap mutableMap = new LinkedHashMap<>(); mutableMap.put("someString", "abc"); FrozenMap arg = new FrozenMap<>(mutableMap); - final RequiredValidator validator = new RequiredValidator(requiredProperties); + final RequiredValidator validator = new RequiredValidator(); PathToSchemasMap pathToSchemas = validator.validate( - MapJsonSchema.getInstance(), - arg, - validationMetadata, - new ArrayList<>(), - new PathToSchemasMap(), - new PathToSchemasMap() + new ValidationData( + new ObjectWithRequiredSchema(), + arg, + validationMetadata + ) ); assertNull(pathToSchemas); } @Test public void testNotApplicableTypeReturnsNull() { - Set requiredProperties = new LinkedHashSet<>(); - requiredProperties.add("someString"); - List pathToItem = List.of("args[0]"); ValidationMetadata validationMetadata = new ValidationMetadata( pathToItem, @@ -59,23 +78,19 @@ public class RequiredValidatorTest { new PathToSchemasMap(), new LinkedHashSet<>() ); - final RequiredValidator validator = new RequiredValidator(requiredProperties); + final RequiredValidator validator = new RequiredValidator(); PathToSchemasMap pathToSchemas = validator.validate( - MapJsonSchema.getInstance(), - 1, - validationMetadata, - new ArrayList<>(), - new PathToSchemasMap(), - new PathToSchemasMap() + new ValidationData( + new ObjectWithRequiredSchema(), + 1, + validationMetadata + ) ); assertNull(pathToSchemas); } @Test public void testIncorrectPropertyFails() { - Set requiredProperties = new LinkedHashSet<>(); - requiredProperties.add("someString"); - List pathToItem = List.of("args[0]"); ValidationMetadata validationMetadata = new ValidationMetadata( pathToItem, @@ -86,14 +101,13 @@ public class RequiredValidatorTest { LinkedHashMap mutableMap = new LinkedHashMap<>(); mutableMap.put("aDifferentProp", 1); FrozenMap arg = new FrozenMap<>(mutableMap); - final RequiredValidator validator = new RequiredValidator(requiredProperties); + final RequiredValidator validator = new RequiredValidator(); Assert.assertThrows(ValidationException.class, () -> validator.validate( - MapJsonSchema.getInstance(), - arg, - validationMetadata, - new ArrayList<>(), - new PathToSchemasMap(), - new PathToSchemasMap() + new ValidationData( + new ObjectWithRequiredSchema(), + arg, + validationMetadata + ) )); } } \ No newline at end of file diff --git a/src/main/resources/java/src/test/java/packagename/schemas/validation/TypeValidatorTest.hbs b/src/main/resources/java/src/test/java/packagename/schemas/validation/TypeValidatorTest.hbs index 3ce4264cd1c..5cb5fcde8f7 100644 --- a/src/main/resources/java/src/test/java/packagename/schemas/validation/TypeValidatorTest.hbs +++ b/src/main/resources/java/src/test/java/packagename/schemas/validation/TypeValidatorTest.hbs @@ -19,9 +19,7 @@ public class TypeValidatorTest { @Test public void testValidateSucceeds() { - LinkedHashSet> type = new LinkedHashSet<>(); - type.add(String.class); - final TypeValidator validator = new TypeValidator(type); + final TypeValidator validator = new TypeValidator(); ValidationMetadata validationMetadata = new ValidationMetadata( new ArrayList<>(), new SchemaConfiguration(JsonSchemaKeywordFlags.ofNone()), @@ -29,21 +27,18 @@ public class TypeValidatorTest { new LinkedHashSet<>() ); @Nullable PathToSchemasMap pathToSchemasMap = validator.validate( - StringJsonSchema.getInstance(), - "hi", - validationMetadata, - new ArrayList<>(), - new PathToSchemasMap(), - new PathToSchemasMap() + new ValidationData( + StringJsonSchema.getInstance(), + "hi", + validationMetadata + ) ); assertNull(pathToSchemasMap); } @Test public void testValidateFailsIntIsNotString() { - LinkedHashSet> type = new LinkedHashSet<>(); - type.add(String.class); - final TypeValidator validator = new TypeValidator(type); + final TypeValidator validator = new TypeValidator(); ValidationMetadata validationMetadata = new ValidationMetadata( new ArrayList<>(), new SchemaConfiguration(JsonSchemaKeywordFlags.ofNone()), @@ -51,12 +46,11 @@ public class TypeValidatorTest { new LinkedHashSet<>() ); Assert.assertThrows(ValidationException.class, () -> validator.validate( - StringJsonSchema.getInstance(), - 1, - validationMetadata, - new ArrayList<>(), - new PathToSchemasMap(), - new PathToSchemasMap() + new ValidationData( + StringJsonSchema.getInstance(), + 1, + validationMetadata + ) )); } } \ No newline at end of file