22
33import jdk .sandbox .java .util .json .*;
44
5+ import java .time .OffsetDateTime ;
6+ import java .time .format .DateTimeFormatter ;
57import java .util .List ;
68
79/// JTD Schema interface - validates JSON instances against JTD schemas
@@ -73,15 +75,17 @@ public boolean validateWithFrame(Jtd.Frame frame, java.util.List<String> errors,
7375 }
7476
7577 /// Ref schema - references a definition in the schema's definitions
76- record RefSchema (String ref ) implements JtdSchema {
78+ record RefSchema (String ref , JtdSchema resolvedSchema ) implements JtdSchema {
7779 @ Override
7880 public Jtd .Result validate (JsonValue instance ) {
79- throw new AssertionError ( "not implemented" );
81+ return resolvedSchema . validate ( instance );
8082 }
8183
8284 @ Override
8385 public boolean validateWithFrame (Jtd .Frame frame , java .util .List <String > errors , boolean verboseErrors ) {
84- throw new AssertionError ("not implemented" );
86+ // Create new frame with the resolved schema but same instance, path, and crumbs
87+ Jtd .Frame resolvedFrame = new Jtd .Frame (resolvedSchema , frame .instance (), frame .ptr (), frame .crumbs ());
88+ return resolvedSchema .validateWithFrame (resolvedFrame , errors , verboseErrors );
8589 }
8690 }
8791
@@ -139,8 +143,18 @@ Jtd.Result validateString(JsonValue instance, boolean verboseErrors) {
139143 }
140144
141145 Jtd .Result validateTimestamp (JsonValue instance , boolean verboseErrors ) {
142- if (instance instanceof JsonString ignored ) {
143- throw new AssertionError ("not implemented" );
146+ if (instance instanceof JsonString str ) {
147+ try {
148+ // Parse using RFC 3339 format (ISO_OFFSET_DATE_TIME)
149+ OffsetDateTime .parse (str .value (), DateTimeFormatter .ISO_OFFSET_DATE_TIME );
150+ return Jtd .Result .success ();
151+ } catch (Exception e ) {
152+ // Invalid RFC 3339 timestamp format
153+ String error = verboseErrors
154+ ? Jtd .Error .EXPECTED_TIMESTAMP .message (instance , instance .getClass ().getSimpleName ())
155+ : Jtd .Error .EXPECTED_TIMESTAMP .message (instance .getClass ().getSimpleName ());
156+ return Jtd .Result .failure (error );
157+ }
144158 }
145159 String error = verboseErrors
146160 ? Jtd .Error .EXPECTED_TIMESTAMP .message (instance , instance .getClass ().getSimpleName ())
@@ -151,11 +165,37 @@ Jtd.Result validateTimestamp(JsonValue instance, boolean verboseErrors) {
151165 Jtd .Result validateInteger (JsonValue instance , String type , boolean verboseErrors ) {
152166 if (instance instanceof JsonNumber num ) {
153167 Number value = num .toNumber ();
168+
169+ // Check if the number is not integral (has fractional part)
154170 if (value instanceof Double d && d != Math .floor (d )) {
155171 return Jtd .Result .failure (Jtd .Error .EXPECTED_INTEGER .message ());
156172 }
157- throw new AssertionError ("not implemented" );
173+
174+ // Convert to long for range checking
175+ long longValue = value .longValue ();
176+
177+ // Check ranges according to RFC 8927 §2.2.3.1
178+ boolean valid = switch (type ) {
179+ case "int8" -> longValue >= -128 && longValue <= 127 ;
180+ case "uint8" -> longValue >= 0 && longValue <= 255 ;
181+ case "int16" -> longValue >= -32768 && longValue <= 32767 ;
182+ case "uint16" -> longValue >= 0 && longValue <= 65535 ;
183+ case "int32" -> longValue >= -2147483648L && longValue <= 2147483647L ;
184+ case "uint32" -> longValue >= 0 && longValue <= 4294967295L ;
185+ default -> false ;
186+ };
187+
188+ if (valid ) {
189+ return Jtd .Result .success ();
190+ }
191+
192+ // Range violation
193+ String error = verboseErrors
194+ ? Jtd .Error .EXPECTED_NUMERIC_TYPE .message (instance , type , instance .getClass ().getSimpleName ())
195+ : Jtd .Error .EXPECTED_NUMERIC_TYPE .message (type , instance .getClass ().getSimpleName ());
196+ return Jtd .Result .failure (error );
158197 }
198+
159199 String error = verboseErrors
160200 ? Jtd .Error .EXPECTED_NUMERIC_TYPE .message (instance , type , instance .getClass ().getSimpleName ())
161201 : Jtd .Error .EXPECTED_NUMERIC_TYPE .message (type , instance .getClass ().getSimpleName ());
0 commit comments