coder-client/src/com/coder/client/CoderClient.java

264 lines
8.7 KiB
Java
Raw Normal View History

2015-10-09 13:37:45 +00:00
package com.coder.client;
import java.io.IOException;
import java.util.Map;
2015-10-09 13:37:45 +00:00
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JOptionPane;
2015-10-09 13:37:45 +00:00
import com.coder.server.CoderServer;
import com.coder.server.message.CoderMessage;
2015-10-20 06:56:14 +00:00
import com.coder.server.message.ConfigData;
import com.coder.server.message.ProjectListData;
2015-10-20 06:56:14 +00:00
import com.coder.server.message.ProjectListReqMsg;
import com.coder.server.message.ProjectRspMsg;
2015-10-09 13:37:45 +00:00
import zutil.log.CompactLogFormatter;
2015-10-09 13:37:45 +00:00
import zutil.log.LogUtil;
public class CoderClient extends Thread{
public static final Logger logger = LogUtil.getLogger();
private static final int DEFAULT_CONNECTION_RETRIES = 5;
2015-10-09 13:37:45 +00:00
private String url;
private int port;
private Session session;
private ProjectEditorWindow projectEditorWindow;
2015-10-20 06:56:14 +00:00
private ProjectSelectDialog projectSelectDialog;
private String username = null;
private char[] password = null;
private int connectionRetriesLimit = DEFAULT_CONNECTION_RETRIES; //if zero, try forever
2015-10-09 13:37:45 +00:00
public CoderClient(String url, int port) {
this.url = url;
this.port = port;
this.projectEditorWindow = new ProjectEditorWindow("CoderClient");
2015-10-20 06:56:14 +00:00
this.projectSelectDialog = new ProjectSelectDialog(null);
LogUtil.setGlobalLevel(Level.INFO);
LogUtil.setGlobalFormatter(new CompactLogFormatter());
2015-10-09 13:37:45 +00:00
}
public void run(){
//keep track of the number of connection retries to the server
int connectionRetries = 0;
2015-10-09 13:37:45 +00:00
while(true){
//close previous session if applicable
closeCurrentSession();
//setup a new session
if(connectionRetries > 0){
logger.fine("This is reconnection try number: " + connectionRetries);
}
logger.fine("Setting up a connected session");
2015-10-09 13:37:45 +00:00
this.session = Session.setupConnection(url, port);
if(session == null){
logger.warning("Could not setup a connection to " + url + ":" + port);
connectionRetries++;
if(connectionRetriesLimit > 0 && connectionRetries > connectionRetriesLimit){
//stop trying to connect
logger.severe("Was not able to conenct to the remote host.");
break;
}else{
//wait for awhile and try to connect one more
logger.info("Will retry to connect once more in 2 seconds.");
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
}
continue;
}
2015-10-09 13:37:45 +00:00
}
//get user credentials
if(username != null && !username.isEmpty() && password != null && password.length > 0){
//do nothing, already have all credentials we need
logger.fine("All login credentials have already been given. No need for a login dialog.");
}else{
//ask for username and password in a dialog window
logger.info("All or some login credentials have not been given. Using a dialog for input.");
LoginDialog loginDialog = new LoginDialog(username, null);
loginDialog.setVisible(true); //blocking
loginDialog.dispose();
2015-10-20 06:56:14 +00:00
if(loginDialog.getAction() == LoginDialog.LoginDialogAction.CANCEL){
logger.fine("Login dialog closed or canceled by the user. terminating.");
break;
}
username = loginDialog.getUsername();
password = loginDialog.getPassword();
2015-10-09 13:37:45 +00:00
}
logger.fine("The username: \"" + username + "\" will be used as the credential holder");
//authenticate the user
2015-10-09 13:37:45 +00:00
boolean authenticated = session.authenticate(username, password);
if(!authenticated){
JOptionPane.showMessageDialog(null, "Wrong username or password", "Authentication Failed", JOptionPane.INFORMATION_MESSAGE);
logger.severe("Authentication failed: wrong username or password");
2015-10-09 13:37:45 +00:00
continue;
}
//forget the password
for(int i = 0; i < password.length; ++i){
password[i] = '*';
}
password = null;
//resister a message listener to the session
session.addCoderMessageReceivedListener(new CoderMessageReceivedListener() {
@Override
public void projectListRspReceived(Map<String, ProjectListData> projectListRsp) {
2015-10-20 06:56:14 +00:00
for(String projectName : projectListRsp.keySet()){
ProjectListData projectData = projectListRsp.get(projectName);
projectSelectDialog.addProjectToList(projectName, projectData.type);
}
}
@Override
public void projectTypeRspReceived(Map<String, ConfigData> projectTypeRsp) {
// TODO Auto-generated method stub
}
@Override
public void projectRspReceived(ProjectRspMsg projectRspMsg) {
// TODO Auto-generated method stub
}
});
//start receiving traffic from the server
2015-10-09 13:37:45 +00:00
session.start();
2015-10-20 06:56:14 +00:00
//clear the current local project list
this.projectSelectDialog.clearProjectList();
//request a new project list from the server
CoderMessage msg = new CoderMessage();
msg.ProjectListReq = new ProjectListReqMsg();
try {
session.send(msg);
} catch (IOException e) {
logger.log(Level.SEVERE, "Unable to send ProjectListReqMsg", e);
continue;
}
//show the project selector dialog
this.projectSelectDialog.setVisible(true); //blocking
if(this.projectSelectDialog.getAction() == ProjectSelectDialog.ProjectSelectDialogAction.CANCEL){
logger.fine("Project select dialog closed or canceled by the user. terminating.");
break;
}
String selectedProjectName = this.projectSelectDialog.getSelecteProjectName();
logger.info("Project \"" +selectedProjectName+ "\" was selected.");
//add a listener to forward messages from the editor GUI to the server
this.projectEditorWindow.addMessageSentListener(new GUIMessageSentListener(){
@Override
public void sendMessage(CoderMessage msg) {
try {
session.send(msg);
} catch (IOException e) {
logger.log(Level.SEVERE, "could not forward message from editor to the server", e);
}
}
});
//show the user the editor GUI
this.projectEditorWindow.setVisible(true);
2015-10-09 13:37:45 +00:00
try {Thread.sleep(1000);} catch (InterruptedException e) {}
//wait here until the session is closed for some reason
2015-10-09 13:37:45 +00:00
while(session.isConnected()){
Thread.yield();
}
//hide the main GUI
logger.fine("The socket was closed.");
this.projectEditorWindow.setVisible(false);
2015-10-09 13:37:45 +00:00
Thread.yield();
}
logger.info("The program till now terminate");
closeCurrentSession();
this.projectEditorWindow.dispose();
2015-10-09 13:37:45 +00:00
System.exit(0);
}
private void closeCurrentSession(){
if(this.session != null){
session.close();
session = null;
}
}
2015-10-20 06:56:14 +00:00
public void setPassword(char[] password) {
this.password = password;
}
2015-10-20 06:56:14 +00:00
public void setUsername(String username) {
this.username = username;
}
2015-10-20 06:56:14 +00:00
public void setRetryConnectForever(boolean tryForever) {
if(tryForever){
this.connectionRetriesLimit = 0;
}else{
this.connectionRetriesLimit = DEFAULT_CONNECTION_RETRIES;
}
}
2015-10-09 13:37:45 +00:00
public static void main(String[] args){
int port = CoderServer.SERVER_PORT;
String username = null;
char[] password = null;
boolean reconnectForever = false;
//parse program arguments
for(int i = 0; i < args.length; ++i){
String arg = args[i];
if(arg.equals("-h") || arg.equals("--help")){
System.out.println("Usage: CoderClient [options]");
System.out.println("Options:");
System.out.println("-h|--help Print this help.");
System.out.println("-u|--username <username> Set the username to use when authenticating.");
System.out.println("-p|--password <password> Set the password used when authenticating. The password will not be safetly");
System.out.println(" stored and ths option should not be used in anything but debuging.");
System.out.println(" A password cannot be defined without a username. If booth");
System.out.println(" a username and a password has been defined by arguments the software will not.");
System.out.println(" prompt for this.");
System.out.println(" If not a port have been defined, the deafult port will be used.");
System.out.println("--retry-connect-forever Make the software never stop trying to reconnect to its peer.");
System.exit(0);
}else if(arg.equals("-u") || arg.equals("--username")){
i++;
if(i < args.length){
username = args[i];
}else{
System.err.println("missing username argument");
System.exit(1);
}
}else if(arg.equals("-p") || arg.equals("--password")){
i++;
if(i < args.length){
password = args[i].toCharArray();
}else{
System.err.println("missing password argument");
System.exit(1);
}
}else if(arg.equals("--retry-connect-forever")){
reconnectForever = true;
}
}
//create a client instance
CoderClient client = new CoderClient("127.0.0.1", port);
if(username != null){
client.setUsername(username);
if(password != null){
client.setPassword(password);
}
}
client.setRetryConnectForever(reconnectForever);
client.start();
2015-10-09 13:37:45 +00:00
}
}