diff options
Diffstat (limited to 'pdf-as-pdfbox/src/main')
5 files changed, 178 insertions, 58 deletions
diff --git a/pdf-as-pdfbox/src/main/java/at/gv/egiz/pdfas/lib/impl/signing/pdfbox/PADESPDFBOXSigner.java b/pdf-as-pdfbox/src/main/java/at/gv/egiz/pdfas/lib/impl/signing/pdfbox/PADESPDFBOXSigner.java index d1337ce2..8095911d 100644 --- a/pdf-as-pdfbox/src/main/java/at/gv/egiz/pdfas/lib/impl/signing/pdfbox/PADESPDFBOXSigner.java +++ b/pdf-as-pdfbox/src/main/java/at/gv/egiz/pdfas/lib/impl/signing/pdfbox/PADESPDFBOXSigner.java @@ -39,8 +39,10 @@ import java.util.Calendar; import java.util.List; import org.apache.commons.io.IOUtils; +import org.apache.pdfbox.cos.COSArray; import org.apache.pdfbox.cos.COSBase; import org.apache.pdfbox.cos.COSDictionary; +import org.apache.pdfbox.cos.COSInteger; import org.apache.pdfbox.cos.COSName; import org.apache.pdfbox.cos.COSString; import org.apache.pdfbox.exceptions.COSVisitorException; @@ -50,8 +52,13 @@ import org.apache.pdfbox.pdmodel.PDDocumentCatalog; import org.apache.pdfbox.pdmodel.PDPage; import org.apache.pdfbox.pdmodel.PDPageNode; import org.apache.pdfbox.pdmodel.PDResources; +import org.apache.pdfbox.pdmodel.common.PDNumberTreeNode; +import org.apache.pdfbox.pdmodel.documentinterchange.logicalstructure.PDAttributeObject; +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.xobject.PDJpeg; +import org.apache.pdfbox.pdmodel.interactive.annotation.PDAnnotationWidget; import org.apache.pdfbox.pdmodel.interactive.digitalsignature.PDSignature; import org.apache.pdfbox.pdmodel.interactive.digitalsignature.SignatureOptions; import org.apache.pdfbox.pdmodel.interactive.form.PDAcroForm; @@ -105,6 +112,8 @@ public class PADESPDFBOXSigner implements IPdfSigner, IConfigurationConstants { PDFASSignatureInterface genericSigner) throws PdfAsException { String fisTmpFile = null; + PDFAsVisualSignatureProperties properties=null; + if (!(genericPdfObject instanceof PDFBOXObject)) { // tODO: throw new PdfAsException(); @@ -152,8 +161,8 @@ public class PADESPDFBOXSigner implements IPdfSigner, IConfigurationConstants { logger.debug("Placeholder Profile set to: " + signaturePlaceholderData.getProfile()); requestedSignature - .setSignatureProfileID(signaturePlaceholderData - .getProfile()); + .setSignatureProfileID(signaturePlaceholderData + .getProfile()); } tablePos = signaturePlaceholderData.getTablePos(); @@ -165,7 +174,7 @@ public class PADESPDFBOXSigner implements IPdfSigner, IConfigurationConstants { PDSignature signature = new PDSignature(); signature.setFilter(COSName.getPDFName(signer.getPDFFilter())); // default - // filter + // filter signature.setSubFilter(COSName.getPDFName(signer .getPDFSubFilter())); @@ -313,7 +322,7 @@ public class PADESPDFBOXSigner implements IPdfSigner, IConfigurationConstants { requestedSignature.setSignaturePosition(position); - PDFAsVisualSignatureProperties properties = new PDFAsVisualSignatureProperties( + properties = new PDFAsVisualSignatureProperties( pdfObject.getStatus().getSettings(), pdfObject, (PdfBoxVisualObject) visualObject, positioningInstruction, signatureProfileSettings); @@ -348,7 +357,7 @@ public class PADESPDFBOXSigner implements IPdfSigner, IConfigurationConstants { logger.info("Placeholder name: " + signaturePlaceholderData - .getPlaceholderName()); + .getPlaceholderName()); COSDictionary xobjectsDictionary = (COSDictionary) page .findResources().getCOSDictionary() .getDictionaryObject(COSName.XOBJECT); @@ -356,10 +365,10 @@ public class PADESPDFBOXSigner implements IPdfSigner, IConfigurationConstants { .getPlaceholderName(), img); xobjectsDictionary.setNeedToBeUpdate(true); page.findResources().getCOSObject() - .setNeedToBeUpdate(true); + .setNeedToBeUpdate(true); logger.info("Placeholder name: " + signaturePlaceholderData - .getPlaceholderName()); + .getPlaceholderName()); } finally { IOUtils.closeQuietly(is); } @@ -397,23 +406,7 @@ public class PADESPDFBOXSigner implements IPdfSigner, IConfigurationConstants { } } - // if (signatureProfileSettings.isPDFA()) { // Check for - // PDF-UA - // PDDocumentCatalog root = doc.getDocumentCatalog(); - // PDStructureTreeRoot treeRoot = - // root.getStructureTreeRoot(); - // if (treeRoot != null) { // Handle as PDF-UA - // logger.info("Tree Root: {}", treeRoot.toString()); - // PDStructureElement docElement = PDFBoxTaggingUtils - // .getDocumentElement(treeRoot); - // PDStructureElement sigBlock = new PDStructureElement( - // "Table", docElement); - // root.getCOSObject().setNeedToBeUpdate(true); - // docElement.getCOSObject().setNeedToBeUpdate(true); - // treeRoot.getCOSObject().setNeedToBeUpdate(true); - // sigBlock.setTitle("Signature Table"); - // } - // } + options.setPage(positioningInstruction.getPage()); options.setVisualSignature(properties.getVisibleSignature()); @@ -433,25 +426,35 @@ public class PADESPDFBOXSigner implements IPdfSigner, IConfigurationConstants { sigFieldName = sigFieldName + count; PDAcroForm acroFormm = doc.getDocumentCatalog().getAcroForm(); + + // PDStructureTreeRoot pdstRoot = doc.getDocumentCatalog().getStructureTreeRoot(); + // COSDictionary dic = doc.getDocumentCatalog().getCOSDictionary(); + // PDStructureElement el = new PDStructureElement("Widget", pdstRoot); + + + + PDSignatureField signatureField = null; if (acroFormm != null) { @SuppressWarnings("unchecked") List<PDField> fields = acroFormm.getFields(); - PDSignatureField signatureField = null; + if (fields != null) { for (PDField pdField : fields) { if (pdField != null) { if (pdField instanceof PDSignatureField) { PDSignatureField tmpSigField = (PDSignatureField) pdField; + if (tmpSigField.getSignature() != null && tmpSigField.getSignature() - .getDictionary() != null) { + .getDictionary() != null) { if (tmpSigField .getSignature() .getDictionary() .equals(signature .getDictionary())) { signatureField = (PDSignatureField) pdField; + } } } @@ -462,12 +465,111 @@ public class PADESPDFBOXSigner implements IPdfSigner, IConfigurationConstants { } if (signatureField != null) { - signatureField.setPartialName(sigFieldName); + signatureField.setPartialName(sigFieldName); + } + if(properties!=null){ + signatureField.setAlternateFieldName(properties.getAlternativeTableCaption()); + }else{ + signatureField.setAlternateFieldName(sigFieldName); } } else { logger.warn("Failed to name Signature Field! [Cannot find acroForm!]"); } + // PDF-UA + logger.info("Adding pdf/ua content."); + try{ + PDDocumentCatalog root = doc.getDocumentCatalog(); + PDStructureTreeRoot treeRoot = root.getStructureTreeRoot(); + + logger.info("Tree Root: {}", treeRoot.toString()); + List<Object> kids = treeRoot.getKids(); + + if(kids==null){ + logger.info("No kid-elements in structure tree Root, maybe not PDF/UA document"); + } + + PDStructureElement docElement = null; + for(Object k: kids){ + if(k instanceof PDStructureElement){ + docElement=(PDStructureElement) k; + break; + // if(((PDStructureElement) k).getStructureType().equals("Document")){ + // docElement=(PDStructureElement) k; + // } + } + } + + PDStructureElement sigBlock = new PDStructureElement( + "Form", docElement); + + //create object dictionary and add as child element + COSDictionary objectdic= new COSDictionary(); + objectdic.setName("Type", "OBJR"); + objectdic.setItem("Pg", signatureField.getWidget().getPage()); + objectdic.setItem("Obj", signatureField.getWidget()); + + List<Object> l = new ArrayList<Object>(); + l.add(objectdic); + sigBlock.setKids(l); + + sigBlock.setTitle("Signature Table"); + sigBlock.setParent(docElement); + docElement.appendKid(sigBlock); + + //Create and add Attribute dictionary to mitigate PAC warning + COSDictionary sigBlockDic = (COSDictionary) sigBlock.getCOSObject(); + COSDictionary sub = new COSDictionary(); + + sub.setName("O", "Layout"); + sub.setName("Placement", "Block"); + sigBlockDic.setItem(COSName.A, sub); + sigBlockDic.setNeedToBeUpdate(true); + + + //Modify number tree + PDNumberTreeNode ntn = treeRoot.getParentTree(); + if(ntn==null){ + ntn = new PDNumberTreeNode(objectdic, null); + logger.info("No number-tree-node found!"); + } + + COSDictionary ntndic=ntn.getCOSDictionary(); + COSArray ntndicnumbersarray = (COSArray)ntndic.getDictionaryObject(COSName.NUMS); + int arrindex = ntndicnumbersarray.size(); + int treeindex = arrindex/2; + + ntndicnumbersarray.add(arrindex, COSInteger.get(treeindex)); + ntndicnumbersarray.add(arrindex+1, sigBlock.getCOSObject()); + + treeRoot.setParentTree(ntn); + treeRoot.setParentTreeNextKey(treeindex+1); + + //setStructureParent + PDAnnotationWidget widg=signatureField.getWidget(); + widg.setStructParent(treeindex); + + //add the Tabs /S Element for Tabbing through annots + PDPage p = signatureField.getWidget().getPage(); + p.getCOSDictionary().setName("Tabs", "S"); + p.getCOSObject().setNeedToBeUpdate(true); + + ntndic.setNeedToBeUpdate(true); + sigBlock.getCOSObject().setNeedToBeUpdate(true); + treeRoot.getCOSObject().setNeedToBeUpdate(true); + objectdic.getCOSObject().setNeedToBeUpdate(true); + docElement.getCOSObject().setNeedToBeUpdate(true); + + + }catch(Throwable e){ + if (signatureProfileSettings.isPDFUA()==true){ + logger.error("Could not create PDF-UA conform document!"); + throw new PdfAsException("error.pdf.sig.pdfua.1", e); + }else{ + logger.info("Could not create PDF-UA conform signature"); + } + } + if (requestedSignature.isVisual()) { // if(requestedSignature.getSignaturePosition().) @@ -559,7 +661,7 @@ public class PADESPDFBOXSigner implements IPdfSigner, IConfigurationConstants { // Ignore } } - + if(fisTmpFile != null) { helper.deleteFile(fisTmpFile); } @@ -609,7 +711,7 @@ public class PADESPDFBOXSigner implements IPdfSigner, IConfigurationConstants { public Image generateVisibleSignaturePreview(SignParameter parameter, java.security.cert.X509Certificate cert, int resolution, OperationStatus status, RequestedSignature requestedSignature) - throws PDFASError { + throws PDFASError { try { PDFBOXObject pdfObject = (PDFBOXObject) status.getPdfObject(); @@ -693,11 +795,11 @@ public class PADESPDFBOXSigner implements IPdfSigner, IConfigurationConstants { graphics.drawImage(outputImage, 0, 0, cutOut.getWidth(), cutOut .getHeight(), (int) (1 * factor), (int) (outputImage - .getHeight() - ((position.getHeight() + 1) * factor)), - (int) ((1 + position.getWidth()) * factor), - (int) (outputImage.getHeight() - - ((position.getHeight() + 1) * factor) + (position - .getHeight() * factor)), null); + .getHeight() - ((position.getHeight() + 1) * factor)), + (int) ((1 + position.getWidth()) * factor), + (int) (outputImage.getHeight() + - ((position.getHeight() + 1) * factor) + (position + .getHeight() * factor)), null); return cutOut; } catch (PdfAsException e) { logger.warn("PDF-AS Exception", e); diff --git a/pdf-as-pdfbox/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/pdfbox/PDFAsVisualSignatureBuilder.java b/pdf-as-pdfbox/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/pdfbox/PDFAsVisualSignatureBuilder.java index 882830bc..33e4102d 100644 --- a/pdf-as-pdfbox/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/pdfbox/PDFAsVisualSignatureBuilder.java +++ b/pdf-as-pdfbox/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/pdfbox/PDFAsVisualSignatureBuilder.java @@ -262,7 +262,7 @@ public class PDFAsVisualSignatureBuilder extends PDVisibleSigBuilder implements TableDrawUtils.drawTable(getStructure().getPage(), stream, 1, 1, designer.getWidth(), designer.getHeight(), properties.getMainTable(), template, false, - innerFormResources, images, settings, this); + innerFormResources, images, settings, this, properties); stream.close(); PDStream innterFormStream = getStructure().getPage().getContents(); getStructure().setInnterFormStream(innterFormStream); diff --git a/pdf-as-pdfbox/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/pdfbox/PDFAsVisualSignatureProperties.java b/pdf-as-pdfbox/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/pdfbox/PDFAsVisualSignatureProperties.java index d7ef6fae..3fdc6b4c 100644 --- a/pdf-as-pdfbox/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/pdfbox/PDFAsVisualSignatureProperties.java +++ b/pdf-as-pdfbox/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/pdfbox/PDFAsVisualSignatureProperties.java @@ -54,6 +54,8 @@ public class PDFAsVisualSignatureProperties extends PDVisibleSigProperties { private SignatureProfileSettings signatureProfileSettings; + private String alternativeTableCaption=""; + public PDFAsVisualSignatureProperties(ISettings settings, PDFBOXObject object, PdfBoxVisualObject visObj, PositioningInstruction pos, SignatureProfileSettings signatureProfileSettings) { this.settings = settings; @@ -134,5 +136,12 @@ public class PDFAsVisualSignatureProperties extends PDVisibleSigProperties { return signatureProfileSettings; } + public String getAlternativeTableCaption() { + return alternativeTableCaption; + } + + public void setAlternativeTableCaption(String alternativeTableCaption) { + this.alternativeTableCaption = alternativeTableCaption; + } } diff --git a/pdf-as-pdfbox/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/pdfbox/TableDrawUtils.java b/pdf-as-pdfbox/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/pdfbox/TableDrawUtils.java index dff8e543..9b0f5ae1 100644 --- a/pdf-as-pdfbox/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/pdfbox/TableDrawUtils.java +++ b/pdf-as-pdfbox/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/pdfbox/TableDrawUtils.java @@ -24,6 +24,7 @@ package at.gv.egiz.pdfas.lib.impl.stamping.pdfbox; import java.awt.Color; +import java.beans.DesignMode; import java.io.IOException; import java.util.ArrayList; import java.util.Iterator; @@ -40,6 +41,7 @@ import org.slf4j.LoggerFactory; import at.gv.egiz.pdfas.common.exceptions.PdfAsException; import at.gv.egiz.pdfas.common.settings.ISettings; +import at.gv.egiz.pdfas.lib.impl.signing.pdfbox.PADESPDFBOXSigner; import at.knowcenter.wag.egov.egiz.table.Entry; import at.knowcenter.wag.egov.egiz.table.Style; @@ -49,14 +51,18 @@ public class TableDrawUtils { .getLogger(TableDrawUtils.class); public static final String TABLE_DEBUG = "debug.table"; - + + private static StringBuilder alternateTableCaption; + public static void drawTable(PDPage page, PDPageContentStream contentStream, float x, float y, float width, float height, PDFBoxTable abstractTable, PDDocument doc, boolean subtable, PDResources formResources, - Map<String, ImageObject> images, ISettings settings, IDGenerator generator) + Map<String, ImageObject> images, ISettings settings, IDGenerator generator, PDFAsVisualSignatureProperties properties) throws PdfAsException { + alternateTableCaption = new StringBuilder(); + logger.debug("Drawing Table: X {} Y {} WIDTH {} HEIGHT {} \n{}", x, y, width, height, abstractTable.getOrigTable().toString()); @@ -67,16 +73,16 @@ public class TableDrawUtils { drawBorder(page, contentStream, x, y, width, height, abstractTable, doc, subtable, settings); - +//append strings drawContent(page, contentStream, x, y, width, height, abstractTable, - doc, subtable, formResources, images, settings, generator); + doc, subtable, formResources, images, settings, generator, properties); } public static void drawContent(PDPage page, PDPageContentStream contentStream, float x, float y, float width, float height, PDFBoxTable abstractTable, PDDocument doc, boolean subtable, PDResources formResources, - Map<String, ImageObject> images, ISettings settings, IDGenerator generator) + Map<String, ImageObject> images, ISettings settings, IDGenerator generator, PDFAsVisualSignatureProperties properties) throws PdfAsException { float contentx = x; @@ -114,11 +120,13 @@ public class TableDrawUtils { drawCaption(page, contentStream, contentx, contenty, colWidth, abstractTable.getRowHeights()[i], padding, abstractTable, doc, cell, formResources, settings); + addToAlternateTableCaption(cell); break; case Entry.TYPE_VALUE: drawValue(page, contentStream, contentx, contenty, colWidth, abstractTable.getRowHeights()[i], padding, abstractTable, doc, cell, formResources, settings); + addToAlternateTableCaption(cell); break; case Entry.TYPE_IMAGE: drawImage(page, contentStream, contentx, contenty, @@ -137,7 +145,7 @@ public class TableDrawUtils { drawTable(page, contentStream, contentx, contenty - abstractTable.getRowHeights()[i], colWidth, abstractTable.getRowHeights()[i], tbl_value, doc, - true, formResources, images, settings, generator); + true, formResources, images, settings, generator,properties); break; default: logger.warn("Unknown Cell entry type: " + cell.getType()); @@ -155,6 +163,7 @@ public class TableDrawUtils { contenty -= abstractTable.getRowHeights()[i]; contentx = x; } + properties.setAlternativeTableCaption(alternateTableCaption.toString()); } private static void drawString(PDPage page, @@ -280,7 +289,7 @@ public class TableDrawUtils { Style cellStyle = cell.getStyle(); String valign = cellStyle.getVAlign(); String halign = cellStyle.getHAlign(); - + drawString(page, contentStream, contentx, contenty, width, height, padding, abstractTable, doc, cell, fontSize, textHeight, valign, halign, tlines, textFont, formResources, settings); @@ -592,5 +601,11 @@ public class TableDrawUtils { } return ""; } + + private static void addToAlternateTableCaption(Entry cell){ + alternateTableCaption.append(cell.getValue()); + alternateTableCaption.append("\n");//better for screen reader + } + } diff --git a/pdf-as-pdfbox/src/main/java/at/knowcenter/wag/egov/egiz/pdf/PDFPage.java b/pdf-as-pdfbox/src/main/java/at/knowcenter/wag/egov/egiz/pdf/PDFPage.java index 5a3711a4..a7aaf2df 100644 --- a/pdf-as-pdfbox/src/main/java/at/knowcenter/wag/egov/egiz/pdf/PDFPage.java +++ b/pdf-as-pdfbox/src/main/java/at/knowcenter/wag/egov/egiz/pdf/PDFPage.java @@ -320,21 +320,17 @@ public class PDFPage extends PDFTextStripper { current_y = text.getY(); } if (pageRotation == 90) { - current_y = text.getX(); + current_y = text.getY(); } if (pageRotation == 180) { - float page_height = this.getCurrentPage().findMediaBox().getHeight(); - current_y = page_height - text.getY(); + current_y = text.getY(); } if (pageRotation == 270) { - float page_height = this.getCurrentPage().findMediaBox().getHeight(); - current_y = page_height - text.getX(); + current_y = text.getY(); } - if (current_y > this.effectivePageHeight) { - // logger_.debug("character is below footer_line. footer_line = " + - // this.footer_line + ", text.character=" + character + ", y=" + - // current_y); + if (current_y > this.effectivePageHeight) { + this.max_character_ypos=this.effectivePageHeight; return; } @@ -454,10 +450,8 @@ public class PDFPage extends PDFTextStripper { if (pageRotation == 180) { float min_y = findMinY(transformed_coordinates); logger.debug("min_y = " + min_y); - float page_height = this.mypage.getCurrentPage().findMediaBox().getHeight(); - actual_lowest_point = page_height - - findMaxY(transformed_coordinates); - actual_starting_point = page_height - min_y; + actual_lowest_point = findMaxY(transformed_coordinates); + actual_starting_point = actual_lowest_point + min_y; } if (pageRotation == 270) { float min_x = findMinX(transformed_coordinates); @@ -581,14 +575,14 @@ public class PDFPage extends PDFTextStripper { current_y = page_height - anno.getRectangle().getLowerLeftY(); } if (pageRotation == 90) { - current_y = anno.getRectangle().getLowerLeftX(); + current_y = anno.getRectangle().getUpperRightX(); } if (pageRotation == 180) { current_y = anno.getRectangle().getUpperRightY(); } if (pageRotation == 270) { - float page_height = page.findMediaBox().getHeight(); - current_y = page_height - anno.getRectangle().getUpperRightX(); + float page_width = page.findMediaBox().getWidth(); + current_y = page_width - anno.getRectangle().getLowerLeftX() ; } if (current_y > this.effectivePageHeight) { |