Package org.apache.pdfbox.pdfwriter
Class COSWriter
- java.lang.Object
-
- org.apache.pdfbox.pdfwriter.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 Summary
Fields Modifier and Type Field Description private java.util.Set<COSBase>
actualsAdded
static byte[]
ARRAY_CLOSE
The array close token.static byte[]
ARRAY_OPEN
The array open token.private COSArray
byteRangeArray
private long
byteRangeLength
private long
byteRangeOffset
static byte[]
COMMENT
The start to a PDF comment.private COSObjectKey
currentObjectKey
static byte[]
DICT_CLOSE
The dictionary close token.static byte[]
DICT_OPEN
The dictionary open token.static byte[]
ENDOBJ
The end object token.static byte[]
ENDSTREAM
The close stream token.static byte[]
EOF
The EOF constant.private FDFDocument
fdfDocument
private java.text.NumberFormat
formatXrefGeneration
private java.text.NumberFormat
formatXrefOffset
static byte[]
GARBAGE
Garbage bytes used to create the PDF header.private RandomAccessRead
incrementalInput
private java.io.OutputStream
incrementalOutput
private boolean
incrementalUpdate
private byte[]
incrementPart
private java.util.Map<COSObjectKey,COSBase>
keyObject
private static org.apache.commons.logging.Log
LOG
private long
number
static byte[]
OBJ
The starting object token.private java.util.Map<COSBase,COSObjectKey>
objectKeys
private java.util.Deque<COSBase>
objectsToWrite
private java.util.Set<COSBase>
objectsToWriteSet
private java.io.OutputStream
output
private PDDocument
pdDocument
private boolean
reachedSignature
static byte[]
REFERENCE
The reference token.private SignatureInterface
signatureInterface
private long
signatureLength
private long
signatureOffset
static byte[]
SPACE
space character.private COSStandardOutputStream
standardOutput
private long
startxref
static byte[]
STARTXREF
The start xref token.static byte[]
STREAM
The open stream token.static byte[]
TRAILER
The trailer token.static byte[]
VERSION
The output version of the PDF.private boolean
willEncrypt
private java.util.Set<COSBase>
writtenObjects
static byte[]
XREF
The XREF token.static byte[]
XREF_FREE
The xref free token.static byte[]
XREF_USED
The xref used token.private java.util.List<COSWriterXRefEntry>
xRefEntries
-
Constructor Summary
Constructors Constructor Description COSWriter(java.io.OutputStream outputStream)
COSWriter constructor.COSWriter(java.io.OutputStream outputStream, RandomAccessRead inputData)
COSWriter constructor for incremental updates.COSWriter(java.io.OutputStream outputStream, RandomAccessRead inputData, java.util.Set<COSDictionary> objectsToWrite)
Constructor for incremental updates with a list of objects to write.
-
Method Summary
All Methods Static Methods Instance Methods Concrete Methods Modifier and Type Method Description private void
addObjectToWrite(COSBase object)
protected void
addXRefEntry(COSWriterXRefEntry entry)
add an entry in the x ref table for later dump.void
close()
This will close the stream.protected void
doWriteBody(COSDocument doc)
This will write the body of the document.protected void
doWriteHeader(COSDocument doc)
This will write the header to the PDF document.private void
doWriteIncrement()
Write an incremental update for a non signature case.void
doWriteObject(COSBase obj)
This will write a COS object.private void
doWriteObjects()
private void
doWriteSignature()
protected void
doWriteTrailer(COSDocument doc)
This will write the trailer to the PDF document.private void
doWriteXRefInc(COSDocument doc, long hybridPrev)
private void
doWriteXRefTable()
java.io.InputStream
getDataToSign()
Return the stream of PDF data to be signed.protected long
getNumber()
This will get the current object number.private COSObjectKey
getObjectKey(COSBase obj)
This will get the object key for the object.java.util.Map<COSBase,COSObjectKey>
getObjectKeys()
This will get all available object keys.protected java.io.OutputStream
getOutput()
This will get the output stream.protected COSStandardOutputStream
getStandardOutput()
This will get the standard output stream.protected long
getStartxref()
This will get the current start xref.protected java.util.List<COSWriterXRefEntry>
getXRefEntries()
This will get the xref entries.protected java.lang.Long[]
getXRefRanges(java.util.List<COSWriterXRefEntry> xRefEntriesList)
check the xref entries and write out the ranges.private boolean
isNeedToBeUpdated(COSBase base)
Convenience method, so that we get false for types that can't be updated.private void
prepareIncrement(PDDocument doc)
protected void
setNumber(long newNumber)
This will set the current object number.private void
setOutput(java.io.OutputStream newOutput)
This will set the output stream.private void
setStandardOutput(COSStandardOutputStream newStandardOutput)
This will set the standard output stream.protected void
setStartxref(long newStartxref)
This will set the start xref.java.lang.Object
visitFromArray(COSArray obj)
Notification of visit to Array object.java.lang.Object
visitFromBoolean(COSBoolean obj)
Notification of visit to boolean object.java.lang.Object
visitFromDictionary(COSDictionary obj)
Notification of visit to dictionary object.java.lang.Object
visitFromDocument(COSDocument doc)
Notification of visit to document object.java.lang.Object
visitFromFloat(COSFloat obj)
Notification of visit to float object.java.lang.Object
visitFromInt(COSInteger obj)
Notification of visit to integer object.java.lang.Object
visitFromName(COSName obj)
Notification of visit to name object.java.lang.Object
visitFromNull(COSNull obj)
Notification of visit to null object.java.lang.Object
visitFromStream(COSStream obj)
Notification of visit to stream object.java.lang.Object
visitFromString(COSString obj)
Notification of visit to string object.void
write(COSDocument doc)
This will write the pdf document.void
write(FDFDocument doc)
This will write the fdf document.void
write(PDDocument doc)
This will write the pdf document.void
write(PDDocument doc, SignatureInterface signInterface)
This will write the pdf document.void
writeExternalSignature(byte[] cmsSignature)
Write externally created signature of PDF data obtained viagetDataToSign()
method.void
writeReference(COSBase obj)
visitFromObjRef method comment.private static void
writeString(byte[] bytes, boolean forceHex, java.io.OutputStream output)
This will output the given text/byte string as a PDF object.static void
writeString(byte[] bytes, java.io.OutputStream output)
This will output the given text/byte getString as a PDF object.static void
writeString(COSString string, java.io.OutputStream output)
This will output the given byte getString as a PDF object.private void
writeXrefEntry(COSWriterXRefEntry entry)
private void
writeXrefRange(long x, long y)
-
-
-
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
-
standardOutput
private COSStandardOutputStream standardOutput
-
startxref
private long startxref
-
number
private long number
-
objectKeys
private final java.util.Map<COSBase,COSObjectKey> objectKeys
-
keyObject
private final java.util.Map<COSObjectKey,COSBase> keyObject
-
xRefEntries
private final java.util.List<COSWriterXRefEntry> xRefEntries
-
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
-
currentObjectKey
private COSObjectKey currentObjectKey
-
pdDocument
private PDDocument pdDocument
-
fdfDocument
private FDFDocument fdfDocument
-
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
-
incrementalInput
private RandomAccessRead incrementalInput
-
incrementalOutput
private java.io.OutputStream incrementalOutput
-
signatureInterface
private SignatureInterface signatureInterface
-
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 haveCOSUpdateInfo.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 haveCOSUpdateInfo.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 interfacejava.lang.AutoCloseable
- Specified by:
close
in interfacejava.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 usingwriteExternalSignature(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 signingjava.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 viagetDataToSign()
method.- Parameters:
cmsSignature
- CMS signature byte array- Throws:
java.lang.IllegalStateException
- if PDF is not prepared for external signingjava.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 interfaceICOSVisitor
- 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 interfaceICOSVisitor
- 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 interfaceICOSVisitor
- 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 interfaceICOSVisitor
- 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 interfaceICOSVisitor
- 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 interfaceICOSVisitor
- 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 interfaceICOSVisitor
- 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 interfaceICOSVisitor
- 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 interfaceICOSVisitor
- 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 interfaceICOSVisitor
- 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 writtenoutput
- 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 writtenoutput
- 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.
-
-