Added a listener for incoming traffic from the server to the application
This commit is contained in:
parent
b08e459843
commit
e7f012dc5f
6 changed files with 148 additions and 82 deletions
|
|
@ -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,16 +34,35 @@ 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 password in a dialog window
|
||||
LoginDialog loginDialog = new LoginDialog(username, null);
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
}
|
||||
|
|
|
|||
9
src/com/coder/client/GUIMessageSentListener.java
Normal file
9
src/com/coder/client/GUIMessageSentListener.java
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
package com.coder.client;
|
||||
|
||||
import com.coder.server.message.CoderMessage;
|
||||
|
||||
public interface GUIMessageSentListener {
|
||||
|
||||
void sendMessage(CoderMessage msg);
|
||||
|
||||
}
|
||||
|
|
@ -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() {
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue