KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > pdfbox > pdmodel > PDDocument


1 /**
2  * Copyright (c) 2003-2006, www.pdfbox.org
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are met:
7  *
8  * 1. Redistributions of source code must retain the above copyright notice,
9  * this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright notice,
11  * this list of conditions and the following disclaimer in the documentation
12  * and/or other materials provided with the distribution.
13  * 3. Neither the name of pdfbox; nor the names of its
14  * contributors may be used to endorse or promote products derived from this
15  * software without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20  * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
21  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
24  * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
26  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27  *
28  * http://www.pdfbox.org
29  *
30  */

31 package org.pdfbox.pdmodel;
32
33 import java.awt.print.PageFormat JavaDoc;
34 import java.awt.print.Pageable JavaDoc;
35 import java.awt.print.Paper JavaDoc;
36 import java.awt.print.Printable JavaDoc;
37 import java.awt.print.PrinterException JavaDoc;
38 import java.awt.print.PrinterJob JavaDoc;
39 import java.io.BufferedInputStream JavaDoc;
40 import java.io.File JavaDoc;
41 import java.io.FileInputStream JavaDoc;
42 import java.io.FileOutputStream JavaDoc;
43 import java.io.IOException JavaDoc;
44 import java.io.InputStream JavaDoc;
45 import java.io.OutputStream JavaDoc;
46 import java.net.URL JavaDoc;
47 import java.util.List JavaDoc;
48
49 import org.pdfbox.cos.COSArray;
50 import org.pdfbox.cos.COSDictionary;
51 import org.pdfbox.cos.COSDocument;
52 import org.pdfbox.cos.COSInteger;
53 import org.pdfbox.cos.COSName;
54 import org.pdfbox.cos.COSStream;
55 import org.pdfbox.exceptions.COSVisitorException;
56 import org.pdfbox.exceptions.CryptographyException;
57 import org.pdfbox.exceptions.InvalidPasswordException;
58 import org.pdfbox.io.RandomAccess;
59 import org.pdfbox.pdfparser.PDFParser;
60 import org.pdfbox.pdfwriter.COSWriter;
61 import org.pdfbox.pdmodel.common.PDRectangle;
62 import org.pdfbox.pdmodel.common.PDStream;
63 import org.pdfbox.pdmodel.encryption.AccessPermission;
64 import org.pdfbox.pdmodel.encryption.BadSecurityHandlerException;
65 import org.pdfbox.pdmodel.encryption.DecryptionMaterial;
66 import org.pdfbox.pdmodel.encryption.PDEncryptionDictionary;
67 import org.pdfbox.pdmodel.encryption.ProtectionPolicy;
68 import org.pdfbox.pdmodel.encryption.SecurityHandler;
69 import org.pdfbox.pdmodel.encryption.SecurityHandlersManager;
70 import org.pdfbox.pdmodel.encryption.StandardDecryptionMaterial;
71 import org.pdfbox.pdmodel.encryption.StandardProtectionPolicy;
72
73 /**
74  * This is the in-memory representation of the PDF document. You need to call
75  * close() on this object when you are done using it!!
76  *
77  * @author <a HREF="mailto:ben@benlitchfield.com">Ben Litchfield</a>
78  * @version $Revision: 1.43 $
79  */

