refactor(api): Use try-with-resources for better resource management (#1457)

- Use `try-with-resources` for better resource management in `EpubMetadataWriter` and `AppMigrationService`.
- Use a single `HttpClient` instance in `GoogleParser` to improve efficiency.

Signed-off-by: Balázs Szücs <bszucs1209@gmail.com>
This commit is contained in:
Balázs Szücs
2025-10-27 20:38:58 +01:00
committed by GitHub
parent 9e7afe6e51
commit cd0ca7ffa8
3 changed files with 59 additions and 47 deletions

View File

@@ -35,6 +35,7 @@ public class GoogleParser implements BookParser {
private static final Pattern WHITESPACE_PATTERN = Pattern.compile("\\s+");
private static final Pattern SPECIAL_CHARACTERS_PATTERN = Pattern.compile("[.,\\-\\[\\]{}()!@#$%^&*_=+|~`<>?/\";:]");
private final ObjectMapper objectMapper;
private final HttpClient httpClient = HttpClient.newHttpClient();
private static final String GOOGLE_BOOKS_API_URL = "https://www.googleapis.com/books/v1/volumes";
@Override
@@ -61,13 +62,12 @@ public class GoogleParser implements BookParser {
log.info("Google Books API URL (ISBN): {}", uri);
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
.uri(uri)
.GET()
.build();
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
HttpResponse<String> response = httpClient.send(request, HttpResponse.BodyHandlers.ofString());
if (response.statusCode() == 200) {
return parseGoogleBooksApiResponse(response.body());
@@ -91,13 +91,12 @@ public class GoogleParser implements BookParser {
log.info("Google Books API URL: {}", uri);
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
.uri(uri)
.GET()
.build();
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
HttpResponse<String> response = httpClient.send(request, HttpResponse.BodyHandlers.ofString());
if (response.statusCode() == 200) {
return parseGoogleBooksApiResponse(response.body());

View File

@@ -55,8 +55,9 @@ public class EpubMetadataWriter implements MetadataWriter {
Path tempDir = null;
try {
tempDir = Files.createTempDirectory("epub_edit_" + UUID.randomUUID());
ZipFile zipFile = new ZipFile(epubFile);
zipFile.extractAll(tempDir.toString());
try (ZipFile zipFile = new ZipFile(epubFile)) {
zipFile.extractAll(tempDir.toString());
}
File opfFile = findOpfFile(tempDir.toFile());
if (opfFile == null) {
@@ -171,7 +172,9 @@ public class EpubMetadataWriter implements MetadataWriter {
transformer.transform(new DOMSource(opfDoc), new StreamResult(opfFile));
File tempEpub = new File(epubFile.getParentFile(), epubFile.getName() + ".tmp");
addFolderContentsToZip(new ZipFile(tempEpub), tempDir.toFile(), tempDir.toFile());
try (ZipFile tempZipFile = new ZipFile(tempEpub)) {
addFolderContentsToZip(tempZipFile, tempDir.toFile(), tempDir.toFile());
}
if (!epubFile.delete()) throw new IOException("Could not delete original EPUB");
if (!tempEpub.renameTo(epubFile)) throw new IOException("Could not rename temp EPUB");
@@ -260,7 +263,9 @@ public class EpubMetadataWriter implements MetadataWriter {
try {
File epubFile = new File(bookEntity.getFullFilePath().toUri());
tempDir = Files.createTempDirectory("epub_cover_" + UUID.randomUUID());
new ZipFile(epubFile).extractAll(tempDir.toString());
try (ZipFile zipFile = new ZipFile(epubFile)) {
zipFile.extractAll(tempDir.toString());
}
File opfFile = findOpfFile(tempDir.toFile());
if (opfFile == null) {
@@ -282,7 +287,9 @@ public class EpubMetadataWriter implements MetadataWriter {
transformer.transform(new DOMSource(opfDoc), new StreamResult(opfFile));
File tempEpub = new File(epubFile.getParentFile(), epubFile.getName() + ".tmp");
addFolderContentsToZip(new ZipFile(tempEpub), tempDir.toFile(), tempDir.toFile());
try (ZipFile tempZipFile = new ZipFile(tempEpub)) {
addFolderContentsToZip(tempZipFile, tempDir.toFile(), tempDir.toFile());
}
if (!epubFile.delete()) throw new IOException("Could not delete original EPUB");
if (!tempEpub.renameTo(epubFile)) throw new IOException("Could not rename temp EPUB");
@@ -308,7 +315,9 @@ public class EpubMetadataWriter implements MetadataWriter {
try {
File epubFile = new File(bookEntity.getFullFilePath().toUri());
tempDir = Files.createTempDirectory("epub_cover_url_" + UUID.randomUUID());
new ZipFile(epubFile).extractAll(tempDir.toString());
try (ZipFile zipFile = new ZipFile(epubFile)) {
zipFile.extractAll(tempDir.toString());
}
File opfFile = findOpfFile(tempDir.toFile());
if (opfFile == null) {
@@ -335,7 +344,9 @@ public class EpubMetadataWriter implements MetadataWriter {
transformer.transform(new DOMSource(opfDoc), new StreamResult(opfFile));
File tempEpub = new File(epubFile.getParentFile(), epubFile.getName() + ".tmp");
addFolderContentsToZip(new ZipFile(tempEpub), tempDir.toFile(), tempDir.toFile());
try (ZipFile tempZipFile = new ZipFile(tempEpub)) {
addFolderContentsToZip(tempZipFile, tempDir.toFile(), tempDir.toFile());
}
if (!epubFile.delete()) throw new IOException("Could not delete original EPUB");
if (!tempEpub.renameTo(epubFile)) throw new IOException("Could not rename temp EPUB");

View File

@@ -127,46 +127,48 @@ public class AppMigrationService {
try {
if (Files.exists(thumbsDir)) {
Files.walk(thumbsDir)
.filter(Files::isRegularFile)
.forEach(path -> {
try {
// Load original image
BufferedImage originalImage = ImageIO.read(path.toFile());
if (originalImage == null) {
log.warn("Skipping non-image file: {}", path);
return;
try (var stream = Files.walk(thumbsDir)) {
stream.filter(Files::isRegularFile)
.forEach(path -> {
try {
// Load original image
BufferedImage originalImage = ImageIO.read(path.toFile());
if (originalImage == null) {
log.warn("Skipping non-image file: {}", path);
return;
}
// Extract bookId from folder structure
Path relative = thumbsDir.relativize(path); // e.g., "11/f.jpg"
String bookId = relative.getParent().toString(); // "11"
Path bookDir = imagesDir.resolve(bookId);
Files.createDirectories(bookDir);
// Copy original to cover.jpg
Path coverFile = bookDir.resolve("cover.jpg");
ImageIO.write(originalImage, "jpg", coverFile.toFile());
// Resize and save thumbnail.jpg
BufferedImage resized = fileService.resizeImage(originalImage, 250, 350);
Path thumbnailFile = bookDir.resolve("thumbnail.jpg");
ImageIO.write(resized, "jpg", thumbnailFile.toFile());
log.debug("Processed book {}: cover={} thumbnail={}", bookId, coverFile, thumbnailFile);
} catch (IOException e) {
log.error("Error processing file {}", path, e);
throw new UncheckedIOException(e);
}
// Extract bookId from folder structure
Path relative = thumbsDir.relativize(path); // e.g., "11/f.jpg"
String bookId = relative.getParent().toString(); // "11"
Path bookDir = imagesDir.resolve(bookId);
Files.createDirectories(bookDir);
// Copy original to cover.jpg
Path coverFile = bookDir.resolve("cover.jpg");
ImageIO.write(originalImage, "jpg", coverFile.toFile());
// Resize and save thumbnail.jpg
BufferedImage resized = fileService.resizeImage(originalImage, 250, 350);
Path thumbnailFile = bookDir.resolve("thumbnail.jpg");
ImageIO.write(resized, "jpg", thumbnailFile.toFile());
log.debug("Processed book {}: cover={} thumbnail={}", bookId, coverFile, thumbnailFile);
} catch (IOException e) {
log.error("Error processing file {}", path, e);
throw new UncheckedIOException(e);
}
});
});
}
// Delete old thumbs directory
log.info("Deleting old thumbs directory: {}", thumbsDir);
Files.walk(thumbsDir)
.sorted(Comparator.reverseOrder())
.map(Path::toFile)
.forEach(File::delete);
try (var stream = Files.walk(thumbsDir)) {
stream.sorted(Comparator.reverseOrder())
.map(Path::toFile)
.forEach(File::delete);
}
}
} catch (IOException e) {
log.error("Error during migration populateCoversAndResizeThumbnails", e);