Search in sources :

Example 1 with COSDocument

use of com.tom_roush.pdfbox.cos.COSDocument in project PdfBox-Android by TomRoush.

the class PDDocument method addSignature.

/**
 * This will add a signature to the document. If the 0-based page number in the options
 * parameter is smaller than 0 or larger than max, the nearest valid page number will be used
 * (i.e. 0 or max) and no exception will be thrown.
 * <p>
 * Only one signature may be added in a document. To sign several times,
 * load document, add signature, save incremental and close again.
 *
 * @param sigObject is the PDSignatureField model
 * @param signatureInterface is an interface whose implementation provides
 * signing capabilities. Can be null if external signing if used.
 * @param options signature options
 * @throws IOException if there is an error creating required fields
 * @throws IllegalStateException if one attempts to add several signature
 * fields.
 */
public void addSignature(PDSignature sigObject, SignatureInterface signatureInterface, SignatureOptions options) throws IOException {
    if (signatureAdded) {
        throw new IllegalStateException("Only one signature may be added in a document");
    }
    signatureAdded = true;
    // Reserve content
    // We need to reserve some space for the signature. Some signatures including
    // big certificate chain and we need enough space to store it.
    int preferredSignatureSize = options.getPreferredSignatureSize();
    if (preferredSignatureSize > 0) {
        sigObject.setContents(new byte[preferredSignatureSize]);
    } else {
        sigObject.setContents(new byte[SignatureOptions.DEFAULT_SIGNATURE_SIZE]);
    }
    // Reserve ByteRange, will be overwritten in COSWriter
    sigObject.setByteRange(RESERVE_BYTE_RANGE);
    signInterface = signatureInterface;
    // Create SignatureForm for signature and append it to the document
    // Get the first valid page
    int pageCount = getNumberOfPages();
    if (pageCount == 0) {
        throw new IllegalStateException("Cannot sign an empty document");
    }
    int startIndex = Math.min(Math.max(options.getPage(), 0), pageCount - 1);
    PDPage page = getPage(startIndex);
    // Get the AcroForm from the Root-Dictionary and append the annotation
    PDDocumentCatalog catalog = getDocumentCatalog();
    PDAcroForm acroForm = catalog.getAcroForm();
    catalog.getCOSObject().setNeedToBeUpdated(true);
    if (acroForm == null) {
        acroForm = new PDAcroForm(this);
        catalog.setAcroForm(acroForm);
    } else {
        acroForm.getCOSObject().setNeedToBeUpdated(true);
    }
    PDSignatureField signatureField = null;
    if (!(acroForm.getCOSObject().getDictionaryObject(COSName.FIELDS) instanceof COSArray)) {
        acroForm.getCOSObject().setItem(COSName.FIELDS, new COSArray());
    } else {
        COSArray fieldArray = (COSArray) acroForm.getCOSObject().getDictionaryObject(COSName.FIELDS);
        fieldArray.setNeedToBeUpdated(true);
        signatureField = findSignatureField(acroForm.getFieldIterator(), sigObject);
    }
    if (signatureField == null) {
        signatureField = new PDSignatureField(acroForm);
        // append the signature object
        signatureField.setValue(sigObject);
        // backward linking
        signatureField.getWidgets().get(0).setPage(page);
    } else {
        sigObject.getCOSObject().setNeedToBeUpdated(true);
    }
    // TODO This "overwrites" the settings of the original signature field which might not be intended by the user
    // better make it configurable (not all users need/want PDF/A but their own setting):
    // to conform PDF/A-1 requirement:
    // The /F key's Print flag bit shall be set to 1 and
    // its Hidden, Invisible and NoView flag bits shall be set to 0
    signatureField.getWidgets().get(0).setPrinted(true);
    // Set the AcroForm Fields
    List<PDField> acroFormFields = acroForm.getFields();
    acroForm.getCOSObject().setDirect(true);
    acroForm.setSignaturesExist(true);
    acroForm.setAppendOnly(true);
    boolean checkFields = checkSignatureField(acroForm.getFieldIterator(), signatureField);
    if (checkFields) {
        signatureField.getCOSObject().setNeedToBeUpdated(true);
    } else {
        acroFormFields.add(signatureField);
    }
    // Get the object from the visual signature
    COSDocument visualSignature = options.getVisualSignature();
    // Distinction of case for visual and non-visual signature
    if (visualSignature == null) {
        prepareNonVisibleSignature(signatureField);
        return;
    }
    prepareVisibleSignature(signatureField, acroForm, visualSignature);
    // Create Annotation / Field for signature
    List<PDAnnotation> annotations = page.getAnnotations();
    // Make /Annots a direct object to avoid problem if it is an existing indirect object:
    // it would not be updated in incremental save, and if we'd set the /Annots array "to be updated"
    // while keeping it indirect, Adobe Reader would claim that the document had been modified.
    page.setAnnotations(annotations);
    // take care that page and acroforms do not share the same array (if so, we don't need to add it twice)
    if (!(annotations instanceof COSArrayList && acroFormFields instanceof COSArrayList && ((COSArrayList<?>) annotations).toList().equals(((COSArrayList<?>) acroFormFields).toList()) && checkFields)) {
        PDAnnotationWidget widget = signatureField.getWidgets().get(0);
        // use check to prevent the annotation widget from appearing twice
        if (checkSignatureAnnotation(annotations, widget)) {
            widget.getCOSObject().setNeedToBeUpdated(true);
        } else {
            annotations.add(widget);
        }
    }
    page.getCOSObject().setNeedToBeUpdated(true);
}
Also used : PDField(com.tom_roush.pdfbox.pdmodel.interactive.form.PDField) PDAnnotation(com.tom_roush.pdfbox.pdmodel.interactive.annotation.PDAnnotation) COSDocument(com.tom_roush.pdfbox.cos.COSDocument) PDAcroForm(com.tom_roush.pdfbox.pdmodel.interactive.form.PDAcroForm) COSArrayList(com.tom_roush.pdfbox.pdmodel.common.COSArrayList) COSArray(com.tom_roush.pdfbox.cos.COSArray) PDAnnotationWidget(com.tom_roush.pdfbox.pdmodel.interactive.annotation.PDAnnotationWidget) PDSignatureField(com.tom_roush.pdfbox.pdmodel.interactive.form.PDSignatureField)

