Skip to content

Commit 8c56c7b

Browse files
Added schema version detection based sample.
Updated structure and text to be more descriptive. Uniform code block style.
1 parent 3156bb4 commit 8c56c7b

File tree

1 file changed

+107
-61
lines changed

1 file changed

+107
-61
lines changed

doc/specversion.md

Lines changed: 107 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -2,35 +2,64 @@ The library supports V4, V6, V7, and V2019-09 JSON schema specifications. By def
22

33
### For Users
44

5-
To create a draft V4 JsonSchemaFactory
5+
#### To create a draft V4 JsonSchemaFactory
66

77
```
8-
protected ObjectMapper mapper = new ObjectMapper();
9-
protected JsonSchemaFactory validatorFactory = JsonSchemaFactory.builder(JsonSchemaFactory.getInstance()).objectMapper(mapper).build();
8+
ObjectMapper mapper = new ObjectMapper();
9+
JsonSchemaFactory validatorFactory = JsonSchemaFactory.builder(JsonSchemaFactory.getInstance(SpecVersion.VersionFlag.V4)).objectMapper(mapper).build();
10+
```
11+
or with default configuration
12+
```
13+
JsonSchemaFactory validatorFactory = JsonSchemaFactory.getInstance(SpecVersion.VersionFlag.V4));
1014
```
1115

12-
The above code is exactly the same as before. Internally, it will default to the SpecVersion.VersionFlag.V4 as the parameter.
16+
Please avoid using default getInstance(), which, internally, defaults to the SpecVersion.VersionFlag.V4 as the parameter. This is deprecated.
1317

14-
To create a draft V6 JsonSchemaFactory
18+
#### To create a draft V6 JsonSchemaFactory
1519

1620
```
17-
protected ObjectMapper mapper = new ObjectMapper();
18-
protected JsonSchemaFactory validatorFactory = JsonSchemaFactory.builder(JsonSchemaFactory.getInstance(SpecVersion.VersionFlag.V6)).objectMapper(mapper).build();
21+
ObjectMapper mapper = new ObjectMapper();
22+
JsonSchemaFactory validatorFactory = JsonSchemaFactory.builder(JsonSchemaFactory.getInstance(SpecVersion.VersionFlag.V6)).objectMapper(mapper).build();
23+
```
24+
or with default configuration
25+
```
26+
JsonSchemaFactory validatorFactory = JsonSchemaFactory.getInstance(SpecVersion.VersionFlag.V6));
27+
```
28+
29+
#### To create a draft V7 JsonSchemaFactory
1930

31+
```
32+
ObjectMapper mapper = new ObjectMapper();
33+
JsonSchemaFactory validatorFactory = JsonSchemaFactory.builder(JsonSchemaFactory.getInstance(SpecVersion.VersionFlag.V7)).objectMapper(mapper).build();
34+
```
35+
or with default configuration
36+
```
37+
JsonSchemaFactory validatorFactory = JsonSchemaFactory.getInstance(SpecVersion.VersionFlag.V7));
2038
```
2139

22-
To create a draft V7 JsonSchemaFactory
40+
#### To create a draft 2019-09 JsonSchemaFactory
2341

2442
```
25-
protected ObjectMapper mapper = new ObjectMapper();
26-
protected JsonSchemaFactory validatorFactory = JsonSchemaFactory.builder(JsonSchemaFactory.getInstance(SpecVersion.VersionFlag.V7)).objectMapper(mapper).build();
43+
ObjectMapper mapper = new ObjectMapper();
44+
JsonSchemaFactory validatorFactory = JsonSchemaFactory.builder(JsonSchemaFactory.getInstance(SpecVersion.VersionFlag.V201909)).objectMapper(mapper).build();
45+
```
46+
or with default configuration
47+
```
48+
JsonSchemaFactory validatorFactory = JsonSchemaFactory.getInstance(SpecVersion.VersionFlag.V201909));
2749
```
2850

29-
To create a draft 2019-09 JsonSchemaFactory
51+
#### To create a JsonSchemaFactory, automatically detecting schema version
3052

