diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..f4b8cf3
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,10 @@
+/.library.txt
+/out/production/Library-Management-System/Admin.class
+/out/production/Library-Management-System/Book.class
+/out/production/Library-Management-System/Library.class
+/out/production/Library-Management-System/Manual.class
+/out/production/Library-Management-System/MyApp.class
+/out/production/Library-Management-System/NormalUser.class
+/out/production/Library-Management-System/Rent.class
+/out/production/Library-Management-System/User.class
+/out/production/Library-Management-System/Updatable.class
diff --git a/.idea/.gitignore b/.idea/.gitignore
new file mode 100644
index 0000000..26d3352
--- /dev/null
+++ b/.idea/.gitignore
@@ -0,0 +1,3 @@
+# Default ignored files
+/shelf/
+/workspace.xml
diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml
new file mode 100644
index 0000000..0a87188
--- /dev/null
+++ b/.idea/inspectionProfiles/Project_Default.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/misc.xml b/.idea/misc.xml
new file mode 100644
index 0000000..6f29fee
--- /dev/null
+++ b/.idea/misc.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/modules.xml b/.idea/modules.xml
new file mode 100644
index 0000000..d5f086e
--- /dev/null
+++ b/.idea/modules.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
new file mode 100644
index 0000000..35eb1dd
--- /dev/null
+++ b/.idea/vcs.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Answers/src/Admin.java b/Answers/src/Admin.java
new file mode 100644
index 0000000..45d1d35
--- /dev/null
+++ b/Answers/src/Admin.java
@@ -0,0 +1,21 @@
+
+public class Admin extends User {
+ private final String password;
+
+ public Admin(String name, String phoneNumber, String password) throws IllegalArgumentException {
+ super(name, phoneNumber);
+
+ // validate password
+ if (!password.matches(".*\\d.*") && !password.matches(".*[a-z].*") &&
+ !password.matches(".*[A-Z].*") && !password.matches("[^(\"\\s)]*"))
+ throw new IllegalArgumentException("Password should contain at least one digit," +
+ "one capital and small letter\nand should not have \" character and white spaces.");
+
+ this.password = password;
+ }
+
+ // to verify the password
+ public boolean verify(String password) {
+ return this.password.equals(password);
+ }
+}
diff --git a/Answers/src/Book.java b/Answers/src/Book.java
new file mode 100644
index 0000000..0dbb580
--- /dev/null
+++ b/Answers/src/Book.java
@@ -0,0 +1,105 @@
+import java.sql.*;
+
+public class Book implements Updatable {
+ private String title;
+ private String author;
+ private String description;
+ private int uniqueID; // unique id automatically generate in database
+ private boolean availabilityStatus = true;
+
+ // two arguments constructor
+ public Book(String title, String author) {
+ this.title = title;
+ this.author = author;
+ }
+
+ // three arguments constructor
+ public Book(String title, String author, String description) {
+ this.title = title;
+ this.author = author;
+ this.description = description;
+ }
+
+ public Book(int bookID) throws Exception {
+ final String SQL_COMMAND = "SELECT * FROM books WHERE BookID = ?;";
+
+ try (Connection connection = DriverManager.getConnection(MyApp.DB_URL, MyApp.DB_USERNAME,
+ MyApp.DB_PASSWORD);
+ PreparedStatement selectBook = connection.prepareStatement(SQL_COMMAND)){
+
+ selectBook.setInt(1, bookID);
+
+ ResultSet resultSet = selectBook.executeQuery();
+
+ if (resultSet.next()) {
+ this.uniqueID = bookID;
+ this.title = resultSet.getString("Title");
+ this.author = resultSet.getString("Author");
+ this.description = resultSet.getString("Description");
+ this.availabilityStatus = resultSet.getBoolean("AvailabilityStatus");
+ } else
+ throw new Exception("Book with ID = " + bookID + " not found.");
+ } catch (SQLException e) {
+ e.printStackTrace();
+ System.err.print("Connection to database failed! Terminating...");
+ System.exit(1);
+ }
+ }
+
+ @Override
+ public void update() {
+ final String SQL_COMMAND = "SELECT BookID, AvailabilityStatus FROM books WHERE Title = ? " +
+ "AND Author = ?";
+
+ try (Connection connection = DriverManager.getConnection(MyApp.DB_URL,
+ MyApp.DB_USERNAME, MyApp.DB_PASSWORD);
+ PreparedStatement selectID = connection.prepareStatement(SQL_COMMAND)) {
+
+ selectID.setString(1, this.title);
+ selectID.setString(2, this.author);
+
+ ResultSet resultSet = selectID.executeQuery();
+ if (resultSet.next()) {
+ this.uniqueID = resultSet.getInt("BookID");
+ this.availabilityStatus = resultSet.getBoolean("AvailabilityStatus");
+ }
+ } catch (SQLException sqlException) {
+ sqlException.printStackTrace();
+ System.err.print("Connection to database failed! Terminating...");
+ System.exit(1);
+ }
+ }
+
+ public void setStatus(boolean availabilityStatus) {
+ final String SQL_COMMAND = "UPDATE books SET AvailabilityStatus = ? WHERE BookID = ?;";
+
+ try (Connection connection = DriverManager.getConnection(MyApp.DB_URL, MyApp.DB_USERNAME,
+ MyApp.DB_PASSWORD);
+ PreparedStatement changeStatusCommand = connection.prepareStatement(SQL_COMMAND)){
+
+ changeStatusCommand.setBoolean(1, availabilityStatus);
+ changeStatusCommand.setInt(2, this.uniqueID);
+ changeStatusCommand.executeUpdate();
+
+ this.availabilityStatus = availabilityStatus;
+ } catch (SQLException e) {
+ e.printStackTrace();
+ System.err.print("Connection to database failed! Terminating...");
+ }
+ }
+ public String getTitle() {
+ return title;
+ }
+
+ public String getAuthor() {
+ return author;
+ }
+
+ public String getDescription() {
+ return description;
+ }
+
+ public int getUniqueID() {
+ return uniqueID;
+ }
+}
\ No newline at end of file
diff --git a/Answers/src/Library.java b/Answers/src/Library.java
new file mode 100644
index 0000000..df96f87
--- /dev/null
+++ b/Answers/src/Library.java
@@ -0,0 +1,304 @@
+import javax.naming.NoPermissionException;
+import javax.sql.rowset.JdbcRowSet;
+import javax.sql.rowset.RowSetProvider;
+import java.io.FileNotFoundException;
+import java.sql.*;
+import java.util.ArrayList;
+import java.util.Formatter;
+
+public class Library {
+ private String name;
+ private int capacity;
+ private String operatingHours;
+ private User user; // user that log in now
+
+ public void saveLibrary() throws FileNotFoundException, SecurityException {
+ Formatter output = new Formatter(MyApp.PATH.toString());
+ output.format("%s%n%d%n%s", name, capacity, operatingHours);
+ output.close();
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setCapacity(int capacity) {
+ this.capacity = capacity;
+ }
+
+ public User getUser() {
+ return user;
+ }
+
+ public void setUser(User user) {
+ this.user = user;
+ }
+
+ public String getOperatingHours() {
+ return operatingHours;
+ }
+
+ public void setOperatingHours(String operatingHours) throws IllegalArgumentException {
+ {
+ // validate operating hours
+ if (!operatingHours.matches("\\d{2}-\\d{2}"))
+ throw new IllegalArgumentException("Invalid format (e.g. 08-20).");
+
+ String[] hours = operatingHours.split("-");
+ if (Integer.parseInt(hours[0]) > 24 || Integer.parseInt(hours[1]) > 24)
+ throw new IllegalArgumentException("Invalid hours.");
+ }
+ this.operatingHours = operatingHours;
+ }
+
+ // add normal user
+ // return the unique ID of the user
+ public int addUser(NormalUser user) {
+ final String SQL_COMMAND = "INSERT INTO users (Name, PhoneNumber, UserType," +
+ " RegisterTimestamp) VALUES (?, ?, ?, ?)";
+
+ try (Connection connection = DriverManager.getConnection(MyApp.DB_URL,
+ MyApp.DB_USERNAME, MyApp.DB_PASSWORD);
+ PreparedStatement insertUser = connection.prepareStatement(SQL_COMMAND)) {
+
+ insertUser.setString(1, user.getName());
+ insertUser.setString(2, user.getPhoneNumber());
+ insertUser.setString(3, "normal");
+ insertUser.setTimestamp(4, user.getRegisterTimestamp());
+
+ insertUser.executeUpdate();
+ } catch (SQLException sqlException) {
+ sqlException.printStackTrace();
+ System.err.print("Connection to database failed!");
+ return 0;
+ }
+
+ user.update();
+ return user.getUniqueID();
+ }
+
+ // add admin user
+ // return the unique ID of the user
+ public int addUser(User admin, String password) {
+ final String SQL_COMMAND = "INSERT INTO users (Name, PhoneNumber, UserType, Password) "
+ + "VALUES (?, ?, ?, ?)";
+
+ try (Connection connection = DriverManager.getConnection(MyApp.DB_URL,
+ MyApp.DB_USERNAME, MyApp.DB_PASSWORD);
+ PreparedStatement insertUser = connection.prepareStatement(SQL_COMMAND)) {
+
+ insertUser.setString(1, admin.getName());
+ insertUser.setString(2, admin.getPhoneNumber());
+ insertUser.setString(3, "admin");
+ insertUser.setString(4, password);
+
+ insertUser.executeUpdate();
+ } catch (SQLException sqlException) {
+ sqlException.printStackTrace();
+ System.err.print("Connection to database failed!");
+ return 0;
+ }
+
+ // get the unique id from database
+ admin.update();
+ return admin.getUniqueID();
+ }
+
+ public int removeUser(int userID) throws NoPermissionException {
+ if (user == null || user instanceof NormalUser)
+ throw new NoPermissionException("You don't have permission to remove members!");
+
+ if (userID < this.user.getUniqueID())
+ throw new NoPermissionException("You don't have permission to remove this member!");
+
+ for (int i = 0;; i++) {
+ System.out.print("Enter your password: ");
+ String password = MyApp.input.nextLine();
+ if (((Admin) user).verify(password))
+ break;
+ else if (i == 2)
+ throw new IllegalArgumentException("3 incorrect password attempts...");
+ else
+ System.out.println("Invalid password. Try again.");
+ }
+
+ final String SQL_COMMAND = "DELETE FROM users WHERE UserID = ?";
+ try (Connection connection = DriverManager.getConnection(MyApp.DB_URL,
+ MyApp.DB_USERNAME, MyApp.DB_PASSWORD);
+ PreparedStatement deleteUser = connection.prepareStatement(SQL_COMMAND)) {
+
+ deleteUser.setInt(1, userID);
+ return deleteUser.executeUpdate();
+ } catch (SQLException sqlException) {
+ sqlException.printStackTrace();
+ System.err.print("Connection to database failed!");
+ return 0;
+ }
+ }
+
+ // add book
+ public int addBook(Book book) {
+ final String SQL_COMMAND = "INSERT INTO books (BookID, Title, Author, Description) " +
+ "VALUES (?, ?, ?, ?)";
+
+ try (Connection connection = DriverManager.getConnection(MyApp.DB_URL,
+ MyApp.DB_USERNAME, MyApp.DB_PASSWORD);
+ PreparedStatement insertBook = connection.prepareStatement(SQL_COMMAND)) {
+
+ insertBook.setInt(1, book.getUniqueID());
+ insertBook.setString(2, book.getTitle());
+ insertBook.setString(3, book.getAuthor());
+ insertBook.setString(4, book.getDescription());
+
+ insertBook.executeUpdate();
+ } catch (SQLException sqlException) {
+ sqlException.printStackTrace();
+ System.err.print("Connection to database failed!");
+ return 0;
+ }
+
+ // get the unique id from database
+ book.update();
+
+ return book.getUniqueID();
+ }
+
+ // login to library
+ public User login(String userID) {
+ User user = null;
+ final String SQL_COMMAND = "SELECT * FROM users WHERE UserID = ?";
+
+ try (Connection connection = DriverManager.getConnection(MyApp.DB_URL,
+ MyApp.DB_USERNAME, MyApp.DB_PASSWORD);
+ PreparedStatement loginUser = connection.prepareStatement(SQL_COMMAND)) {
+
+ loginUser.setString(1, userID);
+ ResultSet resultSet = loginUser.executeQuery();
+
+ // If there is no such user
+ if (!resultSet.isBeforeFirst())
+ return null;
+ resultSet.next();
+
+ // get name and phone number of the user
+ String name = resultSet.getString("Name");
+ String phoneNumber = resultSet.getString("PhoneNumber");
+
+ if (resultSet.getString("UserType").equals("admin")) {
+ String password = resultSet.getString("Password");
+ user = new Admin(name, phoneNumber, password);
+ user.update();
+ } else {
+ Timestamp registerTimestamp = resultSet.getTimestamp("RegisterTimestamp");
+ user = new NormalUser(name, phoneNumber, registerTimestamp);
+ user.update();
+ }
+ } catch (SQLException sqlException) {
+ sqlException.printStackTrace();
+ System.err.print("Connection to database failed! Terminating...");
+ System.exit(1);
+ }
+ return user;
+ }
+
+ public void getAvailableBooks() {
+ final String SQl_COMMAND = "SELECT BookID, Title, Author, Description " +
+ "FROM books WHERE AvailabilityStatus = 1";
+
+ // connect to database books and query database
+ try (JdbcRowSet rowSet = RowSetProvider.newFactory().createJdbcRowSet()) {
+
+ rowSet.setUrl(MyApp.DB_URL);
+ rowSet.setUsername(MyApp.DB_USERNAME);
+ rowSet.setPassword(MyApp.DB_PASSWORD);
+ rowSet.setCommand(SQl_COMMAND);
+ rowSet.execute();
+
+ // process query results
+ ResultSetMetaData metaData = rowSet.getMetaData();
+ int numberOfColumns = metaData.getColumnCount();
+ System.out.printf("Available books:%n%n");
+ // display rowset header
+ for (int i = 1; i <= numberOfColumns; i++) {
+ if (i > 2)
+ System.out.printf("%-20s\t", metaData.getColumnName(i));
+ else
+ System.out.printf("%-15s\t", metaData.getColumnName(i));
+ }
+ System.out.println();
+ // display each row
+ while (rowSet.next())
+ {
+ for (int i = 1; i <= numberOfColumns; i++) {
+ if (i > 2)
+ System.out.printf("%-20s\t", rowSet.getObject(i));
+ else
+ System.out.printf("%-15s\t", rowSet.getObject(i));
+ }
+ System.out.println();
+ }
+ } catch (SQLException e) {
+ e.printStackTrace();
+ System.err.print("Connection to database failed! Terminating...");
+ System.exit(1);
+ }
+ }
+
+ // search books by name
+ public ArrayList searchBook(String bookName) {
+ final String SQL_COMMAND = "SELECT * FROM books WHERE Title = ? AND AvailabilityStatus = ?";
+ ArrayList resultBooks = new ArrayList<>();
+
+ try (Connection connection = DriverManager.getConnection(MyApp.DB_URL, MyApp.DB_USERNAME,
+ MyApp.DB_PASSWORD);
+ PreparedStatement searchStatement = connection.prepareStatement(SQL_COMMAND)) {
+
+ searchStatement.setString(1, bookName);
+ searchStatement.setBoolean(2, true);
+
+ ResultSet resultSet = searchStatement.executeQuery();
+
+ while (resultSet.next()) {
+ Book book = new Book(bookName, resultSet.getString("Author"),
+ resultSet.getString("Description"));
+ book.update();
+ resultBooks.add(book);
+ }
+
+ return resultBooks;
+ } catch (SQLException e) {
+ e.printStackTrace();
+ System.err.print("Connection to database failed!");
+ return null;
+ }
+ }
+
+ public void returnBook(int bookID) {
+ // set rental date in database
+ final String SQL_COMMAND1 = "UPDATE rents SET ReturnDate = ? WHERE BookID = ?;";
+
+ // change availability status of the book
+ final String SQL_COMMAND2 = "UPDATE books SET AvailabilityStatus = 1 WHERE BookID = ?;";
+
+ try (Connection connection = DriverManager.getConnection(MyApp.DB_URL, MyApp.DB_USERNAME,
+ MyApp.DB_PASSWORD);
+ PreparedStatement returnCommand = connection.prepareStatement(SQL_COMMAND1);
+ PreparedStatement changeStatus = connection.prepareStatement(SQL_COMMAND2)) {
+ // set rental date
+ returnCommand.setTimestamp(1, new Timestamp(System.currentTimeMillis()));
+ returnCommand.setInt(2, bookID);
+ returnCommand.executeUpdate();
+
+ // change availability status of the book
+ changeStatus.setInt(1, bookID);
+ changeStatus.executeUpdate();
+ } catch (SQLException e) {
+ e.printStackTrace();
+ System.err.print("Connection to database failed!");
+ }
+ }
+}
diff --git a/Answers/src/Manual.java b/Answers/src/Manual.java
new file mode 100644
index 0000000..469de3e
--- /dev/null
+++ b/Answers/src/Manual.java
@@ -0,0 +1,48 @@
+public class Manual {
+ public static void printNormalUser() {
+ // command who am I
+ System.out.println("whoami: show who are you");
+
+ // command log in
+ System.out.println("lib login : Log in to your account");
+
+ // command log out
+ System.out.println("lib logout : Log out from your account");
+
+ // command hrs
+ System.out.println("lib get hrs : Retrieve library operating hours.");
+
+ // command view book
+ System.out.println("lib get available books : View available books for rental.");
+
+ // command rent from library
+ System.out.println("lib rent : Rent a book from the library.");
+
+ // command lib get rented books
+ System.out.println("lib get rented books : shows your rented books");
+
+ // command exit
+ System.out.println("lib exit : exit the program");
+
+ // command return book
+ System.out.println("lib return : Return a rented book to the library.");
+ }
+
+ public static void printAdmin() {
+ // command add book
+ System.out.println("lib add book : " +
+ "Add a new book to the library.");
+
+ // command add member
+ System.out.println("lib add member " +
+ " : Add a new member to the library (admin privilege required).");
+
+ // command remove member
+ System.out.println("lib remove member " +
+ ": Remove a member from the library (admin privilege required).");
+
+ // command rent for member
+ System.out.println("lib rent " +
+ " : Rent a book for a specific member.");
+ }
+}
diff --git a/Answers/src/MyApp.java b/Answers/src/MyApp.java
new file mode 100644
index 0000000..a092cd2
--- /dev/null
+++ b/Answers/src/MyApp.java
@@ -0,0 +1,577 @@
+// main class for handling the CLI
+
+import javax.naming.NoPermissionException;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.security.InvalidParameterException;
+import java.util.ArrayList;
+import java.util.InputMismatchException;
+import java.util.Scanner;
+
+public class MyApp {
+ // database information
+ public static final String DB_URL = "jdbc:mysql://localhost/library";
+ public static final String DB_USERNAME = "LMSjava";
+ public static final String DB_PASSWORD = "lmsjava1234";
+
+ // library information
+ public static final Library library = new Library(); // our library
+ public static final Path PATH = Paths.get(".library.txt");
+
+ // scanner for input from client
+ public static Scanner input = new Scanner(System.in);
+
+ public static void main(String[] args) {
+ // check to library is existed or not
+ if (!Files.exists(PATH)) {
+ System.out.println("Welcome to LMS(Library Management System)!");
+ System.out.println("You should create your own library first\n");
+ while (!createLibrary()); // first we should create a library to use it
+
+ System.out.println("Now you should add a new admin to your library!");
+ // add a new admin user
+ while (true) {
+ System.out.println("\nEnter these information about your admin:");
+ try {
+ // get admin name
+ System.out.print("Name: ");
+ String name = input.nextLine();
+
+ // get admin phone number
+ System.out.print("Phone number: ");
+ String phoneNumber = input.nextLine();
+
+ // get admin password
+ System.out.print("Password: ");
+ String password = input.nextLine();
+
+ Admin admin = new Admin(name, phoneNumber, password);
+
+ if (library.addUser(admin, password) == 0) {
+ // delete library file
+ File libraryFile = PATH.toFile();
+ libraryFile.delete();
+
+ System.out.println("Terminating...");
+ System.exit(1);
+ }
+
+ library.setUser(admin); // this is log in now
+ System.out.printf("You are now logged in! Your ID is %s.%n",
+ library.getUser().getUniqueID());
+ } catch (IllegalArgumentException e) {
+ System.err.printf("%s%n", e.getMessage());
+ System.out.println("Try again.");
+ continue;
+ }
+
+ break;
+ }
+ }
+ else {
+ try (Scanner retrieveLibrary = new Scanner(PATH)) {
+ library.setName(retrieveLibrary.nextLine());
+ library.setCapacity(retrieveLibrary.nextInt());
+ library.setOperatingHours(retrieveLibrary.next());
+
+ } catch (IOException e) {
+ System.err.printf("%s%n", e.getMessage());
+ e.printStackTrace();
+ }
+ }
+ // welcome to library
+ System.out.printf("Welcome to %s library.%n", library.getName());
+ System.out.println("For more information enter command ");
+ System.out.println("Enter your command:");
+
+ while (true) {
+ String command = null;
+
+ try {
+ if (library.getUser() == null)
+ System.out.print(">>> ");
+ else if (library.getUser() instanceof Admin)
+ System.out.print("Admin> ");
+ else
+ System.out.printf("%s> ", library.getUser().getName());
+ command = input.nextLine();
+ CLI(command.trim());
+ } catch (InvalidParameterException e) {
+ System.err.println("Invalid username. please try again.");
+ } catch (IllegalArgumentException e) {
+ if (e.getMessage() == null)
+ System.out.printf("command <%s> %s%n", command.trim(), "Not Found.");
+ else
+ System.out.printf("%s%n", e.getMessage());
+ } catch (ArrayIndexOutOfBoundsException e) {
+ System.out.printf("command <%s> %s%n", command.trim(), "Not Found.");
+ } catch (NoPermissionException e) {
+ System.out.printf("%s%n", e.getMessage());
+ } catch (InputMismatchException e) {
+ System.out.printf("Invalid input. proccess cancled...");
+ }
+ }
+ }
+
+ private static boolean createLibrary() {
+ System.out.println("Please enter these information about your library:");
+
+ try {
+ System.out.print("name : ");
+ library.setName(input.nextLine());
+
+ System.out.print("capacity : ");
+ library.setCapacity(input.nextInt());
+ input.nextLine();
+
+ System.out.print("operating hours (format : xx-xx): ");
+ library.setOperatingHours(input.nextLine());
+
+ library.saveLibrary();
+
+ System.out.println("Your library was created successfully.\n");
+ } catch (InputMismatchException e) {
+ System.err.printf("%s%n", e.getMessage());
+ System.err.println("creation was not successful. Terminating program.");
+ System.exit(1); // creation was not successful
+
+ } catch (IllegalArgumentException e) {
+ System.err.printf("%s%n%n", e.getMessage());
+ System.out.println("Try again.");
+ return false;
+ } catch (SecurityException securityException) {
+ System.err.println("Write permission denied. Terminating.");
+ System.exit(1); // terminate the program
+
+ } catch (FileNotFoundException fileNotFoundException) {
+ System.err.println("Error opening file. Terminating.");
+ System.exit(1); // terminate the program
+ }
+ return true;
+ }
+
+ public static void CLI(String command) throws IllegalArgumentException, NoPermissionException,
+ InputMismatchException {
+ if (command.equals("whoami"))
+ if (library.getUser() == null)
+ System.out.println("No one one has logged in yet.");
+ else
+ System.out.println(library.getUser());
+ // command lib man
+ else if (command.matches("lib\\sman")) {
+ System.out.println("You can use these commands :\n");
+ if (library.getUser() instanceof Admin)
+ Manual.printAdmin();
+
+ Manual.printNormalUser();
+ }
+ else if (command.matches("lib\\sget\\srented\\sbooks")) {
+ if (library.getUser() == null)
+ throw new NoPermissionException("You should first login.");
+ else if (library.getUser() instanceof Admin)
+ throw new NoPermissionException("You are admin!You can't rent a book:)");
+
+ ArrayList books = ((NormalUser) library.getUser()).getRentBooks();
+
+ if (books.size() == 1)
+ System.out.println("Your rented book is :");
+ else
+ System.out.println("Your rented books are: ");
+
+ int numberOfRows = 1;
+ for (Book book : books) {
+ System.out.printf("%d.%s", numberOfRows++, book.getTitle());
+ System.out.println();
+ }
+ }
+ // command lib get hrs
+ else if (command.matches("lib\\sget\\shrs"))
+ System.out.print(library.getOperatingHours());
+ else if (command.matches("lib\\sget\\savailable\\sbooks"))
+ library.getAvailableBooks();
+ // command lib remove member
+ else if (command.matches("lib\\slogin\\s\\d+")) {
+ //command lib login
+ if (library.getUser() != null)
+ throw new NoPermissionException("Another account is still logged in! " +
+ "Log out and try again.");
+ String[] temp = command.split("\\s");
+ library.setUser(library.login(temp[2]));
+ if (library.getUser() == null)
+ throw new InvalidParameterException();
+ else if (library.getUser() instanceof NormalUser)
+ System.out.printf("Hello %s!You logged in successfully.%n", library.getUser().getName());
+ else {
+ Admin adminUser = (Admin) library.getUser();
+ for (int i = 0; i < 3; i++) {
+ System.out.printf("Enter password for %s: ", adminUser.getName());
+ String password = input.nextLine();
+ if (adminUser.verify(password)) {
+ System.out.printf("Hello %s! You logged in successfully.%n", adminUser.getName());
+ return;
+ } else
+ System.out.println("Invalid password. Try again.");
+ }
+ library.setUser(null);
+ throw new IllegalArgumentException("3 incorrect password attempts...");
+ }
+ } else if (command.matches("lib\\slogout")) {
+ if (library.getUser() == null)
+ System.out.println("No one has logged in yet");
+ else {
+ System.out.printf("%s logged out successfully.%n", library.getUser().getName());
+ library.setUser(null);
+ }
+ } else if (command.matches("lib\\sreturn\\s.+")) {
+ // return a book
+ String bookName = command.substring(11);
+ ArrayList books = ((NormalUser) library.getUser()).getRentBooks();
+ boolean hasBook = false;
+ int bookID = 0;
+ for (Book book : books)
+ if (book.getTitle().equals(bookName)) {
+ hasBook = true;
+ bookID = book.getUniqueID();
+ }
+ if (hasBook) {
+ library.returnBook(bookID);
+ System.out.printf("Book <%s> returned to library.%n", bookName);
+ } else
+ System.out.println("You didn't rent this book:)");
+ } else if (command.matches("lib\\srent\\s\"?[^\"]*\"?\\s\"?[^\"]*\"?\\s\\d{7,}")) {
+ if (library.getUser() == null)
+ throw new NoPermissionException("You should first login.");
+ else if (library.getUser() instanceof NormalUser)
+ throw new NoPermissionException("You don't have permission to rent a book for " +
+ "another person.");
+ else
+ for (int i = 0; i < 3; i++) {
+ System.out.printf("Enter password for %s: ", library.getUser().getName());
+ String password = input.nextLine();
+ if (((Admin) library.getUser()).verify(password))
+ break;
+ else if (i == 2) {
+ System.out.println("3 incorrect password attempts...");
+ library.setUser(null);
+ return;
+ } else
+ System.out.println("Invalid password. Try again.");
+ }
+ command = command.substring(9);
+
+ String[] temp = new String[2];
+ for (int i = 0; i < 2; i++) {
+ if (command.startsWith("\"")) {
+ command = command.substring(1);
+ temp[i] = command.substring(0, command.indexOf("\""));
+ command = command.replaceFirst(temp[i] + "\" ", "");
+ } else {
+ temp[i] = command.substring(0, command.indexOf(" "));
+ command = command.replaceFirst(temp[i] + " ", "");
+ }
+ }
+
+ String bookName = temp[0], memberName = temp[1];
+ int memberID = Integer.parseInt(command);
+
+ // get books with this name
+ ArrayList books = library.searchBook(bookName);
+
+ if (books.size() == 0) {
+ System.out.printf("book %s not found or not available!%n", bookName);
+ return;
+ }
+
+ Rent rent = null;
+ NormalUser user = null;
+
+ try {
+ user = new NormalUser(memberID, memberName);
+ } catch (Exception e) {
+ System.out.println(e.getMessage());
+ return;
+ }
+
+ if (user.getRentBooks().size() >= 5) {
+ System.out.println("You have already rented 5 books and you can no longer " +
+ "rent a book");
+ return;
+ } if (books.size() == 1)
+ rent = new Rent(books.get(0), user);
+ else {
+ System.out.println("Which book?");
+
+ // show selections
+ int numberOfRows = 1;
+ for (Book book : books) {
+ System.out.printf("%d. ID = %d, Author = %d", numberOfRows,
+ book.getUniqueID(), book.getAuthor());
+ numberOfRows++;
+ }
+
+ // select choice
+ int choice = 1;
+ for (int i = 0; i < 3; i++) {
+ if (library.getUser() == null)
+ System.out.print(">>> ");
+ else if (library.getUser() instanceof Admin)
+ System.out.print("Admin> ");
+ else
+ System.out.printf("%s> ", library.getUser().getName());
+ choice = input.nextInt();
+ if (choice > numberOfRows) {
+ if (i == 2) {
+ System.out.println("3 invalid choice...");
+ return;
+ }
+ System.out.print("Invalid choice. please try again.");
+ } else
+ break;
+ }
+
+ // create rent class
+ rent = new Rent(books.get(choice - 1), user);
+
+ }
+ int rentalID = user.rentBook(rent);
+ if (rentalID == 0)
+ return;
+ System.out.printf("Book %s was rented for %s successfully.", bookName, user.getName());
+ System.out.printf("rental ID = %d%n", rentalID);
+ } else if (command.matches("lib\\sadd\\smember\\s\"?[^\"]*\"?\\s\\+?[\\d-]+\\s?[^(\"\\s)]*")) {
+ // commadn lib add member
+ // if he didn't admin user yet throw exception
+ if (library.getUser() instanceof Admin) {
+ for (int i = 0; i < 3; i++) {
+ System.out.printf("Enter password for %s: ", library.getUser().getName());
+ String password = input.nextLine();
+ if (((Admin) library.getUser()).verify(password))
+ break;
+ else if (i == 2) {
+ System.out.println("3 incorrect password attempts...");
+ library.setUser(null);
+ return;
+ } else
+ System.out.println("Invalid password. Try again.");
+ }
+
+ String name, phoneNumber;
+ int userID;
+
+ String[] temp1 = command.split("\"");
+ if (temp1.length == 3) {
+ name = temp1[1].trim();
+
+ String[] temp2 = temp1[2].trim().split("\\s");
+ phoneNumber = temp2[0].trim();
+ User user;
+ if (temp2.length == 2) {
+ user = new Admin(name, phoneNumber, temp2[1].trim());
+ userID = library.addUser(user, temp2[1].trim());
+ } else {
+ user = new NormalUser(name, phoneNumber);
+ userID = library.addUser((NormalUser) user);
+ }
+ } else {
+ String[] temp = command.split("\\s");
+
+ if (temp.length > 6)
+ throw new IllegalArgumentException(
+ "You should use \" character to split string with space");
+
+ name = temp[3].trim();
+ phoneNumber = temp[4].trim();
+
+ User user;
+ if (temp.length == 6) {
+ user = new Admin(name, phoneNumber, temp[5].trim());
+ userID = library.addUser(user, temp[5].trim());
+ } else {
+ user = new NormalUser(name, phoneNumber);
+ userID = library.addUser((NormalUser) user);
+ }
+ }
+
+ // prompt the user
+ System.out.printf("User %s with ID = %d added to library.%n", name, userID);
+ } // end if (library.user instanceof Admin)
+ else
+ throw new NoPermissionException("You don't have permission to add members!");
+ } else if (command.matches("lib\\sremove\\smember\\s\\d{7,}")) {
+ if (library.getUser() == null)
+ throw new NoPermissionException("You should first login.");
+ else if (library.getUser() instanceof NormalUser)
+ throw new NoPermissionException("You don't have permission to remove members.");
+ else
+ for (int i = 0; i < 3; i++) {
+ System.out.printf("Enter password for %s: ", library.getUser().getName());
+ String password = input.nextLine();
+ if (((Admin) library.getUser()).verify(password))
+ break;
+ else if (i == 2) {
+ System.out.println("3 incorrect password attempts...");
+ library.setUser(null);
+ return;
+ } else
+ System.out.println("Invalid password. Try again.");
+ }
+
+ // get user id from command
+ int userID = Integer.parseInt(command.substring(18));
+
+ if (library.removeUser(userID) == 0)
+ throw new IllegalArgumentException("User with " + userID + " not found!");
+
+ System.out.printf("Account with ID = %d deleted successfully.%n", userID);
+ } else if (command.matches("lib\\sadd\\sbook\\s\"?[^\"]*\"?\\s\"?[^\"]*\"?\\s?(\"?[^\"]*\"?)?")) {
+ // command lib add book
+ // if he didn't admin user yet throw exception
+ if (library.getUser() instanceof Admin) {
+ String title, author;
+
+ // delete lib add book from command
+ command = command.replaceFirst("lib\\sadd\\sbook\\s", "");
+
+ // find the name of the book
+ if (command.startsWith("\"")) {
+ title = command.substring(1, command.indexOf("\"", 1));
+
+ // delete title of the book from command
+ command = command.replaceFirst("\"" + title + "\" ", "");
+ } else {
+ title = command.substring(0, command.indexOf(" "));
+
+ // delete title of the book from command
+ command = command.replaceFirst(title + " ", "");
+ }
+
+ // find the author of the book
+ if (!command.contains(" ")) {
+ author = command;
+ command = "";
+ } else if (command.startsWith("\"")) {
+ author = command.substring(1, command.indexOf("\"", 1));
+
+ // delete author of the book from command
+ command = command.replaceFirst("\"" + author + "\" ", "");
+ } else {
+ author = command.substring(0, command.indexOf(" "));
+
+ // delete author of the book from command
+ command = command.replaceFirst(author + " ", "");
+ }
+
+ // if command doesn't have description
+ if (command.equals("")) {
+ Book book = new Book(title.trim(), author.trim());
+ int bookID = library.addBook(book);
+ if (bookID != 0)
+ System.out.printf("Book %s with ID = %d added to library.%n", book.getTitle(),
+ bookID);
+ return;
+ }
+
+ String description;
+
+ // find the desciption of the book
+ if (command.startsWith("\"")) {
+ description = command.substring(1, command.indexOf("\"", 1));
+
+ // delete description of the book from command
+ command = command.replaceFirst("\"" + description + "\"", "");
+ } else if (command.contains(" "))
+ throw new IllegalArgumentException(
+ "You should use \" character to split string with space");
+ else {
+ description = command;
+
+ // delete description of the book from command
+ command = "";
+ }
+
+ // if command has too many argument
+ if (!command.equals(""))
+ throw new IllegalArgumentException(
+ "You should use \" character to split string with space");
+
+ Book book = new Book(title.trim(), author.trim(), description.trim());
+ int bookID = library.addBook(book);
+ if (bookID != 0)
+ System.out.printf("Book %s with ID = %d added to library.%n", book.getTitle(),
+ bookID);
+ } else
+ throw new NoPermissionException("You don't have permission to add books!");
+ } else if (command.matches("lib\\srent\\s.+")) {
+ if (library.getUser() == null)
+ System.out.println("You should first login to rent a book.");
+ else if (library.getUser() instanceof Admin)
+ System.out.println("You are admin!You can't rent a book:)");
+ else {
+ String bookName = command.substring(8).trim();
+ if (bookName.startsWith("\""))
+ bookName = bookName.substring(1, bookName.length() - 1);
+
+ ArrayList books = library.searchBook(bookName);
+ Rent rent = null;
+
+ if (books.size() == 0) {
+ System.out.printf("book %s not found or not available!%n", bookName);
+ return;
+ } else if (((NormalUser) library.getUser()).getRentBooks().size() >= 5) {
+ System.out.println("You have already rented 5 books and you can no longer " +
+ "rent a book");
+ return;
+ } else if (books.size() == 1)
+ rent = new Rent(books.get(0), (NormalUser) library.getUser());
+ else {
+ System.out.println("Which book do you want?");
+
+ // show selections
+ int numberOfRows = 1;
+ for (Book book : books) {
+ System.out.printf("%d. ID = %d, Author = %d", numberOfRows,
+ book.getUniqueID(), book.getAuthor());
+ numberOfRows++;
+ }
+
+ // select choice
+ int choice = 1;
+ for (int i = 0; i < 3; i++) {
+ if (library.getUser() == null)
+ System.out.print(">>> ");
+ else if (library.getUser() instanceof Admin)
+ System.out.print("Admin> ");
+ else
+ System.out.printf("%s> ", library.getUser().getName());
+ choice = input.nextInt();
+ if (choice > numberOfRows) {
+ if (i == 2) {
+ System.out.println("3 invalid choice...");
+ return;
+ }
+ System.out.print("Invalid choice. please try again.");
+ } else
+ break;
+ }
+
+ // create rent class
+ rent = new Rent(books.get(choice - 1), (NormalUser) library.getUser());
+ }
+ int rentalID = ((NormalUser) library.getUser()).rentBook(rent);
+ if (rentalID == 0)
+ return;
+ System.out.println("You rented this book successfully.");
+ System.out.printf("rental ID = %d%n", rentalID);
+ }
+ } else if (command.matches("lib\\sexit")) {
+ //command lib exit
+ System.out.print("Bye.");
+ System.exit(0);
+ } else
+ throw new IllegalArgumentException();
+ }
+}
diff --git a/Answers/src/NormalUser.java b/Answers/src/NormalUser.java
new file mode 100644
index 0000000..558faa2
--- /dev/null
+++ b/Answers/src/NormalUser.java
@@ -0,0 +1,99 @@
+import java.sql.*;
+import java.util.ArrayList;
+
+public class NormalUser extends User implements Updatable {
+ private Timestamp registerTimestamp;
+ private ArrayList rentBooks = new ArrayList<>();
+
+ public NormalUser(String name, String phoneNumber, Timestamp registerDateTime) {
+ super(name, phoneNumber);
+ this.registerTimestamp = registerDateTime;
+ }
+
+ public NormalUser(String name, String phoneNumber) {
+ super(name, phoneNumber);
+ this.registerTimestamp = new Timestamp(System.currentTimeMillis());
+ }
+
+ public NormalUser(int userID, String name) throws Exception {
+ super(userID, name);
+ final String SQL_COMMAND = "SELECT RegisterTimeStamp FROM users WHERE UserID = ? " +
+ "AND UserType = 'normal';";
+
+ try (Connection connection = DriverManager.getConnection(MyApp.DB_URL, MyApp.DB_USERNAME,
+ MyApp.DB_PASSWORD);
+ PreparedStatement selectUser = connection.prepareStatement(SQL_COMMAND)){
+
+ selectUser.setInt(1, userID);
+ ResultSet resultSet = selectUser.executeQuery();
+
+ if (resultSet.next()) {
+ registerTimestamp = resultSet.getTimestamp("RegisterTimeStamp");
+ } else
+ throw new Exception("User with ID = " + userID + "is not a normal user.");
+ } catch (SQLException e) {
+ e.printStackTrace();
+ System.err.print("Connection to database failed! Terminating...");
+ System.exit(1);
+ }
+ }
+
+ public Timestamp getRegisterTimestamp() {
+ return registerTimestamp;
+ }
+
+ // rent a book
+ public int rentBook(Rent rent) {
+ final String SQL_COMMAND = "INSERT INTO rents (UserID, BookID, RentalDate) VALUES (?, ?, ?);";
+
+ try (Connection connection = DriverManager.getConnection(MyApp.DB_URL, MyApp.DB_USERNAME,
+ MyApp.DB_PASSWORD);
+ PreparedStatement addRentCommand = connection.prepareStatement(SQL_COMMAND)){
+
+ addRentCommand.setInt(1, rent.getPerson().getUniqueID());
+ addRentCommand.setInt(2, rent.getBook().getUniqueID());
+ addRentCommand.setTimestamp(3, rent.getRentalTimestamp());
+ addRentCommand.executeUpdate();
+
+ rent.update();
+ rent.getBook().setStatus(false);
+ rentBooks.add(rent.getBook());
+ return rent.getRentalID();
+ } catch (SQLException e) {
+ e.printStackTrace();
+ System.err.print("Connection to database failed!");
+ return 0;
+ }
+ }
+
+ @Override
+ public void update() {
+ super.update();
+ final String SQL_COMMAND = "SELECT * FROM rents WHERE UserID = ? AND ReturnDate IS NULL;";
+ rentBooks.clear();
+
+ try (Connection connection = DriverManager.getConnection(MyApp.DB_URL, MyApp.DB_USERNAME,
+ MyApp.DB_PASSWORD);
+ PreparedStatement selectRentBooks = connection.prepareStatement(SQL_COMMAND)) {
+
+ selectRentBooks.setInt(1, this.getUniqueID());
+
+ ResultSet resultSet = selectRentBooks.executeQuery();
+
+ while (resultSet.next()) {
+ Book book = new Book(resultSet.getInt("BookID"));
+ rentBooks.add(book);
+ }
+ } catch (SQLException e) {
+ e.printStackTrace();
+ System.err.print("Connection to database failed!");
+ } catch (Exception e) {
+ System.out.println(e.getMessage());
+ }
+ }
+
+ public ArrayList getRentBooks() {
+ update();
+ return rentBooks;
+ }
+}
\ No newline at end of file
diff --git a/Answers/src/Rent.java b/Answers/src/Rent.java
new file mode 100644
index 0000000..8d7316d
--- /dev/null
+++ b/Answers/src/Rent.java
@@ -0,0 +1,57 @@
+// this class for simulates renting
+import java.sql.*;
+
+public class Rent implements Updatable {
+ private Book book;
+ private NormalUser person;
+ private int rentalID;
+ private Timestamp rentalTimestamp;
+
+ public Rent(Book book, NormalUser person) {
+ this.book = book;
+ this.person = person;
+ this.rentalTimestamp = new Timestamp(System.currentTimeMillis());
+ }
+
+ public Rent(Book book, NormalUser person, Timestamp rentalTimestamp) {
+ this.book = book;
+ this.person = person;
+ this.rentalTimestamp = rentalTimestamp;
+ }
+
+ public void update() {
+ final String SQL_COMMAND = "SELECT RentalID FROM rents WHERE UserID = ? AND BookID = ? " +
+ "AND ReturnDate IS NULL;";
+
+ try (Connection connection = DriverManager.getConnection(MyApp.DB_URL,
+ MyApp.DB_USERNAME, MyApp.DB_PASSWORD);
+ PreparedStatement updateRent = connection.prepareStatement(SQL_COMMAND)) {
+
+ updateRent.setInt(1, this.person.getUniqueID());
+ updateRent.setInt(2, this.book.getUniqueID());
+
+ ResultSet resultSet = updateRent.executeQuery();
+ if (resultSet.next())
+ this.rentalID = resultSet.getInt("RentalID");
+ } catch (SQLException sqlException) {
+ sqlException.printStackTrace();
+ System.err.print("Connection to database failed! Terminating...");
+ System.exit(1);
+ }
+ }
+ public Book getBook() {
+ return book;
+ }
+
+ public NormalUser getPerson() {
+ return person;
+ }
+
+ public int getRentalID() {
+ return rentalID;
+ }
+
+ public Timestamp getRentalTimestamp() {
+ return rentalTimestamp;
+ }
+}
\ No newline at end of file
diff --git a/Answers/src/Updatable.java b/Answers/src/Updatable.java
new file mode 100644
index 0000000..9d7467f
--- /dev/null
+++ b/Answers/src/Updatable.java
@@ -0,0 +1,3 @@
+public interface Updatable {
+ void update();
+}
diff --git a/Answers/src/User.java b/Answers/src/User.java
new file mode 100644
index 0000000..8d34632
--- /dev/null
+++ b/Answers/src/User.java
@@ -0,0 +1,85 @@
+// this class simulates the users
+// and it is superclass for NormalUser and Admin
+import java.sql.*;
+
+public class User implements Updatable {
+ private String name;
+ private int uniqueID; // unique id automatically creates in database
+ private String phoneNumber;
+
+ // constructor
+ public User(String name, String phoneNumber) throws IllegalArgumentException {
+ // validate phoneNumber
+ String regexPhoneNumber = "(\\+989|09|00989)((0[0-5]|1[0-9]|2[0-3]|3[0-9]|9[0-6])-?\\d{3}-?\\d{4})|" +
+ "(99-?1[0134]{2}-?[0134]{4})|(99-?[09]{3}-?[09]{4})";
+ if (phoneNumber != null && !phoneNumber.matches(regexPhoneNumber))
+ throw new IllegalArgumentException("Invalid phone number!");
+
+ this.name = name;
+ this.phoneNumber = phoneNumber;
+ }
+
+ protected User(int uniqueID, String name) throws Exception {
+ final String SQL_COMMAND = "SELECT Name, PhoneNumber FROM users WHERE UserID = ?;";
+
+ try (Connection connection = DriverManager.getConnection(MyApp.DB_URL, MyApp.DB_USERNAME,
+ MyApp.DB_PASSWORD);
+ PreparedStatement selectUser = connection.prepareStatement(SQL_COMMAND)) {
+
+ selectUser.setInt(1, uniqueID);
+ ResultSet resultSet = selectUser.executeQuery();
+
+ if (resultSet.next()) {
+ if (name.equals(resultSet.getString("Name")))
+ this.name = name;
+ else
+ throw new Exception("The username does not match the ID");
+ this.uniqueID = uniqueID;
+ this.phoneNumber = resultSet.getString("PhoneNumber");
+ } else
+ throw new Exception("User with ID = " + uniqueID + "not found.");
+ } catch (SQLException e) {
+ e.printStackTrace();
+ System.err.print("Connection to database failed! Terminating...");
+ System.exit(1);
+ }
+ }
+
+ @Override
+ public void update() {
+ final String SQL_COMMAND = "SELECT UserID FROM users WHERE PhoneNumber = ?";
+
+ try (Connection connection = DriverManager.getConnection(MyApp.DB_URL,
+ MyApp.DB_USERNAME, MyApp.DB_PASSWORD);
+ PreparedStatement selectID = connection.prepareStatement(SQL_COMMAND)) {
+
+ selectID.setString(1, this.phoneNumber);
+
+ ResultSet resultSet = selectID.executeQuery();
+ if (resultSet.next())
+ this.uniqueID = resultSet.getInt("UserID");
+ } catch (SQLException sqlException) {
+ sqlException.printStackTrace();
+ System.err.print("Connection to database failed! Terminating...");
+ System.exit(1);
+ }
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public String getPhoneNumber() {
+ return phoneNumber;
+ }
+
+ public int getUniqueID() {
+ return uniqueID;
+ }
+
+ @Override
+ // to string method of admins
+ public String toString() {
+ return String.format("You are "+ this.getName() + " with id = " + this.getUniqueID());
+ }
+}
diff --git a/Library-Management-System.iml b/Library-Management-System.iml
new file mode 100644
index 0000000..b1321ae
--- /dev/null
+++ b/Library-Management-System.iml
@@ -0,0 +1,20 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file