Skip to content

Commit

Permalink
Merge branch 'undo-command-a'
Browse files Browse the repository at this point in the history
  • Loading branch information
Nathanael Seen committed Mar 19, 2020
2 parents 201f9e8 + d53b489 commit 60b2b63
Show file tree
Hide file tree
Showing 17 changed files with 166 additions and 10 deletions.
5 changes: 4 additions & 1 deletion src/main/java/igrad/MainApp.java
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,10 @@ public void init() throws Exception {

UserPrefsStorage userPrefsStorage = new JsonUserPrefsStorage(config.getUserPrefsFilePath());
ReadOnlyUserPrefs userPrefs = initPrefs(userPrefsStorage);
CourseBookStorage courseBookStorage = new JsonCourseBookStorage(userPrefs.getCourseBookFilePath());
CourseBookStorage courseBookStorage = new JsonCourseBookStorage(
userPrefs.getCourseBookFilePath(),
userPrefs.getBackupCourseBookFilePath()
);
storage = new StorageManager(courseBookStorage, userPrefsStorage);

initLogging(config);
Expand Down
11 changes: 11 additions & 0 deletions src/main/java/igrad/logic/LogicManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import igrad.logic.commands.CommandResult;
import igrad.logic.commands.CourseAddCommand;
import igrad.logic.commands.SelectAvatarCommand;
import igrad.logic.commands.UndoCommand;
import igrad.logic.commands.exceptions.CommandException;
import igrad.logic.parser.CourseBookParser;
import igrad.logic.parser.exceptions.ParseException;
Expand Down Expand Up @@ -78,9 +79,19 @@ public CommandResult execute(String commandText) throws CommandException,
ParseException, IOException, ServiceException {
logger.info("----------------[USER COMMAND][" + commandText + "]");


CommandResult commandResult;
Command command = courseBookParser.parseCommand(commandText);

if (!(command instanceof UndoCommand)) {
try {
// First, load current state into backup
storage.saveBackupCourseBook(model.getCourseBook());
} catch (IOException ioe) {
throw new CommandException(FILE_OPS_ERROR_MESSAGE + ioe, ioe);
}
}

commandResult = command.execute(model);

try {
Expand Down
47 changes: 47 additions & 0 deletions src/main/java/igrad/logic/commands/UndoCommand.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package igrad.logic.commands;

import java.util.Optional;

import igrad.commons.exceptions.DataConversionException;
import igrad.logic.commands.exceptions.CommandException;
import igrad.model.Model;
import igrad.model.ReadOnlyCourseBook;
import igrad.storage.JsonCourseBookStorage;

/**
* Undoes the previous action taken.
*/
public class UndoCommand extends Command {

public static final String COMMAND_WORD = "undo";

public static final String MESSAGE_USAGE = COMMAND_WORD + ": Undoes latest action.\n"
+ "Example: " + COMMAND_WORD;

public static final String MESSAGE_SUCCESS = "Undid last command.";
public static final String MESSAGE_ERROR = "Unable to undo the last comamand.";

@Override
public CommandResult execute(Model model) throws CommandException {

JsonCourseBookStorage courseBookStorage = new JsonCourseBookStorage(
model.getCourseBookFilePath(),
model.getBackupCourseBookFilePath()
);

try {
Optional<ReadOnlyCourseBook> backupCourseBook = courseBookStorage.readBackupCourseBook();

if (backupCourseBook.isPresent()) {
model.setCourseBook(backupCourseBook.get());
} else {
throw new CommandException(MESSAGE_ERROR);
}

} catch (DataConversionException e) {
throw new CommandException(MESSAGE_ERROR);
}

return new CommandResult(MESSAGE_SUCCESS, false, false, false);
}
}
4 changes: 4 additions & 0 deletions src/main/java/igrad/logic/parser/CourseBookParser.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import igrad.logic.commands.ModuleDeleteCommand;
import igrad.logic.commands.ModuleEditCommand;
import igrad.logic.commands.SelectAvatarCommand;
import igrad.logic.commands.UndoCommand;
import igrad.logic.commands.requirement.RequirementAddCommand;
import igrad.logic.commands.requirement.RequirementDeleteCommand;
import igrad.logic.commands.requirement.RequirementEditCommand;
Expand Down Expand Up @@ -133,6 +134,9 @@ public Command parseCommand(String userInput) throws ParseException, IOException
case ExportCommand.COMMAND_WORD:
return new ExportCommand();

case UndoCommand.COMMAND_WORD:
return new UndoCommand();

case CourseAddCommand.COMMAND_WORD:
return new CourseAddCommandParser().parse(arguments);

Expand Down
6 changes: 6 additions & 0 deletions src/main/java/igrad/model/Model.java
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,12 @@ public interface Model {
*/
Path getCourseBookFilePath();

/**
* Returns the user prefs' backup course book file path.
*/
Path getBackupCourseBookFilePath();


/**
* Sets the user prefs' course book file path.
*/
Expand Down
5 changes: 5 additions & 0 deletions src/main/java/igrad/model/ModelManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,11 @@ public Path getCourseBookFilePath() {
return userPrefs.getCourseBookFilePath();
}

@Override
public Path getBackupCourseBookFilePath() {
return userPrefs.getBackupCourseBookFilePath();
}

@Override
public void setCourseBookFilePath(Path courseBookFilePath) {
requireNonNull(courseBookFilePath);
Expand Down
2 changes: 2 additions & 0 deletions src/main/java/igrad/model/ReadOnlyUserPrefs.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,7 @@ public interface ReadOnlyUserPrefs {

Path getCourseBookFilePath();

Path getBackupCourseBookFilePath();

Avatar getAvatar();
}
14 changes: 14 additions & 0 deletions src/main/java/igrad/model/UserPrefs.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ public class UserPrefs implements ReadOnlyUserPrefs {

private GuiSettings guiSettings = new GuiSettings();
private Path courseBookFilePath = Paths.get("data", "coursebook.json");
private Path backupCourseBookFilePath = Paths.get("data", "backup_coursebook.json");
private Avatar avatar = new Avatar();

/**
Expand All @@ -39,6 +40,7 @@ public void resetData(ReadOnlyUserPrefs newUserPrefs) {
requireNonNull(newUserPrefs);
setGuiSettings(newUserPrefs.getGuiSettings());
setCourseBookFilePath(newUserPrefs.getCourseBookFilePath());
setBackupCourseBookFilePath(newUserPrefs.getBackupCourseBookFilePath());
setAvatar(newUserPrefs.getAvatar());
}

Expand All @@ -55,11 +57,21 @@ public Path getCourseBookFilePath() {
return courseBookFilePath;
}

@Override
public Path getBackupCourseBookFilePath() {
return backupCourseBookFilePath;
}

public void setCourseBookFilePath(Path courseBookFilePath) {
requireNonNull(courseBookFilePath);
this.courseBookFilePath = courseBookFilePath;
}

public void setBackupCourseBookFilePath(Path backupCourseBookFilePath) {
requireNonNull(backupCourseBookFilePath);
this.backupCourseBookFilePath = backupCourseBookFilePath;
}

public Avatar getAvatar() {
return avatar;
}
Expand All @@ -82,6 +94,7 @@ public boolean equals(Object other) {

return guiSettings.equals(o.guiSettings)
&& courseBookFilePath.equals(o.courseBookFilePath)
&& backupCourseBookFilePath.equals(o.backupCourseBookFilePath)
&& avatar.equals(o.avatar);
}

Expand All @@ -95,6 +108,7 @@ public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("Gui Settings : " + guiSettings);
sb.append("\nLocal data file location : " + courseBookFilePath);
sb.append("\nBackup Local data file location : " + backupCourseBookFilePath);
sb.append("\nAvatar : " + avatar);
return sb.toString();
}
Expand Down
5 changes: 5 additions & 0 deletions src/main/java/igrad/model/util/SampleDataUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,10 @@ public static Path getSampleCourseBookFilePath() {
return Paths.get("data", "coursebook.json");
}

public static Path getSampleBackupCourseBookFilePath() {
return Paths.get("data", "backup_coursebook.json");
}

public static ReadOnlyCourseBook getSampleCourseBook() {
CourseBook sampleCourseBook = new CourseBook();
for (Module sampleModule : getSamplePersons()) {
Expand All @@ -71,6 +75,7 @@ public static UserPrefs getSampleUserPrefs() {

sampleUserPrefs.setGuiSettings(new GuiSettings());
sampleUserPrefs.setCourseBookFilePath(getSampleCourseBookFilePath());
sampleUserPrefs.setBackupCourseBookFilePath(getSampleBackupCourseBookFilePath());
sampleUserPrefs.setAvatar(getSampleAvatar());

return sampleUserPrefs;
Expand Down
19 changes: 19 additions & 0 deletions src/main/java/igrad/storage/CourseBookStorage.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,20 @@ public interface CourseBookStorage {
*/
Path getCourseBookFilePath();

/**
* Returns the file path of the backup data file.
*/
Path getBackupCourseBookFilePath();

/**
* Returns backup CourseBook data as a {@link ReadOnlyCourseBook}.
* Returns {@code Optional.empty()} if storage file is not found.
*
* @throws DataConversionException if the data in storage is not in the expected format.
* @throws IOException if there was any problem when reading from the storage.
*/
Optional<ReadOnlyCourseBook> readBackupCourseBook() throws DataConversionException, IOException;

/**
* Returns CourseBook data as a {@link ReadOnlyCourseBook}.
* Returns {@code Optional.empty()} if storage file is not found.
Expand Down Expand Up @@ -45,4 +59,9 @@ public interface CourseBookStorage {
*/
void saveCourseBook(ReadOnlyCourseBook courseBook, Path filePath) throws IOException;

/**
* @see #saveBackupCourseBook(ReadOnlyCourseBook)
*/
void saveBackupCourseBook(ReadOnlyCourseBook courseBook) throws IOException;

}
21 changes: 21 additions & 0 deletions src/main/java/igrad/storage/JsonCourseBookStorage.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,12 @@ public class JsonCourseBookStorage implements CourseBookStorage {
private static final Logger logger = LogsCenter.getLogger(JsonCourseBookStorage.class);

private Path filePath;
private Path backupFilePath;

public JsonCourseBookStorage(Path filePath, Path backupFilePath) {
this.filePath = filePath;
this.backupFilePath = backupFilePath;
}

public JsonCourseBookStorage(Path filePath) {
this.filePath = filePath;
Expand All @@ -31,6 +37,16 @@ public Path getCourseBookFilePath() {
return filePath;
}

@Override
public Path getBackupCourseBookFilePath() {
return backupFilePath;
}

@Override
public Optional<ReadOnlyCourseBook> readBackupCourseBook() throws DataConversionException {
return readCourseBook(backupFilePath);
}

@Override
public Optional<ReadOnlyCourseBook> readCourseBook() throws DataConversionException {
return readCourseBook(filePath);
Expand Down Expand Up @@ -79,4 +95,9 @@ public void saveCourseBook(ReadOnlyCourseBook courseBook, Path filePath) throws
JsonUtil.saveJsonFile(new JsonSerializableCourseBook(courseBook), filePath);
}

@Override
public void saveBackupCourseBook(ReadOnlyCourseBook courseBook) throws IOException {
saveCourseBook(courseBook, backupFilePath);
}

}
6 changes: 6 additions & 0 deletions src/main/java/igrad/storage/Storage.java
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,12 @@ public interface Storage extends CourseBookStorage, UserPrefsStorage {
@Override
Optional<ReadOnlyCourseBook> readCourseBook() throws DataConversionException, IOException;

@Override
Optional<ReadOnlyCourseBook> readBackupCourseBook() throws DataConversionException, IOException;

@Override
void saveCourseBook(ReadOnlyCourseBook courseBook) throws IOException;

@Override
void saveBackupCourseBook(ReadOnlyCourseBook courseBook) throws IOException;
}
16 changes: 16 additions & 0 deletions src/main/java/igrad/storage/StorageManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,11 @@ public Path getCourseBookFilePath() {
return courseBookStorage.getCourseBookFilePath();
}

@Override
public Path getBackupCourseBookFilePath() {
return courseBookStorage.getBackupCourseBookFilePath();
}

@Override
public Optional<ReadOnlyCourseBook> readCourseBook() throws DataConversionException, IOException {
return readCourseBook(courseBookStorage.getCourseBookFilePath());
Expand All @@ -62,11 +67,22 @@ public Optional<ReadOnlyCourseBook> readCourseBook(Path filePath) throws DataCon
return courseBookStorage.readCourseBook(filePath);
}

@Override
public Optional<ReadOnlyCourseBook> readBackupCourseBook() throws DataConversionException, IOException {
return readCourseBook(courseBookStorage.getBackupCourseBookFilePath());
}

@Override
public void saveBackupCourseBook(ReadOnlyCourseBook courseBook) throws IOException {
saveCourseBook(courseBook, courseBookStorage.getBackupCourseBookFilePath());
}

@Override
public void saveCourseBook(ReadOnlyCourseBook courseBook) throws IOException {
saveCourseBook(courseBook, courseBookStorage.getCourseBookFilePath());
}


@Override
public void saveCourseBook(ReadOnlyCourseBook courseBook, Path filePath) throws IOException {
logger.fine("Attempting to write to data file: " + filePath);
Expand Down
2 changes: 1 addition & 1 deletion src/main/resources/view/MainWindow.fxml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
<?import javafx.scene.layout.VBox?>
<?import javafx.stage.Stage?>

<fx:root minHeight="750.0" minWidth="800.0" onCloseRequest="#handleExit" title="iGrad" type="javafx.stage.Stage" xmlns="http://javafx.com/javafx/11.0.1" xmlns:fx="http://javafx.com/fxml/1">
<fx:root minHeight="800.0" minWidth="800.0" onCloseRequest="#handleExit" title="iGrad" type="javafx.stage.Stage" xmlns="http://javafx.com/javafx/11.0.1" xmlns:fx="http://javafx.com/fxml/1">
<icons>
<Image url="@/images/iGrad_Shibu.png" />
</icons>
Expand Down
5 changes: 5 additions & 0 deletions src/test/java/igrad/logic/commands/AddCommandTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,11 @@ public Path getCourseBookFilePath() {
throw new AssertionError("This method should not be called.");
}

@Override
public Path getBackupCourseBookFilePath() {
throw new AssertionError("This method should not be called.");
}

@Override
public void setCourseBookFilePath(Path courseBookFilePath) {
throw new AssertionError("This method should not be called.");
Expand Down
7 changes: 0 additions & 7 deletions study_plan.csv

This file was deleted.

1 change: 0 additions & 1 deletion study_plan.csv~

This file was deleted.

0 comments on commit 60b2b63

Please sign in to comment.