From cc3e985f2ed5c78b04f494feb2abdb534479a06e Mon Sep 17 00:00:00 2001 From: emusic Date: Fri, 17 Jan 2020 14:39:04 +0100 Subject: changes in qr placeholder search - additional information removed, location of dictionary used for storing qr info --- .../placeholder/PDFBoxPlaceholderExtractor.java | 6 +- .../placeholder/SignaturePlaceholderExtractor.java | 43 +++----- .../lib/impl/pdfbox2/positioning/Positioning.java | 4 +- .../impl/signing/pdfbox2/PADESPDFBOXSigner.java | 113 ++++++++++++--------- 4 files changed, 81 insertions(+), 85 deletions(-) (limited to 'pdf-as-pdfbox-2/src/main/java') diff --git a/pdf-as-pdfbox-2/src/main/java/at/gv/egiz/pdfas/lib/impl/pdfbox2/placeholder/PDFBoxPlaceholderExtractor.java b/pdf-as-pdfbox-2/src/main/java/at/gv/egiz/pdfas/lib/impl/pdfbox2/placeholder/PDFBoxPlaceholderExtractor.java index 730a6581..256400a0 100644 --- a/pdf-as-pdfbox-2/src/main/java/at/gv/egiz/pdfas/lib/impl/pdfbox2/placeholder/PDFBoxPlaceholderExtractor.java +++ b/pdf-as-pdfbox-2/src/main/java/at/gv/egiz/pdfas/lib/impl/pdfbox2/placeholder/PDFBoxPlaceholderExtractor.java @@ -9,16 +9,12 @@ import at.gv.egiz.pdfas.lib.impl.status.PDFObject; public class PDFBoxPlaceholderExtractor implements PlaceholderExtractor { @Override - public SignaturePlaceholderData extract(PDFObject doc, - String placeholderId, int matchMode) throws PdfAsException { - + public SignaturePlaceholderData extract(PDFObject doc, String placeholderId, int matchMode) throws PdfAsException { if (doc instanceof PDFBOXObject) { PDFBOXObject object = (PDFBOXObject) doc; return SignaturePlaceholderExtractor.extract(object.getDocument(), placeholderId, matchMode); } - throw new PdfAsException("INVALID STATE"); } - } diff --git a/pdf-as-pdfbox-2/src/main/java/at/gv/egiz/pdfas/lib/impl/pdfbox2/placeholder/SignaturePlaceholderExtractor.java b/pdf-as-pdfbox-2/src/main/java/at/gv/egiz/pdfas/lib/impl/pdfbox2/placeholder/SignaturePlaceholderExtractor.java index 31bbb76f..f69b1788 100644 --- a/pdf-as-pdfbox-2/src/main/java/at/gv/egiz/pdfas/lib/impl/pdfbox2/placeholder/SignaturePlaceholderExtractor.java +++ b/pdf-as-pdfbox-2/src/main/java/at/gv/egiz/pdfas/lib/impl/pdfbox2/placeholder/SignaturePlaceholderExtractor.java @@ -50,14 +50,8 @@ import java.awt.geom.AffineTransform; import java.awt.geom.NoninvertibleTransformException; import java.awt.image.BufferedImage; import java.io.IOException; -import java.util.HashMap; -import java.util.Hashtable; -import java.util.List; -import java.util.Map; +import java.util.*; import java.util.Map.Entry; -import java.util.Properties; -import java.util.Set; -import java.util.Vector; import javassist.bytecode.stackmap.TypeData.ClassName; @@ -109,7 +103,7 @@ public class SignaturePlaceholderExtractor extends PDFStreamEngine implements Pl private static Logger logger = LoggerFactory .getLogger(SignaturePlaceholderExtractor.class); - private List placeholders = new Vector(); + private static List placeholders = new Vector<>(); private int currentPage = 0; private PDDocument doc; @@ -131,10 +125,12 @@ public class SignaturePlaceholderExtractor extends PDFStreamEngine implements Pl addOperator( processor ); } - this.doc = doc; } + public static List listPlaceholders() { + return placeholders; + } /** * Search the document for placeholder images and possibly included * additional info.
@@ -310,8 +306,8 @@ public class SignaturePlaceholderExtractor extends PDFStreamEngine implements Pl float yPos = unrotatedCTM.getYPosition(); float yScale = unrotatedCTM.getScaleY(); float y = yPos + yScale; - float w = unrotatedCTM.getScaleX();; - + float w = unrotatedCTM.getScaleX(); + logger.debug("Page height: {}", page.getCropBox().getHeight()); logger.debug("Page width: {}", page.getCropBox().getWidth()); @@ -349,39 +345,31 @@ public class SignaturePlaceholderExtractor extends PDFStreamEngine implements Pl //TODO: pdfbox2 - was override public Map getFonts() { - if (fonts == null) - { + if (fonts == null) { // at least an empty map will be returned // TODO we should return null instead of an empty map fonts = new HashMap(); if(this.getResources() != null && this.getResources().getCOSObject() != null) { COSDictionary fontsDictionary = (COSDictionary) this.getResources().getCOSObject().getDictionaryObject(COSName.FONT); - if (fontsDictionary == null) - { + if (fontsDictionary == null) { // ignore we do not want to set anything, never when creating a signature!!!!! //fontsDictionary = new COSDictionary(); //this.getResources().getCOSDictionary().setItem(COSName.FONT, fontsDictionary); } - else - { - for (COSName fontName : fontsDictionary.keySet()) - { + else { + for (COSName fontName : fontsDictionary.keySet()) { COSBase font = fontsDictionary.getDictionaryObject(fontName); // data-000174.pdf contains a font that is a COSArray, looks to be an error in the // PDF, we will just ignore entries that are not dictionaries. - if (font instanceof COSDictionary) - { + if (font instanceof COSDictionary) { PDFont newFont = null; - try - { + try { newFont = PDFontFactory.createFont((COSDictionary) font); } - catch (IOException exception) - { + catch (IOException exception) { logger.error("error while creating a font", exception); } - if (newFont != null) - { + if (newFont != null) { fonts.put(fontName.getName(), newFont); } } @@ -488,5 +476,4 @@ public class SignaturePlaceholderExtractor extends PDFStreamEngine implements Pl } return null; } - } diff --git a/pdf-as-pdfbox-2/src/main/java/at/gv/egiz/pdfas/lib/impl/pdfbox2/positioning/Positioning.java b/pdf-as-pdfbox-2/src/main/java/at/gv/egiz/pdfas/lib/impl/pdfbox2/positioning/Positioning.java index 7942edcd..8aaa51ac 100644 --- a/pdf-as-pdfbox-2/src/main/java/at/gv/egiz/pdfas/lib/impl/pdfbox2/positioning/Positioning.java +++ b/pdf-as-pdfbox-2/src/main/java/at/gv/egiz/pdfas/lib/impl/pdfbox2/positioning/Positioning.java @@ -196,8 +196,7 @@ public class Positioning { } } - if(make_new_page && counter!=0) - { + if(make_new_page && counter!=0) { make_new_page = false; } @@ -327,7 +326,6 @@ public class Positioning { // we do have text take SIGNATURE_MARGIN pos_y = page_height - page_length - SIGNATURE_MARGIN_VERTICAL; if (pos_y - footer_line <= table_height) { - ///TODO: new page should not be created when signature exists if(counter!=0) make_new_page = false; else{ diff --git a/pdf-as-pdfbox-2/src/main/java/at/gv/egiz/pdfas/lib/impl/signing/pdfbox2/PADESPDFBOXSigner.java b/pdf-as-pdfbox-2/src/main/java/at/gv/egiz/pdfas/lib/impl/signing/pdfbox2/PADESPDFBOXSigner.java index c99bb608..aa61d623 100644 --- a/pdf-as-pdfbox-2/src/main/java/at/gv/egiz/pdfas/lib/impl/signing/pdfbox2/PADESPDFBOXSigner.java +++ b/pdf-as-pdfbox-2/src/main/java/at/gv/egiz/pdfas/lib/impl/signing/pdfbox2/PADESPDFBOXSigner.java @@ -35,7 +35,7 @@ import at.gv.egiz.pdfas.lib.impl.ErrorExtractor; import at.gv.egiz.pdfas.lib.impl.SignaturePositionImpl; import at.gv.egiz.pdfas.lib.impl.configuration.SignatureProfileConfiguration; import at.gv.egiz.pdfas.lib.impl.pdfbox2.PDFBOXObject; -import at.gv.egiz.pdfas.lib.impl.pdfbox2.placeholder.SignatureFieldsExtractor; +import at.gv.egiz.pdfas.lib.impl.pdfbox2.placeholder.SignaturePlaceholderExtractor; import at.gv.egiz.pdfas.lib.impl.pdfbox2.positioning.Positioning; import at.gv.egiz.pdfas.lib.impl.pdfbox2.utils.PdfBoxUtils; import at.gv.egiz.pdfas.lib.impl.placeholder.PlaceholderFilter; @@ -69,8 +69,6 @@ import org.apache.pdfbox.pdmodel.common.PDRectangle; import org.apache.pdfbox.pdmodel.documentinterchange.logicalstructure.PDStructureElement; import org.apache.pdfbox.pdmodel.documentinterchange.logicalstructure.PDStructureTreeRoot; import org.apache.pdfbox.pdmodel.graphics.color.PDOutputIntent; -import org.apache.pdfbox.pdmodel.graphics.image.JPEGFactory; -import org.apache.pdfbox.pdmodel.graphics.image.PDImageXObject; import org.apache.pdfbox.pdmodel.interactive.digitalsignature.PDSignature; import org.apache.pdfbox.pdmodel.interactive.digitalsignature.SignatureOptions; import org.apache.pdfbox.pdmodel.interactive.form.PDAcroForm; @@ -93,7 +91,6 @@ import javax.activation.DataSource; import java.awt.*; import java.awt.image.BufferedImage; import java.io.ByteArrayOutputStream; -import java.io.Closeable; import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; @@ -109,6 +106,7 @@ public class PADESPDFBOXSigner implements IPdfSigner, IConfigurationConstants { PDFASSignatureInterface genericSigner) throws PdfAsException { PDFAsVisualSignatureProperties properties = null; + String placeholder_id = ""; if (!(genericPdfObject instanceof PDFBOXObject)) { // tODO: @@ -134,13 +132,37 @@ public class PADESPDFBOXSigner implements IPdfSigner, IConfigurationConstants { doc = pdfObject.getDocument(); //if signature already exists dont create new page List pdSignatureFieldList = doc.getSignatureFields(); + PDSignature signature; + + // sign a PDF with an existing empty signature, as created by the CreateEmptySignatureForm example. + String sigFieldName = pdfObject.getStatus().getSettings().getValue(SIGNATURE_FIELD_NAME); + signature = findExistingSignature(doc, sigFieldName); + if (signature == null) { + // create signature dictionary + signature = new PDSignature(); + } + else { + isAdobeSigForm = true; + } + + signature.setFilter(COSName.getPDFName(signer.getPDFFilter())); + signature.setSubFilter(COSName.getPDFName(signer.getPDFSubFilter())); + SignaturePlaceholderData signaturePlaceholderDataInit = PlaceholderFilter.checkPlaceholderSignatureLocation(pdfObject.getStatus(), pdfObject.getStatus().getSettings(), placeholder_id); + //gives a list of all placeholders + List placeholders = SignaturePlaceholderExtractor.listPlaceholders(); + if(checkAvailablePlaceholders(placeholders,existingSignatureLocations(doc))!=null) + { + placeholder_id = (checkAvailablePlaceholders(placeholders, existingSignatureLocations(doc))).getId(); + }; SignaturePlaceholderData signaturePlaceholderData = PlaceholderFilter - .checkPlaceholderSignature(pdfObject.getStatus(), pdfObject.getStatus().getSettings()); + .checkPlaceholderSignatureLocation(pdfObject.getStatus(), pdfObject.getStatus().getSettings(),placeholder_id); TablePos tablePos = null; + signature.setLocation(signaturePlaceholderData.getPlaceholderName()); + if (signaturePlaceholderData != null) { // Placeholder found! logger.info("Placeholder data found."); @@ -166,32 +188,8 @@ public class PADESPDFBOXSigner implements IPdfSigner, IConfigurationConstants { logger.debug("Placeholder Position set to: " + tablePos.toString()); } } - - //PDSignature signature = new PDSignature(); - - PDSignature signature; - - // sign a PDF with an existing empty signature, as created by the CreateEmptySignatureForm example. - String sigFieldName = pdfObject.getStatus().getSettings().getValue(SIGNATURE_FIELD_NAME); - signature = findExistingSignature(doc, sigFieldName); - //signature = findExistingSignature(doc, "ownerSignature"); - if (signature == null) { - // create signature dictionary - signature = new PDSignature(); - - } - else { - isAdobeSigForm = true; - } - - signature.setFilter(COSName.getPDFName(signer.getPDFFilter())); // default - // filter - signature.setSubFilter(COSName.getPDFName(signer.getPDFSubFilter())); - SignatureProfileSettings signatureProfileSettings = TableFactory .createProfile(requestedSignature.getSignatureProfileID(), pdfObject.getStatus().getSettings()); - - //Check if input document is PDF-A conform if (signatureProfileSettings.isPDFA()) { DataSource origDoc = pdfObject.getOriginalDocument(); @@ -200,7 +198,6 @@ public class PADESPDFBOXSigner implements IPdfSigner, IConfigurationConstants { //runPDFAPreflight(origDoc); } - ValueResolver resolver = new ValueResolver(requestedSignature, pdfObject.getStatus()); String signerName = resolver.resolve("SIG_SUBJECT", signatureProfileSettings.getValue("SIG_SUBJECT"), signatureProfileSettings); @@ -351,7 +348,7 @@ public class PADESPDFBOXSigner implements IPdfSigner, IConfigurationConstants { * (properties .getVisibleSignature())); sigbos.close(); */ - if (signaturePlaceholderData != null) { + /*if (signaturePlaceholderData != null) { InputStream fis = PADESPDFBOXSigner.class.getResourceAsStream("/placeholder/empty.jpg"); PDImageXObject img = JPEGFactory.createFromStream(doc, fis); @@ -367,12 +364,13 @@ public class PADESPDFBOXSigner implements IPdfSigner, IConfigurationConstants { logger.info("Placeholder name: " + signaturePlaceholderData.getPlaceholderName()); COSDictionary xobjectsDictionary = (COSDictionary) page.getResources().getCOSObject() .getDictionaryObject(COSName.XOBJECT); + + xobjectsDictionary.setItem(signaturePlaceholderData.getPlaceholderName(), img); xobjectsDictionary.setNeedToBeUpdated(true); page.getResources().getCOSObject().setNeedToBeUpdated(true); logger.info("Placeholder name: " + signaturePlaceholderData.getPlaceholderName()); - - } + }*/ if (signatureProfileSettings.isPDFA() || signatureProfileSettings.isPDFA3()) { PDDocumentCatalog root = doc.getDocumentCatalog(); @@ -597,13 +595,11 @@ public class PADESPDFBOXSigner implements IPdfSigner, IConfigurationConstants { signatureField.setAlternateFieldName(sigFieldName); } - ntn.getCOSObject().setNeedToBeUpdated(true); sigBlock.getCOSObject().setNeedToBeUpdated(true); structureTreeRoot.getCOSObject().setNeedToBeUpdated(true); objectDic.setNeedToBeUpdated(true); docElement.getCOSObject().setNeedToBeUpdated(true); - } } catch (Throwable e) { if (signatureProfileSettings.isPDFUA() == true) { @@ -652,9 +648,7 @@ public class PADESPDFBOXSigner implements IPdfSigner, IConfigurationConstants { // Ignore } } - logger.debug("Signature done!"); - } } @@ -722,8 +716,7 @@ public class PADESPDFBOXSigner implements IPdfSigner, IConfigurationConstants { } @Override - public PDFASSignatureExtractor buildBlindSignaturInterface(X509Certificate certificate, String filter, - String subfilter, Calendar date) { + public PDFASSignatureExtractor buildBlindSignaturInterface(X509Certificate certificate, String filter, String subfilter, Calendar date) { return new SignatureDataExtractor(certificate, filter, subfilter, date); } @@ -867,29 +860,51 @@ public class PADESPDFBOXSigner implements IPdfSigner, IConfigurationConstants { } // Find an existing signature. - private PDSignature findExistingSignature(PDDocument doc, String sigFieldName) - { + private PDSignature findExistingSignature(PDDocument doc, String sigFieldName) { PDSignature signature = null; PDSignatureField signatureField; PDAcroForm acroForm = doc.getDocumentCatalog().getAcroForm(); - if (acroForm != null) - { + if (acroForm != null) { signatureField = (PDSignatureField) acroForm.getField(sigFieldName); - if (signatureField != null) - { + if (signatureField != null) { // retrieve signature dictionary signature = signatureField.getSignature(); - if (signature == null) - { + if (signature == null) { signature = new PDSignature(); signatureField.getCOSObject().setItem(COSName.V, signature); } - else - { + else { throw new IllegalStateException("The signature field " + sigFieldName + " is already signed."); } } } return signature; } + + private List existingSignatureLocations(PDDocument doc) { + List existingLocations = new ArrayList<>(); + try { + List pdSignatureList = doc.getSignatureDictionaries(); + if(pdSignatureList.size() != 0) { + for(PDSignature sig : pdSignatureList) { + existingLocations.add(sig.getLocation()); + } + } + } catch (IOException e) { + e.printStackTrace(); + } + return existingLocations; + } + + //find first available placeholder + public SignaturePlaceholderData checkAvailablePlaceholders(List placeholders, List existingPlaceholders) { + SignaturePlaceholderData result = null; + for(int i = 0; i < placeholders.size(); ++i) { + if(!existingPlaceholders.contains(placeholders.get(i).getPlaceholderName())) { + result = placeholders.get(i); + break; + } + } + return result; + } } \ No newline at end of file -- cgit v1.2.3