/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.pdfbox.pdmodel.interactive.form; import static org.junit.Assert.assertTrue; import java.awt.image.BufferedImage; import java.io.File; import java.io.FileOutputStream; import java.io.FilenameFilter; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.URL; import javax.imageio.ImageIO; import org.apache.pdfbox.pdmodel.PDDocument; import org.apache.pdfbox.rendering.PDFRenderer; import org.apache.pdfbox.rendering.TestPDFToImage; import org.junit.Before; import org.junit.Test; /** * Test flatten different forms and compare with rendering. * * The tests are currently disabled to not run within the CI environment * as the test results need manual inspection. Enable as needed. * */ public class PDAcroFormFlattenTest { private static final File IN_DIR = new File("target/test-output/flatten/in"); private static final File OUT_DIR = new File("target/test-output/flatten/out"); @Before public void setUp() { IN_DIR.mkdirs();; OUT_DIR.mkdirs();; } /* * PDFBOX-142 Filled template. */ // @Test public void testFlattenPDFBOX142() throws IOException { String sourceUrl = "https://issues.apache.org/jira/secure/attachment/12742551/Testformular1.pdf"; String targetFileName = "Testformular1.pdf"; flattenAndCompare(sourceUrl, targetFileName); } /* * PDFBOX-563 Filled template. */ // @Test public void testFlattenPDFBOX563() throws IOException { String sourceUrl = "https://issues.apache.org/jira/secure/attachment/12425859/TestFax_56972.pdf"; String targetFileName = "TestFax_56972.pdf"; flattenAndCompare(sourceUrl, targetFileName); } /* * PDFBOX-2469 Empty template. */ // @Test public void testFlattenPDFBOX2469Empty() throws IOException { String sourceUrl = "https://issues.apache.org/jira/secure/attachment/12682897/FormI-9-English.pdf"; String targetFileName = "FormI-9-English.pdf"; flattenAndCompare(sourceUrl, targetFileName); } /* * PDFBOX-2469 Filled template. */ // @Test public void testFlattenPDFBOX2469Filled() throws IOException { String sourceUrl = "https://issues.apache.org/jira/secure/attachment/12678455/testPDF_acroForm.pdf"; String targetFileName = "testPDF_acroForm.pdf"; flattenAndCompare(sourceUrl, targetFileName); } /* * PDFBOX-2586 Empty template. */ // @Test public void testFlattenPDFBOX2586() throws IOException { String sourceUrl = "https://issues.apache.org/jira/secure/attachment/12689788/test.pdf"; String targetFileName = "test-2586.pdf"; flattenAndCompare(sourceUrl, targetFileName); } /* * PDFBOX-3083 Filled template rotated. */ // @Test public void testFlattenPDFBOX3083() throws IOException { String sourceUrl = "https://issues.apache.org/jira/secure/attachment/12770263/mypdf.pdf"; String targetFileName = "mypdf.pdf"; flattenAndCompare(sourceUrl, targetFileName); } /* * PDFBOX-3262 Hidden fields */ // @Test public void testFlattenPDFBOX3262() throws IOException { String sourceUrl = "https://issues.apache.org/jira/secure/attachment/12792007/hidden_fields.pdf"; String targetFileName = "hidden_fields.pdf"; assertTrue(flattenAndCompare(sourceUrl, targetFileName)); } /* * PDFBOX-3396 Signed Document 1. */ // @Test public void testFlattenPDFBOX3396_1() throws IOException { String sourceUrl = "https://issues.apache.org/jira/secure/attachment/12816014/Signed-Document-1.pdf"; String targetFileName = "Signed-Document-1.pdf"; flattenAndCompare(sourceUrl, targetFileName); } /* * PDFBOX-3396 Signed Document 2. */ // @Test public void testFlattenPDFBOX3396_2() throws IOException { String sourceUrl = "https://issues.apache.org/jira/secure/attachment/12816016/Signed-Document-2.pdf"; String targetFileName = "Signed-Document-2.pdf"; flattenAndCompare(sourceUrl, targetFileName); } /* * PDFBOX-3396 Signed Document 3. */ // @Test public void testFlattenPDFBOX3396_3() throws IOException { String sourceUrl = "https://issues.apache.org/jira/secure/attachment/12821307/Signed-Document-3.pdf"; String targetFileName = "Signed-Document-3.pdf"; flattenAndCompare(sourceUrl, targetFileName); } /* * PDFBOX-3396 Signed Document 4. */ // @Test public void testFlattenPDFBOX3396_4() throws IOException { String sourceUrl = "https://issues.apache.org/jira/secure/attachment/12821308/Signed-Document-4.pdf"; String targetFileName = "Signed-Document-4.pdf"; flattenAndCompare(sourceUrl, targetFileName); } /* * PDFBOX-3587 Empty template. */ // @Test public void testFlattenOpenOfficeForm() throws IOException { String sourceUrl = "https://issues.apache.org/jira/secure/attachment/12839977/OpenOfficeForm.pdf"; String targetFileName = "OpenOfficeForm.pdf"; flattenAndCompare(sourceUrl, targetFileName); } /* * PDFBOX-3587 Filled template. */ // @Test public void testFlattenOpenOfficeFormFilled() throws IOException { String sourceUrl = "https://issues.apache.org/jira/secure/attachment/12840280/OpenOfficeForm_filled.pdf"; String targetFileName = "OpenOfficeForm_filled.pdf"; flattenAndCompare(sourceUrl, targetFileName); } /* * Flatten and compare with generated image samples. */ private static boolean flattenAndCompare(String sourceUrl, String targetFileName) throws IOException { generateSamples(sourceUrl,targetFileName); File inputFile = new File(IN_DIR, targetFileName); File outputFile = new File(OUT_DIR, targetFileName); PDDocument testPdf = PDDocument.load(inputFile); testPdf.getDocumentCatalog().getAcroForm().flatten(); testPdf.setAllSecurityToBeRemoved(true); assertTrue(testPdf.getDocumentCatalog().getAcroForm().getFields().isEmpty()); testPdf.save(outputFile); testPdf.close(); // compare rendering TestPDFToImage testPDFToImage = new TestPDFToImage(TestPDFToImage.class.getName()); if (!testPDFToImage.doTestFile(outputFile, IN_DIR.getAbsolutePath(), OUT_DIR.getAbsolutePath())) { // don't fail, rendering is different on different systems, result must be viewed manually System.out.println("Rendering of " + outputFile + " failed or is not identical to expected rendering in " + IN_DIR + " directory"); removeMatchingRenditions(inputFile); return false; } else { // cleanup input and output directory for matching files. removeAllRenditions(inputFile); inputFile.delete(); outputFile.delete(); } return true; } /* * Generate the sample images to which the PDF will be compared after flatten. */ private static void generateSamples(String sourceUrl, String targetFile) throws IOException { getFromUrl(sourceUrl, targetFile); File file = new File(IN_DIR,targetFile); PDDocument document = PDDocument.load(file, (String)null); String outputPrefix = IN_DIR.getAbsolutePath() + '/' + file.getName() + "-"; int numPages = document.getNumberOfPages(); PDFRenderer renderer = new PDFRenderer(document); for (int i = 0; i < numPages; i++) { String fileName = outputPrefix + (i + 1) + ".png"; BufferedImage image = renderer.renderImageWithDPI(i, 96); // Windows native DPI ImageIO.write(image, "PNG", new File(fileName)); } document.close(); } /* * Get a PDF from URL and copy to file for processing. */ private static void getFromUrl(String sourceUrl, String targetFile) throws IOException { URL url = new URL(sourceUrl); InputStream is = url.openStream(); OutputStream os = new FileOutputStream(new File(IN_DIR,targetFile)); byte[] b = new byte[2048]; int length; while ((length = is.read(b)) != -1) { os.write(b, 0, length); } is.close(); os.close(); } /* * Remove renditions for the PDF from the input directory for which there is no * corresponding rendition in the output directory. * Renditions in the output directory which were identical to the ones in the * input directory will have been deleted by the TestPDFToImage utility. */ private static void removeMatchingRenditions(final File inputFile) { File[] testFiles = inputFile.getParentFile().listFiles(new FilenameFilter() { @Override public boolean accept(File dir, String name) { return (name.startsWith(inputFile.getName()) && name.toLowerCase().endsWith(".png")); } }); for (File testFile : testFiles) { if (! new File(OUT_DIR, testFile.getName()).exists()) { testFile.delete(); } } } /* * Remove renditions for the PDF from the input directory. * The output directory will have been cleaned by the TestPDFToImage utility. */ private static void removeAllRenditions(final File inputFile) { File[] testFiles = inputFile.getParentFile().listFiles(new FilenameFilter() { @Override public boolean accept(File dir, String name) { return (name.startsWith(inputFile.getName()) && name.toLowerCase().endsWith(".png")); } }); for (File testFile : testFiles) { testFile.delete(); } } }