LeBook uses the following libraries:

Ui: The Ui of the system.Parser: Process User Input.Command: Executes instructions based on commandType.MemberManager: Library members.Storage: Reads data from, and writes data to, the hard disk.
Data includes book details and borrower.Library: Manages global catalogue and shelves, as well as a UndoManager
for undoing of a command.API: Parser.java
Shown below is a simplified class diagram of the Parser component:

The parser component is responsible for interpreting user input and calling the appropriate command object. It takes a string input from the user, determines the corresponding command type, and returns an instance of a subclass of Command.
How the parser component works:
Overview
API: Storage.java
Storage class in LeBook is responsible for saving the data after the user exits LeBook. To load the data when the user launches LeBook, it reads data from a file and loads it into a list. When exiting the program, it writes the Books back into the file in a specific format.Book is stored in structured text using a | delimiter.
API: Library.java
Overview
Library class in LeBook handles the job of managing all book-related operations. It contains
a BookManager called catalogueManager, a ShelvesManager to manage the books on shelves, as well as a
UndoManager to facilitate undoing of past user interactions.add, both the global catalogue of books and the shelves will be modified.
(In this case, the book is added to the global catalogue and the relevant shelf based on its Genre).Design
catalogueManager: manages the global catalogue (e.g adding / deleting).ShelvesManager: manages shelves of different genres. The same book in the global catalogue is also stored in their respective
shelves.UndoManager: undo certain user commands like delete and add when prompted.Class Diagram (Library):

The BookManager class is responsible for managing the library’s global catalogue of books. Within the Library class, it is referenced as catalogueManager.
It handles core operations such as:
Class Diagram (BookManager):

The ShelvesManager class is responsible for managing the Shelves. ShelvesManager contains sections, divided based on the genre of the book added. In each section, there are 5 Shelf objects, and each Shelf contains 100 Books.
It handles core operations such as:
Class Diagram(ShelvesManager):

API: Ui.java
Overview
Uiclass in LeBook is responsible for all user interaction in the Command Line Interface (CLI).Ui handles:
Ui class is designed as a Singleton to ensure only one instance manages all user interaction throughout application’s cycle.Design
Ui provides static instance via Ui.getUiInstance() and uses private constructor to prevent multiple instances.readCommand() -> Reads user input from terminal.printWelcomeMessage(), printHelp(), printExitMessage() -> Prints standardized success messages.printSuccess(String message) -> Prints standardized success message.printError(String message) -> Prints standardized error messages.printWithSeparator(String message) -> Prints message surrounded by separators.showBookList(List<Book> books) -> Displays formated list of books with their details.The add book feature allows librarians to add a book to the catalogue. When the librarian wishes to add a book, the book
is added to the global catalogue in BookManager, and also concurrently added to the shelf in ShelvesManager.
The feature is facilitated by the following components:
AddCommand: A command object that encapsulates the logic for adding the book to the catalogue and shelf.Library: Responsible for managing the BookManager as well as the ShelvesManager.ShelvesManager: Responsible for sorting the books into the correct genre.Shelves: Responsible for checking the appropriate shelf to add the book to.Key Methods
getSuitableIndex() in Shelf:
Execution Flow
add <Book Details>.AddCommand.execute method in AddCommand class calls Library’s addNewBookToCatalogue(<Book Details>) and addNewBookToShelf(<Book Details>) method.ShelfManager iterates through its shelf indexes, checks for open slots.Sequence Diagram
Note: The Book Details consists of the Title, Author Name, as well as the genre.
The delete book feature allows librarians to delete irrelevant books from the library using their bookID, their unique title and author or their bookIndex.
Each delete command also supports undo, restoring the last deleted book into the system.
Key Methods
deleteBook(int bookIndex) in Library
Deletes a book based on its index in the global catalog list.
delete num / 0deleteBook(String bookTitle, String author) in Library
Deletes a book based on its title and author in the global catalog list.
delete bk / The Hobbit / J.R.R. TolkiendeleteBook(String bookID) in Library
Deletes a book based on its book ID.
delete id / AC-0-1Execution Flow
Given below is an example usage scenario and how the delete mechanism behaves at each step.
Assuming the initial state of the library is that there’s one book titled Book1 by AuthorA.
Step 1. The user types in the string input delete num / 1
to delete the 1st book in the catalogue (in this case, it’s Book1).
Step 2. The Parser class parses the input and creates a
DeleteByIndexCommand.
Step 3. The execute method in this command class calls library’s deleteBook(Int bookIndex) method.
Step 4. library calls upon catalogueManager deleteBook(bookIndex) to delete the book from the
catalogue. The response containing information about the bookDeletion is stored in response.
Step 5. library calls retrieves the bookID using the bookIndex and passes it to shelvesManager
which deletes the book from the relevant shelf.
Step 6. Book deletion is complete.
The response is finally returned back to DeleteByIndexCommand which calls Ui to print out the response.
Storage is also updated.
Sequence Diagram (of this example)