80 public class PDDocument implements Pageable JavaDoc
81 {
82     private COSDocument document;
83     
84     // NOTE BGUILLON: this property must be removed because it is
85
// not the responsability of this class to know
86
//private boolean encryptOnSave = false;
87

88     
89     // NOTE BGUILLON: these properties are not used anymore. See getCurrentAccessPermission() instead
90
//private String encryptUserPassword = null;
91
//private String encryptOwnerPassword = null;
92

93     //cached values
94
private PDDocumentInformation documentInformation;
95     private PDDocumentCatalog documentCatalog;
96
97     //The encParameters will be cached here. When the document is decrypted then
98
//the COSDocument will not have an "Encrypt" dictionary anymore and this object
99
//must be used.
100
private PDEncryptionDictionary encParameters = null;
101     
102     /**
103      * This will tell if the document was decrypted with the master password.
104      * NOTE BGUILLON: this property is not used anymore. See getCurrentAccessPermission() instead
105      */

106    //private boolean decryptedWithOwnerPassword = false;
107

108     
109     /**
110      * The security handler used to decrypt / encrypt the document.
111      */

112     private SecurityHandler securityHandler = null;
113     
114
115     /**
116      * Constructor, creates a new PDF Document with no pages. You need to add
117      * at least one page for the document to be valid.
118      *
119      * @throws IOException If there is an error creating this document.
120      */

121     public PDDocument() throws IOException JavaDoc
122     {
123         document = new COSDocument();
124
125         //First we need a trailer
126
COSDictionary trailer = new COSDictionary();
127         document.setTrailer( trailer );
128
129         //Next we need the root dictionary.
130
COSDictionary rootDictionary = new COSDictionary();
131         trailer.setItem( COSName.ROOT, rootDictionary );
132         rootDictionary.setItem( COSName.TYPE, COSName.CATALOG );
133         rootDictionary.setItem( COSName.VERSION, COSName.getPDFName( "1.4" ) );
134
135         //next we need the pages tree structure
136
COSDictionary pages = new COSDictionary();
137         rootDictionary.setItem( COSName.PAGES, pages );
138         pages.setItem( COSName.TYPE, COSName.PAGES );
139         COSArray kidsArray = new COSArray();
140         pages.setItem( COSName.KIDS, kidsArray );
141         pages.setItem( COSName.COUNT, new COSInteger( 0 ) );
142     }
143
144     /**
145      * This will add a page to the document. This is a convenience method, that
146      * will add the page to the root of the hierarchy and set the parent of the
147      * page to the root.
148      *
149      * @param page The page to add to the document.
150      */

151     public void addPage( PDPage page )
152     {
153         PDPageNode rootPages = getDocumentCatalog().getPages();
154         rootPages.getKids().add( page );
155         page.setParent( rootPages );
156         rootPages.updateCount();
157     }
158     
159     /**
160      * Remove the page from the document.
161      *
162      * @param page The page to remove from the document.
163      *
164      * @return true if the page was found false otherwise.
165      */

166     public boolean removePage( PDPage page )
167     {
168         PDPageNode parent = page.getParent();
169         boolean retval = parent.getKids().remove( page );
170         if( retval )
171         {
172             //do a recursive updateCount starting at the root
173
//of the document
174
getDocumentCatalog().getPages().updateCount();
175         }
176         return retval;
177     }
178     
179     /**
180      * Remove the page from the document.
181      *
182      * @param pageNumber 0 based index to page number.
183      * @return true if the page was found false otherwise.
184      */

185     public boolean removePage( int pageNumber )
186     {
187         boolean removed = false;
188         List JavaDoc allPages = getDocumentCatalog().getAllPages();
189         if( allPages.size() > pageNumber)
190         {
191             PDPage page = (PDPage)allPages.get( pageNumber );
192             removed = removePage( page );
193         }
194         return removed;
195     }
196
197     /**
198      * This will import and copy the contents from another location. Currently
199      * the content stream is stored in a scratch file. The scratch file is
200      * associated with the document. If you are adding a page to this document
201      * from another document and want to copy the contents to this document's
202      * scratch file then use this method otherwise just use the addPage method.
203      *
204      * @param page The page to import.
205      * @return The page that was imported.
206      *
207      * @throws IOException If there is an error copying the page.
208      */

209     public PDPage importPage( PDPage page ) throws IOException JavaDoc
210     {
211         PDPage importedPage = new PDPage( new COSDictionary( page.getCOSDictionary() ) );
212         InputStream JavaDoc is = null;
213         OutputStream JavaDoc os = null;
214         try
215         {
216             PDStream src = page.getContents();
217             PDStream dest = new PDStream( new COSStream( src.getStream(), document.getScratchFile() ) );
218             importedPage.setContents( dest );
219             os = dest.createOutputStream();
220
221             byte[] buf = new byte[10240];
222             int amountRead = 0;
223             is = src.createInputStream();
224             while((amountRead = is.read(buf,0,10240)) > -1)
225             {
226                 os.write(buf, 0, amountRead);
227             }
228             addPage( importedPage );
229         }
230         finally
231         {
232             if( is != null )
233             {
234                 is.close();
235             }
236             if( os != null )
237             {
238                 os.close();
239             }
240         }
241         return importedPage;
242
243     }
244
245     /**
246      * Constructor that uses an existing document. The COSDocument that
247      * is passed in must be valid.
248      *
249      * @param doc The COSDocument that this document wraps.
250      */

251     public PDDocument( COSDocument doc )
252     {
253         document = doc;
254     }
255
256     /**
257      * This will get the low level document.
258      *
259      * @return The document that this layer sits on top of.
260      */

261     public COSDocument getDocument()
262     {
263         return document;
264     }
265
266     /**
267      * This will get the document info dictionary. This is guaranteed to not return null.
268      *
269      * @return The documents /Info dictionary
270      */

271     public PDDocumentInformation getDocumentInformation()
272     {
273         if( documentInformation == null )
274         {
275             COSDictionary trailer = document.getTrailer();
276             COSDictionary infoDic = (COSDictionary)trailer.getDictionaryObject( COSName.INFO );
277             if( infoDic == null )
278             {
279                 infoDic = new COSDictionary();
280                 trailer.setItem( COSName.INFO, infoDic );
281             }
282             documentInformation = new PDDocumentInformation( infoDic );
283         }
284         return documentInformation;
285     }
286
287     /**
288      * This will set the document information for this document.
289      *
290      * @param info The updated document information.
291      */

292     public void setDocumentInformation( PDDocumentInformation info )
293     {
294         documentInformation = info;
295         document.getTrailer().setItem( COSName.INFO, info.getDictionary() );
296     }
297
298     /**
299      * This will get the document CATALOG. This is guaranteed to not return null.
300      *
301      * @return The documents /Root dictionary
302      */

303     public PDDocumentCatalog getDocumentCatalog()
304     {
305         if( documentCatalog == null )
306         {
307             COSDictionary trailer = document.getTrailer();
308             COSDictionary infoDic = (COSDictionary)trailer.getDictionaryObject( COSName.ROOT );
309             if( infoDic == null )
310             {
311                 documentCatalog = new PDDocumentCatalog( this );
312             }
313             else
314             {
315                 documentCatalog = new PDDocumentCatalog( this, infoDic );
316             }
317
318         }
319         return documentCatalog;
320     }
321
322     /**
323      * This will tell if this document is encrypted or not.
324      *
325      * @return true If this document is encrypted.
326      */

327     public boolean isEncrypted()
328     {
329         return document.isEncrypted();
330     }
331
332     /**
333      * This will get the encryption dictionary for this document. This will still
334      * return the parameters if the document was decrypted. If the document was
335      * never encrypted then this will return null. As the encryption architecture
336      * in PDF documents is plugable this returns an abstract class, but the only
337      * supported subclass at this time is a PDStandardEncryption object.
338      *
339      * @return The encryption dictionary(most likely a PDStandardEncryption object)
340      *
341      * @throws IOException If there is an error determining which security handler to use.
342      */

343     public PDEncryptionDictionary getEncryptionDictionary() throws IOException JavaDoc
344     {
345         if( encParameters == null )
346         {
347             if( isEncrypted() )
348             {
349                 encParameters = new PDEncryptionDictionary(document.getEncryptionDictionary());
350             }
351             else
352             {
353                 encParameters = new PDEncryptionDictionary();
354             }
355         }
356         return encParameters;
357     }
358
359     /**
360      * This will set the encryption dictionary for this document.
361      *
362      * @param encDictionary The encryption dictionary(most likely a PDStandardEncryption object)
363      *
364      * @throws IOException If there is an error determining which security handler to use.
365      */

366     public void setEncryptionDictionary( PDEncryptionDictionary encDictionary ) throws IOException JavaDoc
367     {
368         encParameters = encDictionary;
369     }
370
371     /**
372      * This will determine if this is the user password. This only applies when
373      * the document is encrypted and uses standard encryption.
374      *
375      * @param password The plain text user password.
376      *
377      * @return true If the password passed in matches the user password used to encrypt the document.
378      *
379      * @throws IOException If there is an error determining if it is the user password.
380      * @throws CryptographyException If there is an error in the encryption algorithms.
381      *
382      * @deprecated
383      */

384     public boolean isUserPassword( String JavaDoc password ) throws IOException JavaDoc, CryptographyException
385     {
386             return false;
387         /*boolean retval = false;
388         if( password == null )
389         {
390             password = "";
391         }
392         PDFEncryption encryptor = new PDFEncryption();
393         PDEncryptionDictionary encryptionDictionary = getEncryptionDictionary();
394         if( encryptionDictionary == null )
395         {
396             throw new IOException( "Error: Document is not encrypted" );
397         }
398         else
399         {
400             if( encryptionDictionary instanceof PDStandardEncryption )
401             {
402                 COSString documentID = (COSString)document.getDocumentID().get(0);
403                 PDStandardEncryption standard = (PDStandardEncryption)encryptionDictionary;
404                 retval = encryptor.isUserPassword(
405                     password.getBytes(),
406                     standard.getUserKey(),
407                     standard.getOwnerKey(),
408                     standard.getPermissions(),
409                     documentID.getBytes(),
410                     standard.getRevision(),
411                     standard.getLength()/8 );
412             }
413             else
414             {
415                 throw new IOException( "Error: Encyption dictionary is not 'Standard'" +
416                     encryptionDictionary.getClass().getName() );
417             }
418         }
419         return retval;*/

420     }
421
422     /**
423      * This will determine if this is the owner password. This only applies when
424      * the document is encrypted and uses standard encryption.
425      *
426      * @param password The plain text owner password.
427      *
428      * @return true If the password passed in matches the owner password used to encrypt the document.
429      *
430      * @throws IOException If there is an error determining if it is the user password.
431      * @throws CryptographyException If there is an error in the encryption algorithms.
432      *
433      * @deprecated
434      */

435     public boolean isOwnerPassword( String JavaDoc password ) throws IOException JavaDoc, CryptographyException
436     {
437             return false;
438         /*boolean retval = false;
439         if( password == null )
440         {
441             password = "";
442         }
443         PDFEncryption encryptor = new PDFEncryption();
444         PDEncryptionDictionary encryptionDictionary = getEncryptionDictionary();
445         if( encryptionDictionary == null )
446         {
447             throw new IOException( "Error: Document is not encrypted" );
448         }
449         else
450         {
451             if( encryptionDictionary instanceof PDStandardEncryption )
452             {
453                 COSString documentID = (COSString)document.getDocumentID().get( 0 );
454                 PDStandardEncryption standard = (PDStandardEncryption)encryptionDictionary;
455                 retval = encryptor.isOwnerPassword(
456                     password.getBytes(),
457                     standard.getUserKey(),
458                     standard.getOwnerKey(),
459                     standard.getPermissions(),
460                     documentID.getBytes(),
461                     standard.getRevision(),
462                     standard.getLength()/8 );
463             }
464             else
465             {
466                 throw new IOException( "Error: Encyption dictionary is not 'Standard'" +
467                     encryptionDictionary.getClass().getName() );
468             }
469         }
470         return retval;*/

471     }
472
473     /**
474      * This will decrypt a document. This method is provided for compatibility reasons only. User should use
475      * the new security layer instead and the openProtection method especially.
476      *
477      * @param password Either the user or owner password.
478      *
479      * @throws CryptographyException If there is an error decrypting the document.
480      * @throws IOException If there is an error getting the stream data.
481      * @throws InvalidPasswordException If the password is not a user or owner password.
482      *
483      */

484     public void decrypt( String JavaDoc password ) throws CryptographyException, IOException JavaDoc, InvalidPasswordException
485     {
486         try
487         {
488             StandardDecryptionMaterial m = new StandardDecryptionMaterial(password);
489             this.openProtection(m);
490             document.dereferenceObjectStreams();
491         }
492         catch(BadSecurityHandlerException e)
493         {
494             throw new CryptographyException(e);
495         }
496     }
497     
498     /**
499      * This will tell if the document was decrypted with the master password. This
500      * entry is invalid if the PDF was not decrypted.
501      *
502      * @return true if the pdf was decrypted with the master password.
503      *
504      * @deprecated use <code>getCurrentAccessPermission</code> instead
505      */

506     public boolean wasDecryptedWithOwnerPassword()
507     {
508         return false;
509     }
510
511     /**
512      * This will <b>mark</b> a document to be encrypted. The actual encryption
513      * will occur when the document is saved.
514      * This method is provided for compatibility reasons only. User should use
515      * the new security layer instead and the openProtection method especially.
516      *
517      * @param ownerPassword The owner password to encrypt the document.
518      * @param userPassword The user password to encrypt the document.
519      *
520      * @throws CryptographyException If an error occurs during encryption.
521      * @throws IOException If there is an error accessing the data.
522      *
523      */

524     public void encrypt( String JavaDoc ownerPassword, String JavaDoc userPassword )
525         throws CryptographyException, IOException JavaDoc
526     {
527         try
528         {
529             StandardProtectionPolicy policy =
530                 new StandardProtectionPolicy(ownerPassword, userPassword, new AccessPermission());
531             this.protect(policy);
532         }
533         catch(BadSecurityHandlerException e)
534         {
535             throw new CryptographyException(e);
536         }
537     }
538     
539     
540     /**
541      * The owner password that was passed into the encrypt method. You should
542      * never use this method. This will not longer be valid once encryption
543      * has occured.
544      *
545      * @return The owner password passed to the encrypt method.
546      *
547      * @deprecated Do not rely on this method anymore.
548      */

549     public String JavaDoc getOwnerPasswordForEncryption()
550     {
551         return null;
552     }
553     
554     /**
555      * The user password that was passed into the encrypt method. You should
556      * never use this method. This will not longer be valid once encryption
557      * has occured.
558      *
559      * @return The user password passed to the encrypt method.
560      *
561      * @deprecated Do not rely on this method anymore.
562      */

563     public String JavaDoc getUserPasswordForEncryption()
564     {
565         return null;
566     }
567     
568     /**
569      * Internal method do determine if the document will be encrypted when it is saved.
570      *
571      * @return True if encrypt has been called and the document
572      * has not been saved yet.
573      *
574      * @deprecated Do not rely on this method anymore. It is the responsibility of
575      * COSWriter to hold this state
576      */

577     public boolean willEncryptWhenSaving()
578     {
579         return false;
580     }
581     
582     /**
583      * This shoule only be called by the COSWriter after encryption has completed.
584      *
585      * @deprecated Do not rely on this method anymore. It is the responsability of
586      * COSWriter to hold this state.
587      */

588     public void clearWillEncryptWhenSaving()
589     {
590         //method is deprecated.
591
}
592     
593     /**
594      * This will load a document from a url.
595      *
596      * @param url The url to load the PDF from.
597      *
598      * @return The document that was loaded.
599      *
600      * @throws IOException If there is an error reading from the stream.
601      */

602     public static PDDocument load( URL JavaDoc url ) throws IOException JavaDoc
603     {
604         return load( url.openStream() );
605     }
606     
607     /**
608      * This will load a document from a url.
609      *
610      * @param url The url to load the PDF from.
611      * @param scratchFile A location to store temp PDFBox data for this document.
612      *
613      * @return The document that was loaded.
614      *
615      * @throws IOException If there is an error reading from the stream.
616      */

617     public static PDDocument load( URL JavaDoc url, RandomAccess scratchFile ) throws IOException JavaDoc
618     {
619         return load( url.openStream(), scratchFile );
620     }
621
622     /**
623      * This will load a document from a file.
624      *
625      * @param filename The name of the file to load.
626      *
627      * @return The document that was loaded.
628      *
629      * @throws IOException If there is an error reading from the stream.
630      */

631     public static PDDocument load( String JavaDoc filename ) throws IOException JavaDoc
632     {
633         return load( new FileInputStream JavaDoc( filename ) );
634     }
635     
636     /**
637      * This will load a document from a file.
638      *
639      * @param filename The name of the file to load.
640      * @param scratchFile A location to store temp PDFBox data for this document.
641      *
642      * @return The document that was loaded.
643      *
644      * @throws IOException If there is an error reading from the stream.
645      */

646     public static PDDocument load( String JavaDoc filename, RandomAccess scratchFile ) throws IOException JavaDoc
647     {
648         return load( new FileInputStream JavaDoc( filename ), scratchFile );
649     }
650
651     /**
652      * This will load a document from a file.
653      *
654      * @param file The name of the file to load.
655      *
656      * @return The document that was loaded.
657      *
658      * @throws IOException If there is an error reading from the stream.
659      */

660     public static PDDocument load( File JavaDoc file ) throws IOException JavaDoc
661     {
662         return load( new FileInputStream JavaDoc( file ) );
663     }
664     
665     /**
666      * This will load a document from a file.
667      *
668      * @param file The name of the file to load.
669      * @param scratchFile A location to store temp PDFBox data for this document.
670      *
671      * @return The document that was loaded.
672      *
673      * @throws IOException If there is an error reading from the stream.
674      */

675     public static PDDocument load( File JavaDoc file, RandomAccess scratchFile ) throws IOException JavaDoc
676     {
677         return load( new FileInputStream JavaDoc( file ) );
678     }
679
680     /**
681      * This will load a document from an input stream.
682      *
683      * @param input The stream that contains the document.
684      *
685      * @return The document that was loaded.
686      *
687      * @throws IOException If there is an error reading from the stream.
688      */

689     public static PDDocument load( InputStream JavaDoc input ) throws IOException JavaDoc
690     {
691         return load( input, null );
692     }
693     
694     /**
695      * This will load a document from an input stream.
696      *
697      * @param input The stream that contains the document.
698      * @param scratchFile A location to store temp PDFBox data for this document.
699      *
700      * @return The document that was loaded.
701      *
702      * @throws IOException If there is an error reading from the stream.
703      */

704     public static PDDocument load( InputStream JavaDoc input, RandomAccess scratchFile ) throws IOException JavaDoc
705     {
706         PDFParser parser = new PDFParser( new BufferedInputStream JavaDoc( input ), scratchFile );
707         parser.parse();
708         return parser.getPDDocument();
709     }
710
711     /**
712      * This will save this document to the filesystem.
713      *
714      * @param fileName The file to save as.
715      *
716      * @throws IOException If there is an error saving the document.
717      * @throws COSVisitorException If an error occurs while generating the data.
718      */

719     public void save( String JavaDoc fileName ) throws IOException JavaDoc, COSVisitorException
720     {
721         save( new FileOutputStream JavaDoc( fileName ) );
722     }
723
724     /**
725      * This will save the document to an output stream.
726      *
727      * @param output The stream to write to.
728      *
729      * @throws IOException If there is an error writing the document.
730      * @throws COSVisitorException If an error occurs while generating the data.
731      */

732     public void save( OutputStream JavaDoc output ) throws IOException JavaDoc, COSVisitorException
733     {
734         //update the count in case any pages have been added behind the scenes.
735
getDocumentCatalog().getPages().updateCount();
736         COSWriter writer = null;
737         try
738         {
739             writer = new COSWriter( output );
740             writer.write( this );
741             writer.close();
742         }
743         finally
744         {
745             if( writer != null )
746             {
747                 writer.close();
748             }
749         }
750     }
751
752     /**
753      * This will return the total page count of the PDF document. Note: This method
754      * is deprecated in favor of the getNumberOfPages method. The getNumberOfPages is
755      * a required interface method of the Pageable interface. This method will
756      * be removed in a future version of PDFBox!!
757      *
758      * @return The total number of pages in the PDF document.
759      * @deprecated Use the getNumberOfPages method instead!
760      */

761     public int getPageCount()
762     {
763         return getNumberOfPages();
764     }
765     
766     /**
767      * {@inheritDoc}
768      */

769     public int getNumberOfPages()
770     {
771         PDDocumentCatalog cat = getDocumentCatalog();
772         return (int)cat.getPages().getCount();
773     }
774     
775     /**
776      * {@inheritDoc}
777      */

778     public PageFormat JavaDoc getPageFormat(int pageIndex)
779     {
780         PDPage page = (PDPage)getDocumentCatalog().getAllPages().get( pageIndex );
781         PDRectangle mediaBox = page.findMediaBox();
782         PageFormat JavaDoc format = new PageFormat JavaDoc();
783         Paper JavaDoc paper = new Paper JavaDoc();
784         //hmm the imageable area might need to be the CropBox instead
785
//of the media box???
786
double width=mediaBox.getWidth();
787         double height=mediaBox.getHeight();
788         if( width > height )
789         {
790             format.setOrientation( PageFormat.LANDSCAPE );
791             width=mediaBox.getHeight();
792             height=mediaBox.getWidth();
793         }
794         paper.setImageableArea( 0,0,width,height);
795         paper.setSize( width, height );
796         format.setPaper( paper );
797         return format;
798     }
799     
800     /**
801      * {@inheritDoc}
802      */

803     public Printable JavaDoc getPrintable(int pageIndex)
804     {
805         return (Printable JavaDoc)getDocumentCatalog().getAllPages().get( pageIndex );
806     }
807     
808     /**
809      * This will send the PDF document to a printer. The printing functionality
810      * depends on the org.pdfbox.pdfviewer.PageDrawer functionality. The PageDrawer
811      * is a work in progress and some PDFs will print correctly and some will
812      * not. This is a convenience method to create the java.awt.print.PrinterJob.
813      * The PDDocument implements the java.awt.print.Pageable interface and
814      * PDPage implementes the java.awt.print.Printable interface, so advanced printing
815      * capabilities can be done by using those interfaces instead of this method.
816      *
817      * @throws PrinterException If there is an error while sending the PDF to
818      * the printer, or you do not have permissions to print this document.
819      */

820     public void print() throws PrinterException JavaDoc
821     {
822         
823         AccessPermission currentPermissions = this.getCurrentAccessPermission();
824         
825         if(!currentPermissions.canPrint())
826         {
827             throw new PrinterException JavaDoc( "You do not have permission to print this document." );
828         }
829         PrinterJob JavaDoc printJob = PrinterJob.getPrinterJob();
830         printJob.setPageable(this);
831         if( printJob.printDialog() )
832         {
833             printJob.print();
834         }
835     }
836     
837     /**
838      * This will send the PDF to the default printer without prompting the user
839      * for any printer settings.
840      *
841      * @see PDDocument#print()
842      *
843      * @throws PrinterException If there is an error while printing.
844      */

845     public void silentPrint() throws PrinterException JavaDoc
846     {
847         
848         AccessPermission currentPermissions = this.getCurrentAccessPermission();
849         
850         if(!currentPermissions.canPrint())
851         {
852             throw new PrinterException JavaDoc( "You do not have permission to print this document." );
853         }
854         PrinterJob JavaDoc printJob = PrinterJob.getPrinterJob();
855         printJob.setPageable(this);
856         printJob.print();
857     }
858     
859     /**
860      * This will close the underlying COSDocument object.
861      *
862      * @throws IOException If there is an error releasing resources.
863      */

864     public void close() throws IOException JavaDoc
865     {
866         document.close();
867     }
868     
869     
870     /**
871      * Protects the document with the protection policy pp. The document content will be really encrypted
872      * when it will be saved. This method only marks the document for encryption.
873      *
874      * @see org.pdfbox.pdmodel.encryption.StandardProtectionPolicy
875      * @see org.pdfbox.pdmodel.encryption.PublicKeyProtectionPolicy
876      *
877      * @param pp The protection policy.
878      *
879      * @throws BadSecurityHandlerException If there is an error during protection.
880      */

881     public void protect(ProtectionPolicy pp) throws BadSecurityHandlerException
882     {
883         SecurityHandler handler = SecurityHandlersManager.getInstance().getSecurityHandler(pp);
884         securityHandler = handler;
885     }
886     
887     /**
888      * Tries to decrypt the document in memory using the provided decryption material.
889      *
890      * @see org.pdfbox.pdmodel.encryption.StandardDecryptionMaterial
891      * @see org.pdfbox.pdmodel.encryption.PublicKeyDecryptionMaterial
892      *
893      * @param pm The decryption material (password or certificate).
894      *
895      * @throws BadSecurityHandlerException If there is an error during decryption.
896      * @throws IOException If there is an error reading cryptographic information.
897      * @throws CryptographyException If there is an error during decryption.
898      */

899     public void openProtection(DecryptionMaterial pm)
900         throws BadSecurityHandlerException, IOException JavaDoc, CryptographyException
901     {
902         PDEncryptionDictionary dict = this.getEncryptionDictionary();
903         if(dict.getFilter() != null)
904         {
905             SecurityHandler handler = SecurityHandlersManager.getInstance().getSecurityHandler(dict.getFilter());
906             securityHandler = handler;
907             handler.decryptDocument(this, pm);
908             document.dereferenceObjectStreams();
909         }
910         else
911         {
912             throw new RuntimeException JavaDoc("This document does not need to be decrypted");
913         }
914     }
915     
916     /**
917      * Returns the access permissions granted when the document was decrypted.
918      * If the document was not decrypted this method returns the access permission
919      * for a document owner (ie can do everything).
920      * The returned object is in read only mode so that permissions cannot be changed.
921      * Methods providing access to content should rely on this object to verify if the current
922      * user is allowed to proceed.
923      *
924      * @return the access permissions for the current user on the document.
925      */

926     
927     public AccessPermission getCurrentAccessPermission()
928     {
929         if(this.securityHandler == null)
930         {
931             return AccessPermission.getOwnerAccessPermission();
932         }
933         return securityHandler.getCurrentAccessPermission();
934     }
935     
936     /**
937      * Get the security handler that is used for document encryption.
938      *
939      * @return The handler used to encrypt/decrypt the document.
940      */

941     public SecurityHandler getSecurityHandler()
942     {
943         return securityHandler;
944     }
945 }
Popular Tags