Skip to content
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

[Wang Haochen] iP #233

Open
wants to merge 85 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 28 commits
Commits
Show all changes
85 commits
Select commit Hold shift + click to select a range
6050b37
first iteration
cwhcgit Jan 21, 2021
6fd5092
Level-2: add, list
cwhcgit Jan 21, 2021
ca4f2a4
Level-3 commit
cwhcgit Jan 21, 2021
ebb2b49
Level-4
cwhcgit Jan 21, 2021
3c4e80a
A-TextUiTesting
cwhcgit Jan 21, 2021
08bc173
Level-6
cwhcgit Jan 21, 2021
1866354
add packages and classes for specific tasks
cwhcgit Jan 28, 2021
5d2bbdf
add file save function
cwhcgit Jan 28, 2021
b379cc6
add date time recognition
cwhcgit Jan 28, 2021
69be918
Merge branch 'branch-Level-7'
cwhcgit Jan 28, 2021
bea5c35
Merge branch 'master' into branch-Level-8
ssagit Jan 28, 2021
7c3f602
Merge pull request #2 from ssagit/branch-Level-8
ssagit Jan 28, 2021
71eadd9
resolve merge conflicts of level-7 & level-8
cwhcgit Jan 28, 2021
76c1d33
add UI class and consolidate all UI stuff into that class
cwhcgit Jan 29, 2021
9486102
add folder for task classes, deprecate enum
cwhcgit Jan 30, 2021
5ba35ea
add Storage which deals with all file IOs
cwhcgit Jan 30, 2021
47b74a9
add Parser class, deals with all user inputs
cwhcgit Jan 30, 2021
5c39d4d
Add junit tests for DateValidator & Task classes
cwhcgit Jan 30, 2021
9680dfc
Merge pull request #3 from ssagit/A-Junit
ssagit Jan 30, 2021
25ce9bd
Add level-9 Find
cwhcgit Jan 30, 2021
48dfc42
Merge pull request #4 from ssagit/Level-9
ssagit Jan 30, 2021
d0de061
add missing branch
cwhcgit Jan 30, 2021
bc65901
Merge pull request #5 from ssagit/branch-A-JavaDoc
ssagit Jan 30, 2021
d28682b
add missing branch
cwhcgit Jan 30, 2021
1a9093c
add missing branch
cwhcgit Jan 30, 2021
4edb089
Merge pull request #6 from ssagit/branch-A-CodingStandard
ssagit Jan 30, 2021
1a7719c
Fix incorrect branch name
cwhcgit Jan 30, 2021
1ffe0ca
Merge pull request #7 from ssagit/branch-Level-9
ssagit Jan 30, 2021
42deda2
Add gradle support, allows build and run of Duke.java
cwhcgit Feb 2, 2021
b58f80f
Merge pull request #8 from ssagit/A-Gradle
ssagit Feb 2, 2021
e080cee
Resolve code standard violations & update style using CheckStyle
cwhcgit Feb 2, 2021
fd8f275
Merge pull request #9 from ssagit/A-CheckStyle
ssagit Feb 2, 2021
6fd6bf1
Add minimal JavaFX
cwhcgit Feb 7, 2021
a52b97c
Merge pull request #10 from ssagit/Level-10
ssagit Feb 7, 2021
936f6f5
Update JavaDocs for new classes
cwhcgit Feb 8, 2021
7ebbaf0
Merge pull request #11 from ssagit/branch-A-Javadoc
ssagit Feb 8, 2021
876ffb8
Clean up parser class by adding classes
cwhcgit Feb 8, 2021
bcbbaae
Merge pull request #12 from ssagit/branch-A-CodingStandard
ssagit Feb 8, 2021
9578301
Resolve issue with finding taskList.txt after .jar file is created
cwhcgit Feb 9, 2021
eab7755
Add assertion for user input and filePath
cwhcgit Feb 11, 2021
b103639
Merge pull request #14 from ssagit/A-Assertions
ssagit Feb 11, 2021
06a43e4
Improve code quality by reducing depth of if-else, refactor to use gu…
cwhcgit Feb 11, 2021
0c74975
Merge pull request #15 from ssagit/A-CodeQuality
ssagit Feb 11, 2021
9f94d03
Add feature to detect and not add duplicated tasks
cwhcgit Feb 11, 2021
ae63913
Merge pull request #16 from ssagit/C-DetectDuplicates
ssagit Feb 11, 2021
06aa20c
Very minor update to javadocs
cwhcgit Feb 13, 2021
8c9dbbe
Merge pull request #17 from ssagit/branch-A-JavaDoc
ssagit Feb 13, 2021
2a00b34
add CI
cwhcgit Feb 13, 2021
681223c
remove CI checks for macos & ubuntu
cwhcgit Feb 13, 2021
90a57a0
Merge pull request #18 from ssagit/A-CI
ssagit Feb 13, 2021
99bfd80
remove CI checks for macos & ubuntu, test 1
cwhcgit Feb 13, 2021
4d85d0e
Merge pull request #19 from ssagit/A-CI
ssagit Feb 13, 2021
ac4fe40
Update gradle.yml
cwhcgit Feb 16, 2021
b6b9c47
test CI
cwhcgit Feb 16, 2021
57a2dcb
change gradlew permission
cwhcgit Feb 16, 2021
aa624ef
Merge pull request #20 from ssagit/A-CI
ssagit Feb 16, 2021
9fe8ade
add accessors
cwhcgit Feb 16, 2021
3b59951
Merge pull request #21 from ssagit/A-CI
ssagit Feb 16, 2021
1780df0
resolve issue with filePath (fP), remove FP assertion
cwhcgit Feb 16, 2021
b79bd72
Merge pull request #22 from ssagit/week6_v0
ssagit Feb 16, 2021
d658f1b
Update README.md
ssagit Feb 16, 2021
1e445e4
Update README.md
ssagit Feb 16, 2021
49dba24
Add file counter, add media resources
cwhcgit Feb 16, 2021
b6a3ba7
Merge pull request #23 from ssagit/week6_v0
ssagit Feb 16, 2021
e2e117a
Update README.md
ssagit Feb 16, 2021
fbbc8f2
Update code for checkstyle
cwhcgit Feb 16, 2021
c5b8fde
Merge branch 'master' of https://github.com/ssagit/ip
cwhcgit Feb 16, 2021
7313a0c
Add files via upload
ssagit Feb 16, 2021
d4f7e8c
Add Ui.png to new location to resolve 404
ssagit Feb 17, 2021
60ae821
Add files via upload
ssagit Feb 18, 2021
a064a92
Update README.md
ssagit Feb 18, 2021
d788d2d
Update javafx and final cleanup
cwhcgit Feb 18, 2021
ae967ca
Merge pull request #24 from ssagit/ip_final
ssagit Feb 18, 2021
58be175
Add files via upload
ssagit Feb 18, 2021
dd3f9d2
Update README.md
ssagit Feb 18, 2021
20d6e32
Add files via upload
ssagit Feb 18, 2021
bb0fd9d
Add files via upload
ssagit Feb 18, 2021
f0e8833
Delete Ui.png
ssagit Feb 18, 2021
9fca0a1
Add files via upload
ssagit Feb 18, 2021
57c78cb
Update README.md
ssagit Feb 18, 2021
7b00d84
Delete Ui.png
ssagit Feb 18, 2021
e6fffed
Add files via upload
ssagit Feb 18, 2021
20bae0b
Delete Ui.png
ssagit Feb 18, 2021
0d7ac25
Add files via upload
ssagit Feb 18, 2021
6e65908
Update README.md
ssagit Feb 18, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 0 additions & 10 deletions src/main/java/Duke.java

