mirror of
https://github.com/Stirling-Tools/Stirling-PDF.git
synced 2025-08-27 06:39:24 +00:00
auto formatting
This commit is contained in:
parent
e764158178
commit
0b045bc23a
@ -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;
|
||||
|
||||
|
@ -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
|
||||
|
@ -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(
|
||||
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
|
||||
);
|
||||
context);
|
||||
} else {
|
||||
message = I18nUtils.getMessage(
|
||||
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."
|
||||
);
|
||||
"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(
|
||||
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."
|
||||
);
|
||||
"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(
|
||||
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()
|
||||
);
|
||||
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(
|
||||
String message =
|
||||
I18nUtils.getMessage(
|
||||
"error.pdfPassword",
|
||||
"The PDF Document is passworded and either the password was not provided or was incorrect"
|
||||
);
|
||||
"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(
|
||||
String message =
|
||||
I18nUtils.getMessage(
|
||||
"error.fileProcessing",
|
||||
"An error occurred while processing the file during {0} operation: {1}",
|
||||
operation,
|
||||
cause.getMessage()
|
||||
);
|
||||
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");
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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,7 +40,8 @@ public class PdfErrorUtils {
|
||||
*/
|
||||
@Deprecated
|
||||
public static String getCorruptedPdfMessage(MessageSource messageSource) {
|
||||
return I18nUtils.getMessage("error.pdfCorrupted",
|
||||
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.");
|
||||
}
|
||||
|
||||
@ -51,14 +49,16 @@ public class PdfErrorUtils {
|
||||
* 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",
|
||||
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);
|
||||
}
|
||||
@ -66,7 +66,8 @@ public class PdfErrorUtils {
|
||||
}
|
||||
|
||||
/**
|
||||
* 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,7 +75,8 @@ public class PdfErrorUtils {
|
||||
*/
|
||||
@Deprecated
|
||||
public static String getCorruptedPdfMessageForMultipleFiles(MessageSource messageSource) {
|
||||
return I18nUtils.getMessage("error.pdfCorruptedMultiple",
|
||||
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.");
|
||||
}
|
||||
|
||||
@ -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.";
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
|
@ -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 *
|
||||
|
@ -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)) {
|
||||
|
@ -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
|
||||
|
@ -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 {
|
||||
|
@ -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")
|
||||
|
@ -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")
|
||||
|
@ -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")
|
||||
|
@ -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
|
||||
|
@ -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());
|
||||
|
@ -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) {
|
||||
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user