diff --git a/src/main/java/com/networknt/schema/JsonMetaSchema.java b/src/main/java/com/networknt/schema/JsonMetaSchema.java index 43a0004e8..0716181cb 100644 --- a/src/main/java/com/networknt/schema/JsonMetaSchema.java +++ b/src/main/java/com/networknt/schema/JsonMetaSchema.java @@ -42,33 +42,34 @@ public class JsonMetaSchema { static PatternFormat pattern(String name, String regex) { return new PatternFormat(name, regex); } - public static final List BUILTIN_FORMATS = new ArrayList(); + public static final List COMMON_BUILTIN_FORMATS = new ArrayList(); // this section contains formats that is common for all specification versions. static { - BUILTIN_FORMATS.add(pattern("time", "^\\d{2}:\\d{2}:\\d{2}$")); - BUILTIN_FORMATS.add(pattern("ip-address", + COMMON_BUILTIN_FORMATS.add(pattern("time", "^\\d{2}:\\d{2}:\\d{2}$")); + COMMON_BUILTIN_FORMATS.add(pattern("ip-address", "^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$")); - BUILTIN_FORMATS.add(pattern("ipv4", + COMMON_BUILTIN_FORMATS.add(pattern("ipv4", "^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$")); - BUILTIN_FORMATS.add(pattern("ipv6", + COMMON_BUILTIN_FORMATS.add(pattern("ipv6", "^\\s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:)))(%.+)?\\s*$")); - BUILTIN_FORMATS.add(pattern("uri", "(^[a-zA-Z][a-zA-Z0-9+-.]*:[^\\s]*$)|(^//[^\\s]*$)")); - BUILTIN_FORMATS.add(pattern("color", + COMMON_BUILTIN_FORMATS.add(pattern("uri", "(^[a-zA-Z][a-zA-Z0-9+-.]*:[^\\s]*$)|(^//[^\\s]*$)")); + COMMON_BUILTIN_FORMATS.add(pattern("color", "(#?([0-9A-Fa-f]{3,6})\\b)|(aqua)|(black)|(blue)|(fuchsia)|(gray)|(green)|(lime)|(maroon)|(navy)|(olive)|(orange)|(purple)|(red)|(silver)|(teal)|(white)|(yellow)|(rgb\\(\\s*\\b([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\\b\\s*,\\s*\\b([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\\b\\s*,\\s*\\b([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\\b\\s*\\))|(rgb\\(\\s*(\\d?\\d%|100%)+\\s*,\\s*(\\d?\\d%|100%)+\\s*,\\s*(\\d?\\d%|100%)+\\s*\\))")); - BUILTIN_FORMATS.add(pattern("hostname", + COMMON_BUILTIN_FORMATS.add(pattern("hostname", "^([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\\-]{0,61}[a-zA-Z0-9])(\\.([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\\-]{0,61}[a-zA-Z0-9]))*$")); - BUILTIN_FORMATS.add(pattern("alpha", "^[a-zA-Z]+$")); - BUILTIN_FORMATS.add(pattern("alphanumeric", "^[a-zA-Z0-9]+$")); - BUILTIN_FORMATS.add(pattern("phone", "^\\+(?:[0-9] ?){6,14}[0-9]$")); - BUILTIN_FORMATS.add(pattern("utc-millisec", "^[0-9]+(\\.?[0-9]+)?$")); - BUILTIN_FORMATS.add(pattern("style", "\\s*(.+?):\\s*([^;]+);?")); + COMMON_BUILTIN_FORMATS.add(pattern("alpha", "^[a-zA-Z]+$")); + COMMON_BUILTIN_FORMATS.add(pattern("alphanumeric", "^[a-zA-Z0-9]+$")); + COMMON_BUILTIN_FORMATS.add(pattern("phone", "^\\+(?:[0-9] ?){6,14}[0-9]$")); + COMMON_BUILTIN_FORMATS.add(pattern("utc-millisec", "^[0-9]+(\\.?[0-9]+)?$")); + COMMON_BUILTIN_FORMATS.add(pattern("style", "\\s*(.+?):\\s*([^;]+);?")); } private static class V4 { private static String URI = "http://json-schema.org/draft-04/schema#"; private static final String ID = "id"; + public static final List BUILTIN_FORMATS = new ArrayList<>(JsonMetaSchema.COMMON_BUILTIN_FORMATS); static { // add version specific formats here. //BUILTIN_FORMATS.add(pattern("phone", "^\\+(?:[0-9] ?){6,14}[0-9]$")); @@ -97,6 +98,7 @@ private static class V6 { // Draft 6 uses "$id" private static final String ID = "$id"; + public static final List BUILTIN_FORMATS = new ArrayList<>(JsonMetaSchema.COMMON_BUILTIN_FORMATS); static { // add version specific formats here. //BUILTIN_FORMATS.add(pattern("phone", "^\\+(?:[0-9] ?){6,14}[0-9]$")); @@ -124,6 +126,7 @@ private static class V7 { private static String URI = "http://json-schema.org/draft-07/schema#"; private static final String ID = "$id"; + public static final List BUILTIN_FORMATS = new ArrayList<>(JsonMetaSchema.COMMON_BUILTIN_FORMATS); static { // add version specific formats here. //BUILTIN_FORMATS.add(pattern("phone", "^\\+(?:[0-9] ?){6,14}[0-9]$")); @@ -151,6 +154,7 @@ private static class V201909 { private static String URI = "http://json-schema.org/draft/2019-09/schema#"; private static final String ID = "$id"; + public static final List BUILTIN_FORMATS = new ArrayList<>(JsonMetaSchema.COMMON_BUILTIN_FORMATS); static { // add version specific formats here. //BUILTIN_FORMATS.add(pattern("phone", "^\\+(?:[0-9] ?){6,14}[0-9]$")); diff --git a/src/test/java/com/networknt/schema/V201909JsonSchemaTest.java b/src/test/java/com/networknt/schema/V201909JsonSchemaTest.java index 07cf4bc5d..7fb5bc0a0 100644 --- a/src/test/java/com/networknt/schema/V201909JsonSchemaTest.java +++ b/src/test/java/com/networknt/schema/V201909JsonSchemaTest.java @@ -115,6 +115,32 @@ public void testBignumValidator() throws Exception { runTestFile("draft2019-09/optional/bignum.json"); } + @Test + public void testFormatDateValidator() throws Exception { + runTestFile("draft2019-09/optional/format/date.json"); + } + + @Test + public void testFormatDateTimeValidator() throws Exception { + runTestFile("draft2019-09/optional/format/date-time.json"); + } + + @Test + public void testFormatEmailValidator() throws Exception { + runTestFile("draft2019-09/optional/format/email.json"); + } + + @Test + public void testFormatHostnameValidator() throws Exception { + runTestFile("draft2019-09/optional/format/hostname.json"); + } + + @Test + @Ignore + public void testFormatIdnEmailValidator() throws Exception { + runTestFile("draft2019-09/optional/format/idn-email.json"); + } + @Test public void testIfValidator() throws Exception { runTestFile("draft2019-09/if.json");