Example 2 with COSDocument

use of com.tom_roush.pdfbox.cos.COSDocument in project PdfBox-Android by TomRoush.

the class COSWriter method prepareIncrement.

private void prepareIncrement(PDDocument doc) {
    try {
        if (doc != null) {
            COSDocument cosDoc = doc.getDocument();
            Map<COSObjectKey, Long> xrefTable = cosDoc.getXrefTable();
            Set<COSObjectKey> keySet = xrefTable.keySet();
            long highestNumber = doc.getDocument().getHighestXRefObjectNumber();
            for (COSObjectKey cosObjectKey : keySet) {
                COSBase object = cosDoc.getObjectFromPool(cosObjectKey).getObject();
                if (object != null && cosObjectKey != null && !(object instanceof COSNumber)) {
                    objectKeys.put(object, cosObjectKey);
                    keyObject.put(cosObjectKey, object);
                }
                if (cosObjectKey != null) {
                    long num = cosObjectKey.getNumber();
                    if (num > highestNumber) {
                        highestNumber = num;
                    }
                }
            }
            setNumber(highestNumber);
        }
    } catch (IOException e) {
        Log.e("PdfBox-Android", e.getMessage(), e);
    }
}
Also used : COSObjectKey(com.tom_roush.pdfbox.cos.COSObjectKey) COSNumber(com.tom_roush.pdfbox.cos.COSNumber) COSDocument(com.tom_roush.pdfbox.cos.COSDocument) COSBase(com.tom_roush.pdfbox.cos.COSBase) IOException(java.io.IOException)

Example 3 with COSDocument

use of com.tom_roush.pdfbox.cos.COSDocument in project PdfBox-Android by TomRoush.

the class COSWriter method write.

/**
 * This will write the fdf document.
 *
 * @param doc The document to write.
 *
 * @throws IOException If an error occurs while generating the data.
 */
public void write(FDFDocument doc) throws IOException {
    fdfDocument = doc;
    willEncrypt = false;
    COSDocument cosDoc = fdfDocument.getDocument();
    cosDoc.accept(this);
}
Also used : COSDocument(com.tom_roush.pdfbox.cos.COSDocument)

