diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md index 0773456ae7..ac9033d548 100644 --- a/docs/DeveloperGuide.md +++ b/docs/DeveloperGuide.md @@ -99,6 +99,48 @@ separating it into BookRating respects the Single Responsibility Principle, lead ![SetRatingSequenceDiagram.png](UML_diagrams/SetRatingSequenceDiagram.png) +### Listing all Books +This feature allows users to list all books currently added. + +#### Overview +The book list feature in the book management system allows users to view all the books they have added at a quick glance. +This feature enhances user interaction by allowing for a quick overview of all the book titles. +- `ParserMain`: Interprets the initial command and delegates to the specific parser. +- `ParserList`: Processes the list-related commands. +- `BookList`: Maintains the list of books +- `BookDisplay`: Prints out all the books currently in the list. + +#### Architecture-Level Design +The system utilizes a layered architecture that separates concerns and streamlines interaction across different functionalities: + +- `UI Layer`: This layer is responsible for interacting with the user, displaying prompts, and outputs. +- `Command Parser Layer`: Includes parsers that interpret user commands and validate inputs. +- `Data Model Layer`: Manages the book data and handles logic for book operations, including storing of the books in the list. + +#### Component-Level Design +- `UI`: Manages all interactions with the user, displaying necessary prompts or success/error messages. +- `ParserList`: Parses and validates user input specifically for which list to display. It ensures the input does not include extra parameters before passing them to the data model. +- `BookList` & `BookDisplay`: `BookList` maintains a list of books, and `BookDisplay` handles the logic for printing out all these books. + +#### Implementation Details +- Users initiate the `list` command. +- Input Parsing and Validation: + - `ParserList.parseList` is called with the user input. It uses `Exceptions.validateCommandArguments` to check whether there are extra input parameters added. + - If there are the correct number of parameters give, the command proceeds. + +#### Lisitng Application: +- `BookDisplay.printAllBooks` is invoked to print all the books. It checks whether the current booklist is empty and prints out all books if it is not. + +#### Rationale for Design +- Consistency and Usability: The command structure is consistent with other list features like list-by-date and list-rated, providing a familiar interface for users. +- Robustness: Separate validation steps ensure that only correct and sensible data is processed, improving the system's reliability. +- Scalability: The modular design allows for easy updates and modifications to the listing feature or additions of new features. + +#### Alternatives Considered +- An alternative considered was to have a command that opened the text file in which the data was stored. However, this could lead to issues when the user is trying to comprehend the data as it might not be in a readable format. + +![ListCommand.png](UML_diagrams/ListCommand.png) + ### Labeling Books by Custom Labels The labeling feature allows users to tag books with custom labels for easy identification and categorization based on personalized criteria. diff --git a/src/main/java/seedu/bookbuddy/Ui.java b/src/main/java/seedu/bookbuddy/Ui.java index 959e2a0ec3..1587df7a29 100644 --- a/src/main/java/seedu/bookbuddy/Ui.java +++ b/src/main/java/seedu/bookbuddy/Ui.java @@ -8,16 +8,9 @@ //@@ liuzehui03 public class Ui { public static void printWelcome() { - String logo = - " ____ ____ \n" - + "| \\ | \\ \n" - + "| |_) / | |_) / \n" - + "| |_) \\ | |_) \\ \n" - + "|____/ |____/ \n"; printLine(); System.out.println("Hello from"); System.out.println("BookBuddy!"); - //System.out.println("Hello! We are BookBuddy!"); System.out.println("How can I help you today?"); printShortLine(); } @@ -74,7 +67,7 @@ public static void helpMessage() { System.out.println("list -> to show whole list of added books"); System.out.println("mark [BOOK_INDEX] -> to mark book as read [R]"); System.out.println("unmark [BOOK_INDEX] -> to mark book as unread [U]"); - System.out.println("list-by-date -> to print out all books sorted in descending order of date"); + System.out.println("list-by-date -> to print out all books sorted in descending order of date read"); System.out.println("list-genre - > to print out all genres"); System.out.println("(basic) set-genre [BOOK_INDEX] -> to set a genre for a book"); System.out.println("(advanced) set-genre [BOOK_INDEX] [GENRE] -> to set a genre for a book"); diff --git a/src/main/java/seedu/bookbuddy/bookdetailsmodifier/BookMark.java b/src/main/java/seedu/bookbuddy/bookdetailsmodifier/BookMark.java index 72c755468e..c849e51958 100644 --- a/src/main/java/seedu/bookbuddy/bookdetailsmodifier/BookMark.java +++ b/src/main/java/seedu/bookbuddy/bookdetailsmodifier/BookMark.java @@ -28,15 +28,18 @@ public static void markDoneByIndex(BookList bookList, int index) throws IndexOut try { assert index > 0 && index <= bookList.getBooks().size() : "Index out of valid range"; if (Read.getRead(bookList.getBooks().get(index - 1))) { - throw new BookReadAlreadyException("That book is already marked as read!"); + throw new BookReadAlreadyException("That book is already marked as read! " + + "Type 'list' to view the list of books."); } - assert !Read.getRead(bookList.getBooks().get(index - 1)) : "Book is already marked as read"; + assert !Read.getRead(bookList.getBooks().get(index - 1)) : "Book is already marked as read. "; markBookAsRead(bookList.getBooks().get(index - 1)); assert Read.getRead(bookList.getBooks().get(index - 1)) : "Book should be marked as read"; } catch (IndexOutOfBoundsException e) { - System.out.println("Invalid book index. Please enter a valid index"); + System.out.println("Invalid book index. Please enter a valid index. " + + "Type 'list' to view the list of books."); } catch (BookReadAlreadyException e) { - System.out.println("That book is already marked as read!"); + System.out.println("That book is already marked as read! " + + "Type 'list' to view the list of books."); } catch (Exception e) { LOGGER.log(Level.SEVERE, "An unexpected error occurred: {0}", e.getMessage()); throw e; // Rethrow or handle as needed @@ -55,15 +58,19 @@ public static void markUndoneByIndex(BookList bookList, int index) throws IndexO try { assert index > 0 && index <= bookList.getBooks().size() : "Index out of valid range"; if (!Read.getRead(bookList.getBooks().get(index - 1))) { - throw new BookUnreadAlreadyException("That book is already marked as unread!"); + throw new BookUnreadAlreadyException("That book is already marked as unread! " + + "Type 'list' to view the list of books."); } - assert Read.getRead(bookList.getBooks().get(index - 1)) : "Book is already marked as unread"; + assert Read.getRead(bookList.getBooks().get(index - 1)) : "Book is already marked as unread. " + + "Type 'list' to view the list of books."; markBookAsUnread(bookList.getBooks().get(index - 1)); - assert !Read.getRead(bookList.getBooks().get(index - 1)) : "Book should be marked as unread"; + assert !Read.getRead(bookList.getBooks().get(index - 1)) : "Book should be marked as unread. " + + "Type 'list' to view the list of books."; } catch (IndexOutOfBoundsException e) { - System.out.println("Invalid book index. Please enter a valid index"); + System.out.println("Invalid book index. Please enter a valid index. " + + "Type 'list' to view the list of books."); } catch (BookUnreadAlreadyException e) { - System.out.println("That book is already marked as unread!"); + System.out.println("That book is already marked as unread! Type 'list' to view the list of books."); } catch (Exception e) { // Generic catch block for any other exceptions System.out.println("An unexpected error occurred. Please contact support."); } diff --git a/src/main/java/seedu/bookbuddy/booklist/BookListModifier.java b/src/main/java/seedu/bookbuddy/booklist/BookListModifier.java index 21a555c548..b3edb4c82d 100644 --- a/src/main/java/seedu/bookbuddy/booklist/BookListModifier.java +++ b/src/main/java/seedu/bookbuddy/booklist/BookListModifier.java @@ -38,14 +38,16 @@ public static void addBookFromFile(BookList bookList, String inputArray, int lin public static void deleteBook(BookList bookList, int index) throws IndexOutOfBoundsException { try { if (bookList.getBooks().isEmpty()) { - System.out.println("Unable to remove book as the list is empty."); + System.out.println("Unable to remove book as the list is empty. " + + "Type 'list' to view the list of books."); } else { Ui.removeBookMessage(index, bookList); bookList.books.remove(index - 1); assert bookList.books.size() >= 0 : "Book list size should not be negative after deletion"; } } catch (IndexOutOfBoundsException e) { - System.out.println("Invalid book index. Please enter a valid index"); + System.out.println("Invalid book index. Please enter a valid index. " + + "Type 'list' to view the list of books."); } catch (Exception e) { LOGGER.log(Level.SEVERE, "An unexpected error occurred: {0}", e.getMessage()); throw e; // Rethrow or handle as needed diff --git a/src/main/java/seedu/bookbuddy/parser/ParserMain.java b/src/main/java/seedu/bookbuddy/parser/ParserMain.java index 7fcabc2a5e..bb6c0298d6 100644 --- a/src/main/java/seedu/bookbuddy/parser/ParserMain.java +++ b/src/main/java/seedu/bookbuddy/parser/ParserMain.java @@ -3,7 +3,6 @@ import exceptions.UnsupportedCommandException; import seedu.bookbuddy.booklist.BookList; -import seedu.bookbuddy.Ui; import seedu.bookbuddy.parser.parsercommands.ParserAdd; import seedu.bookbuddy.parser.parsercommands.ParserAuthor; import seedu.bookbuddy.parser.parsercommands.ParserDisplay; @@ -17,6 +16,7 @@ import seedu.bookbuddy.parser.parsercommands.ParserUnmark; import seedu.bookbuddy.parser.parsercommands.parsegenre.ParserGenre; import seedu.bookbuddy.parser.parsercommands.parserating.ParserRating; +import seedu.bookbuddy.parser.parsercommands.ParserHelp; import seedu.bookbuddy.parser.parservalidation.CommandList; import seedu.bookbuddy.parser.parservalidation.Exceptions; @@ -74,7 +74,7 @@ public static void parseCommand(String input, BookList books) { ParserUnmark.executeParseUnmark(books, inputArray); break; case CommandList.HELP_COMMAND: - Ui.helpMessage(); + ParserHelp.executeParseHelp(inputArray); break; case CommandList.FIND_TITLE_COMMAND: ParserFind.parseTitle(books, inputArray[1]); diff --git a/src/main/java/seedu/bookbuddy/parser/parsercommands/ParserFind.java b/src/main/java/seedu/bookbuddy/parser/parsercommands/ParserFind.java index a52b9092f7..93624d1453 100644 --- a/src/main/java/seedu/bookbuddy/parser/parsercommands/ParserFind.java +++ b/src/main/java/seedu/bookbuddy/parser/parsercommands/ParserFind.java @@ -57,7 +57,7 @@ public static void parseLabel(BookList books, String[] inputArray) { public static void parseRate(BookList books, String[] input) { assert input.length == 2 : "Command requires additional arguments"; Exceptions.validateCommandArguments(input, 2, - "The correct command is `find-rated [RATING]"); + "The correct command is `find-rate [RATING]"); BookFind.findRate(books, input[1].trim()); } diff --git a/src/main/java/seedu/bookbuddy/parser/parsercommands/ParserHelp.java b/src/main/java/seedu/bookbuddy/parser/parsercommands/ParserHelp.java new file mode 100644 index 0000000000..f225a2b121 --- /dev/null +++ b/src/main/java/seedu/bookbuddy/parser/parsercommands/ParserHelp.java @@ -0,0 +1,18 @@ +package seedu.bookbuddy.parser.parsercommands; + +import seedu.bookbuddy.Ui; +import seedu.bookbuddy.parser.parservalidation.Exceptions; + +public class ParserHelp { + + private static void parseHelp(String[] inputArray) { + Exceptions.validateCommandArguments(inputArray, 1, + "The help command does not require any further arguments, just type `help` :))))"); + Ui.helpMessage(); + } + + + public static void executeParseHelp (String[] inputArray) { + parseHelp(inputArray); + } +}