A simple client for CoderServer
This commit is contained in:
parent
34a65faf9d
commit
a414f42e58
11 changed files with 844 additions and 0 deletions
8
.classpath
Normal file
8
.classpath
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<classpath>
|
||||
<classpathentry kind="src" path="src"/>
|
||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.7"/>
|
||||
<classpathentry combineaccessrules="false" kind="src" path="/ZUtil"/>
|
||||
<classpathentry combineaccessrules="false" kind="src" path="/CoderServer"/>
|
||||
<classpathentry kind="output" path="bin"/>
|
||||
</classpath>
|
||||
17
.externalToolBuilders/ANT Build.launch
Normal file
17
.externalToolBuilders/ANT Build.launch
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<launchConfiguration type="org.eclipse.ant.AntBuilderLaunchConfigurationType">
|
||||
<stringAttribute key="org.eclipse.ant.ui.ATTR_ANT_AFTER_CLEAN_TARGETS" value="clean,"/>
|
||||
<stringAttribute key="org.eclipse.ant.ui.ATTR_ANT_CLEAN_TARGETS" value="clean,"/>
|
||||
<booleanAttribute key="org.eclipse.ant.ui.ATTR_TARGETS_UPDATED" value="true"/>
|
||||
<booleanAttribute key="org.eclipse.ant.ui.DEFAULT_VM_INSTALL" value="false"/>
|
||||
<stringAttribute key="org.eclipse.debug.core.ATTR_REFRESH_SCOPE" value="${project}"/>
|
||||
<booleanAttribute key="org.eclipse.debug.ui.ATTR_LAUNCH_IN_BACKGROUND" value="false"/>
|
||||
<stringAttribute key="org.eclipse.jdt.launching.CLASSPATH_PROVIDER" value="org.eclipse.ant.ui.AntClasspathProvider"/>
|
||||
<booleanAttribute key="org.eclipse.jdt.launching.DEFAULT_CLASSPATH" value="true"/>
|
||||
<stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value="CoderClient"/>
|
||||
<booleanAttribute key="org.eclipse.ui.externaltools.ATTR_BUILDER_ENABLED" value="false"/>
|
||||
<stringAttribute key="org.eclipse.ui.externaltools.ATTR_LOCATION" value="${workspace_loc:/CoderClient/build.xml}"/>
|
||||
<stringAttribute key="org.eclipse.ui.externaltools.ATTR_RUN_BUILD_KINDS" value="full,incremental,auto,clean"/>
|
||||
<booleanAttribute key="org.eclipse.ui.externaltools.ATTR_TRIGGERS_CONFIGURED" value="true"/>
|
||||
<stringAttribute key="org.eclipse.ui.externaltools.ATTR_WORKING_DIRECTORY" value="${workspace_loc:/CoderClient}"/>
|
||||
</launchConfiguration>
|
||||
26
.project
Normal file
26
.project
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>CoderClient</name>
|
||||
<comment></comment>
|
||||
<projects>
|
||||
</projects>
|
||||
<buildSpec>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.jdt.core.javabuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.ui.externaltools.ExternalToolBuilder</name>
|
||||
<arguments>
|
||||
<dictionary>
|
||||
<key>LaunchConfigHandle</key>
|
||||
<value><project>/.externalToolBuilders/ANT Build.launch</value>
|
||||
</dictionary>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
||||
11
.settings/org.eclipse.jdt.core.prefs
Normal file
11
.settings/org.eclipse.jdt.core.prefs
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
eclipse.preferences.version=1
|
||||
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
|
||||
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7
|
||||
org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
|
||||
org.eclipse.jdt.core.compiler.compliance=1.7
|
||||
org.eclipse.jdt.core.compiler.debug.lineNumber=generate
|
||||
org.eclipse.jdt.core.compiler.debug.localVariable=generate
|
||||
org.eclipse.jdt.core.compiler.debug.sourceFile=generate
|
||||
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
|
||||
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
|
||||
org.eclipse.jdt.core.compiler.source=1.7
|
||||
135
build.xml
Normal file
135
build.xml
Normal file
|
|
@ -0,0 +1,135 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project name="CoderClient" default="buildRelease" >
|
||||
|
||||
<!-- ________________________ PROPERTIES AND SETTINGS ________________________ -->
|
||||
|
||||
<property name="version" value="0.1b" />
|
||||
<property name="title" value="CoderClient" />
|
||||
<property name="vendor" value="" />
|
||||
<property name="build-type" value="black" />
|
||||
|
||||
<!--common properties-->
|
||||
<property name="gitRoot" value="." />
|
||||
<property name="coderServerRoot" value="${gitRoot}/../CoderServer" />
|
||||
<property name="srcDir" value="${gitRoot}/src" />
|
||||
<property name="libDir" value="${gitRoot}/lib" />
|
||||
<property name="buildDir" value="${gitRoot}/build" />
|
||||
<property name="releaseDir" value="${gitRoot}/release"/>
|
||||
|
||||
<!--CodeClient properties-->
|
||||
<property name="coderClientBuildDir" value="${buildDir}/coderClient/classes" />
|
||||
<property name="coderClientJar" value="${releaseDir}/CoderClient.jar" />
|
||||
<property name="coderClientPackage" value="com/coder/client" />
|
||||
|
||||
<!--define standard arduments for javac-->
|
||||
<presetdef name="javac">
|
||||
<javac includeantruntime="false" />
|
||||
</presetdef>
|
||||
|
||||
<!-- ________________________ CLASSPATHS ________________________ -->
|
||||
|
||||
<!--classpath included when building-->
|
||||
<path id="classpath.build">
|
||||
<pathelement location="${coderServerRoot}/lib/Zutil.jar" />
|
||||
<pathelement location="${coderServerRoot}/release/CoderServer.jar" />
|
||||
</path>
|
||||
|
||||
<!-- ________________________ PUBLIC TARGETS ________________________ -->
|
||||
|
||||
<target name="runBooth">
|
||||
<parallel>
|
||||
<antcall target="startCoderServer" />
|
||||
<sequential>
|
||||
<sleep seconds="5" />
|
||||
<antcall target="run" />
|
||||
</sequential>
|
||||
</parallel>
|
||||
</target>
|
||||
|
||||
<target name="startCoderServer">
|
||||
<ant antfile="${coderServerRoot}/build.xml" dir="${coderServerRoot}" target="run" />
|
||||
</target>
|
||||
|
||||
<!--build release and run-->
|
||||
<target name="run" depends="buildRelease">
|
||||
<java fork="true" failonerror="true" dir="${releaseDir}" classname="com.coder.client.CoderClient">
|
||||
<classpath>
|
||||
<pathelement path="${releaseDir}/*"/> <!--wildcard may not be platform independent, ok?-->
|
||||
<pathelement path="${releaseDir}/lib/*"/> <!--wildcard may not be platform independent, ok?-->
|
||||
</classpath>
|
||||
</java>
|
||||
</target>
|
||||
|
||||
<!--build all target code and create .jar files -->
|
||||
<target name="buildRelease" depends="buildAll, build-coder-client-jar">
|
||||
<!--create release dir-->
|
||||
<mkdir dir="${releaseDir}" />
|
||||
<!--create release/lib dir-->
|
||||
<mkdir dir="${releaseDir}/lib" />
|
||||
<!--copy libs and related files to release/lib dir-->
|
||||
<copy todir="${releaseDir}/lib" flatten="true">
|
||||
<path refid="classpath.build" />
|
||||
</copy>
|
||||
</target>
|
||||
|
||||
<!--build all product code-->
|
||||
<target name="buildAll" depends="clean, build-coder-client">
|
||||
</target>
|
||||
|
||||
<!--clean all build paths-->
|
||||
<target name="clean">
|
||||
<delete includeemptydirs="true" failonerror="false">
|
||||
<fileset dir="${buildDir}" includes="**/*"/>
|
||||
</delete>
|
||||
<delete includeemptydirs="true" failonerror="false">
|
||||
<fileset dir="${releaseDir}" includes="**/*"/>
|
||||
</delete>
|
||||
</target>
|
||||
|
||||
<!-- ________________________ CODER CLIENT ________________________ -->
|
||||
|
||||
<!--build product code and create jar file-->
|
||||
<target name="build-coder-client-jar" depends="git.revision">
|
||||
<mkdir dir="${releaseDir}" />
|
||||
<jar destfile="${coderClientJar}" baseDir="${coderClientBuildDir}">
|
||||
<manifest>
|
||||
<attribute name="Main-class" value="com.coder.client.CoderClient" />
|
||||
<attribute name="Implementation-Title" value="${title}" />
|
||||
<attribute name="Implementation-Version" value="${version} (${repository.version}) (${build-type})" />
|
||||
<attribute name="Implementation-Vendor" value="${vendor}" />
|
||||
</manifest>
|
||||
</jar>
|
||||
</target>
|
||||
|
||||
<!--build product code-->
|
||||
<target name="build-coder-client">
|
||||
<delete dir="${coderClientBuildDir}" />
|
||||
<mkdir dir="${coderClientBuildDir}" />
|
||||
<javac srcdir="${srcDir}" destdir="${coderClientBuildDir}" fork="yes">
|
||||
<include name="**/*.java" />
|
||||
<exclude name="**/plugin/**" />
|
||||
<classpath refid="classpath.build" />
|
||||
</javac>
|
||||
</target>
|
||||
|
||||
<!-- ________________________ UTILITY ________________________ -->
|
||||
|
||||
<!--find the current GIT commit SHA-->
|
||||
<available file="${gitRoot}/.git" type="dir" property="git.present" />
|
||||
<target name="git.revision" if="git.present">
|
||||
<exec executable="git" outputproperty="git.revision" failifexecutionfails="false" errorproperty="">
|
||||
<arg value="describe" />
|
||||
<arg value="--tags" />
|
||||
<arg value="--always" />
|
||||
<arg value="HEAD" />
|
||||
</exec>
|
||||
<condition property="repository.version" value="${git.revision}" else="unknown">
|
||||
<and>
|
||||
<isset property="git.revision" />
|
||||
<length string="${git.revision}" trim="yes" length="0" when="greater" />
|
||||
</and>
|
||||
</condition>
|
||||
<echo message="Current commit SHA is ${git.revision}" />
|
||||
</target>
|
||||
|
||||
</project>
|
||||
87
src/com/coder/client/ClientWindow.java
Normal file
87
src/com/coder/client/ClientWindow.java
Normal file
|
|
@ -0,0 +1,87 @@
|
|||
package com.coder.client;
|
||||
|
||||
import java.awt.Dimension;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JFrame;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JScrollPane;
|
||||
import javax.swing.JSplitPane;
|
||||
import javax.swing.JTextArea;
|
||||
import javax.swing.JTree;
|
||||
import javax.swing.event.TreeSelectionEvent;
|
||||
import javax.swing.event.TreeSelectionListener;
|
||||
import javax.swing.tree.DefaultMutableTreeNode;
|
||||
import javax.swing.tree.TreeSelectionModel;
|
||||
|
||||
import zutil.log.LogUtil;
|
||||
|
||||
public class ClientWindow extends JFrame implements TreeSelectionListener {
|
||||
private static final long serialVersionUID = -5486192344225335322L;
|
||||
public static final Logger logger = LogUtil.getLogger();
|
||||
|
||||
private JTree fileTree;
|
||||
private ProjectFileTreeModel fileTreeModel;
|
||||
private JTextArea codingArea;
|
||||
private JButton compileButton;
|
||||
private JButton runButton;
|
||||
|
||||
public ClientWindow(String title){
|
||||
super(title);
|
||||
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
|
||||
Dimension minimumSize = new Dimension(500,300);
|
||||
this.setMinimumSize(minimumSize);
|
||||
|
||||
//left panel containing a file tree
|
||||
this.fileTreeModel = new ProjectFileTreeModel();
|
||||
this.fileTree = new JTree(fileTreeModel);
|
||||
fileTree.getSelectionModel().setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION);
|
||||
fileTree.addTreeSelectionListener(this);
|
||||
|
||||
//test pane
|
||||
this.codingArea = new JTextArea();
|
||||
JScrollPane textScrolPane = new JScrollPane(codingArea);
|
||||
codingArea.setEditable(false);
|
||||
|
||||
//right top pane
|
||||
JPanel rightTopPanel = new JPanel();
|
||||
|
||||
//right bottom pane
|
||||
JPanel rightBottomPanel = new JPanel();
|
||||
this.compileButton = new JButton("Compile");
|
||||
compileButton.setEnabled(false);
|
||||
rightBottomPanel.add(compileButton);
|
||||
this.runButton = new JButton("Run");
|
||||
runButton.setEnabled(false);
|
||||
rightBottomPanel.add(runButton);
|
||||
|
||||
//split panes
|
||||
JSplitPane rightVerticalSpitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT, rightTopPanel, rightBottomPanel);
|
||||
rightVerticalSpitPane.setResizeWeight(1.0);
|
||||
rightVerticalSpitPane.setEnabled(false);
|
||||
JSplitPane rightHorizontalSpitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, textScrolPane, rightVerticalSpitPane);
|
||||
rightHorizontalSpitPane.setResizeWeight(1.0);
|
||||
JSplitPane leftHorizontalSpitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, fileTree, rightHorizontalSpitPane);
|
||||
leftHorizontalSpitPane.setResizeWeight(0.0);
|
||||
this.add(leftHorizontalSpitPane);
|
||||
|
||||
//show this window
|
||||
this.pack();
|
||||
}
|
||||
|
||||
//TreeSelectionListener interface impl.
|
||||
@Override
|
||||
public void valueChanged(TreeSelectionEvent event) {
|
||||
DefaultMutableTreeNode node = (DefaultMutableTreeNode)fileTree.getLastSelectedPathComponent();
|
||||
if(node == null)
|
||||
return;
|
||||
Object nodeInfo = node.getUserObject();
|
||||
if(node.isLeaf()){
|
||||
logger.info("A file has been selected in the file tree");
|
||||
}else{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
80
src/com/coder/client/CoderClient.java
Normal file
80
src/com/coder/client/CoderClient.java
Normal file
|
|
@ -0,0 +1,80 @@
|
|||
package com.coder.client;
|
||||
|
||||
import java.util.Scanner;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import com.coder.client.LoginDialog.LoginDialogAction;
|
||||
import com.coder.server.CoderServer;
|
||||
|
||||
import zutil.log.LogUtil;
|
||||
|
||||
public class CoderClient extends Thread{
|
||||
public static final Logger logger = LogUtil.getLogger();
|
||||
|
||||
private String url;
|
||||
private int port;
|
||||
private Session session;
|
||||
private ClientWindow window;
|
||||
//private Scanner userInput = new Scanner(System.in);
|
||||
|
||||
public CoderClient(String url, int port) {
|
||||
this.url = url;
|
||||
this.port = port;
|
||||
|
||||
this.window = new ClientWindow("CoderClient");
|
||||
|
||||
super.start();
|
||||
}
|
||||
|
||||
public void run(){
|
||||
String username = "";
|
||||
while(true){
|
||||
this.session = Session.setupConnection(url, port);
|
||||
if(session == null){
|
||||
logger.info("Could not setup a connection to " + url + ":" + port);
|
||||
continue;
|
||||
}
|
||||
|
||||
LoginDialog loginDialog = new LoginDialog(username, null);
|
||||
loginDialog.setVisible(true);
|
||||
if(loginDialog.getAction() == LoginDialogAction.CANCEL){
|
||||
logger.info("Login dialog closed or canceled by the user. terminating.");
|
||||
break;
|
||||
}
|
||||
username = loginDialog.getUsername();
|
||||
String password = loginDialog.getPassword();
|
||||
/*
|
||||
System.out.println("username:");
|
||||
String username = userInput.next();
|
||||
System.out.println("password:");
|
||||
String password = userInput.next();
|
||||
*/
|
||||
boolean authenticated = session.authenticate(username, password);
|
||||
if(!authenticated){
|
||||
System.out.println("Authentication failed");
|
||||
continue;
|
||||
}
|
||||
|
||||
session.start();
|
||||
|
||||
this.window.setVisible(true);
|
||||
try {Thread.sleep(1000);} catch (InterruptedException e) {}
|
||||
|
||||
while(session.isConnected()){
|
||||
Thread.yield();
|
||||
}
|
||||
|
||||
logger.info("The socket was closed. terminating.");
|
||||
this.window.setVisible(false);
|
||||
Thread.yield();
|
||||
}
|
||||
System.exit(0);
|
||||
}
|
||||
|
||||
public static void main(String[] args){
|
||||
int port = CoderServer.SERVER_PORT;
|
||||
new CoderClient("127.0.0.1", port);
|
||||
}
|
||||
|
||||
}
|
||||
20
src/com/coder/client/CoderMessageReceivedListener.java
Normal file
20
src/com/coder/client/CoderMessageReceivedListener.java
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
package com.coder.client;
|
||||
|
||||
import com.coder.server.message.AuthenticationChallengeMsg;
|
||||
import com.coder.server.message.AuthenticationReqMsg;
|
||||
import com.coder.server.message.AuthenticationRspMsg;
|
||||
import com.coder.server.message.AuthenticationSuccessMsg;
|
||||
|
||||
public interface CoderMessageReceivedListener {
|
||||
|
||||
void authenticationChallengeMsgReceived(AuthenticationChallengeMsg authenticationChallenge);
|
||||
|
||||
void authenticationReqMsgReceived(AuthenticationReqMsg authenticationReq);
|
||||
|
||||
void authenticationRspMsgReceived(AuthenticationRspMsg authenticationRsp);
|
||||
|
||||
void authenticationSuccessMsgReceived(AuthenticationSuccessMsg authenticationSuccess);
|
||||
|
||||
void msgReceived(Class msgClass, Object authenticationChallenge);
|
||||
|
||||
}
|
||||
154
src/com/coder/client/LoginDialog.java
Normal file
154
src/com/coder/client/LoginDialog.java
Normal file
|
|
@ -0,0 +1,154 @@
|
|||
package com.coder.client;
|
||||
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.Color;
|
||||
import java.awt.Frame;
|
||||
import java.awt.GridBagConstraints;
|
||||
import java.awt.GridBagLayout;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.awt.event.KeyEvent;
|
||||
import java.awt.event.KeyListener;
|
||||
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JDialog;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JPasswordField;
|
||||
import javax.swing.JTextField;
|
||||
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
|
||||
}
|
||||
|
||||
public LoginDialog(String username, Frame parent) {
|
||||
super(parent, "Login", true);
|
||||
//
|
||||
JPanel panel = new JPanel(new GridBagLayout());
|
||||
GridBagConstraints cs = new GridBagConstraints();
|
||||
|
||||
cs.fill = GridBagConstraints.HORIZONTAL;
|
||||
|
||||
lbUsername = new JLabel("Username: ");
|
||||
cs.gridx = 0;
|
||||
cs.gridy = 0;
|
||||
cs.gridwidth = 1;
|
||||
panel.add(lbUsername, cs);
|
||||
|
||||
tfUsername = new JTextField(20);
|
||||
tfUsername.setText(username);
|
||||
cs.gridx = 1;
|
||||
cs.gridy = 0;
|
||||
cs.gridwidth = 2;
|
||||
panel.add(tfUsername, cs);
|
||||
|
||||
lbPassword = new JLabel("Password: ");
|
||||
cs.gridx = 0;
|
||||
cs.gridy = 1;
|
||||
cs.gridwidth = 1;
|
||||
panel.add(lbPassword, cs);
|
||||
|
||||
pfPassword = new JPasswordField(20);
|
||||
cs.gridx = 1;
|
||||
cs.gridy = 1;
|
||||
cs.gridwidth = 2;
|
||||
panel.add(pfPassword, cs);
|
||||
panel.setBorder(new LineBorder(Color.GRAY));
|
||||
|
||||
btnLogin = new JButton("Login");
|
||||
|
||||
btnCancel = new JButton("Cancel");
|
||||
|
||||
JPanel bp = new JPanel();
|
||||
bp.add(btnLogin);
|
||||
bp.add(btnCancel);
|
||||
|
||||
getContentPane().add(panel, BorderLayout.CENTER);
|
||||
getContentPane().add(bp, BorderLayout.PAGE_END);
|
||||
|
||||
|
||||
btnLogin.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
loginAction = LoginDialogAction.LOGIN;
|
||||
dispose();
|
||||
}
|
||||
});
|
||||
btnCancel.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
loginAction = LoginDialogAction.CANCEL;
|
||||
dispose();
|
||||
}
|
||||
});
|
||||
tfUsername.addKeyListener(new KeyListener(){
|
||||
|
||||
@Override
|
||||
public void keyPressed(KeyEvent e) {
|
||||
if(e.getKeyCode() == KeyEvent.VK_ENTER){
|
||||
btnLogin.doClick();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void keyReleased(KeyEvent e) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void keyTyped(KeyEvent e) {
|
||||
|
||||
}
|
||||
|
||||
});
|
||||
pfPassword.addKeyListener(new KeyListener(){
|
||||
|
||||
@Override
|
||||
public void keyPressed(KeyEvent e) {
|
||||
if(e.getKeyCode() == KeyEvent.VK_ENTER){
|
||||
btnLogin.doClick();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void keyReleased(KeyEvent e) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void keyTyped(KeyEvent e) {
|
||||
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
|
||||
pack();
|
||||
setResizable(false);
|
||||
setLocationRelativeTo(parent);
|
||||
}
|
||||
|
||||
public String getUsername() {
|
||||
return tfUsername.getText().trim();
|
||||
}
|
||||
|
||||
public String getPassword() {
|
||||
return new String(pfPassword.getPassword());
|
||||
}
|
||||
|
||||
public LoginDialogAction getAction() {
|
||||
return this.loginAction;
|
||||
}
|
||||
}
|
||||
65
src/com/coder/client/ProjectFileTreeModel.java
Normal file
65
src/com/coder/client/ProjectFileTreeModel.java
Normal file
|
|
@ -0,0 +1,65 @@
|
|||
package com.coder.client;
|
||||
|
||||
import java.util.HashSet;
|
||||
|
||||
import javax.swing.event.TreeModelListener;
|
||||
import javax.swing.tree.DefaultMutableTreeNode;
|
||||
import javax.swing.tree.TreeModel;
|
||||
import javax.swing.tree.TreePath;
|
||||
|
||||
public class ProjectFileTreeModel implements TreeModel {
|
||||
|
||||
private HashSet<TreeModelListener> treeModelListeners;
|
||||
|
||||
public ProjectFileTreeModel(){
|
||||
treeModelListeners = new HashSet<TreeModelListener>();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addTreeModelListener(TreeModelListener listener) {
|
||||
this.treeModelListeners.add(listener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getChild(Object arg0, int arg1) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getChildCount(Object arg0) {
|
||||
// TODO Auto-generated method stub
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getIndexOfChild(Object arg0, Object arg1) {
|
||||
// TODO Auto-generated method stub
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getRoot() {
|
||||
return new DefaultMutableTreeNode("[Project Name]");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isLeaf(Object arg0) {
|
||||
// TODO Auto-generated method stub
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeTreeModelListener(TreeModelListener listener) {
|
||||
this.treeModelListeners.remove(listener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void valueForPathChanged(TreePath arg0, Object arg1) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
241
src/com/coder/client/Session.java
Normal file
241
src/com/coder/client/Session.java
Normal file
|
|
@ -0,0 +1,241 @@
|
|||
package com.coder.client;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Field;
|
||||
import java.net.Socket;
|
||||
import java.net.UnknownHostException;
|
||||
import java.util.HashSet;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import zutil.log.LogUtil;
|
||||
import zutil.parser.json.JSONObjectInputStream;
|
||||
import zutil.parser.json.JSONObjectOutputStream;
|
||||
|
||||
import com.coder.server.message.AuthenticationChallengeMsg;
|
||||
import com.coder.server.message.AuthenticationReqMsg;
|
||||
import com.coder.server.message.AuthenticationRspMsg;
|
||||
import com.coder.server.message.AuthenticationSuccessMsg;
|
||||
import com.coder.server.message.CoderMessage;
|
||||
|
||||
public class Session extends Thread {
|
||||
public static final Logger logger = LogUtil.getLogger();
|
||||
private static final int AUTH_HASH_ITERATIONS = 500;
|
||||
|
||||
private HashSet<CoderMessageReceivedListener> messageReceivedlisteners = new HashSet<CoderMessageReceivedListener>();
|
||||
|
||||
private boolean authenticated;
|
||||
private Socket socket;
|
||||
private JSONObjectInputStream in;
|
||||
private JSONObjectOutputStream out;
|
||||
|
||||
private Session(){
|
||||
|
||||
}
|
||||
|
||||
public static Session setupConnection(String url, int port){
|
||||
Session session = new Session();
|
||||
logger.info("Setting up a TCP socket to " + url + ":" + port);
|
||||
try {
|
||||
session.socket = new Socket(url, port);
|
||||
} catch (UnknownHostException e) {
|
||||
logger.log(Level.SEVERE, null, e);
|
||||
session.close();
|
||||
return null;
|
||||
} catch (IOException e) {
|
||||
logger.log(Level.SEVERE, null, e);
|
||||
session.close();
|
||||
return null;
|
||||
}
|
||||
logger.info(session.socket + " connected");
|
||||
return session;
|
||||
}
|
||||
|
||||
private void close(){
|
||||
if(socket != null){
|
||||
try {
|
||||
socket.close();
|
||||
} catch (IOException e) {
|
||||
logger.log(Level.SEVERE, null, e);
|
||||
}
|
||||
socket = null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run(){
|
||||
if(!authenticated){
|
||||
logger.severe("Session cannot start since it is not authenticated");
|
||||
close();
|
||||
return;
|
||||
}
|
||||
while(true){
|
||||
CoderMessage msg;
|
||||
try {
|
||||
msg = readMsg();
|
||||
} catch (IOException e) {
|
||||
close();
|
||||
return;
|
||||
}
|
||||
if(msg == null){
|
||||
close();
|
||||
return;
|
||||
}
|
||||
if(msg != null){
|
||||
handleMessage(msg);
|
||||
}
|
||||
Thread.yield();
|
||||
}
|
||||
}
|
||||
|
||||
public void send(CoderMessage msg) throws IOException{
|
||||
out.writeObject(msg);
|
||||
out.flush();
|
||||
}
|
||||
|
||||
public void addCoderMessageReceivedListener(CoderMessageReceivedListener listener){
|
||||
messageReceivedlisteners.add(listener);
|
||||
}
|
||||
|
||||
public boolean removeListener(CoderMessageReceivedListener listener){
|
||||
return messageReceivedlisteners.remove(listener);
|
||||
}
|
||||
|
||||
public boolean isConnected(){
|
||||
return socket != null;
|
||||
}
|
||||
|
||||
public String[] getProjectNames(){
|
||||
return new String[]{};
|
||||
}
|
||||
|
||||
public boolean authenticate(String username, String clearTextPassword) {
|
||||
|
||||
logger.info("Authenticating session");
|
||||
|
||||
if(socket == null){
|
||||
logger.severe("Cannot authenticate on a closed socket");
|
||||
return false;
|
||||
}
|
||||
|
||||
///////////// CLEARTEXT CONNECTION //////////////////////
|
||||
|
||||
// We dont create any buffers here as these streams might be replaced by encrypted ones
|
||||
try {
|
||||
in = new JSONObjectInputStream(socket.getInputStream());
|
||||
} catch (IOException e) {
|
||||
logger.log(Level.SEVERE, null, e);
|
||||
close();
|
||||
return false;
|
||||
}
|
||||
in.registerRootClass(CoderMessage.class);
|
||||
in.registerClass("AuthenticationChallenge", AuthenticationChallengeMsg.class);
|
||||
in.registerClass("AuthenticationSuccess", AuthenticationSuccessMsg.class);
|
||||
try {
|
||||
out = new JSONObjectOutputStream(socket.getOutputStream());
|
||||
} catch (IOException e) {
|
||||
logger.log(Level.SEVERE, null, e);
|
||||
close();
|
||||
return false;
|
||||
}
|
||||
out.enableMetaData(false);
|
||||
|
||||
//Send AuthenticationReq
|
||||
CoderMessage authReq = new CoderMessage();
|
||||
authReq.AuthenticationReq = new AuthenticationReqMsg();
|
||||
authReq.AuthenticationReq.username = username;
|
||||
logger.info("Sending AuthenticationReq");
|
||||
try {
|
||||
send(authReq);
|
||||
} catch (IOException e) {
|
||||
logger.log(Level.SEVERE, null, e);
|
||||
close();
|
||||
return false;
|
||||
}
|
||||
|
||||
//Receive AuthenticationChallenge
|
||||
logger.info("Waiting for AuthenticationChallenge");
|
||||
CoderMessage msg;
|
||||
try {
|
||||
msg = readMsg();
|
||||
} catch (IOException e) {
|
||||
logger.log(Level.SEVERE, null, e);
|
||||
close();
|
||||
return false;
|
||||
}
|
||||
if(msg == null || msg.AuthenticationChallenge == null){
|
||||
logger.severe("Expected message AuthenticationChallenge");
|
||||
close();
|
||||
return false;
|
||||
}
|
||||
logger.log(Level.INFO, "Received AuthenticationChallenge");
|
||||
|
||||
// Setting up encryption
|
||||
logger.info("Setting up encryption");
|
||||
/*
|
||||
String hashedPassword = Hasher.PBKDF2(clearTextPassword, "BYTESUT", AUTH_HASH_ITERATIONS);
|
||||
String key = Hasher.PBKDF2(hashedPassword, msg.AuthenticationChallenge.salt, AUTH_HASH_ITERATIONS);
|
||||
Encrypter crypto = new Encrypter(key, Encrypter.AES_ALGO);
|
||||
in = new JSONObjectInputStream(new BufferedInputStream(crypto.decrypt(socket.getInputStream())));
|
||||
in.registerRootClass(CoderMessage.class);
|
||||
out = new JSONObjectOutputStream(new BufferedOutputStream(crypto.encrypt(socket.getOutputStream())));
|
||||
out.enableMetaData(false);
|
||||
*/
|
||||
|
||||
///////////// ENCRYPTED CONNECTION //////////////////////
|
||||
|
||||
//Send AuthenticationRsp
|
||||
CoderMessage authRsp = new CoderMessage();
|
||||
authRsp.AuthenticationRsp = new AuthenticationRspMsg();
|
||||
authRsp.AuthenticationRsp.timestamp = System.currentTimeMillis();
|
||||
logger.info("Sending AuthenticationRsp");
|
||||
try {
|
||||
send(authRsp);
|
||||
} catch (IOException e) {
|
||||
logger.log(Level.SEVERE, null, e);
|
||||
close();
|
||||
return false;
|
||||
}
|
||||
|
||||
logger.info("Waiting for AuthenticationSuccess");
|
||||
try {
|
||||
msg = readMsg();
|
||||
} catch (IOException e) {
|
||||
logger.log(Level.SEVERE, null, e);
|
||||
close();
|
||||
return false;
|
||||
}
|
||||
if(msg == null || msg.AuthenticationSuccess == null){
|
||||
logger.severe("Authentication failure");
|
||||
close();
|
||||
return false;
|
||||
}
|
||||
logger.info("Received AuthenticationSuccess");
|
||||
|
||||
logger.info("Session authenticated");
|
||||
|
||||
this.authenticated = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
private CoderMessage readMsg() throws IOException {
|
||||
return (CoderMessage) in.readObject();
|
||||
}
|
||||
|
||||
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){
|
||||
for(CoderMessageReceivedListener listener : messageReceivedlisteners){
|
||||
listener.msgReceived(field.getClass(), obj);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue