• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2016 Network New Technologies Inc.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.networknt.schema;
18 
19 import com.fasterxml.jackson.databind.JsonNode;
20 import com.networknt.schema.SpecVersion.VersionFlag;
21 
22 import java.util.ArrayList;
23 import java.util.EnumSet;
24 import java.util.HashMap;
25 import java.util.List;
26 import java.util.Map;
27 
28 @FunctionalInterface
29 interface ValidatorFactory {
newInstance(SchemaLocation schemaLocation, JsonNodePath evaluationPath, JsonNode schemaNode, JsonSchema parentSchema, ValidationContext validationContext)30     JsonValidator newInstance(SchemaLocation schemaLocation, JsonNodePath evaluationPath, JsonNode schemaNode,
31             JsonSchema parentSchema, ValidationContext validationContext);
32 }
33 
34 enum VersionCode {
35     None(new SpecVersion.VersionFlag[] { }),
36     AllVersions(new SpecVersion.VersionFlag[] { SpecVersion.VersionFlag.V4, SpecVersion.VersionFlag.V6, SpecVersion.VersionFlag.V7, SpecVersion.VersionFlag.V201909, SpecVersion.VersionFlag.V202012 }),
37     MinV6(new SpecVersion.VersionFlag[] { SpecVersion.VersionFlag.V6, SpecVersion.VersionFlag.V7, SpecVersion.VersionFlag.V201909, SpecVersion.VersionFlag.V202012 }),
38     MinV6MaxV7(new SpecVersion.VersionFlag[] { SpecVersion.VersionFlag.V6, SpecVersion.VersionFlag.V7 }),
39     MinV7(new SpecVersion.VersionFlag[] { SpecVersion.VersionFlag.V7, SpecVersion.VersionFlag.V201909, SpecVersion.VersionFlag.V202012 }),
40     MaxV7(new SpecVersion.VersionFlag[] { SpecVersion.VersionFlag.V4, SpecVersion.VersionFlag.V6, SpecVersion.VersionFlag.V7 }),
41     MaxV201909(new SpecVersion.VersionFlag[] { SpecVersion.VersionFlag.V4, SpecVersion.VersionFlag.V6, SpecVersion.VersionFlag.V7, SpecVersion.VersionFlag.V201909 }),
42     MinV201909(new SpecVersion.VersionFlag[] { SpecVersion.VersionFlag.V201909, SpecVersion.VersionFlag.V202012 }),
43     MinV202012(new SpecVersion.VersionFlag[] { SpecVersion.VersionFlag.V202012 }),
44     V201909(new SpecVersion.VersionFlag[] { SpecVersion.VersionFlag.V201909 }),
45     V7(new SpecVersion.VersionFlag[] { SpecVersion.VersionFlag.V7 });
46 
47     private final EnumSet<VersionFlag> versions;
48 
VersionCode(SpecVersion.VersionFlag[] versionFlags)49     VersionCode(SpecVersion.VersionFlag[] versionFlags) {
50         this.versions = EnumSet.noneOf(VersionFlag.class);
51         for (VersionFlag flag: versionFlags) {
52             this.versions.add(flag);
53         }
54     }
55 
getVersions()56     EnumSet<VersionFlag> getVersions() {
57         return this.versions;
58     }
59 }
60 
61 public enum ValidatorTypeCode implements Keyword, ErrorMessageType {
62     ADDITIONAL_PROPERTIES("additionalProperties", "1001", AdditionalPropertiesValidator::new, VersionCode.MaxV7),
63     ALL_OF("allOf", "1002", AllOfValidator::new, VersionCode.MaxV7),
64     ANY_OF("anyOf", "1003", AnyOfValidator::new, VersionCode.MaxV7),
65     CONST("const", "1042", ConstValidator::new, VersionCode.MinV6MaxV7),
66     CONTAINS("contains", "1043", ContainsValidator::new, VersionCode.MinV6MaxV7),
67     CONTENT_ENCODING("contentEncoding", "1052", ContentEncodingValidator::new, VersionCode.V7),
68     CONTENT_MEDIA_TYPE("contentMediaType", "1053", ContentMediaTypeValidator::new, VersionCode.V7),
69     DEPENDENCIES("dependencies", "1007", DependenciesValidator::new, VersionCode.AllVersions),
70     DEPENDENT_REQUIRED("dependentRequired", "1045", DependentRequired::new, VersionCode.None),
71     DEPENDENT_SCHEMAS("dependentSchemas", "1046", DependentSchemas::new, VersionCode.None),
72     DISCRIMINATOR("discriminator", "2001", DiscriminatorValidator::new, VersionCode.None),
73     DYNAMIC_REF("$dynamicRef", "1051", DynamicRefValidator::new, VersionCode.None),
74     ENUM("enum", "1008", EnumValidator::new, VersionCode.MaxV7),
75     EXCLUSIVE_MAXIMUM("exclusiveMaximum", "1038", ExclusiveMaximumValidator::new, VersionCode.MinV6MaxV7),
76     EXCLUSIVE_MINIMUM("exclusiveMinimum", "1039", ExclusiveMinimumValidator::new, VersionCode.MinV6MaxV7),
77     FALSE("false", "1041", FalseValidator::new, VersionCode.MinV6),
78     FORMAT("format", "1009", null, VersionCode.MaxV7) {
newValidator(SchemaLocation schemaLocation, JsonNodePath evaluationPath, JsonNode schemaNode, JsonSchema parentSchema, ValidationContext validationContext)79         @Override public JsonValidator newValidator(SchemaLocation schemaLocation, JsonNodePath evaluationPath, JsonNode schemaNode, JsonSchema parentSchema, ValidationContext validationContext) {
80             throw new UnsupportedOperationException("Use FormatKeyword instead");
81         }
82     },
83     ID("id", "1036", null, VersionCode.AllVersions),
84     IF_THEN_ELSE("if", "1037", IfValidator::new, VersionCode.V7),
85     ITEMS_202012("items", "1010", ItemsValidator202012::new, VersionCode.None),
86     ITEMS("items", "1010", ItemsValidator::new, VersionCode.MaxV7),
87     MAX_CONTAINS("maxContains", "1006", MinMaxContainsValidator::new, VersionCode.None),
88     MAX_ITEMS("maxItems", "1012", MaxItemsValidator::new, VersionCode.MaxV7),
89     MAX_LENGTH("maxLength", "1013", MaxLengthValidator::new, VersionCode.MaxV7),
90     MAX_PROPERTIES("maxProperties", "1014", MaxPropertiesValidator::new, VersionCode.MaxV7),
91     MAXIMUM("maximum", "1011", MaximumValidator::new, VersionCode.MaxV7),
92     MIN_CONTAINS("minContains", "1049", MinMaxContainsValidator::new, VersionCode.None),
93     MIN_ITEMS("minItems", "1016", MinItemsValidator::new, VersionCode.MaxV7),
94     MIN_LENGTH("minLength", "1017", MinLengthValidator::new, VersionCode.MaxV7),
95     MIN_PROPERTIES("minProperties", "1018", MinPropertiesValidator::new, VersionCode.MaxV7),
96     MINIMUM("minimum", "1015", MinimumValidator::new, VersionCode.MaxV7),
97     MULTIPLE_OF("multipleOf", "1019", MultipleOfValidator::new, VersionCode.MaxV7),
98     NOT_ALLOWED("notAllowed", "1033", NotAllowedValidator::new, VersionCode.AllVersions),
99     NOT("not", "1020", NotValidator::new, VersionCode.MaxV7),
100     ONE_OF("oneOf", "1022", OneOfValidator::new, VersionCode.MaxV7),
101     PATTERN_PROPERTIES("patternProperties", "1024", PatternPropertiesValidator::new, VersionCode.MaxV7),
102     PATTERN("pattern", "1023", PatternValidator::new, VersionCode.MaxV7),
103     PREFIX_ITEMS("prefixItems", "1048", PrefixItemsValidator::new, VersionCode.None),
104     PROPERTIES("properties", "1025", PropertiesValidator::new, VersionCode.MaxV7),
105     PROPERTYNAMES("propertyNames", "1044", PropertyNamesValidator::new, VersionCode.MinV6MaxV7),
106     READ_ONLY("readOnly", "1032", ReadOnlyValidator::new, VersionCode.V7),
107     RECURSIVE_REF("$recursiveRef", "1050", RecursiveRefValidator::new, VersionCode.None),
108     REF("$ref", "1026", RefValidator::new, VersionCode.MaxV7),
109     REQUIRED("required", "1028", RequiredValidator::new, VersionCode.MaxV7),
110     TRUE("true", "1040", TrueValidator::new, VersionCode.MinV6),
111     TYPE("type", "1029", TypeValidator::new, VersionCode.MaxV7),
112     UNEVALUATED_ITEMS("unevaluatedItems", "1021", UnevaluatedItemsValidator::new, VersionCode.None),
113     UNEVALUATED_PROPERTIES("unevaluatedProperties","1047",UnevaluatedPropertiesValidator::new,VersionCode.None),
114     UNION_TYPE("unionType", "1030", UnionTypeValidator::new, VersionCode.None),
115     UNIQUE_ITEMS("uniqueItems", "1031", UniqueItemsValidator::new, VersionCode.MaxV7),
116     WRITE_ONLY("writeOnly", "1027", WriteOnlyValidator::new, VersionCode.V7),
117     ;
118 
119     private static final Map<String, ValidatorTypeCode> CONSTANTS = new HashMap<>();
120 
121     static {
122         for (ValidatorTypeCode c : values()) {
CONSTANTS.put(c.value, c)123             CONSTANTS.put(c.value, c);
124         }
125     }
126 
127     private final String value;
128     private final String errorCode;
129     private final ValidatorFactory validatorFactory;
130     private final VersionCode versionCode;
131 
ValidatorTypeCode(String value, String errorCode, ValidatorFactory validatorFactory, VersionCode versionCode)132     private ValidatorTypeCode(String value, String errorCode, ValidatorFactory validatorFactory, VersionCode versionCode) {
133         this.value = value;
134         this.errorCode = errorCode;
135         this.validatorFactory = validatorFactory;
136         this.versionCode = versionCode;
137     }
138 
getKeywords(SpecVersion.VersionFlag versionFlag)139     public static List<ValidatorTypeCode> getKeywords(SpecVersion.VersionFlag versionFlag) {
140         final List<ValidatorTypeCode> result = new ArrayList<>();
141         for (ValidatorTypeCode keyword : values()) {
142             if (keyword.getVersionCode().getVersions().contains(versionFlag)) {
143                 result.add(keyword);
144             }
145         }
146         return result;
147     }
148 
fromValue(String value)149     public static ValidatorTypeCode fromValue(String value) {
150         ValidatorTypeCode constant = CONSTANTS.get(value);
151         if (constant == null) {
152             throw new IllegalArgumentException(value);
153         }
154         return constant;
155     }
156 
157     @Override
newValidator(SchemaLocation schemaLocation, JsonNodePath evaluationPath, JsonNode schemaNode, JsonSchema parentSchema, ValidationContext validationContext)158     public JsonValidator newValidator(SchemaLocation schemaLocation, JsonNodePath evaluationPath, JsonNode schemaNode,
159             JsonSchema parentSchema, ValidationContext validationContext) {
160         if (this.validatorFactory == null) {
161             throw new UnsupportedOperationException("No suitable validator for " + getValue());
162         }
163         return validatorFactory.newInstance(schemaLocation, evaluationPath, schemaNode, parentSchema,
164                 validationContext);
165     }
166 
167     @Override
toString()168     public String toString() {
169         return this.value;
170     }
171 
172     @Override
getValue()173     public String getValue() {
174         return this.value;
175     }
176 
177     @Override
getErrorCode()178     public String getErrorCode() {
179         return this.errorCode;
180     }
181 
getVersionCode()182     public VersionCode getVersionCode() {
183         return this.versionCode;
184     }
185 
186     @Override
getErrorCodeValue()187     public String getErrorCodeValue() {
188         return getValue();
189     }
190 }
191