Skip to content

Commit 155b799

Browse files
committed
moving $ref handling into a SchemaExtactor
also adding `AbstractSchemaExtractor` with a few protected methods, helping that consumed keys will be added to `ExtractionResult#consumedKeys`
1 parent c07bf38 commit 155b799

File tree

2 files changed

+79
-38
lines changed

2 files changed

+79
-38
lines changed

core/src/main/java/org/everit/json/schema/loader/SchemaExtractor.java

Lines changed: 57 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,21 @@
11
package org.everit.json.schema.loader;
22

3-
import static java.util.Arrays.asList;
4-
import static java.util.Collections.emptySet;
3+
import static java.util.Collections.emptyList;
54
import static java.util.Collections.singleton;
5+
import static java.util.Collections.singletonList;
66
import static java.util.Objects.requireNonNull;
7-
import static org.everit.json.schema.loader.ExtractionResult.EMPTY;
87

98
import java.util.Collection;
109
import java.util.HashSet;
10+
import java.util.List;
11+
import java.util.Optional;
1112
import java.util.Set;
1213

1314
import org.everit.json.schema.EnumSchema;
1415
import org.everit.json.schema.Schema;
1516

1617
class ExtractionResult {
1718

18-
static final ExtractionResult EMPTY = new ExtractionResult(emptySet(), emptySet());
19-
2019
final Set<String> consumedKeys;
2120

2221
final Collection<Schema.Builder<?>> extractedSchemas;
@@ -38,17 +37,64 @@ interface SchemaExtractor {
3837

3938
}
4039

41-
class EnumSchemaExtractor implements SchemaExtractor {
40+
abstract class AbstractSchemaExtractor implements SchemaExtractor {
41+
42+
protected JsonObject schemaJson;
43+
44+
private Set<String> consumedKeys;
45+
46+
@Override
47+
public final ExtractionResult extract(JsonObject schemaJson) {
48+
this.schemaJson = requireNonNull(schemaJson, "schemaJson cannot be null");
49+
consumedKeys = new HashSet<>(schemaJson.keySet().size());
50+
return new ExtractionResult(consumedKeys, extract());
51+
}
52+
53+
private void keyConsumed(String key) {
54+
if (schemaJson.keySet().contains(key)) {
55+
consumedKeys.add(key);
56+
}
57+
}
58+
59+
protected JsonValue require(String key) {
60+
keyConsumed(key);
61+
return schemaJson.require(key);
62+
}
63+
64+
protected Optional<JsonValue> maybe(String key) {
65+
keyConsumed(key);
66+
return schemaJson.maybe(key);
67+
}
68+
69+
protected boolean containsKey(String key) {
70+
return schemaJson.containsKey(key);
71+
}
72+
73+
protected abstract List<Schema.Builder<?>> extract();
74+
}
75+
76+
class EnumSchemaExtractor extends AbstractSchemaExtractor {
4277

43-
@Override public ExtractionResult extract(JsonObject schemaJson) {
44-
if (!schemaJson.containsKey("enum")) {
45-
return EMPTY;
78+
@Override protected List<Schema.Builder<?>> extract() {
79+
if (!containsKey("enum")) {
80+
return emptyList();
4681
}
4782
EnumSchema.Builder builder = EnumSchema.builder();
4883
Set<Object> possibleValues = new HashSet<>();
49-
schemaJson.require("enum").requireArray().forEach((i, item) -> possibleValues.add(item.unwrap()));
84+
require("enum").requireArray().forEach((i, item) -> possibleValues.add(item.unwrap()));
5085
builder.possibleValues(possibleValues);
51-
return new ExtractionResult("enum", asList(builder));
86+
return singletonList(builder);
5287
}
5388

5489
}
90+
91+
class ReferenceSchemaExtractor extends AbstractSchemaExtractor {
92+
93+
@Override protected List<Schema.Builder<?>> extract() {
94+
if (containsKey("$ref")) {
95+
String ref = require("$ref").requireString();
96+
return singletonList(new ReferenceLookup(schemaJson.ls).lookup(ref, schemaJson));
97+
}
98+
return emptyList();
99+
}
100+
}

core/src/main/java/org/everit/json/schema/loader/SchemaLoader.java

Lines changed: 22 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,10 @@
1414
import java.util.ArrayList;
1515
import java.util.Collection;
1616
import java.util.HashMap;
17-
import java.util.HashSet;
1817
import java.util.List;
1918
import java.util.Map;
2019
import java.util.Objects;
2120
import java.util.Optional;
22-
import java.util.Set;
2321
import java.util.function.Supplier;
2422

2523
import org.everit.json.schema.ArraySchema;
@@ -28,7 +26,6 @@
2826
import org.everit.json.schema.ConditionalSchema;
2927
import org.everit.json.schema.ConstSchema;
3028
import org.everit.json.schema.EmptySchema;
31-
import org.everit.json.schema.EnumSchema;
3229
import org.everit.json.schema.FalseSchema;
3330
import org.everit.json.schema.FormatValidator;
3431
import org.everit.json.schema.NotSchema;
@@ -356,14 +353,6 @@ private Schema.Builder buildConstSchema() {
356353
.permittedValue(ls.schemaJson().require("const").unwrap());
357354
}
358355

359-
private EnumSchema.Builder buildEnumSchema() {
360-
EnumSchema.Builder builder = EnumSchema.builder();
361-
Set<Object> possibleValues = new HashSet<>();
362-
ls.schemaJson().require("enum").requireArray().forEach((i, item) -> possibleValues.add(item.unwrap()));
363-
builder.possibleValues(possibleValues);
364-
return builder;
365-
}
366-
367356
private NotSchema.Builder buildNotSchema() {
368357
Schema mustNotMatch = loadChild(ls.schemaJson().require("not")).build();
369358
return NotSchema.builder().mustNotMatch(mustNotMatch);
@@ -373,10 +362,6 @@ private Schema.Builder<?> buildSchemaWithoutExplicitType() {
373362
if (ls.schemaJson().isEmpty()) {
374363
return EmptySchema.builder();
375364
}
376-
if (ls.schemaJson().containsKey("$ref")) {
377-
String ref = ls.schemaJson().require("$ref").requireString();
378-
return new ReferenceLookup(ls).lookup(ref, ls.schemaJson());
379-
}
380365
Schema.Builder<?> rval = sniffSchemaByProps();
381366
if (rval != null) {
382367
return rval;
@@ -412,24 +397,14 @@ private Schema.Builder loadSchemaBoolean(Boolean rawBoolean) {
412397
}
413398

414399
private Schema.Builder loadSchemaObject(JsonObject o) {
415-
Collection<Schema.Builder<?>> extractedSchemas = new ArrayList<>(1);
416-
List<SchemaExtractor> extractors = asList(new EnumSchemaExtractor(), new CombinedSchemaLoader(this));
417-
// extractors.stream().map(extractor -> extractor.extract(o)).forEach(extractedSchemas::addAll);
418-
419-
AdjacentSchemaExtractionState state = new AdjacentSchemaExtractionState(o);
420-
for (SchemaExtractor extractor : extractors) {
421-
ExtractionResult result = extractor.extract(state.projectedSchemaJson());
422-
state = state.reduce(result);
423-
}
424-
extractedSchemas = state.extractedSchemaBuilders();
425-
400+
Collection<Schema.Builder<?>> extractedSchemas = runSchemaExtractors(o);
426401
//////////////////////
427402
Schema.Builder builder;
428403
if (ls.schemaJson().containsKey("const") && (config.specVersion != DRAFT_4)) {
429404
builder = buildConstSchema();
430405
} else {
431406
Supplier<Schema.Builder> supplier = () -> {
432-
if (!ls.schemaJson().containsKey("type") || ls.schemaJson().containsKey("$ref")) {
407+
if (!ls.schemaJson().containsKey("type")) {
433408
return buildSchemaWithoutExplicitType();
434409
} else {
435410
return loadForType(ls.schemaJson().require("type"));
@@ -460,6 +435,26 @@ private Schema.Builder loadSchemaObject(JsonObject o) {
460435
// return builder;
461436
}
462437

438+
private Collection<Schema.Builder<?>> runSchemaExtractors(JsonObject o) {
439+
if (o.containsKey("$ref")) {
440+
return new ReferenceSchemaExtractor().extract(o).extractedSchemas;
441+
}
442+
Collection<Schema.Builder<?>> extractedSchemas;
443+
List<SchemaExtractor> extractors = asList(
444+
new EnumSchemaExtractor(),
445+
new CombinedSchemaLoader(this)
446+
);
447+
// extractors.stream().map(extractor -> extractor.extract(o)).forEach(extractedSchemas::addAll);
448+
449+
AdjacentSchemaExtractionState state = new AdjacentSchemaExtractionState(o);
450+
for (SchemaExtractor extractor : extractors) {
451+
ExtractionResult result = extractor.extract(state.projectedSchemaJson());
452+
state = state.reduce(result);
453+
}
454+
extractedSchemas = state.extractedSchemaBuilders();
455+
return extractedSchemas;
456+
}
457+
463458
private void loadCommonSchemaProperties(Schema.Builder builder) {
464459
ls.schemaJson().maybe(config.specVersion.idKeyword()).map(JsonValue::requireString).ifPresent(builder::id);
465460
ls.schemaJson().maybe("title").map(JsonValue::requireString).ifPresent(builder::title);

0 commit comments

Comments
 (0)