Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 5 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,9 @@ This is a Java implementation of the [JSON Schema Core Draft v4, v6, v7, v2019-0

It is the fastest Java JSON Schema Validator as far as I know. Here is the testing result compare with the other two open-source implementations. It is about 32 times faster than the Fge and five times faster than the Everit.

fge: 7130ms

everit-org: 1168ms

networknt: 223ms
- fge: 7130ms
- everit-org: 1168ms
- networknt: 223ms

You can run the performance tests for three libraries from [https://github.com/networknt/json-schema-validator-perftest](https://github.com/networknt/json-schema-validator-perftest)

Expand All @@ -44,7 +42,7 @@ Following the design principle of the Light Platform, this library has minimum d

Here are the dependencies.

```
```xml
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
Expand Down Expand Up @@ -88,7 +86,7 @@ Maven:

Gradle:

```
```java
dependencies {
compile(group: "com.networknt", name: "json-schema-validator", version: "1.0.73");
}
Expand Down
12 changes: 6 additions & 6 deletions doc/collector-context.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ CollectorContext instance can be obtained by calling the getInstance static meth

Collectors are added to CollectorContext. Collectors allow to collect the objects. A Collector is added to CollectorContext with a name and corresponding Collector instance.

```
```java
CollectorContext collectorContext = CollectorContext.getInstance();
collectorContext.add(SAMPLE_COLLECTOR_NAME, new Collector<List<String>>() {
@Override
Expand All @@ -29,7 +29,7 @@ collectorContext.add(SAMPLE_COLLECTOR_NAME, new Collector<List<String>>() {

However there might be use cases where we want to add a simple Object like String, Integer, etc, into the Context. This can be done the same way a collector is added to the context.

```
```java
CollectorContext collectorContext = CollectorContext.getInstance();
collectorContext.add(SAMPLE_COLLECTOR,"sample-string")

Expand All @@ -38,7 +38,7 @@ collectorContext.add(SAMPLE_COLLECTOR,"sample-string")
To validate the schema with the ability to use CollectorContext, validateAndCollect method has to be invoked on the JsonSchema class. This class returns a ValidationResult that contains the errors encountered during validation and a CollectorContext instance. Objects constructed by Collectors or directly added to CollectorContext can be retrieved from CollectorContext by using the name they were added with.


```
```java
ValidationResult validationResult = jsonSchema.validateAndCollect(jsonNode);
CollectorContext context = validationResult.getCollectorContext();
List<String> contextValue = (List<String>)context.get(SAMPLE_COLLECTOR);
Expand All @@ -49,7 +49,7 @@ Note that CollectorContext will be removed from ThreadLocal once validateAndColl

There might be usecases where a collector needs to collect the data at multiple touch points. For example one usecase might be collecting data in a validator and a formatter. If you are using a Collector rather than a Object, the combine method of the Collector allows to define how we want to combine the data into existing Collector. CollectorContext combineWithCollector method calls the combine method on the Collector. User just needs to call the CollectorContext combineWithCollector method every time some data needs to merged into existing Collector. The collect method on the Collector is called by the framework at the end of validation to return the data that was collected.

```
```java
class CustomCollector implements Collector<List<String>> {

List<String> returnList = new ArrayList<String>();
Expand Down Expand Up @@ -81,7 +81,7 @@ collectorContext.combineWithCollector(SAMPLE_COLLECTOR, node.textValue());

One important thing to note when using Collectors is if we call get method on CollectorContext before the validation is complete, we would get back a Collector instance that was added to CollectorContext.

```
```java
// Returns Collector before validation is done.
Collector<List<String>> collector = collectorContext.get(SAMPLE_COLLECTOR);

Expand All @@ -92,7 +92,7 @@ List<String> data = collectorContext.get(SAMPLE_COLLECTOR);

If you are using simple objects and if the data needs to be collected from multiple touch points, logic is straightforward as shown.

```
```java

CollectorContext collectorContext = CollectorContext.getInstance();
// If collector name is not added to context add one.
Expand Down
8 changes: 4 additions & 4 deletions doc/config.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@ Most of the configuration flags are used to control the difference between Swagg

#### How to use config

When you create a JsonSchema instance from the JsonSchemaFactory, you can pass an object of SchemaValidatorsConfig as the second parameter.
When you create a `JsonSchema` instance from the `JsonSchemaFactory`, you can pass an object of SchemaValidatorsConfig as the second parameter.

```
```java
SchemaValidatorsConfig config = new SchemaValidatorsConfig();
config.setTypeLoose(false);
JsonSchema jsonSchema = JsonSchemaFactory.getInstance().getSchema(schema, config);
Expand Down Expand Up @@ -46,7 +46,7 @@ For more details, please refer to this [issue](https://github.com/networknt/json
Map of public, typically internet-accessible schema URLs to alternate locations; this allows for offline validation of schemas that refer to public URLs. This is merged with any mappings the sonSchemaFactory
may have been built.

The type for this variable is Map<String, String>.
The type for this variable is `Map<String, String>`.

* javaSemantics

Expand All @@ -62,4 +62,4 @@ When set to true, can interpret round doubles as integers.

Note that setting `javaSemantics = true` will achieve the same functionality at this time.

For more details, please refer to this [issue](https://github.com/networknt/json-schema-validator/issues/344).
For more details, please refer to this [issue](https://github.com/networknt/json-schema-validator/issues/344).
2 changes: 1 addition & 1 deletion doc/cust-fetcher.md
Original file line number Diff line number Diff line change
@@ -1 +1 @@
The default URIFetcher implementation uses JDK connection/socket without handling network exceptions. It works in most of the cases; however, if you want to have a customized implementation, you can do so. One user has his implementation with urirest to handle the timeout. A detailed discussion can be found in this [issue](https://github.com/networknt/json-schema-validator/issues/240)
The default `URIFetcher` implementation uses JDK connection/socket without handling network exceptions. It works in most of the cases; however, if you want to have a customized implementation, you can do so. One user has his implementation with urirest to handle the timeout. A detailed discussion can be found in this [issue](https://github.com/networknt/json-schema-validator/issues/240)
2 changes: 1 addition & 1 deletion doc/cust-meta.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
How to use your customized meta schema?

The library supports customized meta schema with this builder method. We have provided default instances for v4, v6, v7, and v2019-09 but users can always create their own JsonMetaSchema instance with customized meta schema.
The library supports customized meta schema with this builder method. We have provided default instances for v4, v6, v7, and v2019-09 but users can always create their own `JsonMetaSchema` instance with customized meta schema.

https://github.com/networknt/json-schema-validator/blob/master/src/main/java/com/networknt/schema/JsonMetaSchema.java#L188

8 changes: 4 additions & 4 deletions doc/cust-msg.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ We can provide the custom message in the json schema itself.

<b> Example of schema with default message: </b>

````
````json
{
"type": "object",
"properties": {
Expand All @@ -24,7 +24,7 @@ We can provide the custom message in the json schema itself.

<b> Example of schema with a custom message: </b>

````
````json
{
"type": "object",
"properties": {
Expand All @@ -46,7 +46,7 @@ We can provide the custom message in the json schema itself.



````
````json
"message": {
[validationType] : [customMessage]
}
Expand All @@ -59,4 +59,4 @@ Also, we can make format the dynamic message with properties returned from [Vali



Take a look at the [PR](https://github.com/networknt/json-schema-validator/pull/438)
Take a look at the [PR](https://github.com/networknt/json-schema-validator/pull/438)
10 changes: 5 additions & 5 deletions doc/ecma-262.md
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
For the pattern validator, we now have two options for regex in the library. The default one is java.util. regex; however, you can use the ECMA-262 standard library org.jruby.joni by configuration.
For the pattern validator, we now have two options for regex in the library. The default one is `java.util.regex`; however, you can use the ECMA-262 standard library `org.jruby.joni` by configuration.

As we know, the JSON schema is designed based on the Javascript language and its regex. The Java internal implementation has some differences which don't comply with the standard. For most users, these edge cases are not the issue as they are not using them anyway. Even when they are using it, they are expecting the Java regex result as the application is built on the Java platform. For users who want to ensure that they are using 100% standard patter validator, we have provided an option to override the default regex library with org.jruby.joni that is complying with the ECMA-262 standard.
As we know, the JSON schema is designed based on the Javascript language and its regex. The Java internal implementation has some differences which don't comply with the standard. For most users, these edge cases are not the issue as they are not using them anyway. Even when they are using it, they are expecting the Java regex result as the application is built on the Java platform. For users who want to ensure that they are using 100% standard patter validator, we have provided an option to override the default regex library with `org.jruby.joni` that is complying with the ECMA-262 standard.

### Which one to choose?

If you want a faster regex lib and don't care about the slight difference between Java and Javascript regex, then you don't need to do anything. The default regex lib is the java.util.regex.
If you want a faster regex lib and don't care about the slight difference between Java and Javascript regex, then you don't need to do anything. The default regex lib is the `java.util.regex`.

If you want to ensure full compliance, use the org.jruby.joni. It is 1.5 times slower then java.util.regex. Depending on your use case, it might not be an issue.
If you want to ensure full compliance, use the `org.jruby.joni`. It is 1.5 times slower then `java.util.regex`. Depending on your use case, it might not be an issue.

### How to switch?

Here is the test case that shows how to pass a config object to use the ECMA-262 library.

```
```java
@Test(expected = JsonSchemaException.class)
public void testInvalidPatternPropertiesValidatorECMA262() throws Exception {
SchemaValidatorsConfig config = new SchemaValidatorsConfig();
Expand Down
2 changes: 0 additions & 2 deletions doc/openapi-discriminators.md
Original file line number Diff line number Diff line change
Expand Up @@ -187,5 +187,3 @@ more examples in https://github.com/networknt/json-schema-validator/blob/master/
}
}
```

###
8 changes: 4 additions & 4 deletions doc/quickstart.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
## Quick Start

To use the validator, we need to have both the JsonSchema object and JsonNode object constructed.
To use the validator, we need to have both the `JsonSchema` object and `JsonNode` object constructed.
There are many ways to do that.
Here is base test class, that shows several ways to construct these from String, Stream, Url, and JsonNode.
Please pay attention to the JsonSchemaFactory class as it is the way to construct the JsonSchema object.
Here is base test class, that shows several ways to construct these from `String`, `Stream`, `Url`, and `JsonNode`.
Please pay attention to the `JsonSchemaFactory` class as it is the way to construct the `JsonSchema` object.

```java
public class BaseJsonSchemaValidatorTest {
Expand Down Expand Up @@ -54,7 +54,7 @@ public class BaseJsonSchemaValidatorTest {

}
```
And the following is one of the test cases in one of the test classes that extend from the above base class. As you can see, it constructs JsonSchema and JsonNode from String.
And the following is one of the test cases in one of the test classes that extend from the above base class. As you can see, it constructs `JsonSchema` and `JsonNode` from `String`.

```java
class Sample extends BaseJsonSchemaValidatorTest {
Expand Down
4 changes: 2 additions & 2 deletions doc/schema-map.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ Basically, you can specify a mapping in the builder. For more details, please ta

https://github.com/JMRI/JMRI/blob/master/java/src/jmri/server/json/schema-map.json

In case you provide the schema through an InputStream or a String to resolve $ref with URN (relative path), you need to provide the URNFactory to the JsonSchemaFactory.Builder.
URNFactory interface will allow you to resolve URN to URI.
In case you provide the schema through an `InputStream` or a `String` to resolve `$ref` with URN (relative path), you need to provide the `URNFactory` to the `JsonSchemaFactory.Builder.
URNFactory` interface will allow you to resolve URN to URI.

please take a look at the test cases and the [PR](https://github.com/networknt/json-schema-validator/pull/274).
14 changes: 7 additions & 7 deletions doc/specversion.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ or with default configuration
JsonSchemaFactory validatorFactory = JsonSchemaFactory.getInstance(SpecVersion.VersionFlag.V4));
```

Please avoid using default getInstance(), which, internally, defaults to the SpecVersion.VersionFlag.V4 as the parameter. This is deprecated.
Please avoid using default `getInstance()`, which, internally, defaults to the `SpecVersion.VersionFlag.V4` as the parameter. This is deprecated.

#### To create a draft V6 JsonSchemaFactory

Expand Down Expand Up @@ -77,7 +77,7 @@ JsonSchemaFactory validatorFactory = JsonSchemaFactory.getInstance(SpecVersionDe

#### SpecVersion

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.
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.

```java
public enum VersionFlag {
Expand Down Expand Up @@ -110,19 +110,19 @@ For most of the validators, the version code should be 31, which is 11111. This

For example.

```
```java
MAXIMUM("maximum", "1011", new MessageFormat("{0}: must have a maximum value of {1}"), MaximumValidator.class, 31),
```

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

```
```java
IF_THEN_ELSE("if", "1037", null, IfValidator.class, 28), // V7|V201909|V202012 11100
```

For exclusiveMaximum, it was introduced from V6

```
```java
EXCLUSIVE_MAXIMUM("exclusiveMaximum", "1038", new MessageFormat("{0}: must have a exclusive maximum value of {1}"), ExclusiveMaximumValidator.class, 30), // V6|V7|V201909|V202012
```

Expand All @@ -142,13 +142,13 @@ public static List<ValidatorTypeCode> getNonFormatKeywords(SpecVersion.VersionFl

#### JsonMetaSchema

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

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

#### JsonSchemaFactory

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.
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.

```java
@Deprecated
Expand Down
8 changes: 4 additions & 4 deletions doc/validators.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ If `if` is valid, `then` must also be valid (and `else` is ignored.) If `if` is
For usage, please refer to the test cases at https://github.com/networknt/json-schema-validator/blob/master/src/test/resources/draft7/if-then-else.json

### Custom Validators
````
````java
@Bean
public JsonSchemaFactory mySchemaFactory() {
// base on JsonMetaSchema.V201909 copy code below
Expand Down Expand Up @@ -69,7 +69,7 @@ public class GroovyKeyword extends AbstractKeyword {
}
````
You can use GroovyKeyword like below:
````
````json
{
"type": "object",
"properties": {
Expand All @@ -87,7 +87,7 @@ In this library, if the format keyword is "email", "uuid", "date", "date-time",

If you want to override this behavior, do as below.

```
```java
public JsonSchemaFactory mySchemaFactory() {
// base on JsonMetaSchema.V201909 copy code below
String URI = "https://json-schema.org/draft/2019-09/schema";
Expand All @@ -103,4 +103,4 @@ public JsonSchemaFactory mySchemaFactory() {
.addMetaSchema(overrideEmailValidatorMetaSchema)
.build();
}
```
```
10 changes: 5 additions & 5 deletions doc/yaml-line-numbers.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ A great feature of json-schema-validator is it's ability to validate YAML docume

One solution is to use a custom [JsonNodeFactory](https://fasterxml.github.io/jackson-databind/javadoc/2.10/com/fasterxml/jackson/databind/node/JsonNodeFactory.html) that returns custom JsonNode objects which are created during initial parsing, and which record the original YAML locations that were being parsed at the time they were created. The example below shows this

```
```java
public static class MyNodeFactory extends JsonNodeFactory
{
YAMLParser yp;
Expand Down Expand Up @@ -69,7 +69,7 @@ We can be as simple or fancy as we like in the `JsonNode` subclassses, but basic

Those could be the same thing of course, but in our case we separated them as shown in the following example

```
```java
public interface LocationProvider
{
LocationDetails getLocationDetails();
Expand Down Expand Up @@ -193,7 +193,7 @@ Those could be the same thing of course, but in our case we separated them as sh

With the pieces we now have, we just need to tell the YAML library to make of use them, which involves a minor and simple modification to the normal sequence of processing.

```
```java
this.yamlFactory = new YAMLFactory();

try (YAMLParser yp = yamlFactory.createParser(f);)
Expand Down Expand Up @@ -235,7 +235,7 @@ Some notes on what is happening here:
Having got everything prepared, actually getting the line locations is rather easy


```
```java
void processJsonItems(JsonNode item)
{
Iterator<Map.Entry<String, JsonNode>> iter = item.fields();
Expand Down Expand Up @@ -268,7 +268,7 @@ Any failures validation against the schema come back in the form of a set of `Va

Within the `ValidationMessage` object is something called the 'path' of the error, which we can access with the `getPath()` method. The syntax of this path is not exactly the same as a regular [JsonPointer](https://fasterxml.github.io/jackson-core/javadoc/2.10/com/fasterxml/jackson/core/JsonPointer.html) object, but it is sufficiently close as to be convertible. And, once converted, we can use that pointer for locating the appropriate `JsonNode`. The following couple of methods can be used to automate this process

```
```java
JsonNode findJsonNode(ValidationMessage msg, JsonNode rootNode)
{
// munge the ValidationMessage path
Expand Down
4 changes: 2 additions & 2 deletions doc/yaml.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ One of the features of this library is to validate the YAML file in addition to

Add the dependency

```
```xml
<dependency>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-yaml</artifactId>
Expand All @@ -15,7 +15,7 @@ Add the dependency
and create object mapper using yaml factory i.e `ObjectMapper objMapper =new ObjectMapper(new YAMLFactory());`

#### Example
```
```java
JsonSchemaFactory factory = JsonSchemaFactory.builder(JsonSchemaFactory.getInstance(SpecVersion.VersionFlag.V7)).objectMapper(mapper).build(); /* Using draft-07. You can choose anyother draft.*/
JsonSchema schema = factory.getSchema(YamlOperations.class.getClassLoader().getResourceAsStream("your-schema.json"));

Expand Down