package com.coder.client; import java.io.IOException; import java.util.Map; import java.util.logging.Level; import java.util.logging.Logger; import javax.swing.JOptionPane; import com.coder.client.Session; import com.coder.client.gui.editor.EditorWindow; import com.coder.client.gui.editor.EditorWindowListener; import com.coder.client.gui.login.LoginDialog; import com.coder.client.gui.login.LoginDialogListener; import com.coder.client.gui.selectProject.SelectProjectDialog; import com.coder.client.gui.selectProject.SelectProjectDialogListener; import com.coder.client.gui.selectServer.SelectServerDialog; import com.coder.client.gui.selectServer.SelectServerDialogListener; import com.coder.server.CoderServer; import com.coder.server.message.CoderMessage; import com.coder.server.message.ProjectListReqMsg; import zutil.log.CompactLogFormatter; import zutil.log.LogUtil; import javafx.application.Application; import javafx.stage.Stage; public class CoderClient extends Application{ public static final Logger logger = LogUtil.getLogger(); private int port = CoderServer.SERVER_PORT; private static final int DEFAULT_CONNECTION_RETRIES = 5; private Session session; private Stage mainStage; private int connectionRetriesLimit = DEFAULT_CONNECTION_RETRIES; //if zero, try forever private String url; private String username = null; private char[] password = null; private EditorWindow editorWindow; private LoginDialog loginDialog; private SelectProjectDialog selectProjectDialog; private SelectServerDialog selectServerDialog; public static void main(String[] args) { Application.launch(args); } @Override public void start(Stage mainStage) throws Exception { //setup logging LogUtil.setGlobalLevel(Level.INFO); LogUtil.setGlobalFormatter(new CompactLogFormatter()); //parse program arguments Map params = this.getParameters().getNamed(); String url = null; String username = null; char[] password = null; boolean reconnectForever = false; for(String key : params.keySet()){ String value = params.get(key); if(key.equals("username")){ username = value; }else if(key.equals("password")){ password = value.toCharArray(); }else if(key.equals("retry-connect-forever")){ reconnectForever = true; }else if(key.equals("url")){ url = value; } } //create a client instance if(url != null){ this.url = url; } if(username != null){ this.username = username; if(password != null){ this.password = password; } } if(reconnectForever){ this.connectionRetriesLimit = 0; } //loading GUI this.mainStage = mainStage; mainStage.setTitle("CoderClient"); this.editorWindow = new EditorWindow(); this.loginDialog = new LoginDialog(); this.selectProjectDialog = new SelectProjectDialog(); this.selectServerDialog = new SelectServerDialog(); //register listeners registerListeners(); //start program logic selectServerDialog.showOnStage(mainStage); //run(); } private void registerListeners() { this.selectServerDialog.addSelectProjectDialogListener(new SelectServerDialogListener() { @Override public void willShow() { selectServerDialog.setURL(url); } @Override public void cancel() { //TODO } @Override public void connect(String serverUrl) { //selectServerDialog.hide(); url = serverUrl; //connect session session = Session.setupConnection(url, port); if(session == null){ logger.warning("Could not setup a connection to " + url + ":" + port); url = null; selectServerDialog.showOnStage(mainStage); } loginDialog.showOnStage(mainStage); } }); this.loginDialog.addLoginDialogListener(new LoginDialogListener(){ @Override public void willShow() { loginDialog.setUsername(username); loginDialog.setPassword(password); } @Override public void cancel() { //TODO } @Override public void login(String uname, char[] paswd) { username = uname; password = paswd; //authenticate session 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"); password = null; loginDialog.showOnStage(mainStage); } selectProjectDialog.showOnStage(mainStage); } }); this.selectProjectDialog.addSelectProjectDialogListener(new SelectProjectDialogListener() { @Override public void willShow() { //clear current list of project selectProjectDialog.clearProjectList(); //send a request for a new list of projects CoderMessage msg = new CoderMessage(); msg.ProjectListReq = new ProjectListReqMsg(); try { session.send(msg); } catch (IOException e) { logger.log(Level.SEVERE, "Unable to send ProjectListReqMsg", e); closeCurrentSession(); } } @Override public void openProject(String selectedProjectName) { editorWindow.showOnStage(mainStage); } @Override public void newProject() { //TODO } @Override public void cancel() { //TODO } }); this.editorWindow.addMessageSentListener(new EditorWindowListener() { }); } private void closeCurrentSession(){ if(this.session != null){ session.close(); session = null; } } /* public void run(){ //keep track of the number of connection retries to the server int connectionRetries = 0; 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"); 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; } } //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.setUsername(username); loginDialog.showModal(this.mainStage); if(loginDialog.getAction() == LoginDialogAction.CANCEL){ logger.fine("Login dialog closed or canceled by the user. terminating."); break; } username = loginDialog.getUsername(); password = loginDialog.getPassword(); } logger.fine("The username: \"" + username + "\" will be used as the credential holder"); //authenticate the user 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"); continue; } //resister a message listener to the session session.addCoderMessageReceivedListener(new CoderMessageReceivedListener() { @Override public void projectListRspReceived(Map projectListRsp) { for(String projectName : projectListRsp.keySet()){ ProjectListData projectData = projectListRsp.get(projectName); selectProjectDialog.addProjectToList(projectName, projectData.type); } } @Override public void projectTypeRspReceived(Map projectTypeRsp) { // TODO Auto-generated method stub } @Override public void projectRspReceived(ProjectRspMsg projectRspMsg) { // TODO Auto-generated method stub } }); //start receiving traffic from the server session.start(); //show the project selector dialog this.selectProjectDialog.showModal(mainStage); //wait here until the session is closed for some reason while(session.isConnected()){ Thread.yield(); } //hide the main GUI logger.fine("The socket was closed."); mainStage.close(); Thread.yield(); } logger.info("The program till now terminate"); closeCurrentSession(); // this.projectEditorWindow.dispose(); System.exit(0); } */ }