1 /* 2 * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package sun.print; 27 28 import java.awt.Dimension; 29 import java.awt.Frame; 30 import java.awt.Graphics; 31 import java.awt.Graphics2D; 32 import java.awt.PrintJob; 33 import java.awt.JobAttributes; 34 import java.awt.JobAttributes.*; 35 import java.awt.PageAttributes; 36 import java.awt.PageAttributes.*; 37 38 import java.awt.print.PageFormat; 39 import java.awt.print.Paper; 40 import java.awt.print.Printable; 41 import java.awt.print.PrinterException; 42 import java.awt.print.PrinterJob; 43 44 import java.io.File; 45 import java.io.FilePermission; 46 import java.io.IOException; 47 48 import java.net.URI; 49 import java.net.URISyntaxException; 50 51 import java.util.ArrayList; 52 import java.util.Properties; 53 54 import javax.print.PrintService; 55 import javax.print.attribute.HashPrintRequestAttributeSet; 56 import javax.print.attribute.PrintRequestAttributeSet; 57 import javax.print.attribute.ResolutionSyntax; 58 import javax.print.attribute.Size2DSyntax; 59 import javax.print.attribute.standard.Chromaticity; 60 import javax.print.attribute.standard.Copies; 61 import javax.print.attribute.standard.Destination; 62 import javax.print.attribute.standard.DialogTypeSelection; 63 import javax.print.attribute.standard.JobName; 64 import javax.print.attribute.standard.MediaSize; 65 import javax.print.attribute.standard.PrintQuality; 66 import javax.print.attribute.standard.PrinterResolution; 67 import javax.print.attribute.standard.SheetCollate; 68 import javax.print.attribute.standard.Sides; 69 import javax.print.attribute.standard.Media; 70 import javax.print.attribute.standard.OrientationRequested; 71 import javax.print.attribute.standard.MediaSizeName; 72 import javax.print.attribute.standard.PageRanges; 73 74 import sun.print.SunPageSelection; 75 import sun.print.SunMinMaxPage; 76 77 /** 78 * A class which initiates and executes a print job using 79 * the underlying PrinterJob graphics conversions. 80 * 81 * @see Toolkit#getPrintJob 82 * 83 */ 84 public class PrintJob2D extends PrintJob implements Printable, Runnable { 85 86 private static final MediaType SIZES[] = { 87 MediaType.ISO_4A0, MediaType.ISO_2A0, MediaType.ISO_A0, 88 MediaType.ISO_A1, MediaType.ISO_A2, MediaType.ISO_A3, 89 MediaType.ISO_A4, MediaType.ISO_A5, MediaType.ISO_A6, 90 MediaType.ISO_A7, MediaType.ISO_A8, MediaType.ISO_A9, 91 MediaType.ISO_A10, MediaType.ISO_B0, MediaType.ISO_B1, 92 MediaType.ISO_B2, MediaType.ISO_B3, MediaType.ISO_B4, 93 MediaType.ISO_B5, MediaType.ISO_B6, MediaType.ISO_B7, 94 MediaType.ISO_B8, MediaType.ISO_B9, MediaType.ISO_B10, 95 MediaType.JIS_B0, MediaType.JIS_B1, MediaType.JIS_B2, 96 MediaType.JIS_B3, MediaType.JIS_B4, MediaType.JIS_B5, 97 MediaType.JIS_B6, MediaType.JIS_B7, MediaType.JIS_B8, 98 MediaType.JIS_B9, MediaType.JIS_B10, MediaType.ISO_C0, 99 MediaType.ISO_C1, MediaType.ISO_C2, MediaType.ISO_C3, 100 MediaType.ISO_C4, MediaType.ISO_C5, MediaType.ISO_C6, 101 MediaType.ISO_C7, MediaType.ISO_C8, MediaType.ISO_C9, 102 MediaType.ISO_C10, MediaType.ISO_DESIGNATED_LONG, 103 MediaType.EXECUTIVE, MediaType.FOLIO, MediaType.INVOICE, 104 MediaType.LEDGER, MediaType.NA_LETTER, MediaType.NA_LEGAL, 105 MediaType.QUARTO, MediaType.A, MediaType.B, 106 MediaType.C, MediaType.D, MediaType.E, 107 MediaType.NA_10X15_ENVELOPE, MediaType.NA_10X14_ENVELOPE, 108 MediaType.NA_10X13_ENVELOPE, MediaType.NA_9X12_ENVELOPE, 109 MediaType.NA_9X11_ENVELOPE, MediaType.NA_7X9_ENVELOPE, 110 MediaType.NA_6X9_ENVELOPE, MediaType.NA_NUMBER_9_ENVELOPE, 111 MediaType.NA_NUMBER_10_ENVELOPE, MediaType.NA_NUMBER_11_ENVELOPE, 112 MediaType.NA_NUMBER_12_ENVELOPE, MediaType.NA_NUMBER_14_ENVELOPE, 113 MediaType.INVITE_ENVELOPE, MediaType.ITALY_ENVELOPE, 114 MediaType.MONARCH_ENVELOPE, MediaType.PERSONAL_ENVELOPE 115 }; 116 117 /* This array maps the above array to the objects used by the 118 * javax.print APIs 119 */ 120 private static final MediaSizeName JAVAXSIZES[] = { 121 null, null, MediaSizeName.ISO_A0, 122 MediaSizeName.ISO_A1, MediaSizeName.ISO_A2, MediaSizeName.ISO_A3, 123 MediaSizeName.ISO_A4, MediaSizeName.ISO_A5, MediaSizeName.ISO_A6, 124 MediaSizeName.ISO_A7, MediaSizeName.ISO_A8, MediaSizeName.ISO_A9, 125 MediaSizeName.ISO_A10, MediaSizeName.ISO_B0, MediaSizeName.ISO_B1, 126 MediaSizeName.ISO_B2, MediaSizeName.ISO_B3, MediaSizeName.ISO_B4, 127 MediaSizeName.ISO_B5, MediaSizeName.ISO_B6, MediaSizeName.ISO_B7, 128 MediaSizeName.ISO_B8, MediaSizeName.ISO_B9, MediaSizeName.ISO_B10, 129 MediaSizeName.JIS_B0, MediaSizeName.JIS_B1, MediaSizeName.JIS_B2, 130 MediaSizeName.JIS_B3, MediaSizeName.JIS_B4, MediaSizeName.JIS_B5, 131 MediaSizeName.JIS_B6, MediaSizeName.JIS_B7, MediaSizeName.JIS_B8, 132 MediaSizeName.JIS_B9, MediaSizeName.JIS_B10, MediaSizeName.ISO_C0, 133 MediaSizeName.ISO_C1, MediaSizeName.ISO_C2, MediaSizeName.ISO_C3, 134 MediaSizeName.ISO_C4, MediaSizeName.ISO_C5, MediaSizeName.ISO_C6, 135 null, null, null, null, 136 MediaSizeName.ISO_DESIGNATED_LONG, MediaSizeName.EXECUTIVE, 137 MediaSizeName.FOLIO, MediaSizeName.INVOICE, MediaSizeName.LEDGER, 138 MediaSizeName.NA_LETTER, MediaSizeName.NA_LEGAL, 139 MediaSizeName.QUARTO, MediaSizeName.A, MediaSizeName.B, 140 MediaSizeName.C, MediaSizeName.D, MediaSizeName.E, 141 MediaSizeName.NA_10X15_ENVELOPE, MediaSizeName.NA_10X14_ENVELOPE, 142 MediaSizeName.NA_10X13_ENVELOPE, MediaSizeName.NA_9X12_ENVELOPE, 143 MediaSizeName.NA_9X11_ENVELOPE, MediaSizeName.NA_7X9_ENVELOPE, 144 MediaSizeName.NA_6X9_ENVELOPE, 145 MediaSizeName.NA_NUMBER_9_ENVELOPE, 146 MediaSizeName.NA_NUMBER_10_ENVELOPE, 147 MediaSizeName.NA_NUMBER_11_ENVELOPE, 148 MediaSizeName.NA_NUMBER_12_ENVELOPE, 149 MediaSizeName.NA_NUMBER_14_ENVELOPE, 150 null, MediaSizeName.ITALY_ENVELOPE, 151 MediaSizeName.MONARCH_ENVELOPE, MediaSizeName.PERSONAL_ENVELOPE, 152 }; 153 154 155 // widths and lengths in PostScript points (1/72 in.) 156 private static final int WIDTHS[] = { 157 /*iso-4a0*/ 4768, /*iso-2a0*/ 3370, /*iso-a0*/ 2384, /*iso-a1*/ 1684, 158 /*iso-a2*/ 1191, /*iso-a3*/ 842, /*iso-a4*/ 595, /*iso-a5*/ 420, 159 /*iso-a6*/ 298, /*iso-a7*/ 210, /*iso-a8*/ 147, /*iso-a9*/ 105, 160 /*iso-a10*/ 74, /*iso-b0*/ 2835, /*iso-b1*/ 2004, /*iso-b2*/ 1417, 161 /*iso-b3*/ 1001, /*iso-b4*/ 709, /*iso-b5*/ 499, /*iso-b6*/ 354, 162 /*iso-b7*/ 249, /*iso-b8*/ 176, /*iso-b9*/ 125, /*iso-b10*/ 88, 163 /*jis-b0*/ 2920, /*jis-b1*/ 2064, /*jis-b2*/ 1460, /*jis-b3*/ 1032, 164 /*jis-b4*/ 729, /*jis-b5*/ 516, /*jis-b6*/ 363, /*jis-b7*/ 258, 165 /*jis-b8*/ 181, /*jis-b9*/ 128, /*jis-b10*/ 91, /*iso-c0*/ 2599, 166 /*iso-c1*/ 1837, /*iso-c2*/ 1298, /*iso-c3*/ 918, /*iso-c4*/ 649, 167 /*iso-c5*/ 459, /*iso-c6*/ 323, /*iso-c7*/ 230, /*iso-c8*/ 162, 168 /*iso-c9*/ 113, /*iso-c10*/ 79, /*iso-designated-long*/ 312, 169 /*executive*/ 522, /*folio*/ 612, /*invoice*/ 396, /*ledger*/ 792, 170 /*na-letter*/ 612, /*na-legal*/ 612, /*quarto*/ 609, /*a*/ 612, 171 /*b*/ 792, /*c*/ 1224, /*d*/ 1584, /*e*/ 2448, 172 /*na-10x15-envelope*/ 720, /*na-10x14-envelope*/ 720, 173 /*na-10x13-envelope*/ 720, /*na-9x12-envelope*/ 648, 174 /*na-9x11-envelope*/ 648, /*na-7x9-envelope*/ 504, 175 /*na-6x9-envelope*/ 432, /*na-number-9-envelope*/ 279, 176 /*na-number-10-envelope*/ 297, /*na-number-11-envelope*/ 324, 177 /*na-number-12-envelope*/ 342, /*na-number-14-envelope*/ 360, 178 /*invite-envelope*/ 624, /*italy-envelope*/ 312, 179 /*monarch-envelope*/ 279, /*personal-envelope*/ 261 180 }; 181 private static final int LENGTHS[] = { 182 /*iso-4a0*/ 6741, /*iso-2a0*/ 4768, /*iso-a0*/ 3370, /*iso-a1*/ 2384, 183 /*iso-a2*/ 1684, /*iso-a3*/ 1191, /*iso-a4*/ 842, /*iso-a5*/ 595, 184 /*iso-a6*/ 420, /*iso-a7*/ 298, /*iso-a8*/ 210, /*iso-a9*/ 147, 185 /*iso-a10*/ 105, /*iso-b0*/ 4008, /*iso-b1*/ 2835, /*iso-b2*/ 2004, 186 /*iso-b3*/ 1417, /*iso-b4*/ 1001, /*iso-b5*/ 729, /*iso-b6*/ 499, 187 /*iso-b7*/ 354, /*iso-b8*/ 249, /*iso-b9*/ 176, /*iso-b10*/ 125, 188 /*jis-b0*/ 4127, /*jis-b1*/ 2920, /*jis-b2*/ 2064, /*jis-b3*/ 1460, 189 /*jis-b4*/ 1032, /*jis-b5*/ 729, /*jis-b6*/ 516, /*jis-b7*/ 363, 190 /*jis-b8*/ 258, /*jis-b9*/ 181, /*jis-b10*/ 128, /*iso-c0*/ 3677, 191 /*iso-c1*/ 2599, /*iso-c2*/ 1837, /*iso-c3*/ 1298, /*iso-c4*/ 918, 192 /*iso-c5*/ 649, /*iso-c6*/ 459, /*iso-c7*/ 323, /*iso-c8*/ 230, 193 /*iso-c9*/ 162, /*iso-c10*/ 113, /*iso-designated-long*/ 624, 194 /*executive*/ 756, /*folio*/ 936, /*invoice*/ 612, /*ledger*/ 1224, 195 /*na-letter*/ 792, /*na-legal*/ 1008, /*quarto*/ 780, /*a*/ 792, 196 /*b*/ 1224, /*c*/ 1584, /*d*/ 2448, /*e*/ 3168, 197 /*na-10x15-envelope*/ 1080, /*na-10x14-envelope*/ 1008, 198 /*na-10x13-envelope*/ 936, /*na-9x12-envelope*/ 864, 199 /*na-9x11-envelope*/ 792, /*na-7x9-envelope*/ 648, 200 /*na-6x9-envelope*/ 648, /*na-number-9-envelope*/ 639, 201 /*na-number-10-envelope*/ 684, /*na-number-11-envelope*/ 747, 202 /*na-number-12-envelope*/ 792, /*na-number-14-envelope*/ 828, 203 /*invite-envelope*/ 624, /*italy-envelope*/ 652, 204 /*monarch-envelope*/ 540, /*personal-envelope*/ 468 205 }; 206 207 208 private Frame frame; 209 private String docTitle = ""; 210 private JobAttributes jobAttributes; 211 private PageAttributes pageAttributes; 212 private PrintRequestAttributeSet attributes; 213 214 /* 215 * Displays the native or cross-platform dialog and allows the 216 * user to update job & page attributes 217 */ 218 219 /** 220 * The PrinterJob being uses to implement the PrintJob. 221 */ 222 private PrinterJob printerJob; 223 224 /** 225 * The size of the page being used for the PrintJob. 226 */ 227 private PageFormat pageFormat; 228 229 /** 230 * The PrinterJob and the application run on different 231 * threads and communicate through a pair of message 232 * queues. This queue is the list of Graphics that 233 * the PrinterJob has requested rendering for, but 234 * for which the application has not yet called getGraphics(). 235 * In practice the length of this message queue is always 236 * 0 or 1. 237 */ 238 private MessageQ graphicsToBeDrawn = new MessageQ("tobedrawn"); 239 240 /** 241 * Used to communicate between the application's thread 242 * and the PrinterJob's thread this message queue holds 243 * the list of Graphics into which the application has 244 * finished drawing, but that have not yet been returned 245 * to the PrinterJob thread. Again, in practice, the 246 * length of this message queue is always 0 or 1. 247 */ 248 private MessageQ graphicsDrawn = new MessageQ("drawn"); 249 250 /** 251 * The last Graphics returned to the application via 252 * getGraphics. This is the Graphics into which the 253 * application is currently drawing. 254 */ 255 private Graphics2D currentGraphics; 256 257 /** 258 * The zero based index of the page currently being rendered 259 * by the application. 260 */ 261 private int pageIndex = -1; 262 263 // The following Strings are maintained for backward-compatibility with 264 // Properties based print control. 265 private final static String DEST_PROP = "awt.print.destination"; 266 private final static String PRINTER = "printer"; 267 private final static String FILE = "file"; 268 269 private final static String PRINTER_PROP = "awt.print.printer"; 270 271 private final static String FILENAME_PROP = "awt.print.fileName"; 272 273 private final static String NUMCOPIES_PROP = "awt.print.numCopies"; 274 275 private final static String OPTIONS_PROP = "awt.print.options"; 276 277 private final static String ORIENT_PROP = "awt.print.orientation"; 278 private final static String PORTRAIT = "portrait"; 279 private final static String LANDSCAPE = "landscape"; 280 281 private final static String PAPERSIZE_PROP = "awt.print.paperSize"; 282 private final static String LETTER = "letter"; 283 private final static String LEGAL = "legal"; 284 private final static String EXECUTIVE = "executive"; 285 private final static String A4 = "a4"; 286 287 private Properties props; 288 289 private String options = ""; // REMIND: needs implementation 290 291 /** 292 * The thread on which PrinterJob is running. 293 * This is different than the applications thread. 294 */ 295 private Thread printerJobThread; 296 297 public PrintJob2D(Frame frame, String doctitle, 298 final Properties props) { 299 this.props = props; 300 this.jobAttributes = new JobAttributes(); 301 this.pageAttributes = new PageAttributes(); 302 translateInputProps(); 303 initPrintJob2D(frame, doctitle, 304 this.jobAttributes, this.pageAttributes); 305 } 306 307 public PrintJob2D(Frame frame, String doctitle, 308 JobAttributes jobAttributes, 309 PageAttributes pageAttributes) { 310 initPrintJob2D(frame, doctitle, jobAttributes, pageAttributes); 311 } 312 313 private void initPrintJob2D(Frame frame, String doctitle, 314 JobAttributes jobAttributes, 315 PageAttributes pageAttributes) { 316 317 SecurityManager security = System.getSecurityManager(); 318 if (security != null) { 319 security.checkPrintJobAccess(); 320 } 321 322 if (frame == null && 323 (jobAttributes == null || 324 jobAttributes.getDialog() == DialogType.NATIVE)) { 325 throw new NullPointerException("Frame must not be null"); 326 } 327 this.frame = frame; 328 329 this.docTitle = (doctitle == null) ? "" : doctitle; 330 this.jobAttributes = (jobAttributes != null) 331 ? jobAttributes : new JobAttributes(); 332 this.pageAttributes = (pageAttributes != null) 333 ? pageAttributes : new PageAttributes(); 334 335 // Currently, we always reduce page ranges to xxx or xxx-xxx 336 int[][] pageRanges = this.jobAttributes.getPageRanges(); 337 int first = pageRanges[0][0]; 338 int last = pageRanges[pageRanges.length - 1][1]; 339 this.jobAttributes.setPageRanges(new int[][] { 340 new int[] { first, last } 341 }); 342 this.jobAttributes.setToPage(last); 343 this.jobAttributes.setFromPage(first); 344 345 346 // Verify that the cross feed and feed resolutions are the same 347 int[] res = this.pageAttributes.getPrinterResolution(); 348 if (res[0] != res[1]) { 349 throw new IllegalArgumentException("Differing cross feed and feed"+ 350 " resolutions not supported."); 351 } 352 353 // Verify that the app has access to the file system 354 DestinationType dest= this.jobAttributes.getDestination(); 355 if (dest == DestinationType.FILE) { 356 throwPrintToFile(); 357 358 // check if given filename is valid 359 String destStr = jobAttributes.getFileName(); 360 if ((destStr != null) && 361 (jobAttributes.getDialog() == JobAttributes.DialogType.NONE)) { 362 363 File f = new File(destStr); 364 try { 365 // check if this is a new file and if filename chars are valid 366 // createNewFile returns false if file exists 367 if (f.createNewFile()) { 368 f.delete(); 369 } 370 } catch (IOException ioe) { 371 throw new IllegalArgumentException("Cannot write to file:"+ 372 destStr); 373 } catch (SecurityException se) { 374 //There is already file read/write access so at this point 375 // only delete access is denied. Just ignore it because in 376 // most cases the file created in createNewFile gets overwritten 377 // anyway. 378 } 379 380 File pFile = f.getParentFile(); 381 if ((f.exists() && 382 (!f.isFile() || !f.canWrite())) || 383 ((pFile != null) && 384 (!pFile.exists() || (pFile.exists() && !pFile.canWrite())))) { 385 throw new IllegalArgumentException("Cannot write to file:"+ 386 destStr); 387 } 388 } 389 } 390 } 391 392 public boolean printDialog() { 393 394 boolean proceedWithPrint = false; 395 396 printerJob = PrinterJob.getPrinterJob(); 397 if (printerJob == null) { 398 return false; 399 } 400 DialogType d = this.jobAttributes.getDialog(); 401 PrintService pServ = printerJob.getPrintService(); 402 if ((pServ == null) && (d == DialogType.NONE)){ 403 return false; 404 } 405 copyAttributes(pServ); 406 407 DefaultSelectionType select = 408 this.jobAttributes.getDefaultSelection(); 409 if (select == DefaultSelectionType.RANGE) { 410 attributes.add(SunPageSelection.RANGE); 411 } else if (select == DefaultSelectionType.SELECTION) { 412 attributes.add(SunPageSelection.SELECTION); 413 } else { 414 attributes.add(SunPageSelection.ALL); 415 } 416 417 if (frame != null) { 418 attributes.add(new DialogOwner(frame)); 419 } 420 421 if ( d == DialogType.NONE) { 422 proceedWithPrint = true; 423 } else { 424 if (d == DialogType.NATIVE) { 425 attributes.add(DialogTypeSelection.NATIVE); 426 } else { // (d == DialogType.COMMON) 427 attributes.add(DialogTypeSelection.COMMON); 428 } 429 if (proceedWithPrint = printerJob.printDialog(attributes)) { 430 if (pServ == null) { 431 // Windows gives an option to install a service 432 // when it detects there are no printers so 433 // we make sure we get the updated print service. 434 pServ = printerJob.getPrintService(); 435 if (pServ == null) { 436 return false; 437 } 438 } 439 updateAttributes(); 440 translateOutputProps(); 441 } 442 } 443 444 if (proceedWithPrint) { 445 446 JobName jname = (JobName)attributes.get(JobName.class); 447 if (jname != null) { 448 printerJob.setJobName(jname.toString()); 449 } 450 451 pageFormat = new PageFormat(); 452 453 Media media = (Media)attributes.get(Media.class); 454 MediaSize mediaSize = null; 455 if (media != null && media instanceof MediaSizeName) { 456 mediaSize = MediaSize.getMediaSizeForName((MediaSizeName)media); 457 } 458 459 Paper p = pageFormat.getPaper(); 460 if (mediaSize != null) { 461 p.setSize(mediaSize.getX(MediaSize.INCH)*72.0, 462 mediaSize.getY(MediaSize.INCH)*72.0); 463 } 464 465 if (pageAttributes.getOrigin()==OriginType.PRINTABLE) { 466 // AWT uses 1/4" borders by default 467 p.setImageableArea(18.0, 18.0, 468 p.getWidth()-36.0, 469 p.getHeight()-36.0); 470 } else { 471 p.setImageableArea(0.0,0.0,p.getWidth(),p.getHeight()); 472 } 473 474 pageFormat.setPaper(p); 475 476 OrientationRequested orient = 477 (OrientationRequested)attributes.get(OrientationRequested.class); 478 if (orient!= null && 479 orient == OrientationRequested.REVERSE_LANDSCAPE) { 480 pageFormat.setOrientation(PageFormat.REVERSE_LANDSCAPE); 481 } else if (orient == OrientationRequested.LANDSCAPE) { 482 pageFormat.setOrientation(PageFormat.LANDSCAPE); 483 } else { 484 pageFormat.setOrientation(PageFormat.PORTRAIT); 485 } 486 487 printerJob.setPrintable(this, pageFormat); 488 489 } 490 491 return proceedWithPrint; 492 } 493 494 private void updateAttributes() { 495 Copies c = (Copies)attributes.get(Copies.class); 496 jobAttributes.setCopies(c.getValue()); 497 498 SunPageSelection sel = 499 (SunPageSelection)attributes.get(SunPageSelection.class); 500 if (sel == SunPageSelection.RANGE) { 501 jobAttributes.setDefaultSelection(DefaultSelectionType.RANGE); 502 } else if (sel == SunPageSelection.SELECTION) { 503 jobAttributes.setDefaultSelection(DefaultSelectionType.SELECTION); 504 } else { 505 jobAttributes.setDefaultSelection(DefaultSelectionType.ALL); 506 } 507 508 Destination dest = (Destination)attributes.get(Destination.class); 509 if (dest != null) { 510 jobAttributes.setDestination(DestinationType.FILE); 511 jobAttributes.setFileName(dest.getURI().getPath()); 512 } else { 513 jobAttributes.setDestination(DestinationType.PRINTER); 514 } 515 516 PrintService serv = printerJob.getPrintService(); 517 if (serv != null) { 518 jobAttributes.setPrinter(serv.getName()); 519 } 520 521 PageRanges range = (PageRanges)attributes.get(PageRanges.class); 522 int[][] members = range.getMembers(); 523 jobAttributes.setPageRanges(members); 524 525 SheetCollate collation = 526 (SheetCollate)attributes.get(SheetCollate.class); 527 if (collation == SheetCollate.COLLATED) { 528 jobAttributes.setMultipleDocumentHandling( 529 MultipleDocumentHandlingType.SEPARATE_DOCUMENTS_COLLATED_COPIES); 530 } else { 531 jobAttributes.setMultipleDocumentHandling( 532 MultipleDocumentHandlingType.SEPARATE_DOCUMENTS_UNCOLLATED_COPIES); 533 } 534 535 Sides sides = (Sides)attributes.get(Sides.class); 536 if (sides == Sides.TWO_SIDED_LONG_EDGE) { 537 jobAttributes.setSides(SidesType.TWO_SIDED_LONG_EDGE); 538 } else if (sides == Sides.TWO_SIDED_SHORT_EDGE) { 539 jobAttributes.setSides(SidesType.TWO_SIDED_SHORT_EDGE); 540 } else { 541 jobAttributes.setSides(SidesType.ONE_SIDED); 542 } 543 544 // PageAttributes 545 546 Chromaticity color = 547 (Chromaticity)attributes.get(Chromaticity.class); 548 if (color == Chromaticity.COLOR) { 549 pageAttributes.setColor(ColorType.COLOR); 550 } else { 551 pageAttributes.setColor(ColorType.MONOCHROME); 552 } 553 554 OrientationRequested orient = 555 (OrientationRequested)attributes.get(OrientationRequested.class); 556 if (orient == OrientationRequested.LANDSCAPE) { 557 pageAttributes.setOrientationRequested( 558 OrientationRequestedType.LANDSCAPE); 559 } else { 560 pageAttributes.setOrientationRequested( 561 OrientationRequestedType.PORTRAIT); 562 } 563 564 PrintQuality qual = (PrintQuality)attributes.get(PrintQuality.class); 565 if (qual == PrintQuality.DRAFT) { 566 pageAttributes.setPrintQuality(PrintQualityType.DRAFT); 567 } else if (qual == PrintQuality.HIGH) { 568 pageAttributes.setPrintQuality(PrintQualityType.HIGH); 569 } else { // NORMAL 570 pageAttributes.setPrintQuality(PrintQualityType.NORMAL); 571 } 572 573 Media msn = (Media)attributes.get(Media.class); 574 if (msn != null && msn instanceof MediaSizeName) { 575 MediaType mType = unMapMedia((MediaSizeName)msn); 576 577 if (mType != null) { 578 pageAttributes.setMedia(mType); 579 } 580 } 581 debugPrintAttributes(false, false); 582 } 583 584 private void debugPrintAttributes(boolean ja, boolean pa ) { 585 if (ja) { 586 System.out.println("new Attributes\ncopies = "+ 587 jobAttributes.getCopies()+ 588 "\nselection = "+ 589 jobAttributes.getDefaultSelection()+ 590 "\ndest "+jobAttributes.getDestination()+ 591 "\nfile "+jobAttributes.getFileName()+ 592 "\nfromPage "+jobAttributes.getFromPage()+ 593 "\ntoPage "+jobAttributes.getToPage()+ 594 "\ncollation "+ 595 jobAttributes.getMultipleDocumentHandling()+ 596 "\nPrinter "+jobAttributes.getPrinter()+ 597 "\nSides2 "+jobAttributes.getSides() 598 ); 599 } 600 601 if (pa) { 602 System.out.println("new Attributes\ncolor = "+ 603 pageAttributes.getColor()+ 604 "\norientation = "+ 605 pageAttributes.getOrientationRequested()+ 606 "\nquality "+pageAttributes.getPrintQuality()+ 607 "\nMedia2 "+pageAttributes.getMedia() 608 ); 609 } 610 } 611 612 613 /* From JobAttributes we will copy job name and duplex printing 614 * and destination. 615 * The majority of the rest of the attributes are reflected 616 * attributes. 617 * 618 * From PageAttributes we copy color, media size, orientation, 619 * origin type, resolution and print quality. 620 * We use the media, orientation in creating the page format, and 621 * the origin type to set its imageable area. 622 * 623 * REMIND: Interpretation of resolution, additional media sizes. 624 */ 625 private void copyAttributes(PrintService printServ) { 626 627 attributes = new HashPrintRequestAttributeSet(); 628 attributes.add(new JobName(docTitle, null)); 629 PrintService pServ = printServ; 630 631 String printerName = jobAttributes.getPrinter(); 632 if (printerName != null && printerName != "" 633 && !printerName.equals(pServ.getName())) { 634 635 // Search for the given printerName in the list of PrintServices 636 PrintService []services = PrinterJob.lookupPrintServices(); 637 try { 638 for (int i=0; i<services.length; i++) { 639 if (printerName.equals(services[i].getName())) { 640 printerJob.setPrintService(services[i]); 641 pServ = services[i]; 642 break; 643 } 644 } 645 } catch (PrinterException pe) { 646 } 647 } 648 649 DestinationType dest = jobAttributes.getDestination(); 650 if (dest == DestinationType.FILE && 651 pServ.isAttributeCategorySupported(Destination.class)) { 652 653 String fileName = jobAttributes.getFileName(); 654 655 Destination defaultDest; 656 if (fileName == null && (defaultDest = (Destination)pServ. 657 getDefaultAttributeValue(Destination.class)) != null) { 658 attributes.add(defaultDest); 659 } else { 660 URI uri = null; 661 try { 662 if (fileName != null) { 663 if (fileName.equals("")) { 664 fileName = "."; 665 } 666 } else { 667 // defaultDest should not be null. The following code 668 // is only added to safeguard against a possible 669 // buggy implementation of a PrintService having a 670 // null default Destination. 671 fileName = "out.prn"; 672 } 673 uri = (new File(fileName)).toURI(); 674 } catch (SecurityException se) { 675 try { 676 // '\\' file separator is illegal character in opaque 677 // part and causes URISyntaxException, so we replace 678 // it with '/' 679 fileName = fileName.replace('\\', '/'); 680 uri = new URI("file:"+fileName); 681 } catch (URISyntaxException e) { 682 } 683 } 684 if (uri != null) { 685 attributes.add(new Destination(uri)); 686 } 687 } 688 } 689 attributes.add(new SunMinMaxPage(jobAttributes.getMinPage(), 690 jobAttributes.getMaxPage())); 691 SidesType sType = jobAttributes.getSides(); 692 if (sType == SidesType.TWO_SIDED_LONG_EDGE) { 693 attributes.add(Sides.TWO_SIDED_LONG_EDGE); 694 } else if (sType == SidesType.TWO_SIDED_SHORT_EDGE) { 695 attributes.add(Sides.TWO_SIDED_SHORT_EDGE); 696 } else if (sType == SidesType.ONE_SIDED) { 697 attributes.add(Sides.ONE_SIDED); 698 } 699 700 MultipleDocumentHandlingType hType = 701 jobAttributes.getMultipleDocumentHandling(); 702 if (hType == 703 MultipleDocumentHandlingType.SEPARATE_DOCUMENTS_COLLATED_COPIES) { 704 attributes.add(SheetCollate.COLLATED); 705 } else { 706 attributes.add(SheetCollate.UNCOLLATED); 707 } 708 709 attributes.add(new Copies(jobAttributes.getCopies())); 710 711 attributes.add(new PageRanges(jobAttributes.getFromPage(), 712 jobAttributes.getToPage())); 713 714 if (pageAttributes.getColor() == ColorType.COLOR) { 715 attributes.add(Chromaticity.COLOR); 716 } else { 717 attributes.add(Chromaticity.MONOCHROME); 718 } 719 720 pageFormat = printerJob.defaultPage(); 721 if (pageAttributes.getOrientationRequested() == 722 OrientationRequestedType.LANDSCAPE) { 723 pageFormat.setOrientation(PageFormat.LANDSCAPE); 724 attributes.add(OrientationRequested.LANDSCAPE); 725 } else { 726 pageFormat.setOrientation(PageFormat.PORTRAIT); 727 attributes.add(OrientationRequested.PORTRAIT); 728 } 729 730 MediaType media = pageAttributes.getMedia(); 731 MediaSizeName msn = mapMedia(media); 732 if (msn != null) { 733 attributes.add(msn); 734 } 735 736 PrintQualityType qType = 737 pageAttributes.getPrintQuality(); 738 if (qType == PrintQualityType.DRAFT) { 739 attributes.add(PrintQuality.DRAFT); 740 } else if (qType == PrintQualityType.NORMAL) { 741 attributes.add(PrintQuality.NORMAL); 742 } else if (qType == PrintQualityType.HIGH) { 743 attributes.add(PrintQuality.HIGH); 744 } 745 } 746 747 /** 748 * Gets a Graphics object that will draw to the next page. 749 * The page is sent to the printer when the graphics 750 * object is disposed. This graphics object will also implement 751 * the PrintGraphics interface. 752 * @see PrintGraphics 753 */ 754 public Graphics getGraphics() { 755 756 Graphics printGraphics = null; 757 758 synchronized (this) { 759 ++pageIndex; 760 761 // Thread should not be created after end has been called. 762 // One way to detect this is if any of the graphics queue 763 // has been closed. 764 if (pageIndex == 0 && !graphicsToBeDrawn.isClosed()) { 765 766 /* We start a thread on which the PrinterJob will run. 767 * The PrinterJob will ask for pages on that thread 768 * and will use a message queue to fulfill the application's 769 * requests for a Graphics on the application's 770 * thread. 771 */ 772 773 startPrinterJobThread(); 774 775 } 776 notify(); 777 } 778 779 /* If the application has already been handed back 780 * a graphics then we need to put that graphics into 781 * the drawn queue so that the PrinterJob thread can 782 * return to the print system. 783 */ 784 if (currentGraphics != null) { 785 graphicsDrawn.append(currentGraphics); 786 currentGraphics = null; 787 } 788 789 /* We'll block here until a new graphics becomes 790 * available. 791 */ 792 793 currentGraphics = graphicsToBeDrawn.pop(); 794 795 if (currentGraphics instanceof PeekGraphics) { 796 ( (PeekGraphics) currentGraphics).setAWTDrawingOnly(); 797 graphicsDrawn.append(currentGraphics); 798 currentGraphics = graphicsToBeDrawn.pop(); 799 } 800 801 802 if (currentGraphics != null) { 803 804 /* In the PrintJob API, the origin is at the upper- 805 * left of the imageable area when using the new "printable" 806 * origin attribute, otherwise its the physical origin (for 807 * backwards compatibility. We emulate this by createing 808 * a PageFormat which matches and then performing the 809 * translate to the origin. This is a no-op if physical 810 * origin is specified. 811 */ 812 currentGraphics.translate(pageFormat.getImageableX(), 813 pageFormat.getImageableY()); 814 815 /* Scale to accommodate AWT's notion of printer resolution */ 816 double awtScale = 72.0/getPageResolutionInternal(); 817 currentGraphics.scale(awtScale, awtScale); 818 819 /* The caller wants a Graphics instance but we do 820 * not want them to make 2D calls. We can't hand 821 * back a Graphics2D. The returned Graphics also 822 * needs to implement PrintGraphics, so we wrap 823 * the Graphics2D instance. The PrintJob API has 824 * the application dispose of the Graphics so 825 * we create a copy of the one returned by PrinterJob. 826 */ 827 printGraphics = new ProxyPrintGraphics(currentGraphics.create(), 828 this); 829 830 } 831 832 return printGraphics; 833 } 834 835 /** 836 * Returns the dimensions of the page in pixels. 837 * The resolution of the page is chosen so that it 838 * is similar to the screen resolution. 839 * Except (since 1.3) when the application specifies a resolution. 840 * In that case it it scaled accordingly. 841 */ 842 public Dimension getPageDimension() { 843 double wid, hgt, scale; 844 if (pageAttributes != null && 845 pageAttributes.getOrigin()==OriginType.PRINTABLE) { 846 wid = pageFormat.getImageableWidth(); 847 hgt = pageFormat.getImageableHeight(); 848 } else { 849 wid = pageFormat.getWidth(); 850 hgt = pageFormat.getHeight(); 851 } 852 scale = getPageResolutionInternal() / 72.0; 853 return new Dimension((int)(wid * scale), (int)(hgt * scale)); 854 } 855 856 private double getPageResolutionInternal() { 857 if (pageAttributes != null) { 858 int []res = pageAttributes.getPrinterResolution(); 859 if (res[2] == 3) { 860 return res[0]; 861 } else /* if (res[2] == 4) */ { 862 return (res[0] * 2.54); 863 } 864 } else { 865 return 72.0; 866 } 867 } 868 869 /** 870 * Returns the resolution of the page in pixels per inch. 871 * Note that this doesn't have to correspond to the physical 872 * resolution of the printer. 873 */ 874 public int getPageResolution() { 875 return (int)getPageResolutionInternal(); 876 } 877 878 /** 879 * Returns true if the last page will be printed first. 880 */ 881 public boolean lastPageFirst() { 882 return false; 883 } 884 885 /** 886 * Ends the print job and does any necessary cleanup. 887 */ 888 public synchronized void end() { 889 890 /* Prevent the PrinterJob thread from appending any more 891 * graphics to the to-be-drawn queue 892 */ 893 graphicsToBeDrawn.close(); 894 895 /* If we have a currentGraphics it was the last one returned to the 896 * PrintJob client. Append it to the drawn queue so that print() 897 * will return allowing the page to be flushed. 898 * This really ought to happen in dispose() but for whatever reason 899 * that isn't how the old PrintJob worked even though its spec 900 * said dispose() flushed the page. 901 */ 902 if (currentGraphics != null) { 903 graphicsDrawn.append(currentGraphics); 904 } 905 graphicsDrawn.closeWhenEmpty(); 906 907 /* Wait for the PrinterJob.print() thread to terminate, ensuring 908 * that RasterPrinterJob has made its end doc call, and resources 909 * are released, files closed etc. 910 */ 911 if( printerJobThread != null && printerJobThread.isAlive() ){ 912 try { 913 printerJobThread.join(); 914 } catch (InterruptedException e) { 915 } 916 } 917 } 918 919 /** 920 * Ends this print job once it is no longer referenced. 921 * @see #end 922 */ 923 public void finalize() { 924 end(); 925 } 926 927 /** 928 * Prints the page at the specified index into the specified 929 * {@link Graphics} context in the specified 930 * format. A <code>PrinterJob</code> calls the 931 * <code>Printable</code> interface to request that a page be 932 * rendered into the context specified by 933 * <code>graphics</code>. The format of the page to be drawn is 934 * specified by <code>pageFormat</code>. The zero based index 935 * of the requested page is specified by <code>pageIndex</code>. 936 * If the requested page does not exist then this method returns 937 * NO_SUCH_PAGE; otherwise PAGE_EXISTS is returned. 938 * The <code>Graphics</code> class or subclass implements the 939 * {@link PrinterGraphics} interface to provide additional 940 * information. If the <code>Printable</code> object 941 * aborts the print job then it throws a {@link PrinterException}. 942 * @param graphics the context into which the page is drawn 943 * @param pageFormat the size and orientation of the page being drawn 944 * @param pageIndex the zero based index of the page to be drawn 945 * @return PAGE_EXISTS if the page is rendered successfully 946 * or NO_SUCH_PAGE if <code>pageIndex</code> specifies a 947 * non-existent page. 948 * @exception java.awt.print.PrinterException 949 * thrown when the print job is terminated. 950 */ 951 public int print(Graphics graphics, PageFormat pageFormat, int pageIndex) 952 throws PrinterException { 953 954 int result; 955 956 /* This method will be called by the PrinterJob on a thread other 957 * that the application's thread. We hold on to the graphics 958 * until we can rendevous with the application's thread and 959 * hand over the graphics. The application then does all the 960 * drawing. When the application is done drawing we rendevous 961 * again with the PrinterJob thread and release the Graphics 962 * so that it knows we are done. 963 */ 964 965 /* Add the graphics to the message queue of graphics to 966 * be rendered. This is really a one slot queue. The 967 * application's thread will come along and remove the 968 * graphics from the queue when the app asks for a graphics. 969 */ 970 graphicsToBeDrawn.append( (Graphics2D) graphics); 971 972 /* We now wait for the app's thread to finish drawing on 973 * the Graphics. This thread will sleep until the application 974 * release the graphics by placing it in the graphics drawn 975 * message queue. If the application signals that it is 976 * finished drawing the entire document then we'll get null 977 * returned when we try and pop a finished graphic. 978 */ 979 if (graphicsDrawn.pop() != null) { 980 result = PAGE_EXISTS; 981 } else { 982 result = NO_SUCH_PAGE; 983 } 984 985 return result; 986 } 987 988 private void startPrinterJobThread() { 989 990 printerJobThread = new Thread(this, "printerJobThread"); 991 printerJobThread.start(); 992 } 993 994 995 public void run() { 996 997 try { 998 printerJob.print(attributes); 999 } catch (PrinterException e) { 1000 //REMIND: need to store this away and not rethrow it. 1001 } 1002 1003 /* Close the message queues so that nobody is stuck 1004 * waiting for one. 1005 */ 1006 graphicsToBeDrawn.closeWhenEmpty(); 1007 graphicsDrawn.close(); 1008 } 1009 1010 private class MessageQ { 1011 1012 private String qid="noname"; 1013 1014 private ArrayList queue = new ArrayList(); 1015 1016 MessageQ(String id) { 1017 qid = id; 1018 } 1019 1020 synchronized void closeWhenEmpty() { 1021 1022 while (queue != null && queue.size() > 0) { 1023 try { 1024 wait(1000); 1025 } catch (InterruptedException e) { 1026 // do nothing. 1027 } 1028 } 1029 1030 queue = null; 1031 notifyAll(); 1032 } 1033 1034 synchronized void close() { 1035 queue = null; 1036 notifyAll(); 1037 } 1038 1039 synchronized boolean append(Graphics2D g) { 1040 1041 boolean queued = false; 1042 1043 if (queue != null) { 1044 queue.add(g); 1045 queued = true; 1046 notify(); 1047 } 1048 1049 return queued; 1050 } 1051 1052 synchronized Graphics2D pop() { 1053 Graphics2D g = null; 1054 1055 while (g == null && queue != null) { 1056 1057 if (queue.size() > 0) { 1058 g = (Graphics2D) queue.remove(0); 1059 notify(); 1060 1061 } else { 1062 try { 1063 wait(2000); 1064 } catch (InterruptedException e) { 1065 // do nothing. 1066 } 1067 } 1068 } 1069 1070 return g; 1071 } 1072 1073 synchronized boolean isClosed() { 1074 return queue == null; 1075 } 1076 1077 } 1078 1079 1080 private static int[] getSize(MediaType mType) { 1081 int []dim = new int[2]; 1082 dim[0] = 612; 1083 dim[1] = 792; 1084 1085 for (int i=0; i < SIZES.length; i++) { 1086 if (SIZES[i] == mType) { 1087 dim[0] = WIDTHS[i]; 1088 dim[1] = LENGTHS[i]; 1089 break; 1090 } 1091 } 1092 return dim; 1093 } 1094 1095 public static MediaSizeName mapMedia(MediaType mType) { 1096 MediaSizeName media = null; 1097 1098 // JAVAXSIZES.length and SIZES.length must be equal! 1099 // Attempt to recover by getting the smaller size. 1100 int length = Math.min(SIZES.length, JAVAXSIZES.length); 1101 1102 for (int i=0; i < length; i++) { 1103 if (SIZES[i] == mType) { 1104 if ((JAVAXSIZES[i] != null) && 1105 MediaSize.getMediaSizeForName(JAVAXSIZES[i]) != null) { 1106 media = JAVAXSIZES[i]; 1107 break; 1108 } else { 1109 /* create Custom Media */ 1110 media = new CustomMediaSizeName(SIZES[i].toString()); 1111 1112 float w = (float)Math.rint(WIDTHS[i] / 72.0); 1113 float h = (float)Math.rint(LENGTHS[i] / 72.0); 1114 if (w > 0.0 && h > 0.0) { 1115 // add new created MediaSize to our static map 1116 // so it will be found when we call findMedia 1117 new MediaSize(w, h, Size2DSyntax.INCH, media); 1118 } 1119 1120 break; 1121 } 1122 } 1123 } 1124 return media; 1125 } 1126 1127 1128 public static MediaType unMapMedia(MediaSizeName mSize) { 1129 MediaType media = null; 1130 1131 // JAVAXSIZES.length and SIZES.length must be equal! 1132 // Attempt to recover by getting the smaller size. 1133 int length = Math.min(SIZES.length, JAVAXSIZES.length); 1134 1135 for (int i=0; i < length; i++) { 1136 if (JAVAXSIZES[i] == mSize) { 1137 if (SIZES[i] != null) { 1138 media = SIZES[i]; 1139 break; 1140 } 1141 } 1142 } 1143 return media; 1144 } 1145 1146 private void translateInputProps() { 1147 if (props == null) { 1148 return; 1149 } 1150 1151 String str; 1152 1153 str = props.getProperty(DEST_PROP); 1154 if (str != null) { 1155 if (str.equals(PRINTER)) { 1156 jobAttributes.setDestination(DestinationType.PRINTER); 1157 } else if (str.equals(FILE)) { 1158 jobAttributes.setDestination(DestinationType.FILE); 1159 } 1160 } 1161 str = props.getProperty(PRINTER_PROP); 1162 if (str != null) { 1163 jobAttributes.setPrinter(str); 1164 } 1165 str = props.getProperty(FILENAME_PROP); 1166 if (str != null) { 1167 jobAttributes.setFileName(str); 1168 } 1169 str = props.getProperty(NUMCOPIES_PROP); 1170 if (str != null) { 1171 jobAttributes.setCopies(Integer.parseInt(str)); 1172 } 1173 1174 this.options = props.getProperty(OPTIONS_PROP, ""); 1175 1176 str = props.getProperty(ORIENT_PROP); 1177 if (str != null) { 1178 if (str.equals(PORTRAIT)) { 1179 pageAttributes.setOrientationRequested( 1180 OrientationRequestedType.PORTRAIT); 1181 } else if (str.equals(LANDSCAPE)) { 1182 pageAttributes.setOrientationRequested( 1183 OrientationRequestedType.LANDSCAPE); 1184 } 1185 } 1186 str = props.getProperty(PAPERSIZE_PROP); 1187 if (str != null) { 1188 if (str.equals(LETTER)) { 1189 pageAttributes.setMedia(SIZES[MediaType.LETTER.hashCode()]); 1190 } else if (str.equals(LEGAL)) { 1191 pageAttributes.setMedia(SIZES[MediaType.LEGAL.hashCode()]); 1192 } else if (str.equals(EXECUTIVE)) { 1193 pageAttributes.setMedia(SIZES[MediaType.EXECUTIVE.hashCode()]); 1194 } else if (str.equals(A4)) { 1195 pageAttributes.setMedia(SIZES[MediaType.A4.hashCode()]); 1196 } 1197 } 1198 } 1199 1200 private void translateOutputProps() { 1201 if (props == null) { 1202 return; 1203 } 1204 1205 String str; 1206 1207 props.setProperty(DEST_PROP, 1208 (jobAttributes.getDestination() == DestinationType.PRINTER) ? 1209 PRINTER : FILE); 1210 str = jobAttributes.getPrinter(); 1211 if (str != null && !str.equals("")) { 1212 props.setProperty(PRINTER_PROP, str); 1213 } 1214 str = jobAttributes.getFileName(); 1215 if (str != null && !str.equals("")) { 1216 props.setProperty(FILENAME_PROP, str); 1217 } 1218 int copies = jobAttributes.getCopies(); 1219 if (copies > 0) { 1220 props.setProperty(NUMCOPIES_PROP, "" + copies); 1221 } 1222 str = this.options; 1223 if (str != null && !str.equals("")) { 1224 props.setProperty(OPTIONS_PROP, str); 1225 } 1226 props.setProperty(ORIENT_PROP, 1227 (pageAttributes.getOrientationRequested() == 1228 OrientationRequestedType.PORTRAIT) 1229 ? PORTRAIT : LANDSCAPE); 1230 MediaType media = SIZES[pageAttributes.getMedia().hashCode()]; 1231 if (media == MediaType.LETTER) { 1232 str = LETTER; 1233 } else if (media == MediaType.LEGAL) { 1234 str = LEGAL; 1235 } else if (media == MediaType.EXECUTIVE) { 1236 str = EXECUTIVE; 1237 } else if (media == MediaType.A4) { 1238 str = A4; 1239 } else { 1240 str = media.toString(); 1241 } 1242 props.setProperty(PAPERSIZE_PROP, str); 1243 } 1244 1245 private void throwPrintToFile() { 1246 SecurityManager security = System.getSecurityManager(); 1247 FilePermission printToFilePermission = null; 1248 if (security != null) { 1249 if (printToFilePermission == null) { 1250 printToFilePermission = 1251 new FilePermission("<<ALL FILES>>", "read,write"); 1252 } 1253 security.checkPermission(printToFilePermission); 1254 } 1255 } 1256 1257 }