Repository: networknt/json-schema-validator
Pull request #152 (2019-05-28 01:07:57)

fixes issue #151
add new format validator for uuid:

format: uuid


Patch:
diff --git a/src/main/java/com/networknt/schema/FormatKeyword.java b/src/main/java/com/networknt/schema/FormatKeyword.java
index 9344bc1..91d062e 100644
--- a/src/main/java/com/networknt/schema/FormatKeyword.java
+++ b/src/main/java/com/networknt/schema/FormatKeyword.java
@@ -28,6 +28,7 @@ public class FormatKeyword implements Keyword {
 
     private final String DATE = "date";
     private final String DATE_TIME = "date-time";
+    private final String UUID = "uuid";
 
     public FormatKeyword(ValidatorTypeCode type, Map<String, Format> formats) {
         this.type = type;
@@ -48,6 +49,8 @@ public class FormatKeyword implements Keyword {
             // Validate date and time separately
             if (formatName.equals(DATE) || formatName.equals(DATE_TIME)) {
                 return new DateTimeValidator(schemaPath, schemaNode, parentSchema, validationContext, formatName);
+            } else if (formatName.equals(UUID)) {
+                return new UUIDValidator(schemaPath, schemaNode, parentSchema, validationContext, formatName);
             }
         }
         return new FormatValidator(schemaPath, schemaNode, parentSchema, validationContext, format);
diff --git a/src/main/java/com/networknt/schema/UUIDValidator.java b/src/main/java/com/networknt/schema/UUIDValidator.java
new file mode 100644
index 0000000..49fda9f
--- /dev/null
+++ b/src/main/java/com/networknt/schema/UUIDValidator.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2016 Network New Technologies Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.networknt.schema;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.text.ParsePosition;
+import java.text.SimpleDateFormat;
+import java.util.Collections;
+import java.util.LinkedHashSet;
+import java.util.Set;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+public class UUIDValidator extends BaseJsonValidator implements JsonValidator {
+    private static final Logger logger = LoggerFactory.getLogger(UUIDValidator.class);
+
+    private final String formatName;
+
+
+    private static final String regex = "^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$";
+
+    public UUIDValidator(String schemaPath, JsonNode schemaNode, JsonSchema parentSchema, ValidationContext validationContext, String formatName) {
+        super(schemaPath, schemaNode, parentSchema, ValidatorTypeCode.DATETIME, validationContext);
+        this.formatName = formatName;
+        parseErrorCode(getValidatorType().getErrorCodeKey());
+    }
+
+    public Set<ValidationMessage> validate(JsonNode node, JsonNode rootNode, String at) {
+        debug(logger, node, rootNode, at);
+
+        Set<ValidationMessage> errors = new LinkedHashSet<ValidationMessage>();
+
+        JsonType nodeType = TypeFactory.getValueNodeType(node);
+        if (nodeType != JsonType.STRING) {
+            return errors;
+        }
+        if (!isUUID(node.textValue())) {
+            errors.add(buildValidationMessage(at, node.textValue(), formatName));
+        }
+        return Collections.unmodifiableSet(errors);
+    }
+
+    public boolean isUUID(String s){
+        return s.matches(regex);
+    }
+}
diff --git a/src/main/java/com/networknt/schema/ValidatorTypeCode.java b/src/main/java/com/networknt/schema/ValidatorTypeCode.java
index 2dbc02e..63655a7 100644
--- a/src/main/java/com/networknt/schema/ValidatorTypeCode.java
+++ b/src/main/java/com/networknt/schema/ValidatorTypeCode.java
@@ -63,7 +63,8 @@ public enum ValidatorTypeCode implements Keyword, ErrorMessageType {
     TYPE("type", "1029", new MessageFormat("{0}: {1} found, {2} expected")),
     UNION_TYPE("unionType", "1030", new MessageFormat("{0}: {1} found, but {2} is required")),
     UNIQUE_ITEMS("uniqueItems", "1031", new MessageFormat("{0}: the items in the array must be unique")),
-    DATETIME("date-time", "1034", new MessageFormat("{0}: {1} is an invalid {2}"));
+    DATETIME("date-time", "1034", new MessageFormat("{0}: {1} is an invalid {2}")),
+    UUID("uuid", "1035", new MessageFormat("{0}: {1} is an invalid {2}"));
 
 	private static Map<String, ValidatorTypeCode> constants = new HashMap<String, ValidatorTypeCode>();
 


Test patch:
diff --git a/src/test/java/com/networknt/schema/JsonSchemaTest.java b/src/test/java/com/networknt/schema/JsonSchemaTest.java
index 2a4e82e..711d524 100644
--- a/src/test/java/com/networknt/schema/JsonSchemaTest.java
+++ b/src/test/java/com/networknt/schema/JsonSchemaTest.java
@@ -270,6 +270,7 @@ public class JsonSchemaTest {
         runTestFile("tests/required.json");
     }
 
+
     @Test
     public void testTypeValidator() throws Exception {
         runTestFile("tests/type.json");
@@ -300,4 +301,10 @@ public class JsonSchemaTest {
         runTestFile("tests/classpath/schema.json");
     }
 
+
+
+    @Test
+    public void testUUIDValidator() throws Exception {
+        runTestFile("tests/uuid.json");
+    }
 }
diff --git a/src/test/resources/tests/uuid.json b/src/test/resources/tests/uuid.json
new file mode 100644
index 0000000..9fe1470
--- /dev/null
+++ b/src/test/resources/tests/uuid.json
@@ -0,0 +1,28 @@
+[
+    {
+        "description": "uuid format validation",
+        "schema": {"format": "uuid"},
+        "tests": [
+            {
+                "description": "invalid uuid",
+                "data": "df984f5c-59bd-48e3sac87-b03d574b37e9",
+                "valid": false
+            },
+            {
+                "description": "valid uuid string",
+                "data": "df984f5c-59bd-48e3-ac87-b03d574b37e9",
+                "valid": true
+            },
+            {
+                "description": "too short, it is invalid",
+                "data": "5fc03087d-d265-11e7-b8c6-83e29cd24f",
+                "valid": false
+            },
+            {
+                "description": "two long, length is greater than 36",
+                "data": "5fc03087d-d265-11e7-b8c6-83e29cd24f42333",
+                "valid": false
+            }
+        ]
+    }
+]