diff --git a/pom.xml b/pom.xml index 8aa0575..9b47e5c 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..cde1709 --- /dev/null +++ b/src/test/java/TestManualllyProtectAttach.java @@ -0,0 +1,116 @@ +// 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); + } +}