Method from org.apache.pdfbox.pdfwriter.COSWriter Detail: |
protected void addXRefEntry(COSWriterXRefEntry entry) {
getXRefEntries().add(entry);
}
add an entry in the x ref table for later dump. |
public void close() throws IOException {
if (getStandardOutput() != null)
{
getStandardOutput().close();
}
if (getOutput() != null)
{
getOutput().close();
}
}
This will close the stream. |
protected void doWriteBody(COSDocument doc) throws IOException, COSVisitorException {
COSDictionary trailer = doc.getTrailer();
COSDictionary root = (COSDictionary)trailer.getDictionaryObject( COSName.ROOT );
COSDictionary info = (COSDictionary)trailer.getDictionaryObject( COSName.INFO );
COSDictionary encrypt = (COSDictionary)trailer.getDictionaryObject( COSName.ENCRYPT );
if( root != null )
{
addObjectToWrite( root );
}
if( info != null )
{
addObjectToWrite( info );
}
while( objectsToWrite.size() > 0 )
{
COSBase nextObject = (COSBase)objectsToWrite.remove( 0 );
doWriteObject( nextObject );
}
willEncrypt = false;
if( encrypt != null )
{
addObjectToWrite( encrypt );
}
while( objectsToWrite.size() > 0 )
{
COSBase nextObject = (COSBase)objectsToWrite.remove( 0 );
doWriteObject( nextObject );
}
// write all objects
/**
for (Iterator i = doc.getObjects().iterator(); i.hasNext();)
{
COSObject obj = (COSObject) i.next();
doWriteObject(obj);
}**/
}
This will write the body of the document. |
protected void doWriteHeader(COSDocument doc) throws IOException {
getStandardOutput().write( doc.getHeaderString().getBytes() );
getStandardOutput().writeEOL();
getStandardOutput().write(COMMENT);
getStandardOutput().write(GARBAGE);
getStandardOutput().writeEOL();
}
This will write the header to the PDF document. |
public void doWriteObject(COSBase obj) throws COSVisitorException {
try
{
writtenObjects.add( obj );
// find the physical reference
currentObjectKey = getObjectKey( obj );
// add a x ref entry
addXRefEntry( new COSWriterXRefEntry(getStandardOutput().getPos(), obj, currentObjectKey));
// write the object
getStandardOutput().write(String.valueOf(currentObjectKey.getNumber()).getBytes());
getStandardOutput().write(SPACE);
getStandardOutput().write(String.valueOf(currentObjectKey.getGeneration()).getBytes());
getStandardOutput().write(SPACE);
getStandardOutput().write(OBJ);
getStandardOutput().writeEOL();
obj.accept( this );
getStandardOutput().writeEOL();
getStandardOutput().write(ENDOBJ);
getStandardOutput().writeEOL();
}
catch (IOException e)
{
throw new COSVisitorException(e);
}
}
This will write a COS object. |
protected void doWriteTrailer(COSDocument doc) throws IOException, COSVisitorException {
getStandardOutput().write(TRAILER);
getStandardOutput().writeEOL();
COSDictionary trailer = doc.getTrailer();
//sort xref, needed only if object keys not regenerated
Collections.sort(getXRefEntries());
COSWriterXRefEntry lastEntry = (COSWriterXRefEntry)getXRefEntries().get( getXRefEntries().size()-1);
trailer.setInt(COSName.SIZE, (int)lastEntry.getKey().getNumber()+1);
trailer.removeItem( COSName.PREV );
/**
COSObject catalog = doc.getCatalog();
if (catalog != null)
{
trailer.setItem(COSName.getPDFName("Root"), catalog);
}
*/
trailer.accept(this);
getStandardOutput().write(STARTXREF);
getStandardOutput().writeEOL();
getStandardOutput().write(String.valueOf(getStartxref()).getBytes());
getStandardOutput().writeEOL();
getStandardOutput().write(EOF);
}
This will write the trailer to the PDF document. |
protected void doWriteXRef(COSDocument doc) throws IOException {
String offset;
String generation;
// sort xref, needed only if object keys not regenerated
Collections.sort(getXRefEntries());
COSWriterXRefEntry lastEntry = (COSWriterXRefEntry)getXRefEntries().get( getXRefEntries().size()-1 );
// remember the position where x ref is written
setStartxref(getStandardOutput().getPos());
//
getStandardOutput().write(XREF);
getStandardOutput().writeEOL();
// write start object number and object count for this x ref section
// we assume starting from scratch
getStandardOutput().write(String.valueOf(0).getBytes());
getStandardOutput().write(SPACE);
getStandardOutput().write(String.valueOf(lastEntry.getKey().getNumber() + 1).getBytes());
getStandardOutput().writeEOL();
// write initial start object with ref to first deleted object and magic generation number
offset = formatXrefOffset.format(0);
generation = formatXrefGeneration.format(65535);
getStandardOutput().write(offset.getBytes());
getStandardOutput().write(SPACE);
getStandardOutput().write(generation.getBytes());
getStandardOutput().write(SPACE);
getStandardOutput().write(XREF_FREE);
getStandardOutput().writeCRLF();
// write entry for every object
long lastObjectNumber = 0;
for (Iterator i = getXRefEntries().iterator(); i.hasNext();)
{
COSWriterXRefEntry entry = (COSWriterXRefEntry) i.next();
while( lastObjectNumber< entry.getKey().getNumber()-1 )
{
offset = formatXrefOffset.format(0);
generation = formatXrefGeneration.format(65535);
getStandardOutput().write(offset.getBytes());
getStandardOutput().write(SPACE);
getStandardOutput().write(generation.getBytes());
getStandardOutput().write(SPACE);
getStandardOutput().write(XREF_FREE);
getStandardOutput().writeCRLF();
lastObjectNumber++;
}
lastObjectNumber = entry.getKey().getNumber();
offset = formatXrefOffset.format(entry.getOffset());
generation = formatXrefGeneration.format(entry.getKey().getGeneration());
getStandardOutput().write(offset.getBytes());
getStandardOutput().write(SPACE);
getStandardOutput().write(generation.getBytes());
getStandardOutput().write(SPACE);
getStandardOutput().write(entry.isFree() ? XREF_FREE : XREF_USED);
getStandardOutput().writeCRLF();
}
}
write the x ref section for the pdf file
currently, the pdf is reconstructed from the scratch, so we write a single section
todo support for incremental writing? |
protected long getNumber() {
return number;
}
This will get the current object number. |
public Map getObjectKeys() {
return objectKeys;
}
This will get all available object keys. |
protected OutputStream getOutput() {
return output;
}
This will get the output stream. |
protected COSStandardOutputStream getStandardOutput() {
return standardOutput;
}
This will get the standard output stream. |
protected long getStartxref() {
return startxref;
}
This will get the current start xref. |
protected List getXRefEntries() {
return xRefEntries;
}
This will get the xref entries. |
protected void setNumber(long newNumber) {
number = newNumber;
}
This will set the current object number. |
protected void setStartxref(long newStartxref) {
startxref = newStartxref;
}
This will set the start xref. |
public Object visitFromArray(COSArray obj) throws COSVisitorException {
try
{
int count = 0;
getStandardOutput().write(ARRAY_OPEN);
for (Iterator i = obj.iterator(); i.hasNext();)
{
COSBase current = (COSBase) i.next();
if( current instanceof COSDictionary )
{
addObjectToWrite( current );
writeReference( current );
}
else if( current instanceof COSObject )
{
COSBase subValue = ((COSObject)current).getObject();
if( subValue instanceof COSDictionary || subValue == null )
{
addObjectToWrite( current );
writeReference( current );
}
else
{
subValue.accept( this );
}
}
else if( current == null )
{
COSNull.NULL.accept( this );
}
else
{
current.accept(this);
}
count++;
if (i.hasNext())
{
if (count % 10 == 0)
{
getStandardOutput().writeEOL();
}
else
{
getStandardOutput().write(SPACE);
}
}
}
getStandardOutput().write(ARRAY_CLOSE);
getStandardOutput().writeEOL();
return null;
}
catch (IOException e)
{
throw new COSVisitorException(e);
}
}
visitFromArray method comment. |
public Object visitFromBoolean(COSBoolean obj) throws COSVisitorException {
try
{
obj.writePDF( getStandardOutput() );
return null;
}
catch (IOException e)
{
throw new COSVisitorException(e);
}
}
visitFromBoolean method comment. |
public Object visitFromDictionary(COSDictionary obj) throws COSVisitorException {
try
{
getStandardOutput().write(DICT_OPEN);
getStandardOutput().writeEOL();
for (Map.Entry< COSName, COSBase > entry : obj.entrySet())
{
COSBase value = entry.getValue();
if (value != null)
{
entry.getKey().accept(this);
getStandardOutput().write(SPACE);
if( value instanceof COSDictionary )
{
addObjectToWrite( value );
writeReference( value );
}
else if( value instanceof COSObject )
{
COSBase subValue = ((COSObject)value).getObject();
if( subValue instanceof COSDictionary || subValue == null )
{
addObjectToWrite( value );
writeReference( value );
}
else
{
subValue.accept( this );
}
}
else
{
value.accept(this);
}
getStandardOutput().writeEOL();
}
else
{
//then we won't write anything, there are a couple cases
//were the value of an entry in the COSDictionary will
//be a dangling reference that points to nothing
//so we will just not write out the entry if that is the case
}
}
getStandardOutput().write(DICT_CLOSE);
getStandardOutput().writeEOL();
return null;
}
catch( IOException e )
{
throw new COSVisitorException(e);
}
}
visitFromDictionary method comment. |
public Object visitFromDocument(COSDocument doc) throws COSVisitorException {
try
{
doWriteHeader(doc);
doWriteBody(doc);
doWriteXRef(doc);
doWriteTrailer(doc);
return null;
}
catch (IOException e)
{
throw new COSVisitorException(e);
}
}
The visit from document method. |
public Object visitFromFloat(COSFloat obj) throws COSVisitorException {
try
{
obj.writePDF( getStandardOutput() );
return null;
}
catch (IOException e)
{
throw new COSVisitorException(e);
}
}
visitFromFloat method comment. |
public Object visitFromInt(COSInteger obj) throws COSVisitorException {
try
{
obj.writePDF( getStandardOutput() );
return null;
}
catch (IOException e)
{
throw new COSVisitorException(e);
}
}
visitFromFloat method comment. |
public Object visitFromName(COSName obj) throws COSVisitorException {
try
{
obj.writePDF( getStandardOutput() );
return null;
}
catch (IOException e)
{
throw new COSVisitorException(e);
}
}
visitFromName method comment. |
public Object visitFromNull(COSNull obj) throws COSVisitorException {
try
{
obj.writePDF( getStandardOutput() );
return null;
}
catch (IOException e)
{
throw new COSVisitorException(e);
}
}
visitFromNull method comment. |
public Object visitFromStream(COSStream obj) throws COSVisitorException {
try
{
if(willEncrypt)
{
document.getSecurityHandler().decryptStream(
obj,
currentObjectKey.getNumber(),
currentObjectKey.getGeneration());
}
InputStream input = obj.getFilteredStream();
// set the length of the stream and write stream dictionary
COSObject lengthObject = new COSObject( null );
obj.setItem(COSName.LENGTH, lengthObject);
//obj.accept(this);
// write the stream content
visitFromDictionary( obj );
getStandardOutput().write(STREAM);
getStandardOutput().writeCRLF();
byte[] buffer = new byte[1024];
int amountRead = 0;
int totalAmountWritten = 0;
while( (amountRead = input.read(buffer,0,1024)) != -1 )
{
getStandardOutput().write( buffer, 0, amountRead );
totalAmountWritten += amountRead;
}
lengthObject.setObject( COSInteger.get( totalAmountWritten ) );
getStandardOutput().writeCRLF();
getStandardOutput().write(ENDSTREAM);
getStandardOutput().writeEOL();
return null;
}
catch( Exception e )
{
throw new COSVisitorException(e);
}
}
visitFromStream method comment. |
public Object visitFromString(COSString obj) throws COSVisitorException {
try
{
if(willEncrypt)
{
document.getSecurityHandler().decryptString(
obj,
currentObjectKey.getNumber(),
currentObjectKey.getGeneration());
}
obj.writePDF( getStandardOutput() );
}
catch (Exception e)
{
throw new COSVisitorException(e);
}
return null;
}
visitFromString method comment. |
public void write(COSDocument doc) throws COSVisitorException {
PDDocument pdDoc = new PDDocument( doc );
write( pdDoc );
}
This will write the pdf document. |
public void write(PDDocument doc) throws COSVisitorException {
document = doc;
// if the document says we should remove encryption, then we shouldn't encrypt
if(doc.isAllSecurityToBeRemoved())
{
this.willEncrypt = false;
// also need to get rid of the "Encrypt" in the trailer so readers
// don't try to decrypt a document which is not encrypted
COSDocument cosDoc = doc.getDocument();
COSDictionary trailer = cosDoc.getTrailer();
trailer.removeItem(COSName.ENCRYPT);
}
else
{
SecurityHandler securityHandler = document.getSecurityHandler();
if(securityHandler != null)
{
try
{
securityHandler.prepareDocumentForEncryption(document);
this.willEncrypt = true;
}
catch(IOException e)
{
throw new COSVisitorException( e );
}
catch(CryptographyException e)
{
throw new COSVisitorException( e );
}
}
else
{
this.willEncrypt = false;
}
}
COSDocument cosDoc = document.getDocument();
COSDictionary trailer = cosDoc.getTrailer();
COSArray idArray = (COSArray)trailer.getDictionaryObject( COSName.ID );
if( idArray == null )
{
try
{
//algothim says to use time/path/size/values in doc to generate
//the id. We don't have path or size, so do the best we can
MessageDigest md = MessageDigest.getInstance( "MD5" );
md.update( Long.toString( System.currentTimeMillis()).getBytes() );
COSDictionary info = (COSDictionary)trailer.getDictionaryObject( COSName.INFO );
if( info != null )
{
Iterator values = info.getValues().iterator();
while( values.hasNext() )
{
md.update( values.next().toString().getBytes() );
}
}
idArray = new COSArray();
COSString id = new COSString( md.digest() );
idArray.add( id );
idArray.add( id );
trailer.setItem( COSName.ID, idArray );
}
catch( NoSuchAlgorithmException e )
{
throw new COSVisitorException( e );
}
}
/*
List objects = doc.getObjects();
Iterator iter = objects.iterator();
long maxNumber = 0;
while( iter.hasNext() )
{
COSObject object = (COSObject)iter.next();
if( object.getObjectNumber() != null &&
object.getGenerationNumber() != null )
{
COSObjectKey key = new COSObjectKey( object.getObjectNumber().longValue(),
object.getGenerationNumber().longValue() );
objectKeys.put( object.getObject(), key );
objectKeys.put( object, key );
maxNumber = Math.max( key.getNumber(), maxNumber );
setNumber( maxNumber );
}
}*/
cosDoc.accept(this);
}
This will write the pdf document. |
public void writeReference(COSBase obj) throws COSVisitorException {
try
{
COSObjectKey key = getObjectKey(obj);
getStandardOutput().write(String.valueOf(key.getNumber()).getBytes());
getStandardOutput().write(SPACE);
getStandardOutput().write(String.valueOf(key.getGeneration()).getBytes());
getStandardOutput().write(SPACE);
getStandardOutput().write(REFERENCE);
}
catch (IOException e)
{
throw new COSVisitorException(e);
}
}
visitFromObjRef method comment. |