19
19
import java .util .Collection ;
20
20
import java .util .List ;
21
21
import java .util .Objects ;
22
+ import java .util .Optional ;
22
23
23
24
import org .json .JSONArray ;
24
25
@@ -66,16 +67,6 @@ public Builder addItemSchema(final Schema itemSchema) {
66
67
return this ;
67
68
}
68
69
69
- public Builder schemaOfAdditionalItems (final Schema schemaOfAdditionalItems ) {
70
- this .schemaOfAdditionalItems = schemaOfAdditionalItems ;
71
- return this ;
72
- }
73
-
74
- public Builder requiresArray (final boolean requiresArray ) {
75
- this .requiresArray = requiresArray ;
76
- return this ;
77
- }
78
-
79
70
public Builder additionalItems (final boolean additionalItems ) {
80
71
this .additionalItems = additionalItems ;
81
72
return this ;
@@ -101,6 +92,16 @@ public Builder minItems(final Integer minItems) {
101
92
return this ;
102
93
}
103
94
95
+ public Builder requiresArray (final boolean requiresArray ) {
96
+ this .requiresArray = requiresArray ;
97
+ return this ;
98
+ }
99
+
100
+ public Builder schemaOfAdditionalItems (final Schema schemaOfAdditionalItems ) {
101
+ this .schemaOfAdditionalItems = schemaOfAdditionalItems ;
102
+ return this ;
103
+ }
104
+
104
105
public Builder uniqueItems (final boolean uniqueItems ) {
105
106
this .uniqueItems = uniqueItems ;
106
107
return this ;
@@ -168,6 +169,19 @@ public Integer getMinItems() {
168
169
return minItems ;
169
170
}
170
171
172
+ public Schema getSchemaOfAdditionalItems () {
173
+ return schemaOfAdditionalItems ;
174
+ }
175
+
176
+ private Optional <ValidationException > ifFails (final Schema schema , final Object input ) {
177
+ try {
178
+ schema .validate (input );
179
+ return Optional .empty ();
180
+ } catch (ValidationException e ) {
181
+ return Optional .of (e );
182
+ }
183
+ }
184
+
171
185
public boolean needsUniqueItems () {
172
186
return uniqueItems ;
173
187
}
@@ -176,78 +190,90 @@ public boolean permitsAdditionalItems() {
176
190
return additionalItems ;
177
191
}
178
192
179
- private void testItemCount (final JSONArray subject ) {
193
+ public boolean requiresArray () {
194
+ return requiresArray ;
195
+ }
196
+
197
+ private Optional <ValidationException > testItemCount (final JSONArray subject ) {
180
198
int actualLength = subject .length ();
181
199
if (minItems != null && actualLength < minItems ) {
182
- throw new ValidationException ("expected minimum item count: " + minItems + ", found: "
183
- + actualLength );
200
+ return Optional . of ( new ValidationException (this , "expected minimum item count: " + minItems
201
+ + ", found: " + actualLength ) );
184
202
}
185
203
if (maxItems != null && maxItems < actualLength ) {
186
- throw new ValidationException ("expected maximum item count: " + minItems + ", found: "
187
- + actualLength );
204
+ return Optional . of ( new ValidationException (this , "expected maximum item count: " + minItems
205
+ + ", found: " + actualLength ) );
188
206
}
207
+ return Optional .empty ();
189
208
}
190
209
191
- private void testItems (final JSONArray subject ) {
210
+ private List <ValidationException > testItems (final JSONArray subject ) {
211
+ List <ValidationException > rval = new ArrayList <>();
192
212
if (allItemSchema != null ) {
193
213
for (int i = 0 ; i < subject .length (); ++i ) {
194
- allItemSchema .validate (subject .get (i ));
214
+ int copyOfI = i ; // i is not effectively final so we copy it
215
+ ifFails (allItemSchema , subject .get (i ))
216
+ .map (exc -> exc .prepend (String .valueOf (copyOfI )))
217
+ .ifPresent (rval ::add );
195
218
}
196
219
} else if (itemSchemas != null ) {
197
220
if (!additionalItems && subject .length () > itemSchemas .size ()) {
198
- throw new ValidationException (String .format ("expected: [%d] array items, found: [%d]" ,
199
- itemSchemas .size (), subject .length ()));
221
+ rval .add (new ValidationException (this , String .format (
222
+ "expected: [%d] array items, found: [%d]" ,
223
+ itemSchemas .size (), subject .length ())));
200
224
}
201
225
int itemValidationUntil = Math .min (subject .length (), itemSchemas .size ());
202
226
for (int i = 0 ; i < itemValidationUntil ; ++i ) {
203
- itemSchemas .get (i ).validate (subject .get (i ));
227
+ int copyOfI = i ; // i is not effectively final so we copy it
228
+ ifFails (itemSchemas .get (i ), subject .get (i ))
229
+ .map (exc -> exc .prepend (String .valueOf (copyOfI )))
230
+ .ifPresent (rval ::add );
204
231
}
205
232
if (schemaOfAdditionalItems != null ) {
206
233
for (int i = itemValidationUntil ; i < subject .length (); ++i ) {
207
- schemaOfAdditionalItems .validate (subject .get (i ));
234
+ int copyOfI = i ; // i is not effectively final so we copy it
235
+ ifFails (schemaOfAdditionalItems , subject .get (i ))
236
+ .map (exc -> exc .prepend (String .valueOf (copyOfI )))
237
+ .ifPresent (rval ::add );
208
238
}
209
239
}
210
240
}
241
+ return rval ;
211
242
}
212
243
213
- private void testUniqueness (final JSONArray subject ) {
244
+ private Optional < ValidationException > testUniqueness (final JSONArray subject ) {
214
245
if (subject .length () == 0 ) {
215
- return ;
246
+ return Optional . empty () ;
216
247
}
217
248
Collection <Object > uniqueItems = new ArrayList <Object >(subject .length ());
218
249
for (int i = 0 ; i < subject .length (); ++i ) {
219
250
Object item = subject .get (i );
220
251
for (Object contained : uniqueItems ) {
221
252
if (ObjectComparator .deepEquals (contained , item )) {
222
- throw new ValidationException ("array items are not unique" );
253
+ return Optional . of ( new ValidationException (this , "array items are not unique" ) );
223
254
}
224
255
}
225
256
uniqueItems .add (item );
226
257
}
258
+ return Optional .empty ();
227
259
}
228
260
229
261
@ Override
230
262
public void validate (final Object subject ) {
263
+ List <ValidationException > failures = new ArrayList <>();
231
264
if (!(subject instanceof JSONArray )) {
232
265
if (requiresArray ) {
233
- throw new ValidationException (JSONArray .class , subject );
266
+ throw new ValidationException (this , JSONArray .class , subject );
234
267
}
235
268
} else {
236
269
JSONArray arrSubject = (JSONArray ) subject ;
237
- testItemCount (arrSubject );
270
+ testItemCount (arrSubject ). ifPresent ( failures :: add ) ;
238
271
if (uniqueItems ) {
239
- testUniqueness (arrSubject );
272
+ testUniqueness (arrSubject ). ifPresent ( failures :: add ) ;
240
273
}
241
- testItems (arrSubject );
274
+ failures . addAll ( testItems (arrSubject ) );
242
275
}
243
- }
244
-
245
- public boolean requiresArray () {
246
- return requiresArray ;
247
- }
248
-
249
- public Schema getSchemaOfAdditionalItems () {
250
- return schemaOfAdditionalItems ;
276
+ ValidationException .throwFor (this , failures );
251
277
}
252
278
253
279
}
0 commit comments