Skip to content
This repository was archived by the owner on Dec 25, 2024. It is now read-only.

Java: adds MapSchema #279

Merged
merged 7 commits into from
Nov 8, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions samples/client/petstore/java/.openapi-generator/FILES
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,11 @@ src/main/java/org/openapijsonschematools/schemas/DateTimeSchema.java
src/main/java/org/openapijsonschematools/schemas/DecimalSchema.java
src/main/java/org/openapijsonschematools/schemas/DoubleSchema.java
src/main/java/org/openapijsonschematools/schemas/FloatSchema.java
src/main/java/org/openapijsonschematools/schemas/FrozenMap.java
src/main/java/org/openapijsonschematools/schemas/Int32Schema.java
src/main/java/org/openapijsonschematools/schemas/Int64Schema.java
src/main/java/org/openapijsonschematools/schemas/IntSchema.java
src/main/java/org/openapijsonschematools/schemas/MapSchema.java
src/main/java/org/openapijsonschematools/schemas/NullSchema.java
src/main/java/org/openapijsonschematools/schemas/NumberSchema.java
src/main/java/org/openapijsonschematools/schemas/PathToSchemasMap.java
Expand All @@ -22,15 +24,23 @@ src/main/java/org/openapijsonschematools/schemas/SchemaValidator.java
src/main/java/org/openapijsonschematools/schemas/StringSchema.java
src/main/java/org/openapijsonschematools/schemas/UnsetAnyTypeSchema.java
src/main/java/org/openapijsonschematools/schemas/ValidationMetadata.java
src/main/java/org/openapijsonschematools/schemas/validators/AdditionalPropertiesValidator.java
src/main/java/org/openapijsonschematools/schemas/validators/FormatValidator.java
src/main/java/org/openapijsonschematools/schemas/validators/KeywordValidator.java
src/main/java/org/openapijsonschematools/schemas/validators/PropertiesValidator.java
src/main/java/org/openapijsonschematools/schemas/validators/RequiredValidator.java
src/main/java/org/openapijsonschematools/schemas/validators/TypeValidator.java
src/test/java/org/openapijsonschematools/configurations/JsonSchemaKeywordFlagsTest.java
src/test/java/org/openapijsonschematools/schemas/AnyTypeSchemaTest.java
src/test/java/org/openapijsonschematools/schemas/BooleanSchemaTest.java
src/test/java/org/openapijsonschematools/schemas/CustomIsoparserTest.java
src/test/java/org/openapijsonschematools/schemas/MapSchemaTest.java
src/test/java/org/openapijsonschematools/schemas/NullSchemaTest.java
src/test/java/org/openapijsonschematools/schemas/NumberSchemaTest.java
src/test/java/org/openapijsonschematools/schemas/ObjectTypeSchemaTest.java
src/test/java/org/openapijsonschematools/schemas/SchemaValidatorTest.java
src/test/java/org/openapijsonschematools/schemas/validators/AdditionalPropertiesValidatorTest.java
src/test/java/org/openapijsonschematools/schemas/validators/FormatValidatorTest.java
src/test/java/org/openapijsonschematools/schemas/validators/PropertiesValidatorTest.java
src/test/java/org/openapijsonschematools/schemas/validators/RequiredValidatorTest.java
src/test/java/org/openapijsonschematools/schemas/validators/TypeValidatorTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
import java.util.List;
import java.util.Map;

record AnyTypeSchema() implements Schema {
public record AnyTypeSchema() implements Schema {
public static AnyTypeSchema withDefaults() {
return new AnyTypeSchema();
}
Expand Down Expand Up @@ -48,11 +48,11 @@ public static String validate(LocalDate arg, SchemaConfiguration configuration)
return Schema.validate(AnyTypeSchema.class, arg, configuration);
}

public static <T extends Map> T validate(T arg, SchemaConfiguration configuration) {
public static <T extends FrozenMap> T validate(Map<String, Object> arg, SchemaConfiguration configuration) {
return Schema.validate(AnyTypeSchema.class, arg, configuration);
}

public static <U extends List> U validate(U arg, SchemaConfiguration configuration) {
public static <U extends List> U validate(List<Object> arg, SchemaConfiguration configuration) {
return Schema.validate(AnyTypeSchema.class, arg, configuration);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

import java.util.LinkedHashSet;

record BooleanSchema(LinkedHashSet<Class<?>> type) implements Schema {
public record BooleanSchema(LinkedHashSet<Class<?>> type) implements Schema {
public static BooleanSchema withDefaults() {
LinkedHashSet<Class<?>> type = new LinkedHashSet<>();
type.add(Boolean.class);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import java.util.LinkedHashSet;
import java.time.LocalDate;

record DateSchema(LinkedHashSet<Class<?>> type, String format) implements Schema {
public record DateSchema(LinkedHashSet<Class<?>> type, String format) implements Schema {
public static DateSchema withDefaults() {
LinkedHashSet<Class<?>> type = new LinkedHashSet<>();
type.add(String.class);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import java.util.LinkedHashSet;
import java.time.ZonedDateTime;

record DateTimeSchema(LinkedHashSet<Class<?>> type, String format) implements Schema {
public record DateTimeSchema(LinkedHashSet<Class<?>> type, String format) implements Schema {
public static DateTimeSchema withDefaults() {
LinkedHashSet<Class<?>> type = new LinkedHashSet<>();
type.add(String.class);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

import java.util.LinkedHashSet;

record DecimalSchema(LinkedHashSet<Class<?>> type, String format) implements Schema {
public record DecimalSchema(LinkedHashSet<Class<?>> type, String format) implements Schema {
public static DecimalSchema withDefaults() {
LinkedHashSet<Class<?>> type = new LinkedHashSet<>();
type.add(String.class);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import java.util.LinkedHashSet;
import java.math.BigDecimal;

record DoubleSchema(LinkedHashSet<Class<?>> type, String format) implements Schema {
public record DoubleSchema(LinkedHashSet<Class<?>> type, String format) implements Schema {
public static DoubleSchema withDefaults() {
LinkedHashSet<Class<?>> type = new LinkedHashSet<>();
type.add(BigDecimal.class);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import java.util.LinkedHashSet;
import java.math.BigDecimal;

record FloatSchema(LinkedHashSet<Class<?>> type, String format) implements Schema {
public record FloatSchema(LinkedHashSet<Class<?>> type, String format) implements Schema {
public static FloatSchema withDefaults() {
LinkedHashSet<Class<?>> type = new LinkedHashSet<>();
type.add(BigDecimal.class);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
package org.openapijsonschematools.schemas;

import java.util.LinkedHashMap;
import java.util.Map;
import java.util.function.BiFunction;
import java.util.function.Function;

public class FrozenMap<K, V> extends LinkedHashMap<K, V> {
/*
A frozen Map
Once schema validation has been run, written accessor methods return values of the correct type
If values were mutable, the types in those methods would not agree with returned values
*/
public FrozenMap(Map<? extends K, ? extends V> m) {
super(m);
}

public V put(K key, V value) {
throw new UnsupportedOperationException();
}
public V remove(Object key) {
throw new UnsupportedOperationException();
}
public void putAll(Map<? extends K, ? extends V> m) {
throw new UnsupportedOperationException();
}
public void clear() {
throw new UnsupportedOperationException();
}

@Override
public void replaceAll(BiFunction<? super K, ? super V, ? extends V> function) {
throw new UnsupportedOperationException();
}

@Override
public V putIfAbsent(K key, V value) {
throw new UnsupportedOperationException();
}

@Override
public boolean remove(Object key, Object value) {
throw new UnsupportedOperationException();
}

@Override
public boolean replace(K key, V oldValue, V newValue) {
throw new UnsupportedOperationException();
}

@Override
public V replace(K key, V value) {
throw new UnsupportedOperationException();
}

@Override
public V computeIfAbsent(K key, Function<? super K, ? extends V> mappingFunction) {
throw new UnsupportedOperationException();
}

@Override
public V computeIfPresent(K key,
BiFunction<? super K, ? super V, ? extends V> remappingFunction) {
throw new UnsupportedOperationException();
}

@Override
public V compute(K key,
BiFunction<? super K, ? super V, ? extends V> remappingFunction) {
throw new UnsupportedOperationException();
}

@Override
public V merge(K key, V value,
BiFunction<? super V, ? super V, ? extends V> remappingFunction) {
throw new UnsupportedOperationException();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import java.util.LinkedHashSet;
import java.math.BigDecimal;

record Int32Schema(LinkedHashSet<Class<?>> type, String format) implements Schema {
public record Int32Schema(LinkedHashSet<Class<?>> type, String format) implements Schema {
public static Int32Schema withDefaults() {
LinkedHashSet<Class<?>> type = new LinkedHashSet<>();
type.add(BigDecimal.class);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import java.util.LinkedHashSet;
import java.math.BigDecimal;

record Int64Schema(LinkedHashSet<Class<?>> type, String format) implements Schema {
public record Int64Schema(LinkedHashSet<Class<?>> type, String format) implements Schema {
public static Int64Schema withDefaults() {
LinkedHashSet<Class<?>> type = new LinkedHashSet<>();
type.add(BigDecimal.class);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import java.util.LinkedHashSet;
import java.math.BigDecimal;

record IntSchema(LinkedHashSet<Class<?>> type, String format) implements Schema {
public record IntSchema(LinkedHashSet<Class<?>> type, String format) implements Schema {
public static IntSchema withDefaults() {
LinkedHashSet<Class<?>> type = new LinkedHashSet<>();
type.add(BigDecimal.class);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package org.openapijsonschematools.schemas;

import org.openapijsonschematools.configurations.SchemaConfiguration;

import java.util.LinkedHashSet;
import java.util.Map;

public record MapSchema(LinkedHashSet<Class<?>> type) implements Schema {
public static MapSchema withDefaults() {
LinkedHashSet<Class<?>> type = new LinkedHashSet<>();
// can't use ImmutableMap because it does not allow null values in entries
// can't use Collections.unmodifiableMap because Collections.UnmodifiableMap is not public + extensible
type.add(FrozenMap.class);
return new MapSchema(type);
}

public static FrozenMap<String, Object> validate(Map<String, Object> arg, SchemaConfiguration configuration) {
return Schema.validate(MapSchema.class, arg, configuration);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

import java.util.LinkedHashSet;

record NullSchema(LinkedHashSet<Class<?>> type) implements Schema {
public record NullSchema(LinkedHashSet<Class<?>> type) implements Schema {
public static NullSchema withDefaults() {
LinkedHashSet<Class<?>> type = new LinkedHashSet<>();
type.add(Void.class);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import java.util.LinkedHashSet;
import java.math.BigDecimal;

record NumberSchema(LinkedHashSet<Class<?>> type) implements Schema {
public record NumberSchema(LinkedHashSet<Class<?>> type) implements Schema {
public static NumberSchema withDefaults() {
LinkedHashSet<Class<?>> type = new LinkedHashSet<>();
type.add(BigDecimal.class);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import java.time.LocalDate;
import java.time.ZonedDateTime;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
Expand All @@ -17,7 +18,7 @@
import java.util.Objects;
import java.util.Set;

public interface Schema<T extends Map, U extends List> extends SchemaValidator {
public interface Schema extends SchemaValidator {
private static Object castToAllowedTypes(Object arg, List<Object> pathToItem, PathToTypeMap pathToType) {
if (arg == null) {
pathToType.put(pathToItem, Void.class);
Expand All @@ -36,7 +37,7 @@ private static Object castToAllowedTypes(Object arg, List<Object> pathToItem, Pa
Object fixedVal = castToAllowedTypes(val, newPathToItem, pathToType);
argFixed.put(key, fixedVal);
}
return argFixed;
return new FrozenMap(argFixed);
} else if (arg instanceof Boolean) {
pathToType.put(pathToItem, Boolean.class);
return arg;
Expand Down Expand Up @@ -116,7 +117,7 @@ private static LinkedHashMap<String, Object> getProperties(Object arg, List<Obje
Object castValue = getNewInstance(propertyClass, value, propertyPathToItem, pathToSchemas);
properties.put(propertyName, castValue);
}
return properties;
return new FrozenMap(properties);
}

private static List<Object> getItems(Object arg, List<Object> pathToItem, PathToSchemasMap pathToSchemas) {
Expand Down Expand Up @@ -209,11 +210,11 @@ static String validate(Class<?> cls, LocalDate arg, SchemaConfiguration configur
return (String) validateObject(cls, arg, configuration);
}

static <T extends Map> T validate(Class<?> cls, T arg, SchemaConfiguration configuration) {
static <T extends FrozenMap> T validate(Class<?> cls, Map<String, Object> arg, SchemaConfiguration configuration) {
return (T) validateObject(cls, arg, configuration);
}

static <U extends List> U validate(Class<?> cls, U arg, SchemaConfiguration configuration) {
static <U extends List> U validate(Class<?> cls, List<Object> arg, SchemaConfiguration configuration) {
return (U) validateObject(cls, arg, configuration);
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
package org.openapijsonschematools.schemas;

import org.openapijsonschematools.schemas.validators.AdditionalPropertiesValidator;
import org.openapijsonschematools.schemas.validators.KeywordValidator;
import org.openapijsonschematools.schemas.validators.TypeValidator;
import org.openapijsonschematools.schemas.validators.FormatValidator;
import org.openapijsonschematools.schemas.validators.PropertiesValidator;
import org.openapijsonschematools.schemas.validators.RequiredValidator;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.RecordComponent;
Expand All @@ -14,8 +17,11 @@

public interface SchemaValidator {
HashMap<String, KeywordValidator> keywordToValidator = new HashMap(){{
put("additionalProperties", new AdditionalPropertiesValidator());
put("type", new TypeValidator());
put("format", new FormatValidator());
put("properties", new PropertiesValidator());
put("required", new RequiredValidator());
}};

static PathToSchemasMap validate(
Expand Down Expand Up @@ -44,16 +50,20 @@ static PathToSchemasMap validate(
throw new RuntimeException(e);
}
}
Object extra = null;
PathToSchemasMap pathToSchemas = new PathToSchemasMap();
Class<SchemaValidator> castSchemaCls = (Class<SchemaValidator>) schemaCls;
for (Map.Entry<String, Object> entry: fieldsToValues.entrySet()) {
String jsonKeyword = entry.getKey();
Object value = entry.getValue();
if (jsonKeyword.equals("additionalProperties") && fieldsToValues.containsKey("properties")) {
extra = fieldsToValues.get("properties");
}
KeywordValidator validatorClass = keywordToValidator.get(jsonKeyword);
PathToSchemasMap otherPathToSchemas = validatorClass.validate(
arg,
value,
null,
extra,
castSchemaCls,
validationMetadata
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
import java.time.ZonedDateTime;
import java.time.LocalDate;

record StringSchema(LinkedHashSet<Class<?>> type) implements Schema {
public record StringSchema(LinkedHashSet<Class<?>> type) implements Schema {
public static StringSchema withDefaults() {
LinkedHashSet<Class<?>> type = new LinkedHashSet<>();
type.add(String.class);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
import java.util.List;
import java.util.Map;

record UnsetAnyTypeSchema() implements Schema {
public record UnsetAnyTypeSchema() implements Schema {
static UnsetAnyTypeSchema withDefaults() {
return new UnsetAnyTypeSchema();
}
Expand Down Expand Up @@ -48,11 +48,11 @@ static String validate(LocalDate arg, SchemaConfiguration configuration) {
return Schema.validate(UnsetAnyTypeSchema.class, arg, configuration);
}

static <T extends Map> T validate(T arg, SchemaConfiguration configuration) {
static <T extends FrozenMap> T validate(Map<String, Object> arg, SchemaConfiguration configuration) {
return Schema.validate(UnsetAnyTypeSchema.class, arg, configuration);
}

static <U extends List> U validate(U arg, SchemaConfiguration configuration) {
static <U extends List> U validate(List<Object> arg, SchemaConfiguration configuration) {
return Schema.validate(UnsetAnyTypeSchema.class, arg, configuration);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ public record ValidationMetadata(
Set<Class<?>> seenClasses
) {

protected boolean validationRanEarlier(Class<?> cls) {
public boolean validationRanEarlier(Class<?> cls) {
Map<Class<?>, Void> validatedSchemas = validatedPathToSchemas.getOrDefault(pathToItem, null);
if (validatedSchemas != null && validatedSchemas.containsKey(cls)) {
return true;
Expand Down
Loading