Repository: networknt/json-schema-validator
Pull request #1084 (2024-07-03 06:03:45)

Fix activeDialect for custom meta schema
Fixes the activeDialect for custom meta schema to return the specification instead of attempting to determine from the iri.

codecov-commenter: :warning: Please install the !['codecov app svg image'](https://github.com/codecov/engineering-team/assets/152432831/e90313f4-9d3a-4b63-8b54-cfe14e7ec20d) to ensure uploads and comments are reliably processed by Codecov.

## [Codecov](https://app.codecov.io/gh/networknt/json-schema-validator/pull/1084?dropdown=coverage&src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=networknt) Report
All modified and coverable lines are covered by tests :white_check_mark:
> Project coverage is 78.06%. Comparing base [(`48ca3c2`)](https://app.codecov.io/gh/networknt/json-schema-validator/commit/48ca3c22995e32797e9defdb8b77869f0d15caf3?dropdown=coverage&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=networknt) to head [(`1719414`)](https://app.codecov.io/gh/networknt/json-schema-validator/commit/17194148e973e846f9bddbe51c5675ad30e0ce9b?dropdown=coverage&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=networknt).
> Report is 46 commits behind head on master.

:exclamation: Your organization needs to install the [Codecov GitHub app](https://github.com/apps/codecov/installations/select_target) to enable full functionality.

<details><summary>Additional details and impacted files</summary>


```diff
@@             Coverage Diff              @@
##             master    #1084      +/-   ##
============================================
- Coverage     78.90%   78.06%   -0.85%     
- Complexity     1965     2065     +100     
============================================
  Files           172      201      +29     
  Lines          6352     6878     +526     
  Branches       1255     1257       +2     
============================================
+ Hits           5012     5369     +357     
- Misses          867     1032     +165     
- Partials        473      477       +4     
```

</details>

[:umbrella: View full report in Codecov by Sentry](https://app.codecov.io/gh/networknt/json-schema-validator/pull/1084?dropdown=coverage&src=pr&el=continue&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=networknt).   
:loudspeaker: Have feedback on the report? [Share it here](https://about.codecov.io/codecov-pr-comment-feedback/?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=networknt).


Patch:
diff --git a/doc/quickstart.md b/doc/quickstart.md
index d66c07a..f427e7b 100644
--- a/doc/quickstart.md
+++ b/doc/quickstart.md
@@ -55,7 +55,7 @@ public class SampleTest {
 
     @Test
     void schemaFromSchemaLocationContent() throws JsonMappingException, JsonProcessingException {
-        String schemaData = "{\"enum\":[1, 2, 3, 4],\"enumErrorCode\":\"Not in the list\"}";
+        String schemaData = "{\"enum\":[1, 2, 3, 4]}";
         
         JsonSchemaFactory factory = JsonSchemaFactory.getInstance(VersionFlag.V202012,
                 builder -> builder.schemaLoaders(schemaLoaders -> schemaLoaders.schemas(
@@ -107,7 +107,7 @@ public class SampleTest {
          * resolving relative $ref.
          */
         JsonSchema schemaFromString = factory
-                .getSchema("{\"enum\":[1, 2, 3, 4],\"enumErrorCode\":\"Not in the list\"}");
+                .getSchema("{\"enum\":[1, 2, 3, 4]}");
         Set<ValidationMessage> errors = schemaFromString.validate("7", InputFormat.JSON,
                 executionContext -> executionContext.getExecutionConfig().setFormatAssertionsEnabled(true));
         assertEquals(1, errors.size());
diff --git a/src/main/java/com/networknt/schema/JsonSchema.java b/src/main/java/com/networknt/schema/JsonSchema.java
index 0345974..61a453b 100644
--- a/src/main/java/com/networknt/schema/JsonSchema.java
+++ b/src/main/java/com/networknt/schema/JsonSchema.java
@@ -369,7 +369,7 @@ public class JsonSchema extends BaseJsonValidator {
             Object segment = fragment.getElement(x);
             JsonNode subSchemaNode = getNode(parentNode, segment);
             if (subSchemaNode != null) {
-                if (segment instanceof Number) {
+                if (segment instanceof Number && parentNode.isArray()) {
                     int index = ((Number) segment).intValue();
                     schemaLocation = schemaLocation.append(index);
                     evaluationPath = evaluationPath.append(index);
diff --git a/src/main/java/com/networknt/schema/UnevaluatedItemsValidator.java b/src/main/java/com/networknt/schema/UnevaluatedItemsValidator.java
index 49419f2..1794ce6 100644
--- a/src/main/java/com/networknt/schema/UnevaluatedItemsValidator.java
+++ b/src/main/java/com/networknt/schema/UnevaluatedItemsValidator.java
@@ -44,8 +44,7 @@ public class UnevaluatedItemsValidator extends BaseJsonValidator {
             JsonSchema parentSchema, ValidationContext validationContext) {
         super(schemaLocation, evaluationPath, schemaNode, parentSchema, ValidatorTypeCode.UNEVALUATED_ITEMS,
                 validationContext);
-        isMinV202012 = MinV202012.getVersions().contains(SpecVersionDetector
-                .detectOptionalVersion(validationContext.getMetaSchema().getIri()).orElse(DEFAULT_VERSION));
+        isMinV202012 = MinV202012.getVersions().contains(validationContext.activeDialect().orElse(DEFAULT_VERSION));
         if (schemaNode.isObject() || schemaNode.isBoolean()) {
             this.schema = validationContext.newSchema(schemaLocation, evaluationPath, schemaNode, parentSchema);
         } else {
diff --git a/src/main/java/com/networknt/schema/ValidationContext.java b/src/main/java/com/networknt/schema/ValidationContext.java
index f4d6e12..d35b29b 100644
--- a/src/main/java/com/networknt/schema/ValidationContext.java
+++ b/src/main/java/com/networknt/schema/ValidationContext.java
@@ -107,7 +107,6 @@ public class ValidationContext {
     }
 
     public Optional<VersionFlag> activeDialect() {
-        String metaSchema = getMetaSchema().getIri();
-        return SpecVersionDetector.detectOptionalVersion(metaSchema);
+        return Optional.of(this.metaSchema.getSpecification());
     }
 }
diff --git a/src/main/java/com/networknt/schema/ValidationMessageHandler.java b/src/main/java/com/networknt/schema/ValidationMessageHandler.java
index 727683c..7fd2688 100644
--- a/src/main/java/com/networknt/schema/ValidationMessageHandler.java
+++ b/src/main/java/com/networknt/schema/ValidationMessageHandler.java
@@ -2,7 +2,6 @@ package com.networknt.schema;
 
 import com.fasterxml.jackson.databind.JsonNode;
 import com.networknt.schema.i18n.MessageSource;
-import com.networknt.schema.utils.StringUtils;
 
 import java.util.Collections;
 import java.util.LinkedHashMap;
@@ -26,7 +25,7 @@ public abstract class ValidationMessageHandler {
     protected ValidationMessageHandler(ErrorMessageType errorMessageType, String errorMessageKeyword,
             MessageSource messageSource, Keyword keyword, JsonSchema parentSchema, SchemaLocation schemaLocation,
             JsonNodePath evaluationPath) {
-        ErrorMessageType currentErrorMessageType = errorMessageType;
+        this.errorMessageType = errorMessageType;
         this.messageSource = messageSource;
         this.schemaLocation = Objects.requireNonNull(schemaLocation);
         this.evaluationPath = Objects.requireNonNull(evaluationPath);
@@ -36,24 +35,12 @@ public abstract class ValidationMessageHandler {
         this.keyword = keyword;
 
         Map<String, String> currentErrorMessage = null;
-
         if (this.keyword != null) {
             if (this.errorMessageKeyword != null && keyword != null && parentSchema != null) {
                 currentErrorMessage = getErrorMessage(this.errorMessageKeyword, parentSchema.getSchemaNode(),
                         keyword.getValue());
             }
-            String errorCodeKey = getErrorCodeKey(keyword.getValue());
-            if (errorCodeKey != null && this.parentSchema != null) {
-                JsonNode errorCodeNode = this.parentSchema.getSchemaNode().get(errorCodeKey);
-                if (errorCodeNode != null && errorCodeNode.isTextual()) {
-                    String errorCodeText = errorCodeNode.asText();
-                    if (StringUtils.isNotBlank(errorCodeText)) {
-                        currentErrorMessageType = CustomErrorMessageType.of(errorCodeText);
-                    }
-                }
-            }
         }
-        this.errorMessageType = currentErrorMessageType;
         this.errorMessage = currentErrorMessage;
     }
 
@@ -143,11 +130,4 @@ public abstract class ValidationMessageHandler {
         }
         return messageNode;
     }
-
-    protected String getErrorCodeKey(String keyword) {
-        if (keyword != null) {
-            return keyword + "ErrorCode";
-        }
-        return null;
-    }
 }
diff --git a/src/main/java/com/networknt/schema/utils/JsonNodeUtil.java b/src/main/java/com/networknt/schema/utils/JsonNodeUtil.java
index 07c3b91..d480ee7 100644
--- a/src/main/java/com/networknt/schema/utils/JsonNodeUtil.java
+++ b/src/main/java/com/networknt/schema/utils/JsonNodeUtil.java
@@ -131,10 +131,7 @@ public class JsonNodeUtil {
     }
 
     private static long detectVersion(ValidationContext validationContext) {
-        String metaSchema = validationContext.getMetaSchema().getIri();
-        return SpecVersionDetector.detectOptionalVersion(metaSchema)
-            .orElse(VersionFlag.V4)
-            .getVersionFlagValue();
+        return validationContext.activeDialect().orElse(VersionFlag.V4).getVersionFlagValue();
     }
 
     /**


Test patch:
diff --git a/src/test/java/com/networknt/schema/SampleTest.java b/src/test/java/com/networknt/schema/SampleTest.java
index 9a74b21..418bb06 100644
--- a/src/test/java/com/networknt/schema/SampleTest.java
+++ b/src/test/java/com/networknt/schema/SampleTest.java
@@ -39,7 +39,7 @@ public class SampleTest {
 
     @Test
     void schemaFromSchemaLocationContent() throws JsonMappingException, JsonProcessingException {
-        String schemaData = "{\"enum\":[1, 2, 3, 4],\"enumErrorCode\":\"Not in the list\"}";
+        String schemaData = "{\"enum\":[1, 2, 3, 4]}";
         
         JsonSchemaFactory factory = JsonSchemaFactory.getInstance(VersionFlag.V202012,
                 builder -> builder.schemaLoaders(schemaLoaders -> schemaLoaders.schemas(
@@ -91,7 +91,7 @@ public class SampleTest {
          * resolving relative $ref.
          */
         JsonSchema schemaFromString = factory
-                .getSchema("{\"enum\":[1, 2, 3, 4],\"enumErrorCode\":\"Not in the list\"}");
+                .getSchema("{\"enum\":[1, 2, 3, 4]}");
         Set<ValidationMessage> errors = schemaFromString.validate("7", InputFormat.JSON,
                 executionContext -> executionContext.getExecutionConfig().setFormatAssertionsEnabled(true));
         assertEquals(1, errors.size());
diff --git a/src/test/java/com/networknt/schema/VocabularyTest.java b/src/test/java/com/networknt/schema/VocabularyTest.java
index 84a9b4f..3c42ad0 100644
--- a/src/test/java/com/networknt/schema/VocabularyTest.java
+++ b/src/test/java/com/networknt/schema/VocabularyTest.java
@@ -82,6 +82,7 @@ public class VocabularyTest {
         messages = schema.validate(inputDataNoValidation, InputFormat.JSON);
         assertEquals(1, messages.size());
         assertEquals("minimum", messages.iterator().next().getType());
+        assertEquals(VersionFlag.V202012, schema.getValidationContext().activeDialect().get());
     }
 
     @Test
diff --git a/src/test/java/com/networknt/schema/oas/OpenApi30Test.java b/src/test/java/com/networknt/schema/oas/OpenApi30Test.java
index e00abb4..91526ea 100644
--- a/src/test/java/com/networknt/schema/oas/OpenApi30Test.java
+++ b/src/test/java/com/networknt/schema/oas/OpenApi30Test.java
@@ -28,7 +28,9 @@ import com.networknt.schema.DisallowUnknownJsonMetaSchemaFactory;
 import com.networknt.schema.InputFormat;
 import com.networknt.schema.JsonSchema;
 import com.networknt.schema.JsonSchemaFactory;
+import com.networknt.schema.PathType;
 import com.networknt.schema.SchemaLocation;
+import com.networknt.schema.SchemaValidatorsConfig;
 import com.networknt.schema.SpecVersion.VersionFlag;
 import com.networknt.schema.ValidationMessage;
 
@@ -74,7 +76,10 @@ class OpenApi30Test {
         JsonSchemaFactory factory = JsonSchemaFactory.getInstance(VersionFlag.V7, builder -> builder
                 .metaSchema(OpenApi30.getInstance()).defaultMetaSchemaIri(OpenApi30.getInstance().getIri()));
         JsonSchema schema = factory.getSchema(SchemaLocation.of(
-                "classpath:schema/oas/3.0/petstore.yaml#/paths/~1pet/post/responses/200/content/application~1json/schema"));
+                "classpath:schema/oas/3.0/petstore.yaml#/paths/~1pet/post/responses/200/content/application~1json/schema"),
+                SchemaValidatorsConfig.builder().pathType(PathType.JSON_PATH).build());
         assertNotNull(schema);
+        assertEquals("$.paths['/pet'].post.responses['200'].content['application/json'].schema",
+                schema.getEvaluationPath().toString());
     }
 }