The list book feature allows librarians to see the basic information of the
catalogue in their system. This includes the BookTitle, Author, BookID
and the DueDate if the book was borrowed.
Key Methods
listBooks() in BookManager
listExecution Flow
Given below is an example usage scenario and how the list mechanism behaves at each step:
Assuming the initial state of the library is that there’s one book titled Book1 by AuthorA.
Step 1. The user types in the string input list to list all books in the catalogue.
Step 2. The Parser class parses the input and creates a ListCommand.
Step 3. The execute method in this command class calls library’s listBooks() method.
Step 4. library calls upon catalogueManager’s listBooks() method, stores the response.
Step 5. The response is returned to the command class and printed out by Ui.
The list members with overdue books feature allows librarians to view a list of members who currently have overdue books.
It retrieves data from the MemberManager class, which maintains a list of all members and their borrowed books, and
checks the overdue status of each book.
The feature is facilitated by the following components:
ListOverdueUsersCommand: A command object that encapsulates the logic for listing members with overdue books.MemberManager: Responsible for managing all members and their borrowed books.Member: Represents an individual member and provides methods to retrieve their overdue books.Ui: Displays the formatted list of members with overdue books to the librarian.Key Methods
listMembersWithOverdueBooks() in MemberManager class:
getOverdueBooks() in Member class:
Execution Flow
list overdue users.Parser class parses the input and creates a ListOverdueUsersCommand.execute method in ListOverdueUsersCommand class calls MemberManager’s listMembersWithOverdueBooks() method.MemberManager iterates through its list of members, checks for overdue books, and builds a formatted string containing the results.Ui, which displays it to the user.Sequence Diagram

The search functionality is encapsulated within the BookFinder utility class and initiated by specific SearchBy…Command objects (SearchByTitleCommand, SearchByAuthorCommand, SearchByGenreCommand, SearchByIDCommand).
Delegation: Search logic is intentionally separated from BookManager into BookFinder. This promotes Separation of Concerns, making BookManager focused on catalogue management and BookFinder specialized in searching.
Commands & Behavior
find title <title_query> (e.g., find title Lord of the Rings)BookManager via LibraryBookFinder.findBooksByTitle(titleQuery)Uifind author <author_query> (e.g., find author Tolkien)BookManager via LibraryBookFinder.findBooksByAuthor(authorQuery)Uifind genre <genre_query> (e.g., find genre adventure)BookManager via LibraryBookFinder.findBooksByGenre(genreQuery)Uifind id <book_id> (e.g., find id AD-0-0)BookManager via LibraryBookFinder.findBooksByShelfId(bookId)UiExecution flow:
find title Lord of the Rings or find id AD-0-0).Parser interprets this and creates the appropriate SearchBy…Command object (e.g., SearchByTitleCommand with the search term).BookManager instance via the Library.List<Book> from BookManager.BookFinder instance, passing the bookList to its constructor.BookFinder instance (e.g., finder.findBooksByTitle(searchTerm) or finder.findBooksByShelfId(searchTerm)).BookFinder.Ui component to display the findings or a “not found” message to the user.BookFinder provides specific methods for each search criterion (findBooksByTitle, findBooksByAuthor, findBooksByGenre, findBooksByShelfId). The user interacts with these via the find command using criteria: title, author, genre, or id.
Shown below is a simplified class diagram of Searching:

Simplified Sequence Diagram SearchByTitleCommand: This diagram illustrates the typical flow when a user performs a title search. (This remains unchanged as the core search flow is the same).

Design considerations:
Separate BookFinder class. (Current Choice)
Pros: Adheres to the Single Responsibility Principle. BookManager stays focused on catalogue state, while BookFinder handles search algorithms. BookFinder can be tested independently. Easy to add new search types without modifying BookManager.
Cons: Requires passing the book list reference from BookManager to BookFinder upon creation. Introduces a small amount of indirection.
Implement search methods directly in BookManager
Pros: Reduces the number of classes. Search methods have direct access to the internal books list.
Cons: Bloats the BookManager class, mixing management and query responsibilities. Makes BookManager harder to test and potentially violates SRP.
Design considerations:
Separate BookFinder class. (Current Choice)
Pros: Adheres to the Single Responsibility Principle. BookManager stays focused on catalogue state, while BookFinder handles search algorithms. BookFinder can be tested independently. Easy to add new search types without modifying BookManager.
Cons: Requires passing the book list reference from BookManager to BookFinder upon creation. Introduces a small amount of indirection.
Implement search methods directly in BookManager
Pros: Reduces the number of classes. Search methods have direct access to the internal books list.
Cons: Bloats the BookManager class, mixing management and query responsibilities. Makes BookManager harder to test and potentially violates SRP.

The Undo feature allows users to revert the effects of previous commands that modified the library’s state (add, delete, borrow, return).
It retrieves the command history from the UndoManager class which maintains a stack of executed commands and calls undo() method of the most recent undoable command.
The feature is facilitated by the following components:
UndoCommand: Command object encapsulating logic for performing undo operation.UndoManager: Responsible for storing and managing history of executed commands.Command: Abstract class that defines undo() method of all commands.Ui: Displays SUCCESS or ERROR messages after an undo operation is made.Key Methods
undoCommands() in UndoManager:
undo() in Command:
confirmUndo() in Ui:
y, Y, n, N as inputs.execute() in Command:
boolean to indicate whether a command has been executed successfully.Execution Flow
undo.Parser class parses input and creates UndoCommand instance.Library’s getUndoManager() method.UndoManager invokes undoCommands() and checks command history.undo() method called for each undoable command to revert operation.Ui displays success message if command was undone successfully or error message if no commands to undo.Sequence Diagram

The Load Book from File Feature allows the user to keep and store the catalogue of books that are already present in the library.
It achieves this by scanning the LeBook_data.txt file.
Key Methods
handleCorruptedFile() in Storage:
Storage will call handleCorruptedFile(), which will clear out the text file through a method called clearFile().Execution Flow
loadFileContents().Shelf gets populated in the process as well.Sequence Diagram

The Save Book from File Feature is the counterpart to the Load Book from File. It allows the user to write to a text file as he/she executes commands.
Key Methods
toFileFormat in Book:
Book object to a suitable String format to be saved as.writeToFile() in Storage:
Execution Flow
Command object calls the writeToFile() method in Storage.writeToFile() method calls a method in the Book class to convert the object into an appropriate format to be saved.Sequence Diagram

Here, the newCommand() invocation represents a new command that the user has input to the system.
The Statistics feature allows librarians to get a quick overview of the library’s current status.
Statistics includes:
The feature is facilitated by the following components:
StatisticsCommand: Command object encapsulating the logic for computing and displaying statistics.BookManager: Provides access to the full list of books and contains helper methods to compute statistics.Ui: Displays formatted statistics in a user-friendly format.Key Methods
getStatistics() in BookManager class:
getUniqueTitleSize() and getUniqueTitles() in BookManager class:
Execution Flow
statistics.execute() in StatisticsCommand calls library.getBookManager().getStatistics().Sequence Diagram

