diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 00000000..7bbd729d Binary files /dev/null and b/.DS_Store differ diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..8c0b7bcc --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +/Client/nbproject/private/ +/Server/nbproject/private/ +/Client/build/ +/Server/build/ +/Timolous/build/ \ No newline at end of file diff --git a/Client/build.xml b/Client/build.xml new file mode 100644 index 00000000..4f989572 --- /dev/null +++ b/Client/build.xml @@ -0,0 +1,74 @@ + + + + + + + + + + + Builds, tests, and runs the project Client. + + + diff --git a/Client/log.txt b/Client/log.txt new file mode 100644 index 00000000..4feeb6df --- /dev/null +++ b/Client/log.txt @@ -0,0 +1,11 @@ +6,0,0 +7,1,1368955118424 +9,1,1369016187888 +10,1,1368955118425 +11,0,0 +12,0,1369016187879 +13,0,0 +14,0,0 +10,0,1369073765164 +10,1,1369084335257 +10,0,1369084353159 \ No newline at end of file diff --git a/Client/manifest.mf b/Client/manifest.mf new file mode 100644 index 00000000..328e8e5b --- /dev/null +++ b/Client/manifest.mf @@ -0,0 +1,3 @@ +Manifest-Version: 1.0 +X-COMMENT: Main-Class will be added automatically by build + diff --git a/Client/mysql-connector-java-5.1.25-bin.jar b/Client/mysql-connector-java-5.1.25-bin.jar new file mode 100644 index 00000000..207232df Binary files /dev/null and b/Client/mysql-connector-java-5.1.25-bin.jar differ diff --git a/Client/nbproject/build-impl.xml b/Client/nbproject/build-impl.xml new file mode 100644 index 00000000..3b5b7e80 --- /dev/null +++ b/Client/nbproject/build-impl.xml @@ -0,0 +1,1411 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must set src.dir + Must set test.src.dir + Must set build.dir + Must set dist.dir + Must set build.classes.dir + Must set dist.javadoc.dir + Must set build.test.classes.dir + Must set build.test.results.dir + Must set build.classes.excludes + Must set dist.jar + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must set javac.includes + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + No tests executed. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must set JVM to use for profiling in profiler.info.jvm + Must set profiler agent JVM arguments in profiler.info.jvmargs.agent + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must select some files in the IDE or set javac.includes + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + To run this application from the command line without Ant, try: + + + + + + + java -cp "${run.classpath.with.dist.jar}" ${main.class} + + + + + + + + + + + + + + + + + + + + + + + + + To run this application from the command line without Ant, try: + + java -jar "${dist.jar.resolved}" + + + + + + + + + + + + + + + + + + + + + + + + + Must select one file in the IDE or set run.class + + + + Must select one file in the IDE or set run.class + + + + + + + + + + + + + + + + + + + + + + + Must select one file in the IDE or set debug.class + + + + + Must select one file in the IDE or set debug.class + + + + + Must set fix.includes + + + + + + + + + + This target only works when run from inside the NetBeans IDE. + + + + + + + + + Must select one file in the IDE or set profile.class + This target only works when run from inside the NetBeans IDE. + + + + + + + + + This target only works when run from inside the NetBeans IDE. + + + + + + + + + + + + + This target only works when run from inside the NetBeans IDE. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must select one file in the IDE or set run.class + + + + + + Must select some files in the IDE or set test.includes + + + + + Must select one file in the IDE or set run.class + + + + + Must select one file in the IDE or set applet.url + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must select some files in the IDE or set javac.includes + + + + + + + + + + + + + + + + + + + + Some tests failed; see details above. + + + + + + + + + Must select some files in the IDE or set test.includes + + + + Some tests failed; see details above. + + + + Must select some files in the IDE or set test.class + Must select some method in the IDE or set test.method + + + + Some tests failed; see details above. + + + + + Must select one file in the IDE or set test.class + + + + Must select one file in the IDE or set test.class + Must select some method in the IDE or set test.method + + + + + + + + + + + + + + Must select one file in the IDE or set applet.url + + + + + + + + + Must select one file in the IDE or set applet.url + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Client/nbproject/genfiles.properties b/Client/nbproject/genfiles.properties new file mode 100644 index 00000000..153688c1 --- /dev/null +++ b/Client/nbproject/genfiles.properties @@ -0,0 +1,8 @@ +build.xml.data.CRC32=b87a2947 +build.xml.script.CRC32=612b5c9b +build.xml.stylesheet.CRC32=28e38971@1.56.1.46 +# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml. +# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you. +nbproject/build-impl.xml.data.CRC32=b87a2947 +nbproject/build-impl.xml.script.CRC32=77e84829 +nbproject/build-impl.xml.stylesheet.CRC32=c6d2a60f@1.56.1.46 diff --git a/Client/nbproject/project.properties b/Client/nbproject/project.properties new file mode 100644 index 00000000..3b023b05 --- /dev/null +++ b/Client/nbproject/project.properties @@ -0,0 +1,73 @@ +annotation.processing.enabled=true +annotation.processing.enabled.in.editor=false +annotation.processing.processors.list= +annotation.processing.run.all.processors=true +annotation.processing.source.output=${build.generated.sources.dir}/ap-source-output +application.title=Client +application.vendor=Compaq +build.classes.dir=${build.dir}/classes +build.classes.excludes=**/*.java,**/*.form +# This directory is removed when the project is cleaned: +build.dir=build +build.generated.dir=${build.dir}/generated +build.generated.sources.dir=${build.dir}/generated-sources +# Only compile against the classpath explicitly listed here: +build.sysclasspath=ignore +build.test.classes.dir=${build.dir}/test/classes +build.test.results.dir=${build.dir}/test/results +# Uncomment to specify the preferred debugger connection transport: +#debug.transport=dt_socket +debug.classpath=\ + ${run.classpath} +debug.test.classpath=\ + ${run.test.classpath} +# This directory is removed when the project is cleaned: +dist.dir=dist +dist.jar=${dist.dir}/Client.jar +dist.javadoc.dir=${dist.dir}/javadoc +endorsed.classpath= +excludes= +includes=** +jar.compress=false +javac.classpath= +# Space-separated list of extra javac options +javac.compilerargs= +javac.deprecation=false +javac.processorpath=\ + ${javac.classpath} +javac.source=1.7 +javac.target=1.7 +javac.test.classpath=\ + ${javac.classpath}:\ + ${build.classes.dir} +javac.test.processorpath=\ + ${javac.test.classpath} +javadoc.additionalparam= +javadoc.author=false +javadoc.encoding=${source.encoding} +javadoc.noindex=false +javadoc.nonavbar=false +javadoc.notree=false +javadoc.private=false +javadoc.splitindex=true +javadoc.use=true +javadoc.version=false +javadoc.windowtitle= +main.class=client.Client +manifest.file=manifest.mf +meta.inf.dir=${src.dir}/META-INF +mkdist.disabled=false +platform.active=default_platform +run.classpath=\ + ${javac.classpath}:\ + ${build.classes.dir} +# Space-separated list of JVM arguments used when running the project. +# You may also define separate properties like run-sys-prop.name=value instead of -Dname=value. +# To set system properties for unit tests define test-sys-prop.name=value: +run.jvmargs= +run.test.classpath=\ + ${javac.test.classpath}:\ + ${build.test.classes.dir} +source.encoding=UTF-8 +src.dir=src +test.src.dir=test diff --git a/Client/nbproject/project.xml b/Client/nbproject/project.xml new file mode 100644 index 00000000..f027ba71 --- /dev/null +++ b/Client/nbproject/project.xml @@ -0,0 +1,15 @@ + + + org.netbeans.modules.java.j2seproject + + + Client + + + + + + + + + diff --git a/Client/src/client/Client.java b/Client/src/client/Client.java new file mode 100644 index 00000000..dae24508 --- /dev/null +++ b/Client/src/client/Client.java @@ -0,0 +1,268 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ +package client; + +import java.io.*; +import java.net.*; +import java.sql.DriverManager; +import java.sql.Connection; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.List; +import java.util.Scanner; +import javax.swing.JOptionPane; + +/** + * + * @author Timotius + */ +public class Client { + + private String username; + private long lastUpdate; + private Boolean running; + private Socket clientSocket; + + Client() { + this.running = true; + } + + public Socket getClientSocket() { + return clientSocket; + } + + public void setClientSocket(Socket clientSocket) { + this.clientSocket = clientSocket; + } + + public Boolean getRunning() { + return running; + } + + public long getLastUpdate() { + return lastUpdate; + } + + public void setLastUpdate(long lastUpdate) { + this.lastUpdate = lastUpdate; + } + + public void setUsername(String username) { + this.username = username; + } + + public String getUsername() { + return username; + } + + public static void main(String[] args) { + + Client c = new Client(); + String command; + //String request; + //String respond; + + try { + BufferedReader inClient = new BufferedReader(new InputStreamReader(System.in)); + c.clientSocket = new Socket("localhost", 1234); + DataOutputStream outServer = new DataOutputStream(c.clientSocket.getOutputStream()); + BufferedReader inServer = new BufferedReader(new InputStreamReader(c.clientSocket.getInputStream())); + while (c.running) { + System.out.print(">> "); + command = inClient.readLine(); + command = command.toLowerCase(); + switch (command) { + case ("login"): { + System.out.print("Enter username: "); + String username = inClient.readLine(); + c.setUsername(username); + System.out.print("Enter password: "); + String password = inClient.readLine(); + + String request1 = ("1," + username + "," + password); //kirim: 1,kennyazrina,kennyazrina + outServer.writeBytes(request1 + '\n'); + String respond1 = inServer.readLine(); //terima: 200 atau 400 + user.last_update + System.out.println("respond1: "+respond1); + + String[] responds1 = respond1.split(","); + if (responds1[0].equals("200")) { + c.lastUpdate = Long.parseLong(responds1[1]); + int servercount = Integer.parseInt(responds1[2]); + System.out.println("Login successful, " + username + " username.last_update is " + c.lastUpdate); + //Baca dari log + try { + Scanner scanner = new Scanner(new FileReader("log.txt")); + String logs = ""; + long last = 0; + while (scanner.hasNextLine()) { + String now = scanner.nextLine(); //format now: task_id, task_status, timestamp + String[] logparts = now.split(","); + + if (Long.parseLong(logparts[2]) > c.lastUpdate){ + if (Long.parseLong(logparts[2]) > last){ + last = Long.parseLong(logparts[2]); + } + logs = logs + now + ","; //kumpulkan semua line yang punya timestamp > user.last_update + } + } + //di sini last bernilai 0 jika tidak ada timestamp log yg lebih baru (>) dari user.last_update + //Kirim 4,kennyazrina,,, user.last_update> + String request2 = ("4," + username + "," + c.lastUpdate + "," + logs); + request2 = request2.substring(0, request2.length()-1); //hilangkan koma terakhir dari logs + System.out.println("request2: "+request2); + outServer.writeBytes(request2 + '\n'); + } catch (IOException e) { + System.out.println("Baca dari log: "+e.getMessage()); + System.exit(1); + } + //menerima lastupdate terbaru merdasar max_timestamp + String respond2 = inServer.readLine(); + System.out.println("respond2: "+respond2); + String[] responds2 = respond2.split(","); + if (responds2[0].equals("200")){ + c.lastUpdate = Long.parseLong(responds2[1]); + } else { + c.lastUpdate = Long.parseLong(responds2[1]); //mestinya hasilnya 0 + } + System.out.println("current client's lastupdate: "+c.lastUpdate); + + //menerima semua task milik user + String respond3 = inServer.readLine(); + System.out.println("respond3: "+respond3); + + String[] responds3 = respond3.split(","); + ArrayList logs = new ArrayList<>(); + int a = 0; + while (a < responds3.length){ + Log log = new Log(); + log.setId_task(responds3[a]); + log.setTaskname(responds3[a+1]); + log.setDeadline(responds3[a+2]); + String[] respondsA3Parsed = responds3[a+3].split(":"); + for (int n = 0; n < respondsA3Parsed.length; n++){ + (log.getAssignee()).add(respondsA3Parsed[n]); + } + String[] respondsA4Parsed = responds3[a+4].split(":"); + for (int n = 0; n < respondsA4Parsed.length; n++){ + (log.getTag()).add(respondsA4Parsed[n]); + } + log.setStatus(responds3[a+5]); + log.setCategory(responds3[a+6]); + logs.add(log); + a = a + 7; + } + for (int i = 0; i < logs.size(); i++){ + System.out.println("Log "+(i+1)+":"); + System.out.println(":: task_id: "+logs.get(i).getId_task()); + System.out.println(":: task_name: "+logs.get(i).getTaskname()); + System.out.println(":: deadline: "+logs.get(i).getDeadline()); + System.out.print(":: assignees: "); + for (int j = 0; j < logs.get(i).getAssignee().size(); j++){ + System.out.print(logs.get(i).getAssignee().get(j)+","); + } + System.out.print("\n:: tags: "); + for (int j = 0; j < logs.get(i).getTag().size(); j++){ + System.out.print(logs.get(i).getTag().get(j)+","); + } + System.out.println("\n:: status: "+logs.get(i).getStatus()); + System.out.println(":: category: "+logs.get(i).getCategory()); + } + /*String[] responds2 = respond2.split(","); + if (responds[0].equals("200")) { + System.out.println("Synchronizing..."); + String[] responds2; + for (int i = 1; i < responds.length; i++) { + responds2 = responds[i].split(":"); + System.out.println("task_id: " + responds2[0] + ", current status: " + responds2[1] + ", updated"); + } + + String request2, respond2; + long now = System.currentTimeMillis(); + request2 = "" + now; + outServer.writeBytes(request2 + '\n'); + + respond2 = inServer.readLine(); + if (respond2.equals("200")) { + System.out.println("Update last update successful"); + } else if (respond2.equals("400")) { + System.out.println("Update last update failed"); + } else { + System.out.println("Unrecognized respond"); + } + } else if (responds[0].equals("400")) { + System.out.println("No update..."); + } else { + System.out.println("unrecognized respond"); + }*/ + System.out.println("Creating 'keep update' thread"); + Runnable task = new MyRunnable(c, servercount); + Thread threadUpdate = new Thread(task); + threadUpdate.start(); + } else { + System.out.println("Login failed"); + } + break; + } + case ("check"): { + System.out.print("Enter task_id: "); + String task_id = inClient.readLine(); + String request1 = ("2," + task_id + "," + c.getUsername()); + outServer.writeBytes(request1 + '\n'); + String respond1 = inServer.readLine(); + + String[] responds = respond1.split(","); + if (responds[0].equals("200")) { + c.lastUpdate = Long.parseLong(responds[1]); + //write to log + FileWriter fw = new FileWriter("log.txt",true); + BufferedWriter out = new BufferedWriter(fw); + out.newLine(); + out.write(task_id + ",1," + c.lastUpdate); + out.close(); + System.out.println("Check successful, lastUpdate " + c.lastUpdate); + } else { + System.out.println("Check failed"); + } + break; + } + case ("uncheck"): { + System.out.print("Enter task_id: "); + String task_id = inClient.readLine(); + String request1 = ("3," + task_id + "," + c.getUsername()); + outServer.writeBytes(request1 + '\n'); + String respond1 = inServer.readLine(); + + String[] responds = respond1.split(","); + if (responds[0].equals("200")) { + c.lastUpdate = Long.parseLong(responds[1]); + //write to log + FileWriter fw = new FileWriter("log.txt",true); + BufferedWriter out = new BufferedWriter(fw); + out.newLine(); + out.write(task_id + ",0," + c.lastUpdate); + out.close(); + System.out.println("Uncheck successful, lastUpdate " + c.lastUpdate); + } else { + System.out.println("Uncheck failed"); + } + break; + } + case ("logout"):{ + c.running = false; + System.out.println("exited"); + } + default: { + break; + } + } + + //System.out.println("From Server: " + message); + } + c.clientSocket.close(); + } catch (Exception e) { + System.out.println("ClientSocket: " + e.getMessage()); + } + } +} diff --git a/Client/src/client/Log.java b/Client/src/client/Log.java new file mode 100644 index 00000000..b5ee965c --- /dev/null +++ b/Client/src/client/Log.java @@ -0,0 +1,93 @@ +package client; + +import java.util.ArrayList; +import java.util.List; + +public class Log { + private String id_task; + private String taskname; + private String deadline; + private List assignee; + private List tag; + private String status; + private String category; + + Log(){ + id_task = null; + taskname=null; + deadline = null; + assignee = new ArrayList(); + tag = new ArrayList(); + status=null; + category=null; + } + + Log(String a, String b, String c, Listd, Liste, String f, String g){ + id_task = a; + taskname=b; + deadline=c; + assignee = new ArrayList(d); + tag = new ArrayList(e); + status=f; + category=g; + } + + public String getId_task() { + return id_task; + } + + public String getTaskname() { + return taskname; + } + + public List getAssignee() { + return assignee; + } + + public String getCategory() { + return category; + } + + public String getStatus() { + return status; + } + + public String getDeadline() { + return deadline; + } + + public void setId_task(String id_task) { + this.id_task = id_task; + } + + public void setTaskname(String taskname) { + this.taskname = taskname; + } + + public void setAssignee(List assignee) { + this.assignee = assignee; + } + + public void setCategory(String category) { + this.category = category; + } + + public void setStatus(String status) { + this.status = status; + } + + public void setDeadline(String deadline) { + this.deadline = deadline; + } + + public List getTag() { + return tag; + } + + public void setTag(List tag) { + this.tag = tag; + } + + + +} diff --git a/Client/src/client/MyRunnable.java b/Client/src/client/MyRunnable.java new file mode 100644 index 00000000..e886d83b --- /dev/null +++ b/Client/src/client/MyRunnable.java @@ -0,0 +1,71 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ +package client; + +import java.io.BufferedReader; +import java.io.DataOutputStream; +import java.io.InputStreamReader; +import java.net.Socket; +import java.util.ArrayList; + +/** + * + * @author Compaq + */ +public class MyRunnable implements Runnable { + private Client client; + private int count; + public MyRunnable(Client c, int servercount){ + this.client = c; + this.count = servercount; + } + public void run(){ + try{ + Socket askSocket = new Socket("localhost", 5000 + count); + DataOutputStream out = new DataOutputStream(askSocket.getOutputStream()); + BufferedReader in = new BufferedReader(new InputStreamReader(askSocket.getInputStream())); + while (client.getRunning()){ + out.writeBytes("11,"+client.getUsername()+","+client.getLastUpdate()+"\n"); //11,kennyazrina, + String respond1 = in.readLine(); + //System.out.println("myrunnable :: respond1: " + respond1); + String[] responds1 = respond1.split(","); + if (responds1[0].equals("13")){ + client.setLastUpdate(Long.parseLong(responds1[1])); + //responds1[2] berisi task_id, responds1[3] berisi task-status, dst + int i = 2; + ArrayList elms = new ArrayList<>(); + while (i < responds1.length){ + UpdateElm elm = new UpdateElm(); + elm.setTask_id(responds1[i]); + elm.setTask_status(responds1[i+1]); + elms.add(elm); + i = i + 2; + } + for (int j = 0; j < elms.size(); j++){ + System.out.println("Elms "+j+": "); + System.out.println(":: task_id: "+elms.get(j).getTask_id()); + System.out.println(":: task_status: "+elms.get(j).getTask_status()); + } + } else{ + //System.out.println("myrunnable: no updates"); + } + Thread.sleep(1000); + } + out.writeBytes("5\n"); + } catch (Exception e){ + System.out.println("MyRunnable: "+e.getMessage()); + //saat koneksi diputus + /*boolean reconnected = false; + while (!reconnected){ + try{ + client.setClientSocket(new Socket("localhost", 1234)); + reconnected = true; + } catch (Exception ex){ + System.out.println("Reconnecting: "+ex.getMessage()); + } + }*/ + } + } +} diff --git a/Client/src/client/UpdateElm.java b/Client/src/client/UpdateElm.java new file mode 100644 index 00000000..f5a431cd --- /dev/null +++ b/Client/src/client/UpdateElm.java @@ -0,0 +1,37 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ +package client; + +/** + * + * @author Compaq + */ +public class UpdateElm { + private String task_id; + private String task_status; + + public UpdateElm(){ + this.task_id = null; + this.task_status = null; + } + + public String getTask_id() { + return task_id; + } + + public void setTask_id(String task_id) { + this.task_id = task_id; + } + + public String getTask_status() { + return task_status; + } + + public void setTask_status(String task_status) { + this.task_status = task_status; + } + + +} diff --git a/DokumentasiTimolous.docx b/DokumentasiTimolous.docx new file mode 100644 index 00000000..fec5aef0 Binary files /dev/null and b/DokumentasiTimolous.docx differ diff --git a/Server/build.xml b/Server/build.xml new file mode 100644 index 00000000..fa80ae64 --- /dev/null +++ b/Server/build.xml @@ -0,0 +1,74 @@ + + + + + + + + + + + Builds, tests, and runs the project Server. + + + diff --git a/Server/manifest.mf b/Server/manifest.mf new file mode 100644 index 00000000..328e8e5b --- /dev/null +++ b/Server/manifest.mf @@ -0,0 +1,3 @@ +Manifest-Version: 1.0 +X-COMMENT: Main-Class will be added automatically by build + diff --git a/Server/mysql-connector-java-5.1.25-bin.jar b/Server/mysql-connector-java-5.1.25-bin.jar new file mode 100644 index 00000000..207232df Binary files /dev/null and b/Server/mysql-connector-java-5.1.25-bin.jar differ diff --git a/Server/nbproject/build-impl.xml b/Server/nbproject/build-impl.xml new file mode 100644 index 00000000..f1b6346e --- /dev/null +++ b/Server/nbproject/build-impl.xml @@ -0,0 +1,1411 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must set src.dir + Must set test.src.dir + Must set build.dir + Must set dist.dir + Must set build.classes.dir + Must set dist.javadoc.dir + Must set build.test.classes.dir + Must set build.test.results.dir + Must set build.classes.excludes + Must set dist.jar + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must set javac.includes + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + No tests executed. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must set JVM to use for profiling in profiler.info.jvm + Must set profiler agent JVM arguments in profiler.info.jvmargs.agent + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must select some files in the IDE or set javac.includes + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + To run this application from the command line without Ant, try: + + + + + + + java -cp "${run.classpath.with.dist.jar}" ${main.class} + + + + + + + + + + + + + + + + + + + + + + + + + To run this application from the command line without Ant, try: + + java -jar "${dist.jar.resolved}" + + + + + + + + + + + + + + + + + + + + + + + + + Must select one file in the IDE or set run.class + + + + Must select one file in the IDE or set run.class + + + + + + + + + + + + + + + + + + + + + + + Must select one file in the IDE or set debug.class + + + + + Must select one file in the IDE or set debug.class + + + + + Must set fix.includes + + + + + + + + + + This target only works when run from inside the NetBeans IDE. + + + + + + + + + Must select one file in the IDE or set profile.class + This target only works when run from inside the NetBeans IDE. + + + + + + + + + This target only works when run from inside the NetBeans IDE. + + + + + + + + + + + + + This target only works when run from inside the NetBeans IDE. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must select one file in the IDE or set run.class + + + + + + Must select some files in the IDE or set test.includes + + + + + Must select one file in the IDE or set run.class + + + + + Must select one file in the IDE or set applet.url + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must select some files in the IDE or set javac.includes + + + + + + + + + + + + + + + + + + + + Some tests failed; see details above. + + + + + + + + + Must select some files in the IDE or set test.includes + + + + Some tests failed; see details above. + + + + Must select some files in the IDE or set test.class + Must select some method in the IDE or set test.method + + + + Some tests failed; see details above. + + + + + Must select one file in the IDE or set test.class + + + + Must select one file in the IDE or set test.class + Must select some method in the IDE or set test.method + + + + + + + + + + + + + + Must select one file in the IDE or set applet.url + + + + + + + + + Must select one file in the IDE or set applet.url + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Server/nbproject/genfiles.properties b/Server/nbproject/genfiles.properties new file mode 100644 index 00000000..bdf5b9ac --- /dev/null +++ b/Server/nbproject/genfiles.properties @@ -0,0 +1,8 @@ +build.xml.data.CRC32=6f248d50 +build.xml.script.CRC32=5a7fa1ba +build.xml.stylesheet.CRC32=28e38971@1.56.1.46 +# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml. +# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you. +nbproject/build-impl.xml.data.CRC32=6f248d50 +nbproject/build-impl.xml.script.CRC32=0f64e03c +nbproject/build-impl.xml.stylesheet.CRC32=c6d2a60f@1.56.1.46 diff --git a/Server/nbproject/project.properties b/Server/nbproject/project.properties new file mode 100644 index 00000000..60e5bf45 --- /dev/null +++ b/Server/nbproject/project.properties @@ -0,0 +1,75 @@ +annotation.processing.enabled=true +annotation.processing.enabled.in.editor=false +annotation.processing.processors.list= +annotation.processing.run.all.processors=true +annotation.processing.source.output=${build.generated.sources.dir}/ap-source-output +application.title=Server +application.vendor=Compaq +build.classes.dir=${build.dir}/classes +build.classes.excludes=**/*.java,**/*.form +# This directory is removed when the project is cleaned: +build.dir=build +build.generated.dir=${build.dir}/generated +build.generated.sources.dir=${build.dir}/generated-sources +# Only compile against the classpath explicitly listed here: +build.sysclasspath=ignore +build.test.classes.dir=${build.dir}/test/classes +build.test.results.dir=${build.dir}/test/results +# Uncomment to specify the preferred debugger connection transport: +#debug.transport=dt_socket +debug.classpath=\ + ${run.classpath} +debug.test.classpath=\ + ${run.test.classpath} +# This directory is removed when the project is cleaned: +dist.dir=dist +dist.jar=${dist.dir}/Server.jar +dist.javadoc.dir=${dist.dir}/javadoc +endorsed.classpath= +excludes= +file.reference.mysql-connector-java-5.1.25-bin.jar=mysql-connector-java-5.1.25-bin.jar +includes=** +jar.compress=false +javac.classpath=\ + ${file.reference.mysql-connector-java-5.1.25-bin.jar} +# Space-separated list of extra javac options +javac.compilerargs= +javac.deprecation=false +javac.processorpath=\ + ${javac.classpath} +javac.source=1.7 +javac.target=1.7 +javac.test.classpath=\ + ${javac.classpath}:\ + ${build.classes.dir} +javac.test.processorpath=\ + ${javac.test.classpath} +javadoc.additionalparam= +javadoc.author=false +javadoc.encoding=${source.encoding} +javadoc.noindex=false +javadoc.nonavbar=false +javadoc.notree=false +javadoc.private=false +javadoc.splitindex=true +javadoc.use=true +javadoc.version=false +javadoc.windowtitle= +main.class=server.Server +manifest.file=manifest.mf +meta.inf.dir=${src.dir}/META-INF +mkdist.disabled=false +platform.active=default_platform +run.classpath=\ + ${javac.classpath}:\ + ${build.classes.dir} +# Space-separated list of JVM arguments used when running the project. +# You may also define separate properties like run-sys-prop.name=value instead of -Dname=value. +# To set system properties for unit tests define test-sys-prop.name=value: +run.jvmargs= +run.test.classpath=\ + ${javac.test.classpath}:\ + ${build.test.classes.dir} +source.encoding=UTF-8 +src.dir=src +test.src.dir=test diff --git a/Server/nbproject/project.xml b/Server/nbproject/project.xml new file mode 100644 index 00000000..61113d04 --- /dev/null +++ b/Server/nbproject/project.xml @@ -0,0 +1,15 @@ + + + org.netbeans.modules.java.j2seproject + + + Server + + + + + + + + + diff --git a/Server/src/server/Database.java b/Server/src/server/Database.java new file mode 100644 index 00000000..6a3fe099 --- /dev/null +++ b/Server/src/server/Database.java @@ -0,0 +1,296 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ +package server; + +import java.sql.DriverManager; +import java.sql.Connection; +import java.sql.SQLException; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.Statement; +import java.util.Date; + +/** + * + * @author Compaq + */ +public class Database { + + private Connection connection; + //private Statement statement = null; + //private PreparedStatement preparedStatement = null; + //private ResultSet resultSet = null; + + public Database() { + System.out.println("-------- MySQL JDBC Connection Testing ------------"); + try { + Class.forName("com.mysql.jdbc.Driver"); + } catch (ClassNotFoundException e) { + System.out.println("Where is your MySQL JDBC Driver?"); + e.printStackTrace(); + return; + } + System.out.println("MySQL JDBC Driver Registered!"); + connection = null; + try { + connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/progin_405_13510086", "root", ""); + } catch (SQLException e) { + System.out.println("Connection Failed! Check output console"); + e.printStackTrace(); + return; + } + if (connection != null) { + System.out.println("You made it, take control your database now!"); + } else { + System.out.println("Failed to make connection!"); + } + } + + public String Login(String username, String password) { + String message = "400"; + try { + PreparedStatement preparedStatement1; + preparedStatement1= connection.prepareStatement("SELECT * FROM user WHERE username = ? and password = ?"); + preparedStatement1.setString(1, username); + preparedStatement1.setString(2, password); + ResultSet resultSet1 = preparedStatement1.executeQuery(); + if (resultSet1.next()) { //jika username dan password terdaftar di database + message = "200," + resultSet1.getLong("last_update"); + /*//if success piggy back all task + PreparedStatement preparedStatement2 = connection.prepareStatement("SELECT * FROM task JOIN task_asignee WHERE task.task_id = task_asignee.task_id AND username = ?"); + preparedStatement2.setString(1, username); + ResultSet resultSet2 = preparedStatement2.executeQuery(); + int rowcount = 0; + if (resultSet2.last()) { + rowcount = resultSet2.getRow(); + resultSet2.beforeFirst(); // not rs.first() because the rs.next() below will move on, missing the first element + } + if (rowcount != 0) { //jika ada hasilnya + System.out.println("row(s) affected: " + rowcount); + while (resultSet2.next()) { + //Data yang wajib diterima dan ditampilkan pada sisi klien adalah + //Nama tugas, deadline, daftar assignee, tag, status, dan nama kategori dari tugas tersebut. + String task_id = resultSet2.getString("task_id"); //<-- ini tetap perlu aja biar mudah refer nya waktu di check/uncheck + String task_name = resultSet2.getString("task_name"); + String deadline = resultSet2.getString("task_deadline"); + //belum tag assigne + String task_status = resultSet2.getString("task_status"); + String cat_name = resultSet2.getString("cat_name"); + + message = message + task_id + "," + task_status + ","; + // System.out.println("task_id: " + task_id + ", task_status; "+ task_status +", username: "+ _username +", timestamp: " + timestamp); + } + message = message + "\n"; + }*/ + } else { + //message tetap 400\n + } + } catch (Exception e) { + System.out.println("Login Error: " + e.getMessage()); + } + return message; + } + + public String GetUserTasks(String username){ + String message = ""; //inisialisasi, siapa tahu gada yang bisa di return + try { + PreparedStatement preparedStatement1 = connection.prepareStatement("SELECT * FROM task JOIN task_asignee WHERE task.task_id = task_asignee.task_id AND username = ?"); + preparedStatement1.setString(1, username); + ResultSet resultSet1 = preparedStatement1.executeQuery(); + int rowcount1 = 0; + if (resultSet1.last()) { + rowcount1 = resultSet1.getRow(); + resultSet1.beforeFirst(); + } + if (rowcount1 != 0) { //jika ada hasilnya + System.out.println("row(s) affected: " + rowcount1); + while (resultSet1.next()) { + //Data yang wajib diterima dan ditampilkan pada sisi klien adalah + //Nama tugas, deadline, daftar assignee, tag, status, dan nama kategori dari tugas tersebut. + String task_id = resultSet1.getString("task_id"); //<-- ini tetap perlu aja biar mudah refer nya waktu di check/uncheck + message = message + task_id + ","; + String task_name = resultSet1.getString("task_name"); + message = message + task_name + ","; + String task_deadline = resultSet1.getString("task_deadline"); + message = message + task_deadline + ","; + try { + PreparedStatement preparedStatement2 = connection.prepareStatement("SELECT * FROM task_asignee WHERE task_id = ?"); + preparedStatement2.setString(1, task_id); + ResultSet resultSet2 = preparedStatement2.executeQuery(); + int rowcount2 = 0; + if (resultSet2.last()) { + rowcount2 = resultSet2.getRow(); + resultSet2.beforeFirst(); // not rs.first() because the rs.next() below will move on, missing the first element + } + if (rowcount2 != 0){ //ada assignee nya + while (resultSet2.next()){ + String task_assignees = resultSet2.getString("username"); + message = message + task_assignees + ":"; + } + message = message.substring(0,message.length()-1); //hilangkan : terakhir + } + message = message + ","; + } catch (Exception e){ + System.out.println("GetUserTasks Fetching Assignee Error: "+e.getMessage()); + } + try { + PreparedStatement preparedStatement3 = connection.prepareStatement("SELECT * FROM tag WHERE task_id = ?"); + preparedStatement3.setString(1, task_id); + ResultSet resultSet3 = preparedStatement3.executeQuery(); + int rowcount3 = 0; + if (resultSet3.last()) { + rowcount3 = resultSet3.getRow(); + resultSet3.beforeFirst(); // not rs.first() because the rs.next() below will move on, missing the first element + } + if (rowcount3 != 0){ //ada tag nya + while (resultSet3.next()){ + String tag_name = resultSet3.getString("tag_name"); + message = message + tag_name + ":"; + } + message = message.substring(0,message.length()-1); //hilangkan : terakhir + } + message = message + ","; + } catch (Exception e){ + System.out.println("GetUserTasks Fetching Tags Error: "+e.getMessage()); + } + String task_status = resultSet1.getString("task_status"); + message = message + task_status + ","; + String cat_name = resultSet1.getString("cat_name"); + message = message + cat_name + ","; + } + } + } catch (Exception e){ + System.out.println("GetUserTasks Error: "+e.getMessage()); + } + if (message.length() > 0){ + message = message.substring(0, message.length()-1); //hilangkan koma terakhir + } + return message; + } + + public long GetMaxTimestamp(String username){ + long max_timestamp = 0; + try{ + PreparedStatement preparedStatement1 = connection.prepareStatement("SELECT MAX(timestamp) AS mt FROM task JOIN task_asignee WHERE task.task_id = task_asignee.task_id AND username = ?"); + preparedStatement1.setString(1, username); + ResultSet resultSet1 = preparedStatement1.executeQuery(); + if (resultSet1.next()) { + max_timestamp = resultSet1.getLong("mt"); + } + } catch (Exception e){ + System.out.println("GetMaxTimestamp Error: "+e.getMessage()); + } + return max_timestamp; + } + + public long GetMaxTimestampAbsolute(){ + //mirip GetMaxTimestamp tapi ini untuk semua task biarpun bukan user tsb. Ini untuk cari tau timestamp terbesar global untuk server last update + long max_timestamp_absolute = 0; + try{ + PreparedStatement preparedStatement1 = connection.prepareStatement("SELECT MAX(timestamp) AS mt FROM task JOIN task_asignee WHERE task.task_id = task_asignee.task_id"); + ResultSet resultSet1 = preparedStatement1.executeQuery(); + if (resultSet1.next()) { + max_timestamp_absolute = resultSet1.getLong("mt"); + } + } catch (Exception e){ + System.out.println("GetMaxTimestampAbsolute Error: "+e.getMessage()); + } + return max_timestamp_absolute; + } + + public String Check(String task_id) { + String message = "400"; + long now = System.currentTimeMillis(); + try { + PreparedStatement preparedStatement1 = connection.prepareStatement("UPDATE task SET task_status = 1, timestamp = " + now + " WHERE task_id = ?"); + preparedStatement1.setString(1, task_id); + if (preparedStatement1.executeUpdate() != 0) { + message = "200," + now; //success + } + } catch (Exception e) { + System.out.println("Check Error: " + e.getMessage()); + } + return message; + } + + public String Uncheck(String task_id) { + String message = "400"; + long now = System.currentTimeMillis(); + try { + PreparedStatement preparedStatement1 = connection.prepareStatement("UPDATE task SET task_status = 0, timestamp = " + now + " WHERE task_id = ?"); + preparedStatement1.setString(1, task_id); + if (preparedStatement1.executeUpdate() != 0) { + message = "200," + now; //success + } + } catch (Exception e) { + System.out.println("Uncheck Error: " + e.getMessage()); + } + return message; + } + + public String Synchronize(String task_id, String status, Long lastUpdate) { + String message = "400"; + try { + //update hanya bila timestamp task-X di database lebih usang (<) daripada timestamp task-X di log + PreparedStatement preparedStatement1 = connection.prepareStatement("UPDATE task SET task_status = ?, timestamp = ? WHERE task_id = ? AND timestamp < ?"); + preparedStatement1.setString(1, status); + preparedStatement1.setLong(2, lastUpdate); + preparedStatement1.setString(3, task_id); + preparedStatement1.setLong(4, lastUpdate); + if (preparedStatement1.executeUpdate() != 0) { + message = "200"; //success + } + } catch (Exception e) { + System.out.println("Synchronize Error: " + e.getMessage()); + } + return message; + } + + public String FetchUpdates (String username, Long lastUpdate){ + String message = ""; + try{ + //ambil semua row yang timestamp nya lebih besar dari lastUpdate (lebih baru), ambil task_id sama task_status nya + PreparedStatement preparedStatement1 = connection.prepareStatement("SELECT * FROM task JOIN task_asignee WHERE task.task_id = task_asignee.task_id AND username = ? AND timestamp > ? "); + preparedStatement1.setString(1, username); + preparedStatement1.setLong(2, lastUpdate); + ResultSet resultSet1 = preparedStatement1.executeQuery(); + int rowcount1 = 0; + if (resultSet1.last()) { + rowcount1 = resultSet1.getRow(); + resultSet1.beforeFirst(); // not rs.first() because the rs.next() below will move on, missing the first element + } + if (rowcount1 != 0){ + System.out.println("row(s) affected: "+rowcount1); + while (resultSet1.next()){ + String task_id = resultSet1.getString("task_id"); + message = message + task_id + ","; + String task_status = resultSet1.getString("task_status"); + message = message + task_status + ","; + } + } + } catch (Exception e){ + System.out.println("SynchronizeAll Error: " + e.getMessage()); + } + if (message.length() > 0){ + message = message.substring(0, message.length()-1); //hilangkan koma terakhir + } + return message; + } + + public String UpdateLastUpdate(String username, Long lastUpdate) { + String message = "400"; + try { + PreparedStatement preparedStatement1 = connection.prepareStatement("UPDATE user SET last_update = ? WHERE username = ?"); + preparedStatement1.setLong(1, lastUpdate); + preparedStatement1.setString(2, username); + if (preparedStatement1.executeUpdate() != 0) { + message = "200"; + } + } catch (Exception e) { + System.out.println("UpdateLastUpdate Error: " + e.getMessage()); + } + return message; + } +} diff --git a/Server/src/server/MyRunnable.java b/Server/src/server/MyRunnable.java new file mode 100644 index 00000000..44f9a5ad --- /dev/null +++ b/Server/src/server/MyRunnable.java @@ -0,0 +1,69 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ +package server; + +import java.io.BufferedReader; +import java.io.DataOutputStream; +import java.io.InputStreamReader; +import java.net.ServerSocket; +import java.net.Socket; +import static server.Server.port; + +/** + * + * @author Compaq + */ +public class MyRunnable implements Runnable { + private Server server; + private Database db; + private boolean running; + public MyRunnable(Server s, Database db){ + this.server = s; + this.db = db; + this.running = true; + } + public void run(){ + try{ + ServerSocket confirmSocket = new ServerSocket(5000 + server.getCount()); + Socket askSocket = confirmSocket.accept(); + DataOutputStream out = new DataOutputStream(askSocket.getOutputStream()); + BufferedReader in = new BufferedReader(new InputStreamReader(askSocket.getInputStream())); + while (running){ + String request1 = in.readLine(); + String[] requests1 = request1.split(","); + if (requests1[0].equals("11")){ //ini sebenarnya udah pasti sih message yang dikirim pasti depannya 11 + String clientUsername = requests1[1]; + long clientLastupdate = Long.parseLong(requests1[2]); + System.out.println("myrunnable "+clientUsername+" :: clientLastupdate: "+clientLastupdate+", serverLastupdate: "+server.getLastUpdate()); + if (clientLastupdate < server.getLastUpdate()){ + //server sudah lebih update + + //ambil semua task_id dan task_status di db yang lebih update + String respond1 = db.FetchUpdates(clientUsername, clientLastupdate); + System.out.println("myrunnable :: respond1: "+respond1); + if (respond1.equals("")){ //walaupun clientlastupdate < serverlastupdate, bisa saja lastupdate server itu untuk task yang bukan punya user ini, jadi waktu di fetch tugas yang lebih besar dari client update tetap saja tidak ada + out.writeBytes("12\n"); //no updates yet + } else { + //ambil max_timestamp supaya client bisa update newest dia + long max_timestamp = db.GetMaxTimestamp(clientUsername); + System.out.println("myrunnable :: max_timestamp: "+max_timestamp); + out.writeBytes("13" + "," + max_timestamp + "," + respond1 + '\n'); + } + } else { + out.writeBytes("12\n"); //no updates yet + } + } else { //client kirim pesan putus (5) + running = false; + confirmSocket.close(); + server.setCount(server.getCount()-1); + System.out.println("one listener thread exited, count now: "+server.getCount()); + } + Thread.sleep(1000); + } + } catch (Exception e){ + System.out.println("MyRunnable: "+e.getMessage()); + } + } +} diff --git a/Server/src/server/Server.java b/Server/src/server/Server.java new file mode 100644 index 00000000..1d996823 --- /dev/null +++ b/Server/src/server/Server.java @@ -0,0 +1,191 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ +package server; +import java.io.*; +import java.net.*; +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.List; +/** + * + * @author Timotius + */ +public class Server implements Runnable{ + + protected static int port = 1234; + private static long lastUpdate; + Socket connection; + private int ID; + private static int count = 0; + private String request; + private String respond; + private String capitalizedMessage; + private Database db; + + Server(Socket socket, int id, Database db) { + this.connection = socket; + this.ID = id; + this.db = db; + this.request = ""; + this.respond = ""; + } + + public int getCount() { + return count; + } + + public static void setCount(int count) { + Server.count = count; + } + + public long getLastUpdate() { + return lastUpdate; + } + + public static void main(String[] args) { + + //Starts server ... + Database database = new Database(); + lastUpdate = 0; + + try{ + ServerSocket socket = new ServerSocket(port); + System.out.println("Server ready..."); + while (true) { + Socket conn = socket.accept(); + Runnable runnable = new Server(conn, ++count, database); + System.out.println("New connection with ID: "+count); + Thread thread = new Thread(runnable); + thread.start(); + } + } catch(Exception e){ + System.out.println("ServerSocket: " + e.getMessage()); + } + } + + public void run() { + + try{ + BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream())); + DataOutputStream out = new DataOutputStream(connection.getOutputStream()); + while (true){ + request = in.readLine(); + System.out.println("From Client: " + request); + String[] parts = request.split(","); + String part1 = parts[0]; + switch (part1){ + case ("1"): //login + { + String username = parts[1]; //kennyazrina + String password = parts[2]; //kennyazrina + String respond1 = db.Login(username, password); //200 atau 400 + out.writeBytes(respond1 + "," + count +'\n'); + String[] responds1 = respond1.split(","); + if (responds1[0].equals("200")){ + System.out.println("Login successful"); + } else { + System.out.println("Login failed"); + } + break; + } + case ("2"): //check + { + String task_id = parts[1]; + String respond1 = db.Check(task_id); + System.out.println("respond1: "+respond1); + String[] responds1 = respond1.split(","); + if (responds1[0].equals("200")){ + lastUpdate = Long.parseLong(responds1[1]); + System.out.println("Check successful"); + } else { + System.out.println("Check failed"); + } + out.writeBytes(respond1 + '\n'); + break; + } + case ("3"): //uncheck + { + String task_id = parts[1]; + String respond1 = db.Uncheck(task_id); + System.out.println("respond1: "+respond1); + String[] responds1 = respond1.split(","); + if (responds1[0].equals("200")){ + lastUpdate = Long.parseLong(responds1[1]); + System.out.println("Uncheck successful"); + } else { + System.out.println("Uncheck failed"); + } + out.writeBytes(respond1 + '\n'); + break; + } + case ("4"): //synchronize dari log (tugas-X yang timestamp nya dari log lebih besar dari timestamp tugas-X di database akan overwrite) + { + //Terima 4,kennyazrina,,, user.last_update> + String clientUsername = parts[1]; + Long clientLastUpdate = Long.parseLong(parts[2]); + //sisanya logs terbagi jadi parts[4] untuk task_id, parts[5] task_status, parts[6] timestamp, dst + int i = 3; + while (i < parts.length){ + String respond1 = db.Synchronize(parts[i],parts[i+1],Long.parseLong(parts[i+2])); + if (respond1.equals("200")){ + System.out.println("task_id "+parts[i]+" in log is newer and overwrites old data"); + } else { + System.out.println("task_id "+parts[i]+" in log is older than the one in the database"); + } + //String respond2 = db.UpdateLastUpdate(clientUsername, Long.parseLong(parts[i+2])); + i += 3; + } + //next step: ambil timestamp terbesar dari semua tugas user + long max_timestamp = db.GetMaxTimestamp(clientUsername); + System.out.println("max_timestamp: "+max_timestamp); + + //jadikan max_timestamp sbg user.last_update (sikronisasi selesai) + String respond2 = db.UpdateLastUpdate(clientUsername, max_timestamp); + System.out.println("respond2: "+respond2); + out.writeBytes(respond2 + "," + max_timestamp + '\n'); + + //next step: ambil timestamp terbesar global, untuk last update server + long max_timestamp_absolute = db.GetMaxTimestampAbsolute(); + lastUpdate = max_timestamp_absolute; + + //next step: ambil semua task username ini, kirim ke client + String respond3 = db.GetUserTasks(clientUsername); + System.out.println("respond3: "+respond3); + out.writeBytes(respond3 + '\n'); + + Runnable task = new MyRunnable(this, db); + Thread threadUpdate = new Thread(task); + threadUpdate.start(); +// out.writeBytes(respond); //bila 200 berhasil, bila 400 tak ada update +// String[] responds = respond.split(","); +// if (responds[0].equals("200")){ +// System.out.println("Synchronizing..."); +// String request2, respond2; +// respond2 = "400\n"; +// request2 = in.readLine(); +// clientLastUpdate = Long.parseLong(request2); +// respond2 = db.UpdateLastUpdate(clientUsername, clientLastUpdate); +// out.writeBytes(respond2); +// } else if (responds[0].equals("400")){ +// System.out.println("No update..."); +// } else { +// +// } + break; + } + default: + { + break; + } + } + Thread.sleep(1000); + } + } catch (Exception e){ + System.out.println(e.getMessage()); + } + } +} diff --git a/Timolous/build.xml b/Timolous/build.xml new file mode 100644 index 00000000..fdb0b75f --- /dev/null +++ b/Timolous/build.xml @@ -0,0 +1,74 @@ + + + + + + + + + + + Builds, tests, and runs the project Timolous. + + + diff --git a/Timolous/manifest.mf b/Timolous/manifest.mf new file mode 100644 index 00000000..328e8e5b --- /dev/null +++ b/Timolous/manifest.mf @@ -0,0 +1,3 @@ +Manifest-Version: 1.0 +X-COMMENT: Main-Class will be added automatically by build + diff --git a/Timolous/nbproject/build-impl.xml b/Timolous/nbproject/build-impl.xml new file mode 100644 index 00000000..4472b06b --- /dev/null +++ b/Timolous/nbproject/build-impl.xml @@ -0,0 +1,1411 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must set src.dir + Must set test.src.dir + Must set build.dir + Must set dist.dir + Must set build.classes.dir + Must set dist.javadoc.dir + Must set build.test.classes.dir + Must set build.test.results.dir + Must set build.classes.excludes + Must set dist.jar + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must set javac.includes + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + No tests executed. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must set JVM to use for profiling in profiler.info.jvm + Must set profiler agent JVM arguments in profiler.info.jvmargs.agent + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must select some files in the IDE or set javac.includes + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + To run this application from the command line without Ant, try: + + + + + + + java -cp "${run.classpath.with.dist.jar}" ${main.class} + + + + + + + + + + + + + + + + + + + + + + + + + To run this application from the command line without Ant, try: + + java -jar "${dist.jar.resolved}" + + + + + + + + + + + + + + + + + + + + + + + + + Must select one file in the IDE or set run.class + + + + Must select one file in the IDE or set run.class + + + + + + + + + + + + + + + + + + + + + + + Must select one file in the IDE or set debug.class + + + + + Must select one file in the IDE or set debug.class + + + + + Must set fix.includes + + + + + + + + + + This target only works when run from inside the NetBeans IDE. + + + + + + + + + Must select one file in the IDE or set profile.class + This target only works when run from inside the NetBeans IDE. + + + + + + + + + This target only works when run from inside the NetBeans IDE. + + + + + + + + + + + + + This target only works when run from inside the NetBeans IDE. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must select one file in the IDE or set run.class + + + + + + Must select some files in the IDE or set test.includes + + + + + Must select one file in the IDE or set run.class + + + + + Must select one file in the IDE or set applet.url + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must select some files in the IDE or set javac.includes + + + + + + + + + + + + + + + + + + + + Some tests failed; see details above. + + + + + + + + + Must select some files in the IDE or set test.includes + + + + Some tests failed; see details above. + + + + Must select some files in the IDE or set test.class + Must select some method in the IDE or set test.method + + + + Some tests failed; see details above. + + + + + Must select one file in the IDE or set test.class + + + + Must select one file in the IDE or set test.class + Must select some method in the IDE or set test.method + + + + + + + + + + + + + + Must select one file in the IDE or set applet.url + + + + + + + + + Must select one file in the IDE or set applet.url + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Timolous/nbproject/genfiles.properties b/Timolous/nbproject/genfiles.properties new file mode 100644 index 00000000..a6287b3b --- /dev/null +++ b/Timolous/nbproject/genfiles.properties @@ -0,0 +1,8 @@ +build.xml.data.CRC32=157ecfb9 +build.xml.script.CRC32=9511f67c +build.xml.stylesheet.CRC32=28e38971@1.56.1.46 +# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml. +# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you. +nbproject/build-impl.xml.data.CRC32=157ecfb9 +nbproject/build-impl.xml.script.CRC32=7fd65455 +nbproject/build-impl.xml.stylesheet.CRC32=c6d2a60f@1.56.1.46 diff --git a/Timolous/nbproject/private/private.properties b/Timolous/nbproject/private/private.properties new file mode 100644 index 00000000..31c42f2e --- /dev/null +++ b/Timolous/nbproject/private/private.properties @@ -0,0 +1,2 @@ +compile.on.save=true +user.properties.file=/Users/kaniaazrina/Library/Application Support/NetBeans/7.3/build.properties diff --git a/Timolous/nbproject/private/private.xml b/Timolous/nbproject/private/private.xml new file mode 100644 index 00000000..47509625 --- /dev/null +++ b/Timolous/nbproject/private/private.xml @@ -0,0 +1,4 @@ + + + + diff --git a/Timolous/nbproject/project.properties b/Timolous/nbproject/project.properties new file mode 100644 index 00000000..fa0a8343 --- /dev/null +++ b/Timolous/nbproject/project.properties @@ -0,0 +1,72 @@ +annotation.processing.enabled=true +annotation.processing.enabled.in.editor=false +annotation.processing.processor.options= +annotation.processing.processors.list= +annotation.processing.run.all.processors=true +annotation.processing.source.output=${build.generated.sources.dir}/ap-source-output +build.classes.dir=${build.dir}/classes +build.classes.excludes=**/*.java,**/*.form +# This directory is removed when the project is cleaned: +build.dir=build +build.generated.dir=${build.dir}/generated +build.generated.sources.dir=${build.dir}/generated-sources +# Only compile against the classpath explicitly listed here: +build.sysclasspath=ignore +build.test.classes.dir=${build.dir}/test/classes +build.test.results.dir=${build.dir}/test/results +# Uncomment to specify the preferred debugger connection transport: +#debug.transport=dt_socket +debug.classpath=\ + ${run.classpath} +debug.test.classpath=\ + ${run.test.classpath} +# This directory is removed when the project is cleaned: +dist.dir=dist +dist.jar=${dist.dir}/Timolous.jar +dist.javadoc.dir=${dist.dir}/javadoc +excludes= +includes=** +jar.compress=false +javac.classpath=\ + ${libs.swing-layout.classpath} +# Space-separated list of extra javac options +javac.compilerargs= +javac.deprecation=false +javac.processorpath=\ + ${javac.classpath} +javac.source=1.6 +javac.target=1.6 +javac.test.classpath=\ + ${javac.classpath}:\ + ${build.classes.dir} +javac.test.processorpath=\ + ${javac.test.classpath} +javadoc.additionalparam= +javadoc.author=false +javadoc.encoding=${source.encoding} +javadoc.noindex=false +javadoc.nonavbar=false +javadoc.notree=false +javadoc.private=false +javadoc.splitindex=true +javadoc.use=true +javadoc.version=false +javadoc.windowtitle= +main.class=timolous.Timolous +manifest.file=manifest.mf +meta.inf.dir=${src.dir}/META-INF +mkdist.disabled=false +platform.active=default_platform +run.classpath=\ + ${javac.classpath}:\ + ${build.classes.dir} +# Space-separated list of JVM arguments used when running the project. +# You may also define separate properties like run-sys-prop.name=value instead of -Dname=value. +# To set system properties for unit tests define test-sys-prop.name=value: +run.jvmargs= +run.test.classpath=\ + ${javac.test.classpath}:\ + ${build.test.classes.dir} +source.encoding=UTF-8 +src.dir=src +test.src.dir=test diff --git a/Timolous/nbproject/project.xml b/Timolous/nbproject/project.xml new file mode 100644 index 00000000..674b3d19 --- /dev/null +++ b/Timolous/nbproject/project.xml @@ -0,0 +1,15 @@ + + + org.netbeans.modules.java.j2seproject + + + Timolous + + + + + + + + + diff --git a/Timolous/src/Front.form b/Timolous/src/Front.form new file mode 100644 index 00000000..37a209ff --- /dev/null +++ b/Timolous/src/Front.form @@ -0,0 +1,97 @@ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/Timolous/src/Front.java b/Timolous/src/Front.java new file mode 100644 index 00000000..3c580647 --- /dev/null +++ b/Timolous/src/Front.java @@ -0,0 +1,116 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ + +/** + * + * @author kaniaazrina + */ +public class Front extends javax.swing.JFrame { + + /** + * Creates new form Front + */ + public Front() { + initComponents(); + } + + /** + * This method is called from within the constructor to initialize the form. + * WARNING: Do NOT modify this code. The content of this method is always + * regenerated by the Form Editor. + */ + @SuppressWarnings("unchecked") + // //GEN-BEGIN:initComponents + private void initComponents() { + + jTextField1 = new javax.swing.JTextField(); + jTextField3 = new javax.swing.JTextField(); + jPasswordField1 = new javax.swing.JPasswordField(); + jPasswordField2 = new javax.swing.JPasswordField(); + jButton1 = new javax.swing.JButton(); + jLabel1 = new javax.swing.JLabel(); + + setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE); + getContentPane().setLayout(null); + getContentPane().add(jTextField1); + jTextField1.setBounds(440, 260, 130, 28); + + jTextField3.setText("jTextField1"); + getContentPane().add(jTextField3); + jTextField3.setBounds(440, 260, 130, 28); + + jPasswordField1.setText("jPasswordField1"); + getContentPane().add(jPasswordField1); + jPasswordField1.setBounds(440, 300, 134, 28); + + jPasswordField2.setText("jPasswordField2"); + getContentPane().add(jPasswordField2); + jPasswordField2.setBounds(430, 300, 134, 28); + + jButton1.setBackground(new java.awt.Color(0, 102, 0)); + jButton1.setIcon(new javax.swing.ImageIcon(getClass().getResource("/login.png"))); // NOI18N + jButton1.setBorderPainted(false); + jButton1.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jButton1ActionPerformed(evt); + } + }); + getContentPane().add(jButton1); + jButton1.setBounds(350, 340, 190, 60); + + jLabel1.setIcon(new javax.swing.ImageIcon(getClass().getResource("/front.png"))); // NOI18N + getContentPane().add(jLabel1); + jLabel1.setBounds(0, 0, 900, 480); + + pack(); + }// //GEN-END:initComponents + + private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton1ActionPerformed + // TODO add your handling code here: + }//GEN-LAST:event_jButton1ActionPerformed + + /** + * @param args the command line arguments + */ + public static void main(String args[]) { + /* Set the Nimbus look and feel */ + // + /* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel. + * For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html + */ + try { + for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) { + if ("Nimbus".equals(info.getName())) { + javax.swing.UIManager.setLookAndFeel(info.getClassName()); + break; + } + } + } catch (ClassNotFoundException ex) { + java.util.logging.Logger.getLogger(Front.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); + } catch (InstantiationException ex) { + java.util.logging.Logger.getLogger(Front.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); + } catch (IllegalAccessException ex) { + java.util.logging.Logger.getLogger(Front.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); + } catch (javax.swing.UnsupportedLookAndFeelException ex) { + java.util.logging.Logger.getLogger(Front.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); + } + // + + /* Create and display the form */ + java.awt.EventQueue.invokeLater(new Runnable() { + public void run() { + new Front().setVisible(true); + } + }); + } + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JButton jButton1; + private javax.swing.JLabel jLabel1; + private javax.swing.JPasswordField jPasswordField1; + private javax.swing.JPasswordField jPasswordField2; + private javax.swing.JTextField jTextField1; + private javax.swing.JTextField jTextField3; + // End of variables declaration//GEN-END:variables +} diff --git a/Timolous/src/Main.form b/Timolous/src/Main.form new file mode 100644 index 00000000..9799a6c0 --- /dev/null +++ b/Timolous/src/Main.form @@ -0,0 +1,137 @@ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Timolous/src/Main.java b/Timolous/src/Main.java new file mode 100644 index 00000000..2080866d --- /dev/null +++ b/Timolous/src/Main.java @@ -0,0 +1,136 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ + +/** + * + * @author kaniaazrina + */ +public class Main extends javax.swing.JFrame { + + /** + * Creates new form Main + */ + public Main() { + initComponents(); + } + + /** + * This method is called from within the constructor to initialize the form. + * WARNING: Do NOT modify this code. The content of this method is always + * regenerated by the Form Editor. + */ + @SuppressWarnings("unchecked") + // //GEN-BEGIN:initComponents + private void initComponents() { + + jFrame1 = new javax.swing.JFrame(); + jButton1 = new javax.swing.JButton(); + jCheckBox1 = new javax.swing.JCheckBox(); + jScrollPane1 = new javax.swing.JScrollPane(); + jLabel2 = new javax.swing.JLabel(); + jLabel1 = new javax.swing.JLabel(); + jLabel4 = new javax.swing.JLabel(); + jLabel5 = new javax.swing.JLabel(); + + setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE); + setMinimumSize(new java.awt.Dimension(900, 500)); + getContentPane().setLayout(null); + + jButton1.setIcon(new javax.swing.ImageIcon(getClass().getResource("/logout.png"))); // NOI18N + jButton1.setText("jButton1"); + jButton1.setActionCommand(""); + jButton1.setBorderPainted(false); + getContentPane().add(jButton1); + jButton1.setBounds(20, 380, 210, 70); + + jCheckBox1.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jCheckBox1ActionPerformed(evt); + } + }); + getContentPane().add(jCheckBox1); + jCheckBox1.setBounds(780, 140, 106, 23); + + jScrollPane1.setBackground(new java.awt.Color(12, 74, 40)); + jScrollPane1.setForeground(new java.awt.Color(12, 74, 40)); + jScrollPane1.setAlignmentX(1.0F); + + jLabel2.setBackground(new java.awt.Color(11, 71, 38)); + jLabel2.setForeground(new java.awt.Color(11, 71, 36)); + jLabel2.setHorizontalAlignment(javax.swing.SwingConstants.CENTER); + jLabel2.setIcon(new javax.swing.ImageIcon(getClass().getResource("/task.png"))); // NOI18N + jLabel2.setVerticalAlignment(javax.swing.SwingConstants.TOP); + jScrollPane1.setViewportView(jLabel2); + + getContentPane().add(jScrollPane1); + jScrollPane1.setBounds(240, 40, 620, 400); + + jLabel1.setIcon(new javax.swing.ImageIcon(getClass().getResource("/main.png"))); // NOI18N + jLabel1.setText("jLabel1"); + getContentPane().add(jLabel1); + jLabel1.setBounds(0, 0, 900, 480); + + jLabel4.setFont(new java.awt.Font("Hannahs Messy Handwriting", 0, 13)); // NOI18N + jLabel4.setForeground(new java.awt.Color(255, 255, 255)); + jLabel4.setText("Task Name"); + getContentPane().add(jLabel4); + jLabel4.setBounds(400, 60, 320, 13); + + jLabel5.setText("jLabel5"); + getContentPane().add(jLabel5); + jLabel5.setBounds(400, 80, 45, 16); + + pack(); + }// //GEN-END:initComponents + + private void jCheckBox1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jCheckBox1ActionPerformed + // TODO add your handling code here: + }//GEN-LAST:event_jCheckBox1ActionPerformed + + /** + * @param args the command line arguments + */ + public static void main(String args[]) { + /* Set the Nimbus look and feel */ + // + /* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel. + * For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html + */ + try { + for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) { + if ("Nimbus".equals(info.getName())) { + javax.swing.UIManager.setLookAndFeel(info.getClassName()); + break; + } + } + } catch (ClassNotFoundException ex) { + java.util.logging.Logger.getLogger(Main.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); + } catch (InstantiationException ex) { + java.util.logging.Logger.getLogger(Main.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); + } catch (IllegalAccessException ex) { + java.util.logging.Logger.getLogger(Main.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); + } catch (javax.swing.UnsupportedLookAndFeelException ex) { + java.util.logging.Logger.getLogger(Main.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); + } + // + + /* Create and display the form */ + java.awt.EventQueue.invokeLater(new Runnable() { + public void run() { + new Main().setVisible(true); + } + }); + } + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JButton jButton1; + private javax.swing.JCheckBox jCheckBox1; + private javax.swing.JFrame jFrame1; + private javax.swing.JLabel jLabel1; + private javax.swing.JLabel jLabel2; + private javax.swing.JLabel jLabel4; + private javax.swing.JLabel jLabel5; + private javax.swing.JScrollPane jScrollPane1; + // End of variables declaration//GEN-END:variables +} diff --git a/Timolous/src/front.png b/Timolous/src/front.png new file mode 100644 index 00000000..9ca5bb8a Binary files /dev/null and b/Timolous/src/front.png differ diff --git a/Timolous/src/login.png b/Timolous/src/login.png new file mode 100644 index 00000000..a673aa91 Binary files /dev/null and b/Timolous/src/login.png differ diff --git a/Timolous/src/logout.png b/Timolous/src/logout.png new file mode 100644 index 00000000..5af70d95 Binary files /dev/null and b/Timolous/src/logout.png differ diff --git a/Timolous/src/main.png b/Timolous/src/main.png new file mode 100644 index 00000000..f4cf3fe7 Binary files /dev/null and b/Timolous/src/main.png differ diff --git a/Timolous/src/task.png b/Timolous/src/task.png new file mode 100644 index 00000000..6984e7ff Binary files /dev/null and b/Timolous/src/task.png differ diff --git a/Timolous/src/timolous/Timolous.java b/Timolous/src/timolous/Timolous.java new file mode 100644 index 00000000..95baca0f --- /dev/null +++ b/Timolous/src/timolous/Timolous.java @@ -0,0 +1,19 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ +package timolous; + +/** + * + * @author kaniaazrina + */ +public class Timolous { + + /** + * @param args the command line arguments + */ + public static void main(String[] args) { + // TODO code application logic here + } +} diff --git a/Timolous/src/timolous/front.png b/Timolous/src/timolous/front.png new file mode 100644 index 00000000..6eb32e28 Binary files /dev/null and b/Timolous/src/timolous/front.png differ