1
1
/*
2
- * Copyright 2002-2022 the original author or authors.
2
+ * Copyright 2002-2023 the original author or authors.
3
3
*
4
4
* Licensed under the Apache License, Version 2.0 (the "License");
5
5
* you may not use this file except in compliance with the License.
@@ -145,7 +145,7 @@ public DefaultRequest variable(String name, @Nullable Object value) {
145
145
}
146
146
147
147
@ Override
148
- public DefaultRequest extension (String name , Object value ) {
148
+ public DefaultRequest extension (String name , @ Nullable Object value ) {
149
149
this .extensions .put (name , value );
150
150
return this ;
151
151
}
@@ -270,6 +270,7 @@ void verifyErrors() {
270
270
"If expected, please filter them out: " + this .unexpectedErrors ,
271
271
CollectionUtils .isEmpty (this .unexpectedErrors )));
272
272
}
273
+
273
274
}
274
275
275
276
@@ -290,7 +291,12 @@ private DefaultResponse(
290
291
@ Override
291
292
public Path path (String path ) {
292
293
this .delegate .verifyErrors ();
293
- return new DefaultPath (path , this .delegate );
294
+ return DefaultPath .forPath (null , path , this .delegate );
295
+ }
296
+
297
+ @ Override
298
+ public Path path (String path , Consumer <Path > pathConsumer ) {
299
+ return DefaultPath .forNestedPath (null , path , this .delegate , pathConsumer );
294
300
}
295
301
296
302
@ Override
@@ -329,6 +335,9 @@ public Traversable satisfy(Consumer<List<ResponseError>> consumer) {
329
335
*/
330
336
private static final class DefaultPath implements Path {
331
337
338
+ @ Nullable
339
+ private final String basePath ;
340
+
332
341
private final String path ;
333
342
334
343
private final ResponseDelegate delegate ;
@@ -337,19 +346,20 @@ private static final class DefaultPath implements Path {
337
346
338
347
private final JsonPathExpectationsHelper pathHelper ;
339
348
340
- private DefaultPath (String path , ResponseDelegate delegate ) {
349
+ private DefaultPath (@ Nullable String basePath , String path , ResponseDelegate delegate ) {
341
350
Assert .notNull (path , "`path` is required" );
342
351
Assert .notNull (delegate , "ResponseContainer is required" );
343
352
344
- String fullPath = initFullPath (path );
345
-
353
+ this .basePath = basePath ;
346
354
this .path = path ;
347
355
this .delegate = delegate ;
356
+
357
+ String fullPath = initDataJsonPath (this .path );
348
358
this .jsonPath = JsonPath .compile (fullPath );
349
359
this .pathHelper = new JsonPathExpectationsHelper (fullPath );
350
360
}
351
361
352
- private static String initFullPath (String path ) {
362
+ private static String initDataJsonPath (String path ) {
353
363
if (!StringUtils .hasText (path )) {
354
364
path = "$.data" ;
355
365
}
@@ -361,7 +371,12 @@ else if (!path.startsWith("$") && !path.startsWith("data.")) {
361
371
362
372
@ Override
363
373
public Path path (String path ) {
364
- return new DefaultPath (path , this .delegate );
374
+ return forPath (this .basePath , path , this .delegate );
375
+ }
376
+
377
+ @ Override
378
+ public Path path (String path , Consumer <Path > pathConsumer ) {
379
+ return forNestedPath (this .basePath , path , this .delegate , pathConsumer );
365
380
}
366
381
367
382
@ Override
@@ -390,25 +405,25 @@ public Path pathDoesNotExist() {
390
405
@ Override
391
406
public <D > Entity <D , ?> entity (Class <D > entityType ) {
392
407
D entity = this .delegate .read (this .jsonPath , new TypeRefAdapter <>(entityType ));
393
- return new DefaultEntity <>(entity , this .path , this .delegate );
408
+ return new DefaultEntity <>(entity , this .basePath , this . path , this .delegate );
394
409
}
395
410
396
411
@ Override
397
412
public <D > Entity <D , ?> entity (ParameterizedTypeReference <D > entityType ) {
398
413
D entity = this .delegate .read (this .jsonPath , new TypeRefAdapter <>(entityType ));
399
- return new DefaultEntity <>(entity , this .path , this .delegate );
414
+ return new DefaultEntity <>(entity , this .basePath , this . path , this .delegate );
400
415
}
401
416
402
417
@ Override
403
418
public <D > EntityList <D > entityList (Class <D > elementType ) {
404
419
List <D > entity = this .delegate .read (this .jsonPath , new TypeRefAdapter <>(List .class , elementType ));
405
- return new DefaultEntityList <>(entity , this .path , this .delegate );
420
+ return new DefaultEntityList <>(entity , this .basePath , this . path , this .delegate );
406
421
}
407
422
408
423
@ Override
409
424
public <D > EntityList <D > entityList (ParameterizedTypeReference <D > elementType ) {
410
425
List <D > entity = this .delegate .read (this .jsonPath , new TypeRefAdapter <>(List .class , elementType ));
411
- return new DefaultEntityList <>(entity , this .path , this .delegate );
426
+ return new DefaultEntityList <>(entity , this .basePath , this . path , this .delegate );
412
427
}
413
428
414
429
@ Override
@@ -439,6 +454,22 @@ private void matchesJson(String expected, boolean strict) {
439
454
}
440
455
});
441
456
}
457
+
458
+ static Path forPath (@ Nullable String basePath , String path , ResponseDelegate delegate ) {
459
+ String pathToUse = joinPaths (basePath , path );
460
+ return new DefaultPath (basePath , pathToUse , delegate );
461
+ }
462
+
463
+ static Path forNestedPath (@ Nullable String basePath , String path , ResponseDelegate delegate , Consumer <Path > consumer ) {
464
+ String pathToUse = joinPaths (basePath , path );
465
+ consumer .accept (new DefaultPath (pathToUse , pathToUse , delegate ));
466
+ return new DefaultPath (basePath , path , delegate );
467
+ }
468
+
469
+ private static String joinPaths (@ Nullable String basePath , String path ) {
470
+ return (basePath != null ? basePath + "." + path : path );
471
+ }
472
+
442
473
}
443
474
444
475
@@ -449,14 +480,18 @@ private static class DefaultEntity<D, S extends Entity<D, S>> implements Entity<
449
480
450
481
private final D entity ;
451
482
483
+ @ Nullable
484
+ private final String basePath ;
485
+
452
486
private final String path ;
453
487
454
488
private final ResponseDelegate delegate ;
455
489
456
- protected DefaultEntity (D entity , String path , ResponseDelegate delegate ) {
490
+ protected DefaultEntity (D entity , @ Nullable String basePath , String path , ResponseDelegate delegate ) {
457
491
this .entity = entity ;
458
- this .delegate = delegate ;
492
+ this .basePath = basePath ;
459
493
this .path = path ;
494
+ this .delegate = delegate ;
460
495
}
461
496
462
497
protected D getEntity () {
@@ -473,7 +508,12 @@ protected String getPath() {
473
508
474
509
@ Override
475
510
public Path path (String path ) {
476
- return new DefaultPath (path , this .delegate );
511
+ return DefaultPath .forPath (this .basePath , path , this .delegate );
512
+ }
513
+
514
+ @ Override
515
+ public Path path (String path , Consumer <Path > pathConsumer ) {
516
+ return DefaultPath .forNestedPath (this .basePath , path , this .delegate , pathConsumer );
477
517
}
478
518
479
519
@ Override
@@ -528,11 +568,12 @@ private <T extends S> T self() {
528
568
/**
529
569
* Default {@link EntityList} implementation.
530
570
*/
531
- private static final class DefaultEntityList <E > extends DefaultEntity <List <E >, EntityList <E >>
532
- implements EntityList <E > {
571
+ @ SuppressWarnings ("SlowListContainsAll" )
572
+ private static final class DefaultEntityList <E >
573
+ extends DefaultEntity <List <E >, EntityList <E >> implements EntityList <E > {
533
574
534
- private DefaultEntityList (List <E > entity , String path , ResponseDelegate delegate ) {
535
- super (entity , path , delegate );
575
+ private DefaultEntityList (List <E > entity , @ Nullable String basePath , String path , ResponseDelegate delegate ) {
576
+ super (entity , basePath , path , delegate );
536
577
}
537
578
538
579
@ Override
0 commit comments