Refactoring: Moving GUI program logic from CoderClient to each controller class

-Removing the Session Guard
-Adding a SessionHandler
-Adding a ProjectHandler
This commit is contained in:
dcollin 2015-11-11 16:13:01 +01:00
parent 0a580f8c53
commit 5a9e709ae8
22 changed files with 656 additions and 655 deletions

View file

@ -1,30 +1,24 @@
package com.coder.client; package com.coder.client;
import java.io.IOException; import java.io.IOException;
import java.util.HashSet;
import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Properties;
import java.util.logging.Level; import java.util.logging.Level;
import java.util.logging.Logger; import java.util.logging.Logger;
import com.coder.client.gui.GuiWindow;
import com.coder.client.gui.editor.EditorWindow; 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.LoginDialog;
import com.coder.client.gui.login.LoginDialogListener;
import com.coder.client.gui.newProject.NewProjectDialog; import com.coder.client.gui.newProject.NewProjectDialog;
import com.coder.client.gui.newProject.NewProjectDialogListener;
import com.coder.client.gui.selectProject.SelectProjectDialog; 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.SelectServerDialog;
import com.coder.client.gui.selectServer.SelectServerDialogListener; import com.coder.client.project.ProjectHandler;
import com.coder.client.session.ProjectListRspMsgListener; import com.coder.client.project.ProjectListener;
import com.coder.client.session.ProjectRspMsgListener; import com.coder.client.session.ProjectRspMsgListener;
import com.coder.client.session.ProjectTypeRspMsgListener; import com.coder.client.session.SessionHandler;
import com.coder.client.session.Session;
import com.coder.client.session.SessionListener; import com.coder.client.session.SessionListener;
import com.coder.server.message.*; import com.coder.server.message.CoderMessage;
import com.coder.server.message.ProjectCreateReqMsg;
import com.coder.server.message.ProjectReqMsg;
import com.coder.server.message.ProjectRspMsg;
import zutil.log.CompactLogFormatter; import zutil.log.CompactLogFormatter;
import zutil.log.LogUtil; import zutil.log.LogUtil;
@ -37,10 +31,8 @@ import javafx.stage.Stage;
public class CoderClient extends Application{ public class CoderClient extends Application{
public static final Logger logger = LogUtil.getLogger(); public static final Logger logger = LogUtil.getLogger();
private HashSet<SessionListener> sessionListeners = new HashSet<SessionListener>(); private SessionHandler sessionHandler = new SessionHandler();
private ProjectHandler projectHandler = new ProjectHandler();
private Session session;
private Stage mainStage;
//GUI elements //GUI elements
private EditorWindow editorWindow; private EditorWindow editorWindow;
@ -49,9 +41,6 @@ public class CoderClient extends Application{
private SelectServerDialog selectServerDialog; private SelectServerDialog selectServerDialog;
private NewProjectDialog newProjectDialog; private NewProjectDialog newProjectDialog;
//state variables
private GuiWindow projectSelectionWindow = null; //points to the GUI that selected a project for the editor. If any error occurs while creating/loading the project, this is the window we will go back to.
//services //services
SSDPClient ssdpClient; SSDPClient ssdpClient;
@ -60,7 +49,7 @@ public class CoderClient extends Application{
} }
@Override @Override
public void start(Stage mainStage) throws Exception { public void start(final Stage mainStage) throws Exception {
//setup logging //setup logging
CompactLogFormatter formatter = new CompactLogFormatter(); CompactLogFormatter formatter = new CompactLogFormatter();
@ -71,14 +60,13 @@ public class CoderClient extends Application{
LogUtil.setGlobalFormatter(formatter); LogUtil.setGlobalFormatter(formatter);
//setup GUI elements //setup GUI elements
this.mainStage = mainStage;
mainStage.setTitle("CoderClient"); mainStage.setTitle("CoderClient");
try{ try{
setupSelectServerDialog(); this.selectServerDialog = new SelectServerDialog(this);
setupLoginDialog(); this.loginDialog = new LoginDialog(this);
setupSelectProjectDialog(); this.selectProjectDialog = new SelectProjectDialog(this);
setupEditWindow(); this.newProjectDialog = new NewProjectDialog(this);
setupNewProjectDialog(); this.editorWindow = new EditorWindow(this);
}catch(IOException e){ }catch(IOException e){
logger.log(Level.SEVERE, "could not load all GUI elements", e); logger.log(Level.SEVERE, "could not load all GUI elements", e);
System.exit(1); System.exit(1);
@ -90,8 +78,6 @@ public class CoderClient extends Application{
String value = params.get(key); String value = params.get(key);
if(key.equals("username")){ if(key.equals("username")){
loginDialog.setUsername(value); loginDialog.setUsername(value);
}else if(key.equals("password")){
loginDialog.setPassword(value.toCharArray());
}else if(key.equals("url")){ }else if(key.equals("url")){
selectServerDialog.setServerAddress(value); selectServerDialog.setServerAddress(value);
}else if(key.equals("port")){ }else if(key.equals("port")){
@ -102,7 +88,7 @@ public class CoderClient extends Application{
selectServerDialog.setServerPort(-1); selectServerDialog.setServerPort(-1);
} }
}else if(key.equals("project")){ }else if(key.equals("project")){
selectProjectDialog.setProject(value); projectHandler.setProject(value);
} }
} }
@ -113,6 +99,127 @@ public class CoderClient extends Application{
logger.log(Level.SEVERE, "could not setup SSDP client", e); logger.log(Level.SEVERE, "could not setup SSDP client", e);
System.exit(1); System.exit(1);
} }
//add session listeners
sessionHandler.addSessionListener(new SessionListener() {
@Override
public void sessionDisconnected(boolean retryToEstablishConnection) {
Platform.runLater(new Runnable(){
@Override
public void run() {
logger.info("session disconnected, will show the select server dialog on the main stage");
selectServerDialog.showOnStage(mainStage);
}
});
}
@Override
public void sessionConnectionSuccess() {
Platform.runLater(new Runnable(){
@Override
public void run() {
logger.info("session connection successfull, will show the login dialog on the main stage");
loginDialog.showOnStage(mainStage);
}
});
}
@Override
public void sessionConnectionFailure() {
Platform.runLater(new Runnable(){
@Override
public void run() {
logger.info("session connection failure, will show the select server dialog on the main stage");
selectServerDialog.showOnStage(mainStage);
}
});
}
@Override
public void sessionAuthenticationSuccess() {
Platform.runLater(new Runnable(){
@Override
public void run() {
logger.info("session authentication successfull, will show the select project dialog on the main stage");
selectProjectDialog.showOnStage(mainStage);
}
});
}
@Override
public void sessionAuthenticationFailure() {
Platform.runLater(new Runnable(){
@Override
public void run() {
logger.info("session authentication failure, will show the select server dialog on the main stage");
selectServerDialog.showOnStage(mainStage);
}
});
}
@Override
public void sessionAuthenticationCancel() {
Platform.runLater(new Runnable(){
@Override
public void run() {
logger.info("session authentication canceled, will show the select server dialog on the main stage");
selectServerDialog.showOnStage(mainStage);
}
});
}
});
//add project listeners
projectHandler.addprojectListener(new ProjectListener() {
@Override
public void selectProject() {
Platform.runLater(new Runnable(){
@Override
public void run() {
logger.info("select project requested, will show the select project dialog on the main stage");
selectProjectDialog.showOnStage(mainStage);
}
});
}
@Override
public void openProject(String projectName) {
CoderMessage msg = new CoderMessage();
msg.ProjectReq = new ProjectReqMsg();
msg.ProjectReq.name = projectName;
sessionHandler.sendMessage(msg);
}
@Override
public void createNewProject(String name, String type, String description) {
CoderMessage msg = new CoderMessage();
msg.ProjectCreateReq = new ProjectCreateReqMsg();
msg.ProjectCreateReq.name = name;
msg.ProjectCreateReq.type = type;
msg.ProjectCreateReq.description = description;
sessionHandler.sendMessage(msg);
}
@Override
public void createNewProject() {
Platform.runLater(new Runnable(){
@Override
public void run() {
logger.info("new project requested, will show the new project dialog on the main stage");
newProjectDialog.showOnStage(mainStage);
}
});
}
});
//add message listeners
sessionHandler.addMessageListener(new ProjectRspMsgListener() {
@Override
public void messageReceived(final ProjectRspMsg msg) {
Platform.runLater(new Runnable() {
@Override
public void run() {
if(msg.error != null){
selectServerDialog.showOnStage(mainStage);
}else{
editorWindow.showOnStage(mainStage);
}
}
});
}
});
//start program logic //start program logic
selectServerDialog.setServerPort(-1); selectServerDialog.setServerPort(-1);
@ -120,342 +227,6 @@ public class CoderClient extends Application{
} }
private void setupSelectServerDialog() throws IOException{
this.selectServerDialog = new SelectServerDialog();
this.selectServerDialog.addSelectProjectDialogListener(new SelectServerDialogListener() {
@Override
public void willShow() {
logger.fine("about to show select server dialog on main stage");
closeCurrentSession();
selectServerDialog.clearServerList();
if(ssdpClient != null){
ssdpClient.requestService("coder:discover");
for(StandardSSDPInfo server : ssdpClient.getServices("coder:discover"))
selectServerDialog.addServerToList(server.getInetAddress().getHostAddress(), 1337);
}else{
logger.severe("could not send a SSDP request since the client is not setup");
}
}
@Override
public void exit() {
logger.info("terminating");
Platform.exit();
}
@Override
public void connect(String address, int port) {
//connect session
session = Session.setupConnection(address, port);
if(session == null){
logger.warning("Could not setup a connection to " + address + ":" + port);
selectServerDialog.setServerAddress(null);
selectServerDialog.setErrorMessage("ERROR: Unable to connect to remote host");
loginDialog.setErrorMessage("");
selectServerDialog.showOnStage(mainStage);
}else{
selectServerDialog.setErrorMessage("");
loginDialog.showOnStage(mainStage);
}
}
});
}
private void setupLoginDialog() throws IOException {
this.loginDialog = new LoginDialog();
this.loginDialog.addLoginDialogListener(new LoginDialogListener(){
@Override
public void willShow() {
logger.fine("about to show login dialog on main stage");
}
@Override
public void cancel() {
loginDialog.setErrorMessage("");
selectServerDialog.setServerAddress(null);
selectServerDialog.showOnStage(mainStage);
}
@Override
public void login(String username, char[] password) {
//authenticate session
boolean authenticated = session.authenticate(username, password);
if(!authenticated){
logger.severe("Authentication failed: wrong username or password");
loginDialog.setPassword(null);
loginDialog.setErrorMessage("Wrong username or password");
selectServerDialog.showOnStage(mainStage);
return;
}else{
loginDialog.setErrorMessage("");
setupSessionListener(); //resister a message listener to the session
session.start(); //start receiving traffic from the server
selectProjectDialog.showOnStage(mainStage);
}
}
});
}
/**
* To be called after a session has been connected and authenticated
*/
private void setupSessionListener(){
if(session == null){
logger.warning("Cannot setup session listeners for null instance. ignoring call.");
return;
}
if(!session.isAuthenticated()){
logger.warning("Cannot setup session listeners for a non-authenticated session. ignoring call.");
return;
}
//indicate for listeners that a new session is up
for(SessionListener listener : sessionListeners){
listener.sessionUp(session);
}
// create a guard for when the session is closed
new Thread(new Runnable(){
@Override
public void run() {
logger.fine("starting a session guard");
while(true){
if(session == null || !session.isConnected()){
logger.fine("session guard: no connection");
Platform.runLater(new Runnable() {
@Override
public void run() {
selectServerDialog.setErrorMessage("The current session was disconnected");
closeCurrentSession();
selectServerDialog.showOnStage(mainStage);
}
});
break;
}
Thread.yield();
}
logger.fine("terminating session guard");
}
}).start();
}
private void setupSelectProjectDialog() throws IOException {
this.selectProjectDialog = new SelectProjectDialog();
this.selectProjectDialog.addSelectProjectDialogListener(new SelectProjectDialogListener() {
@Override
public void willShow() {
logger.fine("about to show select project dialog on main stage");
selectProjectDialog.clearProjectList();
if(!selectProjectDialog.isProjectSelected()){
sendProjectListReq();
}
}
@Override
public void open(String selectedProjectName) {
projectSelectionWindow = selectProjectDialog;
editorWindow.showOnStage(mainStage);
}
@Override
public void newProject() {
selectProjectDialog.setProject(null);
newProjectDialog.showOnStage(mainStage);
}
@Override
public void cancel() {
loginDialog.setPassword(null);
selectServerDialog.setServerAddress(null);
selectServerDialog.showOnStage(mainStage);
}
@Override
public void refresh() {
selectProjectDialog.clearProjectList();
sendProjectListReq();
}
private void sendProjectListReq(){
//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();
}
}
});
this.sessionListeners.add(new SessionListener() {
@Override
public void sessionUp(Session session) {
session.addProjectListRspMsgListener(new ProjectListRspMsgListener() {
@Override
public void messageReceived(final ProjectListRspMsg msg) {
logger.fine("a ProjectListRsp received");
Platform.runLater(new Runnable() {
@Override
public void run() {
for(String projectName : msg.keySet()){
ProjectListData projectData = msg.get(projectName);
selectProjectDialog.addProjectToList(projectName, projectData);
}
}
});
}
});
}
});
}
private void setupNewProjectDialog() throws IOException {
this.newProjectDialog = new NewProjectDialog();
this.newProjectDialog.addNewProjectDialogListener(new NewProjectDialogListener(){
@Override
public void willShow() {
logger.fine("about to show new project dialog on main stage");
newProjectDialog.clearProjectTypeList();
sendProjectTypeReqMsg();
}
@Override
public void create(String newProjectName, String projectType, String projectDescription) {
projectSelectionWindow = newProjectDialog;
sendProjectCreateReqMsg(newProjectName, projectType, projectDescription);
selectProjectDialog.setProject(newProjectName);
editorWindow.showOnStage(mainStage);
}
private void sendProjectTypeReqMsg(){
CoderMessage msg = new CoderMessage();
msg.ProjectTypeReq = new ProjectTypeReqMsg();
try {
session.send(msg);
} catch (IOException e) {
logger.log(Level.SEVERE, "Unable to send ProjectTypeReq", e);
closeCurrentSession();
}
}
private void sendProjectCreateReqMsg(String projectName, String projectType, String projectDescription){
CoderMessage msg = new CoderMessage();
msg.ProjectCreateReq = new ProjectCreateReqMsg();
msg.ProjectCreateReq.name = projectName;
msg.ProjectCreateReq.type = projectType;
msg.ProjectCreateReq.description = projectDescription;
try {
session.send(msg);
} catch (IOException e) {
logger.log(Level.SEVERE, "Unable to send ProjectCreateReq", e);
closeCurrentSession();
}
}
@Override
public void cancel() {
selectProjectDialog.setProject(null);
selectProjectDialog.showOnStage(mainStage);
}
});
this.sessionListeners.add(new SessionListener() {
@Override
public void sessionUp(Session session) {
session.addProjectTypeRspMsgListener(new ProjectTypeRspMsgListener() {
@Override
public void messageReceived(final ProjectTypeRspMsg msg) {
logger.fine("a ProjectTypeRspMsg received");
Platform.runLater(new Runnable() {
@Override
public void run() {
for(String typeName : msg.keySet()){
SupportedProperties typeData = msg.get(typeName);
newProjectDialog.addProjectTypeToList(typeName, typeData);
}
}
});
}
});
}
});
}
private void setupEditWindow() throws IOException {
this.editorWindow = new EditorWindow();
this.editorWindow.addEditorWindowListener(new EditorWindowListener() {
@Override
public void willShow() {
logger.fine("about to show edit window on main stage");
sendProjectReqMsg();
}
@Override
public void compile() {
//TODO
}
@Override
public void run() {
//TODO
}
private void sendProjectReqMsg(){
if(!selectProjectDialog.isProjectSelected()){
logger.severe("Cannot send a project request when no project is selected");
return;
}
CoderMessage msg = new CoderMessage();
msg.ProjectReq = new ProjectReqMsg();
msg.ProjectReq.name = selectProjectDialog.getSelectedProject();
try {
session.send(msg);
} catch (IOException e) {
logger.log(Level.SEVERE, "Unable to send ProjectReqMsg", e);
closeCurrentSession();
}
}
@Override
public void changeProject() {
selectProjectDialog.setProject(null);
selectProjectDialog.showOnStage(mainStage);
}
@Override
public void exit() {
closeCurrentSession();
Platform.exit();
}
});
sessionListeners.add(new SessionListener() {
@Override
public void sessionUp(Session session) {
session.addProjectRspMsgListener(new ProjectRspMsgListener() {
@Override
public void messageReceived(final ProjectRspMsg msg) {
logger.fine("a ProjectRspMsg received");
Platform.runLater(new Runnable() {
@Override
public void run() {
if(msg.error != null){
logger.severe("Server responded on the project request with the following error message: " + msg.error);
selectProjectDialog.setProject(null);
if(projectSelectionWindow != null){
projectSelectionWindow.setErrorMessage("ERROR: " + msg.error);
projectSelectionWindow.showOnStage(mainStage);
return;
}else{
selectProjectDialog.setErrorMessage("ERROR: " + msg.error);
selectProjectDialog.showOnStage(mainStage);
return;
}
}else{
if(projectSelectionWindow != null){
projectSelectionWindow.setErrorMessage("");
}
editorWindow.setProjectName(msg.name);
Properties projectConfig = msg.config;
String projectDescription = msg.description;
List<String> fileList = msg.fileList;
String projectType = msg.type;
//TODO: handle msg
}
}
});
}
});
session.addProjectTypeRspMsgListener(new ProjectTypeRspMsgListener() {
@Override
public void messageReceived(ProjectTypeRspMsg msg) {
//TODO: update the project properties
}
});
}
});
}
private void setupSSDPClient() throws IOException{ private void setupSSDPClient() throws IOException{
this.ssdpClient = new SSDPClient(); this.ssdpClient = new SSDPClient();
ssdpClient.setListener(new SSDPServiceListener() { ssdpClient.setListener(new SSDPServiceListener() {
@ -477,12 +248,23 @@ public class CoderClient extends Application{
ssdpClient.start(); ssdpClient.start();
} }
private void closeCurrentSession(){ public void exit() {
if(this.session != null){ logger.info("terminating");
logger.info("disconnecting from server"); Platform.exit();
session.close(); System.exit(0);
session = null; }
}
public SSDPClient getSSDPClient() {
return this.ssdpClient;
}
public SessionHandler getSessionHandler() {
return this.sessionHandler;
}
public ProjectHandler getProjectHandler(){
return this.projectHandler;
} }
} }

View file

@ -3,6 +3,9 @@ package com.coder.client.gui;
import java.io.IOException; import java.io.IOException;
import java.net.URL; import java.net.URL;
import java.util.ResourceBundle; import java.util.ResourceBundle;
import java.util.logging.Logger;
import zutil.log.LogUtil;
import javafx.fxml.FXMLLoader; import javafx.fxml.FXMLLoader;
import javafx.fxml.Initializable; import javafx.fxml.Initializable;
@ -11,7 +14,7 @@ import javafx.scene.Scene;
import javafx.stage.Stage; import javafx.stage.Stage;
public abstract class GuiWindow implements Initializable{ public abstract class GuiWindow implements Initializable{
public static final Logger logger = LogUtil.getLogger();
private Scene scene; private Scene scene;
/** /**
@ -30,36 +33,19 @@ public abstract class GuiWindow implements Initializable{
* @param stage The stage to show on * @param stage The stage to show on
*/ */
public void showOnStage(Stage stage){ public void showOnStage(Stage stage){
stage.setScene(scene); if(scene != null && stage.getScene() != null && stage.getScene().equals(scene)){
stage.setTitle(getTitle()); logger.fine("already showing " + getDescriptiveName() + " on stage");
//this.stage = stage; }else{
willShow(); stage.setScene(scene);
stage.show(); stage.setTitle(getTitle());
} logger.fine("about to show " + getDescriptiveName() + " on stage");
willShow();
/** stage.show();
* show a modal dialog logger.fine("showing " + getDescriptiveName());
* @param parent The dialogs parent
*/
/* public void showModal(Stage parent){
Stage modalStage = new Stage();
modalStage.initModality(Modality.WINDOW_MODAL);
modalStage.initOwner(parent);
modalStage.setScene(scene);
modalStage.setTitle(getTitle());
this.stage = modalStage;
willShow();
modalStage.showAndWait();
}
*/
/* public void hide(){
if(stage != null){
this.stage.hide();
} }
} }
*/
protected abstract String getDescriptiveName();
protected abstract String getTitle(); protected abstract String getTitle();
@ -73,6 +59,4 @@ public abstract class GuiWindow implements Initializable{
*/ */
public abstract void initialize(URL fxmlFileLocation, ResourceBundle resources); public abstract void initialize(URL fxmlFileLocation, ResourceBundle resources);
public abstract void setErrorMessage(String msg);
} }

View file

@ -51,12 +51,12 @@
<children> <children>
<HBox alignment="CENTER_LEFT" maxHeight="50.0" prefHeight="50.0" prefWidth="200.0"> <HBox alignment="CENTER_LEFT" maxHeight="50.0" prefHeight="50.0" prefWidth="200.0">
<children> <children>
<Button fx:id="exitButton" mnemonicParsing="false" onAction="#handleExit" text="Exit"> <Button fx:id="exitButton" mnemonicParsing="false" onAction="#exit" text="Exit">
<HBox.margin> <HBox.margin>
<Insets left="10.0" /> <Insets left="10.0" />
</HBox.margin> </HBox.margin>
</Button> </Button>
<Button fx:id="changeProjectButton" mnemonicParsing="false" onAction="#handleChangeProject" text="Change Project"> <Button fx:id="changeProjectButton" mnemonicParsing="false" onAction="#changeProject" text="Change Project">
<HBox.margin> <HBox.margin>
<Insets left="10.0" /> <Insets left="10.0" />
</HBox.margin> </HBox.margin>
@ -65,12 +65,12 @@
</HBox> </HBox>
<HBox alignment="CENTER_RIGHT" maxHeight="50.0" prefHeight="50.0" prefWidth="200.0" GridPane.columnIndex="1"> <HBox alignment="CENTER_RIGHT" maxHeight="50.0" prefHeight="50.0" prefWidth="200.0" GridPane.columnIndex="1">
<children> <children>
<Button fx:id="compileButton" mnemonicParsing="false" onAction="#handleCompile" text="Compile"> <Button fx:id="compileButton" mnemonicParsing="false" onAction="#compile" text="Compile">
<HBox.margin> <HBox.margin>
<Insets right="10.0" /> <Insets right="10.0" />
</HBox.margin> </HBox.margin>
</Button> </Button>
<Button fx:id="runButton" mnemonicParsing="false" onAction="#handleRun" text="Run"> <Button fx:id="runButton" mnemonicParsing="false" onAction="#run" text="Run">
<HBox.margin> <HBox.margin>
<Insets right="10.0" /> <Insets right="10.0" />
</HBox.margin> </HBox.margin>

View file

@ -3,17 +3,26 @@ package com.coder.client.gui.editor;
import java.io.IOException; import java.io.IOException;
import java.net.URL; import java.net.URL;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashSet; import java.util.List;
import java.util.Properties;
import java.util.ResourceBundle; import java.util.ResourceBundle;
import java.util.logging.Logger;
import org.controlsfx.control.PropertySheet; import org.controlsfx.control.PropertySheet;
import org.controlsfx.property.editor.PropertyEditor; import org.controlsfx.property.editor.PropertyEditor;
import zutil.log.LogUtil;
import com.coder.client.CoderClient;
import com.coder.client.gui.GuiWindow; import com.coder.client.gui.GuiWindow;
import com.coder.client.property.CheckBoxProperty; import com.coder.client.property.CheckBoxProperty;
import com.coder.client.property.CoderClientProperty; import com.coder.client.property.CoderClientProperty;
import com.coder.client.property.ComboBoxProperty; import com.coder.client.property.ComboBoxProperty;
import com.coder.client.session.ProjectRspMsgListener;
import com.coder.client.session.ProjectTypeRspMsgListener;
import com.coder.client.session.SessionListener;
import com.coder.server.message.ProjectRspMsg;
import com.coder.server.message.ProjectTypeRspMsg;
import javafx.beans.value.ChangeListener; import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue; import javafx.beans.value.ObservableValue;
@ -26,9 +35,9 @@ import javafx.scene.control.TreeView;
import javafx.util.Callback; import javafx.util.Callback;
public class EditorWindow extends GuiWindow { public class EditorWindow extends GuiWindow {
public static final Logger logger = LogUtil.getLogger();
private HashSet<EditorWindowListener> listsners; private CoderClient client;
@FXML private TreeView<String> fileTreeView; @FXML private TreeView<String> fileTreeView;
@FXML private TextArea editTextArea; @FXML private TextArea editTextArea;
@FXML private PropertySheet propertySheet; @FXML private PropertySheet propertySheet;
@ -37,9 +46,31 @@ public class EditorWindow extends GuiWindow {
@FXML private Button exitButton; @FXML private Button exitButton;
@FXML private Button changeProjectButton; @FXML private Button changeProjectButton;
public EditorWindow() throws IOException{ public EditorWindow(CoderClient client) throws IOException{
super(EditorWindow.class.getResource("EditorWindow.fxml")); super(EditorWindow.class.getResource("EditorWindow.fxml"));
listsners = new HashSet<EditorWindowListener>(); this.client = client;
client.getSessionHandler().addMessageListener(new ProjectRspMsgListener() {
@Override
public void messageReceived(final ProjectRspMsg msg) {
logger.fine("a ProjectRspMsg received");
if(msg.error != null){
return;
}
setProjectName(msg.name);
Properties projectConfig = msg.config;
String projectDescription = msg.description;
List<String> fileList = msg.fileList;
String projectType = msg.type;
//TODO: handle msg
}
});
client.getSessionHandler().addMessageListener(new ProjectTypeRspMsgListener() {
@Override
public void messageReceived(ProjectTypeRspMsg msg) {
//TODO: update the project properties
}
});
} }
@Override @Override
@ -50,37 +81,28 @@ public class EditorWindow extends GuiWindow {
@Override @Override
protected void willShow(){ protected void willShow(){
for(EditorWindowListener listener : listsners){
listener.willShow();
}
} }
@FXML @FXML
protected void handleRun(ActionEvent event){ protected void run(ActionEvent event){
for(EditorWindowListener listener : listsners){ //TODO
listener.run();
}
} }
@FXML @FXML
protected void handleCompile(ActionEvent event){ protected void compile(ActionEvent event){
for(EditorWindowListener listener : listsners){ //TODO
listener.compile();
}
} }
@FXML @FXML
protected void handleChangeProject(ActionEvent event){ protected void changeProject(ActionEvent event){
for(EditorWindowListener listener : listsners){ client.getProjectHandler().setProject(null);
listener.changeProject(); client.getProjectHandler().selectProject();
}
} }
@FXML @FXML
protected void handleExit(ActionEvent event){ protected void exit(ActionEvent event){
for(EditorWindowListener listener : listsners){ client.exit();
listener.exit();
}
} }
private void setupFileTreeView(){ private void setupFileTreeView(){
@ -124,18 +146,13 @@ public class EditorWindow extends GuiWindow {
CheckBoxProperty p2 = new CheckBoxProperty("Melt?", false); CheckBoxProperty p2 = new CheckBoxProperty("Melt?", false);
propertySheet.getItems().add(p2); propertySheet.getItems().add(p2);
} }
public void addEditorWindowListener(EditorWindowListener listener) {
this.listsners.add(listener);
}
@Override @Override
protected String getTitle() { protected String getTitle() {
return "Coder Client"; return "Coder Client";
} }
@Override private void setErrorMessage(String msg) {
public void setErrorMessage(String msg) {
// TODO Auto-generated method stub // TODO Auto-generated method stub
} }
@ -144,4 +161,9 @@ public class EditorWindow extends GuiWindow {
fileTreeView.getRoot().setValue(name); fileTreeView.getRoot().setValue(name);
} }
@Override
protected String getDescriptiveName() {
return "Editor Window";
}
} }

View file

@ -1,11 +0,0 @@
package com.coder.client.gui.editor;
public interface EditorWindowListener {
public void willShow();
public void compile();
public void run();
public void changeProject();
public void exit();
}

View file

@ -2,7 +2,6 @@ package com.coder.client.gui.login;
import java.io.IOException; import java.io.IOException;
import java.net.URL; import java.net.URL;
import java.util.HashSet;
import java.util.ResourceBundle; import java.util.ResourceBundle;
import java.util.logging.Logger; import java.util.logging.Logger;
@ -17,11 +16,13 @@ import javafx.scene.control.TextField;
import javafx.scene.input.KeyCode; import javafx.scene.input.KeyCode;
import javafx.scene.input.KeyEvent; import javafx.scene.input.KeyEvent;
import com.coder.client.CoderClient;
import com.coder.client.gui.GuiWindow; import com.coder.client.gui.GuiWindow;
import com.coder.client.session.SessionListener;
public class LoginDialog extends GuiWindow { public class LoginDialog extends GuiWindow {
public static final Logger logger = LogUtil.getLogger(); public static final Logger logger = LogUtil.getLogger();
private HashSet<LoginDialogListener> listeners; private CoderClient client;
@FXML private TextField usernameTextField; @FXML private TextField usernameTextField;
@FXML private PasswordField passwordPasswordField; @FXML private PasswordField passwordPasswordField;
@ -29,9 +30,35 @@ public class LoginDialog extends GuiWindow {
@FXML private Button loginButton; @FXML private Button loginButton;
@FXML private Label errorLabel; @FXML private Label errorLabel;
public LoginDialog() throws IOException { public LoginDialog(final CoderClient client) throws IOException {
super(LoginDialog.class.getResource("LoginDialog.fxml")); super(LoginDialog.class.getResource("LoginDialog.fxml"));
this.listeners = new HashSet<LoginDialogListener>(); this.client = client;
client.getSessionHandler().addSessionListener(new SessionListener() {
@Override
public void sessionConnectionSuccess() {
}
@Override
public void sessionDisconnected(boolean tryToEstablishConnection) {
setErrorMessage("");
}
@Override
public void sessionConnectionFailure() {
setErrorMessage("");
}
@Override
public void sessionAuthenticationSuccess() {
setErrorMessage("");
}
@Override
public void sessionAuthenticationFailure() {
setErrorMessage("Wrong username or password");
}
@Override
public void sessionAuthenticationCancel() {
setErrorMessage(null);
}
});
} }
@Override @Override
@ -41,18 +68,12 @@ public class LoginDialog extends GuiWindow {
@Override @Override
protected void willShow(){ protected void willShow(){
for(LoginDialogListener listener : this.listeners){ passwordPasswordField.setText("");
listener.willShow(); if(errorLabel.getText() != null && errorLabel.getText().isEmpty() && usernameTextField.getText() != null && !usernameTextField.getText().isEmpty()){
} passwordPasswordField.requestFocus();
if(usernameTextField.getText() != null && !usernameTextField.getText().isEmpty() && passwordPasswordField.getText() != null && !passwordPasswordField.getText().isEmpty()){
loginButton.fire();
}else{ }else{
if(errorLabel.getText() != null && errorLabel.getText().isEmpty() && usernameTextField.getText() != null && !usernameTextField.getText().isEmpty()){ usernameTextField.requestFocus();
passwordPasswordField.requestFocus(); passwordPasswordField.setText("");
}else{
usernameTextField.requestFocus();
passwordPasswordField.setText("");
}
} }
} }
@ -69,42 +90,36 @@ public class LoginDialog extends GuiWindow {
@FXML @FXML
protected void login(ActionEvent event){ protected void login(ActionEvent event){
for(LoginDialogListener listener : this.listeners){ logger.fine("login button triggered");
listener.login(usernameTextField.getText(), passwordPasswordField.getText().toCharArray()); //authenticate session
boolean authenticated = client.getSessionHandler().authenticateSession(usernameTextField.getText(), passwordPasswordField.getText().toCharArray());
if(!authenticated){
logger.severe("Authentication failed: wrong username or password");
} }
} }
@FXML @FXML
protected void cancel(ActionEvent event){ protected void cancel(ActionEvent event){
for(LoginDialogListener listener : this.listeners){ logger.fine("cancel button triggered");
listener.cancel(); client.getSessionHandler().authenticationCancel();
}
} }
public void setUsername(String username){ public void setUsername(String username){
usernameTextField.setText(username); usernameTextField.setText(username);
} }
public void setPassword(char[] password){
if(password != null){
passwordPasswordField.setText(new String(password));
}else{
passwordPasswordField.setText("");
}
}
public void addLoginDialogListener(LoginDialogListener listener) {
this.listeners.add(listener);
}
@Override @Override
protected String getTitle() { protected String getTitle() {
return "Login"; return "Login";
} }
@Override private void setErrorMessage(String msg) {
public void setErrorMessage(String msg) {
errorLabel.setText(msg); errorLabel.setText(msg);
} }
@Override
protected String getDescriptiveName() {
return "Login Dialog";
}
} }

View file

@ -1,9 +0,0 @@
package com.coder.client.gui.login;
public interface LoginDialogListener {
public void cancel();
public void login(String username, char[] password);
public void willShow();
}

View file

@ -2,11 +2,14 @@ package com.coder.client.gui.newProject;
import java.io.IOException; import java.io.IOException;
import java.net.URL; import java.net.URL;
import java.util.HashSet;
import java.util.ResourceBundle; import java.util.ResourceBundle;
import java.util.logging.Logger; import java.util.logging.Logger;
import com.coder.server.message.CoderMessage;
import com.coder.server.message.ProjectTypeReqMsg;
import com.coder.server.message.ProjectTypeRspMsg;
import com.coder.server.message.SupportedProperties; import com.coder.server.message.SupportedProperties;
import javafx.collections.FXCollections; import javafx.collections.FXCollections;
import javafx.collections.ObservableList; import javafx.collections.ObservableList;
import javafx.event.ActionEvent; import javafx.event.ActionEvent;
@ -20,11 +23,13 @@ import javafx.scene.input.KeyEvent;
import zutil.log.LogUtil; import zutil.log.LogUtil;
import com.coder.client.CoderClient;
import com.coder.client.gui.GuiWindow; import com.coder.client.gui.GuiWindow;
import com.coder.client.session.ProjectTypeRspMsgListener;
public class NewProjectDialog extends GuiWindow { public class NewProjectDialog extends GuiWindow {
public static final Logger logger = LogUtil.getLogger(); public static final Logger logger = LogUtil.getLogger();
private HashSet<NewProjectDialogListener> listeners; private CoderClient client;
@FXML private Button createButton; @FXML private Button createButton;
@FXML private Button cancelButton; @FXML private Button cancelButton;
@ -35,18 +40,28 @@ public class NewProjectDialog extends GuiWindow {
private ObservableList<String> projectTypeList = null; private ObservableList<String> projectTypeList = null;
public NewProjectDialog() throws IOException { public NewProjectDialog(CoderClient client) throws IOException {
super(NewProjectDialog.class.getResource("NewProjectDialog.fxml")); super(NewProjectDialog.class.getResource("NewProjectDialog.fxml"));
projectTypeList = FXCollections.observableArrayList(); projectTypeList = FXCollections.observableArrayList();
projectTypeComboBox.setItems(projectTypeList); projectTypeComboBox.setItems(projectTypeList);
listeners = new HashSet<NewProjectDialogListener>(); this.client = client;
client.getSessionHandler().addMessageListener(new ProjectTypeRspMsgListener() {
@Override
public void messageReceived(final ProjectTypeRspMsg msg) {
logger.fine("a ProjectTypeRspMsg received");
for(String typeName : msg.keySet()){
SupportedProperties typeData = msg.get(typeName);
addProjectTypeToList(typeName, typeData);
}
}
});
} }
@Override @Override
protected void willShow() { protected void willShow() {
for(NewProjectDialogListener listener : this.listeners){ clearProjectTypeList();
listener.willShow(); sendProjectTypeReqMsg();
}
if(errorMessageLabel.getText() == null || errorMessageLabel.getText().isEmpty()){ if(errorMessageLabel.getText() == null || errorMessageLabel.getText().isEmpty()){
projectNameTextField.setText(null); projectNameTextField.setText(null);
projectTypeComboBox.setValue(null); projectTypeComboBox.setValue(null);
@ -60,8 +75,15 @@ public class NewProjectDialog extends GuiWindow {
errorMessageLabel.setText(""); errorMessageLabel.setText("");
} }
private void sendProjectTypeReqMsg(){
CoderMessage msg = new CoderMessage();
msg.ProjectTypeReq = new ProjectTypeReqMsg();
client.getSessionHandler().sendMessage(msg);
}
@FXML @FXML
protected void create(ActionEvent event){ protected void create(ActionEvent event){
logger.fine("create button triggered");
if(projectNameTextField.getText() == null || projectNameTextField.getText().isEmpty()){ if(projectNameTextField.getText() == null || projectNameTextField.getText().isEmpty()){
logger.warning("Missing project name"); logger.warning("Missing project name");
return; return;
@ -70,19 +92,17 @@ public class NewProjectDialog extends GuiWindow {
logger.warning("Missing project type"); logger.warning("Missing project type");
return; return;
} }
for(NewProjectDialogListener listener : this.listeners){
listener.create(projectNameTextField.getText(), projectTypeComboBox.getValue(), projectDescriptionTextField.getText()); client.getProjectHandler().createNewProject(projectNameTextField.getText(), projectTypeComboBox.getValue(), projectDescriptionTextField.getText());
}
} }
@FXML @FXML
protected void cancel(ActionEvent event){ protected void cancel(ActionEvent event){
for(NewProjectDialogListener listener : this.listeners){ logger.fine("cancel button triggered");
listener.cancel(); client.getProjectHandler().setProject(null);
} client.getProjectHandler().selectProject();
} }
@FXML @FXML
protected void keyPressed(KeyEvent event){ protected void keyPressed(KeyEvent event){
enableDisableButton(); enableDisableButton();
@ -113,10 +133,6 @@ public class NewProjectDialog extends GuiWindow {
return "New Project"; return "New Project";
} }
public void addNewProjectDialogListener(NewProjectDialogListener newProjectDialogListener) {
this.listeners.add(newProjectDialogListener);
}
public void addProjectTypeToList(String typeName, SupportedProperties typeData) { public void addProjectTypeToList(String typeName, SupportedProperties typeData) {
logger.fine("Adding project type \"" + typeName + "\" to the project type list"); logger.fine("Adding project type \"" + typeName + "\" to the project type list");
projectTypeList.add(typeName); projectTypeList.add(typeName);
@ -126,9 +142,13 @@ public class NewProjectDialog extends GuiWindow {
projectTypeList.clear(); projectTypeList.clear();
} }
@Override private void setErrorMessage(String errorMsg) {
public void setErrorMessage(String errorMsg) {
errorMessageLabel.setText(errorMsg); errorMessageLabel.setText(errorMsg);
} }
@Override
protected String getDescriptiveName() {
return "New Project Dialog";
}
} }

View file

@ -1,11 +0,0 @@
package com.coder.client.gui.newProject;
public interface NewProjectDialogListener {
public void willShow();
public void create(String projectName, String projectType, String projectDescription);
public void cancel();
}

View file

@ -2,7 +2,6 @@ package com.coder.client.gui.selectProject;
import java.io.IOException; import java.io.IOException;
import java.net.URL; import java.net.URL;
import java.util.HashSet;
import java.util.ResourceBundle; import java.util.ResourceBundle;
import java.util.logging.Level; import java.util.logging.Level;
import java.util.logging.Logger; import java.util.logging.Logger;
@ -25,33 +24,65 @@ import javafx.scene.input.MouseButton;
import javafx.scene.input.MouseEvent; import javafx.scene.input.MouseEvent;
import javafx.util.Callback; import javafx.util.Callback;
import com.coder.client.CoderClient;
import com.coder.client.gui.GuiWindow; import com.coder.client.gui.GuiWindow;
import com.coder.client.session.ProjectListRspMsgListener;
import com.coder.client.session.ProjectRspMsgListener;
import com.coder.server.message.CoderMessage;
import com.coder.server.message.ProjectListData; import com.coder.server.message.ProjectListData;
import com.coder.server.message.ProjectListReqMsg;
import com.coder.server.message.ProjectListRspMsg;
import com.coder.server.message.ProjectRspMsg;
public class SelectProjectDialog extends GuiWindow { public class SelectProjectDialog extends GuiWindow {
public static final Logger logger = LogUtil.getLogger(); public static final Logger logger = LogUtil.getLogger();
private HashSet<SelectProjectDialogListener> listeners;
private ObservableList<ProjectListItem> projectList; private ObservableList<ProjectListItem> projectList;
private CoderClient client;
@FXML private ListView<ProjectListItem> projectListView; @FXML private ListView<ProjectListItem> projectListView;
@FXML private Button newProjectButton; @FXML private Button newProjectButton;
@FXML private Button cancelButton; @FXML private Button cancelButton;
@FXML private Button openButton; @FXML private Button openButton;
@FXML private Label errorLabel; @FXML private Label errorLabel;
private String projectName = null;
public SelectProjectDialog() throws IOException { public SelectProjectDialog(final CoderClient client) throws IOException {
super(SelectProjectDialog.class.getResource("SelectProjectDialog.fxml")); super(SelectProjectDialog.class.getResource("SelectProjectDialog.fxml"));
listeners = new HashSet<SelectProjectDialogListener>(); this.client = client;
client.getSessionHandler().addMessageListener(new ProjectListRspMsgListener() {
@Override
public void messageReceived(final ProjectListRspMsg msg) {
logger.fine("a ProjectListRsp received");
for(String projectName : msg.keySet()){
ProjectListData projectData = msg.get(projectName);
addProjectToList(projectName, projectData);
}
}
});
client.getSessionHandler().addMessageListener(new ProjectRspMsgListener() {
@Override
public void messageReceived(final ProjectRspMsg msg) {
logger.fine("a ProjectRspMsg received");
if(msg.error != null){
logger.severe("Server responded on the project request with the following error message: " + msg.error);
client.getProjectHandler().setProject(null);
setErrorMessage("ERROR: " + msg.error);
}else{
setErrorMessage("");
client.getProjectHandler().setProject(msg.name);
}
}
});
} }
@Override @Override
protected void willShow() { protected void willShow() {
for(SelectProjectDialogListener listener : this.listeners){ clearProjectList();
listener.willShow(); if(!client.getProjectHandler().isProjectSet()){
} sendProjectListReq();
if(this.projectName != null && !this.projectName.isEmpty()){ }else{
logger.fine("will outofire the open button since all parameters are already set");
openButton.setDisable(false); openButton.setDisable(false);
openButton.fire(); openButton.fire();
} }
@ -88,6 +119,13 @@ public class SelectProjectDialog extends GuiWindow {
}); });
} }
private void sendProjectListReq(){
//send a request for a new list of projects
CoderMessage msg = new CoderMessage();
msg.ProjectListReq = new ProjectListReqMsg();
client.getSessionHandler().sendMessage(msg);
}
@FXML @FXML
protected void mouseClickedOnList(MouseEvent event){ protected void mouseClickedOnList(MouseEvent event){
if(event.getButton().equals(MouseButton.PRIMARY)){ if(event.getButton().equals(MouseButton.PRIMARY)){
@ -113,42 +151,31 @@ public class SelectProjectDialog extends GuiWindow {
@FXML @FXML
protected void newProject(ActionEvent event){ protected void newProject(ActionEvent event){
logger.fine("user triggered the new project button"); logger.fine("new project button triggered");
for(SelectProjectDialogListener listener : this.listeners){ client.getProjectHandler().createNewProject();
listener.newProject();
}
} }
@FXML @FXML
protected void cancel(ActionEvent event){ protected void cancel(ActionEvent event){
logger.fine("user triggered the cancel button"); logger.fine("cancel button triggered");
for(SelectProjectDialogListener listener : this.listeners){ client.getSessionHandler().closeCurrentSession(false);
listener.cancel();
}
} }
@FXML @FXML
protected void refresh(ActionEvent event){ protected void refresh(ActionEvent event){
for(SelectProjectDialogListener listener : this.listeners){ logger.fine("refresh button triggered");
listener.refresh(); clearProjectList();
} sendProjectListReq();
} }
@FXML @FXML
protected void open(ActionEvent event){ protected void open(ActionEvent event){
if(this.projectName == null || this.projectName.isEmpty()){ logger.fine("open button triggered");
if(!client.getProjectHandler().isProjectSet()){
ProjectListItem selectedItem = projectListView.getSelectionModel().getSelectedItem(); ProjectListItem selectedItem = projectListView.getSelectionModel().getSelectedItem();
projectName = selectedItem.getName(); client.getProjectHandler().setProject(selectedItem.getName());
} }
for(SelectProjectDialogListener listener : this.listeners){ client.getProjectHandler().openProject();
if(projectName != null){
listener.open(projectName);
}
}
}
public void addSelectProjectDialogListener(SelectProjectDialogListener listener){
this.listeners.add(listener);
} }
public void clearProjectList(){ public void clearProjectList(){
@ -167,21 +194,13 @@ public class SelectProjectDialog extends GuiWindow {
return "Open Project"; return "Open Project";
} }
public void setProject(String project) { private void setErrorMessage(String errorMsg){
this.projectName = project;
}
@Override
public void setErrorMessage(String errorMsg){
this.errorLabel.setText(errorMsg); this.errorLabel.setText(errorMsg);
} }
public boolean isProjectSelected() { @Override
return this.projectName != null && !this.projectName.isEmpty(); protected String getDescriptiveName() {
} return "Select Project Dialog";
public String getSelectedProject() {
return this.projectName;
} }
} }

View file

@ -1,15 +0,0 @@
package com.coder.client.gui.selectProject;
public interface SelectProjectDialogListener {
void newProject();
void cancel();
void open(String selectedProjectName);
void willShow();
void refresh();
}

View file

@ -2,7 +2,6 @@ package com.coder.client.gui.selectServer;
import java.io.IOException; import java.io.IOException;
import java.net.URL; import java.net.URL;
import java.util.HashSet;
import java.util.ResourceBundle; import java.util.ResourceBundle;
import java.util.logging.Level; import java.util.logging.Level;
import java.util.logging.Logger; import java.util.logging.Logger;
@ -24,13 +23,17 @@ import javafx.scene.input.MouseEvent;
import javafx.util.Callback; import javafx.util.Callback;
import zutil.log.LogUtil; import zutil.log.LogUtil;
import zutil.net.ssdp.SSDPClient;
import zutil.net.ssdp.StandardSSDPInfo;
import com.coder.client.CoderClient;
import com.coder.client.gui.GuiWindow; import com.coder.client.gui.GuiWindow;
import com.coder.client.session.SessionListener;
public class SelectServerDialog extends GuiWindow { public class SelectServerDialog extends GuiWindow {
public static final Logger logger = LogUtil.getLogger(); public static final Logger logger = LogUtil.getLogger();
private HashSet<SelectServerDialogListener> listeners;
private ObservableList<ServerListItem> serverList; private ObservableList<ServerListItem> serverList;
private CoderClient client;
private String address = null; private String address = null;
private int port = -1; private int port = -1;
@ -40,19 +43,63 @@ public class SelectServerDialog extends GuiWindow {
@FXML private Button connectButton; @FXML private Button connectButton;
@FXML private Label errorLabel; @FXML private Label errorLabel;
public SelectServerDialog() throws IOException { public SelectServerDialog(CoderClient client) throws IOException {
super(SelectServerDialog.class.getResource("SelectServerDialog.fxml")); super(SelectServerDialog.class.getResource("SelectServerDialog.fxml"));
listeners = new HashSet<SelectServerDialogListener>(); this.client = client;
client.getSessionHandler().addSessionListener(new SessionListener() {
@Override
public void sessionConnectionSuccess() {
setErrorMessage("");
}
@Override
public void sessionDisconnected(boolean tryToEstablishConnection) {
if(!tryToEstablishConnection){
logger.info("No reconnection should be performed, reseting server address");
setServerAddress(null);
}else{
setErrorMessage("The current session was disconnected");
}
}
@Override
public void sessionConnectionFailure() {
setServerAddress(null);
setErrorMessage("ERROR: Unable to connect to remote host");
}
@Override
public void sessionAuthenticationSuccess() {
setErrorMessage("");
}
@Override
public void sessionAuthenticationFailure() {
setErrorMessage("");
}
@Override
public void sessionAuthenticationCancel() {
setServerAddress(null);
setErrorMessage(null);
}
});
} }
@Override @Override
protected void willShow() { protected void willShow() {
for(SelectServerDialogListener listener : this.listeners){ logger.fine("Clearing server list");
listener.willShow(); serverList.clear();
}
if(address != null && port != -1){ if(address != null && port != -1){
logger.fine("will outofire the connect button since all parameters are already set");
connectButton.setDisable(false); connectButton.setDisable(false);
connectButton.fire(); connectButton.fire();
}else{
logger.fine("sending a SSDP request for local servers");
SSDPClient ssdpClient = client.getSSDPClient();
if(ssdpClient != null){
ssdpClient.requestService("coder:discover");
for(StandardSSDPInfo server : ssdpClient.getServices("coder:discover")){
addServerToList(server.getInetAddress().getHostAddress(), 1337);
}
}else{
logger.severe("could not send a SSDP request since the client is not setup");
}
} }
connectButton.setDisable(true); connectButton.setDisable(true);
} }
@ -110,21 +157,19 @@ public class SelectServerDialog extends GuiWindow {
@FXML @FXML
protected void exit(ActionEvent event){ protected void exit(ActionEvent event){
for(SelectServerDialogListener listener : this.listeners){ logger.fine("exit button triggered");
listener.exit(); client.exit();
}
} }
@FXML @FXML
protected void connect(ActionEvent event){ protected void connect(ActionEvent event){
for(SelectServerDialogListener listener : this.listeners){ logger.fine("connect button triggered");
listener.connect(address, port); //connect session
boolean success = client.getSessionHandler().setupConnection(address, port);
if(!success){
logger.severe("Could not setup a connection to " + address + ":" + port);
} }
} }
public void addSelectProjectDialogListener(SelectServerDialogListener listener){
this.listeners.add(listener);
}
public void setServerAddress(String serverAddress) { public void setServerAddress(String serverAddress) {
this.address = serverAddress; this.address = serverAddress;
@ -144,15 +189,14 @@ public class SelectServerDialog extends GuiWindow {
ServerListItem item = new ServerListItem(ip, port); ServerListItem item = new ServerListItem(ip, port);
this.serverList.add(item); this.serverList.add(item);
} }
public void clearServerList(){
logger.fine("Clearing server list");
serverList.clear();
}
@Override private void setErrorMessage(String errorMsg) {
public void setErrorMessage(String errorMsg) {
this.errorLabel.setText(errorMsg); this.errorLabel.setText(errorMsg);
} }
@Override
protected String getDescriptiveName() {
return "Select Server Dialog";
}
} }

View file

@ -1,11 +0,0 @@
package com.coder.client.gui.selectServer;
public interface SelectServerDialogListener {
void willShow();
void exit();
void connect(String serverAddress, int port);
}

View file

@ -0,0 +1,48 @@
package com.coder.client.project;
import java.util.HashSet;
public class ProjectHandler {
private HashSet<ProjectListener> projectListeners = new HashSet<ProjectListener>();
private String projectName = null;
public void createNewProject() {
projectName = null;
for(ProjectListener listener : projectListeners){
listener.createNewProject();
}
}
public void createNewProject(String name, String type, String description){
for(ProjectListener listener : projectListeners){
listener.createNewProject(name, type, description);
}
}
public boolean isProjectSet() {
return projectName != null && !projectName.isEmpty();
}
public void setProject(String name) {
this.projectName = name;
}
public void selectProject() {
for(ProjectListener listener : projectListeners){
listener.selectProject();
}
}
public void openProject() {
for(ProjectListener listener : projectListeners){
listener.openProject(projectName);
}
}
public void addprojectListener(ProjectListener listener){
this.projectListeners.add(listener);
}
}

View file

@ -0,0 +1,8 @@
package com.coder.client.project;
public interface ProjectListener {
public void createNewProject();
public void createNewProject(String name, String type, String description);
public void selectProject();
public void openProject(String projectName);
}

View file

@ -2,6 +2,6 @@ package com.coder.client.session;
import com.coder.server.message.ProjectListRspMsg; import com.coder.server.message.ProjectListRspMsg;
public interface ProjectListRspMsgListener { public interface ProjectListRspMsgListener extends ProjectMessageListener {
public void messageReceived(ProjectListRspMsg msg); public void messageReceived(ProjectListRspMsg msg);
} }

View file

@ -0,0 +1,5 @@
package com.coder.client.session;
public interface ProjectMessageListener {
}

View file

@ -2,6 +2,6 @@ package com.coder.client.session;
import com.coder.server.message.ProjectRspMsg; import com.coder.server.message.ProjectRspMsg;
public interface ProjectRspMsgListener { public interface ProjectRspMsgListener extends ProjectMessageListener {
public void messageReceived(ProjectRspMsg msg); public void messageReceived(ProjectRspMsg msg);
} }

View file

@ -2,6 +2,6 @@ package com.coder.client.session;
import com.coder.server.message.ProjectTypeRspMsg; import com.coder.server.message.ProjectTypeRspMsg;
public interface ProjectTypeRspMsgListener { public interface ProjectTypeRspMsgListener extends ProjectMessageListener {
public void messageReceived(ProjectTypeRspMsg msg); public void messageReceived(ProjectTypeRspMsg msg);
} }

View file

@ -7,6 +7,8 @@ import java.util.HashSet;
import java.util.logging.Level; import java.util.logging.Level;
import java.util.logging.Logger; import java.util.logging.Logger;
import javafx.application.Platform;
import zutil.Hasher; import zutil.Hasher;
import zutil.log.InputStreamLogger; import zutil.log.InputStreamLogger;
import zutil.log.LogUtil; import zutil.log.LogUtil;
@ -22,9 +24,7 @@ public class Session extends Thread {
public static final Logger logger = LogUtil.getLogger(); public static final Logger logger = LogUtil.getLogger();
private static final int AUTH_HASH_ITERATIONS = 500; private static final int AUTH_HASH_ITERATIONS = 500;
private HashSet<ProjectListRspMsgListener> projectListRspMsgListeners = new HashSet<ProjectListRspMsgListener>(); private HashSet<ProjectMessageListener> projectMessageListeners = new HashSet<ProjectMessageListener>();
private HashSet<ProjectRspMsgListener> projectRspMsgListeners = new HashSet<ProjectRspMsgListener>();
private HashSet<ProjectTypeRspMsgListener> projectTypeRspMsgListeners = new HashSet<ProjectTypeRspMsgListener>();
private boolean authenticated = false; private boolean authenticated = false;
private Socket socket; private Socket socket;
@ -35,7 +35,7 @@ public class Session extends Thread {
} }
public static Session setupConnection(String url, int port){ protected static Session setupConnection(String url, int port){
Session session = new Session(); Session session = new Session();
logger.fine("Setting up a TCP socket to " + url + ":" + port); logger.fine("Setting up a TCP socket to " + url + ":" + port);
try { try {
@ -55,6 +55,7 @@ public class Session extends Thread {
public void close(){ public void close(){
if(socket != null){ if(socket != null){
logger.fine("closing socket");
try { try {
socket.close(); socket.close();
} catch (IOException e) { } catch (IOException e) {
@ -101,16 +102,8 @@ public class Session extends Thread {
return false; return false;
} }
public void addProjectListRspMsgListener(ProjectListRspMsgListener listener){ public void addMessageListener(ProjectMessageListener listener){
projectListRspMsgListeners.add(listener); projectMessageListeners.add(listener);
}
public void addProjectRspMsgListener(ProjectRspMsgListener listener){
projectRspMsgListeners.add(listener);
}
public void addProjectTypeRspMsgListener(ProjectTypeRspMsgListener listener){
projectTypeRspMsgListeners.add(listener);
} }
public boolean isConnected(){ public boolean isConnected(){
@ -125,7 +118,7 @@ public class Session extends Thread {
return authenticated; return authenticated;
} }
public boolean authenticate(String username, char[] clearTextPassword) { protected boolean authenticate(String username, char[] clearTextPassword) {
logger.fine("Authenticating session"); logger.fine("Authenticating session");
if(socket == null){ if(socket == null){
@ -214,26 +207,27 @@ public class Session extends Thread {
} }
} }
private void handleMessage(CoderMessage msg){ private void handleMessage(final CoderMessage msg){
logger.fine("Received a CoderMessage"); Platform.runLater(new Runnable() {
if(msg.ProjectListRsp != null){ @Override
logger.fine("The message contains a ProjectListRspMsg"); public void run() {
for(ProjectListRspMsgListener listener : projectListRspMsgListeners){ logger.fine("Received a CoderMessage");
listener.messageReceived(msg.ProjectListRsp); for(ProjectMessageListener listener : projectMessageListeners){
if(msg.ProjectListRsp != null && listener instanceof ProjectListRspMsgListener){
logger.fine("The message contains a ProjectListRspMsg that is forwarded to listener: " + listener);
((ProjectListRspMsgListener)listener).messageReceived(msg.ProjectListRsp);
}
if(msg.ProjectRsp != null && listener instanceof ProjectRspMsgListener){
logger.fine("The message contains a ProjectRspMsg that is forwarded to listener: " + listener);
((ProjectRspMsgListener)listener).messageReceived(msg.ProjectRsp);
}
if(msg.ProjectTypeRsp != null && listener instanceof ProjectTypeRspMsgListener){
logger.fine("The message contains a ProjectTypeRsp that is forwarded to listener: " + listener);
((ProjectTypeRspMsgListener)listener).messageReceived(msg.ProjectTypeRsp);
}
}
} }
} });
if(msg.ProjectRsp != null){
logger.fine("The message contains a ProjectRspMsg");
for(ProjectRspMsgListener listener : projectRspMsgListeners){
listener.messageReceived(msg.ProjectRsp);
}
}
if(msg.ProjectTypeRsp != null){
logger.fine("The message contains a ProjectTypeRsp");
for(ProjectTypeRspMsgListener listener : projectTypeRspMsgListeners){
listener.messageReceived(msg.ProjectTypeRsp);
}
}
} }
} }

View file

@ -0,0 +1,107 @@
package com.coder.client.session;
import java.io.IOException;
import java.util.HashSet;
import java.util.logging.Level;
import java.util.logging.Logger;
import zutil.log.LogUtil;
import com.coder.server.message.CoderMessage;
public class SessionHandler{
public static final Logger logger = LogUtil.getLogger();
private Session session;
private HashSet<SessionListener> sessionListeners = new HashSet<SessionListener>();
private HashSet<ProjectMessageListener> messageListeners = new HashSet<ProjectMessageListener>();
public boolean setupConnection(String url, int port){
if(session != null && session.isConnected()){
session.close();
}
session = Session.setupConnection(url, port);
if(session != null){
for(ProjectMessageListener listener : messageListeners){
session.addMessageListener(listener);
}
for(SessionListener listener : sessionListeners){
listener.sessionConnectionSuccess();
}
return true;
}else{
for(SessionListener listener : sessionListeners){
listener.sessionConnectionFailure();
}
return false;
}
}
public boolean authenticateSession(String username, char[] clearTextPassword){
if(session == null){
return false;
}else{
boolean success = session.authenticate(username, clearTextPassword);
if(success){
for(SessionListener listener : sessionListeners){
listener.sessionAuthenticationSuccess();
}
session.start();
return true;
}else{
for(SessionListener listener : sessionListeners){
listener.sessionAuthenticationFailure();
}
return false;
}
}
}
public boolean sendMessage(CoderMessage msg){
logger.fine("sending a message");
if(session != null){
try {
session.send(msg);
} catch (IOException e) {
logger.log(Level.SEVERE, "unable to send message", e);
closeCurrentSession(true);
return false;
}
logger.fine("successfully sent the meessage");
return true;
}
return false;
}
public void closeCurrentSession(boolean retry){
if(session != null){
logger.info("closing session to server");
session.close();
session = null;
for(SessionListener listener : sessionListeners){
listener.sessionDisconnected(retry);
}
}else{
logger.fine("cannot close current session: session already terminated");
}
}
public void addSessionListener(SessionListener listener){
this.sessionListeners.add(listener);
}
public void addMessageListener(ProjectMessageListener listener) {
messageListeners.add(listener);
if(session != null){
session.addMessageListener(listener);
}
}
public void authenticationCancel() {
closeCurrentSession(false);
for(SessionListener listener : sessionListeners){
listener.sessionAuthenticationCancel();
}
}
}

View file

@ -3,6 +3,16 @@ package com.coder.client.session;
public interface SessionListener { public interface SessionListener {
void sessionUp(Session session); void sessionConnectionSuccess();
void sessionConnectionFailure();
void sessionAuthenticationSuccess();
void sessionAuthenticationFailure();
void sessionDisconnected(boolean tryToEstablishConnection);
void sessionAuthenticationCancel();
} }