gclc clean up. socket and swt configured for current stable gclc

gclc items moved around. gclc ready for release.
gclc internationalization
gclc extract command interface
socket server issue (close socket) "fixed"
swt minor improvments (user con't input commands while the application
is actually running one, the history keeps track of mispelled commands
to).
This commit is contained in:
2016-06-02 12:50:36 -04:00
parent 87a668d308
commit 1ffe321898
34 changed files with 2139 additions and 1100 deletions

View File

@@ -0,0 +1,77 @@
/*
* Copyright E. Bigeon (2014)
*
* emmanuel@bigeon.fr
*
* This software is a computer program whose purpose is to
* Socket implementation of GCLC.
*
* This software is governed by the CeCILL license under French law and
* abiding by the rules of distribution of free software. You can use,
* modify and/or redistribute the software under the terms of the CeCILL
* license as circulated by CEA, CNRS and INRIA at the following URL
* "http://www.cecill.info".
*
* As a counterpart to the access to the source code and rights to copy,
* modify and redistribute granted by the license, users are provided only
* with a limited warranty and the software's author, the holder of the
* economic rights, and the successive licensors have only limited
* liability.
*
* In this respect, the user's attention is drawn to the risks associated
* with loading, using, modifying and/or developing or reproducing the
* software by the user in light of its specific status of free software,
* that may mean that it is complicated to manipulate, and that also
* therefore means that it is reserved for developers and experienced
* professionals having in-depth computer knowledge. Users are therefore
* encouraged to load and test the software's suitability as regards their
* requirements in conditions enabling the security of their systems and/or
* data to be ensured and, more generally, to use and operate it in the
* same conditions as regards security.
*
* The fact that you are presently reading this means that you have had
* knowledge of the CeCILL license and that you accept its terms.
*/
/**
* gclc-socket:fr.bigeon.gclc.socket.ConsoleRunnable.java
* Created on: Jun 1, 2016
*/
package fr.bigeon.gclc.socket;
import fr.bigeon.gclc.ConsoleApplication;
/** A runnable class that will actually have the application running.
*
* @author Emmanuel Bigeon */
public class ConsoleRunnable implements Runnable {
/** The actual application */
private final ConsoleApplication app;
/** The synchronization object */
private final Object promptingLock;
/** @param app the application
* @param promptingLock the synchronization object */
public ConsoleRunnable(ConsoleApplication app, Object promptingLock) {
super();
this.app = app;
this.promptingLock = promptingLock;
}
/* (non-Javadoc)
* @see java.lang.Runnable#run() */
@Override
public void run() {
app.start();
synchronized (promptingLock) {
// release all waiting elements before ending
promptingLock.notifyAll();
}
}
/** Stop the application (it will finish its current operation) */
public void stop() {
app.exit();
}
}

View File