This file was deleted.

3 changes: 3 additions & 0 deletions src/main/java/META-INF/MANIFEST.MF
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Manifest-Version: 1.0
Main-Class: ssagit.Duke

Binary file not shown.
Binary file not shown.
Binary file added src/main/java/ssagit/Duke.class
Binary file not shown.
36 changes: 36 additions & 0 deletions src/main/java/ssagit/Duke.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package ssagit;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems a little odd that your package is called ssagit when the application is still called duke.


import java.util.Locale;
import java.time.format.DateTimeFormatter;

import ssagit.parser.Parser;
import ssagit.storage.Storage;
import ssagit.ui.ConsoleUI;
import ssagit.taskclass.*;
import ssagit.datevalidator.DateValidator;
import ssagit.datevalidator.DateValidatorLocalDate;

public class Duke {

public static void main(String[] args) {
/** Create validator for dates */
DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("d/MM/yyyy HHmm", Locale.ENGLISH);
DateValidator validator = new DateValidatorLocalDate(dateFormatter);
/** Handler for all UI stuff. */

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think adding an empty line between these logical blocks would help readability

ConsoleUI ui = new ConsoleUI(System.in);
ui.introduction();
/** Parser for user inputs */
Parser parser = new Parser(ui, validator);
/** Create tasks */
Task[] tasks = new Task[100];
/** Initialize file IO */
Storage storage = new Storage("./ssagit/data/taskList.txt");
int taskIterator = storage.readTaskListToArray(tasks, validator);

while (parser.getIsBye() == false) {
parser.parseInput(tasks, taskIterator);
}
storage.writeTasks(tasks);
ui.bye();
}
}
1 change: 1 addition & 0 deletions src/main/java/ssagit/changelog.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
restore branch-Level-9 (from Level-9)
4 changes: 4 additions & 0 deletions src/main/java/ssagit/data/taskList.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
deadline | not done | return book | 2/12/2019 1800
deadline | not done | return book | 2/12/2019 1800
todo | not done | 1
todo | not done | 2
5 changes: 5 additions & 0 deletions src/main/java/ssagit/data/taskListBackup.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
todo | not done | a
todo | not done | b
todo | not done | c
deadline | not done | return book | 2/12/2019 1800
deadline | not done | return book | 2/12/2019 1800
Binary file not shown.
8 changes: 8 additions & 0 deletions src/main/java/ssagit/datevalidator/DateValidator.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package ssagit.datevalidator;

