-
Notifications
You must be signed in to change notification settings - Fork 316
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Ryan Chew] Duke Increments #355
Open
iltep64
wants to merge
50
commits into
nus-cs2103-AY1920S1:master
Choose a base branch
from
iltep64:pr
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from 29 commits
Commits
Show all changes
50 commits
Select commit
Hold shift + click to select a range
65f72a8
Add support for Gradle workflow
j-lum 0112efe
Add sample checkstyle configuration
j-lum 7faa65a
Added Greet, Echo, Exit features
iltep64 46c55c6
Implement list add and show features.
iltep64 94b4414
Created Task class to represent tasks.
iltep64 4cec14a
Implemented marking a task as done.
iltep64 013cc37
Refactor IO interface into DukeIO instance, and Duke logic into objec…
iltep64 9303e1d
Implement deadline task class and addition logic
iltep64 5abe5d0
Refactor out and improve task-adding logic.
iltep64 11f4134
Create a uniform command interface, with parsing logic.
iltep64 3ec4d4e
Implement dialog block logic, so messages get aggregated into a singl…
iltep64 b79c5c0
Add header to list command output.
iltep64 3a0d632
Add Event task and make it available by the 'event' command.
iltep64 0139127
Add basic error handling support.
iltep64 16718fb
Added deletion functionality.
iltep64 8dd4b9b
Implement basic JSON decoder
iltep64 d7e9187
Add basic JSON writer
iltep64 501ae91
Add type registry for JSON serializiation
iltep64 9880921
Add convenience functions for JSON encoding/decoding.
iltep64 db72071
Refactor task types to enums
iltep64 6ca4441
Add JSON builder class for Tasks
iltep64 1cf63ce
Add listOf function, and produce ArrayList<> values instead of just L…
iltep64 f5ccf6e
Use JSON to load/store task list
iltep64 a0d17c1
Fix completed status not being loaded
iltep64 0b162a2
Add date parsing logic
iltep64 c842c6f
Have EventTask and DeadlineTask to use date logic.
iltep64 355f065
Merge branch 'branch-Level-7'
iltep64 93b6e1c
Merge branch 'branch-Level-8'
iltep64 dce444a
Add encoder lookup cache for Registry, and avoid printing debug messages
iltep64 45172d8
Move all classes into (sub)packages of org.duke
iltep64 9f28efa
Add task find command
iltep64 ed5ea49
Reformat code to satisfy standards
iltep64 8c16531
Add javadocs to public classes and methods.
iltep64 c907b2c
Merge branch 'branch-Level-9'
iltep64 c5eee9a
Merge branch 'codingstandard'
iltep64 af1b0d4
Merge branch 'javadocs'
iltep64 7e2227e
Merge branch 'gradle'
iltep64 e0b6066
Add JAR build plugin.
iltep64 63d9c81
Add tests for Command and DateParser, and automate via Gradle.
iltep64 3bfe760
Refactor out IO and command parsing.
iltep64 1e6e594
Implement a basic JavaFX UI.
iltep64 31fb5b4
Merge branch 'branch-Level-10'
iltep64 b04abda
Encapsulate Command fields.
iltep64 354adca
Beautify DukeFx UI, by adding colored message boxes for Duke and user.
iltep64 f653e2d
Extract command handlers into their own classes, and add a help command.
iltep64 7ea74be
Refactor storage out into own class, and improve CounterDecorator.
iltep64 00772ef
Refactored JavaFX UI to use FXML custom components.
iltep64 6d9eb22
Fix JavaFX startup classpath issues.
iltep64 1eebc7b
Add user guide/documentation.
iltep64 b508421
Set theme jekyll-theme-slate
iltep64 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,201 @@ | ||
package org.duke; | ||
|
||
import java.util.ArrayList; | ||
import java.util.HashMap; | ||
import java.util.List; | ||
import java.util.Map; | ||
import java.util.function.Consumer; | ||
import java.util.function.Function; | ||
import java.util.function.Predicate; | ||
import java.io.FileReader; | ||
import java.io.FileWriter; | ||
import java.io.FileNotFoundException; | ||
import java.io.IOException; | ||
|
||
import org.duke.task.Task; | ||
import org.duke.task.EventTask; | ||
import org.duke.task.DeadlineTask; | ||
import org.duke.task.TaskType; | ||
|
||
import org.duke.json.JsonParser; | ||
import org.duke.json.JsonWriter; | ||
import org.duke.json.ValueHandler; | ||
|
||
import org.duke.ui.DukeIO; | ||
import org.duke.ui.Command; | ||
|
||
import org.duke.util.CounterDecorator; | ||
|
||
public class Duke { | ||
|
||
private static final String[] initialGreeting = new String[]{ | ||
"Hello! I'm Duke", | ||
"What can I do for you?" | ||
}; | ||
|
||
private DukeIO io; | ||
private ArrayList<Task> taskList; | ||
|
||
private void addTask(Task t) { | ||
this.taskList.add(t); | ||
this.io.say( | ||
"Got it. I've added this task:", | ||
" " + t, | ||
String.format("Now you have %d task%s in the list.", | ||
this.taskList.size(), | ||
this.taskList.size() == 1 ? "" : "s") | ||
); | ||
} | ||
|
||
private boolean handleBye(Command input) { | ||
this.io.say("Bye. Hope to see you again soon!"); | ||
return true; | ||
} | ||
|
||
private boolean displayList(Command input) { | ||
this.io.say("Here are the tasks in your list:"); | ||
this.io.say(this.taskList.stream() | ||
.map(Object::toString) | ||
.map(new CounterDecorator(1)) | ||
.iterator()); | ||
return false; | ||
} | ||
|
||
private boolean makeDeadlineTask(Command input) { | ||
String description = input.arguments; | ||
String deadline = input.namedArguments.get("by"); | ||
if(deadline == null) { | ||
deadline = "unknown"; | ||
} | ||
|
||
DeadlineTask task = new DeadlineTask(description, deadline); | ||
|
||
this.addTask(task); | ||
return false; | ||
} | ||
|
||
private boolean makeEventTask(Command input) { | ||
String description = input.arguments; | ||
String timing = input.namedArguments.get("at"); | ||
if(timing == null) { | ||
timing = "unknown"; | ||
} | ||
|
||
EventTask task = new EventTask(description, timing); | ||
|
||
this.addTask(task); | ||
return false; | ||
} | ||
private boolean makeToDoTask(Command input) { | ||
this.addTask(new Task(input.arguments)); | ||
return false; | ||
} | ||
|
||
private boolean markAsDone(Command input) { | ||
int index; | ||
try { | ||
index = Integer.parseInt(input.arguments); | ||
} catch(NumberFormatException e) { | ||
throw new DukeException("Index provided was not an integer!", e); | ||
} | ||
|
||
if(index < 0 || index > this.taskList.size()) { | ||
throw new DukeException("There's no task with that index!"); | ||
} | ||
|
||
Task selectedTask = this.taskList.get(index-1); | ||
selectedTask.markComplete(); | ||
this.io.say("Nice! I've marked this task as done:", | ||
" " + selectedTask); | ||
return false; | ||
} | ||
|
||
private boolean deleteTask(Command input) { | ||
int index; | ||
try { | ||
index = Integer.parseInt(input.arguments); | ||
} catch(NumberFormatException e) { | ||
throw new DukeException("Index provided was not an integer!", e); | ||
} | ||
|
||
if(index < 0 || index > this.taskList.size()) { | ||
throw new DukeException("There's no task with that index!"); | ||
} | ||
|
||
Task selectedTask = this.taskList.remove(index-1); | ||
this.io.say("Nice! I've marked this task as done:", | ||
" " + selectedTask, | ||
String.format("Now you have %d task%s in the list.", | ||
this.taskList.size(), | ||
this.taskList.size() == 1 ? "" : "s")); | ||
|
||
|
||
return false; | ||
} | ||
|
||
private boolean findTasks(Command input) { | ||
this.io.say("Here are the matching tasks in your list:"); | ||
String target = input.arguments.toLowerCase(); | ||
this.io.say(this.taskList.stream() | ||
.filter(task -> | ||
task.getDescription().toLowerCase().contains(target)) | ||
.map(Object::toString) | ||
.map(new CounterDecorator(1)) | ||
.iterator()); | ||
return false; | ||
} | ||
|
||
private Duke() { | ||
this.io = new DukeIO(); | ||
//Bind command handlers | ||
this.io.bindCommand("list", this::displayList); | ||
this.io.bindCommand("done", this::markAsDone); | ||
this.io.bindCommand("bye", this::handleBye); | ||
this.io.bindCommand("deadline", this::makeDeadlineTask); | ||
this.io.bindCommand("event", this::makeEventTask); | ||
this.io.bindCommand("todo", this::makeToDoTask); | ||
this.io.bindCommand("delete", this::deleteTask); | ||
this.io.bindCommand("find", this::findTasks); | ||
this.io.setUnknownCommandHandler(cmd -> { throw new DukeException("I'm sorry, but I don't know what that means. :-("); }); | ||
} | ||
|
||
private static final String SAVE_PATH = "./duke.json"; | ||
private ArrayList<Task> loadStorage() { | ||
try(FileReader read = new FileReader(SAVE_PATH)) { | ||
return JsonParser.parse(read, ValueHandler.listOf(new TaskType.Builder())); | ||
} catch(FileNotFoundException e) { | ||
return new ArrayList<>(); | ||
} catch(IOException e) { | ||
throw new DukeException("Unable to load saved data", e); | ||
} | ||
} | ||
|
||
private void saveStorage(ArrayList<Task> tasks) { | ||
try(FileWriter write = new FileWriter(SAVE_PATH); | ||
JsonWriter jw = new JsonWriter(write)) { | ||
jw.writeValue(tasks); | ||
} catch(Exception e) { | ||
throw new DukeException(e); | ||
} | ||
} | ||
|
||
private void run() { | ||
this.loadStorage(); | ||
//Start off greeting the user. | ||
this.io.withDialogBlock(() -> { | ||
this.io.say(initialGreeting); | ||
this.taskList = this.loadStorage(); | ||
}); | ||
|
||
//Start listen loop. | ||
this.io.listen(); | ||
this.io.withDialogBlock(() -> { | ||
this.saveStorage(this.taskList); | ||
}); | ||
} | ||
|
||
public static void main(String[] args) { | ||
Duke duke = new Duke(); | ||
duke.run(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
package org.duke; | ||
|
||
public class DukeException extends RuntimeException { | ||
public DukeException() {} | ||
public DukeException(String message) { super(message); } | ||
public DukeException(Exception inner) { super(inner); } | ||
public DukeException(String message, Exception inner) { super(message, inner); } | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
package org.duke.json; | ||
|
||
import java.util.*; | ||
import java.util.function.*; | ||
|
||
public interface ArrayHandler<T> { | ||
public void handleElement(Receiver receiver); | ||
public T handleEnd(); | ||
|
||
public static <T> ValueHandler<ArrayList<T>> listOf(ValueHandler<T> valueHandler) { | ||
return new ValueHandler<ArrayList<T>>() { | ||
public ArrayHandler<ArrayList<T>> handleArray() { | ||
return new ListValue<>(valueHandler); | ||
} | ||
}; | ||
} | ||
|
||
public class ListValue<T> implements ArrayHandler<ArrayList<T>> { | ||
private final ArrayList<T> list = new ArrayList<>(); | ||
private final ValueHandler<T> valueHandler; | ||
public ListValue(ValueHandler<T> valueHandler) { | ||
this.valueHandler = valueHandler; | ||
} | ||
public void handleElement(Receiver receiver) { | ||
T elem = receiver.receive(valueHandler); | ||
list.add(elem); | ||
} | ||
public ArrayList<T> handleEnd() { | ||
return list; | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
package org.duke.json; | ||
|
||
public class JsonException extends RuntimeException { | ||
public JsonException(String message) { | ||
super(message); | ||
} | ||
public JsonException(String message, Throwable cause) { | ||
super(message, cause); | ||
} | ||
public JsonException(String format, Object... args) { | ||
super(String.format(format, args)); | ||
} | ||
public JsonException(String format, Throwable cause, Object... args) { | ||
super(String.format(format, args), cause); | ||
} | ||
} |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice use of streams here!