refactor(services): update BookFileProcessor to use BookFileType for processor retrieval

This commit is contained in:
Alexander Puzynia
2025-07-21 20:03:33 -07:00
committed by Aditya Chandel
parent 3f23e4a3eb
commit f4207cf9b3
10 changed files with 42 additions and 56 deletions

View File

@@ -167,10 +167,7 @@ public class BookDropService {
.fileName(fileName)
.build();
BookFileExtension extension = BookFileExtension.fromFileName(fileName)
.orElseThrow(() -> ApiError.INVALID_FILE_FORMAT.createException("Unsupported file extension"));
BookFileProcessor processor = processorRegistry.getProcessorOrThrow(extension);
BookFileProcessor processor = processorRegistry.getProcessorOrThrow(type);
return processor.processFile(libraryFile);
}

View File

@@ -3,12 +3,12 @@ package com.adityachandel.booklore.service.fileprocessor;
import com.adityachandel.booklore.model.dto.Book;
import com.adityachandel.booklore.model.dto.settings.LibraryFile;
import com.adityachandel.booklore.model.entity.BookEntity;
import com.adityachandel.booklore.model.enums.BookFileExtension;
import com.adityachandel.booklore.model.enums.BookFileType;
import java.util.List;
public interface BookFileProcessor {
List<BookFileExtension> getSupportedExtensions();
List<BookFileType> getSupportedTypes();
Book processFile(LibraryFile libraryFile);
boolean generateCover(BookEntity bookEntity);
}

View File

