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