1 31 package org.pdfbox.pdmodel; 32 33 import java.awt.print.PageFormat ; 34 import java.awt.print.Pageable ; 35 import java.awt.print.Paper ; 36 import java.awt.print.Printable ; 37 import java.awt.print.PrinterException ; 38 import java.awt.print.PrinterJob ; 39 import java.io.BufferedInputStream ; 40 import java.io.File ; 41 import java.io.FileInputStream ; 42 import java.io.FileOutputStream ; 43 import java.io.IOException ; 44 import java.io.InputStream ; 45 import java.io.OutputStream ; 46 import java.net.URL ; 47 import java.util.List ; 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 80 public class PDDocument implements Pageable 81 { 82 private COSDocument document; 83 84 88 89 93 private PDDocumentInformation documentInformation; 95 private PDDocumentCatalog documentCatalog; 96 97 private PDEncryptionDictionary encParameters = null; 101 102 106 108 109 112 private SecurityHandler securityHandler = null; 113 114 115 121 public PDDocument() throws IOException 122 { 123 document = new COSDocument(); 124 125 COSDictionary trailer = new COSDictionary(); 127 document.setTrailer( trailer ); 128 129 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 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 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 166 public boolean removePage( PDPage page ) 167 { 168 PDPageNode parent = page.getParent(); 169 boolean retval = parent.getKids().remove( page ); 170 if( retval ) 171 { 172 getDocumentCatalog().getPages().updateCount(); 175 } 176 return retval; 177 } 178 179 185 public boolean removePage( int pageNumber ) 186 { 187 boolean removed = false; 188 List 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 209 public PDPage importPage( PDPage page ) throws IOException 210 { 211 PDPage importedPage = new PDPage( new COSDictionary( page.getCOSDictionary() ) ); 212 InputStream is = null; 213 OutputStream 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 251 public PDDocument( COSDocument doc ) 252 { 253 document = doc; 254 } 255 256 261 public COSDocument getDocument() 262 { 263 return document; 264 } 265 266 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 292 public void setDocumentInformation( PDDocumentInformation info ) 293 { 294 documentInformation = info; 295 document.getTrailer().setItem( COSName.INFO, info.getDictionary() ); 296 } 297 298 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 327 public boolean isEncrypted() 328 { 329 return document.isEncrypted(); 330 } 331 332 343 public PDEncryptionDictionary getEncryptionDictionary() throws IOException 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 366 public void setEncryptionDictionary( PDEncryptionDictionary encDictionary ) throws IOException 367 { 368 encParameters = encDictionary; 369 } 370 371 384 public boolean isUserPassword( String password ) throws IOException , CryptographyException 385 { 386 return false; 387 420 } 421 422 435 public boolean isOwnerPassword( String password ) throws IOException , CryptographyException 436 { 437 return false; 438 471 } 472 473 484 public void decrypt( String password ) throws CryptographyException, IOException , 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 506 public boolean wasDecryptedWithOwnerPassword() 507 { 508 return false; 509 } 510 511 524 public void encrypt( String ownerPassword, String userPassword ) 525 throws CryptographyException, IOException 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 549 public String getOwnerPasswordForEncryption() 550 { 551 return null; 552 } 553 554 563 public String getUserPasswordForEncryption() 564 { 565 return null; 566 } 567 568 577 public boolean willEncryptWhenSaving() 578 { 579 return false; 580 } 581 582 588 public void clearWillEncryptWhenSaving() 589 { 590 } 592 593 602 public static PDDocument load( URL url ) throws IOException 603 { 604 return load( url.openStream() ); 605 } 606 607 617 public static PDDocument load( URL url, RandomAccess scratchFile ) throws IOException 618 { 619 return load( url.openStream(), scratchFile ); 620 } 621 622 631 public static PDDocument load( String filename ) throws IOException 632 { 633 return load( new FileInputStream ( filename ) ); 634 } 635 636 646 public static PDDocument load( String filename, RandomAccess scratchFile ) throws IOException 647 { 648 return load( new FileInputStream ( filename ), scratchFile ); 649 } 650 651 660 public static PDDocument load( File file ) throws IOException 661 { 662 return load( new FileInputStream ( file ) ); 663 } 664 665 675 public static PDDocument load( File file, RandomAccess scratchFile ) throws IOException 676 { 677 return load( new FileInputStream ( file ) ); 678 } 679 680 689 public static PDDocument load( InputStream input ) throws IOException 690 { 691 return load( input, null ); 692 } 693 694 704 public static PDDocument load( InputStream input, RandomAccess scratchFile ) throws IOException 705 { 706 PDFParser parser = new PDFParser( new BufferedInputStream ( input ), scratchFile ); 707 parser.parse(); 708 return parser.getPDDocument(); 709 } 710 711 719 public void save( String fileName ) throws IOException , COSVisitorException 720 { 721 save( new FileOutputStream ( fileName ) ); 722 } 723 724 732 public void save( OutputStream output ) throws IOException , COSVisitorException 733 { 734 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 761 public int getPageCount() 762 { 763 return getNumberOfPages(); 764 } 765 766 769 public int getNumberOfPages() 770 { 771 PDDocumentCatalog cat = getDocumentCatalog(); 772 return (int)cat.getPages().getCount(); 773 } 774 775 778 public PageFormat getPageFormat(int pageIndex) 779 { 780 PDPage page = (PDPage)getDocumentCatalog().getAllPages().get( pageIndex ); 781 PDRectangle mediaBox = page.findMediaBox(); 782 PageFormat format = new PageFormat (); 783 Paper paper = new Paper (); 784 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 803 public Printable getPrintable(int pageIndex) 804 { 805 return (Printable )getDocumentCatalog().getAllPages().get( pageIndex ); 806 } 807 808 820 public void print() throws PrinterException 821 { 822 823 AccessPermission currentPermissions = this.getCurrentAccessPermission(); 824 825 if(!currentPermissions.canPrint()) 826 { 827 throw new PrinterException ( "You do not have permission to print this document." ); 828 } 829 PrinterJob printJob = PrinterJob.getPrinterJob(); 830 printJob.setPageable(this); 831 if( printJob.printDialog() ) 832 { 833 printJob.print(); 834 } 835 } 836 837 845 public void silentPrint() throws PrinterException 846 { 847 848 AccessPermission currentPermissions = this.getCurrentAccessPermission(); 849 850 if(!currentPermissions.canPrint()) 851 { 852 throw new PrinterException ( "You do not have permission to print this document." ); 853 } 854 PrinterJob printJob = PrinterJob.getPrinterJob(); 855 printJob.setPageable(this); 856 printJob.print(); 857 } 858 859 864 public void close() throws IOException 865 { 866 document.close(); 867 } 868 869 870 881 public void protect(ProtectionPolicy pp) throws BadSecurityHandlerException 882 { 883 SecurityHandler handler = SecurityHandlersManager.getInstance().getSecurityHandler(pp); 884 securityHandler = handler; 885 } 886 887 899 public void openProtection(DecryptionMaterial pm) 900 throws BadSecurityHandlerException, IOException , 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 ("This document does not need to be decrypted"); 913 } 914 } 915 916 926 927 public AccessPermission getCurrentAccessPermission() 928 { 929 if(this.securityHandler == null) 930 { 931 return AccessPermission.getOwnerAccessPermission(); 932 } 933 return securityHandler.getCurrentAccessPermission(); 934 } 935 936 941 public SecurityHandler getSecurityHandler() 942 { 943 return securityHandler; 944 } 945 } | Popular Tags |