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.LoginDialogAction; import com.coder.client.gui.project.SelectProjectDialog; import com.coder.client.gui.project.SelectProjectDialogListener; import com.coder.server.CoderServer; import com.coder.server.message.CoderMessage; import com.coder.server.message.ConfigData; import com.coder.server.message.ProjectListData; import com.coder.server.message.ProjectListReqMsg; import com.coder.server.message.ProjectRspMsg; import zutil.log.CompactLogFormatter; import zutil.log.LogUtil; import javafx.application.Application; import javafx.fxml.FXMLLoader; import javafx.scene.Parent; import javafx.scene.Scene; 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 String url; private Stage mainStage; private String username = null; private char[] password = null; private int connectionRetriesLimit = DEFAULT_CONNECTION_RETRIES; //if zero, try forever private EditorWindow editorWindow; private LoginDialog loginDialog; private SelectProjectDialog selectProjectDialog; 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 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; } } //create a client instance this.url = "127.0.0.1"; 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(); //register listeners registerListeners(); //start program logic run(); } private void registerListeners() { 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) { selectProjectDialog.close(); editorWindow.showOnStage(mainStage); } @Override public void newProject() { selectProjectDialog.close(); //TODO } @Override public void cancel() { selectProjectDialog.close(); } }); 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); } }