diff --git a/common/build.gradle b/common/build.gradle index bb8503de9..7d7111d6c 100644 --- a/common/build.gradle +++ b/common/build.gradle @@ -27,5 +27,5 @@ dependencies { api 'jakarta.servlet:jakarta.servlet-api:6.1.0' api 'org.snakeyaml:snakeyaml-engine:2.9' api "org.springdoc:springdoc-openapi-starter-webmvc-ui:2.8.9" - api 'jakarta.mail:jakarta.mail-api:2.1.3' + api 'com.sun.mail:jakarta.mail:2.0.1' } diff --git a/common/src/main/java/stirling/software/common/util/EmlToPdf.java b/common/src/main/java/stirling/software/common/util/EmlToPdf.java index c11b4db4c..1e6b2eca5 100644 --- a/common/src/main/java/stirling/software/common/util/EmlToPdf.java +++ b/common/src/main/java/stirling/software/common/util/EmlToPdf.java @@ -1,5 +1,7 @@ package stirling.software.common.util; +import static stirling.software.common.util.PDFAttachmentUtils.setCatalogViewerPreferences; + import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; @@ -20,10 +22,7 @@ import java.util.Properties; import java.util.regex.Matcher; import java.util.regex.Pattern; -import org.apache.pdfbox.cos.COSDictionary; -import org.apache.pdfbox.cos.COSName; import org.apache.pdfbox.pdmodel.PDDocument; -import org.apache.pdfbox.pdmodel.PDDocumentCatalog; import org.apache.pdfbox.pdmodel.PDDocumentNameDictionary; import org.apache.pdfbox.pdmodel.PDEmbeddedFilesNameTreeNode; import org.apache.pdfbox.pdmodel.PDPage; @@ -43,7 +42,8 @@ import lombok.experimental.UtilityClass; import lombok.extern.slf4j.Slf4j; import stirling.software.common.model.api.converters.EmlToPdfRequest; -import static stirling.software.common.util.PDFAttachmentUtils.setCatalogViewerPreferences; +import stirling.software.common.model.api.converters.HTMLToPdfRequest; +import stirling.software.common.service.CustomPDFDocumentFactory; @Slf4j @UtilityClass @@ -197,8 +197,7 @@ public class EmlToPdf { boolean disableSanitize) throws IOException, InterruptedException { - stirling.software.common.model.api.converters.HTMLToPdfRequest htmlRequest = - createHtmlRequest(request); + HTMLToPdfRequest htmlRequest = createHtmlRequest(request); try { return FileToPdf.convertHtmlToPdf( @@ -882,33 +881,33 @@ public class EmlToPdf { Class messageClass = message.getClass(); // Extract headers via reflection - java.lang.reflect.Method getSubject = messageClass.getMethod("getSubject"); + Method getSubject = messageClass.getMethod("getSubject"); String subject = (String) getSubject.invoke(message); content.setSubject(subject != null ? safeMimeDecode(subject) : "No Subject"); - java.lang.reflect.Method getFrom = messageClass.getMethod("getFrom"); + Method getFrom = messageClass.getMethod("getFrom"); Object[] fromAddresses = (Object[]) getFrom.invoke(message); content.setFrom( fromAddresses != null && fromAddresses.length > 0 ? safeMimeDecode(fromAddresses[0].toString()) : ""); - java.lang.reflect.Method getAllRecipients = messageClass.getMethod("getAllRecipients"); + Method getAllRecipients = messageClass.getMethod("getAllRecipients"); Object[] recipients = (Object[]) getAllRecipients.invoke(message); content.setTo( recipients != null && recipients.length > 0 ? safeMimeDecode(recipients[0].toString()) : ""); - java.lang.reflect.Method getSentDate = messageClass.getMethod("getSentDate"); + Method getSentDate = messageClass.getMethod("getSentDate"); content.setDate((Date) getSentDate.invoke(message)); // Extract content - java.lang.reflect.Method getContent = messageClass.getMethod("getContent"); + Method getContent = messageClass.getMethod("getContent"); Object messageContent = getContent.invoke(message); if (messageContent instanceof String stringContent) { - java.lang.reflect.Method getContentType = messageClass.getMethod("getContentType"); + Method getContentType = messageClass.getMethod("getContentType"); String contentType = (String) getContentType.invoke(message); if (contentType != null && contentType.toLowerCase().contains("text/html")) { content.setHtmlBody(stringContent); @@ -947,11 +946,10 @@ public class EmlToPdf { } Class multipartClass = multipart.getClass(); - java.lang.reflect.Method getCount = multipartClass.getMethod("getCount"); + Method getCount = multipartClass.getMethod("getCount"); int count = (Integer) getCount.invoke(multipart); - java.lang.reflect.Method getBodyPart = - multipartClass.getMethod("getBodyPart", int.class); + Method getBodyPart = multipartClass.getMethod("getBodyPart", int.class); for (int i = 0; i < count; i++) { Object part = getBodyPart.invoke(multipart, i); @@ -972,12 +970,12 @@ public class EmlToPdf { } Class partClass = part.getClass(); - java.lang.reflect.Method isMimeType = partClass.getMethod("isMimeType", String.class); - java.lang.reflect.Method getContent = partClass.getMethod("getContent"); - java.lang.reflect.Method getDisposition = partClass.getMethod("getDisposition"); - java.lang.reflect.Method getFileName = partClass.getMethod("getFileName"); - java.lang.reflect.Method getContentType = partClass.getMethod("getContentType"); - java.lang.reflect.Method getHeader = partClass.getMethod("getHeader", String.class); + Method isMimeType = partClass.getMethod("isMimeType", String.class); + Method getContent = partClass.getMethod("getContent"); + Method getDisposition = partClass.getMethod("getDisposition"); + Method getFileName = partClass.getMethod("getFileName"); + Method getContentType = partClass.getMethod("getContentType"); + Method getHeader = partClass.getMethod("getHeader", String.class); Object disposition = getDisposition.invoke(part); String filename = (String) getFileName.invoke(part); @@ -1184,7 +1182,7 @@ public class EmlToPdf { private static byte[] attachFilesToPdf( byte[] pdfBytes, List attachments, - stirling.software.common.service.CustomPDFDocumentFactory pdfDocumentFactory) + CustomPDFDocumentFactory pdfDocumentFactory) throws IOException { try (PDDocument document = pdfDocumentFactory.load(pdfBytes); ByteArrayOutputStream outputStream = new ByteArrayOutputStream()) { diff --git a/common/src/main/java/stirling/software/common/util/PDFAttachmentUtils.java b/common/src/main/java/stirling/software/common/util/PDFAttachmentUtils.java index 79737b0c2..ee789da6a 100644 --- a/common/src/main/java/stirling/software/common/util/PDFAttachmentUtils.java +++ b/common/src/main/java/stirling/software/common/util/PDFAttachmentUtils.java @@ -1,12 +1,13 @@ package stirling.software.common.util; -import lombok.extern.slf4j.Slf4j; import org.apache.pdfbox.cos.COSDictionary; import org.apache.pdfbox.cos.COSName; import org.apache.pdfbox.pdmodel.PDDocument; import org.apache.pdfbox.pdmodel.PDDocumentCatalog; import org.apache.pdfbox.pdmodel.PageMode; +import lombok.extern.slf4j.Slf4j; + @Slf4j public class PDFAttachmentUtils { @@ -18,24 +19,29 @@ public class PDFAttachmentUtils { COSDictionary catalogDict = catalog.getCOSObject(); // Set PageMode to UseAttachments - this is the standard PDF specification approach - // PageMode values: UseNone, UseOutlines, UseThumbs, FullScreen, UseOC, UseAttachments + // PageMode values: UseNone, UseOutlines, UseThumbs, FullScreen, UseOC, + // UseAttachments catalog.setPageMode(pageMode); catalogDict.setName(COSName.PAGE_MODE, pageMode.stringValue()); // Also set viewer preferences for better attachment viewing experience - COSDictionary viewerPrefs = (COSDictionary) catalogDict.getDictionaryObject(COSName.VIEWER_PREFERENCES); + COSDictionary viewerPrefs = + (COSDictionary) catalogDict.getDictionaryObject(COSName.VIEWER_PREFERENCES); if (viewerPrefs == null) { viewerPrefs = new COSDictionary(); catalogDict.setItem(COSName.VIEWER_PREFERENCES, viewerPrefs); } - // Set NonFullScreenPageMode to UseAttachments as fallback for viewers that support it - viewerPrefs.setName(COSName.getPDFName("NonFullScreenPageMode"), pageMode.stringValue()); + // Set NonFullScreenPageMode to UseAttachments as fallback for viewers that support + // it + viewerPrefs.setName( + COSName.getPDFName("NonFullScreenPageMode"), pageMode.stringValue()); // Additional viewer preferences that may help with attachment display viewerPrefs.setBoolean(COSName.getPDFName("DisplayDocTitle"), true); - log.info("Set PDF PageMode to UseAttachments to automatically show attachments pane"); + log.info( + "Set PDF PageMode to UseAttachments to automatically show attachments pane"); } } catch (Exception e) { // Log error but don't fail the entire operation for viewer preferences diff --git a/common/src/main/java/stirling/software/common/util/WebResponseUtils.java b/common/src/main/java/stirling/software/common/util/WebResponseUtils.java index 96d446c06..745f5d5ec 100644 --- a/common/src/main/java/stirling/software/common/util/WebResponseUtils.java +++ b/common/src/main/java/stirling/software/common/util/WebResponseUtils.java @@ -44,8 +44,7 @@ public class WebResponseUtils { headers.setContentType(mediaType); headers.setContentLength(bytes.length); String encodedDocName = - URLEncoder.encode(docName, StandardCharsets.UTF_8) - .replaceAll("\\+", "%20"); + URLEncoder.encode(docName, StandardCharsets.UTF_8).replaceAll("\\+", "%20"); headers.setContentDispositionFormData("attachment", encodedDocName); return new ResponseEntity<>(bytes, headers, HttpStatus.OK); } diff --git a/stirling-pdf/src/main/java/stirling/software/SPDF/config/EndpointConfiguration.java b/stirling-pdf/src/main/java/stirling/software/SPDF/config/EndpointConfiguration.java index adab85c62..3e100f08d 100644 --- a/stirling-pdf/src/main/java/stirling/software/SPDF/config/EndpointConfiguration.java +++ b/stirling-pdf/src/main/java/stirling/software/SPDF/config/EndpointConfiguration.java @@ -10,6 +10,7 @@ import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.stereotype.Service; import lombok.extern.slf4j.Slf4j; + import stirling.software.common.model.ApplicationProperties; @Service @@ -83,9 +84,9 @@ public class EndpointConfiguration { } public void disableGroup(String group) { - Set endpoints = endpointGroups.get(group); - if (endpoints != null) { - for (String endpoint : endpoints) { + Set disabledEndpoints = endpointGroups.get(group); + if (disabledEndpoints != null) { + for (String endpoint : disabledEndpoints) { disableEndpoint(endpoint); } } diff --git a/stirling-pdf/src/main/java/stirling/software/SPDF/controller/api/misc/AttachmentController.java b/stirling-pdf/src/main/java/stirling/software/SPDF/controller/api/misc/AttachmentController.java new file mode 100644 index 000000000..fce8273e5 --- /dev/null +++ b/stirling-pdf/src/main/java/stirling/software/SPDF/controller/api/misc/AttachmentController.java @@ -0,0 +1,57 @@ +package stirling.software.SPDF.controller.api.misc; + +import java.io.IOException; +import java.util.List; + +import org.apache.pdfbox.pdmodel.PDDocument; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.multipart.MultipartFile; + +import io.github.pixee.security.Filenames; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; + +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; + +import stirling.software.SPDF.service.AttachmentServiceInterface; +import stirling.software.common.service.CustomPDFDocumentFactory; +import stirling.software.common.util.WebResponseUtils; + +@Slf4j +@RestController +@RequiredArgsConstructor +@RequestMapping("/api/v1/misc") +@Tag(name = "Misc", description = "Miscellaneous APIs") +public class AttachmentController { + + private final CustomPDFDocumentFactory pdfDocumentFactory; + + private final AttachmentServiceInterface pdfAttachmentService; + + @SuppressWarnings("DataFlowIssue") + @PostMapping(consumes = "multipart/form-data", value = "/add-attachments") + @Operation( + summary = "Add attachments to PDF", + description = + "This endpoint adds embedded files (attachments) to a PDF and sets the PageMode to UseAttachments to make them visible. Input:PDF + Files Output:PDF Type:MISO") + public ResponseEntity addAttachments( + @RequestParam("fileInput") MultipartFile pdfFile, + @RequestParam("attachments") List attachments) + throws IOException { + + PDDocument document = + pdfAttachmentService.addAttachment( + pdfDocumentFactory.load(pdfFile, false), attachments); + + return WebResponseUtils.pdfDocToWebResponse( + document, + Filenames.toSimpleFileName(pdfFile.getOriginalFilename()) + .replaceFirst("[.][^.]+$", "") + + "_with_attachments.pdf"); + } +} diff --git a/stirling-pdf/src/main/java/stirling/software/SPDF/controller/api/misc/AttachmentsController.java b/stirling-pdf/src/main/java/stirling/software/SPDF/controller/api/misc/AttachmentsController.java deleted file mode 100644 index 9f5bacb1b..000000000 --- a/stirling-pdf/src/main/java/stirling/software/SPDF/controller/api/misc/AttachmentsController.java +++ /dev/null @@ -1,100 +0,0 @@ -package stirling.software.SPDF.controller.api.misc; - -import java.io.IOException; -import java.util.List; - -import org.apache.pdfbox.pdmodel.*; -import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.*; -import org.springframework.web.multipart.MultipartFile; - -import io.github.pixee.security.Filenames; -import io.swagger.v3.oas.annotations.Operation; -import io.swagger.v3.oas.annotations.tags.Tag; - -import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; - -import stirling.software.SPDF.service.PDFAttachmentServiceInterface; -import stirling.software.common.service.CustomPDFDocumentFactory; -import stirling.software.common.util.WebResponseUtils; - -@Slf4j -@RestController -@RequiredArgsConstructor -@RequestMapping("/api/v1/misc") -@Tag(name = "Misc", description = "Miscellaneous APIs") -public class AttachmentsController { - - private final CustomPDFDocumentFactory pdfDocumentFactory; - - private final PDFAttachmentServiceInterface pdfAttachmentService; - - @SuppressWarnings("DataFlowIssue") - @PostMapping(consumes = "multipart/form-data", value = "/add-attachments") - @Operation( - summary = "Add attachments to PDF", - description = - "This endpoint adds embedded files (attachments) to a PDF and sets the PageMode to UseAttachments to make them visible. Input:PDF + Files Output:PDF Type:MISO") - public ResponseEntity addAttachments( - @RequestParam("fileInput") MultipartFile pdfFile, - @RequestParam("attachments") List attachments) - throws IOException { - - // Load the PDF document - PDDocument document = pdfDocumentFactory.load(pdfFile, false); - - // Get or create the document catalog - PDDocumentCatalog catalog = document.getDocumentCatalog(); - - // Create embedded files name tree if it doesn't exist - PDDocumentNameDictionary documentNames = catalog.getNames(); - PDEmbeddedFilesNameTreeNode embeddedFilesTree = new PDEmbeddedFilesNameTreeNode(); - - if (documentNames != null) { - embeddedFilesTree = documentNames.getEmbeddedFiles(); - } else { - documentNames = new PDDocumentNameDictionary(catalog); - documentNames.setEmbeddedFiles(embeddedFilesTree); - } - - // Add attachments - catalog.setNames(documentNames); - byte[] output = - pdfAttachmentService.addAttachment(document, embeddedFilesTree, attachments); - - return WebResponseUtils.bytesToWebResponse( - output, - Filenames.toSimpleFileName(pdfFile.getOriginalFilename()) - .replaceFirst("[.][^.]+$", "") - + "_with_attachments.pdf"); - } - - @PostMapping(consumes = "multipart/form-data", value = "/remove-attachments") - @Operation( - summary = "Remove attachments from PDF", - description = - "This endpoint removes all embedded files (attachments) from a PDF. Input:PDF Output:PDF Type:SISO") - public ResponseEntity removeAttachments( - @RequestParam("fileInput") MultipartFile pdfFile) throws IOException { - - // Load the PDF document and document catalog - PDDocument document = pdfDocumentFactory.load(pdfFile); - PDDocumentCatalog catalog = document.getDocumentCatalog(); - - // Remove embedded files - if (catalog.getNames() != null) { - catalog.getNames().setEmbeddedFiles(null); - } - - // Reset PageMode to UseNone (default) - catalog.setPageMode(PageMode.USE_NONE); - - // Return the modified PDF - return WebResponseUtils.pdfDocToWebResponse( - document, - Filenames.toSimpleFileName(pdfFile.getOriginalFilename()) - .replaceFirst("[.][^.]+$", "") - + "_attachments_removed.pdf"); - } -} diff --git a/stirling-pdf/src/main/java/stirling/software/SPDF/service/PDFAttachmentService.java b/stirling-pdf/src/main/java/stirling/software/SPDF/service/AttachmentService.java similarity index 54% rename from stirling-pdf/src/main/java/stirling/software/SPDF/service/PDFAttachmentService.java rename to stirling-pdf/src/main/java/stirling/software/SPDF/service/AttachmentService.java index d7db7c696..c9956aec3 100644 --- a/stirling-pdf/src/main/java/stirling/software/SPDF/service/PDFAttachmentService.java +++ b/stirling-pdf/src/main/java/stirling/software/SPDF/service/AttachmentService.java @@ -1,6 +1,7 @@ package stirling.software.SPDF.service; -import java.io.ByteArrayOutputStream; +import static stirling.software.common.util.PDFAttachmentUtils.setCatalogViewerPreferences; + import java.io.IOException; import java.util.GregorianCalendar; import java.util.HashMap; @@ -9,48 +10,53 @@ import java.util.Map; import org.apache.commons.lang3.StringUtils; import org.apache.pdfbox.pdmodel.PDDocument; +import org.apache.pdfbox.pdmodel.PDDocumentCatalog; +import org.apache.pdfbox.pdmodel.PDDocumentNameDictionary; import org.apache.pdfbox.pdmodel.PDEmbeddedFilesNameTreeNode; import org.apache.pdfbox.pdmodel.PageMode; import org.apache.pdfbox.pdmodel.common.filespecification.PDComplexFileSpecification; import org.apache.pdfbox.pdmodel.common.filespecification.PDEmbeddedFile; -import org.apache.pdfbox.pdmodel.encryption.AccessPermission; -import org.apache.pdfbox.pdmodel.encryption.StandardProtectionPolicy; import org.springframework.stereotype.Service; import org.springframework.web.multipart.MultipartFile; import lombok.extern.slf4j.Slf4j; -import stirling.software.common.util.PDFAttachmentUtils; - @Slf4j @Service -public class PDFAttachmentService implements PDFAttachmentServiceInterface { +public class AttachmentService implements AttachmentServiceInterface { @Override - public byte[] addAttachment( - PDDocument document, - PDEmbeddedFilesNameTreeNode embeddedFilesTree, - List attachments) + public PDDocument addAttachment(PDDocument document, List attachments) throws IOException { + PDDocumentCatalog catalog = document.getDocumentCatalog(); + PDDocumentNameDictionary documentNames = catalog.getNames(); + PDEmbeddedFilesNameTreeNode embeddedFilesTree = new PDEmbeddedFilesNameTreeNode(); + + if (documentNames != null) { + embeddedFilesTree = documentNames.getEmbeddedFiles(); + } else { + documentNames = new PDDocumentNameDictionary(catalog); + documentNames.setEmbeddedFiles(embeddedFilesTree); + } + + catalog.setNames(documentNames); Map existingNames; try { - existingNames = embeddedFilesTree.getNames(); + Map originalNames = embeddedFilesTree.getNames(); - if (existingNames == null) { + if (originalNames == null) { log.debug("No existing embedded files found, creating new names map."); existingNames = new HashMap<>(); + } else { + existingNames = new HashMap<>(originalNames); + log.debug("Embedded files: {}", existingNames.keySet()); } - - log.debug("Embedded files: {}", existingNames.keySet()); } catch (IOException e) { log.error("Could not retrieve existing embedded files", e); throw e; } - grantAccessPermissions(document); - final Map existingEmbeddedFiles = existingNames; - attachments.forEach( attachment -> { String filename = attachment.getOriginalFilename(); @@ -73,12 +79,10 @@ public class PDFAttachmentService implements PDFAttachmentServiceInterface { fileSpecification.setFile(filename); fileSpecification.setFileUnicode(filename); fileSpecification.setFileDescription("Embedded attachment: " + filename); - embeddedFile.setFile(fileSpecification); fileSpecification.setEmbeddedFile(embeddedFile); fileSpecification.setEmbeddedFileUnicode(embeddedFile); - // Add to the existing files map - existingEmbeddedFiles.put(filename, fileSpecification); + existingNames.put(filename, fileSpecification); log.info("Added attachment: {} ({} bytes)", filename, attachment.getSize()); } catch (IOException e) { @@ -87,39 +91,8 @@ public class PDFAttachmentService implements PDFAttachmentServiceInterface { }); embeddedFilesTree.setNames(existingNames); - PDFAttachmentUtils.setCatalogViewerPreferences(document, PageMode.USE_ATTACHMENTS); - ByteArrayOutputStream output = new ByteArrayOutputStream(); - document.save(output); + setCatalogViewerPreferences(document, PageMode.USE_ATTACHMENTS); - return output.toByteArray(); - } - - private void grantAccessPermissions(PDDocument document) { - try { - AccessPermission currentPermissions = document.getCurrentAccessPermission(); - - currentPermissions.setCanAssembleDocument(true); - currentPermissions.setCanFillInForm(currentPermissions.canFillInForm()); - currentPermissions.setCanModify(true); - currentPermissions.setCanPrint(true); - currentPermissions.setCanPrintFaithful(true); - - // Ensure these permissions are enabled for embedded file access - currentPermissions.setCanExtractContent(true); - currentPermissions.setCanExtractForAccessibility(true); - currentPermissions.setCanModifyAnnotations(true); - - var protectionPolicy = new StandardProtectionPolicy(null, null, currentPermissions); - - if (!document.isAllSecurityToBeRemoved()) { - document.setAllSecurityToBeRemoved(true); - } - - document.protect(protectionPolicy); - ByteArrayOutputStream output = new ByteArrayOutputStream(); - document.save(output); - } catch (IOException e) { - throw new RuntimeException(e); - } + return document; } } diff --git a/stirling-pdf/src/main/java/stirling/software/SPDF/service/AttachmentServiceInterface.java b/stirling-pdf/src/main/java/stirling/software/SPDF/service/AttachmentServiceInterface.java new file mode 100644 index 000000000..c684a429d --- /dev/null +++ b/stirling-pdf/src/main/java/stirling/software/SPDF/service/AttachmentServiceInterface.java @@ -0,0 +1,13 @@ +package stirling.software.SPDF.service; + +import java.io.IOException; +import java.util.List; + +import org.apache.pdfbox.pdmodel.PDDocument; +import org.springframework.web.multipart.MultipartFile; + +public interface AttachmentServiceInterface { + + PDDocument addAttachment(PDDocument document, List attachments) + throws IOException; +} diff --git a/stirling-pdf/src/main/java/stirling/software/SPDF/service/PDFAttachmentServiceInterface.java b/stirling-pdf/src/main/java/stirling/software/SPDF/service/PDFAttachmentServiceInterface.java deleted file mode 100644 index 13ed19e6c..000000000 --- a/stirling-pdf/src/main/java/stirling/software/SPDF/service/PDFAttachmentServiceInterface.java +++ /dev/null @@ -1,17 +0,0 @@ -package stirling.software.SPDF.service; - -import java.io.IOException; -import java.util.List; - -import org.apache.pdfbox.pdmodel.PDDocument; -import org.apache.pdfbox.pdmodel.PDEmbeddedFilesNameTreeNode; -import org.springframework.web.multipart.MultipartFile; - -public interface PDFAttachmentServiceInterface { - - byte[] addAttachment( - PDDocument document, - PDEmbeddedFilesNameTreeNode efTree, - List attachments) - throws IOException; -} diff --git a/stirling-pdf/src/main/resources/messages_ar_AR.properties b/stirling-pdf/src/main/resources/messages_ar_AR.properties index 36617425a..94efd646e 100644 --- a/stirling-pdf/src/main/resources/messages_ar_AR.properties +++ b/stirling-pdf/src/main/resources/messages_ar_AR.properties @@ -1205,6 +1205,13 @@ addImage.everyPage=كل صفحة؟ addImage.upload=إضافة صورة addImage.submit=إضافة صورة +#attachments +attachments.title=Add Attachments +attachments.header=Add attachments +attachments.description=Allows you to add attachments to the PDF +attachments.descriptionPlaceholder=Enter a description for the attachments... +attachments.addButton=Add Attachments + #merge merge.title=دمج @@ -1594,6 +1601,7 @@ fileChooser.dragAndDropPDF=Drag & Drop PDF file fileChooser.dragAndDropImage=Drag & Drop Image file fileChooser.hoveredDragAndDrop=قم بسحب المفات وإفلاتها هنا fileChooser.extractPDF=جاري الاستخراج... +fileChooser.addAttachments=drag & drop attachments here #release notes releases.footer=Releases diff --git a/stirling-pdf/src/main/resources/messages_az_AZ.properties b/stirling-pdf/src/main/resources/messages_az_AZ.properties index bde60af71..db93748ca 100644 --- a/stirling-pdf/src/main/resources/messages_az_AZ.properties +++ b/stirling-pdf/src/main/resources/messages_az_AZ.properties @@ -1594,6 +1594,7 @@ fileChooser.dragAndDropPDF=Drag & Drop PDF file fileChooser.dragAndDropImage=Drag & Drop Image file fileChooser.hoveredDragAndDrop=Drag & Drop file(s) here fileChooser.extractPDF=Extracting... +fileChooser.addAttachments=drag & drop attachments here #release notes releases.footer=Buraxılışlar diff --git a/stirling-pdf/src/main/resources/messages_bg_BG.properties b/stirling-pdf/src/main/resources/messages_bg_BG.properties index a7167eead..27ad5601f 100644 --- a/stirling-pdf/src/main/resources/messages_bg_BG.properties +++ b/stirling-pdf/src/main/resources/messages_bg_BG.properties @@ -1594,6 +1594,7 @@ fileChooser.dragAndDropPDF=Влачете и пуснете PDF файл fileChooser.dragAndDropImage=Влачете и пуснете изображение fileChooser.hoveredDragAndDrop=Влачете и пуснете файл(ове) тук fileChooser.extractPDF=Извличане... +fileChooser.addAttachments=drag & drop attachments here #release notes releases.footer=Версии diff --git a/stirling-pdf/src/main/resources/messages_bo_CN.properties b/stirling-pdf/src/main/resources/messages_bo_CN.properties index e0fdbf651..cd6bf9c19 100644 --- a/stirling-pdf/src/main/resources/messages_bo_CN.properties +++ b/stirling-pdf/src/main/resources/messages_bo_CN.properties @@ -1594,6 +1594,7 @@ fileChooser.dragAndDropPDF=PDF ཡིག་ཆ་འཐེན་ནས་འཇ fileChooser.dragAndDropImage=པར་རིས་ཡིག་ཆ་འཐེན་ནས་འཇོག་པ། fileChooser.hoveredDragAndDrop=ཡིག་ཆ་འདིར་འཐེན་ནས་འཇོག་པ། fileChooser.extractPDF=འདོན་རིས་འགྱུར་བའི་སྒྲིག་བཏང་བ། +fileChooser.addAttachments=drag & drop attachments here #release notes releases.footer=པར་གཞི། diff --git a/stirling-pdf/src/main/resources/messages_ca_CA.properties b/stirling-pdf/src/main/resources/messages_ca_CA.properties index 063f8393e..61cf16a8d 100644 --- a/stirling-pdf/src/main/resources/messages_ca_CA.properties +++ b/stirling-pdf/src/main/resources/messages_ca_CA.properties @@ -1594,7 +1594,7 @@ fileChooser.dragAndDropPDF=Arrossega i deixa anar un fitxer PDF fileChooser.dragAndDropImage=Arrossega i deixa anar un fitxer d'imatge fileChooser.hoveredDragAndDrop=Arrossega i deixa anar fitxer(s) aquí fileChooser.extractPDF=Extracting... - +fileChooser.addAttachments=drag & drop attachments here #release notes releases.footer=Llançaments releases.title=Notes de Llançament diff --git a/stirling-pdf/src/main/resources/messages_cs_CZ.properties b/stirling-pdf/src/main/resources/messages_cs_CZ.properties index 41a2ae9f9..8b060e394 100644 --- a/stirling-pdf/src/main/resources/messages_cs_CZ.properties +++ b/stirling-pdf/src/main/resources/messages_cs_CZ.properties @@ -1594,7 +1594,7 @@ fileChooser.dragAndDropPDF=Přetáhnout PDF soubor fileChooser.dragAndDropImage=Přetáhnout obrázek fileChooser.hoveredDragAndDrop=Přetáhněte soubor(y) sem fileChooser.extractPDF=Extrahování... - +fileChooser.addAttachments=drag & drop attachments here #release notes releases.footer=Vydání releases.title=Poznámky k vydání diff --git a/stirling-pdf/src/main/resources/messages_da_DK.properties b/stirling-pdf/src/main/resources/messages_da_DK.properties index 31a2193f4..d2574b109 100644 --- a/stirling-pdf/src/main/resources/messages_da_DK.properties +++ b/stirling-pdf/src/main/resources/messages_da_DK.properties @@ -1594,7 +1594,7 @@ fileChooser.dragAndDropPDF=Drag & Drop PDF file fileChooser.dragAndDropImage=Drag & Drop Image file fileChooser.hoveredDragAndDrop=Drag & Drop file(s) here fileChooser.extractPDF=Extracting... - +fileChooser.addAttachments=drag & drop attachments here #release notes releases.footer=Releases releases.title=Release Notes diff --git a/stirling-pdf/src/main/resources/messages_de_DE.properties b/stirling-pdf/src/main/resources/messages_de_DE.properties index ac69fdd8e..bf0daa254 100644 --- a/stirling-pdf/src/main/resources/messages_de_DE.properties +++ b/stirling-pdf/src/main/resources/messages_de_DE.properties @@ -1594,6 +1594,7 @@ fileChooser.dragAndDropPDF=Drag & Drop PDF-Datei fileChooser.dragAndDropImage=Drag & Drop Bilddatei fileChooser.hoveredDragAndDrop=Datei(en) hierhin Ziehen & Fallenlassen fileChooser.extractPDF=Extrahiere... +fileChooser.addAttachments=drag & drop attachments here #release notes releases.footer=Veröffentlichungen diff --git a/stirling-pdf/src/main/resources/messages_el_GR.properties b/stirling-pdf/src/main/resources/messages_el_GR.properties index 9c3966d98..c4e9e90b2 100644 --- a/stirling-pdf/src/main/resources/messages_el_GR.properties +++ b/stirling-pdf/src/main/resources/messages_el_GR.properties @@ -1594,7 +1594,7 @@ fileChooser.dragAndDropPDF=Σύρετε & αφήστε αρχείο PDF fileChooser.dragAndDropImage=Σύρετε & αφήστε αρχείο εικόνας fileChooser.hoveredDragAndDrop=Σύρετε & αφήστε αρχείο(α) εδώ fileChooser.extractPDF=Εξαγωγή... - +fileChooser.addAttachments=drag & drop attachments here #release notes releases.footer=Εκδόσεις releases.title=Σημειώσεις έκδοσης diff --git a/stirling-pdf/src/main/resources/messages_en_GB.properties b/stirling-pdf/src/main/resources/messages_en_GB.properties index 8b127171e..d28657b91 100644 --- a/stirling-pdf/src/main/resources/messages_en_GB.properties +++ b/stirling-pdf/src/main/resources/messages_en_GB.properties @@ -1212,13 +1212,9 @@ addImage.submit=Add image #attachments attachments.title=Add Attachments attachments.header=Add attachments -attachments.removeHeader=Remove attachments from PDF -attachments.selectFiles=Select files to attach attachments.description=Allows you to add attachments to the PDF attachments.descriptionPlaceholder=Enter a description for the attachments... attachments.addButton=Add Attachments -attachments.removeDescription=This will remove all embedded files from the PDF. -attachments.removeButton=Remove All Attachments #merge merge.title=Merge @@ -1608,6 +1604,7 @@ fileChooser.dragAndDropPDF=Drag & Drop PDF file fileChooser.dragAndDropImage=Drag & Drop Image file fileChooser.hoveredDragAndDrop=Drag & Drop file(s) here fileChooser.extractPDF=Extracting... +fileChooser.addAttachments=drag & drop attachments here #release notes releases.footer=Releases diff --git a/stirling-pdf/src/main/resources/messages_en_US.properties b/stirling-pdf/src/main/resources/messages_en_US.properties index 53ebb45d4..40b33747f 100644 --- a/stirling-pdf/src/main/resources/messages_en_US.properties +++ b/stirling-pdf/src/main/resources/messages_en_US.properties @@ -1210,15 +1210,11 @@ addImage.submit=Add image #attachments -attachments.title=Attachments +attachments.title=Add Attachments attachments.header=Add attachments -attachments.removeHeader=Remove attachments from PDF -attachments.selectFiles=Select files to attach attachments.description=Allows you to add attachments to the PDF attachments.descriptionPlaceholder=Enter a description for the attachments... attachments.addButton=Add Attachments -attachments.removeDescription=This will remove all embedded files from the PDF. -attachments.removeButton=Remove All Attachments #merge @@ -1609,6 +1605,7 @@ fileChooser.dragAndDropPDF=Drag & Drop PDF file fileChooser.dragAndDropImage=Drag & Drop Image file fileChooser.hoveredDragAndDrop=Drag & Drop file(s) here fileChooser.extractPDF=Extracting... +fileChooser.addAttachments=drag & drop attachments here #release notes releases.footer=Releases diff --git a/stirling-pdf/src/main/resources/messages_es_ES.properties b/stirling-pdf/src/main/resources/messages_es_ES.properties index e5411f38c..30eee6063 100644 --- a/stirling-pdf/src/main/resources/messages_es_ES.properties +++ b/stirling-pdf/src/main/resources/messages_es_ES.properties @@ -1205,6 +1205,12 @@ addImage.everyPage=¿Todas las páginas? addImage.upload=Añadir imagen addImage.submit=Enviar imagen +#attachments +attachments.title=Add Attachments +attachments.header=Add attachments +attachments.description=Allows you to add attachments to the PDF +attachments.descriptionPlaceholder=Enter a description for the attachments... +attachments.addButton=Add Attachments #merge merge.title=Unir @@ -1594,6 +1600,7 @@ fileChooser.dragAndDropPDF=Arrastrar & Soltar archivo PDF fileChooser.dragAndDropImage=Arrastrar & Soltar archivo de Imagen fileChooser.hoveredDragAndDrop=Arrastrar & Soltar archivos(s) aquí fileChooser.extractPDF=Extrayendo... +fileChooser.addAttachments=drag & drop attachments here #release notes releases.footer=Versiones diff --git a/stirling-pdf/src/main/resources/messages_eu_ES.properties b/stirling-pdf/src/main/resources/messages_eu_ES.properties index 0593b8df4..9c90fca28 100644 --- a/stirling-pdf/src/main/resources/messages_eu_ES.properties +++ b/stirling-pdf/src/main/resources/messages_eu_ES.properties @@ -1594,6 +1594,7 @@ fileChooser.dragAndDropPDF=Drag & Drop PDF file fileChooser.dragAndDropImage=Drag & Drop Image file fileChooser.hoveredDragAndDrop=Drag & Drop file(s) here fileChooser.extractPDF=Extracting... +fileChooser.addAttachments=drag & drop attachments here #release notes releases.footer=Releases diff --git a/stirling-pdf/src/main/resources/messages_fa_IR.properties b/stirling-pdf/src/main/resources/messages_fa_IR.properties index b37917f2f..3d2388b91 100644 --- a/stirling-pdf/src/main/resources/messages_fa_IR.properties +++ b/stirling-pdf/src/main/resources/messages_fa_IR.properties @@ -1205,6 +1205,13 @@ addImage.everyPage=هر صفحه؟ addImage.upload=افزودن تصویر addImage.submit=افزودن تصویر +#attachments +attachments.title=Add Attachments +attachments.header=Add attachments +attachments.description=Allows you to add attachments to the PDF +attachments.descriptionPlaceholder=Enter a description for the attachments... +attachments.addButton=Add Attachments + #merge merge.title=ادغام @@ -1594,6 +1601,7 @@ fileChooser.dragAndDropPDF=Drag & Drop PDF file fileChooser.dragAndDropImage=Drag & Drop Image file fileChooser.hoveredDragAndDrop=فایل(های) خود را اینجا بکشید و رها کنید fileChooser.extractPDF=در حال استخراج... +fileChooser.addAttachments=drag & drop attachments here #release notes releases.footer=نسخه‌ها diff --git a/stirling-pdf/src/main/resources/messages_fr_FR.properties b/stirling-pdf/src/main/resources/messages_fr_FR.properties index 6b674cb9e..9e9f49b52 100644 --- a/stirling-pdf/src/main/resources/messages_fr_FR.properties +++ b/stirling-pdf/src/main/resources/messages_fr_FR.properties @@ -1205,6 +1205,13 @@ addImage.everyPage=Toutes les pages ? addImage.upload=Télécharger une image addImage.submit=Ajouter une image +#attachments +attachments.title=Add Attachments +attachments.header=Add attachments +attachments.description=Allows you to add attachments to the PDF +attachments.descriptionPlaceholder=Enter a description for the attachments... +attachments.addButton=Add Attachments + #merge merge.title=Fusionner @@ -1594,6 +1601,7 @@ fileChooser.dragAndDropPDF=Drag & Drop PDF file fileChooser.dragAndDropImage=Drag & Drop Image file fileChooser.hoveredDragAndDrop=Glisser & Déposer le(s) fichier(s) ici fileChooser.extractPDF=Extraction en cours... +fileChooser.addAttachments=drag & drop attachments here #release notes releases.footer=Versions diff --git a/stirling-pdf/src/main/resources/messages_ga_IE.properties b/stirling-pdf/src/main/resources/messages_ga_IE.properties index 09f61437c..bf6820cbc 100644 --- a/stirling-pdf/src/main/resources/messages_ga_IE.properties +++ b/stirling-pdf/src/main/resources/messages_ga_IE.properties @@ -1205,6 +1205,13 @@ addImage.everyPage=Gach Leathanach? addImage.upload=Cuir íomhá leis addImage.submit=Cuir íomhá leis +#attachments +attachments.title=Add Attachments +attachments.header=Add attachments +attachments.description=Allows you to add attachments to the PDF +attachments.descriptionPlaceholder=Enter a description for the attachments... +attachments.addButton=Add Attachments + #merge merge.title=Cumaisc @@ -1594,6 +1601,7 @@ fileChooser.dragAndDropPDF=Tarraing & Scaoil comhad PDF fileChooser.dragAndDropImage=Tarraing & Scaoil comhad Íomhá fileChooser.hoveredDragAndDrop=Tarraing agus scaoil comhad(í) anseo fileChooser.extractPDF=Ag Aistriú... +fileChooser.addAttachments=drag & drop attachments here #release notes releases.footer=Eisiúintí diff --git a/stirling-pdf/src/main/resources/messages_hi_IN.properties b/stirling-pdf/src/main/resources/messages_hi_IN.properties index 7ea02ae0f..1092bb901 100644 --- a/stirling-pdf/src/main/resources/messages_hi_IN.properties +++ b/stirling-pdf/src/main/resources/messages_hi_IN.properties @@ -1205,6 +1205,13 @@ addImage.everyPage=हर पृष्ठ? addImage.upload=छवि जोड़ें addImage.submit=छवि जोड़ें +#attachments +attachments.title=Add Attachments +attachments.header=Add attachments +attachments.description=Allows you to add attachments to the PDF +attachments.descriptionPlaceholder=Enter a description for the attachments... +attachments.addButton=Add Attachments + #merge merge.title=मर्ज करें @@ -1594,6 +1601,7 @@ fileChooser.dragAndDropPDF=PDF फ़ाइल खींचें और छो fileChooser.dragAndDropImage=छवि फ़ाइल खींचें और छोड़ें fileChooser.hoveredDragAndDrop=फ़ाइल(ें) यहाँ खींचें और छोड़ें fileChooser.extractPDF=निकालना... +fileChooser.addAttachments=drag & drop attachments here #release notes releases.footer=रिलीज़ diff --git a/stirling-pdf/src/main/resources/messages_hr_HR.properties b/stirling-pdf/src/main/resources/messages_hr_HR.properties index 49b2b36ad..5d8963f69 100644 --- a/stirling-pdf/src/main/resources/messages_hr_HR.properties +++ b/stirling-pdf/src/main/resources/messages_hr_HR.properties @@ -1206,6 +1206,14 @@ addImage.upload=Dodaj sliku addImage.submit=Dodaj sliku +#attachments +attachments.title=Add Attachments +attachments.header=Add attachments +attachments.description=Allows you to add attachments to the PDF +attachments.descriptionPlaceholder=Enter a description for the attachments... +attachments.addButton=Add Attachments + + #merge merge.title=Spajanje merge.header=Spajanje više PDF-ova (2+) @@ -1594,6 +1602,7 @@ fileChooser.dragAndDropPDF=Drag & Drop PDF file fileChooser.dragAndDropImage=Drag & Drop Image file fileChooser.hoveredDragAndDrop=Drag & Drop file(s) here fileChooser.extractPDF=Extracting... +fileChooser.addAttachments=drag & drop attachments here #release notes releases.footer=Releases diff --git a/stirling-pdf/src/main/resources/messages_hu_HU.properties b/stirling-pdf/src/main/resources/messages_hu_HU.properties index eee163a92..c497bb514 100644 --- a/stirling-pdf/src/main/resources/messages_hu_HU.properties +++ b/stirling-pdf/src/main/resources/messages_hu_HU.properties @@ -1205,6 +1205,13 @@ addImage.everyPage=Minden oldalra? addImage.upload=Kép hozzáadása addImage.submit=Kép hozzáadása +#attachments +attachments.title=Add Attachments +attachments.header=Add attachments +attachments.description=Allows you to add attachments to the PDF +attachments.descriptionPlaceholder=Enter a description for the attachments... +attachments.addButton=Add Attachments + #merge merge.title=Egyesítés @@ -1594,6 +1601,7 @@ fileChooser.dragAndDropPDF=Húzza ide a PDF fájlt fileChooser.dragAndDropImage=Húzza ide a képfájlt fileChooser.hoveredDragAndDrop=Húzza ide a fájl(oka)t fileChooser.extractPDF=Kinyerés... +fileChooser.addAttachments=drag & drop attachments here #release notes releases.footer=Kiadási jegyzék diff --git a/stirling-pdf/src/main/resources/messages_id_ID.properties b/stirling-pdf/src/main/resources/messages_id_ID.properties index d5a38442c..69704acb3 100644 --- a/stirling-pdf/src/main/resources/messages_id_ID.properties +++ b/stirling-pdf/src/main/resources/messages_id_ID.properties @@ -1206,6 +1206,14 @@ addImage.upload=Tambahkan Gambar addImage.submit=Tambahkan Gambar +#attachments +attachments.title=Add Attachments +attachments.header=Add attachments +attachments.description=Allows you to add attachments to the PDF +attachments.descriptionPlaceholder=Enter a description for the attachments... +attachments.addButton=Add Attachments + + #merge merge.title=Gabungkan merge.header=Gabungkan beberapa PDFs (2+) @@ -1594,6 +1602,7 @@ fileChooser.dragAndDropPDF=Drag & Drop PDF file fileChooser.dragAndDropImage=Drag & Drop Image file fileChooser.hoveredDragAndDrop=Drag & Drop file(s) here fileChooser.extractPDF=Extracting... +fileChooser.addAttachments=drag & drop attachments here #release notes releases.footer=Releases diff --git a/stirling-pdf/src/main/resources/messages_it_IT.properties b/stirling-pdf/src/main/resources/messages_it_IT.properties index 06662dccc..541d66872 100644 --- a/stirling-pdf/src/main/resources/messages_it_IT.properties +++ b/stirling-pdf/src/main/resources/messages_it_IT.properties @@ -1205,6 +1205,13 @@ addImage.everyPage=Ogni pagina? addImage.upload=Aggiungi immagine addImage.submit=Aggiungi immagine +#attachments +attachments.title=Add Attachments +attachments.header=Add attachments +attachments.description=Allows you to add attachments to the PDF +attachments.descriptionPlaceholder=Enter a description for the attachments... +attachments.addButton=Add Attachments + #merge merge.title=Unisci @@ -1594,6 +1601,7 @@ fileChooser.dragAndDropPDF=Trascina & rilascia il file PDF fileChooser.dragAndDropImage=Trascina & rilascia il file immagine fileChooser.hoveredDragAndDrop=Trascina & rilascia i file qui fileChooser.extractPDF=Estraendo... +fileChooser.addAttachments=drag & drop attachments here #release notes releases.footer=Rilasci diff --git a/stirling-pdf/src/main/resources/messages_ja_JP.properties b/stirling-pdf/src/main/resources/messages_ja_JP.properties index 6e2a8f6a3..14ae50292 100644 --- a/stirling-pdf/src/main/resources/messages_ja_JP.properties +++ b/stirling-pdf/src/main/resources/messages_ja_JP.properties @@ -1205,6 +1205,12 @@ addImage.everyPage=全ページ? addImage.upload=画像の追加 addImage.submit=画像の追加 +#attachments +attachments.title=Add Attachments +attachments.header=Add attachments +attachments.description=Allows you to add attachments to the PDF +attachments.descriptionPlaceholder=Enter a description for the attachments... +attachments.addButton=Add Attachments #merge merge.title=結合 @@ -1594,6 +1600,7 @@ fileChooser.dragAndDropPDF=PDFファイルをドラッグ&ドロップ fileChooser.dragAndDropImage=画像ファイルをドラッグ&ドロップ fileChooser.hoveredDragAndDrop=ファイルをここにドラッグ&ドロップ fileChooser.extractPDF=抽出中... +fileChooser.addAttachments=drag & drop attachments here #release notes releases.footer=リリース diff --git a/stirling-pdf/src/main/resources/messages_ko_KR.properties b/stirling-pdf/src/main/resources/messages_ko_KR.properties index fded2a16a..78aaaea03 100644 --- a/stirling-pdf/src/main/resources/messages_ko_KR.properties +++ b/stirling-pdf/src/main/resources/messages_ko_KR.properties @@ -1206,6 +1206,14 @@ addImage.upload=이미지 추가 addImage.submit=이미지 추가 +#attachments +attachments.title=Add Attachments +attachments.header=Add attachments +attachments.description=Allows you to add attachments to the PDF +attachments.descriptionPlaceholder=Enter a description for the attachments... +attachments.addButton=Add Attachments + + #merge merge.title=병합 merge.header=여러 PDF 병합 (2개 이상) @@ -1594,6 +1602,7 @@ fileChooser.dragAndDropPDF=PDF 파일을 드래그 앤 드롭 fileChooser.dragAndDropImage=이미지 파일을 드래그 앤 드롭 fileChooser.hoveredDragAndDrop=여기에 파일을 드래그 앤 드롭하세요 fileChooser.extractPDF=추출 중... +fileChooser.addAttachments=drag & drop attachments here #release notes releases.footer=릴리스 diff --git a/stirling-pdf/src/main/resources/messages_ml_IN.properties b/stirling-pdf/src/main/resources/messages_ml_IN.properties index af974ce76..ca5cae50a 100644 --- a/stirling-pdf/src/main/resources/messages_ml_IN.properties +++ b/stirling-pdf/src/main/resources/messages_ml_IN.properties @@ -1205,6 +1205,13 @@ addImage.everyPage=എല്ലാ പേജിലും? addImage.upload=ചിത്രം ചേർക്കുക addImage.submit=ചിത്രം ചേർക്കുക +#attachments +attachments.title=Add Attachments +attachments.header=Add attachments +attachments.description=Allows you to add attachments to the PDF +attachments.descriptionPlaceholder=Enter a description for the attachments... +attachments.addButton=Add Attachments + #merge merge.title=ലയിപ്പിക്കുക @@ -1594,6 +1601,7 @@ fileChooser.dragAndDropPDF=PDF ഫയൽ വലിച്ചിടുക fileChooser.dragAndDropImage=ചിത്ര ഫയൽ വലിച്ചിടുക fileChooser.hoveredDragAndDrop=ഫയൽ(കൾ) ഇവിടെ വലിച്ചിടുക fileChooser.extractPDF=വേർതിരിച്ചെടുക്കുന്നു... +fileChooser.addAttachments=drag & drop attachments here #release notes releases.footer=റിലീസുകൾ diff --git a/stirling-pdf/src/main/resources/messages_nl_NL.properties b/stirling-pdf/src/main/resources/messages_nl_NL.properties index b465d82fb..ee6cedc64 100644 --- a/stirling-pdf/src/main/resources/messages_nl_NL.properties +++ b/stirling-pdf/src/main/resources/messages_nl_NL.properties @@ -1206,6 +1206,14 @@ addImage.upload=Afbeelding toevoegen addImage.submit=Afbeelding toevoegen +#attachments +attachments.title=Add Attachments +attachments.header=Add attachments +attachments.description=Allows you to add attachments to the PDF +attachments.descriptionPlaceholder=Enter a description for the attachments... +attachments.addButton=Add Attachments + + #merge merge.title=Samenvoegen merge.header=Meerdere PDF's samenvoegen (2+) @@ -1594,6 +1602,7 @@ fileChooser.dragAndDropPDF=Drag & Drop PDF file fileChooser.dragAndDropImage=Drag & Drop Image file fileChooser.hoveredDragAndDrop=Drag & Drop file(s) here fileChooser.extractPDF=Extracting... +fileChooser.addAttachments=drag & drop attachments here #release notes releases.footer=Releases diff --git a/stirling-pdf/src/main/resources/messages_no_NB.properties b/stirling-pdf/src/main/resources/messages_no_NB.properties index 393f5575e..3e42a7072 100644 --- a/stirling-pdf/src/main/resources/messages_no_NB.properties +++ b/stirling-pdf/src/main/resources/messages_no_NB.properties @@ -1205,6 +1205,13 @@ addImage.everyPage=På hver side? addImage.upload=Legg til bilde addImage.submit=Legg til bilde +#attachments +attachments.title=Add Attachments +attachments.header=Add attachments +attachments.description=Allows you to add attachments to the PDF +attachments.descriptionPlaceholder=Enter a description for the attachments... +attachments.addButton=Add Attachments + #merge merge.title=Slå sammen @@ -1594,6 +1601,7 @@ fileChooser.dragAndDropPDF=Drag & Drop PDF file fileChooser.dragAndDropImage=Drag & Drop Image file fileChooser.hoveredDragAndDrop=Drag & Drop file(s) here fileChooser.extractPDF=Extracting... +fileChooser.addAttachments=drag & drop attachments here #release notes releases.footer=Versjoner diff --git a/stirling-pdf/src/main/resources/messages_pl_PL.properties b/stirling-pdf/src/main/resources/messages_pl_PL.properties index 912d49222..d981574c0 100644 --- a/stirling-pdf/src/main/resources/messages_pl_PL.properties +++ b/stirling-pdf/src/main/resources/messages_pl_PL.properties @@ -1206,6 +1206,14 @@ addImage.upload=Dodaj obraz addImage.submit=Dodaj obraz +#attachments +attachments.title=Add Attachments +attachments.header=Add attachments +attachments.description=Allows you to add attachments to the PDF +attachments.descriptionPlaceholder=Enter a description for the attachments... +attachments.addButton=Add Attachments + + #merge merge.title=Połącz merge.header=Połącz wiele dokumentów PDF (2+) @@ -1594,6 +1602,7 @@ fileChooser.dragAndDropPDF=Przeciągnij i upuść plik PDF fileChooser.dragAndDropImage=Przeciągnij i upuść plik obrazu fileChooser.hoveredDragAndDrop=Przeciągnij i upuść plik(i) tutaj fileChooser.extractPDF=Trwa wyodrębnianie... +fileChooser.addAttachments=drag & drop attachments here #release notes releases.footer=Wydania diff --git a/stirling-pdf/src/main/resources/messages_pt_BR.properties b/stirling-pdf/src/main/resources/messages_pt_BR.properties index b38a9a817..2892ee448 100644 --- a/stirling-pdf/src/main/resources/messages_pt_BR.properties +++ b/stirling-pdf/src/main/resources/messages_pt_BR.properties @@ -1206,6 +1206,14 @@ addImage.upload=Carregar imagem addImage.submit=Adicionar imagem +#attachments +attachments.title=Add Attachments +attachments.header=Add attachments +attachments.description=Allows you to add attachments to the PDF +attachments.descriptionPlaceholder=Enter a description for the attachments... +attachments.addButton=Add Attachments + + #merge merge.title=Mesclar merge.header=Mesclar @@ -1594,6 +1602,7 @@ fileChooser.dragAndDropPDF=Arraste & Solte PDF(s) fileChooser.dragAndDropImage=Arraste & Solte Imagem(ns) fileChooser.hoveredDragAndDrop=Arraste & Solte arquivo(s) aqui fileChooser.extractPDF=Extraindo... +fileChooser.addAttachments=drag & drop attachments here #release notes releases.footer=Versões diff --git a/stirling-pdf/src/main/resources/messages_pt_PT.properties b/stirling-pdf/src/main/resources/messages_pt_PT.properties index 598e4e6cf..fd970d13f 100644 --- a/stirling-pdf/src/main/resources/messages_pt_PT.properties +++ b/stirling-pdf/src/main/resources/messages_pt_PT.properties @@ -1206,6 +1206,14 @@ addImage.upload=Adicionar imagem addImage.submit=Adicionar imagem +#attachments +attachments.title=Add Attachments +attachments.header=Add attachments +attachments.description=Allows you to add attachments to the PDF +attachments.descriptionPlaceholder=Enter a description for the attachments... +attachments.addButton=Add Attachments + + #merge merge.title=Juntar merge.header=Juntar múltiplos PDFs (2+) @@ -1594,6 +1602,7 @@ fileChooser.dragAndDropPDF=Arrastar e Largar ficheiro PDF fileChooser.dragAndDropImage=Arrastar e Largar ficheiro de Imagem fileChooser.hoveredDragAndDrop=Arrastar e Largar ficheiro(s) aqui fileChooser.extractPDF=Extraindo... +fileChooser.addAttachments=drag & drop attachments here #release notes releases.footer=Lançamentos diff --git a/stirling-pdf/src/main/resources/messages_ro_RO.properties b/stirling-pdf/src/main/resources/messages_ro_RO.properties index 65139a90a..c93d67433 100644 --- a/stirling-pdf/src/main/resources/messages_ro_RO.properties +++ b/stirling-pdf/src/main/resources/messages_ro_RO.properties @@ -1206,6 +1206,14 @@ addImage.upload=Adăugare imagine addImage.submit=Adăugare imagine +#attachments +attachments.title=Add Attachments +attachments.header=Add attachments +attachments.description=Allows you to add attachments to the PDF +attachments.descriptionPlaceholder=Enter a description for the attachments... +attachments.addButton=Add Attachments + + #merge merge.title=Unire merge.header=Unirea mai multor PDF-uri (2+) @@ -1594,6 +1602,7 @@ fileChooser.dragAndDropPDF=Drag & Drop PDF file fileChooser.dragAndDropImage=Drag & Drop Image file fileChooser.hoveredDragAndDrop=Drag & Drop file(s) here fileChooser.extractPDF=Extracting... +fileChooser.addAttachments=drag & drop attachments here #release notes releases.footer=Releases diff --git a/stirling-pdf/src/main/resources/messages_ru_RU.properties b/stirling-pdf/src/main/resources/messages_ru_RU.properties index acd741705..d50cbebd2 100644 --- a/stirling-pdf/src/main/resources/messages_ru_RU.properties +++ b/stirling-pdf/src/main/resources/messages_ru_RU.properties @@ -1205,6 +1205,13 @@ addImage.everyPage=Каждая страница? addImage.upload=Добавить изображение addImage.submit=Добавить изображение +#attachments +attachments.title=Add Attachments +attachments.header=Add attachments +attachments.description=Allows you to add attachments to the PDF +attachments.descriptionPlaceholder=Enter a description for the attachments... +attachments.addButton=Add Attachments + #merge merge.title=Объединить @@ -1594,6 +1601,7 @@ fileChooser.dragAndDropPDF=Перетащите PDF-файл fileChooser.dragAndDropImage=Перетащите файл изображения fileChooser.hoveredDragAndDrop=Перетащите файл(ы) сюда fileChooser.extractPDF=Извлечение... +fileChooser.addAttachments=drag & drop attachments here #release notes releases.footer=Релизы diff --git a/stirling-pdf/src/main/resources/messages_sk_SK.properties b/stirling-pdf/src/main/resources/messages_sk_SK.properties index 398c4d06b..82481117a 100644 --- a/stirling-pdf/src/main/resources/messages_sk_SK.properties +++ b/stirling-pdf/src/main/resources/messages_sk_SK.properties @@ -1205,6 +1205,13 @@ addImage.everyPage=Každá stránka? addImage.upload=Pridať obrázok addImage.submit=Pridať obrázok +#attachments +attachments.title=Add Attachments +attachments.header=Add attachments +attachments.description=Allows you to add attachments to the PDF +attachments.descriptionPlaceholder=Enter a description for the attachments... +attachments.addButton=Add Attachments + #merge merge.title=Zlúčiť @@ -1594,6 +1601,7 @@ fileChooser.dragAndDropPDF=Drag & Drop PDF file fileChooser.dragAndDropImage=Drag & Drop Image file fileChooser.hoveredDragAndDrop=Drag & Drop file(s) here fileChooser.extractPDF=Extracting... +fileChooser.addAttachments=drag & drop attachments here #release notes releases.footer=Releases diff --git a/stirling-pdf/src/main/resources/messages_sl_SI.properties b/stirling-pdf/src/main/resources/messages_sl_SI.properties index ba9ce39cf..80f53d842 100644 --- a/stirling-pdf/src/main/resources/messages_sl_SI.properties +++ b/stirling-pdf/src/main/resources/messages_sl_SI.properties @@ -1206,6 +1206,14 @@ addImage.upload=Dodaj sliko addImage.submit=Dodaj sliko +#attachments +attachments.title=Add Attachments +attachments.header=Add attachments +attachments.description=Allows you to add attachments to the PDF +attachments.descriptionPlaceholder=Enter a description for the attachments... +attachments.addButton=Add Attachments + + #merge merge.title=Združi merge.header=Združi več PDF-jev (2+) @@ -1594,6 +1602,7 @@ fileChooser.dragAndDropPDF=Povleci in spusti datoteko PDF fileChooser.dragAndDropImage=Povleci in spusti slikovno datoteko fileChooser.hoveredDragAndDrop=Povleci in spusti datoteko(e) sem fileChooser.extractPDF=Izvlečenje... +fileChooser.addAttachments=drag & drop attachments here #release notes releases.footer=Izdaje diff --git a/stirling-pdf/src/main/resources/messages_sr_LATN_RS.properties b/stirling-pdf/src/main/resources/messages_sr_LATN_RS.properties index f64e8b279..e835893c3 100644 --- a/stirling-pdf/src/main/resources/messages_sr_LATN_RS.properties +++ b/stirling-pdf/src/main/resources/messages_sr_LATN_RS.properties @@ -1206,6 +1206,14 @@ addImage.upload=Dodaj sliku addImage.submit=Dodaj sliku +#attachments +attachments.title=Add Attachments +attachments.header=Add attachments +attachments.description=Allows you to add attachments to the PDF +attachments.descriptionPlaceholder=Enter a description for the attachments... +attachments.addButton=Add Attachments + + #merge merge.title=Spajanje merge.header=Spajanje više PDF fajlova (2+) @@ -1594,6 +1602,7 @@ fileChooser.dragAndDropPDF=Drag & Drop PDF file fileChooser.dragAndDropImage=Drag & Drop Image file fileChooser.hoveredDragAndDrop=Drag & Drop file(s) here fileChooser.extractPDF=Extracting... +fileChooser.addAttachments=drag & drop attachments here #release notes releases.footer=Releases diff --git a/stirling-pdf/src/main/resources/messages_sv_SE.properties b/stirling-pdf/src/main/resources/messages_sv_SE.properties index 2a7a65438..32f5a98b9 100644 --- a/stirling-pdf/src/main/resources/messages_sv_SE.properties +++ b/stirling-pdf/src/main/resources/messages_sv_SE.properties @@ -1205,6 +1205,13 @@ addImage.everyPage=Varje sida? addImage.upload=Lägg till bild addImage.submit=Lägg till bild +#attachments +attachments.title=Add Attachments +attachments.header=Add attachments +attachments.description=Allows you to add attachments to the PDF +attachments.descriptionPlaceholder=Enter a description for the attachments... +attachments.addButton=Add Attachments + #merge merge.title=Sammanfoga @@ -1594,6 +1601,7 @@ fileChooser.dragAndDropPDF=Dra & Släpp PDF fil fileChooser.dragAndDropImage=Dra & Släpp bildfil fileChooser.hoveredDragAndDrop=Dra & Släpp fil(er) här fileChooser.extractPDF=Extraherar... +fileChooser.addAttachments=drag & drop attachments here #release notes releases.footer=Utgåvor diff --git a/stirling-pdf/src/main/resources/messages_th_TH.properties b/stirling-pdf/src/main/resources/messages_th_TH.properties index 95b0f7d0f..7c5e8ed2d 100644 --- a/stirling-pdf/src/main/resources/messages_th_TH.properties +++ b/stirling-pdf/src/main/resources/messages_th_TH.properties @@ -1205,6 +1205,13 @@ addImage.everyPage=ทุกหน้า? addImage.upload=เพิ่มรูปภาพ addImage.submit=เพิ่มรูปภาพ +#attachments +attachments.title=Add Attachments +attachments.header=Add attachments +attachments.description=Allows you to add attachments to the PDF +attachments.descriptionPlaceholder=Enter a description for the attachments... +attachments.addButton=Add Attachments + #merge merge.title=รวม @@ -1594,6 +1601,7 @@ fileChooser.dragAndDropPDF=Drag & Drop PDF file fileChooser.dragAndDropImage=Drag & Drop Image file fileChooser.hoveredDragAndDrop=Drag & Drop file(s) here fileChooser.extractPDF=Extracting... +fileChooser.addAttachments=drag & drop attachments here #release notes releases.footer=Releases diff --git a/stirling-pdf/src/main/resources/messages_tr_TR.properties b/stirling-pdf/src/main/resources/messages_tr_TR.properties index 55b3d2d94..71be5cb1e 100644 --- a/stirling-pdf/src/main/resources/messages_tr_TR.properties +++ b/stirling-pdf/src/main/resources/messages_tr_TR.properties @@ -1205,6 +1205,13 @@ addImage.everyPage=Her Sayfa mı? addImage.upload=Resim ekle addImage.submit=Resim ekle +#attachments +attachments.title=Add Attachments +attachments.header=Add attachments +attachments.description=Allows you to add attachments to the PDF +attachments.descriptionPlaceholder=Enter a description for the attachments... +attachments.addButton=Add Attachments + #merge merge.title=Birleştir @@ -1594,6 +1601,7 @@ fileChooser.dragAndDropPDF=PDF dosyasını Sürükle & Bırak fileChooser.dragAndDropImage=Görsel dosyasını Sürükle & Bırak fileChooser.hoveredDragAndDrop=Dosya(lar)ı buraya sürükleyip bırakın fileChooser.extractPDF=PDF Çıkarılıyor... +fileChooser.addAttachments=drag & drop attachments here #release notes releases.footer=Sürümler diff --git a/stirling-pdf/src/main/resources/messages_uk_UA.properties b/stirling-pdf/src/main/resources/messages_uk_UA.properties index bbd46cfc8..31768b048 100644 --- a/stirling-pdf/src/main/resources/messages_uk_UA.properties +++ b/stirling-pdf/src/main/resources/messages_uk_UA.properties @@ -1206,6 +1206,14 @@ addImage.upload=Додати зображення addImage.submit=Додати зображення +#attachments +attachments.title=Add Attachments +attachments.header=Add attachments +attachments.description=Allows you to add attachments to the PDF +attachments.descriptionPlaceholder=Enter a description for the attachments... +attachments.addButton=Add Attachments + + #merge merge.title=Об'єднати merge.header=Об'єднання кількох PDF-файлів (2+) @@ -1594,6 +1602,7 @@ fileChooser.dragAndDropPDF=Перетащите PDF-файл fileChooser.dragAndDropImage=Перетащите файл зображення fileChooser.hoveredDragAndDrop=Перетащите файл(и) сюда fileChooser.extractPDF=Видобування... +fileChooser.addAttachments=drag & drop attachments here #release notes releases.footer=Релізи diff --git a/stirling-pdf/src/main/resources/messages_vi_VN.properties b/stirling-pdf/src/main/resources/messages_vi_VN.properties index 951b706e7..f086b4bd4 100644 --- a/stirling-pdf/src/main/resources/messages_vi_VN.properties +++ b/stirling-pdf/src/main/resources/messages_vi_VN.properties @@ -1206,6 +1206,14 @@ addImage.upload=Thêm hình ảnh addImage.submit=Thêm hình ảnh +#attachments +attachments.title=Add Attachments +attachments.header=Add attachments +attachments.description=Allows you to add attachments to the PDF +attachments.descriptionPlaceholder=Enter a description for the attachments... +attachments.addButton=Add Attachments + + #merge merge.title=Trộn merge.header=Trộn nhiều PDF (2+) @@ -1594,6 +1602,7 @@ fileChooser.dragAndDropPDF=Drag & Drop PDF file fileChooser.dragAndDropImage=Drag & Drop Image file fileChooser.hoveredDragAndDrop=Drag & Drop file(s) here fileChooser.extractPDF=Extracting... +fileChooser.addAttachments=drag & drop attachments here #release notes releases.footer=Releases diff --git a/stirling-pdf/src/main/resources/messages_zh_CN.properties b/stirling-pdf/src/main/resources/messages_zh_CN.properties index 07c10e561..4da26181a 100644 --- a/stirling-pdf/src/main/resources/messages_zh_CN.properties +++ b/stirling-pdf/src/main/resources/messages_zh_CN.properties @@ -1206,6 +1206,14 @@ addImage.upload=添加图片 addImage.submit=添加图片 +#attachments +attachments.title=Add Attachments +attachments.header=Add attachments +attachments.description=Allows you to add attachments to the PDF +attachments.descriptionPlaceholder=Enter a description for the attachments... +attachments.addButton=Add Attachments + + #merge merge.title=合并 merge.header=合并多个 PDF(2个以上)。 @@ -1594,6 +1602,7 @@ fileChooser.dragAndDropPDF=拖放PDF文件 fileChooser.dragAndDropImage=拖放图片文件 fileChooser.hoveredDragAndDrop=拖放文件到此处 fileChooser.extractPDF=处理中... +fileChooser.addAttachments=drag & drop attachments here #release notes releases.footer=版本 diff --git a/stirling-pdf/src/main/resources/messages_zh_TW.properties b/stirling-pdf/src/main/resources/messages_zh_TW.properties index 927e7c037..4684df9bf 100644 --- a/stirling-pdf/src/main/resources/messages_zh_TW.properties +++ b/stirling-pdf/src/main/resources/messages_zh_TW.properties @@ -1206,6 +1206,14 @@ addImage.upload=新增圖片 addImage.submit=新增圖片 +#attachments +attachments.title=Add Attachments +attachments.header=Add attachments +attachments.description=Allows you to add attachments to the PDF +attachments.descriptionPlaceholder=Enter a description for the attachments... +attachments.addButton=Add Attachments + + #merge merge.title=合併 merge.header=合併多個 PDF @@ -1594,6 +1602,7 @@ fileChooser.dragAndDropPDF=拖放 PDF 檔案 fileChooser.dragAndDropImage=拖放圖片檔案 fileChooser.hoveredDragAndDrop=將檔案拖放至此 fileChooser.extractPDF=處理中... +fileChooser.addAttachments=drag & drop attachments here #release notes releases.footer=版本資訊 diff --git a/stirling-pdf/src/main/resources/static/js/file-icon-factory.js b/stirling-pdf/src/main/resources/static/js/file-icon-factory.js index 81328f423..645ae323e 100644 --- a/stirling-pdf/src/main/resources/static/js/file-icon-factory.js +++ b/stirling-pdf/src/main/resources/static/js/file-icon-factory.js @@ -6,6 +6,9 @@ class FileIconFactory { return this.createPDFIcon(); case "csv": return this.createCSVIcon(); + case "xls": + case "xlsx": + return this.createXLSXIcon(); case "jpe": case "jpg": case "jpeg": @@ -44,8 +47,29 @@ class FileIconFactory { return ``; } + static createCSVIcon() { + return ` + + + + `; + } + + static createXLSXIcon() { + return ` + + + + + `; + } + static createUnknownFileIcon() { - return ``; + return ` + + + + `; } } diff --git a/stirling-pdf/src/main/resources/static/js/fileInput.js b/stirling-pdf/src/main/resources/static/js/fileInput.js index e874ea1c2..f06371986 100644 --- a/stirling-pdf/src/main/resources/static/js/fileInput.js +++ b/stirling-pdf/src/main/resources/static/js/fileInput.js @@ -45,6 +45,8 @@ function setupFileInput(chooser) { inputContainer.querySelector('#dragAndDrop').innerHTML = window.fileInput.dragAndDropPDF; } else if (inputContainer.id === 'image-upload-input-container') { inputContainer.querySelector('#dragAndDrop').innerHTML = window.fileInput.dragAndDropImage; + } else if (inputContainer.id === 'attachments-input-container') { + inputContainer.querySelector('#dragAndDrop').innerHTML = window.fileInput.addAttachments; } let allFiles = []; let overlay; diff --git a/stirling-pdf/src/main/resources/templates/fragments/common.html b/stirling-pdf/src/main/resources/templates/fragments/common.html index 02d919b2b..38e71f04f 100644 --- a/stirling-pdf/src/main/resources/templates/fragments/common.html +++ b/stirling-pdf/src/main/resources/templates/fragments/common.html @@ -268,6 +268,7 @@ window.fileInput = { dragAndDropPDF: '[[#{fileChooser.dragAndDropPDF}]]', dragAndDropImage: '[[#{fileChooser.dragAndDropImage}]]', + addAttachments: '[[#{fileChooser.addAttachments}]]', extractPDF: '[[#{fileChooser.extractPDF}]]', loading: '[[#{loading}]]' }; diff --git a/stirling-pdf/src/main/resources/templates/fragments/navElements.html b/stirling-pdf/src/main/resources/templates/fragments/navElements.html index 38dfa0ac6..6b6f76d3b 100644 --- a/stirling-pdf/src/main/resources/templates/fragments/navElements.html +++ b/stirling-pdf/src/main/resources/templates/fragments/navElements.html @@ -105,6 +105,9 @@
+
+
diff --git a/stirling-pdf/src/test/java/stirling/software/SPDF/controller/api/misc/AttachmentControllerTest.java b/stirling-pdf/src/test/java/stirling/software/SPDF/controller/api/misc/AttachmentControllerTest.java new file mode 100644 index 000000000..5d794f09b --- /dev/null +++ b/stirling-pdf/src/test/java/stirling/software/SPDF/controller/api/misc/AttachmentControllerTest.java @@ -0,0 +1,123 @@ +package stirling.software.SPDF.controller.api.misc; + +import static org.junit.jupiter.api.Assertions.*; +import static org.mockito.ArgumentMatchers.*; +import static org.mockito.Mockito.*; + +import org.mockito.MockedStatic; + +import java.io.IOException; +import java.util.List; + +import org.apache.pdfbox.pdmodel.PDDocument; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.mock.web.MockMultipartFile; +import org.springframework.web.multipart.MultipartFile; + +import stirling.software.SPDF.service.AttachmentServiceInterface; +import stirling.software.common.service.CustomPDFDocumentFactory; +import stirling.software.common.util.WebResponseUtils; + +@ExtendWith(MockitoExtension.class) +class AttachmentControllerTest { + + @Mock + private CustomPDFDocumentFactory pdfDocumentFactory; + + @Mock + private AttachmentServiceInterface pdfAttachmentService; + + @InjectMocks + private AttachmentController attachmentController; + + private MockMultipartFile pdfFile; + private MockMultipartFile attachment1; + private MockMultipartFile attachment2; + private PDDocument mockDocument; + private PDDocument modifiedMockDocument; + + @BeforeEach + void setUp() { + pdfFile = new MockMultipartFile("fileInput", "test.pdf", "application/pdf", "PDF content".getBytes()); + attachment1 = new MockMultipartFile("attachment1", "file1.txt", "text/plain", "File 1 content".getBytes()); + attachment2 = new MockMultipartFile("attachment2", "file2.jpg", "image/jpeg", "Image content".getBytes()); + + mockDocument = mock(PDDocument.class); + modifiedMockDocument = mock(PDDocument.class); + } + + @Test + void addAttachments_Success() throws IOException { + List attachments = List.of(attachment1, attachment2); + ResponseEntity expectedResponse = ResponseEntity.ok("modified PDF content".getBytes()); + + when(pdfDocumentFactory.load(pdfFile, false)).thenReturn(mockDocument); + when(pdfAttachmentService.addAttachment(mockDocument, attachments)).thenReturn(modifiedMockDocument); + + try (MockedStatic mockedWebResponseUtils = mockStatic(WebResponseUtils.class)) { + mockedWebResponseUtils.when(() -> WebResponseUtils.pdfDocToWebResponse(eq(modifiedMockDocument), eq("test_with_attachments.pdf"))) + .thenReturn(expectedResponse); + + ResponseEntity response = attachmentController.addAttachments(pdfFile, attachments); + + assertNotNull(response); + assertEquals(HttpStatus.OK, response.getStatusCode()); + assertNotNull(response.getBody()); + verify(pdfDocumentFactory).load(pdfFile, false); + verify(pdfAttachmentService).addAttachment(mockDocument, attachments); + } + } + + @Test + void addAttachments_SingleAttachment() throws IOException { + List attachments = List.of(attachment1); + ResponseEntity expectedResponse = ResponseEntity.ok("modified PDF content".getBytes()); + + when(pdfDocumentFactory.load(pdfFile, false)).thenReturn(mockDocument); + when(pdfAttachmentService.addAttachment(mockDocument, attachments)).thenReturn(modifiedMockDocument); + + try (MockedStatic mockedWebResponseUtils = mockStatic(WebResponseUtils.class)) { + mockedWebResponseUtils.when(() -> WebResponseUtils.pdfDocToWebResponse(eq(modifiedMockDocument), eq("test_with_attachments.pdf"))) + .thenReturn(expectedResponse); + + ResponseEntity response = attachmentController.addAttachments(pdfFile, attachments); + + assertNotNull(response); + assertEquals(HttpStatus.OK, response.getStatusCode()); + assertNotNull(response.getBody()); + verify(pdfDocumentFactory).load(pdfFile, false); + verify(pdfAttachmentService).addAttachment(mockDocument, attachments); + } + } + + @Test + void addAttachments_IOExceptionFromPDFLoad() throws IOException { + List attachments = List.of(attachment1); + IOException ioException = new IOException("Failed to load PDF"); + + when(pdfDocumentFactory.load(pdfFile, false)).thenThrow(ioException); + + assertThrows(IOException.class, () -> attachmentController.addAttachments(pdfFile, attachments)); + verify(pdfDocumentFactory).load(pdfFile, false); + verifyNoInteractions(pdfAttachmentService); + } + + @Test + void addAttachments_IOExceptionFromAttachmentService() throws IOException { + List attachments = List.of(attachment1); + IOException ioException = new IOException("Failed to add attachment"); + + when(pdfDocumentFactory.load(pdfFile, false)).thenReturn(mockDocument); + when(pdfAttachmentService.addAttachment(mockDocument, attachments)).thenThrow(ioException); + + assertThrows(IOException.class, () -> attachmentController.addAttachments(pdfFile, attachments)); + verify(pdfAttachmentService).addAttachment(mockDocument, attachments); + } +} diff --git a/stirling-pdf/src/test/java/stirling/software/SPDF/controller/api/misc/AttachmentsControllerTest.java b/stirling-pdf/src/test/java/stirling/software/SPDF/controller/api/misc/AttachmentsControllerTest.java deleted file mode 100644 index 89eadaecd..000000000 --- a/stirling-pdf/src/test/java/stirling/software/SPDF/controller/api/misc/AttachmentsControllerTest.java +++ /dev/null @@ -1,221 +0,0 @@ -package stirling.software.SPDF.controller.api.misc; - -import static org.junit.jupiter.api.Assertions.*; -import static org.mockito.ArgumentMatchers.*; -import static org.mockito.Mockito.*; - -import java.io.IOException; -import java.util.List; - -import org.apache.pdfbox.pdmodel.PDDocument; -import org.apache.pdfbox.pdmodel.PDDocumentCatalog; -import org.apache.pdfbox.pdmodel.PDDocumentNameDictionary; -import org.apache.pdfbox.pdmodel.PDEmbeddedFilesNameTreeNode; -import org.apache.pdfbox.pdmodel.PageMode; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.InjectMocks; -import org.mockito.Mock; -import org.mockito.junit.jupiter.MockitoExtension; -import org.springframework.http.HttpStatus; -import org.springframework.http.ResponseEntity; -import org.springframework.mock.web.MockMultipartFile; -import org.springframework.web.multipart.MultipartFile; - -import stirling.software.SPDF.service.PDFAttachmentServiceInterface; -import stirling.software.common.service.CustomPDFDocumentFactory; - -@ExtendWith(MockitoExtension.class) -class AttachmentsControllerTest { - - @Mock - private CustomPDFDocumentFactory pdfDocumentFactory; - - @Mock - private PDFAttachmentServiceInterface pdfAttachmentService; - - @InjectMocks - private AttachmentsController attachmentsController; - - private MockMultipartFile pdfFile; - private MockMultipartFile attachment1; - private MockMultipartFile attachment2; - private PDDocument mockDocument; - private PDDocumentCatalog mockCatalog; - private PDDocumentNameDictionary mockNameDict; - private PDEmbeddedFilesNameTreeNode mockEmbeddedFilesTree; - - @BeforeEach - void setUp() { - pdfFile = new MockMultipartFile("fileInput", "test.pdf", "application/pdf", "PDF content".getBytes()); - attachment1 = new MockMultipartFile("attachment1", "file1.txt", "text/plain", "File 1 content".getBytes()); - attachment2 = new MockMultipartFile("attachment2", "file2.jpg", "image/jpeg", "Image content".getBytes()); - - mockDocument = mock(PDDocument.class); - mockCatalog = mock(PDDocumentCatalog.class); - mockNameDict = mock(PDDocumentNameDictionary.class); - mockEmbeddedFilesTree = mock(PDEmbeddedFilesNameTreeNode.class); - } - - @Test - void addAttachments_WithExistingNames() throws IOException { - List attachments = List.of(attachment1, attachment2); - byte[] expectedOutput = "modified PDF content".getBytes(); - - when(pdfDocumentFactory.load(pdfFile, false)).thenReturn(mockDocument); - when(mockDocument.getDocumentCatalog()).thenReturn(mockCatalog); - when(mockCatalog.getNames()).thenReturn(mockNameDict); - when(mockNameDict.getEmbeddedFiles()).thenReturn(mockEmbeddedFilesTree); - when(pdfAttachmentService.addAttachment(mockDocument, mockEmbeddedFilesTree, attachments)).thenReturn(expectedOutput); - - ResponseEntity response = attachmentsController.addAttachments(pdfFile, attachments); - - assertNotNull(response); - assertEquals(HttpStatus.OK, response.getStatusCode()); - assertNotNull(response.getBody()); - verify(pdfDocumentFactory).load(pdfFile, false); - verify(mockCatalog).setNames(mockNameDict); - verify(pdfAttachmentService).addAttachment(mockDocument, mockEmbeddedFilesTree, attachments); - } - - @Test - void addAttachments_WithoutExistingNames() throws IOException { - List attachments = List.of(attachment1); - byte[] expectedOutput = "modified PDF content".getBytes(); - - try (PDDocument realDocument = new PDDocument()) { - when(pdfDocumentFactory.load(pdfFile, false)).thenReturn(realDocument); - when(pdfAttachmentService.addAttachment(eq(realDocument), any(PDEmbeddedFilesNameTreeNode.class), eq(attachments))).thenReturn(expectedOutput); - - ResponseEntity response = attachmentsController.addAttachments(pdfFile, attachments); - - assertNotNull(response); - assertEquals(HttpStatus.OK, response.getStatusCode()); - assertNotNull(response.getBody()); - verify(pdfDocumentFactory).load(pdfFile, false); - verify(pdfAttachmentService).addAttachment(eq(realDocument), any(PDEmbeddedFilesNameTreeNode.class), eq(attachments)); - } - } - - @Test - void addAttachments_IOExceptionFromPDFLoad() throws IOException { - List attachments = List.of(attachment1); - IOException ioException = new IOException("Failed to load PDF"); - - when(pdfDocumentFactory.load(pdfFile, false)).thenThrow(ioException); - - assertThrows(IOException.class, () -> attachmentsController.addAttachments(pdfFile, attachments)); - verify(pdfDocumentFactory).load(pdfFile, false); - verifyNoInteractions(pdfAttachmentService); - } - - @Test - void addAttachments_IOExceptionFromAttachmentService() throws IOException { - List attachments = List.of(attachment1); - IOException ioException = new IOException("Failed to add attachment"); - - when(pdfDocumentFactory.load(pdfFile, false)).thenReturn(mockDocument); - when(mockDocument.getDocumentCatalog()).thenReturn(mockCatalog); - when(mockCatalog.getNames()).thenReturn(mockNameDict); - when(mockNameDict.getEmbeddedFiles()).thenReturn(mockEmbeddedFilesTree); - when(pdfAttachmentService.addAttachment(mockDocument, mockEmbeddedFilesTree, attachments)).thenThrow(ioException); - - assertThrows(IOException.class, () -> attachmentsController.addAttachments(pdfFile, attachments)); - verify(pdfAttachmentService).addAttachment(mockDocument, mockEmbeddedFilesTree, attachments); - } - - @Test - void removeAttachments_WithExistingNames() throws IOException { - when(pdfDocumentFactory.load(pdfFile)).thenReturn(mockDocument); - when(mockDocument.getDocumentCatalog()).thenReturn(mockCatalog); - when(mockCatalog.getNames()).thenReturn(mockNameDict); - - ResponseEntity response = attachmentsController.removeAttachments(pdfFile); - - assertNotNull(response); - assertEquals(HttpStatus.OK, response.getStatusCode()); - verify(pdfDocumentFactory).load(pdfFile); - verify(mockNameDict).setEmbeddedFiles(null); - verify(mockCatalog).setPageMode(PageMode.USE_NONE); - } - - @Test - void removeAttachments_WithoutExistingNames() throws IOException { - when(pdfDocumentFactory.load(pdfFile)).thenReturn(mockDocument); - when(mockDocument.getDocumentCatalog()).thenReturn(mockCatalog); - when(mockCatalog.getNames()).thenReturn(null); - - ResponseEntity response = attachmentsController.removeAttachments(pdfFile); - - assertNotNull(response); - assertEquals(HttpStatus.OK, response.getStatusCode()); - verify(pdfDocumentFactory).load(pdfFile); - verify(mockCatalog).setPageMode(PageMode.USE_NONE); - verifyNoInteractions(mockNameDict); - } - - @Test - void removeAttachments_IOExceptionFromPDFLoad() throws IOException { - IOException ioException = new IOException("Failed to load PDF"); - - when(pdfDocumentFactory.load(pdfFile)).thenThrow(ioException); - - assertThrows(IOException.class, () -> attachmentsController.removeAttachments(pdfFile)); - verify(pdfDocumentFactory).load(pdfFile); - } - - @Test - void addAttachments_EmptyAttachmentsList() throws IOException { - List emptyAttachments = List.of(); - byte[] expectedOutput = "PDF content without new attachments".getBytes(); - - when(pdfDocumentFactory.load(pdfFile, false)).thenReturn(mockDocument); - when(mockDocument.getDocumentCatalog()).thenReturn(mockCatalog); - when(mockCatalog.getNames()).thenReturn(mockNameDict); - when(mockNameDict.getEmbeddedFiles()).thenReturn(mockEmbeddedFilesTree); - when(pdfAttachmentService.addAttachment(mockDocument, mockEmbeddedFilesTree, emptyAttachments)).thenReturn(expectedOutput); - - ResponseEntity response = attachmentsController.addAttachments(pdfFile, emptyAttachments); - - assertNotNull(response); - assertEquals(HttpStatus.OK, response.getStatusCode()); - assertNotNull(response.getBody()); - verify(pdfAttachmentService).addAttachment(mockDocument, mockEmbeddedFilesTree, emptyAttachments); - } - - @Test - void addAttachments_NullFilename() throws IOException { - MockMultipartFile attachmentWithNullName = new MockMultipartFile("attachment", null, "text/plain", "content".getBytes()); - List attachments = List.of(attachmentWithNullName); - byte[] expectedOutput = "PDF with null filename attachment".getBytes(); - - when(pdfDocumentFactory.load(pdfFile, false)).thenReturn(mockDocument); - when(mockDocument.getDocumentCatalog()).thenReturn(mockCatalog); - when(mockCatalog.getNames()).thenReturn(mockNameDict); - when(mockNameDict.getEmbeddedFiles()).thenReturn(mockEmbeddedFilesTree); - when(pdfAttachmentService.addAttachment(mockDocument, mockEmbeddedFilesTree, attachments)).thenReturn(expectedOutput); - - ResponseEntity response = attachmentsController.addAttachments(pdfFile, attachments); - - assertNotNull(response); - assertEquals(HttpStatus.OK, response.getStatusCode()); - assertNotNull(response.getBody()); - verify(pdfAttachmentService).addAttachment(mockDocument, mockEmbeddedFilesTree, attachments); - } - - @Test - void removeAttachments_NullPDFFilename() throws IOException { - MockMultipartFile pdfWithNullName = new MockMultipartFile("fileInput", null, "application/pdf", "PDF content".getBytes()); - - when(pdfDocumentFactory.load(pdfWithNullName)).thenReturn(mockDocument); - when(mockDocument.getDocumentCatalog()).thenReturn(mockCatalog); - when(mockCatalog.getNames()).thenReturn(null); - - ResponseEntity response = attachmentsController.removeAttachments(pdfWithNullName); - - assertNotNull(response); - assertEquals(HttpStatus.OK, response.getStatusCode()); - verify(mockCatalog).setPageMode(PageMode.USE_NONE); - } -} \ No newline at end of file diff --git a/stirling-pdf/src/test/java/stirling/software/SPDF/service/AttachmentServiceTest.java b/stirling-pdf/src/test/java/stirling/software/SPDF/service/AttachmentServiceTest.java new file mode 100644 index 000000000..837530533 --- /dev/null +++ b/stirling-pdf/src/test/java/stirling/software/SPDF/service/AttachmentServiceTest.java @@ -0,0 +1,105 @@ +package stirling.software.SPDF.service; + +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.util.List; +import org.apache.pdfbox.pdmodel.PDDocument; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.springframework.web.multipart.MultipartFile; +import static org.junit.jupiter.api.Assertions.*; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +class AttachmentServiceTest { + + private AttachmentService attachmentService; + + @BeforeEach + void setUp() { + attachmentService = new AttachmentService(); + } + + @Test + void addAttachmentToPDF() throws IOException { + try (var document = new PDDocument()) { + document.setDocumentId(100L); + var attachments = List.of(mock(MultipartFile.class)); + + when(attachments.get(0).getOriginalFilename()).thenReturn("test.txt"); + when(attachments.get(0).getInputStream()).thenReturn( + new ByteArrayInputStream("Test content".getBytes())); + when(attachments.get(0).getSize()).thenReturn(12L); + when(attachments.get(0).getContentType()).thenReturn("text/plain"); + + PDDocument result = attachmentService.addAttachment(document, attachments); + + assertNotNull(result); + assertEquals(document.getDocumentId(), result.getDocumentId()); + assertNotNull(result.getDocumentCatalog().getNames()); + } + } + + @Test + void addAttachmentToPDF_MultipleAttachments() throws IOException { + try (var document = new PDDocument()) { + document.setDocumentId(100L); + var attachment1 = mock(MultipartFile.class); + var attachment2 = mock(MultipartFile.class); + var attachments = List.of(attachment1, attachment2); + + when(attachment1.getOriginalFilename()).thenReturn("document.pdf"); + when(attachment1.getInputStream()).thenReturn( + new ByteArrayInputStream("PDF content".getBytes())); + when(attachment1.getSize()).thenReturn(15L); + when(attachment1.getContentType()).thenReturn("application/pdf"); + + when(attachment2.getOriginalFilename()).thenReturn("image.jpg"); + when(attachment2.getInputStream()).thenReturn( + new ByteArrayInputStream("Image content".getBytes())); + when(attachment2.getSize()).thenReturn(20L); + when(attachment2.getContentType()).thenReturn("image/jpeg"); + + PDDocument result = attachmentService.addAttachment(document, attachments); + + assertNotNull(result); + assertNotNull(result.getDocumentCatalog().getNames()); + } + } + + @Test + void addAttachmentToPDF_WithBlankContentType() throws IOException { + try (var document = new PDDocument()) { + document.setDocumentId(100L); + var attachments = List.of(mock(MultipartFile.class)); + + when(attachments.get(0).getOriginalFilename()).thenReturn("image.jpg"); + when(attachments.get(0).getInputStream()).thenReturn( + new ByteArrayInputStream("Image content".getBytes())); + when(attachments.get(0).getSize()).thenReturn(25L); + when(attachments.get(0).getContentType()).thenReturn(""); + + PDDocument result = attachmentService.addAttachment(document, attachments); + + assertNotNull(result); + assertNotNull(result.getDocumentCatalog().getNames()); + } + } + + @Test + void addAttachmentToPDF_AttachmentInputStreamThrowsIOException() throws IOException { + try (var document = new PDDocument()) { + var attachments = List.of(mock(MultipartFile.class)); + var ioException = new IOException("Failed to read attachment stream"); + + when(attachments.get(0).getOriginalFilename()).thenReturn("test.txt"); + when(attachments.get(0).getInputStream()).thenThrow(ioException); + when(attachments.get(0).getSize()).thenReturn(10L); + + PDDocument result = attachmentService.addAttachment(document, attachments); + + assertNotNull(result); + assertNotNull(result.getDocumentCatalog().getNames()); + } + } +} diff --git a/stirling-pdf/src/test/java/stirling/software/SPDF/service/PDFAttachmentServiceTest.java b/stirling-pdf/src/test/java/stirling/software/SPDF/service/PDFAttachmentServiceTest.java deleted file mode 100644 index af40f444c..000000000 --- a/stirling-pdf/src/test/java/stirling/software/SPDF/service/PDFAttachmentServiceTest.java +++ /dev/null @@ -1,216 +0,0 @@ -package stirling.software.SPDF.service; - -import java.io.ByteArrayInputStream; -import java.io.IOException; -import java.util.HashMap; -import java.util.List; -import org.apache.pdfbox.pdmodel.PDDocument; -import org.apache.pdfbox.pdmodel.PDEmbeddedFilesNameTreeNode; -import org.apache.pdfbox.pdmodel.common.filespecification.PDComplexFileSpecification; -import org.apache.pdfbox.pdmodel.encryption.AccessPermission; -import org.apache.pdfbox.pdmodel.encryption.StandardProtectionPolicy; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.springframework.web.multipart.MultipartFile; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.mockito.ArgumentMatchers.anyMap; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -class PDFAttachmentServiceTest { - - private PDFAttachmentService pdfAttachmentService; - - @BeforeEach - void setUp() { - pdfAttachmentService = new PDFAttachmentService(); - } - - @Test - void addAttachmentToPDF() throws IOException { - try (var document = new PDDocument()) { - var embeddedFilesTree = mock(PDEmbeddedFilesNameTreeNode.class); - var attachments = List.of(mock(MultipartFile.class)); - var existingNames = new HashMap(); - - when(embeddedFilesTree.getNames()).thenReturn(existingNames); - when(attachments.get(0).getOriginalFilename()).thenReturn("test.txt"); - when(attachments.get(0).getInputStream()).thenReturn( - new ByteArrayInputStream("Test content".getBytes())); - when(attachments.get(0).getSize()).thenReturn(12L); - when(attachments.get(0).getContentType()).thenReturn("text/plain"); - - byte[] result = pdfAttachmentService.addAttachment(document, embeddedFilesTree, attachments); - - assertNotNull(result); - assertTrue(result.length > 0); - verify(embeddedFilesTree).setNames(anyMap()); - } - } - - @Test - void addAttachmentToPDF_WithNullExistingNames() throws IOException { - try (var document = new PDDocument()) { - var embeddedFilesTree = mock(PDEmbeddedFilesNameTreeNode.class); - var attachments = List.of(mock(MultipartFile.class)); - - when(embeddedFilesTree.getNames()).thenReturn(null); - when(attachments.get(0).getOriginalFilename()).thenReturn("document.pdf"); - when(attachments.get(0).getInputStream()).thenReturn( - new ByteArrayInputStream("PDF content".getBytes())); - when(attachments.get(0).getSize()).thenReturn(15L); - when(attachments.get(0).getContentType()).thenReturn("application/pdf"); - - byte[] result = pdfAttachmentService.addAttachment(document, embeddedFilesTree, attachments); - - assertNotNull(result); - assertTrue(result.length > 0); - verify(embeddedFilesTree).setNames(anyMap()); - } - } - - @Test - void addAttachmentToPDF_WithBlankContentType() throws IOException { - try (var document = new PDDocument()) { - var embeddedFilesTree = mock(PDEmbeddedFilesNameTreeNode.class); - var attachments = List.of(mock(MultipartFile.class)); - var existingNames = new HashMap(); - - when(embeddedFilesTree.getNames()).thenReturn(existingNames); - when(attachments.get(0).getOriginalFilename()).thenReturn("image.jpg"); - when(attachments.get(0).getInputStream()).thenReturn( - new ByteArrayInputStream("Image content".getBytes())); - when(attachments.get(0).getSize()).thenReturn(25L); - when(attachments.get(0).getContentType()).thenReturn(""); - - byte[] result = pdfAttachmentService.addAttachment(document, embeddedFilesTree, attachments); - - assertNotNull(result); - assertTrue(result.length > 0); - verify(embeddedFilesTree).setNames(anyMap()); - } - } - - @Test - void addAttachmentToPDF_GetNamesThrowsIOException() throws IOException { - var document = mock(PDDocument.class); - var embeddedFilesTree = mock(PDEmbeddedFilesNameTreeNode.class); - var attachments = List.of(mock(MultipartFile.class)); - var ioException = new IOException("Failed to retrieve embedded files"); - - when(embeddedFilesTree.getNames()).thenThrow(ioException); - - assertThrows(IOException.class, () -> pdfAttachmentService.addAttachment(document, embeddedFilesTree, attachments)); - - verify(embeddedFilesTree).getNames(); - } - - @Test - void addAttachmentToPDF_AttachmentInputStreamThrowsIOException() throws IOException { - try (var document = new PDDocument()) { - var embeddedFilesTree = mock(PDEmbeddedFilesNameTreeNode.class); - var attachments = List.of(mock(MultipartFile.class)); - var existingNames = new HashMap(); - var ioException = new IOException("Failed to read attachment stream"); - - when(embeddedFilesTree.getNames()).thenReturn(existingNames); - when(attachments.get(0).getOriginalFilename()).thenReturn("corrupted.file"); - when(attachments.get(0).getInputStream()).thenThrow(ioException); - when(attachments.get(0).getSize()).thenReturn(10L); - - byte[] result = pdfAttachmentService.addAttachment(document, embeddedFilesTree, attachments); - - assertNotNull(result); - assertTrue(result.length > 0); - verify(embeddedFilesTree).setNames(anyMap()); - } - } - - @Test - void addAttachmentToPDF_WithProtectedDocument() throws IOException { - try (var document = new PDDocument()) { - // Create a document with restricted permissions (this simulates an encrypted/protected document) - AccessPermission ap = new AccessPermission(); - ap.setCanExtractContent(false); // Restrict content extraction initially - var spp = new StandardProtectionPolicy("owner", "user", ap); - document.protect(spp); - - var embeddedFilesTree = mock(PDEmbeddedFilesNameTreeNode.class); - var attachments = List.of(mock(MultipartFile.class)); - var existingNames = new HashMap(); - - when(embeddedFilesTree.getNames()).thenReturn(existingNames); - when(attachments.get(0).getOriginalFilename()).thenReturn("test.txt"); - when(attachments.get(0).getInputStream()).thenReturn( - new ByteArrayInputStream("Test content".getBytes())); - when(attachments.get(0).getSize()).thenReturn(12L); - when(attachments.get(0).getContentType()).thenReturn("text/plain"); - - byte[] result = pdfAttachmentService.addAttachment(document, embeddedFilesTree, attachments); - - assertNotNull(result); - assertTrue(result.length > 0); - verify(embeddedFilesTree).setNames(anyMap()); - } - } - - @Test - void addAttachmentToPDF_WithRestrictedPermissions() throws IOException { - try (var document = new PDDocument()) { - // Create a document with very restricted permissions that should block permission changes - AccessPermission ap = new AccessPermission(); - ap.setCanModify(false); - ap.setCanAssembleDocument(false); - ap.setCanExtractContent(false); - var spp = new StandardProtectionPolicy("owner", "user", ap); - document.protect(spp); - - var embeddedFilesTree = mock(PDEmbeddedFilesNameTreeNode.class); - var attachments = List.of(mock(MultipartFile.class)); - var existingNames = new HashMap(); - - when(embeddedFilesTree.getNames()).thenReturn(existingNames); - when(attachments.get(0).getOriginalFilename()).thenReturn("test.txt"); - when(attachments.get(0).getInputStream()).thenReturn( - new ByteArrayInputStream("Test content".getBytes())); - when(attachments.get(0).getSize()).thenReturn(12L); - when(attachments.get(0).getContentType()).thenReturn("text/plain"); - - byte[] result = pdfAttachmentService.addAttachment(document, embeddedFilesTree, attachments); - - assertNotNull(result); - assertTrue(result.length > 0); - verify(embeddedFilesTree).setNames(anyMap()); - } - } - - @Test - void addAttachmentToPDF_WithNonEncryptedDocument() throws IOException { - try (var document = new PDDocument()) { - var embeddedFilesTree = mock(PDEmbeddedFilesNameTreeNode.class); - var attachments = List.of(mock(MultipartFile.class)); - var existingNames = new HashMap(); - - when(embeddedFilesTree.getNames()).thenReturn(existingNames); - when(attachments.get(0).getOriginalFilename()).thenReturn("test.txt"); - when(attachments.get(0).getInputStream()).thenReturn( - new ByteArrayInputStream("Test content".getBytes())); - when(attachments.get(0).getSize()).thenReturn(12L); - when(attachments.get(0).getContentType()).thenReturn("text/plain"); - - byte[] result = pdfAttachmentService.addAttachment(document, embeddedFilesTree, attachments); - - assertNotNull(result); - assertTrue(result.length > 0); - // Verify permissions are set correctly for non-encrypted documents - AccessPermission permissions = document.getCurrentAccessPermission(); - assertTrue(permissions.canExtractContent()); - assertTrue(permissions.canExtractForAccessibility()); - assertTrue(permissions.canModifyAnnotations()); - verify(embeddedFilesTree).setNames(anyMap()); - } - } -}