From 4fb352b0894d4d8435e5b89023b0935f3c0ea95c Mon Sep 17 00:00:00 2001
From: Daniel <59575049+lumijiez@users.noreply.github.com>
Date: Fri, 4 Oct 2024 16:37:57 +0300
Subject: [PATCH] First lab
---
.idea/encodings.xml | 7 +
.idea/misc.xml | 2 +-
.idea/uiDesigner.xml | 124 +++++++++++
pom.xml | 2 +-
src/main/java/org/lumijiez/Main.java | 10 -
.../java/org/lumijiez/labs/first/Library.java | 155 ++++++++++++++
.../java/org/lumijiez/labs/first/README.md | 202 ++++++++++++++++++
.../org/lumijiez/labs/first/books/Book.java | 11 +
.../labs/first/books/GeneralBook.java | 46 ++++
.../labs/first/books/ReferenceBook.java | 34 +++
.../InMemoryLibraryRepository.java | 43 ++++
.../repositories/InMemoryUserRepository.java | 33 +++
.../first/repositories/LibraryRepository.java | 11 +
.../first/repositories/UserRepository.java | 9 +
.../labs/first/services/BorrowingService.java | 10 +
.../first/services/BorrowingServiceImpl.java | 27 +++
.../services/EmailNotificationService.java | 21 ++
.../labs/first/services/Notification.java | 11 +
.../labs/first/users/ProfessorUser.java | 59 +++++
.../labs/first/users/StudentUser.java | 58 +++++
.../org/lumijiez/labs/first/users/User.java | 14 ++
21 files changed, 877 insertions(+), 12 deletions(-)
create mode 100644 .idea/encodings.xml
create mode 100644 .idea/uiDesigner.xml
create mode 100644 src/main/java/org/lumijiez/labs/first/Library.java
create mode 100644 src/main/java/org/lumijiez/labs/first/README.md
create mode 100644 src/main/java/org/lumijiez/labs/first/books/Book.java
create mode 100644 src/main/java/org/lumijiez/labs/first/books/GeneralBook.java
create mode 100644 src/main/java/org/lumijiez/labs/first/books/ReferenceBook.java
create mode 100644 src/main/java/org/lumijiez/labs/first/repositories/InMemoryLibraryRepository.java
create mode 100644 src/main/java/org/lumijiez/labs/first/repositories/InMemoryUserRepository.java
create mode 100644 src/main/java/org/lumijiez/labs/first/repositories/LibraryRepository.java
create mode 100644 src/main/java/org/lumijiez/labs/first/repositories/UserRepository.java
create mode 100644 src/main/java/org/lumijiez/labs/first/services/BorrowingService.java
create mode 100644 src/main/java/org/lumijiez/labs/first/services/BorrowingServiceImpl.java
create mode 100644 src/main/java/org/lumijiez/labs/first/services/EmailNotificationService.java
create mode 100644 src/main/java/org/lumijiez/labs/first/services/Notification.java
create mode 100644 src/main/java/org/lumijiez/labs/first/users/ProfessorUser.java
create mode 100644 src/main/java/org/lumijiez/labs/first/users/StudentUser.java
create mode 100644 src/main/java/org/lumijiez/labs/first/users/User.java
diff --git a/.idea/encodings.xml b/.idea/encodings.xml
new file mode 100644
index 0000000..aa00ffa
--- /dev/null
+++ b/.idea/encodings.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/misc.xml b/.idea/misc.xml
index 30d7e2b..890a206 100644
--- a/.idea/misc.xml
+++ b/.idea/misc.xml
@@ -8,7 +8,7 @@
-
+
\ No newline at end of file
diff --git a/.idea/uiDesigner.xml b/.idea/uiDesigner.xml
new file mode 100644
index 0000000..2b63946
--- /dev/null
+++ b/.idea/uiDesigner.xml
@@ -0,0 +1,124 @@
+
+
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+
+
+ -
+
+
+ -
+
+
+
+
+
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
index a7f1a0d..7c5c743 100644
--- a/pom.xml
+++ b/pom.xml
@@ -13,5 +13,5 @@
23
UTF-8
-
+
\ No newline at end of file
diff --git a/src/main/java/org/lumijiez/Main.java b/src/main/java/org/lumijiez/Main.java
index c07936b..8398cc2 100644
--- a/src/main/java/org/lumijiez/Main.java
+++ b/src/main/java/org/lumijiez/Main.java
@@ -1,17 +1,7 @@
package org.lumijiez;
-//TIP To Run code, press or
-// click the icon in the gutter.
public class Main {
public static void main(String[] args) {
- //TIP Press with your caret at the highlighted text
- // to see how IntelliJ IDEA suggests fixing it.
- System.out.printf("Hello and welcome!");
- for (int i = 1; i <= 5; i++) {
- //TIP Press to start debugging your code. We have set one breakpoint
- // for you, but you can always add more by pressing .
- System.out.println("i = " + i);
- }
}
}
\ No newline at end of file
diff --git a/src/main/java/org/lumijiez/labs/first/Library.java b/src/main/java/org/lumijiez/labs/first/Library.java
new file mode 100644
index 0000000..58e1016
--- /dev/null
+++ b/src/main/java/org/lumijiez/labs/first/Library.java
@@ -0,0 +1,155 @@
+package org.lumijiez.labs.first;
+
+import org.lumijiez.labs.first.books.Book;
+import org.lumijiez.labs.first.books.GeneralBook;
+import org.lumijiez.labs.first.books.ReferenceBook;
+import org.lumijiez.labs.first.repositories.InMemoryLibraryRepository;
+import org.lumijiez.labs.first.repositories.InMemoryUserRepository;
+import org.lumijiez.labs.first.repositories.LibraryRepository;
+import org.lumijiez.labs.first.repositories.UserRepository;
+import org.lumijiez.labs.first.services.BorrowingService;
+import org.lumijiez.labs.first.services.BorrowingServiceImpl;
+import org.lumijiez.labs.first.services.EmailNotificationService;
+import org.lumijiez.labs.first.services.Notification;
+import org.lumijiez.labs.first.users.ProfessorUser;
+import org.lumijiez.labs.first.users.StudentUser;
+import org.lumijiez.labs.first.users.User;
+
+import java.util.Scanner;
+
+public class Library {
+
+ static String[][] booksData = {
+ {"Clean Code", "A handbook of agile software craftsmanship."},
+ {"Java Concurrency in Practice", "A comprehensive guide to writing concurrent applications in Java."},
+ {"Effective Java (2nd Edition)", "The definitive guide to programming in Java."},
+ {"Head First Java", "An engaging introduction to the Java programming language."},
+ {"Java: The Complete Reference", "A complete guide to the Java programming language and its features."},
+ {"Design Patterns", "Elements of reusable object-oriented software."},
+ {"Refactoring", "Improving the design of existing code."},
+ {"Introduction to Java Programming", "Comprehensive introduction to Java programming."},
+ {"Java Network Programming", "A guide to network programming in Java."},
+ {"Java Performance: The Definitive Guide", "Getting the most out of Java."}
+ };
+
+ static String[][] referenceBooksData = {
+ {"Java Language Specification", "The official reference for the Java language."},
+ {"Java API Documentation", "Comprehensive documentation for the Java APIs."},
+ {"The Art of Java", "A detailed reference guide to Java programming."},
+ {"Java in a Nutshell", "A quick reference guide for Java developers."},
+ {"Java: A Beginner's Guide", "An introductory guide for beginners."}
+ };
+
+ private static final LibraryRepository libraryRepository = new InMemoryLibraryRepository();
+ private static final UserRepository userRepository = new InMemoryUserRepository();
+ private static final Notification notificationService = new EmailNotificationService();
+ private static final BorrowingService borrowingService = new BorrowingServiceImpl(notificationService);
+
+ public static void main(String[] args) {
+ Scanner scanner = new Scanner(System.in);
+
+ for (String[] bookData : booksData) {
+ GeneralBook book = new GeneralBook(bookData[0], bookData[1]);
+ libraryRepository.addBook(book);
+ }
+
+ for (String[] bookData : referenceBooksData) {
+ ReferenceBook book = new ReferenceBook(bookData[0], bookData[1]);
+ libraryRepository.addBook(book);
+ }
+
+ System.out.println("Welcome to the Library System!");
+ boolean running = true;
+
+ while (running) {
+ System.out.println("\nPlease choose an option:");
+ System.out.println("1. Add a Student User");
+ System.out.println("2. Add a Teacher User");
+ System.out.println("3. Borrow a Book");
+ System.out.println("4. Return a Book");
+ System.out.println("5. List Available Books");
+ System.out.println("6. List Users");
+ System.out.println("7. Exit");
+
+ int option = Integer.parseInt(scanner.nextLine());
+
+ switch (option) {
+ case 1:
+ addUser(scanner, "student");
+ break;
+ case 2:
+ addUser(scanner, "teacher");
+ break;
+ case 3:
+ borrowBook(scanner);
+ break;
+ case 4:
+ returnBook(scanner);
+ break;
+ case 5:
+ libraryRepository.listAvailableBooks();
+ break;
+ case 6:
+ userRepository.listUsers();
+ break;
+ case 7:
+ running = false;
+ System.out.println("Exiting the system. Goodbye!");
+ break;
+ default:
+ System.out.println("Invalid option. Please try again.");
+ }
+ }
+
+ scanner.close();
+ }
+
+ private static void addUser(Scanner scanner, String userType) {
+ System.out.print("Enter user name: ");
+ String userName = scanner.nextLine();
+ User user;
+
+ if (userType.equals("student")) {
+ user = new StudentUser(userName);
+ } else {
+ user = new ProfessorUser(userName);
+ }
+
+ userRepository.addUser(user);
+ System.out.println(userType.substring(0, 1).toUpperCase() + userType.substring(1) + " User '" + userName + "' added.");
+ }
+
+ private static void borrowBook(Scanner scanner) {
+ System.out.print("Enter user name: ");
+ String userName = scanner.nextLine();
+
+ System.out.print("Enter book title to borrow: ");
+ String bookTitle = scanner.nextLine();
+
+ User user = userRepository.getUserByName(userName);
+ Book book = libraryRepository.getBookByTitle(bookTitle);
+
+ if (user != null && book != null) {
+ borrowingService.borrowBook(user, book);
+ } else {
+ System.out.println("User or book not found.");
+ }
+ }
+
+ private static void returnBook(Scanner scanner) {
+ System.out.print("Enter user name: ");
+ String userName = scanner.nextLine();
+
+ System.out.print("Enter book title to return: ");
+ String bookTitle = scanner.nextLine();
+
+ User user = userRepository.getUserByName(userName);
+ Book book = libraryRepository.getBookByTitle(bookTitle);
+
+ if (user != null && book != null) {
+ borrowingService.returnBook(user, book);
+ } else {
+ System.out.println("User or book not found.");
+ }
+ }
+}
diff --git a/src/main/java/org/lumijiez/labs/first/README.md b/src/main/java/org/lumijiez/labs/first/README.md
new file mode 100644
index 0000000..615eef9
--- /dev/null
+++ b/src/main/java/org/lumijiez/labs/first/README.md
@@ -0,0 +1,202 @@
+# Laboratory 0 - Library Management System
+
+## Author: Schipschi Daniil / FAF-223
+
+----
+
+## Objectives:
+
+* Implement the first two letters of SOLID in a simple project.
+
+## Implementation
+
+The Library Management System allows users (students and professors) to borrow and return books while managing the underlying book and user storage efficiently. This implementation employs several creational design patterns while adhering to SOLID principles.
+
+### Key SOLID Principles
+
+1. **Single Responsibility Principle (SRP)**: Each class has one specific responsibility, ensuring that changes in one area of the application don't affect others.
+
+ - **Book Interface**: Responsible for defining book-related properties and behaviors.
+ - **User Repository**: Focused solely on managing user data without coupling to book operations.
+ - **Library Repository**: Focused solely on managing book data.
+ - **Notification Service**: Handles user notifications independently.
+
+ **Example: Book Interface**
+ ```java
+ public interface Book {
+ String getTitle();
+ String getDescription();
+ }
+ ```
+
+ Each class implementing this interface can have its unique implementation. For example:
+
+ **Example: GeneralBook Implementation**
+ ```java
+ public class GeneralBook implements Book {
+ private String title;
+ private String description;
+
+ public GeneralBook(String title, String description) {
+ this.title = title;
+ this.description = description;
+ }
+
+ @Override
+ public String getTitle() {
+ return title;
+ }
+
+ @Override
+ public String getDescription() {
+ return description;
+ }
+ }
+ ```
+
+2. **Open/Closed Principle (OCP)**: The system is open for extension but closed for modification. New types of users or books can be added without changing existing code.
+
+ - **Book Types**: You can add new book types (e.g., `EBook`) by extending the `Book` interface without modifying existing classes.
+
+ **Example: EBook Implementation**
+ ```java
+ public class EBook implements Book {
+ private String title;
+ private String description;
+ private String fileFormat;
+
+ public EBook(String title, String description, String fileFormat) {
+ this.title = title;
+ this.description = description;
+ this.fileFormat = fileFormat;
+ }
+
+ @Override
+ public String getTitle() {
+ return title;
+ }
+
+ @Override
+ public String getDescription() {
+ return description;
+ }
+
+ public String getFileFormat() {
+ return fileFormat;
+ }
+ }
+ ```
+
+ - **User Types**: New user types (e.g., `AdminUser`) can be implemented by creating new classes that implement the `User` interface.
+
+ **Example: AdminUser Implementation**
+ ```java
+ public class AdminUser implements User {
+ private String name;
+
+ public AdminUser(String name) {
+ this.name = name;
+ }
+
+ @Override
+ public String getName() {
+ return name;
+ }
+
+ // Admin-specific functionalities can be added here
+ }
+ ```
+
+### Code Snippets
+
+**User Repository Interface**
+```java
+public interface UserRepository {
+ void addUser(User user);
+ User getUserByName(String userName);
+ void listUsers();
+}
+```
+
+**InMemoryUserRepository Implementation**
+```java
+public class InMemoryUserRepository implements UserRepository {
+private final List users = new ArrayList<>();
+
+ @Override
+ public void addUser(User user) {
+ users.add(user);
+ }
+
+ @Override
+ public User getUserByName(String userName) {
+ return users.stream()
+ .filter(user -> user.getName().equalsIgnoreCase(userName))
+ .findFirst()
+ .orElse(null);
+ }
+
+ @Override
+ public void listUsers() {
+ users.forEach(user -> System.out.println(user.getName()));
+ }
+}
+```
+
+**Notification Interface**
+```java
+public interface Notification {
+ void notifyUser(String message);
+}
+```
+
+**EmailNotificationService Implementation**
+```java
+public class EmailNotificationService implements Notification {
+ @Override
+ public void notifyUser(String message) {
+ System.out.println("Email sent: " + message);
+ }
+}
+```
+
+**Borrowing Service Interface**
+```java
+public interface BorrowingService {
+ void borrowBook(User user, Book book);
+ void returnBook(User user, Book book);
+}
+```
+
+**Borrowing Service Implementation**
+java
+public class BorrowingServiceImpl implements BorrowingService {
+ private final Notification notificationService;
+
+ public BorrowingServiceImpl(Notification notificationService) {
+ this.notificationService = notificationService;
+ }
+
+ @Override
+ public void borrowBook(User user, Book book) {
+ notificationService.notifyUser(user.getName() + " borrowed " + book.getTitle() + ".");
+ }
+
+ @Override
+ public void returnBook(User user, Book book) {
+ notificationService.notifyUser(user.getName() + " returned " + book.getTitle() + ".");
+ }
+}
+```
+
+### Conclusion
+
+This Library Management System effectively demonstrates the application of SOLID principles:
+
+- **Single Responsibility Principle (S)** is maintained by clearly separating the responsibilities of managing users, books, and notifications, which allows for focused changes in each area.
+
+- **Open/Closed Principle (O)** is illustrated through the extensible design of the `Book` and `User` classes. New types can be added easily without modifying existing functionality, thereby promoting a flexible and maintainable system.
+
+This design leads to a more modular, maintainable codebase, making future enhancements straightforward.
+
+---
diff --git a/src/main/java/org/lumijiez/labs/first/books/Book.java b/src/main/java/org/lumijiez/labs/first/books/Book.java
new file mode 100644
index 0000000..63531f5
--- /dev/null
+++ b/src/main/java/org/lumijiez/labs/first/books/Book.java
@@ -0,0 +1,11 @@
+package org.lumijiez.labs.first.books;
+
+import java.time.LocalDate;
+
+public interface Book {
+ String getTitle();
+ boolean canBeBorrowed();
+ String getContent();
+ LocalDate getDueDate();
+}
+
diff --git a/src/main/java/org/lumijiez/labs/first/books/GeneralBook.java b/src/main/java/org/lumijiez/labs/first/books/GeneralBook.java
new file mode 100644
index 0000000..32c58da
--- /dev/null
+++ b/src/main/java/org/lumijiez/labs/first/books/GeneralBook.java
@@ -0,0 +1,46 @@
+package org.lumijiez.labs.first.books;
+
+import java.time.LocalDate;
+
+public class GeneralBook implements Book {
+ private String title;
+ private String content;
+ private boolean borrowed;
+ private LocalDate dueDate;
+
+ public GeneralBook(String title, String content) {
+ this.title = title;
+ this.content = content;
+ this.borrowed = false;
+ }
+
+ @Override
+ public String getTitle() {
+ return this.title;
+ }
+
+ @Override
+ public boolean canBeBorrowed() {
+ return !borrowed;
+ }
+
+ @Override
+ public String getContent() {
+ return this.content;
+ }
+
+ @Override
+ public LocalDate getDueDate() {
+ return dueDate;
+ }
+
+ public void borrow(LocalDate dueDate) {
+ this.borrowed = true;
+ this.dueDate = dueDate;
+ }
+
+ public void returnBook() {
+ this.borrowed = false;
+ this.dueDate = null;
+ }
+}
diff --git a/src/main/java/org/lumijiez/labs/first/books/ReferenceBook.java b/src/main/java/org/lumijiez/labs/first/books/ReferenceBook.java
new file mode 100644
index 0000000..1fe06b8
--- /dev/null
+++ b/src/main/java/org/lumijiez/labs/first/books/ReferenceBook.java
@@ -0,0 +1,34 @@
+package org.lumijiez.labs.first.books;
+
+import java.time.LocalDate;
+
+public class ReferenceBook implements Book {
+ private String title;
+ private String content;
+
+ public ReferenceBook(String title, String content) {
+ this.title = title;
+ this.content = content;
+ }
+
+ @Override
+ public String getTitle() {
+ return this.title;
+ }
+
+ @Override
+ public boolean canBeBorrowed() {
+ return false;
+ }
+
+ @Override
+ public String getContent() {
+ return this.content;
+ }
+
+ @Override
+ public LocalDate getDueDate() {
+ return null;
+ }
+}
+
diff --git a/src/main/java/org/lumijiez/labs/first/repositories/InMemoryLibraryRepository.java b/src/main/java/org/lumijiez/labs/first/repositories/InMemoryLibraryRepository.java
new file mode 100644
index 0000000..89b7bec
--- /dev/null
+++ b/src/main/java/org/lumijiez/labs/first/repositories/InMemoryLibraryRepository.java
@@ -0,0 +1,43 @@
+package org.lumijiez.labs.first.repositories;
+
+import org.lumijiez.labs.first.books.Book;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class InMemoryLibraryRepository implements LibraryRepository {
+ private final List books = new ArrayList<>();
+
+ @Override
+ public void addBook(Book book) {
+ books.add(book);
+ }
+
+ @Override
+ public void removeBook(Book book) {
+ books.remove(book);
+ }
+
+ @Override
+ public void listAvailableBooks() {
+ System.out.println("Available books:");
+ for (Book book : books) {
+ if (book.canBeBorrowed()) {
+ System.out.println(book.getTitle());
+ } else {
+ System.out.println(book.getTitle() + " [NOT FOR BORROW]");
+ }
+ }
+ }
+
+ @Override
+ public Book getBookByTitle(String title) {
+ for (Book book : books) {
+ if (book.getTitle().equals(title)) {
+ return book;
+ }
+ }
+ return null;
+ }
+}
+
diff --git a/src/main/java/org/lumijiez/labs/first/repositories/InMemoryUserRepository.java b/src/main/java/org/lumijiez/labs/first/repositories/InMemoryUserRepository.java
new file mode 100644
index 0000000..e79e22f
--- /dev/null
+++ b/src/main/java/org/lumijiez/labs/first/repositories/InMemoryUserRepository.java
@@ -0,0 +1,33 @@
+package org.lumijiez.labs.first.repositories;
+
+import org.lumijiez.labs.first.users.User;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class InMemoryUserRepository implements UserRepository {
+ private final List users = new ArrayList<>();
+
+ @Override
+ public void addUser(User user) {
+ users.add(user);
+ }
+
+ @Override
+ public User getUserByName(String userName) {
+ return users.stream()
+ .filter(user -> user.getName().equalsIgnoreCase(userName))
+ .findFirst()
+ .orElse(null);
+ }
+
+ @Override
+ public void listUsers() {
+ if (users.isEmpty()) {
+ System.out.println("No users in the system.");
+ } else {
+ users.forEach(user -> System.out.println(user.getName()));
+ }
+ }
+}
+
diff --git a/src/main/java/org/lumijiez/labs/first/repositories/LibraryRepository.java b/src/main/java/org/lumijiez/labs/first/repositories/LibraryRepository.java
new file mode 100644
index 0000000..b1d8242
--- /dev/null
+++ b/src/main/java/org/lumijiez/labs/first/repositories/LibraryRepository.java
@@ -0,0 +1,11 @@
+package org.lumijiez.labs.first.repositories;
+
+import org.lumijiez.labs.first.books.Book;
+
+public interface LibraryRepository {
+ void addBook(Book book);
+ void removeBook(Book book);
+ void listAvailableBooks();
+ Book getBookByTitle(String title);
+}
+
diff --git a/src/main/java/org/lumijiez/labs/first/repositories/UserRepository.java b/src/main/java/org/lumijiez/labs/first/repositories/UserRepository.java
new file mode 100644
index 0000000..5447590
--- /dev/null
+++ b/src/main/java/org/lumijiez/labs/first/repositories/UserRepository.java
@@ -0,0 +1,9 @@
+package org.lumijiez.labs.first.repositories;
+
+import org.lumijiez.labs.first.users.User;
+
+public interface UserRepository {
+ void addUser(User user);
+ User getUserByName(String userName);
+ void listUsers();
+}
diff --git a/src/main/java/org/lumijiez/labs/first/services/BorrowingService.java b/src/main/java/org/lumijiez/labs/first/services/BorrowingService.java
new file mode 100644
index 0000000..173a01d
--- /dev/null
+++ b/src/main/java/org/lumijiez/labs/first/services/BorrowingService.java
@@ -0,0 +1,10 @@
+package org.lumijiez.labs.first.services;
+
+import org.lumijiez.labs.first.books.Book;
+import org.lumijiez.labs.first.users.User;
+
+public interface BorrowingService {
+ void borrowBook(User user, Book book);
+ void returnBook(User user, Book book);
+}
+
diff --git a/src/main/java/org/lumijiez/labs/first/services/BorrowingServiceImpl.java b/src/main/java/org/lumijiez/labs/first/services/BorrowingServiceImpl.java
new file mode 100644
index 0000000..14a95a1
--- /dev/null
+++ b/src/main/java/org/lumijiez/labs/first/services/BorrowingServiceImpl.java
@@ -0,0 +1,27 @@
+package org.lumijiez.labs.first.services;
+
+import org.lumijiez.labs.first.books.Book;
+import org.lumijiez.labs.first.users.User;
+
+public class BorrowingServiceImpl implements BorrowingService {
+ private final Notification notificationService;
+
+ public BorrowingServiceImpl(Notification notificationService) {
+ this.notificationService = notificationService;
+ }
+
+ @Override
+ public void borrowBook(User user, Book book) {
+ if (user.borrowBook(book)) {
+ notificationService.notifyUser(user.getName() + " borrowed " + book.getTitle() + ".");
+ } else {
+ System.out.println("Could not borrow the book: " + book.getTitle());
+ }
+ }
+
+ @Override
+ public void returnBook(User user, Book book) {
+ user.returnBook(book);
+ notificationService.notifyUser(user.getName() + " returned " + book.getTitle() + ".");
+ }
+}
diff --git a/src/main/java/org/lumijiez/labs/first/services/EmailNotificationService.java b/src/main/java/org/lumijiez/labs/first/services/EmailNotificationService.java
new file mode 100644
index 0000000..76bfcbc
--- /dev/null
+++ b/src/main/java/org/lumijiez/labs/first/services/EmailNotificationService.java
@@ -0,0 +1,21 @@
+package org.lumijiez.labs.first.services;
+
+import org.lumijiez.labs.first.books.Book;
+import org.lumijiez.labs.first.users.User;
+
+import java.time.LocalDate;
+
+public class EmailNotificationService implements Notification {
+ @Override
+ public void notifyUser(String message) {
+ System.out.println("Sending email: " + message);
+ }
+
+ @Override
+ public void remindDueDate(Book book, User user) {
+ LocalDate dueDate = book.getDueDate();
+ if (dueDate != null) {
+ System.out.println("Reminder: " + user.getName() + ", your borrowed book " + book.getTitle() + " is due on " + dueDate);
+ }
+ }
+}
diff --git a/src/main/java/org/lumijiez/labs/first/services/Notification.java b/src/main/java/org/lumijiez/labs/first/services/Notification.java
new file mode 100644
index 0000000..3820e7a
--- /dev/null
+++ b/src/main/java/org/lumijiez/labs/first/services/Notification.java
@@ -0,0 +1,11 @@
+package org.lumijiez.labs.first.services;
+
+import org.lumijiez.labs.first.books.Book;
+import org.lumijiez.labs.first.users.User;
+
+public interface Notification {
+ void notifyUser(String message);
+ void remindDueDate(Book book, User user);
+}
+
+
diff --git a/src/main/java/org/lumijiez/labs/first/users/ProfessorUser.java b/src/main/java/org/lumijiez/labs/first/users/ProfessorUser.java
new file mode 100644
index 0000000..cfb10ab
--- /dev/null
+++ b/src/main/java/org/lumijiez/labs/first/users/ProfessorUser.java
@@ -0,0 +1,59 @@
+package org.lumijiez.labs.first.users;
+
+import org.lumijiez.labs.first.books.Book;
+import org.lumijiez.labs.first.books.GeneralBook;
+
+import java.time.LocalDate;
+import java.util.ArrayList;
+import java.util.List;
+
+public class ProfessorUser implements User {
+ private final String name;
+ private final List borrowedBooks = new ArrayList<>();
+ private static final int BORROW_LIMIT = 50;
+
+ public ProfessorUser(String name) {
+ this.name = name;
+ }
+
+ @Override
+ public boolean borrowBook(Book book) {
+ if (borrowedBooks.size() >= BORROW_LIMIT) {
+ System.out.println(name + " has reached the borrowing limit.");
+ return false;
+ }
+ if (book.canBeBorrowed()) {
+ LocalDate dueDate = LocalDate.now().plusWeeks(4);
+ ((GeneralBook) book).borrow(dueDate);
+ borrowedBooks.add(book);
+ System.out.println(name + " borrowed " + book.getTitle() + ". Due date: " + dueDate);
+ return true;
+ } else {
+ System.out.println(book.getTitle() + " cannot be borrowed.");
+ }
+ return false;
+ }
+
+ @Override
+ public void returnBook(Book book) {
+ borrowedBooks.remove(book);
+ ((GeneralBook) book).returnBook();
+ System.out.println(name + " returned " + book.getTitle());
+ }
+
+ @Override
+ public String getName() {
+ return this.name;
+ }
+
+ @Override
+ public List getBorrowedBooks() {
+ return borrowedBooks;
+ }
+
+ @Override
+ public int getBorrowingLimit() {
+ return BORROW_LIMIT;
+ }
+}
+
diff --git a/src/main/java/org/lumijiez/labs/first/users/StudentUser.java b/src/main/java/org/lumijiez/labs/first/users/StudentUser.java
new file mode 100644
index 0000000..d4100d1
--- /dev/null
+++ b/src/main/java/org/lumijiez/labs/first/users/StudentUser.java
@@ -0,0 +1,58 @@
+package org.lumijiez.labs.first.users;
+
+import org.lumijiez.labs.first.books.Book;
+import org.lumijiez.labs.first.books.GeneralBook;
+
+import java.time.LocalDate;
+import java.util.ArrayList;
+import java.util.List;
+
+public class StudentUser implements User {
+ private final String name;
+ private final List borrowedBooks = new ArrayList<>();
+ private static final int BORROW_LIMIT = 3;
+
+ public StudentUser(String name) {
+ this.name = name;
+ }
+
+ @Override
+ public boolean borrowBook(Book book) {
+ if (borrowedBooks.size() >= BORROW_LIMIT) {
+ System.out.println(name + " has reached the borrowing limit.");
+ return false;
+ }
+ if (book.canBeBorrowed()) {
+ LocalDate dueDate = LocalDate.now().plusWeeks(2);
+ ((GeneralBook) book).borrow(dueDate);
+ borrowedBooks.add(book);
+ System.out.println(name + " borrowed " + book.getTitle() + ". Due date: " + dueDate);
+ return true;
+ } else {
+ System.out.println(book.getTitle() + " cannot be borrowed.");
+ }
+ return false;
+ }
+
+ @Override
+ public void returnBook(Book book) {
+ borrowedBooks.remove(book);
+ ((GeneralBook) book).returnBook();
+ System.out.println(name + " returned " + book.getTitle());
+ }
+
+ @Override
+ public String getName() {
+ return this.name;
+ }
+
+ @Override
+ public List getBorrowedBooks() {
+ return borrowedBooks;
+ }
+
+ @Override
+ public int getBorrowingLimit() {
+ return BORROW_LIMIT;
+ }
+}
diff --git a/src/main/java/org/lumijiez/labs/first/users/User.java b/src/main/java/org/lumijiez/labs/first/users/User.java
new file mode 100644
index 0000000..31c812b
--- /dev/null
+++ b/src/main/java/org/lumijiez/labs/first/users/User.java
@@ -0,0 +1,14 @@
+package org.lumijiez.labs.first.users;
+
+import org.lumijiez.labs.first.books.Book;
+
+import java.util.List;
+
+public interface User {
+ boolean borrowBook(Book book);
+ void returnBook(Book book);
+ String getName();
+ List getBorrowedBooks();
+ int getBorrowingLimit();
+}
+