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

Commit 5d1b814

Browse files
authored
Java: adds MapSchema (#279)
* Adds properties validator * Adds FrozenMap and MapSchema * Adds PropertiesValidatorTest * Adds RequiredValidator.java + RequiredValidatorTest.java * Adds AdditionalPropertiesValidator * Adds AdditionalPropertiesValidatorTest * Adds ObjectTypeSchemaTest
1 parent 402221e commit 5d1b814

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

58 files changed

+1617
-182
lines changed

samples/client/petstore/java/.openapi-generator/FILES

+10
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,11 @@ src/main/java/org/openapijsonschematools/schemas/DateTimeSchema.java
1010
src/main/java/org/openapijsonschematools/schemas/DecimalSchema.java
1111
src/main/java/org/openapijsonschematools/schemas/DoubleSchema.java
1212
src/main/java/org/openapijsonschematools/schemas/FloatSchema.java
13+
src/main/java/org/openapijsonschematools/schemas/FrozenMap.java
1314
src/main/java/org/openapijsonschematools/schemas/Int32Schema.java
1415
src/main/java/org/openapijsonschematools/schemas/Int64Schema.java
1516
src/main/java/org/openapijsonschematools/schemas/IntSchema.java
17+
src/main/java/org/openapijsonschematools/schemas/MapSchema.java
1618
src/main/java/org/openapijsonschematools/schemas/NullSchema.java
1719
src/main/java/org/openapijsonschematools/schemas/NumberSchema.java
1820
src/main/java/org/openapijsonschematools/schemas/PathToSchemasMap.java
@@ -22,15 +24,23 @@ src/main/java/org/openapijsonschematools/schemas/SchemaValidator.java
2224
src/main/java/org/openapijsonschematools/schemas/StringSchema.java
2325
src/main/java/org/openapijsonschematools/schemas/UnsetAnyTypeSchema.java
2426
src/main/java/org/openapijsonschematools/schemas/ValidationMetadata.java
27+
src/main/java/org/openapijsonschematools/schemas/validators/AdditionalPropertiesValidator.java
2528
src/main/java/org/openapijsonschematools/schemas/validators/FormatValidator.java
2629
src/main/java/org/openapijsonschematools/schemas/validators/KeywordValidator.java
30+
src/main/java/org/openapijsonschematools/schemas/validators/PropertiesValidator.java
31+
src/main/java/org/openapijsonschematools/schemas/validators/RequiredValidator.java
2732
src/main/java/org/openapijsonschematools/schemas/validators/TypeValidator.java
2833
src/test/java/org/openapijsonschematools/configurations/JsonSchemaKeywordFlagsTest.java
2934
src/test/java/org/openapijsonschematools/schemas/AnyTypeSchemaTest.java
3035
src/test/java/org/openapijsonschematools/schemas/BooleanSchemaTest.java
3136
src/test/java/org/openapijsonschematools/schemas/CustomIsoparserTest.java
37+
src/test/java/org/openapijsonschematools/schemas/MapSchemaTest.java
3238
src/test/java/org/openapijsonschematools/schemas/NullSchemaTest.java
3339
src/test/java/org/openapijsonschematools/schemas/NumberSchemaTest.java
40+
src/test/java/org/openapijsonschematools/schemas/ObjectTypeSchemaTest.java
3441
src/test/java/org/openapijsonschematools/schemas/SchemaValidatorTest.java
42+
src/test/java/org/openapijsonschematools/schemas/validators/AdditionalPropertiesValidatorTest.java
3543
src/test/java/org/openapijsonschematools/schemas/validators/FormatValidatorTest.java
44+
src/test/java/org/openapijsonschematools/schemas/validators/PropertiesValidatorTest.java
45+
src/test/java/org/openapijsonschematools/schemas/validators/RequiredValidatorTest.java
3646
src/test/java/org/openapijsonschematools/schemas/validators/TypeValidatorTest.java

samples/client/petstore/java/src/main/java/org/openapijsonschematools/schemas/AnyTypeSchema.java

+3-3
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
import java.util.List;
88
import java.util.Map;
99

10-
record AnyTypeSchema() implements Schema {
10+
public record AnyTypeSchema() implements Schema {
1111
public static AnyTypeSchema withDefaults() {
1212
return new AnyTypeSchema();
1313
}
@@ -48,11 +48,11 @@ public static String validate(LocalDate arg, SchemaConfiguration configuration)
4848
return Schema.validate(AnyTypeSchema.class, arg, configuration);
4949
}
5050

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

55-
public static <U extends List> U validate(U arg, SchemaConfiguration configuration) {
55+
public static <U extends List> U validate(List<Object> arg, SchemaConfiguration configuration) {
5656
return Schema.validate(AnyTypeSchema.class, arg, configuration);
5757
}
5858
}

samples/client/petstore/java/src/main/java/org/openapijsonschematools/schemas/BooleanSchema.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
import java.util.LinkedHashSet;
66

7-
record BooleanSchema(LinkedHashSet<Class<?>> type) implements Schema {
7+
public record BooleanSchema(LinkedHashSet<Class<?>> type) implements Schema {
88
public static BooleanSchema withDefaults() {
99
LinkedHashSet<Class<?>> type = new LinkedHashSet<>();
1010
type.add(Boolean.class);

samples/client/petstore/java/src/main/java/org/openapijsonschematools/schemas/DateSchema.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
import java.util.LinkedHashSet;
66
import java.time.LocalDate;
77

8-
record DateSchema(LinkedHashSet<Class<?>> type, String format) implements Schema {
8+
public record DateSchema(LinkedHashSet<Class<?>> type, String format) implements Schema {
99
public static DateSchema withDefaults() {
1010
LinkedHashSet<Class<?>> type = new LinkedHashSet<>();
1111
type.add(String.class);

samples/client/petstore/java/src/main/java/org/openapijsonschematools/schemas/DateTimeSchema.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
import java.util.LinkedHashSet;
66
import java.time.ZonedDateTime;
77

8-
record DateTimeSchema(LinkedHashSet<Class<?>> type, String format) implements Schema {
8+
public record DateTimeSchema(LinkedHashSet<Class<?>> type, String format) implements Schema {
99
public static DateTimeSchema withDefaults() {
1010
LinkedHashSet<Class<?>> type = new LinkedHashSet<>();
1111
type.add(String.class);

samples/client/petstore/java/src/main/java/org/openapijsonschematools/schemas/DecimalSchema.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
import java.util.LinkedHashSet;
66

7-
record DecimalSchema(LinkedHashSet<Class<?>> type, String format) implements Schema {
7+
public record DecimalSchema(LinkedHashSet<Class<?>> type, String format) implements Schema {
88
public static DecimalSchema withDefaults() {
99
LinkedHashSet<Class<?>> type = new LinkedHashSet<>();
1010
type.add(String.class);

samples/client/petstore/java/src/main/java/org/openapijsonschematools/schemas/DoubleSchema.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
import java.util.LinkedHashSet;
66
import java.math.BigDecimal;
77

8-
record DoubleSchema(LinkedHashSet<Class<?>> type, String format) implements Schema {
8+
public record DoubleSchema(LinkedHashSet<Class<?>> type, String format) implements Schema {
99
public static DoubleSchema withDefaults() {
1010
LinkedHashSet<Class<?>> type = new LinkedHashSet<>();
1111
type.add(BigDecimal.class);

samples/client/petstore/java/src/main/java/org/openapijsonschematools/schemas/FloatSchema.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
import java.util.LinkedHashSet;
66
import java.math.BigDecimal;
77

8-
record FloatSchema(LinkedHashSet<Class<?>> type, String format) implements Schema {
8+
public record FloatSchema(LinkedHashSet<Class<?>> type, String format) implements Schema {
99
public static FloatSchema withDefaults() {
1010
LinkedHashSet<Class<?>> type = new LinkedHashSet<>();
1111
type.add(BigDecimal.class);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
package org.openapijsonschematools.schemas;
2+
3+
import java.util.LinkedHashMap;
4+
import java.util.Map;
5+
import java.util.function.BiFunction;
6+
import java.util.function.Function;
7+
8+
public class FrozenMap<K, V> extends LinkedHashMap<K, V> {
9+
/*
10+
A frozen Map
11+
Once schema validation has been run, written accessor methods return values of the correct type
12+
If values were mutable, the types in those methods would not agree with returned values
13+
*/
14+
public FrozenMap(Map<? extends K, ? extends V> m) {
15+
super(m);
16+
}
17+
18+
public V put(K key, V value) {
19+
throw new UnsupportedOperationException();
20+
}
21+
public V remove(Object key) {
22+
throw new UnsupportedOperationException();
23+
}
24+
public void putAll(Map<? extends K, ? extends V> m) {
25+
throw new UnsupportedOperationException();
26+
}
27+
public void clear() {
28+
throw new UnsupportedOperationException();
29+
}
30+
31+
@Override
32+
public void replaceAll(BiFunction<? super K, ? super V, ? extends V> function) {
33+
throw new UnsupportedOperationException();
34+
}
35+
36+
@Override
37+
public V putIfAbsent(K key, V value) {
38+
throw new UnsupportedOperationException();
39+
}
40+
41+
@Override
42+
public boolean remove(Object key, Object value) {
43+
throw new UnsupportedOperationException();
44+
}
45+
46+
@Override
47+
public boolean replace(K key, V oldValue, V newValue) {
48+
throw new UnsupportedOperationException();
49+
}
50+
51+
@Override
52+
public V replace(K key, V value) {
53+
throw new UnsupportedOperationException();
54+
}
55+
56+
@Override
57+
public V computeIfAbsent(K key, Function<? super K, ? extends V> mappingFunction) {
58+
throw new UnsupportedOperationException();
59+
}
60+
61+
@Override
62+
public V computeIfPresent(K key,
63+
BiFunction<? super K, ? super V, ? extends V> remappingFunction) {
64+
throw new UnsupportedOperationException();
65+
}
66+
67+
@Override
68+
public V compute(K key,
69+
BiFunction<? super K, ? super V, ? extends V> remappingFunction) {
70+
throw new UnsupportedOperationException();
71+
}
72+
73+
@Override
74+
public V merge(K key, V value,
75+
BiFunction<? super V, ? super V, ? extends V> remappingFunction) {
76+
throw new UnsupportedOperationException();
77+
}
78+
}

samples/client/petstore/java/src/main/java/org/openapijsonschematools/schemas/Int32Schema.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
import java.util.LinkedHashSet;
66
import java.math.BigDecimal;
77

8-
record Int32Schema(LinkedHashSet<Class<?>> type, String format) implements Schema {
8+
public record Int32Schema(LinkedHashSet<Class<?>> type, String format) implements Schema {
99
public static Int32Schema withDefaults() {
1010
LinkedHashSet<Class<?>> type = new LinkedHashSet<>();
1111
type.add(BigDecimal.class);

samples/client/petstore/java/src/main/java/org/openapijsonschematools/schemas/Int64Schema.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
import java.util.LinkedHashSet;
66
import java.math.BigDecimal;
77

8-
record Int64Schema(LinkedHashSet<Class<?>> type, String format) implements Schema {
8+
public record Int64Schema(LinkedHashSet<Class<?>> type, String format) implements Schema {
99
public static Int64Schema withDefaults() {
1010
LinkedHashSet<Class<?>> type = new LinkedHashSet<>();
1111
type.add(BigDecimal.class);

samples/client/petstore/java/src/main/java/org/openapijsonschematools/schemas/IntSchema.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
import java.util.LinkedHashSet;
66
import java.math.BigDecimal;
77

8-
record IntSchema(LinkedHashSet<Class<?>> type, String format) implements Schema {
8+
public record IntSchema(LinkedHashSet<Class<?>> type, String format) implements Schema {
99
public static IntSchema withDefaults() {
1010
LinkedHashSet<Class<?>> type = new LinkedHashSet<>();
1111
type.add(BigDecimal.class);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
package org.openapijsonschematools.schemas;
2+
3+
import org.openapijsonschematools.configurations.SchemaConfiguration;
4+
5+
import java.util.LinkedHashSet;
6+
import java.util.Map;
7+
8+
public record MapSchema(LinkedHashSet<Class<?>> type) implements Schema {
9+
public static MapSchema withDefaults() {
10+
LinkedHashSet<Class<?>> type = new LinkedHashSet<>();
11+
// can't use ImmutableMap because it does not allow null values in entries
12+
// can't use Collections.unmodifiableMap because Collections.UnmodifiableMap is not public + extensible
13+
type.add(FrozenMap.class);
14+
return new MapSchema(type);
15+
}
16+
17+
public static FrozenMap<String, Object> validate(Map<String, Object> arg, SchemaConfiguration configuration) {
18+
return Schema.validate(MapSchema.class, arg, configuration);
19+
}
20+
}

samples/client/petstore/java/src/main/java/org/openapijsonschematools/schemas/NullSchema.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
import java.util.LinkedHashSet;
66

7-
record NullSchema(LinkedHashSet<Class<?>> type) implements Schema {
7+
public record NullSchema(LinkedHashSet<Class<?>> type) implements Schema {
88
public static NullSchema withDefaults() {
99
LinkedHashSet<Class<?>> type = new LinkedHashSet<>();
1010
type.add(Void.class);

samples/client/petstore/java/src/main/java/org/openapijsonschematools/schemas/NumberSchema.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
import java.util.LinkedHashSet;
66
import java.math.BigDecimal;
77

8-
record NumberSchema(LinkedHashSet<Class<?>> type) implements Schema {
8+
public record NumberSchema(LinkedHashSet<Class<?>> type) implements Schema {
99
public static NumberSchema withDefaults() {
1010
LinkedHashSet<Class<?>> type = new LinkedHashSet<>();
1111
type.add(BigDecimal.class);

samples/client/petstore/java/src/main/java/org/openapijsonschematools/schemas/Schema.java

+6-5
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
import java.time.LocalDate;
1010
import java.time.ZonedDateTime;
1111
import java.util.ArrayList;
12+
import java.util.Collections;
1213
import java.util.HashSet;
1314
import java.util.LinkedHashMap;
1415
import java.util.LinkedHashSet;
@@ -17,7 +18,7 @@
1718
import java.util.Objects;
1819
import java.util.Set;
1920

20-
public interface Schema<T extends Map, U extends List> extends SchemaValidator {
21+
public interface Schema extends SchemaValidator {
2122
private static Object castToAllowedTypes(Object arg, List<Object> pathToItem, PathToTypeMap pathToType) {
2223
if (arg == null) {
2324
pathToType.put(pathToItem, Void.class);
@@ -36,7 +37,7 @@ private static Object castToAllowedTypes(Object arg, List<Object> pathToItem, Pa
3637
Object fixedVal = castToAllowedTypes(val, newPathToItem, pathToType);
3738
argFixed.put(key, fixedVal);
3839
}
39-
return argFixed;
40+
return new FrozenMap(argFixed);
4041
} else if (arg instanceof Boolean) {
4142
pathToType.put(pathToItem, Boolean.class);
4243
return arg;
@@ -116,7 +117,7 @@ private static LinkedHashMap<String, Object> getProperties(Object arg, List<Obje
116117
Object castValue = getNewInstance(propertyClass, value, propertyPathToItem, pathToSchemas);
117118
properties.put(propertyName, castValue);
118119
}
119-
return properties;
120+
return new FrozenMap(properties);
120121
}
121122

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

212-
static <T extends Map> T validate(Class<?> cls, T arg, SchemaConfiguration configuration) {
213+
static <T extends FrozenMap> T validate(Class<?> cls, Map<String, Object> arg, SchemaConfiguration configuration) {
213214
return (T) validateObject(cls, arg, configuration);
214215
}
215216

216-
static <U extends List> U validate(Class<?> cls, U arg, SchemaConfiguration configuration) {
217+
static <U extends List> U validate(Class<?> cls, List<Object> arg, SchemaConfiguration configuration) {
217218
return (U) validateObject(cls, arg, configuration);
218219
}
219220

samples/client/petstore/java/src/main/java/org/openapijsonschematools/schemas/SchemaValidator.java

+11-1
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
11
package org.openapijsonschematools.schemas;
22

3+
import org.openapijsonschematools.schemas.validators.AdditionalPropertiesValidator;
34
import org.openapijsonschematools.schemas.validators.KeywordValidator;
45
import org.openapijsonschematools.schemas.validators.TypeValidator;
56
import org.openapijsonschematools.schemas.validators.FormatValidator;
7+
import org.openapijsonschematools.schemas.validators.PropertiesValidator;
8+
import org.openapijsonschematools.schemas.validators.RequiredValidator;
69

710
import java.lang.reflect.InvocationTargetException;
811
import java.lang.reflect.RecordComponent;
@@ -14,8 +17,11 @@
1417

1518
public interface SchemaValidator {
1619
HashMap<String, KeywordValidator> keywordToValidator = new HashMap(){{
20+
put("additionalProperties", new AdditionalPropertiesValidator());
1721
put("type", new TypeValidator());
1822
put("format", new FormatValidator());
23+
put("properties", new PropertiesValidator());
24+
put("required", new RequiredValidator());
1925
}};
2026

2127
static PathToSchemasMap validate(
@@ -44,16 +50,20 @@ static PathToSchemasMap validate(
4450
throw new RuntimeException(e);
4551
}
4652
}
53+
Object extra = null;
4754
PathToSchemasMap pathToSchemas = new PathToSchemasMap();
4855
Class<SchemaValidator> castSchemaCls = (Class<SchemaValidator>) schemaCls;
4956
for (Map.Entry<String, Object> entry: fieldsToValues.entrySet()) {
5057
String jsonKeyword = entry.getKey();
5158
Object value = entry.getValue();
59+
if (jsonKeyword.equals("additionalProperties") && fieldsToValues.containsKey("properties")) {
60+
extra = fieldsToValues.get("properties");
61+
}
5262
KeywordValidator validatorClass = keywordToValidator.get(jsonKeyword);
5363
PathToSchemasMap otherPathToSchemas = validatorClass.validate(
5464
arg,
5565
value,
56-
null,
66+
extra,
5767
castSchemaCls,
5868
validationMetadata
5969
);

samples/client/petstore/java/src/main/java/org/openapijsonschematools/schemas/StringSchema.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
import java.time.ZonedDateTime;
77
import java.time.LocalDate;
88

9-
record StringSchema(LinkedHashSet<Class<?>> type) implements Schema {
9+
public record StringSchema(LinkedHashSet<Class<?>> type) implements Schema {
1010
public static StringSchema withDefaults() {
1111
LinkedHashSet<Class<?>> type = new LinkedHashSet<>();
1212
type.add(String.class);

samples/client/petstore/java/src/main/java/org/openapijsonschematools/schemas/UnsetAnyTypeSchema.java

+3-3
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
import java.util.List;
88
import java.util.Map;
99

10-
record UnsetAnyTypeSchema() implements Schema {
10+
public record UnsetAnyTypeSchema() implements Schema {
1111
static UnsetAnyTypeSchema withDefaults() {
1212
return new UnsetAnyTypeSchema();
1313
}
@@ -48,11 +48,11 @@ static String validate(LocalDate arg, SchemaConfiguration configuration) {
4848
return Schema.validate(UnsetAnyTypeSchema.class, arg, configuration);
4949
}
5050

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

55-
static <U extends List> U validate(U arg, SchemaConfiguration configuration) {
55+
static <U extends List> U validate(List<Object> arg, SchemaConfiguration configuration) {
5656
return Schema.validate(UnsetAnyTypeSchema.class, arg, configuration);
5757
}
5858
}

samples/client/petstore/java/src/main/java/org/openapijsonschematools/schemas/ValidationMetadata.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ public record ValidationMetadata(
1212
Set<Class<?>> seenClasses
1313
) {
1414

15-
protected boolean validationRanEarlier(Class<?> cls) {
15+
public boolean validationRanEarlier(Class<?> cls) {
1616
Map<Class<?>, Void> validatedSchemas = validatedPathToSchemas.getOrDefault(pathToItem, null);
1717
if (validatedSchemas != null && validatedSchemas.containsKey(cls)) {
1818
return true;

0 commit comments

Comments
 (0)