From c3a28e6849972d1bbca2a507006d0c3c9e466aca Mon Sep 17 00:00:00 2001 From: Christopher Bohn <bohn@unl.edu> Date: Tue, 4 Feb 2020 11:49:13 -0600 Subject: [PATCH] Refactored for improved testability --- .../edu/unl/cse/csce361/socket_chat/Chat.java | 70 ++++++++++++------- 1 file changed, 45 insertions(+), 25 deletions(-) diff --git a/src/main/java/edu/unl/cse/csce361/socket_chat/Chat.java b/src/main/java/edu/unl/cse/csce361/socket_chat/Chat.java index cffcb5b..78fceee 100644 --- a/src/main/java/edu/unl/cse/csce361/socket_chat/Chat.java +++ b/src/main/java/edu/unl/cse/csce361/socket_chat/Chat.java @@ -273,40 +273,58 @@ public class Chat { PrintStream remoteOutput) { // "Connection established. Host goes first." System.out.println(bundle.getString("connection.info.ready")); - String message = ""; boolean keepTalking = true; boolean myTurnToTalk = isHost; + while (keepTalking) { + keepTalking = communicateOneMessage(localInput, remoteInput, localOutput, remoteOutput, myTurnToTalk); + myTurnToTalk = !myTurnToTalk; + } + } + + /** + * Processes a single message from one chatter to the other. + * + * @param localInput a {@link java.io.BufferedReader} that gets user input from this end of the connection + * @param remoteInput a {@link java.io.BufferedReader} that gets user input from the other end of the connection + * @param localOutput a {@link java.io.PrintStream} that outputs to the user at this end of the connection + * @param remoteOutput a {@link java.io.PrintStream} that outputs to the user at the other end of the connection + * @param localMessage {@code true} if the message to be processed will originate locally, {@code false} if remotely + * @return {@code true} if the program should continue to execute after processing the message; {@code false} + * otherwise + */ + boolean communicateOneMessage(BufferedReader localInput, BufferedReader remoteInput, + PrintStream localOutput, PrintStream remoteOutput, boolean localMessage) { + String message = ""; + boolean keepTalking = true; try { - while (keepTalking) { - try { - if (myTurnToTalk) { - message = localInput.readLine(); - remoteOutput.println(encipher(message)); + try { + if (localMessage) { + message = localInput.readLine(); + remoteOutput.println(encipher(message)); + } else { + String encipheredMessage = remoteInput.readLine(); + if (encipheredMessage != null) { + message = decipher(encipheredMessage); + localOutput.println(message); } else { - String encipheredMessage = remoteInput.readLine(); - if (encipheredMessage != null) { - message = decipher(encipheredMessage); - localOutput.println(message); - } else { - // "Received null message: lost connection to remote chatter. Terminating." - localOutput.println(bundle.getString("communicate.error.nullMessageFromRemote")); - keepTalking = false; - } + // "Received null message: lost connection to remote chatter. Terminating." + localOutput.println(bundle.getString("communicate.error.nullMessageFromRemote")); + keepTalking = false; } - } catch (SocketException ignored) { - // "Unable to exchange message: lost connection to remote chatter. Terminating." - localOutput.println(bundle.getString("communicate.error.cannotSendMessage")); - keepTalking = false; } - if (keepTalking && keywords.contains(message)) { - keepTalking = handleKeyword(message, myTurnToTalk, localInput, localOutput); - } - myTurnToTalk = !myTurnToTalk; + } catch (SocketException ignored) { + // "Unable to exchange message: lost connection to remote chatter. Terminating." + localOutput.println(bundle.getString("communicate.error.cannotSendMessage")); + keepTalking = false; + } + if (keepTalking && keywords.contains(message)) { + keepTalking = handleKeyword(message, localMessage, localInput, localOutput); } } catch (IOException ioException) { System.err.println("Connection dropped: " + ioException); System.exit(1); } + return keepTalking; } /** @@ -319,11 +337,13 @@ public class Chat { * @param output a {@link java.io.PrintStream} for output to the user * @return {@code true} if the program should continue to execute after processing the keyword; {@code false} * otherwise + * @throws IOException if an I/O error occurs while reading user responses to prompts */ - private boolean handleKeyword(String keyword, boolean localMessage, BufferedReader input, PrintStream output) { + boolean handleKeyword(String keyword, boolean localMessage, BufferedReader input, PrintStream output) + throws IOException { if (keyword.equals(bundle.getString("communicate.keyword.exit"))) { return false; - // Un-comment this next code block in step 3 of the assignment. + // Un-comment this next code block in step 3 of the assignment. /* } else if (keyword.equals(bundle.getString("communicate.keyword.setLocale"))) { if (localMessage) { -- GitLab