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
@@ -172,6 +173,15 @@ public Schema getSchemaOfAdditionalItems() {
172
173
return schemaOfAdditionalItems ;
173
174
}
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
+
175
185
public boolean needsUniqueItems () {
176
186
return uniqueItems ;
177
187
}
@@ -196,7 +206,8 @@ private void testItemCount(final JSONArray subject) {
196
206
}
197
207
}
198
208
199
- private void testItems (final JSONArray subject ) {
209
+ private List <ValidationException > testItems (final JSONArray subject ) {
210
+ List <ValidationException > rval = new ArrayList <>();
200
211
if (allItemSchema != null ) {
201
212
for (int i = 0 ; i < subject .length (); ++i ) {
202
213
allItemSchema .validate (subject .get (i ));
@@ -208,34 +219,43 @@ private void testItems(final JSONArray subject) {
208
219
}
209
220
int itemValidationUntil = Math .min (subject .length (), itemSchemas .size ());
210
221
for (int i = 0 ; i < itemValidationUntil ; ++i ) {
211
- itemSchemas .get (i ).validate (subject .get (i ));
222
+ int copyOfI = i ; // i is not effectively final so we copy it
223
+ ifFails (itemSchemas .get (i ), subject .get (i ))
224
+ .map (exc -> exc .prepend (String .valueOf (copyOfI )))
225
+ .ifPresent (rval ::add );
212
226
}
213
227
if (schemaOfAdditionalItems != null ) {
214
228
for (int i = itemValidationUntil ; i < subject .length (); ++i ) {
215
- schemaOfAdditionalItems .validate (subject .get (i ));
229
+ int copyOfI = i ; // i is not effectively final so we copy it
230
+ ifFails (schemaOfAdditionalItems , subject .get (i ))
231
+ .map (exc -> exc .prepend (String .valueOf (copyOfI )))
232
+ .ifPresent (rval ::add );
216
233
}
217
234
}
218
235
}
236
+ return rval ;
219
237
}
220
238
221
- private void testUniqueness (final JSONArray subject ) {
239
+ private Optional < ValidationException > testUniqueness (final JSONArray subject ) {
222
240
if (subject .length () == 0 ) {
223
- return ;
241
+ return Optional . empty () ;
224
242
}
225
243
Collection <Object > uniqueItems = new ArrayList <Object >(subject .length ());
226
244
for (int i = 0 ; i < subject .length (); ++i ) {
227
245
Object item = subject .get (i );
228
246
for (Object contained : uniqueItems ) {
229
247
if (ObjectComparator .deepEquals (contained , item )) {
230
- throw new ValidationException ("array items are not unique" );
248
+ return Optional . of ( new ValidationException (this , "array items are not unique" ) );
231
249
}
232
250
}
233
251
uniqueItems .add (item );
234
252
}
253
+ return Optional .empty ();
235
254
}
236
255
237
256
@ Override
238
257
public void validate (final Object subject ) {
258
+ List <ValidationException > failures = new ArrayList <>();
239
259
if (!(subject instanceof JSONArray )) {
240
260
if (requiresArray ) {
241
261
throw new ValidationException (JSONArray .class , subject );
@@ -244,10 +264,11 @@ public void validate(final Object subject) {
244
264
JSONArray arrSubject = (JSONArray ) subject ;
245
265
testItemCount (arrSubject );
246
266
if (uniqueItems ) {
247
- testUniqueness (arrSubject );
267
+ testUniqueness (arrSubject ). ifPresent ( failures :: add ) ;
248
268
}
249
- testItems (arrSubject );
269
+ failures . addAll ( testItems (arrSubject ) );
250
270
}
271
+ ValidationException .throwFor (this , failures );
251
272
}
252
273
253
274
}
0 commit comments