3153
```
32-
protected ObjectMapper mapper = new ObjectMapper();
33-
protected JsonSchemaFactory validatorFactory = JsonSchemaFactory.builder(JsonSchemaFactory.getInstance(SpecVersion.VersionFlag.V201909)).objectMapper(mapper).build();
54+
ObjectMapper mapper = new ObjectMapper();
55+
JsonNode jsonNode = mapper.readTree(/* schema / schema input steam etc. */);
56+
JsonSchemaFactory validatorFactory = JsonSchemaFactory.builder(JsonSchemaFactory.getInstance(SpecVersionDetector.detect(jsonNode))).objectMapper(mapper).build();
57+
```
58+
or with default configuration
59+
```
60+
ObjectMapper mapper = new ObjectMapper();
61+
JsonNode jsonNode = mapper.readTree(/* schema / schema input steam etc. */);
62+
JsonSchemaFactory validatorFactory = JsonSchemaFactory.getInstance(SpecVersionDetector.detect(jsonNode));
3463
```
3564

3665
### For Developers
@@ -40,12 +69,12 @@ protected JsonSchemaFactory validatorFactory = JsonSchemaFactory.builder(JsonSch
4069
A new class SpecVersion has been introduced to indicate which version of the specification is used when creating the JsonSchemaFactory. The SpecVersion has an enum and two methods to convert a long to an EnumSet or a set of VersionFlags to a long value.
4170

4271
```
43-
public enum VersionFlag {
72+
public enum VersionFlag {
4473
45-
V4(1<<0),
46-
V6(1<<1),
47-
V7(1<<2),
48-
V201909(1<<3);
74+
V4(1<<0),
75+
V6(1<<1),
76+
V7(1<<2),
77+
V201909(1<<3);
4978
5079
```
5180

@@ -69,80 +98,97 @@ For most of the validators, the version code should be 15, which is 1111. This m
6998
For example.
7099

71100
```
72-
MAXIMUM("maximum", "1011", new MessageFormat("{0}: must have a maximum value of {1}"), MaximumValidator.class, 15),
101+
MAXIMUM("maximum", "1011", new MessageFormat("{0}: must have a maximum value of {1}"), MaximumValidator.class, 15),
73102
```
74103

75104
Since if-then-else was introduced in the V7, it only works for V7 and V2019-09
76105

77106
```
78-
IF_THEN_ELSE("if", "1037", null, IfValidator.class, 12), // V7|V201909 1100
107+
IF_THEN_ELSE("if", "1037", null, IfValidator.class, 12), // V7|V201909 1100
79108
```
80109

81110
For exclusiveMaximum, it was introduced from V6
82111

83112
```
84-
EXCLUSIVE_MAXIMUM("exclusiveMaximum", "1038", new MessageFormat("{0}: must have a exclusive maximum value of {1}"), ExclusiveMaximumValidator.class, 14), // V6|V7|V201909
113+
EXCLUSIVE_MAXIMUM("exclusiveMaximum", "1038", new MessageFormat("{0}: must have a exclusive maximum value of {1}"), ExclusiveMaximumValidator.class, 14), // V6|V7|V201909
85114
```
86115

87116
The getNonFormatKeywords method is updated to accept a SpecVersion.VersionFlag so that only the keywords supported by the specification will be loaded.
88117

89118
```
90-
public static List<ValidatorTypeCode> getNonFormatKeywords(SpecVersion.VersionFlag versionFlag) {
91-
final List<ValidatorTypeCode> result = new ArrayList<ValidatorTypeCode>();
92-
for (ValidatorTypeCode keyword: values()) {
93-
if (!FORMAT.equals(keyword) && specVersion.getVersionFlags(keyword.versionCode).contains(versionFlag)) {
94-
result.add(keyword);
95-
}
119+
public static List<ValidatorTypeCode> getNonFormatKeywords(SpecVersion.VersionFlag versionFlag) {
120+
final List<ValidatorTypeCode> result = new ArrayList<ValidatorTypeCode>();
121+
for (ValidatorTypeCode keyword: values()) {
122+
if (!FORMAT.equals(keyword) && specVersion.getVersionFlags(keyword.versionCode).contains(versionFlag)) {
123+
result.add(keyword);
96124
}
97-
return result;
98125
}
126+
return result;
127+
}
99128
```
100129

101-
### JsonMetaSchema
130+
#### JsonMetaSchema
102131

103132
We have created four different static classes V4, V6, V7, and V201909 to build different JsonMetaSchema instances.
104133

105134
For the BUILDIN_FORMATS, there is a common section, and each static class has its version-specific BUILDIN_FORMATS section.
106135

107-
108-
### JsonSchemaFactory
136+
#### JsonSchemaFactory
109137

110138
The getInstance supports a parameter SpecVersion.VersionFlag to get the right instance of the JsonMetaShema to create the factory. If there is no parameter, then V4 is used by default.
111139

112140
```
113-
public static JsonSchemaFactory getInstance() {
114-
return getInstance(SpecVersion.VersionFlag.V4);
141+
@Deprecated
142+
public static JsonSchemaFactory getInstance() {
143+
return getInstance(SpecVersion.VersionFlag.V4);
144+
}
145+
146+
public static JsonSchemaFactory getInstance(SpecVersion.VersionFlag versionFlag) {
147+
JsonMetaSchema metaSchema = null;
148+
switch (versionFlag) {
149+
case V201909:
150+
metaSchema = JsonMetaSchema.getV201909();
151+
break;
152+
case V7:
153+
metaSchema = JsonMetaSchema.getV7();
154+
break;
155+
case V6:
156+
metaSchema = JsonMetaSchema.getV6();
157+
break;
158+
case V4:
159+
metaSchema = JsonMetaSchema.getV4();
160+
break;
115161
}
162+
return builder()
163+
.defaultMetaSchemaURI(metaSchema.getUri())
164+
.addMetaSchema(metaSchema)
165+
.build();
166+
}
167+
```
116168

117-
public static JsonSchemaFactory getInstance(SpecVersion.VersionFlag versionFlag) {
118-
if(versionFlag == SpecVersion.VersionFlag.V201909) {
119-
JsonMetaSchema v201909 = JsonMetaSchema.getV201909();
120-
return builder()
121-
.defaultMetaSchemaURI(v201909.getUri())
122-
.addMetaSchema(v201909)
123-
.build();
124-
} else if(versionFlag == SpecVersion.VersionFlag.V7) {
125-
JsonMetaSchema v7 = JsonMetaSchema.getV7();
126-
return builder()
127-
.defaultMetaSchemaURI(v7.getUri())
128-
.addMetaSchema(v7)
129-
.build();
130-
} else if(versionFlag == SpecVersion.VersionFlag.V6) {
131-
JsonMetaSchema v6 = JsonMetaSchema.getV6();
132-
return builder()
133-
.defaultMetaSchemaURI(v6.getUri())
134-
.addMetaSchema(v6)
135-
.build();
136-
} else if(versionFlag == SpecVersion.VersionFlag.V4) {
137-
JsonMetaSchema v4 = JsonMetaSchema.getV4();
138-
return builder()
139-
.defaultMetaSchemaURI(v4.getUri())
140-
.addMetaSchema(v4)
141-
.build();
142-
}
143-
return null;
144-
}
169+
#### SpecVersionDetector
170+
171+
This class detects schema version based on the schema tag.
172+
173+
```
174+
private static final String SCHEMA_TAG = "$schema";
175+
176+
public static SpecVersion.VersionFlag detect(JsonNode jsonNode) {
177+
if (!jsonNode.has(SCHEMA_TAG))
178+
throw new JsonSchemaException("Schema tag not present");
145179
180+
String schemaUri = JsonSchemaFactory.normalizeMetaSchemaUri(jsonNode.get(SCHEMA_TAG).asText());
181+
if (schemaUri.equals(JsonMetaSchema.getV4().getUri()))
182+
return SpecVersion.VersionFlag.V4;
183+
else if (schemaUri.equals(JsonMetaSchema.getV6().getUri()))
184+
return SpecVersion.VersionFlag.V6;
185+
else if (schemaUri.equals(JsonMetaSchema.getV7().getUri()))
186+
return SpecVersion.VersionFlag.V7;
187+
else if (schemaUri.equals(JsonMetaSchema.getV201909().getUri()))
188+
return SpecVersion.VersionFlag.V201909;
189+
else
190+
throw new JsonSchemaException("Unrecognizable schema");
191+
}
146192
```
147193

148194
### For Testers

0 commit comments

Comments
 (0)