auto formatting

This commit is contained in:
Anthony Stirling 2025-07-02 10:27:09 +01:00
parent e764158178
commit 0b045bc23a
22 changed files with 360 additions and 290 deletions

View File

@ -25,7 +25,6 @@ import lombok.extern.slf4j.Slf4j;
import stirling.software.common.model.api.PDFFile;
import stirling.software.common.util.ApplicationContextProvider;
import stirling.software.common.util.ExceptionUtils;
import stirling.software.common.util.PdfErrorUtils;
import stirling.software.common.util.TempFileManager;
import stirling.software.common.util.TempFileRegistry;

View File

@ -44,7 +44,6 @@ import lombok.extern.slf4j.Slf4j;
import stirling.software.common.model.api.converters.EmlToPdfRequest;
import stirling.software.common.model.api.converters.HTMLToPdfRequest;
import stirling.software.common.service.CustomPDFDocumentFactory;
import stirling.software.common.util.ExceptionUtils;
@Slf4j
@UtilityClass

View File

@ -5,8 +5,8 @@ import java.io.IOException;
import lombok.extern.slf4j.Slf4j;
/**
* Utility class for handling exceptions with internationalized error messages.
* Provides consistent error handling and user-friendly messages across the application.
* Utility class for handling exceptions with internationalized error messages. Provides consistent
* error handling and user-friendly messages across the application.
*/
@Slf4j
public class ExceptionUtils {
@ -31,16 +31,16 @@ public class ExceptionUtils {
public static IOException createPdfCorruptedException(String context, Exception cause) {
String message;
if (context != null && !context.isEmpty()) {
message = I18nUtils.getMessage(
"error.pdfCorruptedDuring",
"Error {0}: PDF file appears to be corrupted or damaged. Please try using the 'Repair PDF' feature first to fix the file before proceeding with this operation.",
context
);
message =
I18nUtils.getMessage(
"error.pdfCorruptedDuring",
"Error {0}: PDF file appears to be corrupted or damaged. Please try using the 'Repair PDF' feature first to fix the file before proceeding with this operation.",
context);
} else {
message = I18nUtils.getMessage(
"error.pdfCorrupted",
"PDF file appears to be corrupted or damaged. Please try using the 'Repair PDF' feature first to fix the file before proceeding with this operation."
);
message =
I18nUtils.getMessage(
"error.pdfCorrupted",
"PDF file appears to be corrupted or damaged. Please try using the 'Repair PDF' feature first to fix the file before proceeding with this operation.");
}
return new IOException(message, cause);
}
@ -52,10 +52,10 @@ public class ExceptionUtils {
* @return IOException with user-friendly message
*/
public static IOException createMultiplePdfCorruptedException(Exception cause) {
String message = I18nUtils.getMessage(
"error.pdfCorruptedMultiple",
"One or more PDF files appear to be corrupted or damaged. Please try using the 'Repair PDF' feature on each file first before attempting to merge them."
);
String message =
I18nUtils.getMessage(
"error.pdfCorruptedMultiple",
"One or more PDF files appear to be corrupted or damaged. Please try using the 'Repair PDF' feature on each file first before attempting to merge them.");
return new IOException(message, cause);
}
@ -66,11 +66,11 @@ public class ExceptionUtils {
* @return IOException with user-friendly message
*/
public static IOException createPdfEncryptionException(Exception cause) {
String message = I18nUtils.getMessage(
"error.pdfEncryption",
"The PDF appears to have corrupted encryption data. This can happen when the PDF was created with incompatible encryption methods. Please try using the 'Repair PDF' feature first, or contact the document creator for a new copy.",
cause.getMessage()
);
String message =
I18nUtils.getMessage(
"error.pdfEncryption",
"The PDF appears to have corrupted encryption data. This can happen when the PDF was created with incompatible encryption methods. Please try using the 'Repair PDF' feature first, or contact the document creator for a new copy.",
cause.getMessage());
return new IOException(message, cause);
}
@ -81,10 +81,10 @@ public class ExceptionUtils {
* @return IOException with user-friendly message
*/
public static IOException createPdfPasswordException(Exception cause) {
String message = I18nUtils.getMessage(
"error.pdfPassword",
"The PDF Document is passworded and either the password was not provided or was incorrect"
);
String message =
I18nUtils.getMessage(
"error.pdfPassword",
"The PDF Document is passworded and either the password was not provided or was incorrect");
return new IOException(message, cause);
}
@ -96,12 +96,12 @@ public class ExceptionUtils {
* @return IOException with user-friendly message
*/
public static IOException createFileProcessingException(String operation, Exception cause) {
String message = I18nUtils.getMessage(
"error.fileProcessing",
"An error occurred while processing the file during {0} operation: {1}",
operation,
cause.getMessage()
);
String message =
I18nUtils.getMessage(
"error.fileProcessing",
"An error occurred while processing the file during {0} operation: {1}",
operation,
cause.getMessage());
return new IOException(message, cause);
}
@ -114,7 +114,8 @@ public class ExceptionUtils {
* @param args optional arguments for the message
* @return IOException with user-friendly message
*/
public static IOException createIOException(String messageKey, String defaultMessage, Exception cause, Object... args) {
public static IOException createIOException(
String messageKey, String defaultMessage, Exception cause, Object... args) {
String message = I18nUtils.getMessage(messageKey, defaultMessage, args);
return new IOException(message, cause);
}
@ -128,7 +129,8 @@ public class ExceptionUtils {
* @param args optional arguments for the message
* @return RuntimeException with user-friendly message
*/
public static RuntimeException createRuntimeException(String messageKey, String defaultMessage, Exception cause, Object... args) {
public static RuntimeException createRuntimeException(
String messageKey, String defaultMessage, Exception cause, Object... args) {
String message = I18nUtils.getMessage(messageKey, defaultMessage, args);
return new RuntimeException(message, cause);
}
@ -141,112 +143,132 @@ public class ExceptionUtils {
* @param args optional arguments for the message
* @return IllegalArgumentException with user-friendly message
*/
public static IllegalArgumentException createIllegalArgumentException(String messageKey, String defaultMessage, Object... args) {
public static IllegalArgumentException createIllegalArgumentException(
String messageKey, String defaultMessage, Object... args) {
String message = I18nUtils.getMessage(messageKey, defaultMessage, args);
System.out.println("######## Test " + message);
return new IllegalArgumentException(message);
}
/**
* Create file validation exceptions.
*/
/** Create file validation exceptions. */
public static IllegalArgumentException createHtmlFileRequiredException() {
return createIllegalArgumentException("error.fileFormatRequired", "File must be in {0} format", "HTML or ZIP");
return createIllegalArgumentException(
"error.fileFormatRequired", "File must be in {0} format", "HTML or ZIP");
}
public static IllegalArgumentException createMarkdownFileRequiredException() {
return createIllegalArgumentException("error.fileFormatRequired", "File must be in {0} format", "Markdown");
return createIllegalArgumentException(
"error.fileFormatRequired", "File must be in {0} format", "Markdown");
}
public static IllegalArgumentException createMarkdownFormatException() {
return createIllegalArgumentException("error.fileFormatRequired", "File must be in {0} format", ".md");
return createIllegalArgumentException(
"error.fileFormatRequired", "File must be in {0} format", ".md");
}
public static IllegalArgumentException createHtmlZipFormatException() {
return createIllegalArgumentException("error.fileFormatRequired", "File must be in {0} format", ".html or .zip");
return createIllegalArgumentException(
"error.fileFormatRequired", "File must be in {0} format", ".html or .zip");
}
public static IllegalArgumentException createPdfFileRequiredException() {
return createIllegalArgumentException("error.fileFormatRequired", "File must be in {0} format", "PDF");
return createIllegalArgumentException(
"error.fileFormatRequired", "File must be in {0} format", "PDF");
}
public static IllegalArgumentException createInvalidPageSizeException(String size) {
return createIllegalArgumentException("error.invalidFormat", "Invalid {0} format: {1}", "page size", size);
return createIllegalArgumentException(
"error.invalidFormat", "Invalid {0} format: {1}", "page size", size);
}
/**
* Create OCR-related exceptions.
*/
/** Create OCR-related exceptions. */
public static IOException createOcrLanguageRequiredException() {
return createIOException("error.optionsNotSpecified", "{0} options are not specified", null, "OCR language");
return createIOException(
"error.optionsNotSpecified", "{0} options are not specified", null, "OCR language");
}
public static IOException createOcrInvalidLanguagesException() {
return createIOException("error.invalidFormat", "Invalid {0} format: {1}", null, "OCR languages", "none of the selected languages are valid");
return createIOException(
"error.invalidFormat",
"Invalid {0} format: {1}",
null,
"OCR languages",
"none of the selected languages are valid");
}
public static IOException createOcrToolsUnavailableException() {
return createIOException("error.toolNotInstalled", "{0} is not installed", null, "OCR tools");
return createIOException(
"error.toolNotInstalled", "{0} is not installed", null, "OCR tools");
}
/**
* Create URL/website conversion exceptions.
*/
/** Create URL/website conversion exceptions. */
public static IllegalArgumentException createInvalidUrlFormatException() {
return createIllegalArgumentException("error.invalidFormat", "Invalid {0} format: {1}", "URL", "provided format is invalid");
return createIllegalArgumentException(
"error.invalidFormat",
"Invalid {0} format: {1}",
"URL",
"provided format is invalid");
}
public static IllegalArgumentException createUrlNotReachableException() {
return createIllegalArgumentException("error.urlNotReachable", "URL is not reachable, please provide a valid URL");
return createIllegalArgumentException(
"error.urlNotReachable", "URL is not reachable, please provide a valid URL");
}
public static IllegalArgumentException createEndpointDisabledException() {
return createIllegalArgumentException("error.endpointDisabled", "This endpoint has been disabled by the admin");
return createIllegalArgumentException(
"error.endpointDisabled", "This endpoint has been disabled by the admin");
}
/**
* Create system requirement exceptions.
*/
/** Create system requirement exceptions. */
public static IOException createPythonNotInstalledException() {
return createIOException("error.toolNotInstalled", "{0} is not installed", null, "Python");
}
public static IOException createPythonRequiredForWebpException() {
return createIOException("error.toolRequired", "{0} is required for {1}", null, "Python", "WebP conversion");
return createIOException(
"error.toolRequired", "{0} is required for {1}", null, "Python", "WebP conversion");
}
/**
* Create file operation exceptions.
*/
/** Create file operation exceptions. */
public static IOException createFileNotFoundException(String fileId) {
return createIOException("error.fileNotFound", "File not found with ID: {0}", null, fileId);
}
public static RuntimeException createPdfaConversionFailedException() {
return createRuntimeException("error.conversionFailed", "{0} conversion failed", null, "PDF/A");
return createRuntimeException(
"error.conversionFailed", "{0} conversion failed", null, "PDF/A");
}
public static IllegalArgumentException createInvalidComparatorException() {
return createIllegalArgumentException("error.invalidFormat", "Invalid {0} format: {1}", "comparator", "only 'greater', 'equal', and 'less' are supported");
return createIllegalArgumentException(
"error.invalidFormat",
"Invalid {0} format: {1}",
"comparator",
"only 'greater', 'equal', and 'less' are supported");
}
/**
* Create compression-related exceptions.
*/
/** Create compression-related exceptions. */
public static RuntimeException createMd5AlgorithmException(Exception cause) {
return createRuntimeException("error.algorithmNotAvailable", "{0} algorithm not available", cause, "MD5");
return createRuntimeException(
"error.algorithmNotAvailable", "{0} algorithm not available", cause, "MD5");
}
public static IllegalArgumentException createCompressionOptionsException() {
return createIllegalArgumentException("error.optionsNotSpecified", "{0} options are not specified", "compression (expected output size and optimize level)");
return createIllegalArgumentException(
"error.optionsNotSpecified",
"{0} options are not specified",
"compression (expected output size and optimize level)");
}
public static IOException createGhostscriptCompressionException() {
return createIOException("error.commandFailed", "{0} command failed", null, "Ghostscript compression");
return createIOException(
"error.commandFailed", "{0} command failed", null, "Ghostscript compression");
}
public static IOException createGhostscriptCompressionException(Exception cause) {
return createIOException("error.commandFailed", "{0} command failed", cause, "Ghostscript compression");
return createIOException(
"error.commandFailed", "{0} command failed", cause, "Ghostscript compression");
}
public static IOException createQpdfCompressionException(Exception cause) {
@ -257,7 +279,8 @@ public class ExceptionUtils {
* Check if an exception indicates a corrupted PDF and wrap it with appropriate message.
*
* @param e the exception to check
* @return the original exception if not PDF corruption, or a new IOException with user-friendly message
* @return the original exception if not PDF corruption, or a new IOException with user-friendly
* message
*/
public static IOException handlePdfException(IOException e) {
return handlePdfException(e, null);
@ -268,7 +291,8 @@ public class ExceptionUtils {
*
* @param e the exception to check
* @param context additional context for the error
* @return the original exception if not PDF corruption, or a new IOException with user-friendly message
* @return the original exception if not PDF corruption, or a new IOException with user-friendly
* message
*/
public static IOException handlePdfException(IOException e, String context) {
if (PdfErrorUtils.isCorruptedPdfError(e)) {
@ -296,10 +320,10 @@ public class ExceptionUtils {
String message = e.getMessage();
if (message == null) return false;
return message.contains("BadPaddingException") ||
message.contains("Given final block not properly padded") ||
message.contains("AES initialization vector not fully read") ||
message.contains("Failed to decrypt");
return message.contains("BadPaddingException")
|| message.contains("Given final block not properly padded")
|| message.contains("AES initialization vector not fully read")
|| message.contains("Failed to decrypt");
}
/**
@ -312,9 +336,9 @@ public class ExceptionUtils {
String message = e.getMessage();
if (message == null) return false;
return message.contains("password is incorrect") ||
message.contains("Password is not provided") ||
message.contains("PDF contains an encryption dictionary");
return message.contains("password is incorrect")
|| message.contains("Password is not provided")
|| message.contains("PDF contains an encryption dictionary");
}
/**

View File

@ -8,8 +8,8 @@ import org.springframework.context.i18n.LocaleContextHolder;
import lombok.extern.slf4j.Slf4j;
/**
* Utility class for internationalized (i18n) message handling.
* Provides centralized access to Spring MessageSource for consistent error messaging.
* Utility class for internationalized (i18n) message handling. Provides centralized access to
* Spring MessageSource for consistent error messaging.
*/
@Slf4j
public class I18nUtils {
@ -64,8 +64,14 @@ public class I18nUtils {
// Fallback: return the key with arguments if available
if (args != null && args.length > 0) {
return key + " [" + String.join(", ", java.util.Arrays.stream(args)
.map(Object::toString).toArray(String[]::new)) + "]";
return key
+ " ["
+ String.join(
", ",
java.util.Arrays.stream(args)
.map(Object::toString)
.toArray(String[]::new))
+ "]";
}
return key;
}

View File

@ -3,11 +3,8 @@ package stirling.software.common.util;
import java.io.IOException;
import org.springframework.context.MessageSource;
import org.springframework.context.i18n.LocaleContextHolder;
/**
* Utility class for detecting and handling PDF-related errors.
*/
/** Utility class for detecting and handling PDF-related errors. */
public class PdfErrorUtils {
/**
@ -21,17 +18,17 @@ public class PdfErrorUtils {
if (message == null) return false;
// Check for common corruption indicators
return message.contains("Missing root object specification") ||
message.contains("Header doesn't contain versioninfo") ||
message.contains("Expected trailer") ||
message.contains("Invalid PDF") ||
message.contains("Corrupted") ||
message.contains("damaged") ||
message.contains("Unknown dir object") ||
message.contains("Can't dereference COSObject") ||
message.contains("AES initialization vector not fully read") ||
message.contains("BadPaddingException") ||
message.contains("Given final block not properly padded");
return message.contains("Missing root object specification")
|| message.contains("Header doesn't contain versioninfo")
|| message.contains("Expected trailer")
|| message.contains("Invalid PDF")
|| message.contains("Corrupted")
|| message.contains("damaged")
|| message.contains("Unknown dir object")
|| message.contains("Can't dereference COSObject")
|| message.contains("AES initialization vector not fully read")
|| message.contains("BadPaddingException")
|| message.contains("Given final block not properly padded");
}
/**
@ -43,30 +40,34 @@ public class PdfErrorUtils {
*/
@Deprecated
public static String getCorruptedPdfMessage(MessageSource messageSource) {
return I18nUtils.getMessage("error.pdfCorrupted",
"PDF file appears to be corrupted or damaged. Please try using the 'Repair PDF' feature first to fix the file before proceeding with this operation.");
return I18nUtils.getMessage(
"error.pdfCorrupted",
"PDF file appears to be corrupted or damaged. Please try using the 'Repair PDF' feature first to fix the file before proceeding with this operation.");
}
/**
* Creates a user-friendly error message for corrupted PDF files with context using i18n.
*
* @param messageSource the Spring MessageSource for i18n
* @param context additional context about where the error occurred (e.g., "during merge", "during processing")
* @param context additional context about where the error occurred (e.g., "during merge",
* "during processing")
* @return a user-friendly error message
* @deprecated Use ExceptionUtils.createPdfCorruptedException(context, cause) instead
*/
@Deprecated
public static String getCorruptedPdfMessage(MessageSource messageSource, String context) {
if (context != null && !context.isEmpty()) {
return I18nUtils.getMessage("error.pdfCorruptedDuring",
"Error {0}: PDF file appears to be corrupted or damaged. Please try using the 'Repair PDF' feature first to fix the file before proceeding with this operation.",
context);
return I18nUtils.getMessage(
"error.pdfCorruptedDuring",
"Error {0}: PDF file appears to be corrupted or damaged. Please try using the 'Repair PDF' feature first to fix the file before proceeding with this operation.",
context);
}
return getCorruptedPdfMessage(messageSource);
}
/**
* Creates a user-friendly error message for multiple corrupted PDF files (e.g., during merge) using i18n.
* Creates a user-friendly error message for multiple corrupted PDF files (e.g., during merge)
* using i18n.
*
* @param messageSource the Spring MessageSource for i18n
* @return a user-friendly error message for multiple file operations
@ -74,8 +75,9 @@ public class PdfErrorUtils {
*/
@Deprecated
public static String getCorruptedPdfMessageForMultipleFiles(MessageSource messageSource) {
return I18nUtils.getMessage("error.pdfCorruptedMultiple",
"One or more PDF files appear to be corrupted or damaged. Please try using the 'Repair PDF' feature on each file first before attempting to merge them.");
return I18nUtils.getMessage(
"error.pdfCorruptedMultiple",
"One or more PDF files appear to be corrupted or damaged. Please try using the 'Repair PDF' feature on each file first before attempting to merge them.");
}
// Fallback methods for backwards compatibility (when MessageSource is not available)
@ -86,8 +88,9 @@ public class PdfErrorUtils {
* @return a user-friendly error message
*/
public static String getCorruptedPdfMessage(String context) {
String baseMessage = "PDF file appears to be corrupted or damaged. " +
"Please try using the 'Repair PDF' feature first to fix the file before proceeding with this operation.";
String baseMessage =
"PDF file appears to be corrupted or damaged. "
+ "Please try using the 'Repair PDF' feature first to fix the file before proceeding with this operation.";
if (context != null && !context.isEmpty()) {
return "Error " + context + ": " + baseMessage;
@ -101,7 +104,7 @@ public class PdfErrorUtils {
* @return a user-friendly error message for multiple file operations
*/
public static String getCorruptedPdfMessageForMultipleFiles() {
return "One or more PDF files appear to be corrupted or damaged. " +
"Please try using the 'Repair PDF' feature on each file first before attempting to merge them.";
return "One or more PDF files appear to be corrupted or damaged. "
+ "Please try using the 'Repair PDF' feature on each file first before attempting to merge them.";
}
}

View File

@ -36,7 +36,6 @@ import io.github.pixee.security.Filenames;
import lombok.extern.slf4j.Slf4j;
import stirling.software.common.service.CustomPDFDocumentFactory;
import stirling.software.common.util.ExceptionUtils;
@Slf4j
public class PdfUtils {
@ -140,10 +139,12 @@ public class PdfUtils {
// Validate and limit DPI to prevent excessive memory usage
final int MAX_SAFE_DPI = 300; // Maximum safe DPI to prevent memory issues
if (DPI > MAX_SAFE_DPI) {
throw new IllegalArgumentException(String.format(
"DPI value %d exceeds maximum safe limit of %d. " +
"High DPI values can cause memory issues and crashes. " +
"Please use a lower DPI value.", DPI, MAX_SAFE_DPI));
throw new IllegalArgumentException(
String.format(
"DPI value %d exceeds maximum safe limit of %d. "
+ "High DPI values can cause memory issues and crashes. "
+ "Please use a lower DPI value.",
DPI, MAX_SAFE_DPI));
}
try (PDDocument document = pdfDocumentFactory.load(inputStream)) {
@ -173,11 +174,15 @@ public class PdfUtils {
try {
image = pdfRenderer.renderImageWithDPI(i, DPI, colorType);
} catch (IllegalArgumentException e) {
if (e.getMessage() != null && e.getMessage().contains("Maximum size of image exceeded")) {
throw new IllegalArgumentException(String.format(
"PDF page %d is too large to render at %d DPI. " +
"Please try a lower DPI value (recommended: 150 or less).",
i + 1, DPI), e);
if (e.getMessage() != null
&& e.getMessage()
.contains("Maximum size of image exceeded")) {
throw new IllegalArgumentException(
String.format(
"PDF page %d is too large to render at %d DPI. "
+ "Please try a lower DPI value (recommended: 150 or less).",
i + 1, DPI),
e);
}
throw e;
}
@ -215,12 +220,16 @@ public class PdfUtils {
try {
pdfSizeImage = pdfRenderer.renderImageWithDPI(i, DPI, colorType);
} catch (IllegalArgumentException e) {
if (e.getMessage() != null && e.getMessage().contains("Maximum size of image exceeded")) {
throw new IllegalArgumentException(String.format(
"PDF page %d is too large to render at %d DPI. " +
"The resulting image would exceed Java's maximum array size. " +
"Please try a lower DPI value (recommended: 150 or less).",
i + 1, DPI), e);
if (e.getMessage() != null
&& e.getMessage()
.contains("Maximum size of image exceeded")) {
throw new IllegalArgumentException(
String.format(
"PDF page %d is too large to render at %d DPI. "
+ "The resulting image would exceed Java's maximum array size. "
+ "Please try a lower DPI value (recommended: 150 or less).",
i + 1, DPI),
e);
}
throw e;
}
@ -254,11 +263,15 @@ public class PdfUtils {
try {
pageImage = pdfRenderer.renderImageWithDPI(i, DPI, colorType);
} catch (IllegalArgumentException e) {
if (e.getMessage() != null && e.getMessage().contains("Maximum size of image exceeded")) {
throw new IllegalArgumentException(String.format(
"PDF page %d is too large to render at %d DPI. " +
"Please try a lower DPI value (recommended: 150 or less).",
i + 1, DPI), e);
if (e.getMessage() != null
&& e.getMessage()
.contains("Maximum size of image exceeded")) {
throw new IllegalArgumentException(
String.format(
"PDF page %d is too large to render at %d DPI. "
+ "Please try a lower DPI value (recommended: 150 or less).",
i + 1, DPI),
e);
}
throw e;
}
@ -285,11 +298,14 @@ public class PdfUtils {
try {
image = pdfRenderer.renderImageWithDPI(i, DPI, colorType);
} catch (IllegalArgumentException e) {
if (e.getMessage() != null && e.getMessage().contains("Maximum size of image exceeded")) {
throw new IllegalArgumentException(String.format(
"PDF page %d is too large to render at %d DPI. " +
"Please try a lower DPI value (recommended: 150 or less).",
i + 1, DPI), e);
if (e.getMessage() != null
&& e.getMessage().contains("Maximum size of image exceeded")) {
throw new IllegalArgumentException(
String.format(
"PDF page %d is too large to render at %d DPI. "
+ "Please try a lower DPI value (recommended: 150 or less).",
i + 1, DPI),
e);
}
throw e;
}
@ -334,12 +350,15 @@ public class PdfUtils {
try {
bim = pdfRenderer.renderImageWithDPI(page, 300, ImageType.RGB);
} catch (IllegalArgumentException e) {
if (e.getMessage() != null && e.getMessage().contains("Maximum size of image exceeded")) {
throw new IllegalArgumentException(String.format(
"PDF page %d is too large to render at 300 DPI. " +
"The resulting image would exceed Java's maximum array size. " +
"Please use a lower DPI value for PDF-to-image conversion.",
page + 1), e);
if (e.getMessage() != null
&& e.getMessage().contains("Maximum size of image exceeded")) {
throw new IllegalArgumentException(
String.format(
"PDF page %d is too large to render at 300 DPI. "
+ "The resulting image would exceed Java's maximum array size. "
+ "Please use a lower DPI value for PDF-to-image conversion.",
page + 1),
e);
}
throw e;
}

View File

@ -109,8 +109,10 @@ public class CustomColorReplaceStrategy extends ReplaceAndInvertColorStrategy {
log.info("text not supported by font ");
font = checkSupportedFontForCharacter(unicodeText);
} catch (UnsupportedOperationException ue) {
log.info("font does not support encoding operation: {} for text: '{}'",
font.getClass().getSimpleName(), unicodeText);
log.info(
"font does not support encoding operation: {} for text: '{}'",
font.getClass().getSimpleName(),
unicodeText);
font = checkSupportedFontForCharacter(unicodeText);
} finally {
// if any other font is not supported, then replace default character *

View File

@ -20,7 +20,6 @@ import org.apache.pdfbox.pdmodel.interactive.documentnavigation.outline.PDOutlin
import org.apache.pdfbox.pdmodel.interactive.form.PDAcroForm;
import org.apache.pdfbox.pdmodel.interactive.form.PDField;
import org.apache.pdfbox.pdmodel.interactive.form.PDSignatureField;
import org.springframework.context.MessageSource;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping;
@ -194,7 +193,8 @@ public class MergeController {
try {
mergerUtility.mergeDocuments(
pdfDocumentFactory.getStreamCacheFunction(totalSize)); // Merge the documents
pdfDocumentFactory.getStreamCacheFunction(
totalSize)); // Merge the documents
} catch (IOException e) {
ExceptionUtils.logException("PDF merge", e);
if (PdfErrorUtils.isCorruptedPdfError(e)) {

View File

@ -44,7 +44,8 @@ public class RotationController {
// Validate the angle is a multiple of 90
if (angle % 90 != 0) {
throw ExceptionUtils.createIllegalArgumentException("error.angleNotMultipleOf90", "Angle must be a multiple of 90");
throw ExceptionUtils.createIllegalArgumentException(
"error.angleNotMultipleOf90", "Angle must be a multiple of 90");
}
// Load the PDF document

View File

@ -132,7 +132,8 @@ public class SplitPdfByChaptersController {
Integer bookmarkLevel =
request.getBookmarkLevel(); // levels start from 0 (top most bookmarks)
if (bookmarkLevel < 0) {
throw ExceptionUtils.createIllegalArgumentException("error.invalidArgument", "Invalid argument: {0}", "bookmark level");
throw ExceptionUtils.createIllegalArgumentException(
"error.invalidArgument", "Invalid argument: {0}", "bookmark level");
}
sourceDocument = pdfDocumentFactory.load(file);
@ -140,7 +141,8 @@ public class SplitPdfByChaptersController {
if (outline == null) {
log.warn("No outline found for {}", file.getOriginalFilename());
throw ExceptionUtils.createIllegalArgumentException("error.pdfBookmarksNotFound", "No PDF bookmarks/outline found in document");
throw ExceptionUtils.createIllegalArgumentException(
"error.pdfBookmarksNotFound", "No PDF bookmarks/outline found in document");
}
List<Bookmark> bookmarks = new ArrayList<>();
try {

View File

@ -34,12 +34,12 @@ import stirling.software.SPDF.model.api.converters.ConvertToImageRequest;
import stirling.software.SPDF.model.api.converters.ConvertToPdfRequest;
import stirling.software.common.service.CustomPDFDocumentFactory;
import stirling.software.common.util.CheckProgramInstall;
import stirling.software.common.util.ExceptionUtils;
import stirling.software.common.util.GeneralUtils;
import stirling.software.common.util.PdfUtils;
import stirling.software.common.util.ProcessExecutor;
import stirling.software.common.util.ProcessExecutor.ProcessExecutorResult;
import stirling.software.common.util.WebResponseUtils;
import stirling.software.common.util.ExceptionUtils;
@RestController
@RequestMapping("/api/v1/convert")

View File

@ -67,10 +67,10 @@ import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
import stirling.software.SPDF.model.api.converters.PdfToPdfARequest;
import stirling.software.common.util.ExceptionUtils;
import stirling.software.common.util.ProcessExecutor;
import stirling.software.common.util.ProcessExecutor.ProcessExecutorResult;
import stirling.software.common.util.WebResponseUtils;
import stirling.software.common.util.ExceptionUtils;
@RestController
@RequestMapping("/api/v1/convert")

View File

@ -53,11 +53,11 @@ import lombok.extern.slf4j.Slf4j;
import stirling.software.SPDF.config.EndpointConfiguration;
import stirling.software.SPDF.model.api.misc.OptimizePdfRequest;
import stirling.software.common.service.CustomPDFDocumentFactory;
import stirling.software.common.util.ExceptionUtils;
import stirling.software.common.util.GeneralUtils;
import stirling.software.common.util.ProcessExecutor;
import stirling.software.common.util.ProcessExecutor.ProcessExecutorResult;
import stirling.software.common.util.WebResponseUtils;
import stirling.software.common.util.ExceptionUtils;
@RestController
@RequestMapping("/api/v1/misc")

View File

@ -24,7 +24,6 @@ import org.apache.pdfbox.cos.COSName;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage;
import org.apache.pdfbox.pdmodel.graphics.image.PDImageXObject;
import org.springframework.context.MessageSource;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ModelAttribute;
@ -44,7 +43,6 @@ import stirling.software.SPDF.model.api.PDFExtractImagesRequest;
import stirling.software.common.service.CustomPDFDocumentFactory;
import stirling.software.common.util.ExceptionUtils;
import stirling.software.common.util.ImageProcessingUtils;
import stirling.software.common.util.PdfErrorUtils;
import stirling.software.common.util.WebResponseUtils;
@RestController
@ -185,34 +183,34 @@ public class ExtractImagesController {
for (COSName name : page.getResources().getXObjectNames()) {
try {
if (page.getResources().isImageXObject(name)) {
PDImageXObject image = (PDImageXObject) page.getResources().getXObject(name);
if (!allowDuplicates) {
byte[] data = ImageProcessingUtils.getImageData(image.getImage());
byte[] imageHash = md.digest(data);
synchronized (processedImages) {
if (processedImages.stream()
.anyMatch(hash -> Arrays.equals(hash, imageHash))) {
continue; // Skip already processed images
PDImageXObject image = (PDImageXObject) page.getResources().getXObject(name);
if (!allowDuplicates) {
byte[] data = ImageProcessingUtils.getImageData(image.getImage());
byte[] imageHash = md.digest(data);
synchronized (processedImages) {
if (processedImages.stream()
.anyMatch(hash -> Arrays.equals(hash, imageHash))) {
continue; // Skip already processed images
}
processedImages.add(imageHash);
}
processedImages.add(imageHash);
}
RenderedImage renderedImage = image.getImage();
// Convert to standard RGB colorspace if needed
BufferedImage bufferedImage = convertToRGB(renderedImage, format);
// Write image to zip file
String imageName = filename + "_page_" + pageNum + "_" + count++ + "." + format;
synchronized (zos) {
zos.putNextEntry(new ZipEntry(imageName));
ByteArrayOutputStream imageBaos = new ByteArrayOutputStream();
ImageIO.write(bufferedImage, format, imageBaos);
zos.write(imageBaos.toByteArray());
zos.closeEntry();
}
}
RenderedImage renderedImage = image.getImage();
// Convert to standard RGB colorspace if needed
BufferedImage bufferedImage = convertToRGB(renderedImage, format);
// Write image to zip file
String imageName = filename + "_page_" + pageNum + "_" + count++ + "." + format;
synchronized (zos) {
zos.putNextEntry(new ZipEntry(imageName));
ByteArrayOutputStream imageBaos = new ByteArrayOutputStream();
ImageIO.write(bufferedImage, format, imageBaos);
zos.write(imageBaos.toByteArray());
zos.closeEntry();
}
}
} catch (IOException e) {
ExceptionUtils.logException("image extraction", e);
throw ExceptionUtils.handlePdfException(e, "during image extraction");

View File

@ -167,7 +167,10 @@ public class CertSignController {
Boolean showLogo = request.getShowLogo();
if (certType == null) {
throw ExceptionUtils.createIllegalArgumentException("error.optionsNotSpecified", "{0} options are not specified", "certificate type");
throw ExceptionUtils.createIllegalArgumentException(
"error.optionsNotSpecified",
"{0} options are not specified",
"certificate type");
}
KeyStore ks = null;
@ -190,7 +193,10 @@ public class CertSignController {
ks.load(jksfile.getInputStream(), password.toCharArray());
break;
default:
throw ExceptionUtils.createIllegalArgumentException("error.invalidArgument", "Invalid argument: {0}", "certificate type: " + certType);
throw ExceptionUtils.createIllegalArgumentException(
"error.invalidArgument",
"Invalid argument: {0}",
"certificate type: " + certType);
}
CreateSignature createSignature = new CreateSignature(ks, password.toCharArray());

View File

@ -177,7 +177,9 @@ public class GetInfoOnPDF {
}
} catch (XmpParsingException e) {
// XMP parsing failed, but we already checked raw metadata above
log.debug("XMP parsing failed for standard check, but raw metadata was already checked: {}", e.getMessage());
log.debug(
"XMP parsing failed for standard check, but raw metadata was already checked: {}",
e.getMessage());
}
}
} catch (Exception e) {

View File

@ -83,7 +83,12 @@ public class ValidateSignatureController {
CertificateFactory cf = CertificateFactory.getInstance("X.509");
customCert = (X509Certificate) cf.generateCertificate(certStream);
} catch (CertificateException e) {
throw ExceptionUtils.createRuntimeException("error.invalidFormat", "Invalid {0} format: {1}", e, "certificate file", e.getMessage());
throw ExceptionUtils.createRuntimeException(
"error.invalidFormat",
"Invalid {0} format: {1}",
e,
"certificate file",
e.getMessage());
}
}

View File

@ -264,13 +264,17 @@ public class GeneralWebController {
}
return null;
} catch (Exception e) {
throw ExceptionUtils.createRuntimeException("error.fontLoadingFailed", "Error processing font file", e);
throw ExceptionUtils.createRuntimeException(
"error.fontLoadingFailed",
"Error processing font file",
e);
}
})
.filter(Objects::nonNull)
.toList();
} catch (Exception e) {
throw ExceptionUtils.createRuntimeException("error.fontDirectoryReadFailed", "Failed to read font directory", e);
throw ExceptionUtils.createRuntimeException(
"error.fontDirectoryReadFailed", "Failed to read font directory", e);
}
}

View File

@ -48,7 +48,7 @@ public class ConvertWebsiteToPdfTest {
convertWebsiteToPDF.urlToPdf(request);
});
// Assert
assertEquals("Invalid URL format provided.", thrown.getMessage());
assertEquals("Invalid URL format: provided format is invalid", thrown.getMessage());
}
@Test
@ -66,6 +66,6 @@ public class ConvertWebsiteToPdfTest {
convertWebsiteToPDF.urlToPdf(request);
});
// Assert
assertEquals("URL is not reachable, please provide a valid URL.", thrown.getMessage());
assertEquals("URL is not reachable, please provide a valid URL", thrown.getMessage());
}
}