diff --git a/akka-actor-tests/src/test/java/akka/japi/pf/ReceiveBuilderTest.java b/akka-actor-tests/src/test/java/akka/japi/pf/ReceiveBuilderTest.java index 257384aa56..08f48ab736 100644 --- a/akka-actor-tests/src/test/java/akka/japi/pf/ReceiveBuilderTest.java +++ b/akka-actor-tests/src/test/java/akka/japi/pf/ReceiveBuilderTest.java @@ -191,6 +191,21 @@ public class ReceiveBuilderTest extends JUnitSuite { assertFalse(rcv.onMessage().isDefinedAt(42)); } + private boolean externalPredicateAlwaysTrue(){ + return true; + } + + @Test + public void shouldMatchByExternalPredicate(){ + Receive rcv = ReceiveBuilder.create() + .match(Msg1.class, this::externalPredicateAlwaysTrue, m -> result("match Msg1")) + .build(); + assertTrue(rcv.onMessage().isDefinedAt(new Msg1())); + rcv.onMessage().apply(new Msg1()); + assertEquals("match Msg1", result()); + assertFalse(rcv.onMessage().isDefinedAt(new Msg2("foo"))); + } + @Test public void shouldMatchEquals() { Msg2 msg2 = new Msg2("foo"); diff --git a/akka-actor/src/main/java/akka/japi/pf/ReceiveBuilder.java b/akka-actor/src/main/java/akka/japi/pf/ReceiveBuilder.java index 12cca2fc45..2ca261017c 100644 --- a/akka-actor/src/main/java/akka/japi/pf/ReceiveBuilder.java +++ b/akka-actor/src/main/java/akka/japi/pf/ReceiveBuilder.java @@ -130,6 +130,24 @@ public class ReceiveBuilder { return matchUnchecked(type, predicate, apply); } + /** + * Add a new case statement to this builder. + * + * @param type + * a type to match the argument against + * @param externalPredicate + * a external predicate that will be evaluated if the type matches + * @param apply + * an action to apply to the argument if the type matches and the + * predicate returns true + * @return a builder with the case statement added + */ + public
ReceiveBuilder match(final Class
type, + final java.util.function.BooleanSupplier externalPredicate, + final FI.UnitApply
apply) {
+ return matchUnchecked(type, externalPredicate, apply);
+ }
+
/**
* Add a new case statement to this builder without compile time type check.
* Should normally not be used, but when matching on class with generic type
@@ -164,6 +182,38 @@ public class ReceiveBuilder {
return this;
}
+ /**
+ * Add a new case statement to this builder without compile time type check.
+ * Should normally not be used, but when matching on class with generic type
+ * argument it can be useful, e.g. List.class and
+ * (List<String> list) -> {}.
+ *
+ * @param type
+ * a type to match the argument against
+ * @param externalPredicate
+ * a external predicate that will be evaluated if the type matches
+ * @param apply
+ * an action to apply to the argument if the type matches and the
+ * predicate returns true
+ * @return a builder with the case statement added
+ */
+ @SuppressWarnings("unchecked")
+ public
ReceiveBuilder matchUnchecked(final Class> type, + final java.util.function.BooleanSupplier externalPredicate, + final FI.UnitApply
apply) { + FI.Predicate fiPredicate = new FI.Predicate() { + @Override + public boolean defined(Object o) { + return type.isInstance(o) && + externalPredicate.getAsBoolean(); + } + }; + + addStatement(new UnitCaseStatement