diff --git a/src/main/java/com/networknt/schema/SpecVersionDetector.java b/src/main/java/com/networknt/schema/SpecVersionDetector.java index 1d708414a..7be7ac29b 100644 --- a/src/main/java/com/networknt/schema/SpecVersionDetector.java +++ b/src/main/java/com/networknt/schema/SpecVersionDetector.java @@ -18,49 +18,69 @@ import com.fasterxml.jackson.databind.JsonNode; +import java.util.Optional; + /** * This class is used to detect schema version * * @author Subhajitdas298 * @since 25/06/20 */ -public class SpecVersionDetector { +public final class SpecVersionDetector { private static final String SCHEMA_TAG = "$schema"; + private SpecVersionDetector() { + // Prevent instantiation of this utility class + } + /** - * Detects schema version based on the schema tag + * Detects schema version based on the schema tag: if the schema tag is not present, throws + * {@link JsonSchemaException} with the corresponding message, otherwise - returns the detected spec version. * - * @param jsonNode Json Node to read from - * @return Spec version + * @param jsonNode JSON Node to read from + * @return Spec version if present, otherwise throws an exception */ public static SpecVersion.VersionFlag detect(JsonNode jsonNode) { - JsonNode schemaTag = jsonNode.get(SCHEMA_TAG); - if (schemaTag == null) { - throw new JsonSchemaException("'" + SCHEMA_TAG + "' tag is not present"); - } + return detectOptionalVersion(jsonNode).orElseThrow( + () -> new JsonSchemaException("'" + SCHEMA_TAG + "' tag is not present") + ); + } + + /** + * Detects schema version based on the schema tag: if the schema tag is not present, returns an empty {@link + * Optional} value, otherwise - returns the detected spec version wrapped into {@link Optional}. + * + * @param jsonNode JSON Node to read from + * @return Spec version if present, otherwise empty + */ + public static Optional detectOptionalVersion(JsonNode jsonNode) { + return Optional.ofNullable(jsonNode.get(SCHEMA_TAG)).map(schemaTag -> { + + final boolean forceHttps = true; + final boolean removeEmptyFragmentSuffix = true; - final boolean forceHttps = true; - final boolean removeEmptyFragmentSuffix = true; + String schemaTagValue = schemaTag.asText(); + String schemaUri = JsonSchemaFactory.normalizeMetaSchemaUri(schemaTagValue, forceHttps, + removeEmptyFragmentSuffix); - String schemaTagValue = schemaTag.asText(); - String schemaUri = JsonSchemaFactory.normalizeMetaSchemaUri(schemaTagValue, forceHttps, removeEmptyFragmentSuffix); - if (schemaUri.equals(JsonMetaSchema.getV4().getUri())) { - return SpecVersion.VersionFlag.V4; - } - if (schemaUri.equals(JsonMetaSchema.getV6().getUri())) { - return SpecVersion.VersionFlag.V6; - } - if (schemaUri.equals(JsonMetaSchema.getV7().getUri())) { - return SpecVersion.VersionFlag.V7; - } - if (schemaUri.equals(JsonMetaSchema.getV201909().getUri())) { - return SpecVersion.VersionFlag.V201909; - } - if (schemaUri.equals(JsonMetaSchema.getV202012().getUri())) { - return SpecVersion.VersionFlag.V202012; - } - throw new JsonSchemaException("'" + schemaTagValue + "' is unrecognizable schema"); + if (schemaUri.equals(JsonMetaSchema.getV4().getUri())) { + return SpecVersion.VersionFlag.V4; + } + if (schemaUri.equals(JsonMetaSchema.getV6().getUri())) { + return SpecVersion.VersionFlag.V6; + } + if (schemaUri.equals(JsonMetaSchema.getV7().getUri())) { + return SpecVersion.VersionFlag.V7; + } + if (schemaUri.equals(JsonMetaSchema.getV201909().getUri())) { + return SpecVersion.VersionFlag.V201909; + } + if (schemaUri.equals(JsonMetaSchema.getV202012().getUri())) { + return SpecVersion.VersionFlag.V202012; + } + throw new JsonSchemaException("'" + schemaTagValue + "' is unrecognizable schema"); + }); } } diff --git a/src/test/java/com/networknt/schema/SpecVersionDetectorTest.java b/src/test/java/com/networknt/schema/SpecVersionDetectorTest.java index 6433709b1..13a689f1e 100644 --- a/src/test/java/com/networknt/schema/SpecVersionDetectorTest.java +++ b/src/test/java/com/networknt/schema/SpecVersionDetectorTest.java @@ -2,11 +2,13 @@ import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; +import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.CsvSource; import java.io.IOException; import java.io.InputStream; +import java.util.Optional; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertThrows; @@ -42,4 +44,13 @@ void detectInvalidSchemaVersion(String schemaPath, String expectedError) throws JsonSchemaException exception = assertThrows(JsonSchemaException.class, () -> SpecVersionDetector.detect(node)); assertEquals(expectedError, exception.getMessage()); } -} \ No newline at end of file + + @Test + void detectOptionalSpecVersion() throws IOException { + InputStream in = Thread.currentThread().getContextClassLoader().getResourceAsStream( + "data/schemaTagMissing.json"); + JsonNode node = mapper.readTree(in); + Optional flag = SpecVersionDetector.detectOptionalVersion(node); + assertEquals(Optional.empty(), flag); + } +}