package com.limegroup.gnutella;
import java.net.InetSocketAddress;
import java.util.concurrent.Executor;
import org.limewire.inspection.InspectionPoint;
import com.google.inject.Inject;
import com.google.inject.Singleton;
import com.google.inject.name.Named;
import com.limegroup.gnutella.connection.RoutedConnection;
import com.limegroup.gnutella.messages.Message;
import com.limegroup.gnutella.util.LimeWireUtils;
/**
* Dispatches messages to the MessageRouter.
*/
@Singleton
public class MessageDispatcher {
private final Executor DISPATCH;
private final MessageRouter messageRouter;
@InspectionPoint("routed messages")
private final Message.MessageCounter messageCounter = new Message.MessageCounter(LimeWireUtils.isBetaRelease() ? 300 : 30);
@Inject
public MessageDispatcher(MessageRouter messageRouter, @Named("messageExecutor") Executor dispatch) {
this.messageRouter = messageRouter;
this.DISPATCH = dispatch;
}
/** Dispatches a runnable, to allow arbitrary runnables to be processed on the message thread. */
public void dispatch(Runnable r) {
DISPATCH.execute(r);
}
/**
* Dispatches a UDP message.
*/
public void dispatchUDP(Message m, InetSocketAddress addr) {
DISPATCH.execute(new UDPDispatch(messageRouter, m, addr, messageCounter));
}
/**
* Dispatches a Multicast message.
*/
public void dispatchMulticast(Message m, InetSocketAddress addr) {
DISPATCH.execute(new MulticastDispatch(messageRouter, m, addr, messageCounter));
}
/**
* Dispatches a TCP message.
*/
public void dispatchTCP(Message m, RoutedConnection conn) {
DISPATCH.execute(new TCPDispatch(messageRouter, m, conn, messageCounter));
}
private static abstract class Dispatch implements Runnable {
protected final MessageRouter messageRouter;
protected final Message m;
protected final Message.MessageCounter counter;
Dispatch(MessageRouter messageRouter, Message m,
Message.MessageCounter counter) {
this.messageRouter = messageRouter;
this.m = m;
this.counter = counter;
}
public void run() {
counter.countMessage(m);
dispatch();
}
protected abstract void dispatch();
}
private static class UDPDispatch extends Dispatch {
private final InetSocketAddress addr;
UDPDispatch(MessageRouter messageRouter,
Message m,
InetSocketAddress addr,
Message.MessageCounter counter) {
super(messageRouter,m, counter);
this.addr = addr;
}
@Override
protected void dispatch() {
messageRouter.handleUDPMessage(m, addr);
}
}
private static class MulticastDispatch extends Dispatch {
private final InetSocketAddress addr;
MulticastDispatch(MessageRouter messageRouter,
Message m,
InetSocketAddress addr,
Message.MessageCounter counter) {
super(messageRouter,m, counter);
this.addr = addr;
}
@Override
protected void dispatch() {
messageRouter.handleMulticastMessage(m, addr);
}
}
private static class TCPDispatch extends Dispatch {
private final RoutedConnection conn;
TCPDispatch(MessageRouter messageRouter,
Message m,
RoutedConnection conn,
Message.MessageCounter counter) {
super(messageRouter,m, counter);
this.conn = conn;
}
@Override
protected void dispatch() {
messageRouter.handleMessage(m, conn);
}
}
}