Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DFR-3327-PDF-Documents-missing-signatures-Bulk-Print #2072

Merged
merged 18 commits into from
Jan 27, 2025
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
529e36a
DFR-3327-PDF-Documents-missing-signatures-Bulk-Print
dawudgovuk Jan 8, 2025
0e4bcf1
DFR-3327-PDF-Documents-missing-signatures-Bulk-Print
dawudgovuk Jan 8, 2025
b072bd8
DFR-3327-PDF-Documents-missing-signatures-Bulk-Print
dawudgovuk Jan 8, 2025
9b00690
DFR-3327-PDF-Documents-missing-signatures-Bulk-Print
dawudgovuk Jan 9, 2025
23db058
Merge branch 'master' into DFR-3327-PDF-Documents-missing-signatures-…
dawudgovuk Jan 9, 2025
1a89b1f
DFR-3327-PDF-Documents-missing-signatures-Bulk-Print
dawudgovuk Jan 9, 2025
e81395e
DFR-2961-CS-Postcode-field
dawudgovuk Jan 13, 2025
af1fc03
DFR-2961-CS-Postcode-field
dawudgovuk Jan 13, 2025
697eb26
Merge branch 'master' into DFR-3327-PDF-Documents-missing-signatures-…
dawudgovuk Jan 14, 2025
6543295
DFR-3327-PDF-Documents-missing-signatures-Bulk-Print
dawudgovuk Jan 14, 2025
2365fe2
DFR-3327-PDF-Documents-missing-signatures-Bulk-Print
dawudgovuk Jan 15, 2025
e7fe700
Update DocumentConversionService.java
ptrelease Jan 15, 2025
30de8b5
DFR-3327-PDF-Documents-missing-signatures-Bulk-Print
dawudgovuk Jan 15, 2025
19e27cf
Merge branch 'master' into DFR-3327-PDF-Documents-missing-signatures-…
dawudgovuk Jan 15, 2025
232f667
Merge branch 'master' into DFR-3327-PDF-Documents-missing-signatures-…
dawudgovuk Jan 21, 2025
bb73c10
Merge branch 'master' into DFR-3327-PDF-Documents-missing-signatures-…
al-hmcts Jan 22, 2025
fa86857
Merge branch 'master' into DFR-3327-PDF-Documents-missing-signatures-…
dawudgovuk Jan 23, 2025
2735914
Merge branch 'master' into DFR-3327-PDF-Documents-missing-signatures-…
al-hmcts Jan 27, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,12 @@
import org.apache.pdfbox.Loader;
import org.apache.pdfbox.io.IOUtils;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage;
import org.apache.pdfbox.pdmodel.PDPageContentStream;
import org.apache.pdfbox.pdmodel.interactive.annotation.PDAnnotation;
import org.apache.pdfbox.pdmodel.interactive.annotation.PDAppearanceStream;
import org.apache.pdfbox.pdmodel.interactive.form.PDAcroForm;
import org.apache.pdfbox.util.Matrix;
import org.apache.tika.Tika;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.FileSystemResource;
Expand All @@ -26,6 +31,7 @@

import java.io.File;
import java.io.IOException;
import java.util.List;
import java.util.Optional;