LeBook is a comprehensive library management system that allows librarians to easily catalogue borrowed and returned books, streamlining inventory management and tracking book availabilities.
Library staff who wish to efficiently manage book collections.
Enables efficient cataloging, borrowing, and returning of books through a command-line interface, allowing librarians to manage inventory and track book availability quickly compared to a typical mouse/GUI driven app.
| Version | As a … | I want to … | So that I can … |
|---|---|---|---|
| v1.0 | librarian | add new books to the system | keep track of the new arrivals. |
| v1.0 | librarian | delete a book | remove outdated or lost books. |
| v1.0 | librarian | see the list of all my books | see what books I have in the library. |
| v1.0 | librarian | record when members borrow a book | keep track when a book is borrowed. |
| v1.0 | librarian | record when members return a book | update its availability. |
| v1.0 | librarian | set due dates for my books | so that I can monitor when books will be returned and keep track of books that have yet to been returned. |
| v1.0 | librarian | save the book details | keep track of book statuses when using the system again. |
| v1.0 | librarian | enter the command as one long string | enter the input without caring about different parts of the input. |
| v1.0 | librarian | see what happens whenever I perform a command | confirm that my inputs have been added correctly. |
| v2.0 | librarian | view the list of all available commands | know what commands are available in the system. |
| v2.0 | librarian | know the genre of a book | better organise the catalogue. |
| v2.0 | librarian | keep track of what shelf a book is on | easily locate the book. |
| v2.0 | librarian | view the catalogue of a specific shelf | view available/missing/borrowed books on the shelf. |
| v2.0 | librarian | view a list of overdue books | follow up with contacting the appropriate member. |
| v2.0 | librarian | search for a book through keywords | find the appropriate book. |
| v2.0 | librarian | see the overall statistics of the library | know the total number of books, overdue books and borrowed books. |
| v2.0 | librarian | undo the last command | correct my actions if it was a wrong command. |
java -jar LeBook.jar in the terminal.Adding a book while the library is empty
list command. No books in the list.add The Great Gatsby / F. Scott Fitzgerald / romance
add (without title, author and genre)
add TITLEadd / AUTHORadd TITLE / AUTHOR (missing genre)add TITLE / AUTHOR / (missing genre value)Deleting a book while multiple books are listed
list command. Multiple books in the list.delete num / 1
delete num / 0
delete bk / Harry Potter / J.K. Rowling (assuming this book does not exist in the library)
delete id / R-0-0 (assuming there’s a book with this bookID)
deletedelete bk / (missing title)delete bk / TITLE (missing author)Listing books when the library is empty and when it contains multiple books
list command. Initially, no books in the list.list (with no books)
list (after adding multiple books)
Borrowing a book when it is available
list command. At least one available book in the list.borrow 1 / Alice
[X].borrow 0 / Alice
borrowborrow 1 / (missing borrower name)Returning a borrowed book
list command. At least one borrowed book in the list.return 1
[ ].null.return 0
returnreturn x (where x is larger than the list size or the book is not borrowed)Listing books whose return due date has been surpassed by the current date
list overdue command. Initially, no books are overdue.list overdue (with no overdue books)
list overdue (after multiple books have surpassed overdue date)
Listing books that are currently borrowed
list borrowed command. Initially, no books are borrowed.list borrowed (with no borrowed books)
list borrowed (after multiple books have been borrowed)
Listing members who have overdue books, where the book title and author are also displayed
list overdue users command. Initially, no members have overdue books.list overdue users (with no members having overdue books)
list overdue users (after multiple members have overdue books)
Searching books by various criteria (title, author, genre, bookID)
find title lord
find author Tolkien
find genre adventure
find id AD-0-0
findfind title (missing term)find genre (missing term)Viewing the quantity of a specific book
quantity / Harry Potter / J.K. Rowling
quantity / (missing title and author)
quantityquantity / TITLE (missing author)Listing books on a specific shelf
shelf / romance / 1
shelf (missing genre and shelf number)
shelf / GENREshelf / SHELF_NUMBERViewing the total number of book copies, unique titles, borrowed and overdue books, as well as the list of unique book titles
statistics
Undoing the last command
undo (when the previous command was add, delete, borrow, return)
undo (other commands)
Displays a help menu listing commands for the user to refer to.
help
Exiting the application
bye
borrow, return, delete without specifying a book number) to ensure that the application responds correctly with error messages.To simulate a missing or corrupted data file:
A variable tied to a Book and is unique to every new Book added.
Format
[GENRE_CODE]-[SHELF_INDEX]-[SLOT_NUM]
Example: R-0-1
- R refers to 'Romance'
- '0' refers to Shelf 0
- '1' refers to Book 2
Expected behavior: