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