@@ -1,6 +1,6 @@
package com.adityachandel.booklore.service.fileprocessor;
import com.adityachandel.booklore.model.enums.BookFileExtension;
import com.adityachandel.booklore.model.enums.BookFileType;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
@@ -13,32 +13,32 @@ import java.util.Optional;
@Slf4j
public class BookFileProcessorRegistry {
private final Map<BookFileExtension, BookFileProcessor> processorMap;
private final Map<BookFileType, BookFileProcessor> processorMap;
public BookFileProcessorRegistry(List<BookFileProcessor> processors) {
this.processorMap = new EnumMap<>(BookFileExtension.class);
this.processorMap = new EnumMap<>(BookFileType.class);
initializeProcessorMap(processors);
}
private void initializeProcessorMap(List<BookFileProcessor> processors) {
for (BookFileProcessor processor : processors) {
List<BookFileExtension> supportedExtensions = processor.getSupportedExtensions();
for (BookFileExtension extension : supportedExtensions) {
processorMap.put(extension, processor);
log.debug("Registered {} for extension: {}", processor.getClass().getSimpleName(), extension);
List<BookFileType> supportedTypes = processor.getSupportedTypes();
for (BookFileType type : supportedTypes) {
processorMap.put(type, processor);
log.debug("Registered {} for type: {}", processor.getClass().getSimpleName(), type);
}
}
log.info("Initialized BookFileProcessorRegistry with {} processors for {} extensions",
log.info("Initialized BookFileProcessorRegistry with {} processors for {} types",
processors.size(), processorMap.size());
}
public Optional<BookFileProcessor> getProcessor(BookFileExtension extension) {
return Optional.ofNullable(processorMap.get(extension));
public Optional<BookFileProcessor> getProcessor(BookFileType type) {
return Optional.ofNullable(processorMap.get(type));
}
public BookFileProcessor getProcessorOrThrow(BookFileExtension extension) {
return getProcessor(extension)
public BookFileProcessor getProcessorOrThrow(BookFileType type) {
return getProcessor(type)
.orElseThrow(() -> new IllegalArgumentException(
"No processor found for file extension: " + extension));
"No processor found for file type: " + type));
}
}

View File

@@ -1,10 +1,8 @@
package com.adityachandel.booklore.service.fileprocessor;
import com.adityachandel.booklore.mapper.BookMapper;
import com.adityachandel.booklore.model.dto.Book;
import com.adityachandel.booklore.model.dto.settings.LibraryFile;
import com.adityachandel.booklore.model.entity.BookEntity;
import com.adityachandel.booklore.model.enums.BookFileExtension;
import com.adityachandel.booklore.model.enums.BookFileType;
import com.adityachandel.booklore.repository.BookMetadataRepository;
import com.adityachandel.booklore.repository.BookRepository;
@@ -72,8 +70,8 @@ public class CbxProcessor extends AbstractFileProcessor implements BookFileProce
}
@Override
public List<BookFileExtension> getSupportedExtensions() {
return List.of(BookFileExtension.CBZ, BookFileExtension.CBR, BookFileExtension.CB7);
public List<BookFileType> getSupportedTypes() {
return List.of(BookFileType.CBX);
}
private Optional<BufferedImage> extractImagesFromArchive(File file) {

View File

@@ -5,7 +5,6 @@ import com.adityachandel.booklore.model.dto.BookMetadata;
import com.adityachandel.booklore.model.dto.settings.LibraryFile;
import com.adityachandel.booklore.model.entity.BookEntity;
import com.adityachandel.booklore.model.entity.BookMetadataEntity;
import com.adityachandel.booklore.model.enums.BookFileExtension;
import com.adityachandel.booklore.model.enums.BookFileType;
import com.adityachandel.booklore.repository.BookMetadataRepository;
import com.adityachandel.booklore.repository.BookRepository;
@@ -95,8 +94,8 @@ public class EpubProcessor extends AbstractFileProcessor implements BookFileProc
}
@Override
public List<BookFileExtension> getSupportedExtensions() {
return List.of(BookFileExtension.EPUB);
public List<BookFileType> getSupportedTypes() {
return List.of(BookFileType.EPUB);
}
private void setBookMetadata(BookEntity bookEntity) {

View File

@@ -4,7 +4,6 @@ import com.adityachandel.booklore.mapper.BookMapper;
import com.adityachandel.booklore.model.dto.BookMetadata;
import com.adityachandel.booklore.model.dto.settings.LibraryFile;
import com.adityachandel.booklore.model.entity.BookEntity;
import com.adityachandel.booklore.model.enums.BookFileExtension;
import com.adityachandel.booklore.model.enums.BookFileType;
import com.adityachandel.booklore.repository.BookMetadataRepository;
import com.adityachandel.booklore.repository.BookRepository;
@@ -71,8 +70,8 @@ public class PdfProcessor extends AbstractFileProcessor implements BookFileProce
}
@Override
public List<BookFileExtension> getSupportedExtensions() {
return List.of(BookFileExtension.PDF);
public List<BookFileType> getSupportedTypes() {
return List.of(BookFileType.PDF);
}
private void extractAndSetMetadata(BookEntity bookEntity) {

View File

@@ -4,6 +4,7 @@ import com.adityachandel.booklore.model.dto.Book;
import com.adityachandel.booklore.model.dto.settings.LibraryFile;
import com.adityachandel.booklore.model.entity.LibraryEntity;
import com.adityachandel.booklore.model.enums.BookFileExtension;
import com.adityachandel.booklore.model.enums.BookFileType;
import com.adityachandel.booklore.model.websocket.Topic;
import com.adityachandel.booklore.service.NotificationService;
import com.adityachandel.booklore.service.fileprocessor.BookFileProcessor;
@@ -41,13 +42,13 @@ public class FileAsBookProcessor implements LibraryFileProcessor {
@Transactional
protected Book processLibraryFile(LibraryFile libraryFile) {
BookFileExtension extension = BookFileExtension.fromFileName(libraryFile.getFileName()).orElse(null);
if (extension == null) {
BookFileType type = libraryFile.getBookFileType();
if (type == null) {
log.warn("Unsupported file type for file: {}", libraryFile.getFileName());
return null;
}
BookFileProcessor processor = processorRegistry.getProcessorOrThrow(extension);
BookFileProcessor processor = processorRegistry.getProcessorOrThrow(type);
return processor.processFile(libraryFile);
}

View File

@@ -194,11 +194,8 @@ public class BookMetadataService {
String title = book.getMetadata().getTitle();
String message = progress + "Regenerating cover for: " + title;
notificationService.sendMessage(Topic.LOG, createLogNotification(message));
BookFileExtension extension = BookFileExtension.fromFileName(book.getFileName())
.orElseThrow(() -> ApiError.UNSUPPORTED_BOOK_TYPE.createException(book.getBookType()));
BookFileProcessor processor = processorRegistry.getProcessorOrThrow(extension);
BookFileProcessor processor = processorRegistry.getProcessorOrThrow(book.getBookType());
processor.generateCover(book);
log.info("{}Successfully regenerated cover for book ID {} ({})", progress, book.getId(), title);

View File

@@ -81,7 +81,7 @@ public class FileUploadService {
try {
file.transferTo(tempPath);
setTemporaryFileOwnership(tempPath);
BookFileExtension fileExt = BookFileExtension.fromFileName(file.getOriginalFilename()).orElseThrow(() -> ApiError.INVALID_FILE_FORMAT.createException("Unsupported file extension"));
@@ -164,21 +164,18 @@ public class FileUploadService {
}
}
private Book processFile(String fileName, LibraryEntity libraryEntity, LibraryPathEntity libraryPathEntity, File storageFile, BookFileType fileType) {
private Book processFile(String fileName, LibraryEntity libraryEntity, LibraryPathEntity libraryPathEntity, File storageFile, BookFileType type) {
String subPath = FileUtils.getRelativeSubPath(libraryPathEntity.getPath(), storageFile.toPath());
LibraryFile libraryFile = LibraryFile.builder()
.libraryEntity(libraryEntity)
.libraryPathEntity(libraryPathEntity)
.fileSubPath(subPath)
.bookFileType(fileType)
.bookFileType(type)
.fileName(fileName)
.build();
BookFileExtension extension = BookFileExtension.fromFileName(fileName)
.orElseThrow(() -> ApiError.INVALID_FILE_FORMAT.createException("Unsupported file extension"));
BookFileProcessor processor = processorRegistry.getProcessorOrThrow(extension);
BookFileProcessor processor = processorRegistry.getProcessorOrThrow(type);
return processor.processFile(libraryFile);
}

View File

@@ -4,7 +4,6 @@ import com.adityachandel.booklore.model.dto.Book;
import com.adityachandel.booklore.model.dto.settings.LibraryFile;
import com.adityachandel.booklore.model.entity.LibraryEntity;
import com.adityachandel.booklore.model.entity.LibraryPathEntity;
import com.adityachandel.booklore.model.enums.BookFileExtension;
import com.adityachandel.booklore.model.enums.BookFileType;
import com.adityachandel.booklore.model.websocket.LogNotification;
import com.adityachandel.booklore.model.websocket.Topic;
@@ -94,8 +93,8 @@ class FileAsBookProcessorTest {
.bookType(BookFileType.PDF)
.build();
when(processorRegistry.getProcessorOrThrow(BookFileExtension.EPUB)).thenReturn(bookFileProcessor);
when(processorRegistry.getProcessorOrThrow(BookFileExtension.PDF)).thenReturn(bookFileProcessor);
when(processorRegistry.getProcessorOrThrow(BookFileType.EPUB)).thenReturn(bookFileProcessor);
when(processorRegistry.getProcessorOrThrow(BookFileType.PDF)).thenReturn(bookFileProcessor);
when(bookFileProcessor.processFile(file1)).thenReturn(book1);
when(bookFileProcessor.processFile(file2)).thenReturn(book2);
@@ -144,7 +143,7 @@ class FileAsBookProcessorTest {
.bookType(BookFileType.EPUB)
.build();
when(processorRegistry.getProcessorOrThrow(BookFileExtension.EPUB)).thenReturn(bookFileProcessor);
when(processorRegistry.getProcessorOrThrow(BookFileType.EPUB)).thenReturn(bookFileProcessor);
when(bookFileProcessor.processFile(validFile)).thenReturn(book);
// When
@@ -214,7 +213,7 @@ class FileAsBookProcessorTest {
.bookType(BookFileType.EPUB)
.build();
when(processorRegistry.getProcessorOrThrow(BookFileExtension.EPUB)).thenReturn(bookFileProcessor);
when(processorRegistry.getProcessorOrThrow(BookFileType.EPUB)).thenReturn(bookFileProcessor);
when(bookFileProcessor.processFile(libraryFile)).thenReturn(expectedBook);
// When
@@ -222,7 +221,7 @@ class FileAsBookProcessorTest {
// Then
assertThat(result).isEqualTo(expectedBook);
verify(processorRegistry).getProcessorOrThrow(BookFileExtension.EPUB);
verify(processorRegistry).getProcessorOrThrow(BookFileType.EPUB);
verify(bookFileProcessor).processFile(libraryFile);
}
@@ -241,7 +240,7 @@ class FileAsBookProcessorTest {
.bookFileType(BookFileType.PDF)
.build();
when(processorRegistry.getProcessorOrThrow(BookFileExtension.PDF)).thenReturn(bookFileProcessor);
when(processorRegistry.getProcessorOrThrow(BookFileType.PDF)).thenReturn(bookFileProcessor);
when(bookFileProcessor.processFile(libraryFile)).thenReturn(null);
// When
@@ -269,7 +268,7 @@ class FileAsBookProcessorTest {
libraryFiles.add(file);
when(processorRegistry.getProcessorOrThrow(BookFileExtension.EPUB)).thenReturn(bookFileProcessor);
when(processorRegistry.getProcessorOrThrow(BookFileType.EPUB)).thenReturn(bookFileProcessor);
when(bookFileProcessor.processFile(file)).thenReturn(null);
// When
@@ -344,11 +343,10 @@ class FileAsBookProcessorTest {
.bookType(BookFileType.CBX)
.build();
when(processorRegistry.getProcessorOrThrow(BookFileExtension.EPUB)).thenReturn(bookFileProcessor);
when(processorRegistry.getProcessorOrThrow(BookFileExtension.PDF)).thenReturn(bookFileProcessor);
when(processorRegistry.getProcessorOrThrow(BookFileExtension.CBZ)).thenReturn(bookFileProcessor);
when(processorRegistry.getProcessorOrThrow(BookFileExtension.CBR)).thenReturn(bookFileProcessor);
when(processorRegistry.getProcessorOrThrow(BookFileType.EPUB)).thenReturn(bookFileProcessor);
when(processorRegistry.getProcessorOrThrow(BookFileType.PDF)).thenReturn(bookFileProcessor);
when(processorRegistry.getProcessorOrThrow(BookFileType.CBX)).thenReturn(bookFileProcessor);
when(bookFileProcessor.processFile(epubFile)).thenReturn(epubBook);
when(bookFileProcessor.processFile(pdfFile)).thenReturn(pdfBook);
when(bookFileProcessor.processFile(cbzFile)).thenReturn(cbzBook);