/**
* Interface to validate String date input
*/
public interface DateValidator {
boolean isValid(String dateStr);
}
Binary file not shown.
53 changes: 53 additions & 0 deletions src/main/java/ssagit/datevalidator/DateValidatorLocalDate.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package ssagit.datevalidator;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException;

public class DateValidatorLocalDate implements DateValidator {
private DateTimeFormatter dateFormatter;

/**
* DateValidatorLocalDate Constructor.
* @param df {@code dateFormatter} object
*/
public DateValidatorLocalDate(DateTimeFormatter df) {
dateFormatter = df;
}

@Override
/**
* Checks if date given is valid, in the following order:
* date - time - locale;
* If all 3 fails, return with invalid, otherwise return results.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe follow the javadoc style of comments? Use '@param' and '@return', etc.

*/
public boolean isValid(String dateStr) {
LocalDateTime ldt = null;

try {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is really hard to read, why do you need to catch the same kind of exception in so many different places? Maybe there's a way to have only one try-catch block?

ldt = LocalDateTime.parse(dateStr, this.dateFormatter);
String result = ldt.format(dateFormatter);
return result.equals(dateStr);
} catch (DateTimeParseException e) {
try {
LocalDate ld = LocalDate.parse(dateStr, dateFormatter);
String result = ld.format(dateFormatter);
return result.equals(dateStr);
} catch (DateTimeParseException exp) {
try {
LocalTime lt = LocalTime.parse(dateStr, dateFormatter);
String result = lt.format(dateFormatter);
return result.equals(dateStr);
} catch (DateTimeParseException e2) {
// Debugging purposes
e2.printStackTrace();
}
}
}

return false;
}
}

