/*
* Copyright (c) 2013-2014, Parallel Universe Software Co. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
* the Eclipse Foundation
*
* or (per the licensee's choosing)
*
* under the terms of the GNU Lesser General Public License version 3.0
* as published by the Free Software Foundation.
*/
package co.paralleluniverse.actors.behaviors;
import co.paralleluniverse.actors.ActorRef;
import co.paralleluniverse.actors.MessageProcessor;
import java.util.Objects;
/**
* A fluent interface for creating {@link MessageProcessor}s that select messages matching a few simple criteria.
*
* @author pron
*/
public abstract class MessageSelector<M1, M2> implements MessageProcessor<Object, M2> {
/**
* Creates a new {@link MessageSelector}.
*
* @return A new {@code MessageSelector} that selects all messages.
*/
public static <M> MessageSelector<Object, M> select() {
return new MessageSelector<Object, M>() {
@Override
public boolean matches(Object m) {
return true;
}
};
}
/**
* Selects messages of the given class.
*
* @param type The class of the messages to select.
* @return a new {@link MessageSelector} that selects messages of the given class.
*/
public <M extends M1> MessageSelector<M1, M> ofType(final Class<M> type) {
return new MessageSelector<M1, M>() {
@Override
public boolean matches(M1 m) {
return MessageSelector.this.matches(m) && type.isInstance(m);
}
};
}
/**
* Creates a {@link MessageProcessor} that selects {@link FromMessage}s from the given actor.
*
* @param actor The sender of the message to select (should be equal to {@link FromMessage#getFrom() })
* @return a new {@link MessageSelector} that selects messages from the given sender.
*/
public <M extends FromMessage> MessageSelector<M, M> from(final ActorRef<?> actor) {
return new MessageSelector<M, M>() {
@Override
public boolean matches(M m) {
return MessageSelector.this.matches((M1) m) && m instanceof FromMessage && Objects.equals(actor, ((FromMessage) m).getFrom());
}
};
}
/**
* Returns a {@link MessageSelector} that selects {@link IdMessage}s with the given id.
*
* @param id The id of the message to select (should be equal to {@link IdMessage#getId() })
* @return a new {@link MessageSelector} that selects messages from the given id.
*/
public <M extends IdMessage> MessageSelector<M, M> withId(final Object id) {
return new MessageSelector<M, M>() {
@Override
public boolean matches(M m) {
return MessageSelector.this.matches((M1) m) && m instanceof IdMessage && Objects.equals(id, ((IdMessage) m).getId());
}
};
}
protected abstract boolean matches(M1 m);
@Override
public final M2 process(Object m) {
return (M2) (matches((M1) m) ? m : null);
}
private MessageSelector() {
}
}