Skip to content

Commit 79acd4d

Browse files
author
Klas Kalaß
committed
Support custom meta schemas with custom keywords and formats
Refactored so that the library supports multiple meta schemas and users of the library can add custom meta schemas as well as controlling aspects like e.g. fetching via a URL.
1 parent 6800d69 commit 79acd4d

Some content is hidden

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

52 files changed

+895
-328
lines changed

pom.xml

Lines changed: 4 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -13,44 +13,39 @@
1313
~ See the License for the specific language governing permissions and
1414
~ limitations under the License.
1515
-->
16-
17-
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0"
18-
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
16+
<project
17+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
18+
xmlns="http://maven.apache.org/POM/4.0.0" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
1919
<modelVersion>4.0.0</modelVersion>
2020
<groupId>com.networknt</groupId>
2121
<artifactId>json-schema-validator</artifactId>
2222
<version>0.1.11</version>
2323
<description>A json schema validator that supports draft v4</description>
2424
<url>https://github.com/networknt/json-schema-validator</url>
2525
<name>JsonSchemaValidator</name>
26-
2726
<developers>
2827
<developer>
2928
<id>stevehu</id>
3029
<name>Steve Hu</name>
3130
<email>[email protected]</email>
3231
</developer>
3332
</developers>
34-
3533
<issueManagement>
3634
<system>github</system>
3735
<url>https://github.com/networknt/json-schema-validator/issues</url>
3836
</issueManagement>
39-
4037
<licenses>
4138
<license>
4239
<name>Apache License Version 2.0</name>
4340
<url>http://repository.jboss.org/licenses/apache-2.0.txt</url>
4441
<distribution>repo</distribution>
4542
</license>
4643
</licenses>
47-
4844
<scm>
4945
<connection>scm:git://github.com:networknt/json-schema-validator.git</connection>
5046
<developerConnection>scm:git://github.com:networknt/json-schema-validator.git</developerConnection>
5147
<url>https://github.com:networknt/json-schema-validator.git</url>
5248
</scm>
53-
5449
<distributionManagement>
5550
<snapshotRepository>
5651
<id>ossrh</id>
@@ -61,7 +56,6 @@
6156
<url>https://oss.sonatype.org/service/local/staging/deploy/maven2/</url>
6257
</repository>
6358
</distributionManagement>
64-
6559
<properties>
6660
<java.version>1.6</java.version>
6761
<java.testversion>1.7</java.testversion>
@@ -74,10 +68,7 @@
7468
<version.mockito>2.7.21</version.mockito>
7569
<version.hamcrest>1.3</version.hamcrest>
7670
<version.undertow>1.4.11.Final</version.undertow>
77-
7871
</properties>
79-
80-
8172
<dependencies>
8273
<dependency>
8374
<groupId>com.fasterxml.jackson.core</groupId>
@@ -99,7 +90,6 @@
9990
<artifactId>commons-lang3</artifactId>
10091
<version>${version.common-lang3}</version>
10192
</dependency>
102-
10393
<dependency>
10494
<groupId>ch.qos.logback</groupId>
10595
<artifactId>logback-classic</artifactId>
@@ -152,7 +142,6 @@
152142
</includes>
153143
</testResource>
154144
</testResources>
155-
156145
<plugins>
157146
<plugin>
158147
<groupId>org.sonatype.plugins</groupId>
@@ -166,13 +155,8 @@
166155
</configuration>
167156
</plugin>
168157
<!--
169-
<plugin>
170-
<groupId>org.apache.maven.plugins</groupId>
171-
<artifactId>maven-release-plugin</artifactId>
172-
<version>2.5.3</version>
173-
</plugin>
158+
<plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-release-plugin</artifactId><version>2.5.3</version></plugin>
174159
-->
175-
176160
<plugin>
177161
<groupId>org.apache.maven.plugins</groupId>
178162
<artifactId>maven-source-plugin</artifactId>
@@ -221,7 +205,6 @@
221205
</execution>
222206
</executions>
223207
</plugin>
224-
225208
<plugin>
226209
<groupId>org.apache.maven.plugins</groupId>
227210
<artifactId>maven-surefire-plugin</artifactId>
@@ -234,8 +217,6 @@
234217
</dependency>
235218
</dependencies>
236219
</plugin>
237-
238-
239220
<!-- JACOCO added for code coverage -->
240221
<plugin>
241222
<groupId>org.jacoco</groupId>
@@ -261,10 +242,8 @@
261242
</executions>
262243
</plugin>
263244
<!-- end JACOCO -->
264-
265245
</plugins>
266246
</build>
267-
268247
<reporting>
269248
<plugins>
270249
<plugin>
@@ -274,7 +253,6 @@
274253
</plugin>
275254
</plugins>
276255
</reporting>
277-
278256
<profiles>
279257
<profile>
280258
<id>release-sign-artifacts</id>
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
package com.networknt.schema;
2+
3+
public abstract class AbstractFormat implements Format{
4+
private final String name;
5+
private final String errorMessageDescription;
6+
7+
public AbstractFormat(String name) {
8+
this(name, "");
9+
}
10+
11+
public AbstractFormat(String name, String errorMessageDescription) {
12+
this.name = name;
13+
this.errorMessageDescription = errorMessageDescription;
14+
}
15+
16+
@Override
17+
public String getName() {
18+
return name;
19+
}
20+
21+
@Override
22+
public String getErrorMessageDescription() {
23+
return errorMessageDescription;
24+
}
25+
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
package com.networknt.schema;
2+
3+
import java.util.Collections;
4+
import java.util.Map;
5+
import java.util.Set;
6+
7+
import com.fasterxml.jackson.databind.JsonNode;
8+
9+
public abstract class AbstractJsonValidator implements JsonValidator {
10+
private final String keyword;
11+
protected AbstractJsonValidator(String keyword) {
12+
this.keyword = keyword;
13+
}
14+
public Set<ValidationMessage> validate(JsonNode node) {
15+
return validate(node, node, AT_ROOT);
16+
}
17+
18+
protected ValidationMessage buildValidationMessage(ErrorMessageType errorMessageType, String at, String... arguments) {
19+
return ValidationMessage.of(keyword, errorMessageType, at, arguments);
20+
}
21+
protected ValidationMessage buildValidationMessage(ErrorMessageType errorMessageType, String at, Map<String, Object> details) {
22+
return ValidationMessage.of(keyword, errorMessageType, at, details);
23+
}
24+
25+
protected Set<ValidationMessage> pass() {
26+
return Collections.emptySet();
27+
}
28+
29+
protected Set<ValidationMessage> fail(ErrorMessageType errorMessageType, String at, Map<String, Object> details) {
30+
return Collections.singleton(buildValidationMessage(errorMessageType, at, details));
31+
}
32+
33+
protected Set<ValidationMessage> fail(ErrorMessageType errorMessageType, String at, String...arguments) {
34+
return Collections.singleton(buildValidationMessage(errorMessageType, at, arguments));
35+
}
36+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
package com.networknt.schema;
2+
3+
4+
public abstract class AbstractKeyword implements Keyword {
5+
private final String value;
6+
7+
public AbstractKeyword(String value) {
8+
this.value = value;
9+
}
10+
11+
public String getValue() {
12+
return value;
13+
}
14+
15+
}

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

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,19 @@
1616

1717
package com.networknt.schema;
1818

19-
import com.fasterxml.jackson.databind.JsonNode;
20-
import com.fasterxml.jackson.databind.ObjectMapper;
19+
import java.util.ArrayList;
20+
import java.util.Collections;
21+
import java.util.Iterator;
22+
import java.util.LinkedHashSet;
23+
import java.util.List;
24+
import java.util.Set;
25+
import java.util.regex.Matcher;
26+
import java.util.regex.Pattern;
27+
2128
import org.slf4j.Logger;
2229
import org.slf4j.LoggerFactory;
2330

24-
import java.util.*;
25-
import java.util.regex.Matcher;
26-
import java.util.regex.Pattern;
31+
import com.fasterxml.jackson.databind.JsonNode;
2732

2833
public class AdditionalPropertiesValidator extends BaseJsonValidator implements JsonValidator {
2934
private static final Logger logger = LoggerFactory.getLogger(AdditionalPropertiesValidator.class);
@@ -34,15 +39,15 @@ public class AdditionalPropertiesValidator extends BaseJsonValidator implements
3439
private List<Pattern> patternProperties = new ArrayList<Pattern>();
3540

3641
public AdditionalPropertiesValidator(String schemaPath, JsonNode schemaNode, JsonSchema parentSchema,
37-
ObjectMapper mapper) {
38-
super(schemaPath, schemaNode, parentSchema, ValidatorTypeCode.ADDITIONAL_PROPERTIES);
42+
ValidationContext validationContext) {
43+
super(schemaPath, schemaNode, parentSchema, ValidatorTypeCode.ADDITIONAL_PROPERTIES, validationContext);
3944
allowAdditionalProperties = false;
4045
if (schemaNode.isBoolean()) {
4146
allowAdditionalProperties = schemaNode.booleanValue();
4247
}
4348
if (schemaNode.isObject()) {
4449
allowAdditionalProperties = true;
45-
additionalPropertiesSchema = new JsonSchema(mapper, getValidatorType().getValue(), schemaNode, parentSchema);
50+
additionalPropertiesSchema = new JsonSchema(validationContext, getValidatorType().getValue(), schemaNode, parentSchema);
4651
}
4752

4853
allowedProperties = new ArrayList<String>();

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

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
package com.networknt.schema;
1818

1919
import com.fasterxml.jackson.databind.JsonNode;
20-
import com.fasterxml.jackson.databind.ObjectMapper;
2120
import org.slf4j.Logger;
2221
import org.slf4j.LoggerFactory;
2322

@@ -32,11 +31,11 @@ public class AllOfValidator extends BaseJsonValidator implements JsonValidator {
3231

3332
private List<JsonSchema> schemas = new ArrayList<JsonSchema>();
3433

35-
public AllOfValidator(String schemaPath, JsonNode schemaNode, JsonSchema parentSchema, ObjectMapper mapper) {
36-
super(schemaPath, schemaNode, parentSchema, ValidatorTypeCode.ALL_OF);
34+
public AllOfValidator(String schemaPath, JsonNode schemaNode, JsonSchema parentSchema, ValidationContext validationContext) {
35+
super(schemaPath, schemaNode, parentSchema, ValidatorTypeCode.ALL_OF, validationContext);
3736
int size = schemaNode.size();
3837
for (int i = 0; i < size; i++) {
39-
schemas.add(new JsonSchema(mapper, getValidatorType().getValue(), schemaNode.get(i), parentSchema));
38+
schemas.add(new JsonSchema(validationContext, getValidatorType().getValue(), schemaNode.get(i), parentSchema));
4039
}
4140
}
4241

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

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
package com.networknt.schema;
1818

1919
import com.fasterxml.jackson.databind.JsonNode;
20-
import com.fasterxml.jackson.databind.ObjectMapper;
2120
import org.slf4j.Logger;
2221
import org.slf4j.LoggerFactory;
2322

@@ -32,11 +31,11 @@ public class AnyOfValidator extends BaseJsonValidator implements JsonValidator {
3231

3332
private List<JsonSchema> schemas = new ArrayList<JsonSchema>();
3433

35-
public AnyOfValidator(String schemaPath, JsonNode schemaNode, JsonSchema parentSchema, ObjectMapper mapper) {
36-
super(schemaPath, schemaNode, parentSchema, ValidatorTypeCode.ANY_OF);
34+
public AnyOfValidator(String schemaPath, JsonNode schemaNode, JsonSchema parentSchema, ValidationContext validationContext) {
35+
super(schemaPath, schemaNode, parentSchema, ValidatorTypeCode.ANY_OF, validationContext);
3736
int size = schemaNode.size();
3837
for (int i = 0; i < size; i++) {
39-
schemas.add(new JsonSchema(mapper, getValidatorType().getValue(), schemaNode.get(i), parentSchema));
38+
schemas.add(new JsonSchema(validationContext, getValidatorType().getValue(), schemaNode.get(i), parentSchema));
4039
}
4140
}
4241

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

Lines changed: 11 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -31,19 +31,16 @@ public abstract class BaseJsonValidator implements JsonValidator {
3131
private JsonSchema parentSchema;
3232
private JsonSchema subSchema;
3333
private ValidatorTypeCode validatorType;
34-
private String errorCode;
34+
private ErrorMessageType errorMessageType;
3535

3636
public BaseJsonValidator(String schemaPath, JsonNode schemaNode, JsonSchema parentSchema,
37-
ValidatorTypeCode validatorType) {
38-
this.schemaPath = schemaPath;
39-
this.schemaNode = schemaNode;
40-
this.parentSchema = parentSchema;
41-
this.validatorType = validatorType;
42-
this.subSchema = obainSubSchemaNode(schemaNode);
37+
ValidatorTypeCode validatorType, ValidationContext validationContext) {
38+
this(schemaPath, schemaNode, parentSchema, validatorType, obainSubSchemaNode(schemaNode, validationContext) );
4339
}
4440

4541
public BaseJsonValidator(String schemaPath, JsonNode schemaNode, JsonSchema parentSchema,
4642
ValidatorTypeCode validatorType, JsonSchema subSchema) {
43+
this.errorMessageType = validatorType;
4744
this.schemaPath = schemaPath;
4845
this.schemaNode = schemaNode;
4946
this.parentSchema = parentSchema;
@@ -71,20 +68,19 @@ protected boolean hasSubSchema() {
7168
return subSchema != null;
7269
}
7370

74-
protected JsonSchema obainSubSchemaNode(JsonNode schemaNode){
71+
protected static JsonSchema obainSubSchemaNode(JsonNode schemaNode, ValidationContext validationContext){
7572
JsonNode node = schemaNode.get("id");
7673
if(node == null) return null;
7774
if(node.equals(schemaNode.get("$schema"))) return null;
7875

7976
try {
80-
JsonSchemaFactory factory = new JsonSchemaFactory();
8177
String text = node.textValue();
8278
if (text == null) {
8379
return null;
8480
}
8581
else {
8682
URL url = URLFactory.toURL(node.textValue());
87-
return factory.getSchema(url);
83+
return validationContext.getJsonSchemaFactory().getSchema(url);
8884
}
8985
} catch (MalformedURLException e) {
9086
return null;
@@ -110,27 +106,16 @@ protected boolean lessThan(double n1, double n2) {
110106
protected void parseErrorCode(String errorCodeKey) {
111107
JsonNode errorCodeNode = getParentSchema().getSchemaNode().get(errorCodeKey);
112108
if (errorCodeNode != null && errorCodeNode.isTextual()) {
113-
errorCode = errorCodeNode.asText();
109+
String errorCodeText = errorCodeNode.asText();
110+
if (StringUtils.isNotBlank(errorCodeText)) {
111+
errorMessageType = CustomErrorMessageType.of(errorCodeText);
112+
}
114113
}
115114
}
116115

117-
private String getErrorCode() {
118-
return errorCode;
119-
}
120-
121-
private boolean isUsingCustomErrorCode() {
122-
return StringUtils.isNotBlank(errorCode);
123-
}
124116

125117
protected ValidationMessage buildValidationMessage(String at, String... arguments) {
126-
ValidationMessage.Builder builder = new ValidationMessage.Builder();
127-
if (isUsingCustomErrorCode()) {
128-
builder.code(getErrorCode()).path(at).arguments(arguments).type(validatorType.getValue());
129-
} else {
130-
builder.code(validatorType.getErrorCode()).path(at).arguments(arguments)
131-
.format(validatorType.getMessageFormat()).type(validatorType.getValue());
132-
}
133-
return builder.build();
118+
return ValidationMessage.of(getValidatorType().getValue(), errorMessageType, at, arguments);
134119
}
135120

136121
protected void debug(Logger logger, JsonNode node, JsonNode rootNode, String at) {

0 commit comments

Comments
 (0)