@@ -44,7 +44,10 @@ import java.io.PipedOutputStream;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketException;
import java.util.Arrays;
import java.util.logging.Level;
import java.util.logging.Logger;
import fr.bigeon.gclc.ConsoleApplication;
import fr.bigeon.gclc.ConsoleManager;
@@ -70,16 +73,20 @@ import fr.bigeon.smu.StringEncoder;
* @author Emmanuel Bigeon */
public class SocketConsoleApplicationShell implements Runnable {
/**
*
*/
private static final String INTERRUPTION_WHILE_WORKING = "Interruption while application was working"; //$NON-NLS-1$
/** The end of line character */
protected static final String EOL = "\n"; //$NON-NLS-1$
/** The encoder */
private static final StringEncoder ENCODER = new StringEncoder("%", Arrays.asList(EOL)); //$NON-NLS-1$
private static final StringEncoder ENCODER = new StringEncoder("%", //$NON-NLS-1$
Arrays.asList(EOL));
/** The class logger */
private static final Logger LOGGER = Logger
.getLogger(SocketConsoleApplicationShell.class.getName());
/** The listening port */
private final int port;
/** The output */
private PrintWriter output;
/** The input reader */
private BufferedReader input;
/** The input */
private final PipedInputStream consoleInput = new PipedInputStream();
/** The application */
@@ -88,180 +95,174 @@ public class SocketConsoleApplicationShell implements Runnable {
private final String close;
/** The running status */
private boolean running;
/** If the prompt should be next activity */
private boolean doPrompt = false;
/** An object to lock on for prompt */
private final Object promptingLock = new Object();
/** The console manager implementation */
private final ConsoleManager consoleManager = new ConsoleManager() {
private String prompt = new String();
private StringBuffer buffer = new StringBuffer();
@Override
public void setPrompt(String prompt) {
this.prompt = prompt;
}
@SuppressWarnings("synthetic-access")
@Override
public String prompt(String message) {
buffer.append(message);
String userInput = new String();
boolean prompting = true;
while (prompting) {
output.println(ENCODER.encode(buffer.toString()));
try {
synchronized (promptingLock) {
doPrompt = true;
promptingLock.notify();
}
userInput = input.readLine();
doPrompt = false;
prompting = false;
} catch (final IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
buffer = new StringBuffer();
return userInput;
}
@Override
public String prompt() {
return prompt(prompt);
}
@Override
public void println(String message) {
buffer.append(message + EOL);
}
@Override
public void println() {
buffer.append(EOL);
}
@Override
public void print(String text) {
buffer.append(text);
}
@Override
public String getPrompt() {
return prompt;
}
};
private final ThreadedServerConsoleManager consoleManager = new ThreadedServerConsoleManager(
ENCODER, promptingLock);
/** The auto close flag. if this is true, every request closes the session
* after its call */
private final boolean autoClose;
/** The server socket */
private ServerSocket serverSocket;
/** The application shutdown string */
private final String applicationShutdown;
/** The runnable class that will actually have the application running.
*
* @author Emmanuel Bigeon */
private class ConsoleRunnable implements Runnable {
/**
*
*/
public ConsoleRunnable() {
// TODO Auto-generated constructor stub
}
/* (non-Javadoc)
* @see java.lang.Runnable#run() */
@SuppressWarnings("synthetic-access")
@Override
public void run() {
running = true;
app.start();
running = false;
synchronized (promptingLock) {
promptingLock.notifyAll();
}
}
}
/** TODO Describe SocketConsoleApplicationShell.java Constructor
/** Create a socket application shell which will listen on the given port
* and close session upon the provided string reception by client
*
* @param port the port to listen to
* @param close the session closing command */
public SocketConsoleApplicationShell(int port, String close) {
* @param close the session closing command
* @param applicationShutdown the appication shut down command */
public SocketConsoleApplicationShell(int port, String close,
String applicationShutdown) {
this.port = port;
this.close = close;
this.applicationShutdown = applicationShutdown;
this.autoClose = false;
}
/** TODO Describe SocketConsoleApplicationShell.java Constructor
/** Create a socket application shell which will listen on the given port
* and auto close session after one instruction
*
* @param port the port to listen to
* @param autoClose if the session must be closed once the request has been
* sent */
public SocketConsoleApplicationShell(int port, boolean autoClose) {
* sent
* @param applicationShutdown the application shutdown command */
public SocketConsoleApplicationShell(int port, boolean autoClose,
String applicationShutdown) {
this.port = port;
this.close = null;
this.autoClose = autoClose;
this.applicationShutdown = applicationShutdown;
this.close = autoClose ? null : "close"; //$NON-NLS-1$
}
/* (non-Javadoc)
* @see java.lang.Runnable#run() */
@Override
public void run() {
try (ServerSocket serverSocket = new ServerSocket(port)) {
final ConsoleRunnable runnable = new ConsoleRunnable();
try (ServerSocket actualServerSocket = new ServerSocket(port)) {
this.serverSocket = actualServerSocket;
final ConsoleRunnable runnable = new ConsoleRunnable(app,
promptingLock);
final Thread appTh = new Thread(runnable);
running = true;
try (PipedOutputStream outStream = new PipedOutputStream();
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(outStream))) {
BufferedWriter writer = new BufferedWriter(
new OutputStreamWriter(outStream))) {
consoleInput.connect(outStream);
try (BufferedReader inBuf = new BufferedReader(new InputStreamReader(consoleInput))) {
input = inBuf;
while (running) {
try (Socket clientSocket = serverSocket.accept();
PrintWriter out = new PrintWriter(clientSocket.getOutputStream(), true);
BufferedReader in = new BufferedReader(
new InputStreamReader(clientSocket.getInputStream()));) {
output = out;
// Initiate application
if (!appTh.isAlive()) {
appTh.start();
} else {
output.println("Reconnected"); //$NON-NLS-1$
}
synchronized (promptingLock) {
String ln;
if (!doPrompt) try {
promptingLock.wait();
} catch (final InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
while (running && (ln = in.readLine()) != null) {
if (ln.equals(close)) {
break;
}
writer.write(ln + EOL);
writer.flush();
try {
promptingLock.wait();
} catch (final InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if (autoClose) running = false;
}
}
}
}
try (InputStreamReader isr = new InputStreamReader(
consoleInput);
BufferedReader inBuf = new BufferedReader(isr);) {
consoleManager.setInput(inBuf);
runSokectServer(appTh, writer);
// Close the application
// Pass command to application
writer.write(applicationShutdown + EOL);
writer.flush();
}
}
} catch (final IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
LOGGER.log(Level.SEVERE,
"Communication error between client and server", e); //$NON-NLS-1$
}
}
/** @param appTh the application thread
* @param writer the writer to the application
* @throws IOException if the communication with the client failed */
private void runSokectServer(Thread appTh,
BufferedWriter writer) throws IOException {
while (running) {
try (Socket clientSocket = serverSocket.accept();
PrintWriter out = new PrintWriter(
clientSocket.getOutputStream(), true);
BufferedReader in = new BufferedReader(new InputStreamReader(
clientSocket.getInputStream()));) {
// this is not threaded to avoid several clients at the same
// time
consoleManager.setOutput(out);
// Initiate application
if (!appTh.isAlive()) {
appTh.start();
} else {
out.println("Reconnected"); //$NON-NLS-1$
}
communicate(writer, in);
} catch (SocketException e) {
LOGGER.log(Level.INFO, "Socket closed", e); //$NON-NLS-1$
}
}
}
/** active communication between server and client
*
* @param writer the writer to the application
* @param in the input from the client
* @throws IOException if the communication failed */
private void communicate(BufferedWriter writer,
BufferedReader in) throws IOException {
synchronized (promptingLock) {
if (!consoleManager.isPrompting()) {
try {
// wait for application to finish its operation
promptingLock.wait();
} catch (final InterruptedException e) {
LOGGER.log(Level.SEVERE, INTERRUPTION_WHILE_WORKING, e);
}
}
if (autoClose) {
communicateOnce(in, writer);
} else {
communicateLoop(in, writer);
}
}
}
/** @param in the input from the client
* @param writer the output to the client
* @throws IOException if the communication failed */
private void communicateOnce(BufferedReader in,
BufferedWriter writer) throws IOException {
String ln;
if ((ln = in.readLine()) != null) {
if (ln.equals(close)) {
return;
}
// Pass command to application
writer.write(ln + EOL);
writer.flush();
try {
// Wait for application process to
// finish
promptingLock.wait();
} catch (final InterruptedException e) {
LOGGER.log(Level.SEVERE, INTERRUPTION_WHILE_WORKING, e);
}
}
}
/** @param in the input from the client
* @param writer the output to the client
* @throws IOException if the communication failed */
private void communicateLoop(BufferedReader in,
BufferedWriter writer) throws IOException {
String ln;
while (running && (ln = in.readLine()) != null) {
if (ln.equals(close)) {
break;
}
// Pass command to application
writer.write(ln + EOL);
writer.flush();
try {
// Wait for application process to
// finish
promptingLock.wait();
} catch (final InterruptedException e) {
LOGGER.log(Level.SEVERE, INTERRUPTION_WHILE_WORKING, e);
}
}
}
@@ -275,4 +276,21 @@ public class SocketConsoleApplicationShell implements Runnable {
this.app = app;
}
/** This method will request the server to stop.
* <p>
* In most cases, this will terminate communication on every client. On some
* cases, the */
public void stop() {
running = false;
try {
serverSocket.close();
} catch (IOException e) {
LOGGER.log(Level.SEVERE, "Exception in closing socket server", e); //$NON-NLS-1$
}
synchronized (promptingLock) {
promptingLock.notifyAll();
}
app.exit();
}
}

View File

@@ -0,0 +1,158 @@
/*
* Copyright E. Bigeon (2014)
*
* emmanuel@bigeon.fr
*
* This software is a computer program whose purpose is to
* Socket implementation of GCLC.
*
* This software is governed by the CeCILL license under French law and
* abiding by the rules of distribution of free software. You can use,
* modify and/or redistribute the software under the terms of the CeCILL
* license as circulated by CEA, CNRS and INRIA at the following URL
* "http://www.cecill.info".
*
* As a counterpart to the access to the source code and rights to copy,
* modify and redistribute granted by the license, users are provided only
* with a limited warranty and the software's author, the holder of the
* economic rights, and the successive licensors have only limited
* liability.
*
* In this respect, the user's attention is drawn to the risks associated
* with loading, using, modifying and/or developing or reproducing the
* software by the user in light of its specific status of free software,
* that may mean that it is complicated to manipulate, and that also
* therefore means that it is reserved for developers and experienced
* professionals having in-depth computer knowledge. Users are therefore
* encouraged to load and test the software's suitability as regards their
* requirements in conditions enabling the security of their systems and/or
* data to be ensured and, more generally, to use and operate it in the
* same conditions as regards security.
*
* The fact that you are presently reading this means that you have had
* knowledge of the CeCILL license and that you accept its terms.
*/
/**
* gclc-socket:fr.bigeon.gclc.socket.ThreadedServerConsoleManager.java
* Created on: Jun 1, 2016
*/
package fr.bigeon.gclc.socket;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.logging.Level;
import java.util.logging.Logger;
import fr.bigeon.gclc.ConsoleManager;
import fr.bigeon.smu.StringEncoder;
/** The console manager for socket communication
*
* @author Emmanuel Bigeon */
public class ThreadedServerConsoleManager implements ConsoleManager {
/** The eol character */
private static final String EOL = "\n"; //$NON-NLS-1$
/** The class logger */
private static final Logger LOGGER = Logger
.getLogger(ThreadedServerConsoleManager.class.getName());
/** The prompting sequence */
private String prompt = new String();
/** The buffer of data to send to the user */
private StringBuilder buffer = new StringBuilder();
/** The synchronized object */
private final Object promptingLock;
/** The output to write data comming from the application */
private PrintWriter output;
/** The encoder to encode data coming from the application */
private final StringEncoder encoder;
/** The input to wait data from the user */
private BufferedReader input;
/** the prompting status */
private boolean doPrompt;
/** Create the console manager.
*
* @param encoder the encoder for output
* @param promptingLock the synchronization object */
public ThreadedServerConsoleManager(StringEncoder encoder,
Object promptingLock) {
super();
this.encoder = encoder;
this.promptingLock = promptingLock;
}
/** @param input the input to set */
public void setInput(BufferedReader input) {
this.input = input;
}
/** @param output the output to set */
public void setOutput(PrintWriter output) {
this.output = output;
}
@Override
public void setPrompt(String prompt) {
this.prompt = prompt;
}
@Override
public String prompt(String message) {
buffer.append(message);
String userInput = new String();
boolean prompting = true;
while (prompting) {
// Send buffer content
output.println(encoder.encode(buffer.toString()));
try {
synchronized (promptingLock) {
doPrompt = true;
promptingLock.notify();
}
userInput = input.readLine();
doPrompt = false;
prompting = false;
} catch (final IOException e) {
LOGGER.log(Level.SEVERE, "input reading error", e); //$NON-NLS-1$
}
}
// Renew buffer
buffer = new StringBuilder();
return userInput;
}
/** @return the prompting status */
public synchronized boolean isPrompting() {
return doPrompt;
}
@Override
public String prompt() {
return prompt(prompt);
}
@Override
public void println(String message) {
buffer.append(message + EOL);
}
@Override
public void println() {
buffer.append(EOL);
}
@Override
public void print(String text) {
buffer.append(text);
}
@Override
public String getPrompt() {
return prompt;
}
}

View File

@@ -0,0 +1,231 @@
/*
* Copyright E. Bigeon (2014)
*
* emmanuel@bigeon.fr
*
* This software is a computer program whose purpose is to
* Socket implementation of GCLC.
*
* This software is governed by the CeCILL license under French law and
* abiding by the rules of distribution of free software. You can use,
* modify and/or redistribute the software under the terms of the CeCILL
* license as circulated by CEA, CNRS and INRIA at the following URL
* "http://www.cecill.info".
*
* As a counterpart to the access to the source code and rights to copy,
* modify and redistribute granted by the license, users are provided only
* with a limited warranty and the software's author, the holder of the
* economic rights, and the successive licensors have only limited
* liability.
*
* In this respect, the user's attention is drawn to the risks associated
* with loading, using, modifying and/or developing or reproducing the
* software by the user in light of its specific status of free software,
* that may mean that it is complicated to manipulate, and that also
* therefore means that it is reserved for developers and experienced
* professionals having in-depth computer knowledge. Users are therefore
* encouraged to load and test the software's suitability as regards their
* requirements in conditions enabling the security of their systems and/or
* data to be ensured and, more generally, to use and operate it in the
* same conditions as regards security.
*
* The fact that you are presently reading this means that you have had
* knowledge of the CeCILL license and that you accept its terms.
*/
/**
* gclc-socket:fr.bigeon.gclc.socket.ConsoleRunnableTest.java
* Created on: Jun 1, 2016
*/
package fr.bigeon.gclc.socket;
import org.junit.Test;
import fr.bigeon.gclc.ConsoleApplication;
import fr.bigeon.gclc.ConsoleManager;
import fr.bigeon.gclc.system.SystemConsoleManager;
/** Test class for {@link ConsoleRunnable}
*
* @author Emmanuel Bigeon */
@SuppressWarnings({"static-method", "unused"})
public class ConsoleRunnableTest {
/**
* Test method for {@link fr.bigeon.gclc.socket.ConsoleRunnable#ConsoleRunnable(fr.bigeon.gclc.ConsoleApplication, java.lang.Object)}.
*/
@Test
public void testConsoleRunnable() {
Object lock = new Object();
ConsoleApplication app = new ConsoleTestApplication(
new SystemConsoleManager());
ConsoleRunnable runnable = new ConsoleRunnable(app, lock);
}
/**
* Test method for {@link fr.bigeon.gclc.socket.ConsoleRunnable#run()}.
*/
@Test
public void testRunFlow() {
Object lock = new Object();
ConsoleApplication app = new ConsoleTestApplication(
new ConsoleManager() {
@Override
public void setPrompt(String prompt) {
// do nothing
}
@Override
public String getPrompt() {
// Not used in test
return ""; //$NON-NLS-1$
}
@Override
public String prompt() {
try {
Thread.sleep(1000);
} catch (InterruptedException e) { // NOSONAR
// do nothing
}
return "mock"; //$NON-NLS-1$
}
@Override
public String prompt(String message) {
return prompt();
}
@Override
public void println(String message) {
// do nothing
}
@Override
public void println() {
// do nothing
}
@Override
public void print(String text) {
// do nothing
}
});
ConsoleRunnable runnable = new ConsoleRunnable(app, lock);
Thread th = new Thread(runnable);
th.start();
runnable.stop();
}
/**
* Test method for {@link fr.bigeon.gclc.socket.ConsoleRunnable#stop()}.
*/
@Test
public void testStop() {
Object lock = new Object();
ConsoleApplication app = new ConsoleTestApplication(
new ConsoleManager() {
@Override
public void setPrompt(String prompt) {
throw new RuntimeException("Not implemented yet"); //$NON-NLS-1$
}
@Override
public String getPrompt() {
throw new RuntimeException("Not implemented yet"); //$NON-NLS-1$
}
@Override
public String prompt() {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return "mock"; //$NON-NLS-1$
}
@Override
public String prompt(String message) {
throw new RuntimeException("Not implemented yet"); //$NON-NLS-1$
}
@Override
public void println(String message) {
//
}
@Override
public void println() {
//
}
@Override
public void print(String text) {
//
}
});
ConsoleRunnable runnable = new ConsoleRunnable(app, lock);
runnable.stop();
Thread th = new Thread(runnable);
th.start();
runnable.stop();
runnable.stop();
}
/** Test method for {@link fr.bigeon.gclc.socket.ConsoleRunnable#stop()}. */
@Test
public void testRun() {
Object lock = new Object();
ConsoleApplication app = new ConsoleTestApplication(
new ConsoleManager() {
@Override
public void setPrompt(String prompt) {
throw new RuntimeException("Not implemented yet"); //$NON-NLS-1$
}
@Override
public String getPrompt() {
throw new RuntimeException("Not implemented yet"); //$NON-NLS-1$
}
@Override
public String prompt() {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return "exit"; //$NON-NLS-1$
}
@Override
public String prompt(String message) {
throw new RuntimeException("Not implemented yet"); //$NON-NLS-1$
}
@Override
public void println(String message) {
//
}
@Override
public void println() {
//
}
@Override
public void print(String text) {
//
}
});
ConsoleRunnable runnable = new ConsoleRunnable(app, lock);
runnable.run();
}
}

View File

@@ -39,16 +39,18 @@ import fr.bigeon.gclc.ConsoleManager;
import fr.bigeon.gclc.command.Command;
import fr.bigeon.gclc.exception.InvalidCommandName;
/** TODO Describe ConsoleTestApplication.java
* @author Emmanuel Bigeon
*
*/
/** A test-purpose application
*
* @author Emmanuel Bigeon */
public class ConsoleTestApplication extends ConsoleApplication {
/** Exit command */
public static final String EXIT = "exit"; //$NON-NLS-1$
/** @param manager the manager */
@SuppressWarnings("nls")
public ConsoleTestApplication(final ConsoleManager manager) {
super(manager, "exit",
super(manager, EXIT,
"Welcome to the test application. Type help or test.",
"See you");
addHelpCommand("help");
@@ -66,9 +68,7 @@ public class ConsoleTestApplication extends ConsoleApplication {
}
});
} catch (final InvalidCommandName e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}

View File

@@ -0,0 +1,138 @@
/*
* Copyright E. Bigeon (2014)
*
* emmanuel@bigeon.fr
*
* This software is a computer program whose purpose is to
* Socket implementation of GCLC.
*
* This software is governed by the CeCILL license under French law and
* abiding by the rules of distribution of free software. You can use,
* modify and/or redistribute the software under the terms of the CeCILL
* license as circulated by CEA, CNRS and INRIA at the following URL
* "http://www.cecill.info".
*
* As a counterpart to the access to the source code and rights to copy,
* modify and redistribute granted by the license, users are provided only
* with a limited warranty and the software's author, the holder of the
* economic rights, and the successive licensors have only limited
* liability.
*
* In this respect, the user's attention is drawn to the risks associated
* with loading, using, modifying and/or developing or reproducing the
* software by the user in light of its specific status of free software,
* that may mean that it is complicated to manipulate, and that also
* therefore means that it is reserved for developers and experienced
* professionals having in-depth computer knowledge. Users are therefore
* encouraged to load and test the software's suitability as regards their
* requirements in conditions enabling the security of their systems and/or
* data to be ensured and, more generally, to use and operate it in the
* same conditions as regards security.
*
* The fact that you are presently reading this means that you have had
* knowledge of the CeCILL license and that you accept its terms.
*/
/**
* gclc-socket:fr.bigeon.gclc.socket.SocketConsoleApplicationTest.java
* Created on: Jun 1, 2016
*/
package fr.bigeon.gclc.socket;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
import java.util.Arrays;
import org.junit.Test;
import fr.bigeon.smu.StringEncoder;
/** Test class for {@link SocketConsoleApplicationShell}
*
* @author Emmanuel Bigeon */
@SuppressWarnings({"static-method", "unused", "javadoc", "nls"})
public class SocketConsoleApplicationTest {
private static final StringEncoder ENCODER = new StringEncoder("%",
Arrays.asList("\n")); //$NON-NLS-1$
@Test
public void integrationTest() {
Thread server = TestServer.startServer(false);
try {
Thread.sleep(100);
} catch (InterruptedException e1) {
e1.printStackTrace();
}
final String hostName = "127.0.0.1";
final int portNumber = 3300;
try (Socket kkSocket = new Socket(hostName, portNumber);
PrintWriter out = new PrintWriter(kkSocket.getOutputStream(),
true);
BufferedReader in = new BufferedReader(
new InputStreamReader(kkSocket.getInputStream()));) {
String fromServer;
int i = 0;
String[] cmds = {"help", "test", "close"};
while ((fromServer = in.readLine()) != null) {
System.out.println("Server: \n" + ENCODER.decode(fromServer));
if (fromServer.equals("Bye.")) {
break;
}
final String fromUser = cmds[i];
if (fromUser != null) {
System.out.println("Client: " + fromUser);
out.println(fromUser);
}
i++;
}
} catch (final IOException e) {
e.printStackTrace();
}
TestServer.closeServer();
try {
Thread.sleep(100);
} catch (InterruptedException e2) {
e2.printStackTrace();
}
server = TestServer.startServer(true);
try {
Thread.sleep(100);
} catch (InterruptedException e1) {
e1.printStackTrace();
}
try (Socket kkSocket = new Socket(hostName, portNumber);
PrintWriter out = new PrintWriter(kkSocket.getOutputStream(),
true);
BufferedReader in = new BufferedReader(
new InputStreamReader(kkSocket.getInputStream()));) {
String fromServer;
int i = 0;
String[] cmds = {"help", "test", "close"};
while ((fromServer = in.readLine()) != null) {
// System.out.println("Server: \n" + ENCODER.decode(fromServer));
if (fromServer.equals("Bye.")) {
break;
}
final String fromUser = cmds[i];
if (fromUser != null) {
// System.out.println("Client: " + fromUser);
out.println(fromUser);
}
i++;
}
} catch (final IOException e) {
e.printStackTrace();
}
TestServer.closeServer();
}
}

View File

@@ -34,26 +34,58 @@
*/
package fr.bigeon.gclc.socket;
/** TODO Describe TestServer.java
* @author Emmanuel Bigeon
*
*/
/** A test server
*
* @author Emmanuel Bigeon */
@SuppressWarnings({"javadoc", "nls"})
public class TestServer {
private static SocketConsoleApplicationShell SHELL;
private static Thread server;
/** @param args no argument */
@SuppressWarnings("nls")
public static void main(String[] args) {
final SocketConsoleApplicationShell shell = new SocketConsoleApplicationShell(
3300, "close");
final ConsoleTestApplication app = new ConsoleTestApplication(
shell.getConsoleManager());
shell.setApplication(app);
final Thread serverTh = new Thread(shell, "gclcServer");
serverTh.start();
public static void main(String... args) {
try {
serverTh.join();
startServer(false).join();
} catch (final InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static Thread getServer() {
if (server == null) {
server = new Thread(getShell(), "gclcServer");
server.start();
}
return server;
}
/** @return */
private static SocketConsoleApplicationShell getShell() {
if (SHELL == null) {
SHELL = new SocketConsoleApplicationShell(3300, "close",
ConsoleTestApplication.EXIT);
final ConsoleTestApplication app = new ConsoleTestApplication(
SHELL.getConsoleManager());
SHELL.setApplication(app);
}
return SHELL;
}
public static Thread startServer(boolean autoClose) {
if (SHELL == null) {
SHELL = new SocketConsoleApplicationShell(3300, autoClose,
ConsoleTestApplication.EXIT);
final ConsoleTestApplication app = new ConsoleTestApplication(
SHELL.getConsoleManager());
SHELL.setApplication(app);
server = null;
}
return getServer();
}
public static void closeServer() {
SHELL.stop();
SHELL = null;
}
}