Binary file not shown.
Binary file not shown.
Binary file added src/main/java/ssagit/parser/Parser.class
Binary file not shown.
132 changes: 132 additions & 0 deletions src/main/java/ssagit/parser/Parser.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
package ssagit.parser;

import ssagit.datevalidator.DateValidator;
import ssagit.taskclass.DeadlineTask;
import ssagit.taskclass.EventTask;
import ssagit.taskclass.Task;
import ssagit.ui.ConsoleUI;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

public class Parser {
ConsoleUI ui;
boolean isBye;
DateValidator validator;

public Parser(ConsoleUI ui, DateValidator validator) {
this.ui = ui;
this.isBye = false;
this.validator = validator;
}

/**
* Exception class for missing todoTask descriptor.
*/
static class MissingTodoDescriptorException extends Exception {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I feel these exceptions should be under a different class, like a DukeException suggested in the project guide

public MissingTodoDescriptorException(String errorMessage) {
super(errorMessage);
}
}

/**
* Exception class for unknown input parameters.
*/
static class UnknownInputParamException extends Exception {
public UnknownInputParamException(String errorMessage) {
super(errorMessage);
}
}

public boolean getIsBye() {
return this.isBye;
}

/**
* Parses lines of user input and outputs corresponding command.
* @param tasks List of tasks from file.
* @param taskIterator Integer to count number of tasks at a time.
*/
public void parseInput(Task[] tasks, int taskIterator) {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Whew this is long, maybe try moving some logic to other methods.

String input = ui.nextLine();
String inputArr[] = input.split(" ", 2);

try {
switch (inputArr[0]) {
case "bye":
this.isBye = true;
break;
case "list":
ui.list(tasks);
break;
case "done":
int taskNum = Integer.parseInt(inputArr[1]) - 1;
tasks[taskNum].markDone();
ui.markDone(tasks[taskNum].toFormattedString());
break;
case "todo":
case "event":
case "deadline":

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This doesn't seem like good practice to me, should handle the todo and event in their respective cases I feel

// add to list
String[] inputArrTasks = input.split("/", 2);
String[] firstHalf = inputArrTasks[0].split(" ", 2);
if (inputArrTasks.length != 1) {
// create Deadline/Event
String[] secondHalf = inputArrTasks[1].split(" ", 2);
if (validator.isValid(secondHalf[1])) {
Date date = new SimpleDateFormat("d/MM/yyyy HHmm").parse(secondHalf[1]);
if (inputArr[0].equals("event")) {
tasks[taskIterator] = new EventTask(firstHalf[1], false, secondHalf[1].trim(), date);
} else if (inputArr[0].equals("deadline")) {
tasks[taskIterator] = new DeadlineTask(firstHalf[1], false, secondHalf[1].trim(), date);
}
} else {
System.out.println("Invalid date format for timed Task");
}
} else {
// create todoTask
if (firstHalf.length == 1) {
throw new MissingTodoDescriptorException("------------------------------------\n" +
":( OOPS!!! The description of a todo cannot be empty\n" +
"------------------------------------");
} else {
tasks[taskIterator] = new Task(firstHalf[1], false);
}
}
break;
case "delete":
int removeIndex = Integer.parseInt(inputArr[1]);
taskIterator--; // reduce task count in list
ui.deleteTaskMessage(tasks[removeIndex - 1].toFormattedString(), taskIterator);
// actually delete the task and move all other tasks forward
for (int i = removeIndex - 1; i < tasks.length - 1; i++) {
tasks[i] = tasks[i + 1];
}
break;
case "find":
String toFind = inputArr[1];
String output = "Here are the matching tasks in your list:\n";
for (Task t : tasks) {
if (t != null) {
if (t.getTaskName().contains(toFind)) {
output = output + t.toFormattedString() + "\n";
}
}
}
ui.formatBox(output);
break;
default:
throw new UnknownInputParamException("------------------------------------\n" +
":( OOPS!!! I'm sorry, but I don't know what that means :-(\n" +
"------------------------------------");
}
} catch (MissingTodoDescriptorException e) {
System.out.println(e.getMessage());
} catch (UnknownInputParamException e) {
System.out.println(e.getMessage());
} catch (ParseException e) {
System.out.println(e.getMessage());
}
}
}
Binary file added src/main/java/ssagit/storage/Storage.class
Binary file not shown.
111 changes: 111 additions & 0 deletions src/main/java/ssagit/storage/Storage.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
package ssagit.storage;

