⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pdfsignatureappearance.java

📁 iText是一个能够快速产生PDF文件的java类库。iText的java类对于那些要产生包含文本
💻 JAVA
📖 第 1 页 / 共 4 页
字号:
        return this.crlList;
    }
    
    /**
     * Gets the filter used to sign the document.
     * @return the filter used to sign the document
     */    
    public com.lowagie.text.pdf.PdfName getFilter() {
        return filter;
    }
    
    /**
     * Checks if a new field was created.
     * @return <CODE>true</CODE> if a new field was created, <CODE>false</CODE> if signing
     * an existing field or if the signature is invisible
     */    
    public boolean isNewField() {
        return this.newField;
    }
    
    /**
     * Gets the page number of the field.
     * @return the page number of the field
     */    
    public int getPage() {
        return page;
    }
    
    /**
     * Gets the field name.
     * @return the field name
     */    
    public java.lang.String getFieldName() {
        return fieldName;
    }
    
    /**
     * Gets the rectangle that represent the position and dimension of the signature in the page.
     * @return the rectangle that represent the position and dimension of the signature in the page
     */    
    public com.lowagie.text.Rectangle getPageRect() {
        return pageRect;
    }
    
    /**
     * Gets the signature date.
     * @return the signature date
     */    
    public java.util.Calendar getSignDate() {
        return signDate;
    }
    
    /**
     * Sets the signature date.
     * @param signDate the signature date
     */    
    public void setSignDate(java.util.Calendar signDate) {
        this.signDate = signDate;
    }
    
    com.lowagie.text.pdf.ByteBuffer getSigout() {
        return sigout;
    }
    
    void setSigout(com.lowagie.text.pdf.ByteBuffer sigout) {
        this.sigout = sigout;
    }
    
    java.io.OutputStream getOriginalout() {
        return originalout;
    }
    
    void setOriginalout(java.io.OutputStream originalout) {
        this.originalout = originalout;
    }
    
    /**
     * Gets the temporary file.
     * @return the temporary file or <CODE>null</CODE> is the document is created in memory
     */    
    public java.io.File getTempFile() {
        return tempFile;
    }
    
    void setTempFile(java.io.File tempFile) {
        this.tempFile = tempFile;
    }

    /**
     * Gets a new signature fied name that doesn't clash with any existing name.
     * @return a new signature fied name
     */    
    public String getNewSigName() {
        AcroFields af = writer.getAcroFields();
        String name = "Signature";
        int step = 0;
        boolean found = false;
        while (!found) {
            ++step;
            String n1 = name + step;
            if (af.getFieldItem(n1) != null)
                continue;
            n1 += ".";
            found = true;
            for (Iterator it = af.getFields().keySet().iterator(); it.hasNext();) {
                String fn = (String)it.next();
                if (fn.startsWith(n1)) {
                    found = false;
                    break;
                }
            }
        }
        name += step;
        return name;
    }
    
    /**
     * This is the first method to be called when using external signatures. The general sequence is:
     * preClose(), getDocumentBytes() and close().
     * <p>
     * If calling preClose() <B>dont't</B> call PdfStamper.close().
     * <p>
     * No external signatures are allowed if this methos is called.
     * @throws IOException on error
     * @throws DocumentException on error
     */    
    public void preClose() throws IOException, DocumentException {
        preClose(null);
    }
    /**
     * This is the first method to be called when using external signatures. The general sequence is:
     * preClose(), getDocumentBytes() and close().
     * <p>
     * If calling preClose() <B>dont't</B> call PdfStamper.close().
     * <p>
     * If using an external signature <CODE>exclusionSizes</CODE> must contain at least
     * the <CODE>PdfName.CONTENTS</CODE> key with the size that it will take in the
     * document. Note that due to the hex string coding this size should be
     * byte_size*2+2.
     * @param exclusionSizes a <CODE>HashMap</CODE> with names and sizes to be excluded in the signature
     * calculation. The key is a <CODE>PdfName</CODE> and the value an
     * <CODE>Integer</CODE>. At least the <CODE>PdfName.CONTENTS</CODE> must be present
     * @throws IOException on error
     * @throws DocumentException on error
     */    
    public void preClose(HashMap exclusionSizes) throws IOException, DocumentException {
        if (preClosed)
            throw new DocumentException("Document already pre closed.");
        preClosed = true;
        AcroFields af = writer.getAcroFields();
        String name = getFieldName();
        boolean fieldExists = !(isInvisible() || isNewField());
        int flags = PdfAnnotation.FLAGS_PRINT | PdfAnnotation.FLAGS_LOCKED;
        PdfIndirectReference refSig = writer.getPdfIndirectReference();
        writer.setSigFlags(3);
        if (fieldExists) {
            ArrayList widgets = af.getFieldItem(name).widgets;
            PdfDictionary widget = (PdfDictionary)widgets.get(0);
            writer.markUsed(widget);
            widget.put(PdfName.P, writer.getPageReference(getPage()));
            widget.put(PdfName.V, refSig);
            PdfObject obj = PdfReader.getPdfObjectRelease(widget.get(PdfName.F));
            if (obj != null && obj.isNumber())
                flags = ((PdfNumber)obj).intValue() | PdfAnnotation.FLAGS_LOCKED;
            widget.put(PdfName.F, new PdfNumber(flags));
            PdfDictionary ap = new PdfDictionary();
            ap.put(PdfName.N, getAppearance().getIndirectReference());
            widget.put(PdfName.AP, ap);
        }
        else {
            PdfFormField sigField = PdfFormField.createSignature(writer);
            sigField.setFieldName(name);
            sigField.put(PdfName.V, refSig);
            sigField.setFlags(flags);

            int pagen = getPage();
            if (!isInvisible())
                sigField.setWidget(getPageRect(), null);
            else
                sigField.setWidget(new Rectangle(0, 0), null);
            sigField.setAppearance(PdfAnnotation.APPEARANCE_NORMAL, getAppearance());
            sigField.setPage(pagen);
            writer.addAnnotation(sigField, pagen);
        }

        exclusionLocations = new HashMap();
        if (cryptoDictionary == null) {
            if (PdfName.ADOBE_PPKLITE.equals(getFilter()))
                sigStandard = new PdfSigGenericPKCS.PPKLite(getProvider());
            else if (PdfName.ADOBE_PPKMS.equals(getFilter()))
                sigStandard = new PdfSigGenericPKCS.PPKMS(getProvider());
            else if (PdfName.VERISIGN_PPKVS.equals(getFilter()))
                sigStandard = new PdfSigGenericPKCS.VeriSign(getProvider());
            else
                throw new IllegalArgumentException("Unknown filter: " + getFilter());
            sigStandard.setExternalDigest(externalDigest, externalRSAdata, digestEncryptionAlgorithm);
            if (getReason() != null)
                sigStandard.setReason(getReason());
            if (getLocation() != null)
                sigStandard.setLocation(getLocation());
            if (getContact() != null)
                sigStandard.setContact(getContact());
            sigStandard.put(PdfName.M, new PdfDate(getSignDate()));
            sigStandard.setSignInfo(getPrivKey(), getCertChain(), getCrlList());
            PdfString contents = (PdfString)sigStandard.get(PdfName.CONTENTS);
            PdfLiteral lit = new PdfLiteral((contents.toString().length() + (PdfName.ADOBE_PPKLITE.equals(getFilter())?0:64)) * 2 + 2);
            exclusionLocations.put(PdfName.CONTENTS, lit);
            sigStandard.put(PdfName.CONTENTS, lit);
            lit = new PdfLiteral(80);
            exclusionLocations.put(PdfName.BYTERANGE, lit);
            sigStandard.put(PdfName.BYTERANGE, lit);
            if (certificationLevel > 0) {
                addDocMDP(sigStandard);
            }
            if (signatureEvent != null)
                signatureEvent.getSignatureDictionary(sigStandard);
            writer.addToBody(sigStandard, refSig, false);
        }
        else {
            PdfLiteral lit = new PdfLiteral(80);
            exclusionLocations.put(PdfName.BYTERANGE, lit);
            cryptoDictionary.put(PdfName.BYTERANGE, lit);
            for (Iterator it = exclusionSizes.entrySet().iterator(); it.hasNext();) {
                Map.Entry entry = (Map.Entry)it.next();
                PdfName key = (PdfName)entry.getKey();
                Integer v = (Integer)entry.getValue();
                lit = new PdfLiteral(v.intValue());
                exclusionLocations.put(key, lit);
                cryptoDictionary.put(key, lit);
            }
            if (certificationLevel > 0)
                addDocMDP(cryptoDictionary);
            if (signatureEvent != null)
                signatureEvent.getSignatureDictionary(cryptoDictionary);
            writer.addToBody(cryptoDictionary, refSig, false);
        }
        if (certificationLevel > 0) {
          // add DocMDP entry to root
             PdfDictionary docmdp = new PdfDictionary();
             docmdp.put(new PdfName("DocMDP"), refSig);
             writer.reader.getCatalog().put(new PdfName("Perms"), docmdp);
        }
        writer.close(stamper.getMoreInfo());
        
        range = new int[exclusionLocations.size() * 2];
        int byteRangePosition = ((PdfLiteral)exclusionLocations.get(PdfName.BYTERANGE)).getPosition();
        exclusionLocations.remove(PdfName.BYTERANGE);
        int idx = 1;
        for (Iterator it = exclusionLocations.values().iterator(); it.hasNext();) {
            PdfLiteral lit = (PdfLiteral)it.next();
            int n = lit.getPosition();
            range[idx++] = n;
            range[idx++] = lit.getPosLength() + n;
        }
        Arrays.sort(range, 1, range.length - 1);
        for (int k = 3; k < range.length - 2; k += 2)
            range[k] -= range[k - 1];
        
        if (tempFile == null) {
            bout = sigout.getBuffer();
            boutLen = sigout.size();
            range[range.length - 1] = boutLen - range[range.length - 2];
            ByteBuffer bf = new ByteBuffer();
            bf.append('[');
            for (int k = 0; k < range.length; ++k)
                bf.append(range[k]).append(' ');
            bf.append(']');
            System.arraycopy(bf.getBuffer(), 0, bout, byteRangePosition, bf.size());
        }
        else {
            try {
                raf = new RandomAccessFile(tempFile, "rw");
                int boutLen = (int)raf.length();
                range[range.length - 1] = boutLen - range[range.length - 2];
                ByteBuffer bf = new ByteBuffer();
                bf.append('[');
                for (int k = 0; k < range.length; ++k)
                    bf.append(range[k]).append(' ');
                bf.append(']');
                raf.seek(byteRangePosition);
                raf.write(bf.getBuffer(), 0, bf.size());
            }
            catch (IOException e) {
                try{raf.close();}catch(Exception ee){}
                try{tempFile.delete();}catch(Exception ee){}
                throw e;
            }
        }
    }
    
    /**
     * This is the last method to be called when using external signatures. The general sequence is:
     * preClose(), getDocumentBytes() and close().
     * <p>
     * <CODE>update</CODE> is a <CODE>PdfDictionary</CODE> that must have exactly the
     * same keys as the ones provided in {@link #preClose(HashMap)}.
     * @param update a <CODE>PdfDictionary</CODE> with the key/value that will fill the holes defined
     * in {@link #preClose(HashMap)}
     * @throws DocumentException on error
     * @throws IOException on error
     */    
    public void close(PdfDictionary update) throws IOException, DocumentException {
        try {
            if (!preClosed)
                throw new DocumentException("preClose() must be called first.");
            ByteBuffer bf = new ByteBuffer();
            for (Iterator it = update.getKeys().iterator(); it.hasNext();) {
                PdfName key = (PdfName)it.next();
                PdfObject obj = update.get(key);
                PdfLiteral lit = (PdfLiteral)exclusionLocations.get(key);
                if (lit == null)
                    throw new IllegalArgumentException("The key " + key.toString() + " didn't reserve space in preClose().");
                bf.reset();
                obj.toPdf(null, bf);
                if (bf.size() > lit.getPosLength())
                    throw new IllegalArgumentException("The key " + key.toString() + " is too big. Is " + bf.size() + ", reserved " + lit.getPosLength());
                if (tempFile == null)
                    System.arraycopy(bf.getBuffer(), 0, bout, lit.getPosition(), bf.size());
                else {
                    raf.seek(lit.getPosition());
                    raf.write(bf.getBuffer(), 0, bf.size());
                }
            }
            if (update.size() != exclusionLocations.size())
                throw new IllegalArgumentException("The update dictionary has less keys than required.");
            if (tempFile == null) {
                originalout.write(bout, 0, boutLen);
            }
            else {
                if (originalout != null) {
                    raf.seek(0);
                    int length = (int)raf.length();
                    byte buf[] = new byte[8192];
                    while (length > 0) {
                        int r = raf.read(buf, 0, Math.min(buf.length, length));
                        if (r < 0)
                            throw new EOFException("Unexpected EOF");
                        originalout.write(buf, 0, r);
                        length -= r;
                    }
                }
            }
        }
        finally {
            if (tempFile != null) {
                try{raf.close();}catch(Exception ee){}
                if (originalout != null)
                    try{tempFile.delete();}catch(Exception ee){}
            }
            if (originalout != null)
                try{originalout.close();}catch(Exception e){}
        }
    }
    
    private void addDocMDP(PdfDictionary crypto) {
        PdfDictionary reference = new PdfDictionary();
        PdfDictionary transformParams = new PdfDictionary();
        transformParams.put(PdfName.P, new PdfNumber(certificationLevel));
        transformParams.put(PdfName.V, new PdfName("1.2"));
        transformParams.put(PdfName.TYPE, PdfName.TRANSFORMPARAMS);
        reference.put(PdfName.TRANSFORMMETHOD, PdfName.DOCMDP);
        reference.put(PdfName.TYPE, PdfName.SIGREF);
        reference.put(PdfName.TRANSFORMPARAMS, transformParams);
        reference.put(new PdfName("DigestValue"), new PdfString("aa"));
        PdfArray loc = new PdfArray();

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -