From e4a7af3abb9a471f8c18a90ed6d167a34bc4a722 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Klas=20Kala=C3=9F?= Date: Wed, 22 Nov 2017 16:24:09 +0100 Subject: [PATCH] Improved handling for unknown keywords --- .../com/networknt/schema/JsonMetaSchema.java | 18 ++++++++-- .../networknt/schema/JsonSchemaFactory.java | 7 ++-- .../schema/NonValidationKeyword.java | 33 +++++++++++++++++++ 3 files changed, 54 insertions(+), 4 deletions(-) create mode 100644 src/main/java/com/networknt/schema/NonValidationKeyword.java diff --git a/src/main/java/com/networknt/schema/JsonMetaSchema.java b/src/main/java/com/networknt/schema/JsonMetaSchema.java index 1855cfe14..8fc64aaa8 100644 --- a/src/main/java/com/networknt/schema/JsonMetaSchema.java +++ b/src/main/java/com/networknt/schema/JsonMetaSchema.java @@ -18,12 +18,14 @@ import java.lang.reflect.InvocationTargetException; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Optional; +import java.util.concurrent.ConcurrentHashMap; import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; @@ -36,7 +38,7 @@ public class JsonMetaSchema { private static final Logger logger = LoggerFactory .getLogger(JsonMetaSchema.class); - + private static Map UNKNOWN_KEYWORDS = new ConcurrentHashMap(); private static class DraftV4 { private static String URI = "http://json-schema.org/draft-04/schema#"; @@ -76,6 +78,15 @@ public static JsonMetaSchema getInstance() { .idKeyword(DRAFT_4_ID) .addFormats(BUILTIN_FORMATS) .addKeywords(ValidatorTypeCode.getNonFormatKeywords()) + // keywords that may validly exist, but have no validation aspect to them + .addKeywords(Arrays.asList( + new NonValidationKeyword("$schema"), + new NonValidationKeyword("id"), + new NonValidationKeyword("title"), + new NonValidationKeyword("description"), + new NonValidationKeyword("default"), + new NonValidationKeyword("definitions") + )) .build(); } } @@ -221,7 +232,10 @@ public Optional newValidator(ValidationContext validationContext, try { Keyword kw = keywords.get(keyword); if (kw == null) { - logger.warn("Unknown keyword " + keyword); + if (!UNKNOWN_KEYWORDS.containsKey(keyword)) { + UNKNOWN_KEYWORDS.put(keyword, keyword); + logger.warn("Unknown keyword " + keyword + " - you should define your own Meta Schema. If the keyword is irrelevant for validation, just use a NonValidationKeyword"); + } return Optional.empty(); } return Optional.of(kw.newValidator(schemaPath, schemaNode, parentSchema, validationContext)); diff --git a/src/main/java/com/networknt/schema/JsonSchemaFactory.java b/src/main/java/com/networknt/schema/JsonSchemaFactory.java index c3deef8c6..fa67982a4 100644 --- a/src/main/java/com/networknt/schema/JsonSchemaFactory.java +++ b/src/main/java/com/networknt/schema/JsonSchemaFactory.java @@ -214,8 +214,11 @@ private boolean idMatchesSourceUrl(JsonMetaSchema metaSchema, JsonNode schema, U if (id == null || id.isEmpty()) { return false; } - logger.info("Matching " + id + " to " + schemaUrl.toString()); - return id.equals(schemaUrl.toString()); + boolean result = id.equals(schemaUrl.toString()); + if (logger.isDebugEnabled()) { + logger.debug("Matching " + id + " to " + schemaUrl.toString() + ": " + result); + } + return result; } diff --git a/src/main/java/com/networknt/schema/NonValidationKeyword.java b/src/main/java/com/networknt/schema/NonValidationKeyword.java new file mode 100644 index 000000000..0a0e06587 --- /dev/null +++ b/src/main/java/com/networknt/schema/NonValidationKeyword.java @@ -0,0 +1,33 @@ +package com.networknt.schema; + +import java.util.Collections; +import java.util.Set; + +import com.fasterxml.jackson.databind.JsonNode; + +/** + * Used for Keywords that have no validation aspect, but are part of the metaschema. + */ +public class NonValidationKeyword extends AbstractKeyword { + + private static final class Validator extends AbstractJsonValidator { + private Validator(String keyword) { + super(keyword); + } + + @Override + public Set validate(JsonNode node, JsonNode rootNode, String at) { + return Collections.emptySet(); + } + } + + public NonValidationKeyword(String keyword) { + super(keyword); + } + + @Override + public JsonValidator newValidator(String schemaPath, JsonNode schemaNode, JsonSchema parentSchema, + ValidationContext validationContext) throws JsonSchemaException, Exception { + return new Validator(getValue()); + } +}