Skip to content
Snippets Groups Projects
Commit 2ac99769 authored by Christopher Bohn's avatar Christopher Bohn :thinking:
Browse files

Rewrote assignment as pair assignment w/ whitebox testing; added Javadoc

parent b1e76fe6
No related branches found
No related tags found
No related merge requests found
......@@ -72,7 +72,7 @@ target/
# Miscellaneous
tmp/
*.tmp
*.bak
*.bk
*.swp
This diff is collapsed.
......@@ -52,7 +52,7 @@ feel for how the program works.
the client sets up a `Socket` to connect to the host
- The host and client alternate turns sending Strings to each other over the
socket
- When theres's message from either the host or client consisting solely of
- When there's message from either the host or client consisting solely of
the keyword `EXIT` in all capital letters, the program terminates.
### Internationalization
......@@ -70,7 +70,7 @@ user input to a string.
The key-value pairs are in a properties file in the `.../resources/` directory.
The files are of the form `basename_XX.properties`, where XX is the 2- or 3-
character language code. Example langauge codes are `en` for English, `fr` for
character language code. Example language codes are `en` for English, `fr` for
French, `de` for German, `zh` for Chinese, and `tlh` for Klingon. If you decide
to do full localization then the suffix includes a language code, a country
code, and possibly a variant code. We'll limit ourselves to just the language
......
......@@ -11,7 +11,7 @@ import static java.lang.Thread.sleep;
public class Chat {
private static final int MAXIMUM_CONNECTION_ATTEMPTS = 10;
private Socket socket;
private final Socket socket;
private boolean isHost;
private ResourceBundle bundle;
private Set<String> keywords;
......@@ -21,6 +21,11 @@ public class Chat {
socket = connect(new Scanner(System.in));
}
/**
* Overrides the system's default Locale.
*
* @param locale the {@link java.util.Locale} for this application to use
*/
private void setLocale(Locale locale) {
bundle = ResourceBundle.getBundle("socketchat", locale);
Set<String> culledKeySet = bundle.keySet().stream()
......@@ -34,6 +39,12 @@ public class Chat {
* THESE METHODS SET UP AND TEAR DOWN CONNECTION
*/
/**
* Establishes the connection between the host and the client.
*
* @param userInput a {@link java.util.Scanner} to read user responses
* @return the {@link java.net.Socket} for the connection
*/
@SuppressWarnings("WeakerAccess")
public Socket connect(Scanner userInput) {
String yes = bundle.getString("connection.response.yes");
......@@ -54,6 +65,9 @@ public class Chat {
return socket;
}
/**
* Closes the socket connecting the host and the client.
*/
@SuppressWarnings("WeakerAccess")
public void disconnect() {
try {
......@@ -65,6 +79,14 @@ public class Chat {
}
}
/**
* Establishes the host end of the connection between the host and the client
*
* @param userInput a {@link java.util.Scanner} to read user responses
* @return the {@link java.net.Socket} for the connection
* @throws IOException if the local hostname cannot be resolved into an address or if an I/O error occurs while
* creating a socket or waiting for a connection
*/
private Socket connectAsServer(Scanner userInput) throws IOException {
byte[] address = InetAddress.getLocalHost().getAddress();
// "Host address: ..."
......@@ -87,6 +109,13 @@ public class Chat {
return serverSocket.accept();
}
/**
* Establishes the host end of the connection between the host and the client
*
* @param userInput a {@link java.util.Scanner} to read user responses
* @return the {@link java.net.Socket} for the connection
* @throws IOException if an I/O error occurs while creating a socket or waiting for a connection
*/
private Socket connectAsClient(Scanner userInput) throws IOException {
byte[] address = getRemoteHostAddress(userInput);
// "Enter port host is opening at ..."
......@@ -122,6 +151,12 @@ public class Chat {
return socket;
}
/**
* Obtains the host's IP address from user input
*
* @param userInput a {@link java.util.Scanner} to read user responses
* @return the host's IP address
*/
private byte[] getRemoteHostAddress(Scanner userInput) {
// This assumes IPv4. Probably a good assumption.
boolean haveGoodAddress = false;
......@@ -163,6 +198,12 @@ public class Chat {
return address;
}
/**
* Obtains the host's network port from user input
*
* @param userInput a {@link java.util.Scanner} to read user responses
* @return the host's network port
*/
private int getPort(String prompt, Scanner userInput) {
boolean haveGoodNumber = false;
int port = 0;
......@@ -196,6 +237,10 @@ public class Chat {
* THESE METHODS PERFORM CHAT AFTER CONNECTION IS SET UP
*/
/**
* <p>Relays messages between the host and the client.</p>
* <p>Implementation detail: delegates to another method, using dependency injection.</p>
*/
@SuppressWarnings("WeakerAccess")
public void communicate() {
try {
......@@ -213,6 +258,14 @@ public class Chat {
}
}
/**
* Where the real work for {@link #communicate()} happens.
*
* @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
*/
@SuppressWarnings("SameParameterValue")
private void communicate(BufferedReader localInput,
BufferedReader remoteInput,
......@@ -256,15 +309,28 @@ public class Chat {
}
}
/**
* Processes keywords to effect changes in the program, such as exiting, changing Locales, and changing Ciphers.
*
* @param keyword the keyword to be processed
* @param localMessage {@code true} if the message came from the local user, {@code false} if the message came
* from the remote user
* @param input a {@link java.io.BufferedReader} for user input
* @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
*/
private boolean handleKeyword(String keyword, boolean localMessage, BufferedReader input, PrintStream output) {
if (keyword.equals(bundle.getString("communicate.keyword.exit"))) {
return false;
// Un-comment this next code block in step 3 of the assignment.
/*
} else if (keyword.equals(bundle.getString("communicate.keyword.setLocale"))) {
if (localMessage) {
Prompt user using output.println() (be sure to use i18n properties)
and get response using input.readLine(). Get the appropriate Locale and call
setLocale( ... );
// Here, you should
// prompt the user using output.println() (be sure to use i18n properties)
// and get response using input.readLine(). Get the appropriate Locale and call
// setLocale( ... );
}
else {
output.println("Remote chatter is making updates; please be patient."); // replace with i18n property
......@@ -277,15 +343,13 @@ public class Chat {
}
private String encipher(String plaintext) {
// String ciphertext = ...;
// return ciphertext;
return plaintext;
String ciphertext = plaintext; // Replace this with a call to cipherBehavior.encipher(plaintext)
return ciphertext;
}
private String decipher(String ciphertext) {
// String plaintext = ...;
// return plaintext;
return ciphertext;
String plaintext = ciphertext; // Replace this with a call to cipherBehavior.decipher(plaintext)
return plaintext;
}
public static void main(String[] args) {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment