From c5c7887f7eab7bfedffcc5c5dd888d15bc7f1586 Mon Sep 17 00:00:00 2001
From: Guyslain <guyslain.naves@lis-lab.fr>
Date: Tue, 19 Nov 2024 11:56:19 +0100
Subject: [PATCH] TD 9 exceptions

---
 src/main/java/fr/univamu/progav/td9/Book.java |  9 +++
 .../fr/univamu/progav/td9/BookException.java  |  9 +++
 .../progav/td9/BookNotFoundException.java     |  4 ++
 .../fr/univamu/progav/td9/BookStatus.java     |  4 ++
 .../progav/td9/BookUnavailableException.java  |  4 ++
 .../progav/td9/BulkCheckoutResult.java        | 16 +++++
 .../java/fr/univamu/progav/td9/Library.java   | 32 +++++++++
 src/main/java/fr/univamu/progav/td9/TD9.md    | 70 +++++++++++++++++++
 .../fr/univamu/progav/td9/LibraryTest.java    | 65 +++++++++++++++++
 9 files changed, 213 insertions(+)
 create mode 100644 src/main/java/fr/univamu/progav/td9/Book.java
 create mode 100644 src/main/java/fr/univamu/progav/td9/BookException.java
 create mode 100644 src/main/java/fr/univamu/progav/td9/BookNotFoundException.java
 create mode 100644 src/main/java/fr/univamu/progav/td9/BookStatus.java
 create mode 100644 src/main/java/fr/univamu/progav/td9/BookUnavailableException.java
 create mode 100644 src/main/java/fr/univamu/progav/td9/BulkCheckoutResult.java
 create mode 100644 src/main/java/fr/univamu/progav/td9/Library.java
 create mode 100644 src/main/java/fr/univamu/progav/td9/TD9.md
 create mode 100644 src/test/java/fr/univamu/progav/td9/LibraryTest.java

