• 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.i18n.DefaultMessageSource;
21 import com.networknt.schema.i18n.MessageSource;
22 import com.networknt.schema.walk.DefaultItemWalkListenerRunner;
23 import com.networknt.schema.walk.DefaultKeywordWalkListenerRunner;
24 import com.networknt.schema.walk.DefaultPropertyWalkListenerRunner;
25 import com.networknt.schema.walk.JsonSchemaWalkListener;
26 import com.networknt.schema.walk.WalkListenerRunner;
27 
28 import java.util.ArrayList;
29 import java.util.HashMap;
30 import java.util.List;
31 import java.util.Locale;
32 import java.util.Map;
33 import java.util.Objects;
34 
35 public class SchemaValidatorsConfig {
36     /**
37      * Used to validate the acceptable $id values.
38      */
39     private JsonSchemaIdValidator schemaIdValidator = JsonSchemaIdValidator.DEFAULT;
40 
41     /**
42      * when validate type, if TYPE_LOOSE = true, will try to convert string to
43      * different types to match the type defined in schema.
44      */
45     private boolean typeLoose;
46 
47     /**
48      * When set to true, validator process is stop immediately when a very first
49      * validation error is discovered.
50      */
51     private boolean failFast;
52 
53     /**
54      * When set to true, walker sets nodes that are missing or NullNode to the
55      * default value, if any, and mutate the input json.
56      */
57     private ApplyDefaultsStrategy applyDefaultsStrategy = ApplyDefaultsStrategy.EMPTY_APPLY_DEFAULTS_STRATEGY;
58 
59     /**
60      * When set to true, use ECMA-262 compatible validator
61      */
62     private boolean ecma262Validator;
63 
64     /**
65      * When set to true, use Java-specific semantics rather than native JavaScript
66      * semantics
67      */
68     private boolean javaSemantics;
69 
70     /**
71      * When set to true, can interpret round doubles as integers
72      */
73     private boolean losslessNarrowing;
74 
75     /**
76      * When set to true, "messages" provided in schema are used for forming validation errors
77      * else default messages are used
78      */
79     private boolean isCustomMessageSupported = true;
80 
81     /**
82      * When set to true, support for discriminators is enabled for validations of
83      * oneOf, anyOf and allOf as described on <a href=
84      * "https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.3.md#discriminatorObject">GitHub</a>.
85      */
86     private boolean openAPI3StyleDiscriminators = false;
87 
88     /**
89      * Contains a mapping of how strict a keyword's validators should be.
90      * Defaults to {@literal true}.
91      * <p>
92      * Each validator has its own understanding of what constitutes strict
93      * and permissive.
94      */
95     private final Map<String, Boolean> strictness = new HashMap<>(0);
96 
97     /**
98      * When a field is set as nullable in the OpenAPI specification, the schema
99      * validator validates that it is nullable however continues with validation
100      * against the nullable field
101      * <p>
102      * If handleNullableField is set to true && incoming field is nullable && value
103      * is field: null --> succeed If handleNullableField is set to false && incoming
104      * field is nullable && value is field: null --> it is up to the type validator
105      * using the SchemaValidator to handle it.
106      */
107     private boolean handleNullableField = true;
108 
109     /**
110      * When set to true assumes that schema is used to validate incoming data from an API.
111      */
112     private Boolean readOnly = null;
113 
114     /**
115      * When set to true assumes that schema is used to to validate outgoing data from an API.
116      */
117     private Boolean writeOnly = null;
118 
119     /**
120      * The approach used to generate paths in reported messages, logs and errors. Default is the legacy "JSONPath-like" approach.
121      */
122     private PathType pathType = PathType.DEFAULT;
123 
124     /**
125      * Controls if the schema will automatically be preloaded.
126      */
127     private boolean preloadJsonSchema = true;
128 
129     // This is just a constant for listening to all Keywords.
130     public static final String ALL_KEYWORD_WALK_LISTENER_KEY = "com.networknt.AllKeywordWalkListener";
131 
132     private final Map<String, List<JsonSchemaWalkListener>> keywordWalkListenersMap = new HashMap<>();
133 
134     private final List<JsonSchemaWalkListener> propertyWalkListeners = new ArrayList<>();
135 
136     private final List<JsonSchemaWalkListener> itemWalkListeners = new ArrayList<>();
137 
138     private ExecutionContextCustomizer executionContextCustomizer;
139 
140     private boolean loadCollectors = true;
141 
142     /**
143      * The Locale to consider when loading validation messages from the default resource bundle.
144      */
145     private Locale locale;
146 
147     /**
148      * The message source to use for generating localised messages.
149      */
150     private MessageSource messageSource;
151 
152     /**
153      * Since Draft 2019-09 format assertions are not enabled by default.
154      */
155     private Boolean formatAssertionsEnabled = null;
156 
157     /************************ START OF UNEVALUATED CHECKS **********************************/
158 
159     // These are costly in terms of performance so we provide a way to disable them.
160     private boolean disableUnevaluatedItems = false;
161     private boolean disableUnevaluatedProperties = false;
162 
disableUnevaluatedAnalysis()163     public SchemaValidatorsConfig disableUnevaluatedAnalysis() {
164         disableUnevaluatedItems();
165         disableUnevaluatedProperties();
166         return this;
167     }
168 
disableUnevaluatedItems()169     public SchemaValidatorsConfig disableUnevaluatedItems() {
170         this.disableUnevaluatedItems = true;
171         return this;
172     }
173 
disableUnevaluatedProperties()174     public SchemaValidatorsConfig disableUnevaluatedProperties() {
175         this.disableUnevaluatedProperties = true;
176         return this;
177     }
178 
enableUnevaluatedAnalysis()179     public SchemaValidatorsConfig enableUnevaluatedAnalysis() {
180         enableUnevaluatedItems();
181         enableUnevaluatedProperties();
182         return this;
183     }
184 
enableUnevaluatedItems()185     public SchemaValidatorsConfig enableUnevaluatedItems() {
186         this.disableUnevaluatedItems = false;
187         return this;
188     }
189 
enableUnevaluatedProperties()190     public SchemaValidatorsConfig enableUnevaluatedProperties() {
191         this.disableUnevaluatedProperties = false;
192         return this;
193     }
194 
isUnevaluatedItemsAnalysisDisabled()195     public boolean isUnevaluatedItemsAnalysisDisabled() {
196         return this.disableUnevaluatedItems;
197     }
198 
isUnevaluatedItemsAnalysisEnabled()199     public boolean isUnevaluatedItemsAnalysisEnabled() {
200         return !isUnevaluatedItemsAnalysisDisabled();
201     }
202 
isUnevaluatedPropertiesAnalysisDisabled()203     public boolean isUnevaluatedPropertiesAnalysisDisabled() {
204         return this.disableUnevaluatedProperties;
205     }
206 
isUnevaluatedPropertiesAnalysisEnabled()207     public boolean isUnevaluatedPropertiesAnalysisEnabled() {
208         return !isUnevaluatedPropertiesAnalysisDisabled();
209     }
210 
211     /************************ END OF UNEVALUATED CHECKS **********************************/
212 
213     /**
214      *
215      * @return true if type loose is used.
216      */
isTypeLoose()217     public boolean isTypeLoose() {
218         return this.typeLoose;
219     }
220 
setTypeLoose(boolean typeLoose)221     public void setTypeLoose(boolean typeLoose) {
222         this.typeLoose = typeLoose;
223     }
224 
225     /**
226      * When enabled,
227      * {@link JsonValidator#validate(ExecutionContext, JsonNode, JsonNode, JsonNodePath)}
228      * doesn't return any {@link java.util.Set}&lt;{@link ValidationMessage}&gt;,
229      * instead a {@link JsonSchemaException} is thrown as soon as a validation
230      * errors is discovered.
231      *
232      * @param failFast boolean
233      */
setFailFast(final boolean failFast)234     public void setFailFast(final boolean failFast) {
235         this.failFast = failFast;
236     }
237 
isFailFast()238     public boolean isFailFast() {
239         return this.failFast;
240     }
241 
setApplyDefaultsStrategy(ApplyDefaultsStrategy applyDefaultsStrategy)242     public void setApplyDefaultsStrategy(ApplyDefaultsStrategy applyDefaultsStrategy) {
243         this.applyDefaultsStrategy = applyDefaultsStrategy != null ? applyDefaultsStrategy
244                 : ApplyDefaultsStrategy.EMPTY_APPLY_DEFAULTS_STRATEGY;
245     }
246 
getApplyDefaultsStrategy()247     public ApplyDefaultsStrategy getApplyDefaultsStrategy() {
248         return this.applyDefaultsStrategy;
249     }
250 
isHandleNullableField()251     public boolean isHandleNullableField() {
252         return this.handleNullableField;
253     }
254 
setHandleNullableField(boolean handleNullableField)255     public void setHandleNullableField(boolean handleNullableField) {
256         this.handleNullableField = handleNullableField;
257     }
258 
isEcma262Validator()259     public boolean isEcma262Validator() {
260         return this.ecma262Validator;
261     }
262 
setEcma262Validator(boolean ecma262Validator)263     public void setEcma262Validator(boolean ecma262Validator) {
264         this.ecma262Validator = ecma262Validator;
265     }
266 
isJavaSemantics()267     public boolean isJavaSemantics() {
268         return this.javaSemantics;
269     }
270 
setJavaSemantics(boolean javaSemantics)271     public void setJavaSemantics(boolean javaSemantics) {
272         this.javaSemantics = javaSemantics;
273     }
274 
isCustomMessageSupported()275     public boolean isCustomMessageSupported() {
276         return isCustomMessageSupported;
277     }
278 
setCustomMessageSupported(boolean customMessageSupported)279     public void setCustomMessageSupported(boolean customMessageSupported) {
280         this.isCustomMessageSupported = customMessageSupported;
281     }
282 
addKeywordWalkListener(JsonSchemaWalkListener keywordWalkListener)283     public void addKeywordWalkListener(JsonSchemaWalkListener keywordWalkListener) {
284         if (this.keywordWalkListenersMap.get(ALL_KEYWORD_WALK_LISTENER_KEY) == null) {
285             List<JsonSchemaWalkListener> keywordWalkListeners = new ArrayList<>();
286             this.keywordWalkListenersMap.put(ALL_KEYWORD_WALK_LISTENER_KEY, keywordWalkListeners);
287         }
288         this.keywordWalkListenersMap.get(ALL_KEYWORD_WALK_LISTENER_KEY).add(keywordWalkListener);
289     }
290 
addKeywordWalkListener(String keyword, JsonSchemaWalkListener keywordWalkListener)291     public void addKeywordWalkListener(String keyword, JsonSchemaWalkListener keywordWalkListener) {
292         if (this.keywordWalkListenersMap.get(keyword) == null) {
293             List<JsonSchemaWalkListener> keywordWalkListeners = new ArrayList<>();
294             this.keywordWalkListenersMap.put(keyword, keywordWalkListeners);
295         }
296         this.keywordWalkListenersMap.get(keyword).add(keywordWalkListener);
297     }
298 
addKeywordWalkListeners(List<JsonSchemaWalkListener> keywordWalkListeners)299     public void addKeywordWalkListeners(List<JsonSchemaWalkListener> keywordWalkListeners) {
300         if (this.keywordWalkListenersMap.get(ALL_KEYWORD_WALK_LISTENER_KEY) == null) {
301             List<JsonSchemaWalkListener> ikeywordWalkListeners = new ArrayList<>();
302             this.keywordWalkListenersMap.put(ALL_KEYWORD_WALK_LISTENER_KEY, ikeywordWalkListeners);
303         }
304         this.keywordWalkListenersMap.get(ALL_KEYWORD_WALK_LISTENER_KEY).addAll(keywordWalkListeners);
305     }
306 
addKeywordWalkListeners(String keyword, List<JsonSchemaWalkListener> keywordWalkListeners)307     public void addKeywordWalkListeners(String keyword, List<JsonSchemaWalkListener> keywordWalkListeners) {
308         if (this.keywordWalkListenersMap.get(keyword) == null) {
309             List<JsonSchemaWalkListener> ikeywordWalkListeners = new ArrayList<>();
310             this.keywordWalkListenersMap.put(keyword, ikeywordWalkListeners);
311         }
312         this.keywordWalkListenersMap.get(keyword).addAll(keywordWalkListeners);
313     }
314 
addPropertyWalkListeners(List<JsonSchemaWalkListener> propertyWalkListeners)315     public void addPropertyWalkListeners(List<JsonSchemaWalkListener> propertyWalkListeners) {
316         this.propertyWalkListeners.addAll(propertyWalkListeners);
317     }
318 
addPropertyWalkListener(JsonSchemaWalkListener propertyWalkListener)319     public void addPropertyWalkListener(JsonSchemaWalkListener propertyWalkListener) {
320         this.propertyWalkListeners.add(propertyWalkListener);
321     }
322 
addItemWalkListener(JsonSchemaWalkListener itemWalkListener)323     public void addItemWalkListener(JsonSchemaWalkListener itemWalkListener) {
324         this.itemWalkListeners.add(itemWalkListener);
325     }
326 
addItemWalkListeners(List<JsonSchemaWalkListener> itemWalkListeners)327     public void addItemWalkListeners(List<JsonSchemaWalkListener> itemWalkListeners) {
328         this.itemWalkListeners.addAll(itemWalkListeners);
329     }
330 
getPropertyWalkListeners()331     public List<JsonSchemaWalkListener> getPropertyWalkListeners() {
332         return this.propertyWalkListeners;
333     }
334 
getKeywordWalkListenersMap()335     public Map<String, List<JsonSchemaWalkListener>> getKeywordWalkListenersMap() {
336         return this.keywordWalkListenersMap;
337     }
338 
getArrayItemWalkListeners()339     public List<JsonSchemaWalkListener> getArrayItemWalkListeners() {
340         return this.itemWalkListeners;
341     }
342 
343     private final WalkListenerRunner itemWalkListenerRunner = new DefaultItemWalkListenerRunner(getArrayItemWalkListeners());
344 
getItemWalkListenerRunner()345     WalkListenerRunner getItemWalkListenerRunner() {
346         return this.itemWalkListenerRunner;
347     }
348 
349     private WalkListenerRunner keywordWalkListenerRunner = new DefaultKeywordWalkListenerRunner(getKeywordWalkListenersMap());
350 
getKeywordWalkListenerRunner()351     WalkListenerRunner getKeywordWalkListenerRunner() {
352         return this.keywordWalkListenerRunner;
353     }
354 
355     private WalkListenerRunner propertyWalkListenerRunner = new DefaultPropertyWalkListenerRunner(getPropertyWalkListeners());
356 
getPropertyWalkListenerRunner()357     WalkListenerRunner getPropertyWalkListenerRunner() {
358         return this.propertyWalkListenerRunner;
359     }
360 
SchemaValidatorsConfig()361     public SchemaValidatorsConfig() {
362     }
363 
getExecutionContextCustomizer()364     public ExecutionContextCustomizer getExecutionContextCustomizer() {
365         return this.executionContextCustomizer;
366     }
367 
setExecutionContextCustomizer(ExecutionContextCustomizer executionContextCustomizer)368     public void setExecutionContextCustomizer(ExecutionContextCustomizer executionContextCustomizer) {
369         this.executionContextCustomizer = executionContextCustomizer;
370     }
371 
isLosslessNarrowing()372     public boolean isLosslessNarrowing() {
373         return this.losslessNarrowing;
374     }
375 
setLosslessNarrowing(boolean losslessNarrowing)376     public void setLosslessNarrowing(boolean losslessNarrowing) {
377         this.losslessNarrowing = losslessNarrowing;
378     }
379 
380     /**
381      * Indicates whether OpenAPI 3 style discriminators should be supported
382      *
383      * @return true in case discriminators are enabled
384      * @since 1.0.51
385      */
isOpenAPI3StyleDiscriminators()386     public boolean isOpenAPI3StyleDiscriminators() {
387         return this.openAPI3StyleDiscriminators;
388     }
389 
390     /**
391      * When enabled, the validation of <code>anyOf</code> and <code>allOf</code> in
392      * polymorphism will respect OpenAPI 3 style discriminators as described in the
393      * <a href=
394      * "https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.3.md#discriminatorObject">OpenAPI
395      * 3.0.3 spec</a>. The presence of a discriminator configuration on the schema
396      * will lead to the following changes in the behavior:
397      * <ul>
398      * <li>for <code>oneOf</code> the spec is unfortunately very vague. Whether
399      * <code>oneOf</code> semantics should be affected by discriminators or not is
400      * not even 100% clear within the members of the OAS steering committee.
401      * Therefore <code>oneOf</code> at the moment ignores discriminators</li>
402      * <li>for <code>anyOf</code> the validation will choose one of the candidate
403      * schemas for validation based on the discriminator property value and will
404      * pass validation when this specific schema passes. This is in particular
405      * useful when the payload could match multiple candidates in the
406      * <code>anyOf</code> list and could lead to ambiguity. Example: type B has all
407      * mandatory properties of A and adds more mandatory ones. Whether the payload
408      * is an A or B is determined via the discriminator property name. A payload
409      * indicating it is an instance of B then requires passing the validation of B
410      * and passing the validation of A would not be sufficient anymore.</li>
411      * <li>for <code>allOf</code> use cases with discriminators defined on the
412      * copied-in parent type, it is possible to automatically validate against a
413      * subtype. Example: some schema specifies that there is a field of type A. A
414      * carries a discriminator field and B inherits from A. Then B is automatically
415      * a candidate for validation as well and will be chosen in case the
416      * discriminator property matches</li>
417      * </ul>
418      *
419      * @param openAPI3StyleDiscriminators whether or not discriminators should be
420      *                                    used. Defaults to <code>false</code>
421      * @since 1.0.51
422      */
setOpenAPI3StyleDiscriminators(boolean openAPI3StyleDiscriminators)423     public void setOpenAPI3StyleDiscriminators(boolean openAPI3StyleDiscriminators) {
424         this.openAPI3StyleDiscriminators = openAPI3StyleDiscriminators;
425     }
426 
setLoadCollectors(boolean loadCollectors)427     public void setLoadCollectors(boolean loadCollectors) {
428         this.loadCollectors = loadCollectors;
429     }
430 
doLoadCollectors()431     public boolean doLoadCollectors() {
432         return this.loadCollectors;
433     }
434 
isReadOnly()435     public boolean isReadOnly() {
436         return null != this.readOnly && this.readOnly;
437     }
438 
setReadOnly(boolean readOnly)439     public void setReadOnly(boolean readOnly) {
440         this.readOnly = readOnly;
441     }
442 
isWriteOnly()443     public boolean isWriteOnly() {
444         return null != this.writeOnly && this.writeOnly;
445     }
446 
setWriteOnly(boolean writeOnly)447     public void setWriteOnly(boolean writeOnly) {
448         this.writeOnly = writeOnly;
449     }
450 
451     /**
452      * Use {@code isReadOnly} or {@code isWriteOnly}
453      * @return true if schema is used to write data
454      */
455     @Deprecated
isWriteMode()456     public boolean isWriteMode() {
457         return null == this.writeOnly || this.writeOnly;
458     }
459 
460     /**
461      * Set the approach used to generate paths in messages, logs and errors (default is PathType.LEGACY).
462      *
463      * @param pathType The path generation approach.
464      */
setPathType(PathType pathType)465     public void setPathType(PathType pathType) {
466         this.pathType = pathType;
467     }
468 
469     /**
470      * Get the approach used to generate paths in messages, logs and errors.
471      *
472      * @return The path generation approach.
473      */
getPathType()474     public PathType getPathType() {
475         return this.pathType;
476     }
477 
478     /**
479      * Answers whether a keyword's validators may relax their analysis. The
480      * default is to perform strict checking. One must explicitly allow a
481      * validator to be more permissive.
482      * <p>
483      * Each validator has its own understanding of what is permissive and
484      * strict. Consult the keyword's documentation for details.
485      *
486      * @param keyword the keyword to adjust (not null)
487      * @return Whether to perform a strict validation.
488      */
isStrict(String keyword)489     public boolean isStrict(String keyword) {
490         return isStrict(keyword, Boolean.TRUE);
491     }
492 
493     /**
494      * Determines if the validator should perform strict checking.
495      *
496      * @param keyword the keyword
497      * @param defaultValue the default value
498      * @return whether to perform a strict validation
499      */
isStrict(String keyword, Boolean defaultValue)500     public boolean isStrict(String keyword, Boolean defaultValue) {
501         return this.strictness.getOrDefault(Objects.requireNonNull(keyword, "keyword cannot be null"), defaultValue);
502     }
503 
504     /**
505      * Alters the strictness of validations for a specific keyword. When set to
506      * {@literal true}, instructs the keyword's validators to perform strict
507      * validation. Otherwise, a validator may perform a more permissive check.
508      *
509      * @param keyword The keyword to adjust (not null)
510      * @param strict Whether to perform strict validations
511      */
setStrict(String keyword, boolean strict)512     public void setStrict(String keyword, boolean strict) {
513         this.strictness.put(Objects.requireNonNull(keyword, "keyword cannot be null"), strict);
514     }
515 
516     /**
517      * Get the locale to consider when generating localised messages (default is the
518      * JVM default).
519      * <p>
520      * This locale is on a schema basis and will be used as the default locale for
521      * {@link com.networknt.schema.ExecutionConfig}.
522      *
523      * @return The locale.
524      */
getLocale()525     public Locale getLocale() {
526         if (this.locale == null) {
527             // This should not be cached as it can be changed using Locale#setDefault(Locale)
528             return Locale.getDefault();
529         }
530         return this.locale;
531     }
532 
533     /**
534      * Set the locale to consider when generating localised messages.
535      * <p>
536      * Note that this locale is set on a schema basis. To configure the schema on a
537      * per execution basis use
538      * {@link com.networknt.schema.ExecutionConfig#setLocale(Locale)}.
539      *
540      * @param locale The locale.
541      */
setLocale(Locale locale)542     public void setLocale(Locale locale) {
543         this.locale = locale;
544     }
545 
546     /**
547      * Get the message source to use for generating localised messages.
548      *
549      * @return the message source
550      */
getMessageSource()551     public MessageSource getMessageSource() {
552         if (this.messageSource == null) {
553             return DefaultMessageSource.getInstance();
554         }
555         return this.messageSource;
556     }
557 
558     /**
559      * Set the message source to use for generating localised messages.
560      *
561      * @param messageSource the message source
562      */
setMessageSource(MessageSource messageSource)563     public void setMessageSource(MessageSource messageSource) {
564         this.messageSource = messageSource;
565     }
566 
567     /**
568      * Gets the format assertion enabled flag.
569      * <p>
570      * This defaults to null meaning that it will follow the defaults of the
571      * specification.
572      * <p>
573      * Since draft 2019-09 this will default to false unless enabled by using the
574      * $vocabulary keyword.
575      *
576      * @return the format assertions enabled flag
577      */
getFormatAssertionsEnabled()578     public Boolean getFormatAssertionsEnabled() {
579         return formatAssertionsEnabled;
580     }
581 
582     /**
583      * Sets the format assertion enabled flag.
584      *
585      * @param formatAssertionsEnabled the format assertions enabled flag
586      */
setFormatAssertionsEnabled(Boolean formatAssertionsEnabled)587     public void setFormatAssertionsEnabled(Boolean formatAssertionsEnabled) {
588         this.formatAssertionsEnabled = formatAssertionsEnabled;
589     }
590 
591     /**
592      * Gets the schema id validator to validate $id.
593      *
594      * @return the validator
595      */
getSchemaIdValidator()596     public JsonSchemaIdValidator getSchemaIdValidator() {
597         return schemaIdValidator;
598     }
599 
600     /**
601      * Sets the schema id validator to validate $id.
602      *
603      * @param schemaIdValidator the validator
604      */
setSchemaIdValidator(JsonSchemaIdValidator schemaIdValidator)605     public void setSchemaIdValidator(JsonSchemaIdValidator schemaIdValidator) {
606         this.schemaIdValidator = schemaIdValidator;
607     }
608 
609     /**
610      * Gets if the schema should be preloaded.
611      *
612      * @return true if it should be preloaded
613      */
isPreloadJsonSchema()614     public boolean isPreloadJsonSchema() {
615         return preloadJsonSchema;
616     }
617 
618     /**
619      * Sets if the schema should be preloaded.
620      *
621      * @param preloadJsonSchema true to preload
622      */
setPreloadJsonSchema(boolean preloadJsonSchema)623     public void setPreloadJsonSchema(boolean preloadJsonSchema) {
624         this.preloadJsonSchema = preloadJsonSchema;
625     }
626 }
627