All Downloads are FREE. Search and download functionalities are using the official Maven repository.

akka.japi.pf.ReceiveBuilder Maven / Gradle / Ivy

/*
 * Copyright (C) 2009-2020 Lightbend Inc. 
 */

package akka.japi.pf;

import akka.actor.AbstractActor.Receive;
import scala.PartialFunction;
import scala.runtime.BoxedUnit;

/**
 * Used for building a partial function for {@link akka.actor.AbstractActor#createReceive()
 * AbstractActor.createReceive()}.
 *
 * 

There is both a match on type only, and a match on type and predicate. * *

Inside an actor you can use it like this: * *

Example: * *

 * @Override
 * public Receive createReceive() {
 *   return receiveBuilder()
 *     .match(Double.class, d -> {
 *       getSender().tell(d.isNaN() ? 0 : d, self());
 *     })
 *     .match(Integer.class, i -> {
 *       getSender().tell(i * 10, self());
 *     })
 *     .match(String.class, s -> s.startsWith("foo"), s -> {
 *       getSender().tell(s.toUpperCase(), self());
 *     })
 *     .build()
 *   );
 * }
 * 
*/ public class ReceiveBuilder { private PartialFunction statements = null; protected void addStatement(PartialFunction statement) { if (statements == null) statements = statement; else statements = statements.orElse(statement); } /** * Build a {@link scala.PartialFunction} from this builder. After this call the builder will be * reset. * * @return a PartialFunction for this builder. */ public Receive build() { PartialFunction empty = CaseStatement.empty(); if (statements == null) return new Receive(empty); else return new Receive(statements.orElse(empty)); // FIXME why no new Receive(statements)? } /** * Return a new {@link ReceiveBuilder} with no case statements. They can be added later as the * returned {@link ReceiveBuilder} is a mutable object. * * @return a builder with no case statements */ public static ReceiveBuilder create() { return new ReceiveBuilder(); } /** * Add a new case statement to this builder. * * @param type a type to match the argument against * @param apply an action to apply to the argument if the type matches * @return a builder with the case statement added */ public

ReceiveBuilder match(final Class

type, final FI.UnitApply

apply) { return matchUnchecked(type, 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 argument it can be useful, e.g. * List.class and (List<String> list) -> {}. * * @param type a type to match the argument against * @param apply an action to apply to the argument if the type matches * @return a builder with the case statement added */ @SuppressWarnings("unchecked") public ReceiveBuilder matchUnchecked(final Class type, final FI.UnitApply apply) { FI.Predicate predicate = new FI.Predicate() { @Override public boolean defined(Object o) { return type.isInstance(o); } }; addStatement(new UnitCaseStatement(predicate, (FI.UnitApply) apply)); return this; } /** * Add a new case statement to this builder. * * @param type a type to match the argument against * @param predicate a predicate that will be evaluated on the argument 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 FI.TypedPredicate

predicate, final FI.UnitApply

apply) { 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 argument it can be useful, e.g. * List.class and (List<String> list) -> {}. * * @param type a type to match the argument against * @param predicate a predicate that will be evaluated on the argument 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 FI.TypedPredicate predicate, final FI.UnitApply

apply) { FI.Predicate fiPredicate = new FI.Predicate() { @Override public boolean defined(Object o) { if (!type.isInstance(o)) return false; else return ((FI.TypedPredicate) predicate).defined(o); } }; addStatement(new UnitCaseStatement(fiPredicate, (FI.UnitApply) apply)); 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 an 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(fiPredicate, (FI.UnitApply) apply)); return this; } /** * Add a new case statement to this builder. * * @param object the object to compare equals with * @param apply an action to apply to the argument if the object compares equal * @return a builder with the case statement added */ public

ReceiveBuilder matchEquals(final P object, final FI.UnitApply

apply) { addStatement( new UnitCaseStatement( new FI.Predicate() { @Override public boolean defined(Object o) { return object.equals(o); } }, apply)); return this; } /** * Add a new case statement to this builder. * * @param object the object to compare equals with * @param predicate a predicate that will be evaluated on the argument if the object compares * equal * @param apply an action to apply to the argument if the object compares equal * @return a builder with the case statement added */ public

ReceiveBuilder matchEquals( final P object, final FI.TypedPredicate

predicate, final FI.UnitApply

apply) { addStatement( new UnitCaseStatement( new FI.Predicate() { @Override public boolean defined(Object o) { if (!object.equals(o)) return false; else { @SuppressWarnings("unchecked") P p = (P) o; return predicate.defined(p); } } }, apply)); return this; } /** * Add a new case statement to this builder. * * @param object the object to compare equals with * @param externalPredicate an external predicate that will be evaluated if the object compares * equal * @param apply an action to apply to the argument if the object compares equal * @return a builder with the case statement added */ @SuppressWarnings("unchecked") public

ReceiveBuilder matchEquals( final P object, final java.util.function.BooleanSupplier externalPredicate, final FI.UnitApply

apply) { final FI.Predicate predicate = o -> object.equals(o) && externalPredicate.getAsBoolean(); addStatement(new UnitCaseStatement<>(predicate, (FI.UnitApply) apply)); return this; } private static final FI.Predicate ALWAYS_TRUE = (input) -> true; /** * Add a new case statement to this builder, that matches any argument. * * @param apply an action to apply to the argument * @return a builder with the case statement added */ public ReceiveBuilder matchAny(final FI.UnitApply apply) { addStatement(new UnitCaseStatement<>(ALWAYS_TRUE, apply)); return this; } /** * Add a new case statement to this builder, that pass the test of the predicate. * * @param externalPredicate an external predicate that will always be evaluated. * @param apply an action to apply to the argument * @return a builder with the case statement added */ public ReceiveBuilder matchAny( final java.util.function.BooleanSupplier externalPredicate, final FI.UnitApply apply) { final FI.Predicate predicate = o -> externalPredicate.getAsBoolean(); addStatement(new UnitCaseStatement<>(predicate, apply)); return this; } }