This commit is contained in:
2026-04-12 00:24:27 +02:00
parent c7fd2e8311
commit 247a28dcf0
7 changed files with 275 additions and 0 deletions
@@ -0,0 +1,42 @@
package fr.iut_fbleau.but3.dev62.mylibrary.book.converter;
import fr.iut_fbleau.but3.dev62.mylibrary.book.BookDTO;
import fr.iut_fbleau.but3.dev62.mylibrary.book.BookInfo;
import fr.iut_fbleau.but3.dev62.mylibrary.book.entity.Book;
public final class BookConverter {
private BookConverter() {
}
public static Book toDomain(BookInfo bookInfo) {
return Book.builder()
.isbn(bookInfo.isbn())
.title(bookInfo.title())
.author(bookInfo.author())
.publisher(bookInfo.publisher())
.publicationDate(bookInfo.publicationDate())
.price(bookInfo.price())
.stock(bookInfo.initialStock())
.categories(bookInfo.categories())
.description(bookInfo.description())
.language(bookInfo.language())
.build();
}
public static BookDTO toDTO(Book book) {
return BookDTO.builder()
.id(book.getId())
.isbn(book.getIsbn())
.title(book.getTitle())
.author(book.getAuthor())
.publisher(book.getPublisher())
.publicationDate(book.getPublicationDate())
.price(book.getPrice())
.stock(book.getStock())
.categories(book.getCategories())
.description(book.getDescription())
.language(book.getLanguage())
.build();
}
}
@@ -0,0 +1,30 @@
package fr.iut_fbleau.but3.dev62.mylibrary.book.entity;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.util.List;
import java.util.UUID;
import lombok.Builder;
import lombok.Getter;
@Builder
@Getter
public class Book {
private UUID id;
private String isbn;
private String title;
private String author;
private String publisher;
private LocalDate publicationDate;
private BigDecimal price;
private int stock;
private List<String> categories;
private String description;
private String language;
public void setRandomUUID() {
this.id = UUID.randomUUID();
}
}
@@ -0,0 +1,14 @@
package fr.iut_fbleau.but3.dev62.mylibrary.book.exception;
import java.text.MessageFormat;
import java.util.UUID;
public class BookNotFoundException extends Exception {
public static final String THE_BOOK_WITH_ID_DOES_NOT_EXIST_MESSAGE = "The book with id {0} does not exist";
public BookNotFoundException(UUID uuid) {
super(MessageFormat.format(THE_BOOK_WITH_ID_DOES_NOT_EXIST_MESSAGE, uuid));
}
}
@@ -0,0 +1,9 @@
package fr.iut_fbleau.but3.dev62.mylibrary.book.exception;
public class NotValidBookException extends Exception {
public NotValidBookException(String message) {
super(message);
}
}
@@ -0,0 +1,54 @@
package fr.iut_fbleau.but3.dev62.mylibrary.book.repository;
import fr.iut_fbleau.but3.dev62.mylibrary.book.entity.Book;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.UUID;
import lombok.NoArgsConstructor;
@NoArgsConstructor
public final class BookRepository {
private final List<Book> books = new ArrayList<>();
public List<Book> findAll() {
return books;
}
public void deleteAll() {
books.clear();
}
public Book save(Book newBook) {
if (newBook.getId() == null) {
newBook.setRandomUUID();
}
Optional<Book> optionalBookWithSameId = this.findById(newBook.getId());
optionalBookWithSameId.ifPresent(books::remove);
this.books.add(newBook);
return newBook;
}
public Optional<Book> findById(UUID uuid) {
return this.books.stream()
.filter(book -> book.getId().equals(uuid))
.findFirst();
}
public boolean existsById(UUID uuid) {
return this.books.stream()
.anyMatch(book -> book.getId().equals(uuid));
}
public Optional<Book> findByIsbn(String isbn) {
return this.books.stream()
.filter(book -> book.getIsbn().equals(isbn))
.findFirst();
}
public void delete(Book book) {
this.books.remove(book);
}
}
@@ -0,0 +1,67 @@
package fr.iut_fbleau.but3.dev62.mylibrary.book.usecase;
import fr.iut_fbleau.but3.dev62.mylibrary.book.BookDTO;
import fr.iut_fbleau.but3.dev62.mylibrary.book.BookInfo;
import fr.iut_fbleau.but3.dev62.mylibrary.book.converter.BookConverter;
import fr.iut_fbleau.but3.dev62.mylibrary.book.entity.Book;
import fr.iut_fbleau.but3.dev62.mylibrary.book.exception.BookNotFoundException;
import fr.iut_fbleau.but3.dev62.mylibrary.book.exception.NotValidBookException;
import fr.iut_fbleau.but3.dev62.mylibrary.book.repository.BookRepository;
import fr.iut_fbleau.but3.dev62.mylibrary.book.validator.BookValidator;
import java.util.Optional;
import java.util.UUID;
public final class BookUseCase {
private final BookRepository bookRepository;
public BookUseCase(BookRepository bookRepository) {
this.bookRepository = bookRepository;
}
public String registerBook(BookInfo bookInfo) throws NotValidBookException {
BookValidator.validate(bookInfo);
Book bookToRegister = BookConverter.toDomain(bookInfo);
Book registeredBook = bookRepository.save(bookToRegister);
return registeredBook.getIsbn();
}
public Optional<BookDTO> findBookByIsbn(String isbn) {
Optional<Book> optionalBook = bookRepository.findByIsbn(isbn);
return optionalBook.map(BookConverter::toDTO);
}
public BookDTO updateBook(UUID uuid, BookInfo bookInfo) throws BookNotFoundException, NotValidBookException {
BookValidator.validate(bookInfo);
Book existingBook = getBookIfNotFoundThrowException(uuid);
Book updatedBook = Book.builder()
.id(uuid)
.isbn(bookInfo.isbn())
.title(bookInfo.title())
.author(bookInfo.author())
.publisher(bookInfo.publisher())
.publicationDate(bookInfo.publicationDate())
.price(bookInfo.price())
.stock(existingBook.getStock())
.categories(bookInfo.categories())
.description(bookInfo.description())
.language(bookInfo.language())
.build();
Book saved = bookRepository.save(updatedBook);
return BookConverter.toDTO(saved);
}
public void deleteBook(UUID uuid) throws BookNotFoundException {
Book bookToDelete = getBookIfNotFoundThrowException(uuid);
bookRepository.delete(bookToDelete);
}
private Book getBookIfNotFoundThrowException(UUID uuid) throws BookNotFoundException {
Optional<Book> optionalBook = bookRepository.findById(uuid);
if (optionalBook.isEmpty()) {
throw new BookNotFoundException(uuid);
}
return optionalBook.get();
}
}
@@ -0,0 +1,59 @@
package fr.iut_fbleau.but3.dev62.mylibrary.book.validator;
import fr.iut_fbleau.but3.dev62.mylibrary.book.BookInfo;
import fr.iut_fbleau.but3.dev62.mylibrary.book.exception.NotValidBookException;
import java.math.BigDecimal;
public final class BookValidator {
public static final String ISBN_IS_NOT_VALID = "ISBN is not valid";
public static final String PRICE_MUST_BE_POSITIVE = "Price must be positive";
public static final String TITLE_CANNOT_BE_BLANK = "Title cannot be blank";
public static final String AUTHOR_CANNOT_BE_BLANK = "Author cannot be blank";
public static final String PUBLISHER_CANNOT_BE_BLANK = "Publisher cannot be blank";
public static final String ISBN_REGEX = "\\d{13}";
private BookValidator() {
}
public static void validate(BookInfo bookInfo) throws NotValidBookException {
validateIsbn(bookInfo);
validateTitle(bookInfo);
validateAuthor(bookInfo);
validatePublisher(bookInfo);
validatePrice(bookInfo);
}
private static void validateIsbn(BookInfo bookInfo) throws NotValidBookException {
if (bookInfo.isbn() == null || bookInfo.isbn().isBlank()) {
throw new NotValidBookException(ISBN_IS_NOT_VALID);
}
if (!bookInfo.isbn().matches(ISBN_REGEX)) {
throw new NotValidBookException(ISBN_IS_NOT_VALID);
}
}
private static void validateTitle(BookInfo bookInfo) throws NotValidBookException {
if (bookInfo.title() == null || bookInfo.title().isBlank()) {
throw new NotValidBookException(TITLE_CANNOT_BE_BLANK);
}
}
private static void validateAuthor(BookInfo bookInfo) throws NotValidBookException {
if (bookInfo.author() == null || bookInfo.author().isBlank()) {
throw new NotValidBookException(AUTHOR_CANNOT_BE_BLANK);
}
}
private static void validatePublisher(BookInfo bookInfo) throws NotValidBookException {
if (bookInfo.publisher() == null || bookInfo.publisher().isBlank()) {
throw new NotValidBookException(PUBLISHER_CANNOT_BE_BLANK);
}
}
private static void validatePrice(BookInfo bookInfo) throws NotValidBookException {
if (bookInfo.price() == null || bookInfo.price().compareTo(BigDecimal.ZERO) <= 0) {
throw new NotValidBookException(PRICE_MUST_BE_POSITIVE);
}
}
}