From 3909bde6ad93e5b02ffcf21446fc4d7aaab79d7f Mon Sep 17 00:00:00 2001 From: Angular2guy Date: Fri, 6 Sep 2024 14:13:59 +0200 Subject: [PATCH] feat: add mapper --- .../controller/DocumentController.java | 22 ++++++------- .../dto/{Chapter.java => ChapterPages.java} | 2 +- .../xxx/aidoclibchat/domain/utils/Utils.java | 31 +++++++++++++++++++ .../usecase/mapping/BookMapper.java | 29 +++++++++++++++++ .../usecase/mapping/DocumentMapper.java | 16 ++-------- .../usecase/service/DocumentService.java | 22 ++++++++----- 6 files changed, 86 insertions(+), 36 deletions(-) rename backend/src/main/java/ch/xxx/aidoclibchat/domain/model/dto/{Chapter.java => ChapterPages.java} (91%) create mode 100644 backend/src/main/java/ch/xxx/aidoclibchat/domain/utils/Utils.java create mode 100644 backend/src/main/java/ch/xxx/aidoclibchat/usecase/mapping/BookMapper.java diff --git a/backend/src/main/java/ch/xxx/aidoclibchat/adapter/controller/DocumentController.java b/backend/src/main/java/ch/xxx/aidoclibchat/adapter/controller/DocumentController.java index 7996463..29a07c5 100644 --- a/backend/src/main/java/ch/xxx/aidoclibchat/adapter/controller/DocumentController.java +++ b/backend/src/main/java/ch/xxx/aidoclibchat/adapter/controller/DocumentController.java @@ -27,10 +27,12 @@ import org.springframework.web.multipart.MultipartFile; import ch.xxx.aidoclibchat.domain.common.MetaData.DocumentType; -import ch.xxx.aidoclibchat.domain.model.dto.Chapter; +import ch.xxx.aidoclibchat.domain.model.dto.ChapterPages; import ch.xxx.aidoclibchat.domain.model.dto.DocumentDto; import ch.xxx.aidoclibchat.domain.model.dto.DocumentSearchDto; import ch.xxx.aidoclibchat.domain.model.dto.SearchDto; +import ch.xxx.aidoclibchat.domain.utils.Utils; +import ch.xxx.aidoclibchat.usecase.mapping.BookMapper; import ch.xxx.aidoclibchat.usecase.mapping.DocumentMapper; import ch.xxx.aidoclibchat.usecase.service.DocumentService; @@ -39,10 +41,12 @@ public class DocumentController { private final DocumentMapper documentMapper; private final DocumentService documentService; + private final BookMapper bookMapper; - public DocumentController(DocumentMapper documentMapper, DocumentService documentService) { + public DocumentController(DocumentMapper documentMapper, DocumentService documentService, BookMapper bookMapper) { this.documentMapper = documentMapper; this.documentService = documentService; + this.bookMapper = bookMapper; } @PostMapping("/upload") @@ -52,8 +56,8 @@ public long handleDocumentUpload(@RequestParam("file") MultipartFile document) { } @PostMapping("/upload-book") - public String handleBookUpload(@RequestParam("file") MultipartFile document, @RequestParam("chapters") List chapters) { - var result = this.documentService.summarizeBook(this.documentMapper.toEntity(document), List.of()); + public String handleBookUpload(@RequestParam("file") MultipartFile document, @RequestParam("chapters") List chapters) { + var result = this.documentService.summarizeBook(this.bookMapper.toEntity(document), chapters); return result; } @@ -80,15 +84,7 @@ public ResponseEntity getDocumentContent(@PathVariable("id") Long id) { } private ResponseEntity toResultEntity(DocumentDto documentDto) { - var contentType = switch (documentDto.getDocumentType()) { - case DocumentType.PDF -> MediaType.APPLICATION_PDF; - case DocumentType.HTML -> MediaType.TEXT_HTML; - case DocumentType.TEXT -> MediaType.TEXT_PLAIN; - case DocumentType.XML -> MediaType.APPLICATION_XML; - case DocumentType.EPUB -> new MediaType("application", "epub+zip"); - default -> MediaType.ALL; - }; - return ResponseEntity.ok().contentType(contentType).body(documentDto.getDocumentContent()); + return ResponseEntity.ok().contentType(Utils.toMediaType(documentDto.getDocumentType())).body(documentDto.getDocumentContent()); } @PostMapping("/search") diff --git a/backend/src/main/java/ch/xxx/aidoclibchat/domain/model/dto/Chapter.java b/backend/src/main/java/ch/xxx/aidoclibchat/domain/model/dto/ChapterPages.java similarity index 91% rename from backend/src/main/java/ch/xxx/aidoclibchat/domain/model/dto/Chapter.java rename to backend/src/main/java/ch/xxx/aidoclibchat/domain/model/dto/ChapterPages.java index 293a3ef..581c3dc 100644 --- a/backend/src/main/java/ch/xxx/aidoclibchat/domain/model/dto/Chapter.java +++ b/backend/src/main/java/ch/xxx/aidoclibchat/domain/model/dto/ChapterPages.java @@ -12,4 +12,4 @@ */ package ch.xxx.aidoclibchat.domain.model.dto; -public record Chapter(int startPage, int endPage) { } +public record ChapterPages(int startPage, int endPage) { } diff --git a/backend/src/main/java/ch/xxx/aidoclibchat/domain/utils/Utils.java b/backend/src/main/java/ch/xxx/aidoclibchat/domain/utils/Utils.java new file mode 100644 index 0000000..cca200d --- /dev/null +++ b/backend/src/main/java/ch/xxx/aidoclibchat/domain/utils/Utils.java @@ -0,0 +1,31 @@ +package ch.xxx.aidoclibchat.domain.utils; + +import org.springframework.http.MediaType; + +import ch.xxx.aidoclibchat.domain.common.MetaData.DocumentType; + +public class Utils { + public static DocumentType toDocumentType(String mediaType) { + var result = switch (mediaType) { + case MediaType.APPLICATION_PDF_VALUE -> DocumentType.PDF; + case MediaType.TEXT_HTML_VALUE -> DocumentType.HTML; + case MediaType.TEXT_PLAIN_VALUE -> DocumentType.TEXT; + case MediaType.APPLICATION_XML_VALUE -> DocumentType.XML; + case MediaType.TEXT_XML_VALUE -> DocumentType.XML; + default -> DocumentType.UNKNOWN; + }; + return result; + } + + public static MediaType toMediaType(DocumentType documentType) { + var contentType = switch (documentType) { + case DocumentType.PDF -> MediaType.APPLICATION_PDF; + case DocumentType.HTML -> MediaType.TEXT_HTML; + case DocumentType.TEXT -> MediaType.TEXT_PLAIN; + case DocumentType.XML -> MediaType.APPLICATION_XML; + case DocumentType.EPUB -> new MediaType("application", "epub+zip"); + default -> MediaType.ALL; + }; + return contentType; + } +} diff --git a/backend/src/main/java/ch/xxx/aidoclibchat/usecase/mapping/BookMapper.java b/backend/src/main/java/ch/xxx/aidoclibchat/usecase/mapping/BookMapper.java new file mode 100644 index 0000000..d1fc38f --- /dev/null +++ b/backend/src/main/java/ch/xxx/aidoclibchat/usecase/mapping/BookMapper.java @@ -0,0 +1,29 @@ +package ch.xxx.aidoclibchat.usecase.mapping; + +import java.io.IOException; +import java.util.Optional; + +import org.springframework.stereotype.Component; +import org.springframework.web.multipart.MultipartFile; + +import ch.xxx.aidoclibchat.domain.common.MetaData.DocumentType; +import ch.xxx.aidoclibchat.domain.exceptions.DocumentException; +import ch.xxx.aidoclibchat.domain.model.entity.Book; +import ch.xxx.aidoclibchat.domain.utils.Utils; + +@Component +public class BookMapper { + + public Book toEntity(MultipartFile multipartFile) { + var entity = new Book(); + try { + entity.setBookFile(multipartFile.getBytes()); + entity.setTitle(multipartFile.getOriginalFilename()); + entity.setDocumentType(Optional.ofNullable(multipartFile.getContentType()).stream() + .map(Utils::toDocumentType).findFirst().orElse(DocumentType.UNKNOWN)); + } catch (IOException e) { + throw new DocumentException("IOException", e); + } + return entity; + } +} diff --git a/backend/src/main/java/ch/xxx/aidoclibchat/usecase/mapping/DocumentMapper.java b/backend/src/main/java/ch/xxx/aidoclibchat/usecase/mapping/DocumentMapper.java index 3776fe3..dd53fd5 100644 --- a/backend/src/main/java/ch/xxx/aidoclibchat/usecase/mapping/DocumentMapper.java +++ b/backend/src/main/java/ch/xxx/aidoclibchat/usecase/mapping/DocumentMapper.java @@ -15,7 +15,6 @@ import java.io.IOException; import java.util.Optional; -import org.springframework.http.MediaType; import org.springframework.stereotype.Component; import org.springframework.web.multipart.MultipartFile; @@ -25,6 +24,7 @@ import ch.xxx.aidoclibchat.domain.model.dto.DocumentDto; import ch.xxx.aidoclibchat.domain.model.dto.DocumentSearchDto; import ch.xxx.aidoclibchat.domain.model.entity.Document; +import ch.xxx.aidoclibchat.domain.utils.Utils; @Component public class DocumentMapper { @@ -35,25 +35,13 @@ public Document toEntity(MultipartFile multipartFile) { entity.setDocumentContent(multipartFile.getBytes()); entity.setDocumentName(multipartFile.getOriginalFilename()); entity.setDocumentType(Optional.ofNullable(multipartFile.getContentType()).stream() - .map(this::toDocumentType).findFirst().orElse(DocumentType.UNKNOWN)); + .map(Utils::toDocumentType).findFirst().orElse(DocumentType.UNKNOWN)); } catch (IOException e) { throw new DocumentException("IOException", e); } return entity; } - private DocumentType toDocumentType(String myContentType) { - var result = switch (myContentType) { - case MediaType.APPLICATION_PDF_VALUE -> DocumentType.PDF; - case MediaType.TEXT_HTML_VALUE -> DocumentType.HTML; - case MediaType.TEXT_PLAIN_VALUE -> DocumentType.TEXT; - case MediaType.APPLICATION_XML_VALUE -> DocumentType.XML; - case MediaType.TEXT_XML_VALUE -> DocumentType.XML; - default -> DocumentType.UNKNOWN; - }; - return result; - } - public Document toEntity(DocumentDto dto) { var entity = new Document(); entity.setDocumentContent(dto.getDocumentContent()); diff --git a/backend/src/main/java/ch/xxx/aidoclibchat/usecase/service/DocumentService.java b/backend/src/main/java/ch/xxx/aidoclibchat/usecase/service/DocumentService.java index 9c60032..9e0de4e 100644 --- a/backend/src/main/java/ch/xxx/aidoclibchat/usecase/service/DocumentService.java +++ b/backend/src/main/java/ch/xxx/aidoclibchat/usecase/service/DocumentService.java @@ -38,8 +38,10 @@ import ch.xxx.aidoclibchat.domain.common.MetaData; import ch.xxx.aidoclibchat.domain.common.MetaData.DataType; import ch.xxx.aidoclibchat.domain.model.dto.AiDocumentResult; -import ch.xxx.aidoclibchat.domain.model.dto.Chapter; +import ch.xxx.aidoclibchat.domain.model.dto.ChapterPages; import ch.xxx.aidoclibchat.domain.model.dto.SearchDto; +import ch.xxx.aidoclibchat.domain.model.entity.Book; +import ch.xxx.aidoclibchat.domain.model.entity.BookRepository; import ch.xxx.aidoclibchat.domain.model.entity.Document; import ch.xxx.aidoclibchat.domain.model.entity.DocumentRepository; import ch.xxx.aidoclibchat.domain.model.entity.DocumentVsRepository; @@ -52,6 +54,7 @@ public class DocumentService { private static final Logger LOGGER = LoggerFactory.getLogger(DocumentService.class); private final DocumentRepository documentRepository; private final DocumentVsRepository documentVsRepository; + private final BookRepository bookRepository; private final ChatClient chatClient; private final String systemPrompt = """ You're assisting with questions about documents in a catalog.\n @@ -73,10 +76,11 @@ public class DocumentService { private String activeProfile; public DocumentService(DocumentRepository documentRepository, DocumentVsRepository documentVsRepository, - ChatClient chatClient) { + ChatClient chatClient, BookRepository bookRepository) { this.documentRepository = documentRepository; this.documentVsRepository = documentVsRepository; this.chatClient = chatClient; + this.bookRepository = bookRepository; } @PostConstruct @@ -84,12 +88,14 @@ public void init() { LOGGER.info("Profile: {}", this.activeProfile); } - public String summarizeBook(Document document, List chapters) { - var tikaDocuments = new TikaDocumentReader(new ByteArrayResource(document.getDocumentContent())).get(); - var strChapters = chapters.stream() - .flatMap(myChapter -> tikaDocuments.stream().skip(myChapter.startPage()).limit(myChapter.endPage())) - .map(myDocument -> myDocument.getContent()).toList(); - LOGGER.info(strChapters.getLast()); + public String summarizeBook(Book book, List chapters) { + var tikaDocuments = new TikaDocumentReader(new ByteArrayResource(book.getBookFile())).get(); + var myChapters = chapters.stream() + .flatMap(myChapter -> tikaDocuments.stream().skip(myChapter.startPage()).limit(myChapter.endPage())).toList(); + LOGGER.info(myChapters.getLast().getContent()); + + //book.setSummary(""); + this.bookRepository.save(book); return ""; }