@Service
Expand Down Expand Up @@ -73,6 +79,7 @@ public byte[] flattenPdfDocument(byte[] document) {

if (acroForm.isPresent()) {
acroForm.get().flatten();
flattenAnnotations(doc);
doc.save(bos);
doc.close();
return bos.toByteArray();
Expand All @@ -85,6 +92,41 @@ public byte[] flattenPdfDocument(byte[] document) {
return document;
}

private void flattenAnnotations(PDDocument doc) throws IOException {
dawudgovuk marked this conversation as resolved.
Show resolved Hide resolved
for (PDPage page : doc.getPages()) {
List<PDAnnotation> annotations = page.getAnnotations();
for (PDAnnotation annotation : annotations) {
PDAppearanceStream appearanceStream = annotation.getNormalAppearanceStream();
if (appearanceStream != null) {
transformAnnotationsToContentStream(doc, page, annotation, appearanceStream);
}
}
annotations.clear();
}
}
ptrelease marked this conversation as resolved.
Show resolved Hide resolved

private void transformAnnotationsToContentStream(PDDocument doc, PDPage page, PDAnnotation annotation,
PDAppearanceStream appearanceStream) throws IOException {
float appearanceWidth = (float) appearanceStream.getBBox().getWidth();
float appearanceHeight = (float) appearanceStream.getBBox().getHeight();

if (appearanceWidth > 0 && appearanceHeight > 0) {
try (PDPageContentStream contentStream =
new PDPageContentStream(doc, page, PDPageContentStream.AppendMode.APPEND,
true, true)) {
contentStream.saveGraphicsState();
float x = (float) annotation.getRectangle().getLowerLeftX();
float y = (float) annotation.getRectangle().getLowerLeftY();
float width = (float) annotation.getRectangle().getWidth();
float height = (float) annotation.getRectangle().getHeight();
Matrix transformation = new Matrix(width / appearanceWidth, 0, 0, height / appearanceHeight, x, y);
contentStream.transform(transformation);
contentStream.drawForm(appearanceStream);
contentStream.restoreGraphicsState();
}
}
}
dawudgovuk marked this conversation as resolved.
Show resolved Hide resolved

private byte[] convert(Document sourceDocument, String auth) {
try {
String filename = getConvertedFilename(sourceDocument.getFileName());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
import org.apache.commons.lang3.ObjectUtils;
import org.apache.pdfbox.Loader;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage;
import org.apache.pdfbox.pdmodel.interactive.annotation.PDAnnotation;
import org.apache.pdfbox.pdmodel.interactive.form.PDAcroForm;
import org.junit.Before;
import org.junit.Test;
Expand All @@ -24,6 +26,7 @@

import java.io.IOException;
import java.io.InputStream;
import java.util.List;

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.is;
Expand Down Expand Up @@ -89,6 +92,39 @@ public void testFlattenPdfDocument() throws IOException {
}
}

@Test
public void testFlattenAnnotations() throws IOException {

byte[] editedPdfBytes = loadResource("/fixtures/D11Annotations.pdf");

// Ensure the original PDF has an AcroForm and at least one form field
try (PDDocument originalDoc = Loader.loadPDF(editedPdfBytes)) {
PDAcroForm originalAcroForm = originalDoc.getDocumentCatalog().getAcroForm();
assertNotNull("Document should have an AcroForm", originalAcroForm);
for (PDPage page : originalDoc.getPages()) {
List<PDAnnotation> annotations = page.getAnnotations();
assertFalse("Document should have Annotations", annotations.isEmpty());
}
}

// Flatten the PDF using the method under test
byte[] flattenedPdfBytes = documentConversionService.flattenPdfDocument(editedPdfBytes);

// Load the flattened PDF for validation
try (PDDocument document = Loader.loadPDF(flattenedPdfBytes)) {
for (PDPage page : document.getPages()) {
List<PDAnnotation> annotations = page.getAnnotations();
assertTrue("Annotations were not removed after flattening.", annotations.isEmpty());
}
}

// Load the flattened PDF and check that form fields have been removed/flattened
try (PDDocument flattenedDoc = Loader.loadPDF(flattenedPdfBytes)) {
PDAcroForm flattenedAcroForm = flattenedDoc.getDocumentCatalog().getAcroForm();
assertTrue("AcroForm should be flattened", ObjectUtils.isEmpty(flattenedAcroForm.getFields()));
}
}

@Test
public void doNotFlattenPdfDocumentWithNoFromLayer() throws IOException {

Expand Down
Binary file added src/test/resources/fixtures/D11Annotations.pdf
Binary file not shown.