Class COSWriter

  • All Implemented Interfaces:
    java.io.Closeable, java.lang.AutoCloseable, ICOSVisitor

    public class COSWriter
    extends java.lang.Object
    implements ICOSVisitor, java.io.Closeable
    This class acts on a in-memory representation of a PDF document.
    • Field Detail

      • LOG

        private static final org.apache.commons.logging.Log LOG
      • DICT_OPEN

        public static final byte[] DICT_OPEN
        The dictionary open token.
      • DICT_CLOSE

        public static final byte[] DICT_CLOSE
        The dictionary close token.
      • SPACE

        public static final byte[] SPACE
        space character.
      • COMMENT

        public static final byte[] COMMENT
        The start to a PDF comment.
      • VERSION

        public static final byte[] VERSION
        The output version of the PDF.
      • GARBAGE

        public static final byte[] GARBAGE
        Garbage bytes used to create the PDF header.
      • EOF

        public static final byte[] EOF
        The EOF constant.
      • REFERENCE

        public static final byte[] REFERENCE
        The reference token.
      • XREF

        public static final byte[] XREF
        The XREF token.
      • XREF_FREE

        public static final byte[] XREF_FREE
        The xref free token.
      • XREF_USED

        public static final byte[] XREF_USED
        The xref used token.
      • TRAILER

        public static final byte[] TRAILER
        The trailer token.
      • STARTXREF

        public static final byte[] STARTXREF
        The start xref token.
      • OBJ

        public static final byte[] OBJ
        The starting object token.
      • ENDOBJ

        public static final byte[] ENDOBJ
        The end object token.
      • ARRAY_OPEN

        public static final byte[] ARRAY_OPEN
        The array open token.
      • ARRAY_CLOSE

        public static final byte[] ARRAY_CLOSE
        The array close token.
      • STREAM

        public static final byte[] STREAM
        The open stream token.
      • ENDSTREAM

        public static final byte[] ENDSTREAM
        The close stream token.
      • formatXrefOffset

        private final java.text.NumberFormat formatXrefOffset
      • formatXrefGeneration

        private final java.text.NumberFormat formatXrefGeneration
      • output

        private java.io.OutputStream output
      • startxref

        private long startxref
      • number

        private long number
      • objectsToWriteSet

        private final java.util.Set<COSBase> objectsToWriteSet
      • objectsToWrite

        private final java.util.Deque<COSBase> objectsToWrite
      • writtenObjects

        private final java.util.Set<COSBase> writtenObjects
      • actualsAdded

        private final java.util.Set<COSBase> actualsAdded
      • willEncrypt

        private boolean willEncrypt
      • incrementalUpdate

        private boolean incrementalUpdate
      • reachedSignature

        private boolean reachedSignature
      • signatureOffset

        private long signatureOffset
      • signatureLength

        private long signatureLength
      • byteRangeOffset

        private long byteRangeOffset
      • byteRangeLength

        private long byteRangeLength
      • incrementalOutput

        private java.io.OutputStream incrementalOutput
      • incrementPart

        private byte[] incrementPart
      • byteRangeArray

        private COSArray byteRangeArray
    • Constructor Detail

      • COSWriter

        public COSWriter​(java.io.OutputStream outputStream)
        COSWriter constructor.
        Parameters:
        outputStream - The output stream to write the PDF. It will be closed when this object is closed.
      • COSWriter

        public COSWriter​(java.io.OutputStream outputStream,
                         RandomAccessRead inputData)
                  throws java.io.IOException
        COSWriter constructor for incremental updates. There must be a path of objects that have COSUpdateInfo.isNeedToBeUpdated() set, starting from the document catalog. For signatures this is taken care by PDFBox itself.
        Parameters:
        outputStream - output stream where the new PDF data will be written. It will be closed when this object is closed.
        inputData - random access read containing source PDF data
        Throws:
        java.io.IOException - if something went wrong
      • COSWriter

        public COSWriter​(java.io.OutputStream outputStream,
                         RandomAccessRead inputData,
                         java.util.Set<COSDictionary> objectsToWrite)
                  throws java.io.IOException
        Constructor for incremental updates with a list of objects to write. This allows to include objects even if there is no path of objects that have COSUpdateInfo.isNeedToBeUpdated() set so the incremental update gets smaller. Only dictionaries are supported; if you need to update other objects classes, then add their parent dictionary.
        Parameters:
        outputStream - output stream where the new PDF data will be written. It will be closed when this object is closed.
        inputData - random access read containing source PDF data.
        objectsToWrite - objects that must be part of the incremental saving.
        Throws:
        java.io.IOException - if something went wrong
    • Method Detail

      • prepareIncrement

        private void prepareIncrement​(PDDocument doc)
      • addXRefEntry

        protected void addXRefEntry​(COSWriterXRefEntry entry)
        add an entry in the x ref table for later dump.
        Parameters:
        entry - The new entry to add.
      • close

        public void close()
                   throws java.io.IOException
        This will close the stream.
        Specified by:
        close in interface java.lang.AutoCloseable
        Specified by:
        close in interface java.io.Closeable
        Throws:
        java.io.IOException - If the underlying stream throws an exception.
      • getNumber

        protected long getNumber()
        This will get the current object number.
        Returns:
        The current object number.
      • getObjectKeys

        public java.util.Map<COSBase,​COSObjectKey> getObjectKeys()
        This will get all available object keys.
        Returns:
        A map of all object keys.
      • getOutput

        protected java.io.OutputStream getOutput()
        This will get the output stream.
        Returns:
        The output stream.
      • getStandardOutput

        protected COSStandardOutputStream getStandardOutput()
        This will get the standard output stream.
        Returns:
        The standard output stream.
      • getStartxref

        protected long getStartxref()
        This will get the current start xref.
        Returns:
        The current start xref.
      • getXRefEntries

        protected java.util.List<COSWriterXRefEntry> getXRefEntries()
        This will get the xref entries.
        Returns:
        All available xref entries.
      • setNumber

        protected void setNumber​(long newNumber)
        This will set the current object number.
        Parameters:
        newNumber - The new object number.
      • setOutput

        private void setOutput​(java.io.OutputStream newOutput)
        This will set the output stream.
        Parameters:
        newOutput - The new output stream.
      • setStandardOutput

        private void setStandardOutput​(COSStandardOutputStream newStandardOutput)
        This will set the standard output stream.
        Parameters:
        newStandardOutput - The new standard output stream.
      • setStartxref

        protected void setStartxref​(long newStartxref)
        This will set the start xref.
        Parameters:
        newStartxref - The new start xref attribute.
      • doWriteBody

        protected void doWriteBody​(COSDocument doc)
                            throws java.io.IOException
        This will write the body of the document.
        Parameters:
        doc - The document to write the body for.
        Throws:
        java.io.IOException - If there is an error writing the data.
      • doWriteObjects

        private void doWriteObjects()
                             throws java.io.IOException
        Throws:
        java.io.IOException
      • addObjectToWrite

        private void addObjectToWrite​(COSBase object)
      • isNeedToBeUpdated

        private boolean isNeedToBeUpdated​(COSBase base)
        Convenience method, so that we get false for types that can't be updated.
        Parameters:
        base -
        Returns:
      • doWriteObject

        public void doWriteObject​(COSBase obj)
                           throws java.io.IOException
        This will write a COS object.
        Parameters:
        obj - The object to write.
        Throws:
        java.io.IOException - if the output cannot be written
      • doWriteHeader

        protected void doWriteHeader​(COSDocument doc)
                              throws java.io.IOException
        This will write the header to the PDF document.
        Parameters:
        doc - The document to get the data from.
        Throws:
        java.io.IOException - If there is an error writing to the stream.
      • doWriteTrailer

        protected void doWriteTrailer​(COSDocument doc)
                               throws java.io.IOException
        This will write the trailer to the PDF document.
        Parameters:
        doc - The document to create the trailer for.
        Throws:
        java.io.IOException - If there is an IOError while writing the document.
      • doWriteXRefInc

        private void doWriteXRefInc​(COSDocument doc,
                                    long hybridPrev)
                             throws java.io.IOException
        Throws:
        java.io.IOException
      • doWriteXRefTable

        private void doWriteXRefTable()
                               throws java.io.IOException
        Throws:
        java.io.IOException
      • doWriteIncrement

        private void doWriteIncrement()
                               throws java.io.IOException
        Write an incremental update for a non signature case. This can be used for e.g. augmenting signatures.
        Throws:
        java.io.IOException
      • doWriteSignature

        private void doWriteSignature()
                               throws java.io.IOException
        Throws:
        java.io.IOException
      • getDataToSign

        public java.io.InputStream getDataToSign()
                                          throws java.io.IOException
        Return the stream of PDF data to be signed. Clients should use this method only to create signatures externally. write(PDDocument) method should have been called prior. The created signature should be set using writeExternalSignature(byte[]).

        When SignatureInterface instance is used, COSWriter obtains and writes the signature itself.

        Returns:
        data stream to be signed
        Throws:
        java.lang.IllegalStateException - if PDF is not prepared for external signing
        java.io.IOException - if input data is closed
      • writeExternalSignature

        public void writeExternalSignature​(byte[] cmsSignature)
                                    throws java.io.IOException
        Write externally created signature of PDF data obtained via getDataToSign() method.
        Parameters:
        cmsSignature - CMS signature byte array
        Throws:
        java.lang.IllegalStateException - if PDF is not prepared for external signing
        java.io.IOException - if source data stream is closed
      • writeXrefRange

        private void writeXrefRange​(long x,
                                    long y)
                             throws java.io.IOException
        Throws:
        java.io.IOException
      • writeXrefEntry

        private void writeXrefEntry​(COSWriterXRefEntry entry)
                             throws java.io.IOException
        Throws:
        java.io.IOException
      • getXRefRanges

        protected java.lang.Long[] getXRefRanges​(java.util.List<COSWriterXRefEntry> xRefEntriesList)
        check the xref entries and write out the ranges. The format of the returned array is exactly the same as the pdf specification. See section 7.5.4 of ISO32000-1:2008, example 1 (page 40) for reference.

        example: 0 1 2 5 6 7 8 10

        will create a array with follow ranges

        0 3 5 4 10 1

        this mean that the element 0 is followed by two other related numbers that represent a cluster of the size 3. 5 is follow by three other related numbers and create a cluster of size 4. etc.

        Parameters:
        xRefEntriesList - list with the xRef entries that was written
        Returns:
        a integer array with the ranges
      • getObjectKey

        private COSObjectKey getObjectKey​(COSBase obj)
        This will get the object key for the object.
        Parameters:
        obj - The object to get the key for.
        Returns:
        The object key for the object.
      • visitFromArray

        public java.lang.Object visitFromArray​(COSArray obj)
                                        throws java.io.IOException
        Description copied from interface: ICOSVisitor
        Notification of visit to Array object.
        Specified by:
        visitFromArray in interface ICOSVisitor
        Parameters:
        obj - The Object that is being visited.
        Returns:
        any Object depending on the visitor implementation, or null
        Throws:
        java.io.IOException - If there is an error while visiting this object.
      • visitFromBoolean

        public java.lang.Object visitFromBoolean​(COSBoolean obj)
                                          throws java.io.IOException
        Description copied from interface: ICOSVisitor
        Notification of visit to boolean object.
        Specified by:
        visitFromBoolean in interface ICOSVisitor
        Parameters:
        obj - The Object that is being visited.
        Returns:
        any Object depending on the visitor implementation, or null
        Throws:
        java.io.IOException - If there is an error while visiting this object.
      • visitFromDictionary

        public java.lang.Object visitFromDictionary​(COSDictionary obj)
                                             throws java.io.IOException
        Description copied from interface: ICOSVisitor
        Notification of visit to dictionary object.
        Specified by:
        visitFromDictionary in interface ICOSVisitor
        Parameters:
        obj - The Object that is being visited.
        Returns:
        any Object depending on the visitor implementation, or null
        Throws:
        java.io.IOException - If there is an error while visiting this object.
      • visitFromDocument

        public java.lang.Object visitFromDocument​(COSDocument doc)
                                           throws java.io.IOException
        Description copied from interface: ICOSVisitor
        Notification of visit to document object.
        Specified by:
        visitFromDocument in interface ICOSVisitor
        Parameters:
        doc - The Object that is being visited.
        Returns:
        any Object depending on the visitor implementation, or null
        Throws:
        java.io.IOException - If there is an error while visiting this object.
      • visitFromFloat

        public java.lang.Object visitFromFloat​(COSFloat obj)
                                        throws java.io.IOException
        Description copied from interface: ICOSVisitor
        Notification of visit to float object.
        Specified by:
        visitFromFloat in interface ICOSVisitor
        Parameters:
        obj - The Object that is being visited.
        Returns:
        any Object depending on the visitor implementation, or null
        Throws:
        java.io.IOException - If there is an error while visiting this object.
      • visitFromInt

        public java.lang.Object visitFromInt​(COSInteger obj)
                                      throws java.io.IOException
        Description copied from interface: ICOSVisitor
        Notification of visit to integer object.
        Specified by:
        visitFromInt in interface ICOSVisitor
        Parameters:
        obj - The Object that is being visited.
        Returns:
        any Object depending on the visitor implementation, or null
        Throws:
        java.io.IOException - If there is an error while visiting this object.
      • visitFromName

        public java.lang.Object visitFromName​(COSName obj)
                                       throws java.io.IOException
        Description copied from interface: ICOSVisitor
        Notification of visit to name object.
        Specified by:
        visitFromName in interface ICOSVisitor
        Parameters:
        obj - The Object that is being visited.
        Returns:
        any Object depending on the visitor implementation, or null
        Throws:
        java.io.IOException - If there is an error while visiting this object.
      • visitFromNull

        public java.lang.Object visitFromNull​(COSNull obj)
                                       throws java.io.IOException
        Description copied from interface: ICOSVisitor
        Notification of visit to null object.
        Specified by:
        visitFromNull in interface ICOSVisitor
        Parameters:
        obj - The Object that is being visited.
        Returns:
        any Object depending on the visitor implementation, or null
        Throws:
        java.io.IOException - If there is an error while visiting this object.
      • writeReference

        public void writeReference​(COSBase obj)
                            throws java.io.IOException
        visitFromObjRef method comment.
        Parameters:
        obj - The object that is being visited.
        Throws:
        java.io.IOException - If there is an exception while visiting this object.
      • visitFromStream

        public java.lang.Object visitFromStream​(COSStream obj)
                                         throws java.io.IOException
        Description copied from interface: ICOSVisitor
        Notification of visit to stream object.
        Specified by:
        visitFromStream in interface ICOSVisitor
        Parameters:
        obj - The Object that is being visited.
        Returns:
        any Object depending on the visitor implementation, or null
        Throws:
        java.io.IOException - If there is an error while visiting this object.
      • visitFromString

        public java.lang.Object visitFromString​(COSString obj)
                                         throws java.io.IOException
        Description copied from interface: ICOSVisitor
        Notification of visit to string object.
        Specified by:
        visitFromString in interface ICOSVisitor
        Parameters:
        obj - The Object that is being visited.
        Returns:
        any Object depending on the visitor implementation, or null
        Throws:
        java.io.IOException - If there is an error while visiting this object.
      • write

        public void write​(COSDocument doc)
                   throws java.io.IOException
        This will write the pdf document.
        Parameters:
        doc - The document to write.
        Throws:
        java.io.IOException - If an error occurs while generating the data.
      • write

        public void write​(PDDocument doc)
                   throws java.io.IOException
        This will write the pdf document. If signature should be created externally, writeExternalSignature(byte[]) should be invoked to set signature after calling this method.
        Parameters:
        doc - The document to write.
        Throws:
        java.io.IOException - If an error occurs while generating the data.
      • write

        public void write​(PDDocument doc,
                          SignatureInterface signInterface)
                   throws java.io.IOException
        This will write the pdf document. If signature should be created externally, writeExternalSignature(byte[]) should be invoked to set signature after calling this method.
        Parameters:
        doc - The document to write.
        signInterface - class to be used for signing; null if external signing would be performed or there will be no signing at all
        Throws:
        java.io.IOException - If an error occurs while generating the data.
        java.lang.IllegalStateException - If the document has an encryption dictionary but no protection policy.
      • write

        public void write​(FDFDocument doc)
                   throws java.io.IOException
        This will write the fdf document.
        Parameters:
        doc - The document to write.
        Throws:
        java.io.IOException - If an error occurs while generating the data.
      • writeString

        public static void writeString​(COSString string,
                                       java.io.OutputStream output)
                                throws java.io.IOException
        This will output the given byte getString as a PDF object.
        Parameters:
        string - COSString to be written
        output - The stream to write to.
        Throws:
        java.io.IOException - If there is an error writing to the stream.
      • writeString

        public static void writeString​(byte[] bytes,
                                       java.io.OutputStream output)
                                throws java.io.IOException
        This will output the given text/byte getString as a PDF object.
        Parameters:
        bytes - byte array representation of a string to be written
        output - The stream to write to.
        Throws:
        java.io.IOException - If there is an error writing to the stream.
      • writeString

        private static void writeString​(byte[] bytes,
                                        boolean forceHex,
                                        java.io.OutputStream output)
                                 throws java.io.IOException
        This will output the given text/byte string as a PDF object.
        Parameters:
        output - The stream to write to.
        Throws:
        java.io.IOException - If there is an error writing to the stream.