mirror of
https://github.com/Stirling-Tools/Stirling-PDF.git
synced 2025-08-27 22:59:22 +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.model.api.PDFFile;
|
||||||
import stirling.software.common.util.ApplicationContextProvider;
|
import stirling.software.common.util.ApplicationContextProvider;
|
||||||
import stirling.software.common.util.ExceptionUtils;
|
import stirling.software.common.util.ExceptionUtils;
|
||||||
import stirling.software.common.util.PdfErrorUtils;
|
|
||||||
import stirling.software.common.util.TempFileManager;
|
import stirling.software.common.util.TempFileManager;
|
||||||
import stirling.software.common.util.TempFileRegistry;
|
import stirling.software.common.util.TempFileRegistry;
|
||||||
|
|
||||||
@ -373,7 +372,7 @@ public class CustomPDFDocumentFactory {
|
|||||||
Files.write(tempFile, bytes);
|
Files.write(tempFile, bytes);
|
||||||
return loadFromFile(tempFile.toFile(), size, cache);
|
return loadFromFile(tempFile.toFile(), size, cache);
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
return Loader.loadPDF(bytes, "", null, null, cache);
|
return Loader.loadPDF(bytes, "", null, null, cache);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
|
@ -44,7 +44,6 @@ import lombok.extern.slf4j.Slf4j;
|
|||||||
import stirling.software.common.model.api.converters.EmlToPdfRequest;
|
import stirling.software.common.model.api.converters.EmlToPdfRequest;
|
||||||
import stirling.software.common.model.api.converters.HTMLToPdfRequest;
|
import stirling.software.common.model.api.converters.HTMLToPdfRequest;
|
||||||
import stirling.software.common.service.CustomPDFDocumentFactory;
|
import stirling.software.common.service.CustomPDFDocumentFactory;
|
||||||
import stirling.software.common.util.ExceptionUtils;
|
|
||||||
|
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@UtilityClass
|
@UtilityClass
|
||||||
|
@ -5,25 +5,25 @@ import java.io.IOException;
|
|||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Utility class for handling exceptions with internationalized error messages.
|
* Utility class for handling exceptions with internationalized error messages. Provides consistent
|
||||||
* Provides consistent error handling and user-friendly messages across the application.
|
* error handling and user-friendly messages across the application.
|
||||||
*/
|
*/
|
||||||
@Slf4j
|
@Slf4j
|
||||||
public class ExceptionUtils {
|
public class ExceptionUtils {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create an IOException with internationalized message for PDF corruption.
|
* Create an IOException with internationalized message for PDF corruption.
|
||||||
*
|
*
|
||||||
* @param cause the original exception
|
* @param cause the original exception
|
||||||
* @return IOException with user-friendly message
|
* @return IOException with user-friendly message
|
||||||
*/
|
*/
|
||||||
public static IOException createPdfCorruptedException(Exception cause) {
|
public static IOException createPdfCorruptedException(Exception cause) {
|
||||||
return createPdfCorruptedException(null, cause);
|
return createPdfCorruptedException(null, cause);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create an IOException with internationalized message for PDF corruption with context.
|
* Create an IOException with internationalized message for PDF corruption with context.
|
||||||
*
|
*
|
||||||
* @param context additional context (e.g., "during merge", "during image extraction")
|
* @param context additional context (e.g., "during merge", "during image extraction")
|
||||||
* @param cause the original exception
|
* @param cause the original exception
|
||||||
* @return IOException with user-friendly message
|
* @return IOException with user-friendly message
|
||||||
@ -31,295 +31,319 @@ public class ExceptionUtils {
|
|||||||
public static IOException createPdfCorruptedException(String context, Exception cause) {
|
public static IOException createPdfCorruptedException(String context, Exception cause) {
|
||||||
String message;
|
String message;
|
||||||
if (context != null && !context.isEmpty()) {
|
if (context != null && !context.isEmpty()) {
|
||||||
message = I18nUtils.getMessage(
|
message =
|
||||||
"error.pdfCorruptedDuring",
|
I18nUtils.getMessage(
|
||||||
"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.",
|
"error.pdfCorruptedDuring",
|
||||||
context
|
"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 {
|
} else {
|
||||||
message = I18nUtils.getMessage(
|
message =
|
||||||
"error.pdfCorrupted",
|
I18nUtils.getMessage(
|
||||||
"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."
|
"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);
|
return new IOException(message, cause);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create an IOException with internationalized message for multiple corrupted PDFs.
|
* Create an IOException with internationalized message for multiple corrupted PDFs.
|
||||||
*
|
*
|
||||||
* @param cause the original exception
|
* @param cause the original exception
|
||||||
* @return IOException with user-friendly message
|
* @return IOException with user-friendly message
|
||||||
*/
|
*/
|
||||||
public static IOException createMultiplePdfCorruptedException(Exception cause) {
|
public static IOException createMultiplePdfCorruptedException(Exception cause) {
|
||||||
String message = I18nUtils.getMessage(
|
String message =
|
||||||
"error.pdfCorruptedMultiple",
|
I18nUtils.getMessage(
|
||||||
"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."
|
"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);
|
return new IOException(message, cause);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create an IOException with internationalized message for PDF encryption issues.
|
* Create an IOException with internationalized message for PDF encryption issues.
|
||||||
*
|
*
|
||||||
* @param cause the original exception
|
* @param cause the original exception
|
||||||
* @return IOException with user-friendly message
|
* @return IOException with user-friendly message
|
||||||
*/
|
*/
|
||||||
public static IOException createPdfEncryptionException(Exception cause) {
|
public static IOException createPdfEncryptionException(Exception cause) {
|
||||||
String message = I18nUtils.getMessage(
|
String message =
|
||||||
"error.pdfEncryption",
|
I18nUtils.getMessage(
|
||||||
"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.",
|
"error.pdfEncryption",
|
||||||
cause.getMessage()
|
"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);
|
return new IOException(message, cause);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create an IOException with internationalized message for PDF password issues.
|
* Create an IOException with internationalized message for PDF password issues.
|
||||||
*
|
*
|
||||||
* @param cause the original exception
|
* @param cause the original exception
|
||||||
* @return IOException with user-friendly message
|
* @return IOException with user-friendly message
|
||||||
*/
|
*/
|
||||||
public static IOException createPdfPasswordException(Exception cause) {
|
public static IOException createPdfPasswordException(Exception cause) {
|
||||||
String message = I18nUtils.getMessage(
|
String message =
|
||||||
"error.pdfPassword",
|
I18nUtils.getMessage(
|
||||||
"The PDF Document is passworded and either the password was not provided or was incorrect"
|
"error.pdfPassword",
|
||||||
);
|
"The PDF Document is passworded and either the password was not provided or was incorrect");
|
||||||
return new IOException(message, cause);
|
return new IOException(message, cause);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create an IOException with internationalized message for file processing errors.
|
* Create an IOException with internationalized message for file processing errors.
|
||||||
*
|
*
|
||||||
* @param operation the operation being performed (e.g., "merge", "split", "convert")
|
* @param operation the operation being performed (e.g., "merge", "split", "convert")
|
||||||
* @param cause the original exception
|
* @param cause the original exception
|
||||||
* @return IOException with user-friendly message
|
* @return IOException with user-friendly message
|
||||||
*/
|
*/
|
||||||
public static IOException createFileProcessingException(String operation, Exception cause) {
|
public static IOException createFileProcessingException(String operation, Exception cause) {
|
||||||
String message = I18nUtils.getMessage(
|
String message =
|
||||||
"error.fileProcessing",
|
I18nUtils.getMessage(
|
||||||
"An error occurred while processing the file during {0} operation: {1}",
|
"error.fileProcessing",
|
||||||
operation,
|
"An error occurred while processing the file during {0} operation: {1}",
|
||||||
cause.getMessage()
|
operation,
|
||||||
);
|
cause.getMessage());
|
||||||
return new IOException(message, cause);
|
return new IOException(message, cause);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a generic IOException with internationalized message.
|
* Create a generic IOException with internationalized message.
|
||||||
*
|
*
|
||||||
* @param messageKey the i18n message key
|
* @param messageKey the i18n message key
|
||||||
* @param defaultMessage the default message if i18n is not available
|
* @param defaultMessage the default message if i18n is not available
|
||||||
* @param cause the original exception
|
* @param cause the original exception
|
||||||
* @param args optional arguments for the message
|
* @param args optional arguments for the message
|
||||||
* @return IOException with user-friendly 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);
|
String message = I18nUtils.getMessage(messageKey, defaultMessage, args);
|
||||||
return new IOException(message, cause);
|
return new IOException(message, cause);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a generic RuntimeException with internationalized message.
|
* Create a generic RuntimeException with internationalized message.
|
||||||
*
|
*
|
||||||
* @param messageKey the i18n message key
|
* @param messageKey the i18n message key
|
||||||
* @param defaultMessage the default message if i18n is not available
|
* @param defaultMessage the default message if i18n is not available
|
||||||
* @param cause the original exception
|
* @param cause the original exception
|
||||||
* @param args optional arguments for the message
|
* @param args optional arguments for the message
|
||||||
* @return RuntimeException with user-friendly 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);
|
String message = I18nUtils.getMessage(messageKey, defaultMessage, args);
|
||||||
return new RuntimeException(message, cause);
|
return new RuntimeException(message, cause);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create an IllegalArgumentException with internationalized message.
|
* Create an IllegalArgumentException with internationalized message.
|
||||||
*
|
*
|
||||||
* @param messageKey the i18n message key
|
* @param messageKey the i18n message key
|
||||||
* @param defaultMessage the default message if i18n is not available
|
* @param defaultMessage the default message if i18n is not available
|
||||||
* @param args optional arguments for the message
|
* @param args optional arguments for the message
|
||||||
* @return IllegalArgumentException with user-friendly 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);
|
String message = I18nUtils.getMessage(messageKey, defaultMessage, args);
|
||||||
System.out.println("######## Test " + message);
|
System.out.println("######## Test " + message);
|
||||||
return new IllegalArgumentException(message);
|
return new IllegalArgumentException(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/** Create file validation exceptions. */
|
||||||
* Create file validation exceptions.
|
|
||||||
*/
|
|
||||||
public static IllegalArgumentException createHtmlFileRequiredException() {
|
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() {
|
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() {
|
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() {
|
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() {
|
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) {
|
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() {
|
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() {
|
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() {
|
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() {
|
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() {
|
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() {
|
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() {
|
public static IOException createPythonNotInstalledException() {
|
||||||
return createIOException("error.toolNotInstalled", "{0} is not installed", null, "Python");
|
return createIOException("error.toolNotInstalled", "{0} is not installed", null, "Python");
|
||||||
}
|
}
|
||||||
|
|
||||||
public static IOException createPythonRequiredForWebpException() {
|
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) {
|
public static IOException createFileNotFoundException(String fileId) {
|
||||||
return createIOException("error.fileNotFound", "File not found with ID: {0}", null, fileId);
|
return createIOException("error.fileNotFound", "File not found with ID: {0}", null, fileId);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static RuntimeException createPdfaConversionFailedException() {
|
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() {
|
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) {
|
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() {
|
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() {
|
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) {
|
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) {
|
public static IOException createQpdfCompressionException(Exception cause) {
|
||||||
return createIOException("error.commandFailed", "{0} command failed", cause, "QPDF");
|
return createIOException("error.commandFailed", "{0} command failed", cause, "QPDF");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check if an exception indicates a corrupted PDF and wrap it with appropriate message.
|
* Check if an exception indicates a corrupted PDF and wrap it with appropriate message.
|
||||||
*
|
*
|
||||||
* @param e the exception to check
|
* @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) {
|
public static IOException handlePdfException(IOException e) {
|
||||||
return handlePdfException(e, null);
|
return handlePdfException(e, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check if an exception indicates a corrupted PDF and wrap it with appropriate message.
|
* Check if an exception indicates a corrupted PDF and wrap it with appropriate message.
|
||||||
*
|
*
|
||||||
* @param e the exception to check
|
* @param e the exception to check
|
||||||
* @param context additional context for the error
|
* @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) {
|
public static IOException handlePdfException(IOException e, String context) {
|
||||||
if (PdfErrorUtils.isCorruptedPdfError(e)) {
|
if (PdfErrorUtils.isCorruptedPdfError(e)) {
|
||||||
return createPdfCorruptedException(context, e);
|
return createPdfCorruptedException(context, e);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isEncryptionError(e)) {
|
if (isEncryptionError(e)) {
|
||||||
return createPdfEncryptionException(e);
|
return createPdfEncryptionException(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isPasswordError(e)) {
|
if (isPasswordError(e)) {
|
||||||
return createPdfPasswordException(e);
|
return createPdfPasswordException(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
return e; // Return original exception if no specific handling needed
|
return e; // Return original exception if no specific handling needed
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check if an exception indicates a PDF encryption/decryption error.
|
* Check if an exception indicates a PDF encryption/decryption error.
|
||||||
*
|
*
|
||||||
* @param e the exception to check
|
* @param e the exception to check
|
||||||
* @return true if it's an encryption error, false otherwise
|
* @return true if it's an encryption error, false otherwise
|
||||||
*/
|
*/
|
||||||
public static boolean isEncryptionError(IOException e) {
|
public static boolean isEncryptionError(IOException e) {
|
||||||
String message = e.getMessage();
|
String message = e.getMessage();
|
||||||
if (message == null) return false;
|
if (message == null) return false;
|
||||||
|
|
||||||
return message.contains("BadPaddingException") ||
|
return message.contains("BadPaddingException")
|
||||||
message.contains("Given final block not properly padded") ||
|
|| message.contains("Given final block not properly padded")
|
||||||
message.contains("AES initialization vector not fully read") ||
|
|| message.contains("AES initialization vector not fully read")
|
||||||
message.contains("Failed to decrypt");
|
|| message.contains("Failed to decrypt");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check if an exception indicates a PDF password error.
|
* Check if an exception indicates a PDF password error.
|
||||||
*
|
*
|
||||||
* @param e the exception to check
|
* @param e the exception to check
|
||||||
* @return true if it's a password error, false otherwise
|
* @return true if it's a password error, false otherwise
|
||||||
*/
|
*/
|
||||||
public static boolean isPasswordError(IOException e) {
|
public static boolean isPasswordError(IOException e) {
|
||||||
String message = e.getMessage();
|
String message = e.getMessage();
|
||||||
if (message == null) return false;
|
if (message == null) return false;
|
||||||
|
|
||||||
return message.contains("password is incorrect") ||
|
return message.contains("password is incorrect")
|
||||||
message.contains("Password is not provided") ||
|
|| message.contains("Password is not provided")
|
||||||
message.contains("PDF contains an encryption dictionary");
|
|| message.contains("PDF contains an encryption dictionary");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Log an exception with appropriate level based on its type.
|
* Log an exception with appropriate level based on its type.
|
||||||
*
|
*
|
||||||
* @param operation the operation being performed
|
* @param operation the operation being performed
|
||||||
* @param e the exception that occurred
|
* @param e the exception that occurred
|
||||||
*/
|
*/
|
||||||
@ -332,4 +356,4 @@ public class ExceptionUtils {
|
|||||||
log.error("Unexpected error during {}", operation, e);
|
log.error("Unexpected error during {}", operation, e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -8,17 +8,17 @@ import org.springframework.context.i18n.LocaleContextHolder;
|
|||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Utility class for internationalized (i18n) message handling.
|
* Utility class for internationalized (i18n) message handling. Provides centralized access to
|
||||||
* Provides centralized access to Spring MessageSource for consistent error messaging.
|
* Spring MessageSource for consistent error messaging.
|
||||||
*/
|
*/
|
||||||
@Slf4j
|
@Slf4j
|
||||||
public class I18nUtils {
|
public class I18nUtils {
|
||||||
|
|
||||||
private static MessageSource messageSource;
|
private static MessageSource messageSource;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the MessageSource bean from the application context.
|
* Get the MessageSource bean from the application context.
|
||||||
*
|
*
|
||||||
* @return MessageSource instance, or null if not available
|
* @return MessageSource instance, or null if not available
|
||||||
*/
|
*/
|
||||||
public static MessageSource getMessageSource() {
|
public static MessageSource getMessageSource() {
|
||||||
@ -32,10 +32,10 @@ public class I18nUtils {
|
|||||||
}
|
}
|
||||||
return messageSource;
|
return messageSource;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get a localized message for the given key with parameters.
|
* Get a localized message for the given key with parameters.
|
||||||
*
|
*
|
||||||
* @param key the message key
|
* @param key the message key
|
||||||
* @param args optional arguments for the message
|
* @param args optional arguments for the message
|
||||||
* @return the localized message, or the key itself if message source is not available
|
* @return the localized message, or the key itself if message source is not available
|
||||||
@ -43,10 +43,10 @@ public class I18nUtils {
|
|||||||
public static String getMessage(String key, Object... args) {
|
public static String getMessage(String key, Object... args) {
|
||||||
return getMessage(key, LocaleContextHolder.getLocale(), args);
|
return getMessage(key, LocaleContextHolder.getLocale(), args);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get a localized message for the given key with specific locale and parameters.
|
* Get a localized message for the given key with specific locale and parameters.
|
||||||
*
|
*
|
||||||
* @param key the message key
|
* @param key the message key
|
||||||
* @param locale the locale to use
|
* @param locale the locale to use
|
||||||
* @param args optional arguments for the message
|
* @param args optional arguments for the message
|
||||||
@ -61,18 +61,24 @@ public class I18nUtils {
|
|||||||
log.debug("Failed to get message for key '{}': {}", key, e.getMessage());
|
log.debug("Failed to get message for key '{}': {}", key, e.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fallback: return the key with arguments if available
|
// Fallback: return the key with arguments if available
|
||||||
if (args != null && args.length > 0) {
|
if (args != null && args.length > 0) {
|
||||||
return key + " [" + String.join(", ", java.util.Arrays.stream(args)
|
return key
|
||||||
.map(Object::toString).toArray(String[]::new)) + "]";
|
+ " ["
|
||||||
|
+ String.join(
|
||||||
|
", ",
|
||||||
|
java.util.Arrays.stream(args)
|
||||||
|
.map(Object::toString)
|
||||||
|
.toArray(String[]::new))
|
||||||
|
+ "]";
|
||||||
}
|
}
|
||||||
return key;
|
return key;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get a localized message with a fallback default message.
|
* Get a localized message with a fallback default message.
|
||||||
*
|
*
|
||||||
* @param key the message key
|
* @param key the message key
|
||||||
* @param defaultMessage the default message to use if key is not found
|
* @param defaultMessage the default message to use if key is not found
|
||||||
* @param args optional arguments for the message
|
* @param args optional arguments for the message
|
||||||
@ -87,7 +93,7 @@ public class I18nUtils {
|
|||||||
log.debug("Failed to get message for key '{}': {}", key, e.getMessage());
|
log.debug("Failed to get message for key '{}': {}", key, e.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Apply arguments to default message if it contains placeholders
|
// Apply arguments to default message if it contains placeholders
|
||||||
if (defaultMessage != null && args != null && args.length > 0) {
|
if (defaultMessage != null && args != null && args.length > 0) {
|
||||||
try {
|
try {
|
||||||
@ -96,16 +102,16 @@ public class I18nUtils {
|
|||||||
log.debug("Failed to format default message: {}", e.getMessage());
|
log.debug("Failed to format default message: {}", e.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return defaultMessage != null ? defaultMessage : key;
|
return defaultMessage != null ? defaultMessage : key;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check if MessageSource is available.
|
* Check if MessageSource is available.
|
||||||
*
|
*
|
||||||
* @return true if MessageSource is available, false otherwise
|
* @return true if MessageSource is available, false otherwise
|
||||||
*/
|
*/
|
||||||
public static boolean isMessageSourceAvailable() {
|
public static boolean isMessageSourceAvailable() {
|
||||||
return getMessageSource() != null;
|
return getMessageSource() != null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,105 +3,108 @@ package stirling.software.common.util;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
import org.springframework.context.MessageSource;
|
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 {
|
public class PdfErrorUtils {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks if an IOException indicates a corrupted PDF file.
|
* Checks if an IOException indicates a corrupted PDF file.
|
||||||
*
|
*
|
||||||
* @param e the IOException to check
|
* @param e the IOException to check
|
||||||
* @return true if the error indicates PDF corruption, false otherwise
|
* @return true if the error indicates PDF corruption, false otherwise
|
||||||
*/
|
*/
|
||||||
public static boolean isCorruptedPdfError(IOException e) {
|
public static boolean isCorruptedPdfError(IOException e) {
|
||||||
String message = e.getMessage();
|
String message = e.getMessage();
|
||||||
if (message == null) return false;
|
if (message == null) return false;
|
||||||
|
|
||||||
// Check for common corruption indicators
|
// Check for common corruption indicators
|
||||||
return message.contains("Missing root object specification") ||
|
return message.contains("Missing root object specification")
|
||||||
message.contains("Header doesn't contain versioninfo") ||
|
|| message.contains("Header doesn't contain versioninfo")
|
||||||
message.contains("Expected trailer") ||
|
|| message.contains("Expected trailer")
|
||||||
message.contains("Invalid PDF") ||
|
|| message.contains("Invalid PDF")
|
||||||
message.contains("Corrupted") ||
|
|| message.contains("Corrupted")
|
||||||
message.contains("damaged") ||
|
|| message.contains("damaged")
|
||||||
message.contains("Unknown dir object") ||
|
|| message.contains("Unknown dir object")
|
||||||
message.contains("Can't dereference COSObject") ||
|
|| message.contains("Can't dereference COSObject")
|
||||||
message.contains("AES initialization vector not fully read") ||
|
|| message.contains("AES initialization vector not fully read")
|
||||||
message.contains("BadPaddingException") ||
|
|| message.contains("BadPaddingException")
|
||||||
message.contains("Given final block not properly padded");
|
|| message.contains("Given final block not properly padded");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a user-friendly error message for corrupted PDF files using i18n.
|
* Creates a user-friendly error message for corrupted PDF files using i18n.
|
||||||
*
|
*
|
||||||
* @param messageSource the Spring MessageSource for i18n
|
* @param messageSource the Spring MessageSource for i18n
|
||||||
* @return a user-friendly error message
|
* @return a user-friendly error message
|
||||||
* @deprecated Use ExceptionUtils.createPdfCorruptedException() instead
|
* @deprecated Use ExceptionUtils.createPdfCorruptedException() instead
|
||||||
*/
|
*/
|
||||||
@Deprecated
|
@Deprecated
|
||||||
public static String getCorruptedPdfMessage(MessageSource messageSource) {
|
public static String getCorruptedPdfMessage(MessageSource messageSource) {
|
||||||
return I18nUtils.getMessage("error.pdfCorrupted",
|
return I18nUtils.getMessage(
|
||||||
"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.");
|
"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.
|
* Creates a user-friendly error message for corrupted PDF files with context using i18n.
|
||||||
*
|
*
|
||||||
* @param messageSource the Spring MessageSource for 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
|
* @return a user-friendly error message
|
||||||
* @deprecated Use ExceptionUtils.createPdfCorruptedException(context, cause) instead
|
* @deprecated Use ExceptionUtils.createPdfCorruptedException(context, cause) instead
|
||||||
*/
|
*/
|
||||||
@Deprecated
|
@Deprecated
|
||||||
public static String getCorruptedPdfMessage(MessageSource messageSource, String context) {
|
public static String getCorruptedPdfMessage(MessageSource messageSource, String context) {
|
||||||
if (context != null && !context.isEmpty()) {
|
if (context != null && !context.isEmpty()) {
|
||||||
return I18nUtils.getMessage("error.pdfCorruptedDuring",
|
return I18nUtils.getMessage(
|
||||||
"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.",
|
"error.pdfCorruptedDuring",
|
||||||
context);
|
"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);
|
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
|
* @param messageSource the Spring MessageSource for i18n
|
||||||
* @return a user-friendly error message for multiple file operations
|
* @return a user-friendly error message for multiple file operations
|
||||||
* @deprecated Use ExceptionUtils.createMultiplePdfCorruptedException() instead
|
* @deprecated Use ExceptionUtils.createMultiplePdfCorruptedException() instead
|
||||||
*/
|
*/
|
||||||
@Deprecated
|
@Deprecated
|
||||||
public static String getCorruptedPdfMessageForMultipleFiles(MessageSource messageSource) {
|
public static String getCorruptedPdfMessageForMultipleFiles(MessageSource messageSource) {
|
||||||
return I18nUtils.getMessage("error.pdfCorruptedMultiple",
|
return I18nUtils.getMessage(
|
||||||
"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.");
|
"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)
|
// Fallback methods for backwards compatibility (when MessageSource is not available)
|
||||||
/**
|
/**
|
||||||
* Creates a user-friendly error message for corrupted PDF files (fallback).
|
* Creates a user-friendly error message for corrupted PDF files (fallback).
|
||||||
*
|
*
|
||||||
* @param context additional context about where the error occurred
|
* @param context additional context about where the error occurred
|
||||||
* @return a user-friendly error message
|
* @return a user-friendly error message
|
||||||
*/
|
*/
|
||||||
public static String getCorruptedPdfMessage(String context) {
|
public static String getCorruptedPdfMessage(String context) {
|
||||||
String baseMessage = "PDF file appears to be corrupted or damaged. " +
|
String baseMessage =
|
||||||
"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.";
|
||||||
|
|
||||||
if (context != null && !context.isEmpty()) {
|
if (context != null && !context.isEmpty()) {
|
||||||
return "Error " + context + ": " + baseMessage;
|
return "Error " + context + ": " + baseMessage;
|
||||||
}
|
}
|
||||||
return baseMessage;
|
return baseMessage;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a user-friendly error message for multiple corrupted PDF files (fallback).
|
* Creates a user-friendly error message for multiple corrupted PDF files (fallback).
|
||||||
*
|
*
|
||||||
* @return a user-friendly error message for multiple file operations
|
* @return a user-friendly error message for multiple file operations
|
||||||
*/
|
*/
|
||||||
public static String getCorruptedPdfMessageForMultipleFiles() {
|
public static String getCorruptedPdfMessageForMultipleFiles() {
|
||||||
return "One or more PDF files appear to be corrupted or damaged. " +
|
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.";
|
+ "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 lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
import stirling.software.common.service.CustomPDFDocumentFactory;
|
import stirling.software.common.service.CustomPDFDocumentFactory;
|
||||||
import stirling.software.common.util.ExceptionUtils;
|
|
||||||
|
|
||||||
@Slf4j
|
@Slf4j
|
||||||
public class PdfUtils {
|
public class PdfUtils {
|
||||||
@ -136,16 +135,18 @@ public class PdfUtils {
|
|||||||
int DPI,
|
int DPI,
|
||||||
String filename)
|
String filename)
|
||||||
throws IOException, Exception {
|
throws IOException, Exception {
|
||||||
|
|
||||||
// Validate and limit DPI to prevent excessive memory usage
|
// Validate and limit DPI to prevent excessive memory usage
|
||||||
final int MAX_SAFE_DPI = 300; // Maximum safe DPI to prevent memory issues
|
final int MAX_SAFE_DPI = 300; // Maximum safe DPI to prevent memory issues
|
||||||
if (DPI > MAX_SAFE_DPI) {
|
if (DPI > MAX_SAFE_DPI) {
|
||||||
throw new IllegalArgumentException(String.format(
|
throw new IllegalArgumentException(
|
||||||
"DPI value %d exceeds maximum safe limit of %d. " +
|
String.format(
|
||||||
"High DPI values can cause memory issues and crashes. " +
|
"DPI value %d exceeds maximum safe limit of %d. "
|
||||||
"Please use a lower DPI value.", DPI, MAX_SAFE_DPI));
|
+ "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)) {
|
try (PDDocument document = pdfDocumentFactory.load(inputStream)) {
|
||||||
PDFRenderer pdfRenderer = new PDFRenderer(document);
|
PDFRenderer pdfRenderer = new PDFRenderer(document);
|
||||||
pdfRenderer.setSubsamplingAllowed(true);
|
pdfRenderer.setSubsamplingAllowed(true);
|
||||||
@ -173,11 +174,15 @@ public class PdfUtils {
|
|||||||
try {
|
try {
|
||||||
image = pdfRenderer.renderImageWithDPI(i, DPI, colorType);
|
image = pdfRenderer.renderImageWithDPI(i, DPI, colorType);
|
||||||
} catch (IllegalArgumentException e) {
|
} catch (IllegalArgumentException e) {
|
||||||
if (e.getMessage() != null && e.getMessage().contains("Maximum size of image exceeded")) {
|
if (e.getMessage() != null
|
||||||
throw new IllegalArgumentException(String.format(
|
&& e.getMessage()
|
||||||
"PDF page %d is too large to render at %d DPI. " +
|
.contains("Maximum size of image exceeded")) {
|
||||||
"Please try a lower DPI value (recommended: 150 or less).",
|
throw new IllegalArgumentException(
|
||||||
i + 1, DPI), e);
|
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;
|
throw e;
|
||||||
}
|
}
|
||||||
@ -215,12 +220,16 @@ public class PdfUtils {
|
|||||||
try {
|
try {
|
||||||
pdfSizeImage = pdfRenderer.renderImageWithDPI(i, DPI, colorType);
|
pdfSizeImage = pdfRenderer.renderImageWithDPI(i, DPI, colorType);
|
||||||
} catch (IllegalArgumentException e) {
|
} catch (IllegalArgumentException e) {
|
||||||
if (e.getMessage() != null && e.getMessage().contains("Maximum size of image exceeded")) {
|
if (e.getMessage() != null
|
||||||
throw new IllegalArgumentException(String.format(
|
&& e.getMessage()
|
||||||
"PDF page %d is too large to render at %d DPI. " +
|
.contains("Maximum size of image exceeded")) {
|
||||||
"The resulting image would exceed Java's maximum array size. " +
|
throw new IllegalArgumentException(
|
||||||
"Please try a lower DPI value (recommended: 150 or less).",
|
String.format(
|
||||||
i + 1, DPI), e);
|
"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;
|
throw e;
|
||||||
}
|
}
|
||||||
@ -254,11 +263,15 @@ public class PdfUtils {
|
|||||||
try {
|
try {
|
||||||
pageImage = pdfRenderer.renderImageWithDPI(i, DPI, colorType);
|
pageImage = pdfRenderer.renderImageWithDPI(i, DPI, colorType);
|
||||||
} catch (IllegalArgumentException e) {
|
} catch (IllegalArgumentException e) {
|
||||||
if (e.getMessage() != null && e.getMessage().contains("Maximum size of image exceeded")) {
|
if (e.getMessage() != null
|
||||||
throw new IllegalArgumentException(String.format(
|
&& e.getMessage()
|
||||||
"PDF page %d is too large to render at %d DPI. " +
|
.contains("Maximum size of image exceeded")) {
|
||||||
"Please try a lower DPI value (recommended: 150 or less).",
|
throw new IllegalArgumentException(
|
||||||
i + 1, DPI), e);
|
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;
|
throw e;
|
||||||
}
|
}
|
||||||
@ -285,11 +298,14 @@ public class PdfUtils {
|
|||||||
try {
|
try {
|
||||||
image = pdfRenderer.renderImageWithDPI(i, DPI, colorType);
|
image = pdfRenderer.renderImageWithDPI(i, DPI, colorType);
|
||||||
} catch (IllegalArgumentException e) {
|
} catch (IllegalArgumentException e) {
|
||||||
if (e.getMessage() != null && e.getMessage().contains("Maximum size of image exceeded")) {
|
if (e.getMessage() != null
|
||||||
throw new IllegalArgumentException(String.format(
|
&& e.getMessage().contains("Maximum size of image exceeded")) {
|
||||||
"PDF page %d is too large to render at %d DPI. " +
|
throw new IllegalArgumentException(
|
||||||
"Please try a lower DPI value (recommended: 150 or less).",
|
String.format(
|
||||||
i + 1, DPI), e);
|
"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;
|
throw e;
|
||||||
}
|
}
|
||||||
@ -334,12 +350,15 @@ public class PdfUtils {
|
|||||||
try {
|
try {
|
||||||
bim = pdfRenderer.renderImageWithDPI(page, 300, ImageType.RGB);
|
bim = pdfRenderer.renderImageWithDPI(page, 300, ImageType.RGB);
|
||||||
} catch (IllegalArgumentException e) {
|
} catch (IllegalArgumentException e) {
|
||||||
if (e.getMessage() != null && e.getMessage().contains("Maximum size of image exceeded")) {
|
if (e.getMessage() != null
|
||||||
throw new IllegalArgumentException(String.format(
|
&& e.getMessage().contains("Maximum size of image exceeded")) {
|
||||||
"PDF page %d is too large to render at 300 DPI. " +
|
throw new IllegalArgumentException(
|
||||||
"The resulting image would exceed Java's maximum array size. " +
|
String.format(
|
||||||
"Please use a lower DPI value for PDF-to-image conversion.",
|
"PDF page %d is too large to render at 300 DPI. "
|
||||||
page + 1), e);
|
+ "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;
|
throw e;
|
||||||
}
|
}
|
||||||
|
@ -109,8 +109,10 @@ public class CustomColorReplaceStrategy extends ReplaceAndInvertColorStrategy {
|
|||||||
log.info("text not supported by font ");
|
log.info("text not supported by font ");
|
||||||
font = checkSupportedFontForCharacter(unicodeText);
|
font = checkSupportedFontForCharacter(unicodeText);
|
||||||
} catch (UnsupportedOperationException ue) {
|
} catch (UnsupportedOperationException ue) {
|
||||||
log.info("font does not support encoding operation: {} for text: '{}'",
|
log.info(
|
||||||
font.getClass().getSimpleName(), unicodeText);
|
"font does not support encoding operation: {} for text: '{}'",
|
||||||
|
font.getClass().getSimpleName(),
|
||||||
|
unicodeText);
|
||||||
font = checkSupportedFontForCharacter(unicodeText);
|
font = checkSupportedFontForCharacter(unicodeText);
|
||||||
} finally {
|
} finally {
|
||||||
// if any other font is not supported, then replace default character *
|
// 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.PDAcroForm;
|
||||||
import org.apache.pdfbox.pdmodel.interactive.form.PDField;
|
import org.apache.pdfbox.pdmodel.interactive.form.PDField;
|
||||||
import org.apache.pdfbox.pdmodel.interactive.form.PDSignatureField;
|
import org.apache.pdfbox.pdmodel.interactive.form.PDSignatureField;
|
||||||
import org.springframework.context.MessageSource;
|
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.web.bind.annotation.ModelAttribute;
|
import org.springframework.web.bind.annotation.ModelAttribute;
|
||||||
import org.springframework.web.bind.annotation.PostMapping;
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
@ -194,7 +193,8 @@ public class MergeController {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
mergerUtility.mergeDocuments(
|
mergerUtility.mergeDocuments(
|
||||||
pdfDocumentFactory.getStreamCacheFunction(totalSize)); // Merge the documents
|
pdfDocumentFactory.getStreamCacheFunction(
|
||||||
|
totalSize)); // Merge the documents
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
ExceptionUtils.logException("PDF merge", e);
|
ExceptionUtils.logException("PDF merge", e);
|
||||||
if (PdfErrorUtils.isCorruptedPdfError(e)) {
|
if (PdfErrorUtils.isCorruptedPdfError(e)) {
|
||||||
|
@ -44,7 +44,8 @@ public class RotationController {
|
|||||||
|
|
||||||
// Validate the angle is a multiple of 90
|
// Validate the angle is a multiple of 90
|
||||||
if (angle % 90 != 0) {
|
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
|
// Load the PDF document
|
||||||
|
@ -132,7 +132,8 @@ public class SplitPdfByChaptersController {
|
|||||||
Integer bookmarkLevel =
|
Integer bookmarkLevel =
|
||||||
request.getBookmarkLevel(); // levels start from 0 (top most bookmarks)
|
request.getBookmarkLevel(); // levels start from 0 (top most bookmarks)
|
||||||
if (bookmarkLevel < 0) {
|
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);
|
sourceDocument = pdfDocumentFactory.load(file);
|
||||||
|
|
||||||
@ -140,7 +141,8 @@ public class SplitPdfByChaptersController {
|
|||||||
|
|
||||||
if (outline == null) {
|
if (outline == null) {
|
||||||
log.warn("No outline found for {}", file.getOriginalFilename());
|
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<>();
|
List<Bookmark> bookmarks = new ArrayList<>();
|
||||||
try {
|
try {
|
||||||
|
@ -98,8 +98,8 @@ public class SplitPdfBySizeController {
|
|||||||
} else {
|
} else {
|
||||||
log.error("Invalid split type: {}", type);
|
log.error("Invalid split type: {}", type);
|
||||||
throw ExceptionUtils.createIllegalArgumentException(
|
throw ExceptionUtils.createIllegalArgumentException(
|
||||||
"error.invalidArgument",
|
"error.invalidArgument",
|
||||||
"Invalid argument: {0}",
|
"Invalid argument: {0}",
|
||||||
"split type: " + type);
|
"split type: " + type);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -34,12 +34,12 @@ import stirling.software.SPDF.model.api.converters.ConvertToImageRequest;
|
|||||||
import stirling.software.SPDF.model.api.converters.ConvertToPdfRequest;
|
import stirling.software.SPDF.model.api.converters.ConvertToPdfRequest;
|
||||||
import stirling.software.common.service.CustomPDFDocumentFactory;
|
import stirling.software.common.service.CustomPDFDocumentFactory;
|
||||||
import stirling.software.common.util.CheckProgramInstall;
|
import stirling.software.common.util.CheckProgramInstall;
|
||||||
|
import stirling.software.common.util.ExceptionUtils;
|
||||||
import stirling.software.common.util.GeneralUtils;
|
import stirling.software.common.util.GeneralUtils;
|
||||||
import stirling.software.common.util.PdfUtils;
|
import stirling.software.common.util.PdfUtils;
|
||||||
import stirling.software.common.util.ProcessExecutor;
|
import stirling.software.common.util.ProcessExecutor;
|
||||||
import stirling.software.common.util.ProcessExecutor.ProcessExecutorResult;
|
import stirling.software.common.util.ProcessExecutor.ProcessExecutorResult;
|
||||||
import stirling.software.common.util.WebResponseUtils;
|
import stirling.software.common.util.WebResponseUtils;
|
||||||
import stirling.software.common.util.ExceptionUtils;
|
|
||||||
|
|
||||||
@RestController
|
@RestController
|
||||||
@RequestMapping("/api/v1/convert")
|
@RequestMapping("/api/v1/convert")
|
||||||
|
@ -67,10 +67,10 @@ import io.swagger.v3.oas.annotations.tags.Tag;
|
|||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
import stirling.software.SPDF.model.api.converters.PdfToPdfARequest;
|
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;
|
||||||
import stirling.software.common.util.ProcessExecutor.ProcessExecutorResult;
|
import stirling.software.common.util.ProcessExecutor.ProcessExecutorResult;
|
||||||
import stirling.software.common.util.WebResponseUtils;
|
import stirling.software.common.util.WebResponseUtils;
|
||||||
import stirling.software.common.util.ExceptionUtils;
|
|
||||||
|
|
||||||
@RestController
|
@RestController
|
||||||
@RequestMapping("/api/v1/convert")
|
@RequestMapping("/api/v1/convert")
|
||||||
|
@ -53,11 +53,11 @@ import lombok.extern.slf4j.Slf4j;
|
|||||||
import stirling.software.SPDF.config.EndpointConfiguration;
|
import stirling.software.SPDF.config.EndpointConfiguration;
|
||||||
import stirling.software.SPDF.model.api.misc.OptimizePdfRequest;
|
import stirling.software.SPDF.model.api.misc.OptimizePdfRequest;
|
||||||
import stirling.software.common.service.CustomPDFDocumentFactory;
|
import stirling.software.common.service.CustomPDFDocumentFactory;
|
||||||
|
import stirling.software.common.util.ExceptionUtils;
|
||||||
import stirling.software.common.util.GeneralUtils;
|
import stirling.software.common.util.GeneralUtils;
|
||||||
import stirling.software.common.util.ProcessExecutor;
|
import stirling.software.common.util.ProcessExecutor;
|
||||||
import stirling.software.common.util.ProcessExecutor.ProcessExecutorResult;
|
import stirling.software.common.util.ProcessExecutor.ProcessExecutorResult;
|
||||||
import stirling.software.common.util.WebResponseUtils;
|
import stirling.software.common.util.WebResponseUtils;
|
||||||
import stirling.software.common.util.ExceptionUtils;
|
|
||||||
|
|
||||||
@RestController
|
@RestController
|
||||||
@RequestMapping("/api/v1/misc")
|
@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.PDDocument;
|
||||||
import org.apache.pdfbox.pdmodel.PDPage;
|
import org.apache.pdfbox.pdmodel.PDPage;
|
||||||
import org.apache.pdfbox.pdmodel.graphics.image.PDImageXObject;
|
import org.apache.pdfbox.pdmodel.graphics.image.PDImageXObject;
|
||||||
import org.springframework.context.MessageSource;
|
|
||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.web.bind.annotation.ModelAttribute;
|
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.service.CustomPDFDocumentFactory;
|
||||||
import stirling.software.common.util.ExceptionUtils;
|
import stirling.software.common.util.ExceptionUtils;
|
||||||
import stirling.software.common.util.ImageProcessingUtils;
|
import stirling.software.common.util.ImageProcessingUtils;
|
||||||
import stirling.software.common.util.PdfErrorUtils;
|
|
||||||
import stirling.software.common.util.WebResponseUtils;
|
import stirling.software.common.util.WebResponseUtils;
|
||||||
|
|
||||||
@RestController
|
@RestController
|
||||||
@ -185,34 +183,34 @@ public class ExtractImagesController {
|
|||||||
for (COSName name : page.getResources().getXObjectNames()) {
|
for (COSName name : page.getResources().getXObjectNames()) {
|
||||||
try {
|
try {
|
||||||
if (page.getResources().isImageXObject(name)) {
|
if (page.getResources().isImageXObject(name)) {
|
||||||
PDImageXObject image = (PDImageXObject) page.getResources().getXObject(name);
|
PDImageXObject image = (PDImageXObject) page.getResources().getXObject(name);
|
||||||
if (!allowDuplicates) {
|
if (!allowDuplicates) {
|
||||||
byte[] data = ImageProcessingUtils.getImageData(image.getImage());
|
byte[] data = ImageProcessingUtils.getImageData(image.getImage());
|
||||||
byte[] imageHash = md.digest(data);
|
byte[] imageHash = md.digest(data);
|
||||||
synchronized (processedImages) {
|
synchronized (processedImages) {
|
||||||
if (processedImages.stream()
|
if (processedImages.stream()
|
||||||
.anyMatch(hash -> Arrays.equals(hash, imageHash))) {
|
.anyMatch(hash -> Arrays.equals(hash, imageHash))) {
|
||||||
continue; // Skip already processed images
|
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) {
|
} catch (IOException e) {
|
||||||
ExceptionUtils.logException("image extraction", e);
|
ExceptionUtils.logException("image extraction", e);
|
||||||
throw ExceptionUtils.handlePdfException(e, "during image extraction");
|
throw ExceptionUtils.handlePdfException(e, "during image extraction");
|
||||||
|
@ -381,9 +381,9 @@ public class OCRController {
|
|||||||
|
|
||||||
if (result.getRc() != 0) {
|
if (result.getRc() != 0) {
|
||||||
throw ExceptionUtils.createRuntimeException(
|
throw ExceptionUtils.createRuntimeException(
|
||||||
"error.commandFailed",
|
"error.commandFailed",
|
||||||
"{0} command failed with exit code: {1}",
|
"{0} command failed with exit code: {1}",
|
||||||
null,
|
null,
|
||||||
"Tesseract",
|
"Tesseract",
|
||||||
result.getRc());
|
result.getRc());
|
||||||
}
|
}
|
||||||
|
@ -167,7 +167,10 @@ public class CertSignController {
|
|||||||
Boolean showLogo = request.getShowLogo();
|
Boolean showLogo = request.getShowLogo();
|
||||||
|
|
||||||
if (certType == null) {
|
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;
|
KeyStore ks = null;
|
||||||
@ -190,7 +193,10 @@ public class CertSignController {
|
|||||||
ks.load(jksfile.getInputStream(), password.toCharArray());
|
ks.load(jksfile.getInputStream(), password.toCharArray());
|
||||||
break;
|
break;
|
||||||
default:
|
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());
|
CreateSignature createSignature = new CreateSignature(ks, password.toCharArray());
|
||||||
|
@ -150,20 +150,20 @@ public class GetInfoOnPDF {
|
|||||||
PDMetadata pdMetadata = document.getDocumentCatalog().getMetadata();
|
PDMetadata pdMetadata = document.getDocumentCatalog().getMetadata();
|
||||||
if (pdMetadata != null) {
|
if (pdMetadata != null) {
|
||||||
COSInputStream metaStream = pdMetadata.createInputStream();
|
COSInputStream metaStream = pdMetadata.createInputStream();
|
||||||
|
|
||||||
// First try to read raw metadata as string to check for standard keywords
|
// First try to read raw metadata as string to check for standard keywords
|
||||||
byte[] metadataBytes = metaStream.readAllBytes();
|
byte[] metadataBytes = metaStream.readAllBytes();
|
||||||
String rawMetadata = new String(metadataBytes, StandardCharsets.UTF_8);
|
String rawMetadata = new String(metadataBytes, StandardCharsets.UTF_8);
|
||||||
|
|
||||||
if (rawMetadata.contains(standardKeyword)) {
|
if (rawMetadata.contains(standardKeyword)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If raw check doesn't find it, try parsing with XMP parser
|
// If raw check doesn't find it, try parsing with XMP parser
|
||||||
// Reset stream for parsing
|
// Reset stream for parsing
|
||||||
metaStream.close();
|
metaStream.close();
|
||||||
metaStream = pdMetadata.createInputStream();
|
metaStream = pdMetadata.createInputStream();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
DomXmpParser domXmpParser = new DomXmpParser();
|
DomXmpParser domXmpParser = new DomXmpParser();
|
||||||
XMPMetadata xmpMeta = domXmpParser.parse(metaStream);
|
XMPMetadata xmpMeta = domXmpParser.parse(metaStream);
|
||||||
@ -177,7 +177,9 @@ public class GetInfoOnPDF {
|
|||||||
}
|
}
|
||||||
} catch (XmpParsingException e) {
|
} catch (XmpParsingException e) {
|
||||||
// XMP parsing failed, but we already checked raw metadata above
|
// 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) {
|
} catch (Exception e) {
|
||||||
@ -408,7 +410,7 @@ public class GetInfoOnPDF {
|
|||||||
if (pdMetadata != null) {
|
if (pdMetadata != null) {
|
||||||
try {
|
try {
|
||||||
COSInputStream is = pdMetadata.createInputStream();
|
COSInputStream is = pdMetadata.createInputStream();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
DomXmpParser domXmpParser = new DomXmpParser();
|
DomXmpParser domXmpParser = new DomXmpParser();
|
||||||
XMPMetadata xmpMeta = domXmpParser.parse(is);
|
XMPMetadata xmpMeta = domXmpParser.parse(is);
|
||||||
|
@ -43,7 +43,7 @@ public class PasswordController {
|
|||||||
MultipartFile fileInput = request.getFileInput();
|
MultipartFile fileInput = request.getFileInput();
|
||||||
String password = request.getPassword();
|
String password = request.getPassword();
|
||||||
PDDocument document = pdfDocumentFactory.load(fileInput, password);
|
PDDocument document = pdfDocumentFactory.load(fileInput, password);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
document.setAllSecurityToBeRemoved(true);
|
document.setAllSecurityToBeRemoved(true);
|
||||||
return WebResponseUtils.pdfDocToWebResponse(
|
return WebResponseUtils.pdfDocToWebResponse(
|
||||||
|
@ -83,7 +83,12 @@ public class ValidateSignatureController {
|
|||||||
CertificateFactory cf = CertificateFactory.getInstance("X.509");
|
CertificateFactory cf = CertificateFactory.getInstance("X.509");
|
||||||
customCert = (X509Certificate) cf.generateCertificate(certStream);
|
customCert = (X509Certificate) cf.generateCertificate(certStream);
|
||||||
} catch (CertificateException e) {
|
} 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;
|
return null;
|
||||||
} catch (Exception e) {
|
} 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)
|
.filter(Objects::nonNull)
|
||||||
.toList();
|
.toList();
|
||||||
} catch (Exception e) {
|
} 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);
|
convertWebsiteToPDF.urlToPdf(request);
|
||||||
});
|
});
|
||||||
// Assert
|
// Assert
|
||||||
assertEquals("Invalid URL format provided.", thrown.getMessage());
|
assertEquals("Invalid URL format: provided format is invalid", thrown.getMessage());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -66,6 +66,6 @@ public class ConvertWebsiteToPdfTest {
|
|||||||
convertWebsiteToPDF.urlToPdf(request);
|
convertWebsiteToPDF.urlToPdf(request);
|
||||||
});
|
});
|
||||||
// Assert
|
// 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