Skip to content

Commit e1d1c39

Browse files
committed
implemented hostname, uri and date-time formats
1 parent 4bdcf7e commit e1d1c39

File tree

2 files changed

+120
-3
lines changed

2 files changed

+120
-3
lines changed

core/src/main/java/org/everit/json/schema/internal/DefaultFormatValidator.java

Lines changed: 54 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,61 @@
11
package org.everit.json.schema.internal;
22

33
import java.net.InetAddress;
4+
import java.net.URI;
5+
import java.net.URISyntaxException;
6+
import java.text.ParseException;
7+
import java.text.SimpleDateFormat;
48
import java.util.Objects;
59
import java.util.Optional;
610

711
import org.everit.json.schema.Format;
812
import org.everit.json.schema.FormatValidator;
913

1014
import com.google.common.net.InetAddresses;
15+
import com.google.common.net.InternetDomainName;
1116

1217
public class DefaultFormatValidator implements FormatValidator {
1318

1419
private static final int IPV4_LENGTH = 4;
1520

1621
private static final int IPV6_LENGTH = 16;
1722

23+
private static final String DATETIME_FORMAT_STRING = "yyyy-MM-dd'T'HH:mm:ssXXX";
24+
25+
private static final String DATETIME_FORMAT_STRING_SECFRAC = "yyyy-MM-dd'T'HH:mm:ss.SSSXXX";
26+
1827
private Optional<InetAddress> asInetAddress(final String subject) {
19-
if (InetAddresses.isInetAddress(subject)) {
20-
return Optional.of(InetAddresses.forString(subject));
21-
} else {
28+
try {
29+
if (InetAddresses.isInetAddress(subject)) {
30+
return Optional.of(InetAddresses.forString(subject));
31+
} else {
32+
return Optional.empty();
33+
}
34+
} catch (NullPointerException e) {
35+
return Optional.empty();
36+
}
37+
}
38+
39+
private Optional<String> checkDateTime(final String subject) {
40+
try {
41+
new SimpleDateFormat(DATETIME_FORMAT_STRING).parse(subject);
42+
return Optional.empty();
43+
} catch (ParseException e) {
44+
try {
45+
new SimpleDateFormat(DATETIME_FORMAT_STRING_SECFRAC).parse(subject);
46+
return Optional.empty();
47+
} catch (ParseException e1) {
48+
return Optional.of(String.format("[%s] is not a valid date-time", subject));
49+
}
50+
}
51+
}
52+
53+
private Optional<String> checkHostname(final String subject) {
54+
try {
55+
InternetDomainName.from(subject);
2256
return Optional.empty();
57+
} catch (IllegalArgumentException | NullPointerException e) {
58+
return Optional.of(String.format("[%s] is not a valid hostname", subject));
2359
}
2460
}
2561

@@ -31,6 +67,15 @@ private Optional<String> checkIpAddress(final String subject, final int expected
3167
.orElse(Optional.of(String.format(failureFormat, subject)));
3268
}
3369

70+
private Optional<String> checkURI(final String subject) {
71+
try {
72+
new URI(subject);
73+
return Optional.empty();
74+
} catch (URISyntaxException | NullPointerException e) {
75+
return Optional.of(String.format("[%s] is not a valid URI", subject));
76+
}
77+
}
78+
3479
@Override
3580
public Optional<String> validate(final String subject, final Format format) {
3681
Objects.requireNonNull(format, "format cannot be null");
@@ -39,6 +84,12 @@ public Optional<String> validate(final String subject, final Format format) {
3984
return checkIpAddress(subject, IPV4_LENGTH, "[%s] is not a valid ipv4 address");
4085
case IPV6:
4186
return checkIpAddress(subject, IPV6_LENGTH, "[%s] is not a valid ipv6 address");
87+
case HOSTNAME:
88+
return checkHostname(subject);
89+
case URI:
90+
return checkURI(subject);
91+
case DATE_TIME:
92+
return checkDateTime(subject);
4293
default:
4394
throw new IllegalArgumentException("unsupported format: " + format);
4495
}

core/src/test/java/org/everit/json/schema/internal/DefaultFormatValidatorTest.java

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,47 @@ private void assertSuccess(final String subject, final Format format) {
2525
Assert.assertFalse("failure not exist", opt.isPresent());
2626
}
2727

28+
@Test
29+
public void dateTimeFormatFailure() {
30+
assertFailure("2015-03-13T11:00:000", Format.DATE_TIME,
31+
"[2015-03-13T11:00:000] is not a valid date-time");
32+
}
33+
34+
@Test
35+
public void dateTimeSecFracSuccess() {
36+
assertSuccess("2015-02-30T11:00:00.111Z", Format.DATE_TIME);
37+
}
38+
39+
@Test
40+
public void dateTimeSuccess() {
41+
assertSuccess("2015-03-13T11:00:00+00:00", Format.DATE_TIME);
42+
}
43+
44+
@Test
45+
public void dateTimeZSuccess() {
46+
assertSuccess("2015-02-30T11:00:00Z", Format.DATE_TIME);
47+
}
48+
49+
@Test
50+
public void hostnameLengthFailure() {
51+
StringBuilder sb = new StringBuilder();
52+
for (int i = 0; i < 256; ++i) {
53+
sb.append('a');
54+
}
55+
String subject = sb.toString();
56+
assertFailure(subject, Format.HOSTNAME, "[" + subject + "] is not a valid hostname");
57+
}
58+
59+
@Test
60+
public void hostnameNullFailure() {
61+
assertFailure(null, Format.HOSTNAME, "[null] is not a valid hostname");
62+
}
63+
64+
@Test
65+
public void hostnameSuccess() {
66+
assertSuccess("localhost", Format.HOSTNAME);
67+
}
68+
2869
@Test
2970
public void ipv4Failure() {
3071
assertFailure("asd", Format.IPV4, "[asd] is not a valid ipv4 address");
@@ -36,6 +77,11 @@ public void ipv4LengthFailure() {
3677
"[2001:db8:85a3:0:0:8a2e:370:7334] is not a valid ipv4 address");
3778
}
3879

80+
@Test
81+
public void ipv4NullFailure() {
82+
assertFailure(null, Format.IPV4, "[null] is not a valid ipv4 address");
83+
}
84+
3985
@Test
4086
public void ipv4Success() {
4187
assertSuccess(THERE_IS_NO_PLACE_LIKE, Format.IPV4);
@@ -51,6 +97,11 @@ public void ipv6LengthFailure() {
5197
assertFailure(THERE_IS_NO_PLACE_LIKE, Format.IPV6, "[127.0.0.1] is not a valid ipv6 address");
5298
}
5399

100+
@Test
101+
public void ipv6NullFailure() {
102+
assertFailure(null, Format.IPV6, "[null] is not a valid ipv6 address");
103+
}
104+
54105
@Test
55106
public void ipv6Success() {
56107
assertSuccess(IPV6_ADDR, Format.IPV6);
@@ -61,4 +112,19 @@ public void nullFormat() {
61112
new DefaultFormatValidator().validate("asd", null);
62113
}
63114

115+
@Test
116+
public void uriFailure() {
117+
assertFailure("12 34", Format.URI, "[12 34] is not a valid URI");
118+
}
119+
120+
@Test
121+
public void uriNullFailure() {
122+
assertFailure(null, Format.URI, "[null] is not a valid URI");
123+
}
124+
125+
@Test
126+
public void uriSuccess() {
127+
assertSuccess("http://example.org:8080/example.html", Format.URI);
128+
}
129+
64130
}

0 commit comments

Comments
 (0)