21
21
import java .security .Principal ;
22
22
import java .util .Arrays ;
23
23
import java .util .Collections ;
24
- import java .util .HashMap ;
25
24
import java .util .LinkedHashMap ;
26
25
import java .util .LinkedHashSet ;
27
26
import java .util .List ;
@@ -296,11 +295,6 @@ private static void traceMatch(String prefix, Object desired, @Nullable Object a
296
295
}
297
296
}
298
297
299
- private static void restoreAttributes (ServerRequest request , Map <String , Object > attributes ) {
300
- request .attributes ().clear ();
301
- request .attributes ().putAll (attributes );
302
- }
303
-
304
298
private static Map <String , String > mergePathVariables (Map <String , String > oldVariables ,
305
299
Map <String , String > newVariables ) {
306
300
@@ -432,6 +426,81 @@ public interface Visitor {
432
426
}
433
427
434
428
429
+ /**
430
+ * A boolean result with a state-changing commit step to be conditionally
431
+ * applied by a caller.
432
+ */
433
+ static abstract class Evaluation {
434
+ static final Evaluation TRUE = new NopEvaluation (true );
435
+ static final Evaluation FALSE = new NopEvaluation (false );
436
+
437
+ private final boolean value ;
438
+
439
+ Evaluation (boolean value ) {
440
+ this .value = value ;
441
+ }
442
+
443
+ abstract void doCommit ();
444
+
445
+
446
+ private static final class NopEvaluation extends Evaluation {
447
+ private NopEvaluation (boolean value ) {
448
+ super (value );
449
+ }
450
+
451
+ @ Override
452
+ void doCommit () {
453
+ // pass
454
+ }
455
+ }
456
+ }
457
+
458
+
459
+ /**
460
+ * Evaluates a {@link ServerRequest} and returns an {@link Evaluation}.
461
+ */
462
+ private static abstract class Evaluator {
463
+ private static Evaluator of (RequestPredicate requestPredicate ) {
464
+ if (requestPredicate instanceof EvaluatorRequestPredicate evaluatorRequestPredicate ) {
465
+ return evaluatorRequestPredicate ;
466
+ }
467
+ // Wrap the RequestPredicate with an Evaluator
468
+ return new RequestPredicateEvaluator (requestPredicate );
469
+ }
470
+
471
+ abstract Evaluation apply (ServerRequest request );
472
+
473
+
474
+ private static final class RequestPredicateEvaluator extends Evaluator {
475
+ private final RequestPredicate requestPredicate ;
476
+
477
+ private RequestPredicateEvaluator (RequestPredicate requestPredicate ) {
478
+ this .requestPredicate = requestPredicate ;
479
+ }
480
+
481
+ @ Override
482
+ Evaluation apply (ServerRequest request ) {
483
+ return this .requestPredicate .test (request ) ? Evaluation .TRUE : Evaluation .FALSE ;
484
+ }
485
+ }
486
+ }
487
+
488
+ /**
489
+ * A {@link RequestPredicate} which may modify the request.
490
+ */
491
+ static abstract class EvaluatorRequestPredicate extends Evaluator implements RequestPredicate {
492
+ @ Override
493
+ public final boolean test (ServerRequest request ) {
494
+ Evaluation result = apply (request );
495
+ boolean value = result .value ;
496
+ if (value ) {
497
+ result .doCommit ();
498
+ }
499
+ return value ;
500
+ }
501
+ }
502
+
503
+
435
504
private static class HttpMethodPredicate implements RequestPredicate {
436
505
437
506
private final Set <HttpMethod > httpMethods ;
@@ -482,7 +551,7 @@ public String toString() {
482
551
}
483
552
484
553
485
- private static class PathPatternPredicate implements RequestPredicate , ChangePathPatternParserVisitor .Target {
554
+ private static class PathPatternPredicate extends EvaluatorRequestPredicate implements ChangePathPatternParserVisitor .Target {
486
555
487
556
private PathPattern pattern ;
488
557
@@ -492,29 +561,28 @@ public PathPatternPredicate(PathPattern pattern) {
492
561
}
493
562
494
563
@ Override
495
- public boolean test (ServerRequest request ) {
564
+ public Evaluation apply (ServerRequest request ) {
496
565
PathContainer pathContainer = request .requestPath ().pathWithinApplication ();
497
566
PathPattern .PathMatchInfo info = this .pattern .matchAndExtract (pathContainer );
498
567
traceMatch ("Pattern" , this .pattern .getPatternString (), request .path (), info != null );
499
- if (info != null ) {
500
- mergeAttributes (request , info .getUriVariables (), this .pattern );
501
- return true ;
502
- }
503
- else {
504
- return false ;
568
+ if (info == null ) {
569
+ return Evaluation .FALSE ;
505
570
}
506
- }
507
-
508
- private static void mergeAttributes (ServerRequest request , Map <String , String > variables ,
509
- PathPattern pattern ) {
510
- Map <String , String > pathVariables = mergePathVariables (request .pathVariables (), variables );
511
- request .attributes ().put (RouterFunctions .URI_TEMPLATE_VARIABLES_ATTRIBUTE ,
512
- Collections .unmodifiableMap (pathVariables ));
513
-
514
- pattern = mergePatterns (
515
- (PathPattern ) request .attributes ().get (RouterFunctions .MATCHING_PATTERN_ATTRIBUTE ),
516
- pattern );
517
- request .attributes ().put (RouterFunctions .MATCHING_PATTERN_ATTRIBUTE , pattern );
571
+ return new Evaluation (true ) {
572
+ @ Override
573
+ void doCommit () {
574
+ Map <String , Object > attributes = request .attributes ();
575
+ Map <String , String > pathVariables = mergePathVariables (request .pathVariables (),
576
+ info .getUriVariables ());
577
+ attributes .put (RouterFunctions .URI_TEMPLATE_VARIABLES_ATTRIBUTE ,
578
+ Collections .unmodifiableMap (pathVariables ));
579
+
580
+ PathPattern newPattern = mergePatterns (
581
+ (PathPattern ) attributes .get (RouterFunctions .MATCHING_PATTERN_ATTRIBUTE ),
582
+ PathPatternPredicate .this .pattern );
583
+ attributes .put (RouterFunctions .MATCHING_PATTERN_ATTRIBUTE , newPattern );
584
+ }
585
+ };
518
586
}
519
587
520
588
@ Override
@@ -756,28 +824,40 @@ public String toString() {
756
824
* {@link RequestPredicate} for where both {@code left} and {@code right} predicates
757
825
* must match.
758
826
*/
759
- static class AndRequestPredicate implements RequestPredicate , ChangePathPatternParserVisitor .Target {
827
+ static class AndRequestPredicate extends EvaluatorRequestPredicate implements ChangePathPatternParserVisitor .Target {
760
828
761
829
private final RequestPredicate left ;
830
+ private final Evaluator leftEvaluator ;
762
831
763
832
private final RequestPredicate right ;
833
+ private final Evaluator rightEvaluator ;
764
834
765
835
public AndRequestPredicate (RequestPredicate left , RequestPredicate right ) {
766
836
Assert .notNull (left , "Left RequestPredicate must not be null" );
767
837
Assert .notNull (right , "Right RequestPredicate must not be null" );
768
838
this .left = left ;
839
+ this .leftEvaluator = Evaluator .of (left );
769
840
this .right = right ;
841
+ this .rightEvaluator = Evaluator .of (right );
770
842
}
771
843
772
844
@ Override
773
- public boolean test (ServerRequest request ) {
774
- Map <String , Object > oldAttributes = new HashMap <>(request .attributes ());
775
-
776
- if (this .left .test (request ) && this .right .test (request )) {
777
- return true ;
845
+ public Evaluation apply (ServerRequest request ) {
846
+ Evaluation leftResult = this .leftEvaluator .apply (request );
847
+ if (!leftResult .value ) {
848
+ return leftResult ;
849
+ }
850
+ Evaluation rightResult = this .rightEvaluator .apply (request );
851
+ if (!rightResult .value ) {
852
+ return rightResult ;
778
853
}
779
- restoreAttributes (request , oldAttributes );
780
- return false ;
854
+ return new Evaluation (true ) {
855
+ @ Override
856
+ void doCommit () {
857
+ leftResult .doCommit ();
858
+ rightResult .doCommit ();
859
+ }
860
+ };
781
861
}
782
862
783
863
@ Override
@@ -814,23 +894,26 @@ public String toString() {
814
894
/**
815
895
* {@link RequestPredicate} that negates a delegate predicate.
816
896
*/
817
- static class NegateRequestPredicate implements RequestPredicate , ChangePathPatternParserVisitor .Target {
897
+ static class NegateRequestPredicate extends EvaluatorRequestPredicate implements ChangePathPatternParserVisitor .Target {
818
898
819
899
private final RequestPredicate delegate ;
900
+ private final Evaluator delegateEvaluator ;
820
901
821
902
public NegateRequestPredicate (RequestPredicate delegate ) {
822
903
Assert .notNull (delegate , "Delegate must not be null" );
823
904
this .delegate = delegate ;
905
+ this .delegateEvaluator = Evaluator .of (delegate );
824
906
}
825
907
826
908
@ Override
827
- public boolean test (ServerRequest request ) {
828
- Map <String , Object > oldAttributes = new HashMap <>(request .attributes ());
829
- boolean result = !this .delegate .test (request );
830
- if (!result ) {
831
- restoreAttributes (request , oldAttributes );
832
- }
833
- return result ;
909
+ public Evaluation apply (ServerRequest request ) {
910
+ Evaluation result = this .delegateEvaluator .apply (request );
911
+ return new Evaluation (!result .value ) {
912
+ @ Override
913
+ void doCommit () {
914
+ result .doCommit ();
915
+ }
916
+ };
834
917
}
835
918
836
919
@ Override
@@ -858,34 +941,30 @@ public String toString() {
858
941
* {@link RequestPredicate} where either {@code left} or {@code right} predicates
859
942
* may match.
860
943
*/
861
- static class OrRequestPredicate implements RequestPredicate , ChangePathPatternParserVisitor .Target {
944
+ static class OrRequestPredicate extends EvaluatorRequestPredicate implements ChangePathPatternParserVisitor .Target {
862
945
863
946
private final RequestPredicate left ;
947
+ private final Evaluator leftEvaluator ;
864
948
865
949
private final RequestPredicate right ;
950
+ private final Evaluator rightEvaluator ;
866
951
867
952
public OrRequestPredicate (RequestPredicate left , RequestPredicate right ) {
868
953
Assert .notNull (left , "Left RequestPredicate must not be null" );
869
954
Assert .notNull (right , "Right RequestPredicate must not be null" );
870
955
this .left = left ;
956
+ this .leftEvaluator = Evaluator .of (left );
871
957
this .right = right ;
958
+ this .rightEvaluator = Evaluator .of (right );
872
959
}
873
960
874
961
@ Override
875
- public boolean test (ServerRequest request ) {
876
- Map <String , Object > oldAttributes = new HashMap <>(request .attributes ());
877
-
878
- if (this .left .test (request )) {
879
- return true ;
880
- }
881
- else {
882
- restoreAttributes (request , oldAttributes );
883
- if (this .right .test (request )) {
884
- return true ;
885
- }
962
+ public Evaluation apply (ServerRequest request ) {
963
+ Evaluation leftResult = this .leftEvaluator .apply (request );
964
+ if (leftResult .value ) {
965
+ return leftResult ;
886
966
}
887
- restoreAttributes (request , oldAttributes );
888
- return false ;
967
+ return this .rightEvaluator .apply (request );
889
968
}
890
969
891
970
@ Override
0 commit comments