import ssagit.datevalidator.DateValidator;
import ssagit.taskclass.DeadlineTask;
import ssagit.taskclass.EventTask;
import ssagit.taskclass.Task;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;

public class Storage {
Path relativePath;
Path absolutePath;
File taskText;

/**
* Constructor, creates a file of the searched file if it doesn't exist.
* Afterwards, create a {@code FileWriter} which is used to write to the file.
* @param relativePath relative path of file to be searched for.
*/
public Storage (String relativePath) {
this.relativePath = Paths.get(relativePath);
absolutePath = this.relativePath.toAbsolutePath();
taskText = new File(absolutePath.toString());

try {
if (!taskText.exists()) {
System.out.println("new file created");
taskText.createNewFile(); // creates the file if it doesn't exist
}
} catch (IOException e) {
System.out.println("IOException has occurred");
e.printStackTrace();
}
}

/**
* Reads a file into the program and parses each line into a Task and puts it into taskArr.
* @param taskArr array of Task objects.
* @return number of tasks currently available in list (1 index).
*/
public int readTaskListToArray(Task[] taskArr, DateValidator validator) {
int taskIterator = 0;
try {
List<String> list = Files.readAllLines(Paths.get(relativePath.toString()), Charset.defaultCharset());
String[] taskListStr = list.toArray(new String[list.size()]);
for (String str : taskListStr) {
String[] strArr = str.split(" \\| ");
String taskType = strArr[0];
String isDoneStr = strArr[1];
String taskName = strArr[2];

if (taskType.equals("todo")) {
taskArr[taskIterator] = new Task(taskName, isDoneStr.equals("done"));
} else if (taskType.equals("event")) {
if (validator.isValid(strArr[3].trim())) {
Date eventDate = new SimpleDateFormat("d/MM/yyyy HHmm").parse(strArr[3].trim());
taskArr[taskIterator] = new EventTask(taskName, isDoneStr.equals("done"), strArr[3].trim(), eventDate);
} else {
System.out.println("Invalid date format for timed Task");
}
} else if (taskType.equals("deadline")) {
if (validator.isValid(strArr[3].trim())) {
Date deadlineDate = new SimpleDateFormat("d/MM/yyyy HHmm").parse(strArr[3].trim());
taskArr[taskIterator] = new DeadlineTask(taskName, isDoneStr.equals("done"), strArr[3].trim(), deadlineDate);
} else {
System.out.println("Invalid date format for timed Task");
}
}
taskIterator++;
}
return taskIterator;
} catch (IOException e) {
System.out.println("IOException has occurred");
e.printStackTrace();
} catch (ParseException e) {
System.out.println("ParseException has occurred");
e.printStackTrace();
}
return taskIterator;
}

/**
* Writes all tasks from an array of {@code Task} objects to file output.
* @param taskArr Array of {@code Task} objects.
*/
public void writeTasks(Task[] taskArr) {
try {
FileWriter fw = new FileWriter(absolutePath.toString());
for (Task t : taskArr) {
if (t != null) {
fw.write(t.toOutputFileString() + "\n");
fw.flush();
}
}
fw.close();
} catch (IOException e) {
System.out.println("IOException has occurred");
e.printStackTrace();
}
}
}
Binary file added src/main/java/ssagit/taskclass/DeadlineTask.class
Binary file not shown.
Loading