Added a listener for incoming traffic from the server to the application

This commit is contained in:
Daniel Collin 2015-10-13 08:13:23 +00:00
parent b08e459843
commit e7f012dc5f
6 changed files with 148 additions and 82 deletions

View file

@ -1,5 +1,7 @@
package com.coder.client;
import java.io.IOException;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
@ -7,6 +9,8 @@ import javax.swing.JOptionPane;
import com.coder.client.LoginDialog.LoginDialogAction;
import com.coder.server.CoderServer;
import com.coder.server.message.CoderMessage;
import com.coder.server.message.ProjectListData;
import zutil.log.LogUtil;
@ -16,15 +20,13 @@ public class CoderClient extends Thread{
private String url;
private int port;
private Session session;
private ClientWindow window;
private LoginDialog loginDialog;
private ProjectEditorWindow projectEditorWindow;
public CoderClient(String url, int port) {
this.url = url;
this.port = port;
this.window = new ClientWindow("CoderClient");
this.projectEditorWindow = new ProjectEditorWindow("CoderClient");
super.start();
}
@ -32,18 +34,37 @@ public class CoderClient extends Thread{
public void run(){
//save the previously typed user name
String username = "";
//keep track of the number of connection retries to the server
int connectionRetries = 0;
while(true){
//close previou session if applicable
//close previous session if applicable
closeCurrentSession();
//setup a new session
if(connectionRetries > 0){
logger.info("This is reconnection try number: " + connectionRetries);
}
this.session = Session.setupConnection(url, port);
if(session == null){
logger.info("Could not setup a connection to " + url + ":" + port);
connectionRetries++;
if(connectionRetries > 5){
//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;
}
}
//ask for username and passwor din a dialog window
//ask for username and password in a dialog window
LoginDialog loginDialog = new LoginDialog(username, null);
loginDialog.setVisible(true); //blocking
loginDialog.dispose();
@ -58,15 +79,35 @@ public class CoderClient extends Thread{
boolean authenticated = session.authenticate(username, password);
if(!authenticated){
JOptionPane.showMessageDialog(null, "Wrong username or password", "Authentication Failed", JOptionPane.INFORMATION_MESSAGE);
System.out.println("Authentication failed");
logger.info("Authentication failed: wrong username or password");
continue;
}
//resister a message listener to the session
session.addCoderMessageReceivedListener(new CoderMessageReceivedListener() {
@Override
public void projectListRspReceived(Map<String, ProjectListData> projectListRsp) {
//TODO
}
});
//start receiving traffic from the server
session.start();
//show the user the main GUI
this.window.setVisible(true);
//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);
try {Thread.sleep(1000);} catch (InterruptedException e) {}
//wait here until the session is closed for some reason
@ -75,12 +116,13 @@ public class CoderClient extends Thread{
}
//hide the main GUI
logger.info("The socket was closed. terminating.");
this.window.setVisible(false);
logger.info("The socket was closed.");
this.projectEditorWindow.setVisible(false);
Thread.yield();
}
logger.info("The program till now terminate");
closeCurrentSession();
this.window.dispose();
this.projectEditorWindow.dispose();
System.exit(0);
}

View file

@ -1,7 +1,11 @@
package com.coder.client;
import java.util.Map;
import com.coder.server.message.ProjectListData;
public interface CoderMessageReceivedListener {
void msgReceived(Class msgClass, Object authenticationChallenge);
void projectListRspReceived(Map<String, ProjectListData> projectListRsp);
}

View file

@ -0,0 +1,9 @@
package com.coder.client;
import com.coder.server.message.CoderMessage;
public interface GUIMessageSentListener {
void sendMessage(CoderMessage msg);
}

View file

@ -20,87 +20,84 @@ import javax.swing.border.LineBorder;
public class LoginDialog extends JDialog {
private static final long serialVersionUID = 9196349269499229433L;
private JTextField tfUsername;
private JPasswordField pfPassword;
private JLabel lbUsername;
private JLabel lbPassword;
private JButton btnLogin;
private JButton btnCancel;
private LoginDialogAction loginAction = LoginDialogAction.CANCEL;
public static enum LoginDialogAction{
LOGIN,
CANCEL
}
private LoginDialogAction loginAction = LoginDialogAction.CANCEL;
private JTextField usernameTextField;
private JPasswordField passwordPasswordField;
private JButton loginButton;
private JButton cancelButton;
public LoginDialog(String username, Frame parent) {
super(parent, "Login", true);
//
JPanel panel = new JPanel(new GridBagLayout());
GridBagConstraints cs = new GridBagConstraints();
cs.fill = GridBagConstraints.HORIZONTAL;
JPanel fieldPanel = new JPanel(new GridBagLayout());
GridBagConstraints gridBagConstraints = new GridBagConstraints();
lbUsername = new JLabel("Username: ");
cs.gridx = 0;
cs.gridy = 0;
cs.gridwidth = 1;
panel.add(lbUsername, cs);
gridBagConstraints.fill = GridBagConstraints.HORIZONTAL;
tfUsername = new JTextField(20);
tfUsername.setText(username);
cs.gridx = 1;
cs.gridy = 0;
cs.gridwidth = 2;
panel.add(tfUsername, cs);
JLabel usernameLabel = new JLabel("Username: ");
gridBagConstraints.gridx = 0;
gridBagConstraints.gridy = 0;
gridBagConstraints.gridwidth = 1;
fieldPanel.add(usernameLabel, gridBagConstraints);
lbPassword = new JLabel("Password: ");
cs.gridx = 0;
cs.gridy = 1;
cs.gridwidth = 1;
panel.add(lbPassword, cs);
usernameTextField = new JTextField(20);
usernameTextField.setText(username);
gridBagConstraints.gridx = 1;
gridBagConstraints.gridy = 0;
gridBagConstraints.gridwidth = 2;
fieldPanel.add(usernameTextField, gridBagConstraints);
pfPassword = new JPasswordField(20);
cs.gridx = 1;
cs.gridy = 1;
cs.gridwidth = 2;
panel.add(pfPassword, cs);
panel.setBorder(new LineBorder(Color.GRAY));
JLabel passwordLabel = new JLabel("Password: ");
gridBagConstraints.gridx = 0;
gridBagConstraints.gridy = 1;
gridBagConstraints.gridwidth = 1;
fieldPanel.add(passwordLabel, gridBagConstraints);
btnLogin = new JButton("Login");
passwordPasswordField = new JPasswordField(20);
gridBagConstraints.gridx = 1;
gridBagConstraints.gridy = 1;
gridBagConstraints.gridwidth = 2;
fieldPanel.add(passwordPasswordField, gridBagConstraints);
fieldPanel.setBorder(new LineBorder(Color.GRAY));
btnCancel = new JButton("Cancel");
loginButton = new JButton("Login");
JPanel bp = new JPanel();
bp.add(btnLogin);
bp.add(btnCancel);
cancelButton = new JButton("Cancel");
getContentPane().add(panel, BorderLayout.CENTER);
getContentPane().add(bp, BorderLayout.PAGE_END);
JPanel buttonPanel = new JPanel();
buttonPanel.add(loginButton);
buttonPanel.add(cancelButton);
getContentPane().add(fieldPanel, BorderLayout.CENTER);
getContentPane().add(buttonPanel, BorderLayout.PAGE_END);
btnLogin.addActionListener(new ActionListener() {
loginButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
loginAction = LoginDialogAction.LOGIN;
dispose();
}
});
btnCancel.addActionListener(new ActionListener() {
cancelButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
loginAction = LoginDialogAction.CANCEL;
dispose();
}
});
tfUsername.addKeyListener(new KeyListener(){
usernameTextField.addKeyListener(new KeyListener(){
@Override
public void keyPressed(KeyEvent e) {
if(e.getKeyCode() == KeyEvent.VK_ENTER){
btnLogin.doClick();
loginButton.doClick();
}else if(e.getKeyCode() == KeyEvent.VK_ESCAPE){
btnCancel.doClick();
cancelButton.doClick();
}
}
@ -115,14 +112,14 @@ public class LoginDialog extends JDialog {
}
});
pfPassword.addKeyListener(new KeyListener(){
passwordPasswordField.addKeyListener(new KeyListener(){
@Override
public void keyPressed(KeyEvent e) {
if(e.getKeyCode() == KeyEvent.VK_ENTER){
btnLogin.doClick();
loginButton.doClick();
}else if(e.getKeyCode() == KeyEvent.VK_ESCAPE){
btnCancel.doClick();
cancelButton.doClick();
}
}
@ -143,7 +140,7 @@ public class LoginDialog extends JDialog {
//move focus to the password field if already a username has been defined. must be done after pack()
if(username.isEmpty() == false){
pfPassword.requestFocusInWindow();
passwordPasswordField.requestFocusInWindow();
}
setResizable(false);
@ -151,11 +148,11 @@ public class LoginDialog extends JDialog {
}
public String getUsername() {
return tfUsername.getText().trim();
return usernameTextField.getText().trim();
}
public char[] getPassword() {
return pfPassword.getPassword();
return passwordPasswordField.getPassword();
}
public LoginDialogAction getAction() {

View file

@ -1,6 +1,7 @@
package com.coder.client;
import java.awt.Dimension;
import java.util.HashSet;
import java.util.logging.Logger;
import javax.swing.JButton;
@ -15,9 +16,11 @@ import javax.swing.event.TreeSelectionListener;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.TreeSelectionModel;
import com.coder.server.message.CoderMessage;
import zutil.log.LogUtil;
public class ClientWindow extends JFrame implements TreeSelectionListener {
public class ProjectEditorWindow extends JFrame implements TreeSelectionListener {
private static final long serialVersionUID = -5486192344225335322L;
public static final Logger logger = LogUtil.getLogger();
@ -26,8 +29,9 @@ public class ClientWindow extends JFrame implements TreeSelectionListener {
private JTextArea codingArea;
private JButton compileButton;
private JButton runButton;
private HashSet<GUIMessageSentListener> GUIMessageSentListeners;
public ClientWindow(String title){
public ProjectEditorWindow(String title){
super(title);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Dimension minimumSize = new Dimension(500,300);
@ -84,4 +88,19 @@ public class ClientWindow extends JFrame implements TreeSelectionListener {
}
}
public void addMessageSentListener(GUIMessageSentListener listener) {
this.GUIMessageSentListeners.add(listener);
}
private void sendMessage(CoderMessage msg){
for(GUIMessageSentListener listener : GUIMessageSentListeners){
listener.sendMessage(msg);
}
}
public void setProjectName(String projectName) {
// TODO Auto-generated method stub
}
}

View file

@ -5,6 +5,7 @@ import java.io.BufferedOutputStream;
import java.io.IOException;
import java.lang.reflect.Field;
import java.net.Socket;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
@ -76,7 +77,7 @@ public class Session extends Thread {
close();
return;
}
while(true){
while(isConnected()){
CoderMessage msg;
try {
msg = in.readGenericObject();
@ -160,6 +161,7 @@ public class Session extends Thread {
logger.log(Level.INFO, "Received AuthenticationChallenge");
// Setting up encryption
/*
logger.info("Setting up encryption");
String hashedPassword = Hasher.PBKDF2(clearTextPassword, username, AUTH_HASH_ITERATIONS);
String key = Hasher.PBKDF2(hashedPassword, msg.AuthenticationChallenge.salt, AUTH_HASH_ITERATIONS);
@ -177,6 +179,7 @@ public class Session extends Thread {
out.enableMetaData(false);
///////////// ENCRYPTED CONNECTION //////////////////////
*/
//Send AuthenticationRsp
CoderMessage authRsp = new CoderMessage();
@ -206,17 +209,9 @@ public class Session extends Thread {
}
private void handleMessage(CoderMessage msg){
for(Field field : CoderMessage.class.getDeclaredFields()){
Object obj = null;
try {
obj = field.get(msg);
} catch (IllegalArgumentException | IllegalAccessException e) {
logger.warning("CoderMessage field " + field.getName() + " was skipped");
}
if(obj != null){
if(msg.ProjectListRsp != null){
for(CoderMessageReceivedListener listener : messageReceivedlisteners){
listener.msgReceived(field.getClass(), obj);
}
listener.projectListRspReceived(msg.ProjectListRsp);
}
}
}