From 2b641f8456373d923f4518e9a92c0790e44ee469 Mon Sep 17 00:00:00 2001 From: Brett Shouse Date: Sat, 26 Aug 2017 18:11:38 -0600 Subject: [PATCH 1/3] Changes to support Protection and Attachments --- pom.xml | 6 + .../pdf/layoutmanager/PdfLayoutMgr.java | 16 +++ src/test/java/TestManualllyProtectAttach.java | 112 ++++++++++++++++++ 3 files changed, 134 insertions(+) create mode 100644 src/test/java/TestManualllyProtectAttach.java diff --git a/pom.xml b/pom.xml index 8aa0575..a461f4c 100644 --- a/pom.xml +++ b/pom.xml @@ -150,6 +150,12 @@ this directory like the following (you'll have to replace the question marks): 0.0.6 test + + org.bouncycastle + bcprov-jdk15on + 1.58 + test + diff --git a/src/main/java/com/planbase/pdf/layoutmanager/PdfLayoutMgr.java b/src/main/java/com/planbase/pdf/layoutmanager/PdfLayoutMgr.java index f25aa71..a2252e6 100644 --- a/src/main/java/com/planbase/pdf/layoutmanager/PdfLayoutMgr.java +++ b/src/main/java/com/planbase/pdf/layoutmanager/PdfLayoutMgr.java @@ -15,9 +15,12 @@ package com.planbase.pdf.layoutmanager; import org.apache.pdfbox.pdmodel.PDDocument; +import org.apache.pdfbox.pdmodel.PDDocumentCatalog; import org.apache.pdfbox.pdmodel.PDPage; import org.apache.pdfbox.pdmodel.PDPageContentStream; import org.apache.pdfbox.pdmodel.common.PDRectangle; +import org.apache.pdfbox.pdmodel.common.filespecification.PDEmbeddedFile; +import org.apache.pdfbox.pdmodel.encryption.ProtectionPolicy; import org.apache.pdfbox.pdmodel.graphics.color.PDColorSpace; import org.apache.pdfbox.pdmodel.graphics.color.PDDeviceRGB; import org.apache.pdfbox.pdmodel.graphics.image.JPEGFactory; @@ -28,6 +31,7 @@ import java.awt.Color; import java.awt.image.BufferedImage; import java.io.IOException; +import java.io.InputStream; import java.io.OutputStream; import java.io.UnsupportedEncodingException; import java.util.ArrayList; @@ -928,4 +932,16 @@ public static String convertJavaStringToWinAnsi(String in) { } return sB.toString(); } + + public void protect(ProtectionPolicy policy) throws IOException { + doc.protect(policy); + } + + public PDEmbeddedFile addEmbeddedFile(InputStream str) throws IOException { + return new PDEmbeddedFile(doc,str); + } + + public PDDocumentCatalog getDocumentCatalog() { + return doc.getDocumentCatalog(); + } } diff --git a/src/test/java/TestManualllyProtectAttach.java b/src/test/java/TestManualllyProtectAttach.java new file mode 100644 index 0000000..c3c9e9c --- /dev/null +++ b/src/test/java/TestManualllyProtectAttach.java @@ -0,0 +1,112 @@ +// Copyright 2013-03-13 PlanBase Inc. & Glen Peterson +// +// Licensed 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. + +import com.planbase.pdf.layoutmanager.Cell; +import com.planbase.pdf.layoutmanager.CellStyle; +import com.planbase.pdf.layoutmanager.LogicalPage; +import com.planbase.pdf.layoutmanager.PdfLayoutMgr; +import com.planbase.pdf.layoutmanager.TextStyle; +import com.planbase.pdf.layoutmanager.XyOffset; + +import org.apache.pdfbox.pdmodel.PDDocumentNameDictionary; +import org.apache.pdfbox.pdmodel.PDEmbeddedFilesNameTreeNode; +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.apache.pdfbox.pdmodel.font.PDType1Font; +import org.junit.Test; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.util.GregorianCalendar; +import java.util.HashMap; +import java.util.Map; +import java.awt.Color; + +public class TestManualllyProtectAttach { + +// public static void main(String... args) throws IOException, COSVisitorException { +// new TestManualllyPdfLayoutMgr().testPdf(); +// } + + @Test + public void testProtectAttach() throws IOException { + // Nothing happens without a PdfLayoutMgr. + PdfLayoutMgr pageMgr = PdfLayoutMgr.newRgbPageMgr(); + + // A LogicalPage is a group of pages with the same settings. When your contents scroll off + // the bottom of a page, a new page is automatically created for you with the settings taken + // from the LogicPage grouping. If you don't want a new page, be sure to stay within the + // bounds of the current one! + LogicalPage lp = pageMgr.logicalPageStart(); + + + // Include a simple description + Cell protectAttach = Cell.builder(CellStyle.DEFAULT, lp.pageWidth()-100f).textStyle(TextStyle.of(PDType1Font.HELVETICA, 12f, Color.BLACK)).addStrs("This document should be protected against writing","Check the document properties for Security.","It should be password protected with 40-bit encryption","There should also be a PNG image attached.").build(); + XyOffset xya = lp.putCell(20f, lp.yPageTop(), protectAttach); + + lp.commit(); + + // Setup basic access permission + AccessPermission ap = new AccessPermission(); + ap.setCanModify(false); + + // Setup a protection policy + StandardProtectionPolicy sp = new StandardProtectionPolicy("ownerPassword","",ap); + + // Apply protection + pageMgr.protect(sp); + + // Add an attachemnt + PDEmbeddedFilesNameTreeNode efTree = new PDEmbeddedFilesNameTreeNode(); + Map efMap = new HashMap(1); + + + PDComplexFileSpecification pf = new PDComplexFileSpecification(); + pf.setFile("sampleScreenShot.png"); + File png = new File("sampleScreenShot.png"); + FileInputStream fis = new FileInputStream(png); + PDEmbeddedFile ef = pageMgr.addEmbeddedFile(fis); + fis.close(); + ef.setSubtype("image/png"); + ef.setSize((int)png.length()); + ef.setCreationDate(new GregorianCalendar()); + pf.setEmbeddedFile(ef); + efMap.put("Picture", pf); + efTree.setNames(efMap); + PDDocumentNameDictionary dict = new PDDocumentNameDictionary(pageMgr.getDocumentCatalog()); + dict.setEmbeddedFiles(efTree); + pageMgr.getDocumentCatalog().setNames(dict); + + // All done - write it out! + + // In a web application, this could be: + // + // httpServletResponse.setContentType("application/pdf") // your server may do this for you. + // os = httpServletResponse.getOutputStream() // you probably have to do this + // + // Also, in a web app, you probably want name your action something.pdf and put + // target="_blank" on your link to the PDF download action. + + // We're just going to write to a file. + OutputStream os = new FileOutputStream("testProtectAttach.pdf"); + + // Commit it to the output stream! + pageMgr.save(os); + } +} From ff4d9c96680ee66d779fde88bf147d1ef57b82a8 Mon Sep 17 00:00:00 2001 From: B Shouse Date: Sun, 27 Aug 2017 19:31:42 -0600 Subject: [PATCH 2/3] fix "tabbing" on scope --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index a461f4c..9b47e5c 100644 --- a/pom.xml +++ b/pom.xml @@ -154,7 +154,7 @@ this directory like the following (you'll have to replace the question marks): org.bouncycastle bcprov-jdk15on 1.58 - test + test From ef070d4e264c551bcac41600491bd77470619c82 Mon Sep 17 00:00:00 2001 From: B Shouse Date: Sun, 27 Aug 2017 19:34:20 -0600 Subject: [PATCH 3/3] Reformat excessively long line --- src/test/java/TestManualllyProtectAttach.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/test/java/TestManualllyProtectAttach.java b/src/test/java/TestManualllyProtectAttach.java index c3c9e9c..cde1709 100644 --- a/src/test/java/TestManualllyProtectAttach.java +++ b/src/test/java/TestManualllyProtectAttach.java @@ -57,7 +57,11 @@ public void testProtectAttach() throws IOException { // Include a simple description - Cell protectAttach = Cell.builder(CellStyle.DEFAULT, lp.pageWidth()-100f).textStyle(TextStyle.of(PDType1Font.HELVETICA, 12f, Color.BLACK)).addStrs("This document should be protected against writing","Check the document properties for Security.","It should be password protected with 40-bit encryption","There should also be a PNG image attached.").build(); + Cell protectAttach = Cell.builder(CellStyle.DEFAULT, lp.pageWidth() - 100f) + .textStyle(TextStyle.of(PDType1Font.HELVETICA, 12f, Color.BLACK)) + .addStrs("This document should be protected against writing", "Check the document properties for Security.", + "It should be password protected with 40-bit encryption", "There should also be a PNG image attached.") + .build(); XyOffset xya = lp.putCell(20f, lp.yPageTop(), protectAttach); lp.commit();