Skip to content

Commit 21b3bd9

Browse files
Fixes some bugs
- Throws error when no parameter commands are called with command - Fixes program not exiting when a fatal error occurs when running - Allows save data to be created through nested folders - Fixed notification of when parsing corrupted lines
1 parent 72ab977 commit 21b3bd9

File tree

10 files changed

+131
-43
lines changed

10 files changed

+131
-43
lines changed

src/main/java/duke/command/ByeCommand.java

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,23 @@
22

33
import java.io.IOException;
44

5+
import duke.exceptions.UnknownCommandException;
56
import duke.inputoutput.DukeCliSettings;
67
import duke.inputoutput.DukeIo;
8+
import duke.util.ParsedData;
79
import duke.util.Storage;
810
import duke.util.TaskList;
911

1012
/**
1113
* Command class that exit the program. When bye is entered
1214
*/
13-
public class ByeCommand implements Command {
15+
public class ByeCommand extends NoParamCommand {
1416
private static final String OUTRO = "Pff.. Not like I want to see you again";
1517

18+
public ByeCommand(ParsedData data) {
19+
super(data);
20+
}
21+
1622
/**
1723
* Returns true when asked if program should exit.
1824
*
@@ -27,9 +33,11 @@ public boolean isExit() {
2733
* {@inheritDoc} Prints goodbye message and exits program.
2834
*
2935
* @throws IOException raised if an error occured when saving
36+
* @throws UnknownCommandException when extra parameters is included
3037
*/
3138
@Override
32-
public void execute(TaskList tasks, DukeIo io, Storage storage) throws IOException {
39+
public void execute(TaskList tasks, DukeIo io, Storage storage) throws IOException, UnknownCommandException {
40+
checkSingleArgumentGuard();
3341
io.printTask(OUTRO, DukeCliSettings.WRAP_INDENT);
3442
storage.saveTasks(tasks);
3543
}

src/main/java/duke/command/ListCommand.java

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,19 @@
11
package duke.command;
22

3+
import duke.exceptions.UnknownCommandException;
34
import duke.inputoutput.DukeIo;
5+
import duke.util.ParsedData;
46
import duke.util.Storage;
57
import duke.util.TaskList;
68

79
/**
810
* Command to list out all the current tasks.
911
*/
10-
public class ListCommand implements Command {
12+
public class ListCommand extends NoParamCommand {
13+
14+
public ListCommand(ParsedData data) {
15+
super(data);
16+
}
1117

1218
/**
1319
* {@inheritDoc} List command does not exit
@@ -19,9 +25,12 @@ public boolean isExit() {
1925

2026
/**
2127
* Prints out all the current tasks added.
28+
*
29+
* @throws UnknownCommandException when extra parameters is included
2230
*/
2331
@Override
24-
public void execute(TaskList tasks, DukeIo io, Storage storage) {
32+
public void execute(TaskList tasks, DukeIo io, Storage storage) throws UnknownCommandException {
33+
checkSingleArgumentGuard();
2534
io.printNumberedList(tasks.getTasks());
2635
}
2736

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
package duke.command;
2+
3+
import duke.exceptions.UnknownCommandException;
4+
import duke.util.ParsedData;
5+
6+
/**
7+
* Abstract class to handle commands that requires no argument
8+
*/
9+
abstract class NoParamCommand implements Command {
10+
11+
private boolean invalid;
12+
13+
NoParamCommand(ParsedData data) {
14+
if (data.description.isEmpty()) {
15+
invalid = false;
16+
} else {
17+
invalid = true;
18+
}
19+
}
20+
21+
/**
22+
* Guards to ensure commands contains no extra parameters
23+
*/
24+
protected void checkSingleArgumentGuard() throws UnknownCommandException {
25+
if (invalid) {
26+
throw new UnknownCommandException();
27+
}
28+
}
29+
}

src/main/java/duke/command/ResetAliasCommand.java

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,23 @@
22

33
import java.io.IOException;
44

5+
import duke.exceptions.UnknownCommandException;
56
import duke.inputoutput.DukeIo;
7+
import duke.util.ParsedData;
68
import duke.util.Storage;
79
import duke.util.TaskList;
810

911
/**
1012
* Command class that resets set aliases
1113
*/
12-
public class ResetAliasCommand implements Command {
14+
public class ResetAliasCommand extends NoParamCommand {
15+
1316
private static final String OUTRO = "Back to beginning!";
1417

18+
public ResetAliasCommand(ParsedData data) {
19+
super(data);
20+
}
21+
1522
/**
1623
* Returns true when asked if program should exit.
1724
*
@@ -26,9 +33,11 @@ public boolean isExit() {
2633
* {@inheritDoc} Resets all added aliases.
2734
*
2835
* @throws IOException raised if an error occured when saving
36+
* @throws UnknownCommandException when extra parameters is included
2937
*/
3038
@Override
31-
public void execute(TaskList tasks, DukeIo io, Storage storage) throws IOException {
39+
public void execute(TaskList tasks, DukeIo io, Storage storage) throws IOException, UnknownCommandException {
40+
checkSingleArgumentGuard();
3241
io.printTask(OUTRO);
3342
CommandSelector.reset();
3443
}

src/main/java/duke/command/SwapFaceCommand.java

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,11 @@
66
import duke.exceptions.GuiOnlyException;
77
import duke.exceptions.ImageDownloadFailedException;
88
import duke.exceptions.OperatonIsStillRunningException;
9+
import duke.exceptions.UnknownCommandException;
910
import duke.gui.GuiDataController;
1011
import duke.inputoutput.DukeGuiIo;
1112
import duke.inputoutput.DukeIo;
13+
import duke.util.ParsedData;
1214
import duke.util.Storage;
1315
import duke.util.TaskList;
1416
import javafx.concurrent.Task;
@@ -17,14 +19,18 @@
1719
/**
1820
* Command to list out all the current tasks.
1921
*/
20-
public class SwapFaceCommand implements Command {
22+
public class SwapFaceCommand extends NoParamCommand {
2123
private static final String RESPONSE = "I'm gonna replace us! We are not real after all! Goodbye!";
2224
private static final String SUCCESS = "Nice to meet you, I am duke.";
2325
private static final String ANIME_FAKE_IMAGE = "https://www.thiswaifudoesnotexist.net/example-%d.jpg";
2426
private static final String HUMAN_FAKE_IMAGE = "https://thispersondoesnotexist.com/image";
2527

2628
private static boolean isRunning = false;
2729

30+
public SwapFaceCommand(ParsedData data) {
31+
super(data);
32+
}
33+
2834
/**
2935
* {@inheritDoc} List command does not exit
3036
*/
@@ -35,10 +41,16 @@ public boolean isExit() {
3541

3642
/**
3743
* Prints out all the current tasks added.
44+
*
45+
* @throws GuiOnlyException when called via CLI mode
46+
* @throws OperatonIsStillRunningException when another swap face command is running
47+
* @throws UnknownCommandException when extra parameters is included
3848
*/
3949
@Override
4050
public void execute(TaskList tasks, DukeIo io, Storage storage)
41-
throws GuiOnlyException, OperatonIsStillRunningException {
51+
throws GuiOnlyException, OperatonIsStillRunningException, UnknownCommandException {
52+
53+
checkSingleArgumentGuard();
4254
if (!(io instanceof DukeGuiIo)) {
4355
throw new GuiOnlyException();
4456
}

src/main/java/duke/inputoutput/DukeAbstractIo.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,11 @@ public void printError(Exception e) {
104104
printTask(String.format("🙄 OOPS!!! %s", e.getMessage()));
105105
}
106106

107+
@Override
108+
public void printError(String msg) {
109+
printError(new Exception(msg));
110+
}
111+
107112
protected boolean isBitFlag(int bitsValue, DukeCliSettings flagEnum) {
108113
return (bitsValue & flagEnum.value) == flagEnum.value;
109114
}

src/main/java/duke/inputoutput/DukeIo.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,13 @@ public interface DukeIo {
4444
*/
4545
void printError(Exception e);
4646

47+
/**
48+
* Prints the message in the format of an exception
49+
*
50+
* @param msg message to print
51+
*/
52+
void printError(String msg);
53+
4754
/**
4855
* Prints Text with selected features
4956
*

src/main/java/duke/main/Duke.java

Lines changed: 8 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,8 @@
1616
*/
1717
public class Duke {
1818
private static final String LOGO =
19-
"Welcome to\n" + " ____ _ \n" + "| _ \\ _ _| | _____ \n" + "| | | | | | | |/ / _ \\\n"
20-
+ "| |_| | |_| | < __/\n" + "|____/ \\__,_|_|\\_\\___|\n" + " Chatbot!\n";
19+
"Welcome to\n" + " ____ _ \n" + "| _ \\ _ _| | _____ \n" + "| | | | | | | |/ / _ \\\n"
20+
+ "| |_| | |_| | < __/\n" + "|____/ \\__,_|_|\\_\\___|\n" + " Chatbot!\n";
2121

2222
private static final String INTRO = "Hey hey hey! I'm Duke\n" + "What can I do for you?";
2323

@@ -48,9 +48,11 @@ public boolean handleInput(String txt) {
4848
c.execute(tasks, userInputOutput, dukeData);
4949
} catch (DukeException e) {
5050
userInputOutput.printError(e);
51+
return true;
5152
} catch (IOException e) {
5253
userInputOutput.printError(e);
53-
return true;
54+
userInputOutput.printError(FATAL_EXIT);
55+
return false;
5456
}
5557

5658
return !c.isExit();
@@ -84,18 +86,7 @@ public static Duke createApplication() {
8486
* @return returns an instance of Duke
8587
*/
8688
public static Duke createApplication(DukeIo userIo) {
87-
Storage dukeData;
88-
TaskList tasks;
89-
try {
90-
dukeData = Storage.createStorage();
91-
tasks = new TaskList(dukeData.readFile());
92-
} catch (IOException e) {
93-
userIo.printError(e);
94-
userIo.printTask(FATAL_EXIT);
95-
return null;
96-
}
97-
98-
return new Duke(tasks, dukeData, userIo);
89+
return createApplication(userIo, "");
9990
}
10091

10192
/**
@@ -110,10 +101,10 @@ public static Duke createApplication(DukeIo userIo, String filePath) {
110101
TaskList tasks;
111102
try {
112103
dukeData = Storage.createStorage(filePath);
113-
tasks = new TaskList(dukeData.readFile());
104+
tasks = new TaskList(dukeData.readFile(userIo));
114105
} catch (IOException e) {
115106
userIo.printError(e);
116-
userIo.printTask(FATAL_EXIT);
107+
userIo.printError(FATAL_EXIT);
117108
return null;
118109
}
119110

src/main/java/duke/util/DataParser.java

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -71,9 +71,13 @@ public static Command dataToCommand(ParsedData data) {
7171

7272
switch (CommandSelector.getCs().getCommand(data.command)) {
7373
case BYE:
74-
return new ByeCommand();
74+
return new ByeCommand(data);
7575
case LIST:
76-
return new ListCommand();
76+
return new ListCommand(data);
77+
case SWAP:
78+
return new SwapFaceCommand(data);
79+
case RESETALIAS:
80+
return new ResetAliasCommand(data);
7781
case MARK:
7882
return new MarkCommand(data);
7983
case UNMARK:
@@ -94,10 +98,6 @@ public static Command dataToCommand(ParsedData data) {
9498
return new AliasCommand(data);
9599
case DELETECOMMAND:
96100
return new DeleteAliasCommand(data);
97-
case SWAP:
98-
return new SwapFaceCommand();
99-
case RESETALIAS:
100-
return new ResetAliasCommand();
101101
case INVALID:
102102
default:
103103
return new InvalidCommand();

src/main/java/duke/util/Storage.java

Lines changed: 30 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
import java.util.Scanner;
1010

1111
import duke.exceptions.CorruptedLineException;
12+
import duke.inputoutput.DukeIo;
1213
import duke.task.Task;
1314

1415
/**
@@ -17,6 +18,7 @@
1718
public class Storage {
1819

1920
private static final String DEFAULT_SAVE_PATH = "data/SavedData.duke";
21+
private static final String PARSE_FAIL = "I was unable to parse line %s of the save file!";
2022
private File file;
2123

2224
private Storage(File file) {
@@ -31,12 +33,11 @@ private Storage(File file) {
3133
* @throws IOException Throws if pathing cannot exist.
3234
*/
3335
public static Storage createStorage(String path) throws IOException {
34-
File newFile = new File(path);
35-
File parentFolder = newFile.getParentFile();
36-
if (parentFolder != null) {
37-
parentFolder.mkdir();
36+
if (path.trim().isEmpty()) {
37+
path = DEFAULT_SAVE_PATH;
3838
}
39-
newFile.createNewFile();
39+
File newFile = new File(path);
40+
ensureExistance(newFile);
4041
return new Storage(newFile);
4142
}
4243

@@ -50,13 +51,24 @@ public static Storage createStorage() throws IOException {
5051
return createStorage(DEFAULT_SAVE_PATH);
5152
}
5253

54+
private static void ensureExistance(File file) throws IOException {
55+
if (file.exists()) {
56+
return;
57+
}
58+
File parentFolder = file.getParentFile();
59+
if (parentFolder != null) {
60+
parentFolder.mkdirs();
61+
}
62+
file.createNewFile();
63+
}
64+
5365
/**
5466
* Read the save file and convert it to a list of Task.
5567
*
5668
* @return List of Tasks
5769
* @throws FileNotFoundException Throws when save file does not exist
5870
*/
59-
public List<Task> readFile() throws FileNotFoundException {
71+
public List<Task> readFile(DukeIo io) throws FileNotFoundException {
6072
List<Task> ret = new ArrayList<>();
6173
List<Integer> corruptedLines = new ArrayList<>();
6274

@@ -75,6 +87,16 @@ public List<Task> readFile() throws FileNotFoundException {
7587
}
7688
}
7789
sc.close();
90+
if (corruptedLines.size() == 0) {
91+
return ret;
92+
}
93+
StringBuilder joinedList = corruptedLines.stream().collect(StringBuilder::new, (sb, num) -> {
94+
sb.append(num);
95+
sb.append(", ");
96+
}, StringBuilder::append);
97+
// removes the ", " of the last string
98+
joinedList.setLength(joinedList.length() - 2);
99+
io.printError(String.format(PARSE_FAIL, joinedList.toString()));
78100
return ret;
79101
}
80102

@@ -85,9 +107,7 @@ public List<Task> readFile() throws FileNotFoundException {
85107
* @throws IOException Throws when save file doesn't exist
86108
*/
87109
public void saveData(ParsedData[] dataList) throws IOException {
88-
if (!file.exists()) {
89-
file.createNewFile();
90-
}
110+
ensureExistance(file);
91111

92112
assert file.exists();
93113
StringBuilder sb = new StringBuilder();
@@ -117,9 +137,7 @@ public void saveTasks(TaskList tl) throws IOException {
117137
* @throws IOException Throws when save file is missing
118138
*/
119139
public void saveTask(Task task) throws IOException {
120-
if (!file.exists()) {
121-
file.createNewFile();
122-
}
140+
ensureExistance(file);
123141
assert file.exists();
124142

125143
FileWriter fw = new FileWriter(file, true);

0 commit comments

Comments
 (0)