Example 4 with COSDocument

use of com.tom_roush.pdfbox.cos.COSDocument in project PdfBox-Android by TomRoush.

the class FDFParser method init.

private void init() {
    String eofLookupRangeStr = System.getProperty(SYSPROP_EOFLOOKUPRANGE);
    if (eofLookupRangeStr != null) {
        try {
            setEOFLookupRange(Integer.parseInt(eofLookupRangeStr));
        } catch (NumberFormatException nfe) {
            Log.w("PdfBox-Android", "System property " + SYSPROP_EOFLOOKUPRANGE + " does not contain an integer value, but: '" + eofLookupRangeStr + "'");
        }
    }
    document = new COSDocument();
}
Also used : COSDocument(com.tom_roush.pdfbox.cos.COSDocument)

Example 5 with COSDocument

use of com.tom_roush.pdfbox.cos.COSDocument in project PdfBox-Android by TomRoush.

the class PDFTemplateStructure method getTemplateAppearanceStream.

/**
 * Returns the visual signature COSDocument as a stream and closes the template field
 * PDDocument.
 *
 * @return the visual signature COSDocument as a stream
 * @throws IOException
 * @deprecated This will be removed in 2.1 because the method name is misleading and confusing,
 * and the work done rather belongs into the calling class:
 * <pre>
 * {@code
 * COSDocument visualSignature = structure.getVisualSignature();
 *  ByteArrayOutputStream baos = new ByteArrayOutputStream();
 *  COSWriter writer = new COSWriter(baos);
 *  writer.write(visualSignature);
 *  writer.close();
 *  structure.getTemplate().close();
 *  ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
 * } </pre>
 */
@Deprecated
public ByteArrayInputStream getTemplateAppearanceStream() throws IOException {
    COSDocument visualSignature = getVisualSignature();
    ByteArrayOutputStream memoryOut = new ByteArrayOutputStream();
    COSWriter memoryWriter = new COSWriter(memoryOut);
    memoryWriter.write(visualSignature);
    ByteArrayInputStream input = new ByteArrayInputStream(memoryOut.toByteArray());
    getTemplate().close();
    return input;
}
Also used : COSWriter(com.tom_roush.pdfbox.pdfwriter.COSWriter) ByteArrayInputStream(java.io.ByteArrayInputStream) COSDocument(com.tom_roush.pdfbox.cos.COSDocument) ByteArrayOutputStream(java.io.ByteArrayOutputStream)

Aggregations

COSDocument (com.tom_roush.pdfbox.cos.COSDocument)8 COSArray (com.tom_roush.pdfbox.cos.COSArray)2 COSBase (com.tom_roush.pdfbox.cos.COSBase)2 COSDictionary (com.tom_roush.pdfbox.cos.COSDictionary)1 COSNumber (com.tom_roush.pdfbox.cos.COSNumber)1 COSObjectKey (com.tom_roush.pdfbox.cos.COSObjectKey)1 COSString (com.tom_roush.pdfbox.cos.COSString)1 ScratchFile (com.tom_roush.pdfbox.io.ScratchFile)1 COSWriter (com.tom_roush.pdfbox.pdfwriter.COSWriter)1 COSArrayList (com.tom_roush.pdfbox.pdmodel.common.COSArrayList)1 SecurityHandler (com.tom_roush.pdfbox.pdmodel.encryption.SecurityHandler)1 PDAnnotation (com.tom_roush.pdfbox.pdmodel.interactive.annotation.PDAnnotation)1 PDAnnotationWidget (com.tom_roush.pdfbox.pdmodel.interactive.annotation.PDAnnotationWidget)1 PDAcroForm (com.tom_roush.pdfbox.pdmodel.interactive.form.PDAcroForm)1 PDField (com.tom_roush.pdfbox.pdmodel.interactive.form.PDField)1 PDSignatureField (com.tom_roush.pdfbox.pdmodel.interactive.form.PDSignatureField)1 ByteArrayInputStream (java.io.ByteArrayInputStream)1 ByteArrayOutputStream (java.io.ByteArrayOutputStream)1 IOException (java.io.IOException)1 MessageDigest (java.security.MessageDigest)1