mirror of
https://github.com/Stirling-Tools/Stirling-PDF.git
synced 2025-08-27 06:39:24 +00:00
test
This commit is contained in:
parent
666fc05ec6
commit
9e3a7c642d
@ -83,7 +83,7 @@ public class CustomPDFDocumentFactory {
|
|||||||
*/
|
*/
|
||||||
public PDDocument load(File file, boolean readOnly) throws IOException {
|
public PDDocument load(File file, boolean readOnly) throws IOException {
|
||||||
if (file == null) {
|
if (file == null) {
|
||||||
throw new IllegalArgumentException("File cannot be null");
|
throw ExceptionUtils.createNullArgumentException("File");
|
||||||
}
|
}
|
||||||
|
|
||||||
long fileSize = file.length();
|
long fileSize = file.length();
|
||||||
@ -110,7 +110,7 @@ public class CustomPDFDocumentFactory {
|
|||||||
*/
|
*/
|
||||||
public PDDocument load(Path path, boolean readOnly) throws IOException {
|
public PDDocument load(Path path, boolean readOnly) throws IOException {
|
||||||
if (path == null) {
|
if (path == null) {
|
||||||
throw new IllegalArgumentException("File cannot be null");
|
throw ExceptionUtils.createNullArgumentException("File");
|
||||||
}
|
}
|
||||||
|
|
||||||
long fileSize = Files.size(path);
|
long fileSize = Files.size(path);
|
||||||
@ -131,7 +131,7 @@ public class CustomPDFDocumentFactory {
|
|||||||
/** Load a PDF from byte array with automatic optimization and read-only option. */
|
/** Load a PDF from byte array with automatic optimization and read-only option. */
|
||||||
public PDDocument load(byte[] input, boolean readOnly) throws IOException {
|
public PDDocument load(byte[] input, boolean readOnly) throws IOException {
|
||||||
if (input == null) {
|
if (input == null) {
|
||||||
throw new IllegalArgumentException("Input bytes cannot be null");
|
throw ExceptionUtils.createNullArgumentException("Input bytes");
|
||||||
}
|
}
|
||||||
|
|
||||||
long dataSize = input.length;
|
long dataSize = input.length;
|
||||||
@ -152,7 +152,7 @@ public class CustomPDFDocumentFactory {
|
|||||||
/** Load a PDF from InputStream with automatic optimization and read-only option. */
|
/** Load a PDF from InputStream with automatic optimization and read-only option. */
|
||||||
public PDDocument load(InputStream input, boolean readOnly) throws IOException {
|
public PDDocument load(InputStream input, boolean readOnly) throws IOException {
|
||||||
if (input == null) {
|
if (input == null) {
|
||||||
throw new IllegalArgumentException("InputStream cannot be null");
|
throw ExceptionUtils.createNullArgumentException("InputStream");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Since we don't know the size upfront, buffer to a temp file
|
// Since we don't know the size upfront, buffer to a temp file
|
||||||
@ -175,7 +175,7 @@ public class CustomPDFDocumentFactory {
|
|||||||
public PDDocument load(InputStream input, String password, boolean readOnly)
|
public PDDocument load(InputStream input, String password, boolean readOnly)
|
||||||
throws IOException {
|
throws IOException {
|
||||||
if (input == null) {
|
if (input == null) {
|
||||||
throw new IllegalArgumentException("InputStream cannot be null");
|
throw ExceptionUtils.createNullArgumentException("InputStream");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Since we don't know the size upfront, buffer to a temp file
|
// Since we don't know the size upfront, buffer to a temp file
|
||||||
|
@ -137,6 +137,23 @@ public class ExceptionUtils {
|
|||||||
return new TranslatableException(message, messageKey, args);
|
return new TranslatableException(message, messageKey, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Create common validation exceptions with translation support. */
|
||||||
|
public static IllegalArgumentException createInvalidArgumentException(String argumentName) {
|
||||||
|
return createIllegalArgumentException(
|
||||||
|
"error.invalidArgument", "Invalid argument: {0}", argumentName);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static IllegalArgumentException createInvalidArgumentException(
|
||||||
|
String argumentName, String value) {
|
||||||
|
return createIllegalArgumentException(
|
||||||
|
"error.invalidFormat", "Invalid {0} format: {1}", argumentName, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static IllegalArgumentException createNullArgumentException(String argumentName) {
|
||||||
|
return createIllegalArgumentException(
|
||||||
|
"error.argumentRequired", "{0} must not be null", argumentName);
|
||||||
|
}
|
||||||
|
|
||||||
/** Create file validation exceptions. */
|
/** Create file validation exceptions. */
|
||||||
public static IllegalArgumentException createHtmlFileRequiredException() {
|
public static IllegalArgumentException createHtmlFileRequiredException() {
|
||||||
return createIllegalArgumentException(
|
return createIllegalArgumentException(
|
||||||
|
@ -571,8 +571,7 @@ public class PdfUtils {
|
|||||||
case "less":
|
case "less":
|
||||||
return actualPageCount < pageCount;
|
return actualPageCount < pageCount;
|
||||||
default:
|
default:
|
||||||
throw new IllegalArgumentException(
|
throw ExceptionUtils.createInvalidArgumentException("comparator", comparator);
|
||||||
"Invalid comparator. Only 'greater', 'equal', and 'less' are supported.");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -25,6 +25,7 @@ import stirling.software.SPDF.model.api.filter.FileSizeRequest;
|
|||||||
import stirling.software.SPDF.model.api.filter.PageRotationRequest;
|
import stirling.software.SPDF.model.api.filter.PageRotationRequest;
|
||||||
import stirling.software.SPDF.model.api.filter.PageSizeRequest;
|
import stirling.software.SPDF.model.api.filter.PageSizeRequest;
|
||||||
import stirling.software.common.service.CustomPDFDocumentFactory;
|
import stirling.software.common.service.CustomPDFDocumentFactory;
|
||||||
|
import stirling.software.common.util.ExceptionUtils;
|
||||||
import stirling.software.common.util.PdfUtils;
|
import stirling.software.common.util.PdfUtils;
|
||||||
import stirling.software.common.util.WebResponseUtils;
|
import stirling.software.common.util.WebResponseUtils;
|
||||||
|
|
||||||
@ -96,7 +97,7 @@ public class FilterController {
|
|||||||
valid = actualPageCount < pageCount;
|
valid = actualPageCount < pageCount;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
throw new IllegalArgumentException("Invalid comparator: " + comparator);
|
throw ExceptionUtils.createInvalidArgumentException("comparator", comparator);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (valid) return WebResponseUtils.multiPartFileToWebResponse(inputFile);
|
if (valid) return WebResponseUtils.multiPartFileToWebResponse(inputFile);
|
||||||
@ -139,7 +140,7 @@ public class FilterController {
|
|||||||
valid = actualArea < standardArea;
|
valid = actualArea < standardArea;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
throw new IllegalArgumentException("Invalid comparator: " + comparator);
|
throw ExceptionUtils.createInvalidArgumentException("comparator", comparator);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (valid) return WebResponseUtils.multiPartFileToWebResponse(inputFile);
|
if (valid) return WebResponseUtils.multiPartFileToWebResponse(inputFile);
|
||||||
@ -172,7 +173,7 @@ public class FilterController {
|
|||||||
valid = actualFileSize < fileSize;
|
valid = actualFileSize < fileSize;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
throw new IllegalArgumentException("Invalid comparator: " + comparator);
|
throw ExceptionUtils.createInvalidArgumentException("comparator", comparator);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (valid) return WebResponseUtils.multiPartFileToWebResponse(inputFile);
|
if (valid) return WebResponseUtils.multiPartFileToWebResponse(inputFile);
|
||||||
@ -208,7 +209,7 @@ public class FilterController {
|
|||||||
valid = actualRotation < rotation;
|
valid = actualRotation < rotation;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
throw new IllegalArgumentException("Invalid comparator: " + comparator);
|
throw ExceptionUtils.createInvalidArgumentException("comparator", comparator);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (valid) return WebResponseUtils.multiPartFileToWebResponse(inputFile);
|
if (valid) return WebResponseUtils.multiPartFileToWebResponse(inputFile);
|
||||||
|
@ -225,6 +225,7 @@ error.pathTraversalDetected=Path traversal detected for security reasons.
|
|||||||
|
|
||||||
# Validation messages
|
# Validation messages
|
||||||
error.invalidArgument=Invalid argument: {0}
|
error.invalidArgument=Invalid argument: {0}
|
||||||
|
error.argumentRequired={0} must not be null
|
||||||
error.operationFailed=Operation failed: {0}
|
error.operationFailed=Operation failed: {0}
|
||||||
error.angleNotMultipleOf90=Angle must be a multiple of 90
|
error.angleNotMultipleOf90=Angle must be a multiple of 90
|
||||||
error.pdfBookmarksNotFound=No PDF bookmarks/outline found in document
|
error.pdfBookmarksNotFound=No PDF bookmarks/outline found in document
|
||||||
|
@ -348,19 +348,13 @@
|
|||||||
// Handle structured error response with translation support
|
// Handle structured error response with translation support
|
||||||
let displayMessage = json.message;
|
let displayMessage = json.message;
|
||||||
|
|
||||||
// If translation info is available, use it to translate the message
|
// If translation info is available, use MessageFormatter to translate
|
||||||
if (json.translationKey && window.stirlingPDF && window.stirlingPDF.translations) {
|
if (json.translationKey && window.MessageFormatter) {
|
||||||
const translatedTemplate = window.stirlingPDF.translations[json.translationKey];
|
displayMessage = window.MessageFormatter.translate(
|
||||||
if (translatedTemplate) {
|
json.translationKey,
|
||||||
displayMessage = translatedTemplate;
|
json.translationArgs,
|
||||||
|
json.message // fallback to original message
|
||||||
// Replace placeholders with args if available
|
);
|
||||||
if (json.translationArgs && Array.isArray(json.translationArgs)) {
|
|
||||||
json.translationArgs.forEach((arg, index) => {
|
|
||||||
displayMessage = displayMessage.replace(`{${index}}`, arg);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
showErrorBanner((json.error || 'Error') + ': ' + displayMessage, json.trace || '');
|
showErrorBanner((json.error || 'Error') + ': ' + displayMessage, json.trace || '');
|
||||||
|
@ -0,0 +1,66 @@
|
|||||||
|
/**
|
||||||
|
* Utility for formatting internationalized messages with placeholder replacement.
|
||||||
|
* Supports the {0}, {1}, {2}... placeholder format used by Java MessageFormat.
|
||||||
|
*/
|
||||||
|
window.MessageFormatter = (function() {
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Format a message template by replacing {0}, {1}, etc. placeholders with provided arguments.
|
||||||
|
*
|
||||||
|
* @param {string} template - The message template with {0}, {1}, etc. placeholders
|
||||||
|
* @param {Array|string} args - Arguments to replace placeholders with. Can be array or individual arguments
|
||||||
|
* @returns {string} The formatted message with placeholders replaced
|
||||||
|
*
|
||||||
|
* @example
|
||||||
|
* formatMessage("Hello {0}, you have {1} messages", ["John", 5])
|
||||||
|
* // Returns: "Hello John, you have 5 messages"
|
||||||
|
*
|
||||||
|
* formatMessage("Error {0}: {1}", "404", "Not Found")
|
||||||
|
* // Returns: "Error 404: Not Found"
|
||||||
|
*/
|
||||||
|
function formatMessage(template, ...args) {
|
||||||
|
if (!template || typeof template !== 'string') {
|
||||||
|
return template || '';
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle case where first argument is an array
|
||||||
|
const argumentArray = Array.isArray(args[0]) ? args[0] : args;
|
||||||
|
|
||||||
|
// Replace {0}, {1}, {2}, etc. with corresponding arguments
|
||||||
|
return template.replace(/\{(\d+)\}/g, function(match, index) {
|
||||||
|
const argIndex = parseInt(index, 10);
|
||||||
|
return argumentArray[argIndex] !== undefined && argumentArray[argIndex] !== null
|
||||||
|
? String(argumentArray[argIndex])
|
||||||
|
: match; // Keep original placeholder if no argument provided
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Translate and format an error message using the global translation object.
|
||||||
|
* Falls back to the provided fallback message if translation not found.
|
||||||
|
*
|
||||||
|
* @param {string} translationKey - The translation key (e.g., "error.dpiExceedsLimit")
|
||||||
|
* @param {Array} translationArgs - Arguments for placeholder replacement
|
||||||
|
* @param {string} fallbackMessage - Fallback message if translation not found
|
||||||
|
* @returns {string} The translated and formatted message
|
||||||
|
*/
|
||||||
|
function translateAndFormat(translationKey, translationArgs, fallbackMessage) {
|
||||||
|
if (!window.stirlingPDF || !window.stirlingPDF.translations) {
|
||||||
|
return fallbackMessage || translationKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
const template = window.stirlingPDF.translations[translationKey];
|
||||||
|
if (!template) {
|
||||||
|
return fallbackMessage || translationKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
return formatMessage(template, translationArgs || []);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Public API
|
||||||
|
return {
|
||||||
|
format: formatMessage,
|
||||||
|
translate: translateAndFormat
|
||||||
|
};
|
||||||
|
})();
|
@ -86,6 +86,7 @@
|
|||||||
<script th:src="@{'/js/tab-container.js'}"></script>
|
<script th:src="@{'/js/tab-container.js'}"></script>
|
||||||
<script th:src="@{'/js/darkmode.js'}"></script>
|
<script th:src="@{'/js/darkmode.js'}"></script>
|
||||||
<script th:src="@{'/js/csrf.js'}"></script>
|
<script th:src="@{'/js/csrf.js'}"></script>
|
||||||
|
<script th:src="@{'/js/messageFormatter.js'}"></script>
|
||||||
<script th:inline="javascript">
|
<script th:inline="javascript">
|
||||||
|
|
||||||
function UpdatePosthogConsent(){
|
function UpdatePosthogConsent(){
|
||||||
|
Loading…
x
Reference in New Issue
Block a user