diff --git a/src/main/java/fr/univamu/progav/td9/Book.java b/src/main/java/fr/univamu/progav/td9/Book.java
new file mode 100644
index 0000000..cb345b2
--- /dev/null
+++ b/src/main/java/fr/univamu/progav/td9/Book.java
@@ -0,0 +1,9 @@
+package fr.univamu.progav.td9;
+
+public record Book(String isbn, String title) {
+
+  @Override
+  public String toString() {
+    return title + " (" + isbn + ")";
+  }
+}
diff --git a/src/main/java/fr/univamu/progav/td9/BookException.java b/src/main/java/fr/univamu/progav/td9/BookException.java
new file mode 100644
index 0000000..4a4f47b
--- /dev/null
+++ b/src/main/java/fr/univamu/progav/td9/BookException.java
@@ -0,0 +1,9 @@
+package fr.univamu.progav.td9;
+
+public class BookException extends Exception {
+
+  public Book book() {
+    // TODO
+    return null;
+  }
+}
diff --git a/src/main/java/fr/univamu/progav/td9/BookNotFoundException.java b/src/main/java/fr/univamu/progav/td9/BookNotFoundException.java
new file mode 100644
index 0000000..caa7cd3
--- /dev/null
+++ b/src/main/java/fr/univamu/progav/td9/BookNotFoundException.java
@@ -0,0 +1,4 @@
+package fr.univamu.progav.td9;
+
+public class BookNotFoundException extends BookException {
+}
diff --git a/src/main/java/fr/univamu/progav/td9/BookStatus.java b/src/main/java/fr/univamu/progav/td9/BookStatus.java
new file mode 100644
index 0000000..21e3fe5
--- /dev/null
+++ b/src/main/java/fr/univamu/progav/td9/BookStatus.java
@@ -0,0 +1,4 @@
+package fr.univamu.progav.td9;
+
+public enum BookStatus { AVAILABLE, BORROWED; }
+
diff --git a/src/main/java/fr/univamu/progav/td9/BookUnavailableException.java b/src/main/java/fr/univamu/progav/td9/BookUnavailableException.java
new file mode 100644
index 0000000..a6dfffc
--- /dev/null
+++ b/src/main/java/fr/univamu/progav/td9/BookUnavailableException.java
@@ -0,0 +1,4 @@
+package fr.univamu.progav.td9;
+
+public class BookUnavailableException extends BookException {
+}
diff --git a/src/main/java/fr/univamu/progav/td9/BulkCheckoutResult.java b/src/main/java/fr/univamu/progav/td9/BulkCheckoutResult.java
new file mode 100644
index 0000000..5cb03a3
--- /dev/null
+++ b/src/main/java/fr/univamu/progav/td9/BulkCheckoutResult.java
@@ -0,0 +1,16 @@
+package fr.univamu.progav.td9;
+
+import java.util.List;
+
+public record BulkCheckoutResult(
+  List<Book> successfulCheckouts,
+  List<BookException> failedCheckouts
+) {
+
+
+  public boolean isCompletelySuccessful() {
+    // TODO
+    return false;
+  }
+
+}
diff --git a/src/main/java/fr/univamu/progav/td9/Library.java b/src/main/java/fr/univamu/progav/td9/Library.java
new file mode 100644
index 0000000..cd7509a
--- /dev/null
+++ b/src/main/java/fr/univamu/progav/td9/Library.java
@@ -0,0 +1,32 @@
+package fr.univamu.progav.td9;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+public class Library {
+  private final Map<Book, BookStatus> bookStatuses = new HashMap<>();
+
+  public void addBook(Book book) {
+    bookStatuses.put(book, BookStatus.AVAILABLE);
+  }
+
+  public Book findBook(String isbn) {
+    // TODO
+    return null;
+  }
+
+  public void checkoutBook(Book book) throws BookException {
+    // TODO
+  }
+
+  public BulkCheckoutResult checkoutBooks(List<Book> books) {
+    // TODO
+    return null;
+  }
+
+  public BookStatus getBookStatus(Book book) {
+    // TODO
+    return null;
+  }
+}
diff --git a/src/main/java/fr/univamu/progav/td9/TD9.md b/src/main/java/fr/univamu/progav/td9/TD9.md
new file mode 100644
index 0000000..88c4dc5
--- /dev/null
+++ b/src/main/java/fr/univamu/progav/td9/TD9.md
@@ -0,0 +1,70 @@
+Ces exercices portent sur la gestion des exceptions. Le contexte est la 
+gestion des livres d'une bibliothèque, qui n'est pas un exemple très 
+pertinent pour l'utilisation d'exceptions, mais qui a l'avantage d'être 
+relativement simple pour apprendre les bases de la manipulation des exceptions.
+
+La bibliothèque ```Library``` possède une collection de livre ```Book```, et 
+les clients peuvent venir emprunter un ou plusieurs livres (méthodes 
+```checkoutBook``` et ```checkoutBooks```). Un livre peut donc être 
+disponible ou indisponible (classe ```BookStatus```), ou bien ne pas faire 
+partie de la bibliothèque.
+
+Si un client veut emprunter un livre déjà prêté, l'exception 
+```BookUnavailableException``` sera levée. Si le livre n'est pas possédé par la 
+bibliothèque, l'exception ```BookNotFoundException``` sera levée.
+
+Exercice 1
+==========
+
+Compléter la classe d'exception ```BookException```, en y ajoutant une 
+propriété ```Book```, et une méthode ```toString``` affichant le livre. 
+Compléter aussi la méthode ```book```.
+
+Exercice 2
+==========
+
+Compléter les 2 extensions ```BookNotFoundException``` et 
+```BookUnavailable``` de ```BookException```. Assurez-vous que le 
+```toString``` de chacune affiche un message adapté et mentionnant le livre 
+concerné.
+
+Exercice 3
+==========
+
+Compléter la méthode ```findBook``` de la classe ```Library```. Elle doit 
+retourner le livre dont le code ISBN est fourni. S'il n'existe pas un tel 
+livre, il faut émettre l'exception ```BookNotFoundException```. Ajouter la 
+déclaration d'exception à la méthode.
+
+Exercice 4
+==========
+
+Compléter la méthode ```checkBookStatus``` de la classe ```Library```, 
+retournant le status d'un livre précisé par son code ISBN. Si le livre 
+n'existe pas, l'exception ```BookNotFound``` sera émise. Ajouter la
+déclaration d'exception à la méthode.
+
+Exercice 5
+==========
+
+Compléter la méthode ```checkoutBook``` de la classe ```Library```.
+La méthode vérifie l'existence et la disponibilité du livre (donné par son 
+code ISBN), et modifie alors son status à ```BORROWED```. Si les conditions 
+ne sont pas respectées, la méthode émet l'exception appropriée. Ajouter la
+déclaration d'exception à la méthode.
+
+Exercice 6
+==========
+
+Compléter la méthode ```isCompletelySuccessful``` de la classe 
+```BulkCheckoutResult```. Cette classe contiendra les résultats de la 
+réservation d'une liste de livres, comprenant :
+- la liste des livres empruntés;
+- la liste des échecs des tentatives d'emprunt.
+
+Exercice 7
+==========
+
+Compléter la méthode ```checkoutBooks``` de la classe ```Library```.
+
+
diff --git a/src/test/java/fr/univamu/progav/td9/LibraryTest.java b/src/test/java/fr/univamu/progav/td9/LibraryTest.java
new file mode 100644
index 0000000..e5abf05
--- /dev/null
+++ b/src/test/java/fr/univamu/progav/td9/LibraryTest.java
@@ -0,0 +1,65 @@
+package fr.univamu.progav.td9;
+
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
+import java.util.List;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+public class LibraryTest {
+
+  private Library library;
+  private Book book1;
+  private Book book2;
+  private Book book3;
+
+  @BeforeEach
+  void setUp() {
+    library = new Library();
+    book1 = new Book("123", "Livre 1");
+    book2 = new Book("456", "Livre 2");
+    book3 = new Book("789", "Livre 3");
+    library.addBook(book1);
+    library.addBook(book2);
+    library.addBook(book3);
+  }
+
+  @Test
+  void testFindBookThrowsException() {
+    assertThrows(BookNotFoundException.class, () -> {
+      library.findBook("999");
+    });
+  }
+
+  @Test
+  void testSingleCheckoutSuccess() throws BookException {
+    library.checkoutBook(book1);
+    assertEquals(BookStatus.BORROWED, library.getBookStatus(book1));
+  }
+
+  @Test
+  void testBulkCheckoutPartialSuccess() throws BookException {
+    library.checkoutBook(book1);
+    Book nonExistentBook = new Book("999", "Nonexistent");
+    List<Book> booksToCheckout = List.of(book1, book2, nonExistentBook);
+    BulkCheckoutResult result = library.checkoutBooks(booksToCheckout);
+    assertFalse(result.isCompletelySuccessful());
+    assertEquals(1, result.successfulCheckouts().size());
+    assertEquals(2, result.failedCheckouts().size());
+    assertInstanceOf(BookUnavailableException.class, result.failedCheckouts().get(0));
+    assertInstanceOf(BookNotFoundException.class, result.failedCheckouts().get(1));
+    assertEquals(book1,result.failedCheckouts().get(0).book());
+    assertEquals(nonExistentBook,result.failedCheckouts().get(1).book());
+  }
+
+  @Test
+  void testBulkCheckoutAllSuccess() {
+    List<Book> booksToCheckout = List.of(book1, book2);
+    BulkCheckoutResult result = library.checkoutBooks(booksToCheckout);
+
+    assertTrue(result.isCompletelySuccessful());
+    assertEquals(2, result.successfulCheckouts().size());
+    assertTrue(result.failedCheckouts().isEmpty());
+  }
+}
-- 
GitLab