Skip to content

Commit aa9f164

Browse files
authored
Allows to override date-time and duration validators (#787)
Fixes #784
1 parent de1cb89 commit aa9f164

File tree

3 files changed

+92
-4
lines changed

3 files changed

+92
-4
lines changed

src/main/java/com/networknt/schema/FormatKeyword.java

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,11 @@ public JsonValidator newValidator(String schemaPath, JsonNode schemaNode, JsonSc
4545
Format format = null;
4646
if (schemaNode != null && schemaNode.isTextual()) {
4747
String formatName = schemaNode.textValue();
48+
format = this.formats.get(formatName);
49+
if (format != null) {
50+
return new FormatValidator(schemaPath, schemaNode, parentSchema, validationContext, format, type);
51+
}
52+
4853
switch (formatName) {
4954
case DURATION:
5055
format = new DurationFormat(validationContext.getConfig().isStrict(DURATION));
@@ -56,10 +61,6 @@ public JsonValidator newValidator(String schemaPath, JsonNode schemaNode, JsonSc
5661
typeCode.setCustomMessage(this.type.getCustomMessage());
5762
return new DateTimeValidator(schemaPath, schemaNode, parentSchema, validationContext, typeCode);
5863
}
59-
60-
default:
61-
format = this.formats.get(formatName);
62-
break;
6364
}
6465
}
6566

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
package com.networknt.schema;
2+
3+
import com.fasterxml.jackson.core.JsonProcessingException;
4+
import com.fasterxml.jackson.databind.ObjectMapper;
5+
import org.junit.jupiter.api.Test;
6+
7+
import java.io.IOException;
8+
import java.util.Collections;
9+
import java.util.Set;
10+
11+
import static org.junit.jupiter.api.Assertions.assertEquals;
12+
13+
public class Issue784Test {
14+
15+
private static final String FOO_BAR = "foo-bar";
16+
private static final String SOMETHING_ELSE = "something-else";
17+
18+
static class CustomDateTimeFormat implements Format {
19+
20+
@Override
21+
public String getName() {
22+
return "date-time";
23+
}
24+
25+
@Override
26+
public boolean matches(String value) {
27+
return value.equals(FOO_BAR);
28+
}
29+
30+
@Override
31+
public String getErrorMessageDescription() {
32+
return null;
33+
}
34+
}
35+
36+
@Test
37+
public void allowToOverrideDataTime() throws IOException {
38+
JsonSchema jsonSchema = createSchema(true);
39+
40+
// Custom validator checks for FOO_BAR
41+
assertEquals(0, validate(jsonSchema, FOO_BAR).size());
42+
43+
// Fails with SOMETHING_ELSE
44+
assertEquals(1, validate(jsonSchema, SOMETHING_ELSE).size());
45+
}
46+
47+
@Test
48+
public void useDefaultValidatorIfNotOverriden() throws IOException {
49+
JsonSchema jsonSchema = createSchema(false);
50+
51+
// Default validator fails with FOO_BAR
52+
assertEquals(1, validate(jsonSchema, FOO_BAR).size());
53+
54+
// Default validator fails with SOMETHING_ELSE
55+
assertEquals(1, validate(jsonSchema, SOMETHING_ELSE).size());
56+
}
57+
58+
59+
private Set<ValidationMessage> validate(JsonSchema jsonSchema, String myDateTimeContent) throws JsonProcessingException {
60+
return jsonSchema.validate(new ObjectMapper().readTree(" { \"my-date-time\": \"" + myDateTimeContent + "\" } "));
61+
}
62+
63+
private JsonSchema createSchema(boolean useCustomDateFormat) {
64+
JsonMetaSchema overrideDateTimeValidator = new JsonMetaSchema
65+
.Builder(JsonMetaSchema.getV7().getUri())
66+
.idKeyword("$id")
67+
.addKeywords(ValidatorTypeCode.getNonFormatKeywords(SpecVersion.VersionFlag.V7))
68+
.addFormats(useCustomDateFormat ? Collections.singletonList(new CustomDateTimeFormat()) : Collections.emptyList())
69+
.build();
70+
71+
return new JsonSchemaFactory
72+
.Builder()
73+
.defaultMetaSchemaURI(overrideDateTimeValidator.getUri())
74+
.addMetaSchema(overrideDateTimeValidator)
75+
.build()
76+
.getSchema(Issue784Test.class.getResourceAsStream("/issue784/schema.json"));
77+
}
78+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
{
2+
"type": "object",
3+
"properties": {
4+
"my-date-time": {
5+
"type": "string",
6+
"format": "date-time"
7+
}
8+
}
9+
}

0 commit comments

Comments
 (0)