@@ -150,7 +150,7 @@ public static RouterFunction<ServerResponse> resources(String pattern, Resource
150
150
*/
151
151
public static RouterFunction <ServerResponse > resources (Function <ServerRequest , Mono <Resource >> lookupFunction ) {
152
152
Assert .notNull (lookupFunction , "'lookupFunction' must not be null" );
153
- return request -> lookupFunction . apply ( request ). map ( ResourceHandlerFunction :: new );
153
+ return new ResourcesRouterFunction ( lookupFunction );
154
154
}
155
155
156
156
/**
@@ -259,8 +259,138 @@ static <T extends ServerResponse> HandlerFunction<T> cast(HandlerFunction<?> han
259
259
return (HandlerFunction <T >) handlerFunction ;
260
260
}
261
261
262
- private static class DefaultRouterFunction <T extends ServerResponse >
263
- implements RouterFunction <T > {
262
+
263
+ /**
264
+ * Receives notifications from the logical structure of router functions.
265
+ */
266
+ public interface Visitor {
267
+
268
+ /**
269
+ * Receive notification of the beginning of a nested router function.
270
+ * @param predicate the predicate that applies to the nested router functions
271
+ * @see RouterFunctions#nest(RequestPredicate, RouterFunction)
272
+ */
273
+ void startNested (RequestPredicate predicate );
274
+
275
+ /**
276
+ * Receive notification of the end of a nested router function.
277
+ * @param predicate the predicate that applies to the nested router functions
278
+ * @see RouterFunctions#nest(RequestPredicate, RouterFunction)
279
+ */
280
+ void endNested (RequestPredicate predicate );
281
+
282
+ /**
283
+ * Receive notification of a standard predicated route to a handler function.
284
+ * @param predicate the predicate that applies to the handler function
285
+ * @param handlerFunction the handler function.
286
+ * @see RouterFunctions#route(RequestPredicate, HandlerFunction)
287
+ */
288
+ void route (RequestPredicate predicate , HandlerFunction <?> handlerFunction );
289
+
290
+ /**
291
+ * Receive notification of a resource router function.
292
+ * @param lookupFunction the lookup function for the resources
293
+ * @see RouterFunctions#resources(Function)
294
+ */
295
+ void resources (Function <ServerRequest , Mono <Resource >> lookupFunction );
296
+
297
+ /**
298
+ * Receive notification of an unknown router function. This method is called for router
299
+ * functions that were not created via the various {@link RouterFunctions} methods.
300
+ * @param routerFunction the router function
301
+ */
302
+ void unknown (RouterFunction <?> routerFunction );
303
+ }
304
+
305
+
306
+ private static abstract class AbstractRouterFunction <T extends ServerResponse > implements RouterFunction <T > {
307
+
308
+ @ Override
309
+ public String toString () {
310
+ ToStringVisitor visitor = new ToStringVisitor ();
311
+ accept (visitor );
312
+ return visitor .toString ();
313
+ }
314
+ }
315
+
316
+ final static class SameComposedRouterFunction <T extends ServerResponse > extends AbstractRouterFunction <T > {
317
+
318
+ private final RouterFunction <T > first ;
319
+
320
+ private final RouterFunction <T > second ;
321
+
322
+ public SameComposedRouterFunction (RouterFunction <T > first , RouterFunction <T > second ) {
323
+ this .first = first ;
324
+ this .second = second ;
325
+ }
326
+
327
+ @ Override
328
+ public Mono <HandlerFunction <T >> route (ServerRequest request ) {
329
+ return this .first .route (request )
330
+ .switchIfEmpty (Mono .defer (() -> this .second .route (request )));
331
+ }
332
+
333
+ @ Override
334
+ public void accept (Visitor visitor ) {
335
+ this .first .accept (visitor );
336
+ this .second .accept (visitor );
337
+ }
338
+ }
339
+
340
+ final static class DifferentComposedRouterFunction extends AbstractRouterFunction <ServerResponse > {
341
+
342
+ private final RouterFunction <?> first ;
343
+
344
+ private final RouterFunction <?> second ;
345
+
346
+ public DifferentComposedRouterFunction (RouterFunction <?> first , RouterFunction <?> second ) {
347
+ this .first = first ;
348
+ this .second = second ;
349
+ }
350
+
351
+ @ Override
352
+ public Mono <HandlerFunction <ServerResponse >> route (ServerRequest request ) {
353
+ return this .first .route (request )
354
+ .map (RouterFunctions ::cast )
355
+ .switchIfEmpty (Mono .defer (() -> this .second .route (request ).map (RouterFunctions ::cast )));
356
+ }
357
+
358
+ @ Override
359
+ public void accept (Visitor visitor ) {
360
+ this .first .accept (visitor );
361
+ this .second .accept (visitor );
362
+ }
363
+
364
+ }
365
+
366
+ final static class FilteredRouterFunction <T extends ServerResponse , S extends ServerResponse >
367
+ implements RouterFunction <S > {
368
+
369
+ private final RouterFunction <T > routerFunction ;
370
+
371
+ private final HandlerFilterFunction <T , S > filterFunction ;
372
+
373
+ public FilteredRouterFunction (
374
+ RouterFunction <T > routerFunction ,
375
+ HandlerFilterFunction <T , S > filterFunction ) {
376
+ this .routerFunction = routerFunction ;
377
+ this .filterFunction = filterFunction ;
378
+ }
379
+
380
+ @ Override
381
+ public Mono <HandlerFunction <S >> route (ServerRequest request ) {
382
+ return this .routerFunction .route (request ).map (this .filterFunction ::apply );
383
+ }
384
+
385
+ @ Override
386
+ public void accept (Visitor visitor ) {
387
+ this .routerFunction .accept (visitor );
388
+ }
389
+
390
+ }
391
+
392
+ private static final class DefaultRouterFunction <T extends ServerResponse >
393
+ extends AbstractRouterFunction <T > {
264
394
265
395
private final RequestPredicate predicate ;
266
396
@@ -287,13 +417,14 @@ public Mono<HandlerFunction<T>> route(ServerRequest request) {
287
417
}
288
418
289
419
@ Override
290
- public String toString ( ) {
291
- return String . format ( "%s -> %s" , this .predicate , this .handlerFunction );
420
+ public void accept ( Visitor visitor ) {
421
+ visitor . route ( this .predicate , this .handlerFunction );
292
422
}
423
+
293
424
}
294
425
295
- private static class DefaultNestedRouterFunction <T extends ServerResponse >
296
- implements RouterFunction <T > {
426
+ private static final class DefaultNestedRouterFunction <T extends ServerResponse >
427
+ extends AbstractRouterFunction <T > {
297
428
298
429
private final RequestPredicate predicate ;
299
430
@@ -322,12 +453,33 @@ public Mono<HandlerFunction<T>> route(ServerRequest serverRequest) {
322
453
}
323
454
324
455
@ Override
325
- public String toString () {
326
- return String .format ("%s -> %s" , this .predicate , this .routerFunction );
456
+ public void accept (Visitor visitor ) {
457
+ visitor .startNested (this .predicate );
458
+ this .routerFunction .accept (visitor );
459
+ visitor .endNested (this .predicate );
327
460
}
328
461
329
462
}
330
463
464
+ private static class ResourcesRouterFunction extends AbstractRouterFunction <ServerResponse > {
465
+
466
+ private final Function <ServerRequest , Mono <Resource >> lookupFunction ;
467
+
468
+ public ResourcesRouterFunction (Function <ServerRequest , Mono <Resource >> lookupFunction ) {
469
+ this .lookupFunction = lookupFunction ;
470
+ }
471
+
472
+ @ Override
473
+ public Mono <HandlerFunction <ServerResponse >> route (ServerRequest request ) {
474
+ return this .lookupFunction .apply (request ).map (ResourceHandlerFunction ::new );
475
+ }
476
+
477
+ @ Override
478
+ public void accept (Visitor visitor ) {
479
+ visitor .resources (this .lookupFunction );
480
+ }
481
+ }
482
+
331
483
private static class HandlerStrategiesResponseContext implements ServerResponse .Context {
332
484
333
485
private final HandlerStrategies strategies ;
@@ -346,4 +498,5 @@ public List<ViewResolver> viewResolvers() {
346
498
return this .strategies .viewResolvers ();
347
499
}
348
500
}
501
+
349
502
}
0 commit comments