From 7b012b24d88c19e9986db78bf0ab92bf25dc3d47 Mon Sep 17 00:00:00 2001 From: =?utf8?q?David=20=E2=80=98Bombe=E2=80=99=20Roden?= Date: Thu, 16 Oct 2014 07:05:52 +0200 Subject: [PATCH] Move connection establishing logic into its own handler. --- .../java/net/pterodactylus/irc/Connection.java | 39 ++++++------ .../irc/connection/ConnectionEstablishHandler.java | 70 ++++++++++++++++++++++ 2 files changed, 90 insertions(+), 19 deletions(-) create mode 100644 src/main/java/net/pterodactylus/irc/connection/ConnectionEstablishHandler.java diff --git a/src/main/java/net/pterodactylus/irc/Connection.java b/src/main/java/net/pterodactylus/irc/Connection.java index 0f5a065..cc1f9c8 100644 --- a/src/main/java/net/pterodactylus/irc/Connection.java +++ b/src/main/java/net/pterodactylus/irc/Connection.java @@ -36,8 +36,11 @@ import java.util.List; import java.util.Map; import java.util.Set; import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicBoolean; + import javax.net.SocketFactory; +import net.pterodactylus.irc.connection.ConnectionEstablishHandler; import net.pterodactylus.irc.event.ChannelJoined; import net.pterodactylus.irc.event.ChannelLeft; import net.pterodactylus.irc.event.ChannelMessageReceived; @@ -69,6 +72,7 @@ import com.google.common.base.Optional; import com.google.common.collect.Maps; import com.google.common.collect.Sets; import com.google.common.eventbus.EventBus; +import com.google.common.eventbus.Subscribe; import com.google.common.io.Closeables; import com.google.common.primitives.Ints; import com.google.common.primitives.Longs; @@ -123,7 +127,7 @@ public class Connection extends AbstractExecutionThreadService implements Servic private ConnectionHandler connectionHandler; /** Whether the connection has already been established. */ - private boolean established; + private final AtomicBoolean established = new AtomicBoolean(); /** * Creates a new connection. @@ -173,7 +177,7 @@ public class Connection extends AbstractExecutionThreadService implements Servic * false} otherwise */ public boolean established() { - return established; + return established.get(); } /** @@ -363,6 +367,7 @@ public class Connection extends AbstractExecutionThreadService implements Servic return; } + eventBus.register(this); /* now read replies and react. */ try { /* some status variables. */ @@ -376,6 +381,8 @@ public class Connection extends AbstractExecutionThreadService implements Servic Map nickPrefixes = Maps.newHashMap(); Set channelTypes = Sets.newHashSet(); + ConnectionEstablishHandler connectionEstablishHandler = new ConnectionEstablishHandler(eventBus, this); + while (connected) { Reply reply = connectionHandler.readReply(); eventBus.post(new ReplyReceived(this, reply)); @@ -460,15 +467,8 @@ public class Connection extends AbstractExecutionThreadService implements Servic } else if (command.equalsIgnoreCase("PING")) { connectionHandler.sendCommand("PONG", getOptional(parameters, 0), getOptional(parameters, 1)); - /* replies 001-004 don’t hold information but they have to be sent on a successful connection. */ - } else if (command.equals("001")) { - connectionStatus |= 0x01; - } else if (command.equals("002")) { - connectionStatus |= 0x02; - } else if (command.equals("003")) { - connectionStatus |= 0x04; - } else if (command.equals("004")) { - connectionStatus |= 0x08; + } else if (connectionEstablishHandler.willHandle(reply)) { + connectionEstablishHandler.handleReply(reply); /* 005 originally was a bounce message, now used to transmit useful information about the server. */ } else if (command.equals("005")) { @@ -510,13 +510,6 @@ public class Connection extends AbstractExecutionThreadService implements Servic } else { eventBus.post(new UnknownReplyReceived(this, reply)); } - - if ((connectionStatus == 0x0f) && (connectionStatus != oldConnectionStatus)) { - /* connection succeeded! */ - established = true; - eventBus.post(new ConnectionEstablished(this)); - } - oldConnectionStatus = connectionStatus; } eventBus.post(new ConnectionClosed(this)); } catch (IOException ioe1) { @@ -526,7 +519,8 @@ public class Connection extends AbstractExecutionThreadService implements Servic logger.error("Runtime error", re1); eventBus.post(new ConnectionClosed(this, re1)); } finally { - established = false; + established.set(false); + eventBus.unregister(this); logger.info("Closing Connection."); try { Closeables.close(connectionHandler, true); @@ -537,6 +531,13 @@ public class Connection extends AbstractExecutionThreadService implements Servic } + @Subscribe + public void connectionEstablished(ConnectionEstablished connectionEstablished) { + if (connectionEstablished.connection() == this) { + established.set(true); + } + } + // // PRIVATE METHODS // diff --git a/src/main/java/net/pterodactylus/irc/connection/ConnectionEstablishHandler.java b/src/main/java/net/pterodactylus/irc/connection/ConnectionEstablishHandler.java new file mode 100644 index 0000000..da608ca --- /dev/null +++ b/src/main/java/net/pterodactylus/irc/connection/ConnectionEstablishHandler.java @@ -0,0 +1,70 @@ +package net.pterodactylus.irc.connection; + +import static java.util.Arrays.asList; + +import net.pterodactylus.irc.Connection; +import net.pterodactylus.irc.Reply; +import net.pterodactylus.irc.event.ConnectionEstablished; + +import com.google.common.eventbus.EventBus; + +/** + * Handles the necessary commands that establish a connection. + * + * @author David ‘Bombe’ Roden + */ +public class ConnectionEstablishHandler implements Handler { + + private static final int FIRST_COMMAND_RECEIVED = 0x01; + private static final int SECOND_COMMAND_RECEIVED = 0x02; + private static final int THIRD_COMMAND_RECEIVED = 0x04; + private static final int FOURTH_COMMAND_RECEIVED = 0x08; + private static final int ALL_COMMANDS_RECEIVED = 0x0f; + + private final EventBus eventBus; + private final Connection connection; + private int connectionStatus; + private int oldConnectionStatus; + + public ConnectionEstablishHandler(EventBus eventBus, + Connection connection) { + this.eventBus = eventBus; + this.connection = connection; + } + + @Override + public boolean willHandle(Reply reply) { + return asList("001", "002", "003", "004").contains(reply.command()); + } + + @Override + public void handleReply(Reply reply) { + String command = reply.command(); + /* replies 001-004 don’t hold information but they + * have to be sent on a successful connection. */ + if (command.equals("001")) { + connectionStatus |= FIRST_COMMAND_RECEIVED; + } else if (command.equals("002")) { + connectionStatus |= SECOND_COMMAND_RECEIVED; + } else if (command.equals("003")) { + connectionStatus |= THIRD_COMMAND_RECEIVED; + } else if (command.equals("004")) { + connectionStatus |= FOURTH_COMMAND_RECEIVED; + } + + if (hasConnectionStatusChanged() + && isFinalConnectionStatusReached()) { + eventBus.post(new ConnectionEstablished(connection)); + } + oldConnectionStatus = connectionStatus; + } + + private boolean hasConnectionStatusChanged() { + return connectionStatus != oldConnectionStatus; + } + + private boolean isFinalConnectionStatusReached() { + return connectionStatus == ALL_COMMANDS_RECEIVED; + } + +} -- 2.7.4