/**
* Copyright (c) 2003, www.pdfbox.org
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. Neither the name of pdfbox; nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* http://www.pdfbox.org
*
*/
package org.pdfbox.pdmodel;
import java.io.IOException;
import org.pdfbox.cos.COSArray;
import org.pdfbox.cos.COSDictionary;
import org.pdfbox.cos.COSDocument;
import org.pdfbox.cos.COSInteger;
import org.pdfbox.cos.COSName;
import org.pdfbox.cos.COSObject;
/**
* This is the in-memory representation of the PDF document.
*
* @author Ben Litchfield (ben@csh.rit.edu)
* @version $Revision: 1.8 $
*/
public class PDDocument
{
private COSDocument document;
//cached values
private PDDocumentInformation documentInformation;
private PDDocumentCatalog documentCatalog;
/**
* Constructor, creates a new PDF Document with no pages. You need to add
* at least one page for the document to be valid.
*
* @throws IOException If there is an error creating this document.
*/
public PDDocument() throws IOException
{
document = new COSDocument();
//First we need a trailer
COSDictionary trailer = new COSDictionary();
document.setTrailer( trailer );
//Next we need the root dictionary.
COSDictionary rootDictionary = new COSDictionary();
COSObject root = new COSObject( rootDictionary );
document.addObject( root );
trailer.setItem( COSName.getPDFName( "Root" ), root );
rootDictionary.setItem( COSName.getPDFName( "Type" ), COSName.getPDFName( "Catalog" ) );
rootDictionary.setItem( COSName.getPDFName( "Version" ), COSName.getPDFName( "1.4" ) );
//next we need the pages tree structure
COSDictionary pages = new COSDictionary();
COSObject pagesObject = new COSObject( pages );
document.addObject( pagesObject );
rootDictionary.setItem( COSName.getPDFName( "Pages" ), pagesObject );
pages.setItem( COSName.getPDFName( "Type" ), COSName.getPDFName( "Pages" ) );
COSArray kidsArray = new COSArray();
pages.setItem( COSName.getPDFName( "Kids" ), kidsArray );
pages.setItem( COSName.getPDFName( "Count" ), new COSInteger( 0 ) );
}
/**
* This will add a page to the document. This is a convenience method, that
* will add the page to the root of the hierarchy and set the parent of the
* page to the root.
*
* @param page The page to add to the document.
*/
public void addPage( PDPage page )
{
PDPageNode rootPages = getDocumentCatalog().getPages();
rootPages.getKids().add( page );
page.setParent( rootPages );
}
/**
* Constructor that uses an existing document. The COSDocument that
* is passed in must be valid.
*
* @param doc The COSDocument that this document wraps.
*/
public PDDocument( COSDocument doc )
{
document = doc;
}
/**
* This will get the low level document.
*
* @return The document that this layer sits on top of.
*/
public COSDocument getDocument()
{
return document;
}
/**
* This will get the document info dictionary. This is guaranteed to not return null.
*
* @return The documents /Info dictionary
*/
public PDDocumentInformation getDocumentInformation()
{
if( documentInformation == null )
{
COSName infoName = COSName.getPDFName( "Info" );
COSDictionary trailer = document.getTrailer();
COSDictionary infoDic = (COSDictionary)trailer.getDictionaryObject( infoName );
if( infoDic == null )
{
infoDic = new COSDictionary();
COSObject infoObj = new COSObject( infoDic );
trailer.setItem( infoName, infoObj );
document.addObject( infoObj );
}
documentInformation = new PDDocumentInformation( infoDic );
}
return documentInformation;
}
/**
* This will get the document CATALOG. This is guaranteed to not return null.
*
* @return The documents /Root dictionary
*/
public PDDocumentCatalog getDocumentCatalog()
{
if( documentCatalog == null )
{
COSDictionary trailer = document.getTrailer();
COSDictionary infoDic = (COSDictionary)trailer.getDictionaryObject( COSName.ROOT );
if( infoDic == null )
{
documentCatalog = new PDDocumentCatalog( document );
}
else
{
documentCatalog = new PDDocumentCatalog( document, infoDic );
}
}
return documentCatalog;
}
/**
* This will tell if this document is encrypted or not.
*
* @return true If this document is encrypted.
*/
public boolean isEncrypted()
{
return document.isEncrypted();
}
/**
* This will return the total page count of the PDF document.
*
* @return The total number of pages in the PDF document.
*
* @throws IOException If there is an error getting the page count
*/
public int getPageCount() throws IOException
{
COSObject catalog = document.getCatalog();
COSObject pages = (COSObject)catalog.getItem( COSName.PAGES );
return getPageCount(pages);
}
/**
* Helper method for getPageCount method.
*/
private int getPageCount( COSObject pages )
{
COSArray pagesArray = (COSArray)pages.getDictionaryObject( COSName.KIDS );
int pagecount = 0;
if( pagesArray != null )
{
for( int i=0; i<pagesArray.size(); i++ )
{
COSObject pageChild = (COSObject)pagesArray.get( i );
pagecount = pagecount + getPageCount(pageChild );
}
}
else
{
// If its null then its a page otherwise its an array
pagecount++;
}
return pagecount;
}
/**
* This will close the underlying COSDocument object.
*
* @throws IOException If there is an error releasing resources.
*/
public void close() throws IOException
{
document.close();
}
}