1 /* 2 * Copyright (c) 2000, 2015, 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.misc.ManagedLocalsThread; 75 import sun.print.SunPageSelection; 76 import sun.print.SunMinMaxPage; 77 78 /** 79 * A class which initiates and executes a print job using 80 * the underlying PrinterJob graphics conversions. 81 * 82 * @see java.awt.Toolkit#getPrintJob 83 * 84 */ 85 public class PrintJob2D extends PrintJob implements Printable, Runnable { 86 87 private static final MediaType SIZES[] = { 88 MediaType.ISO_4A0, MediaType.ISO_2A0, MediaType.ISO_A0, 89 MediaType.ISO_A1, MediaType.ISO_A2, MediaType.ISO_A3, 90 MediaType.ISO_A4, MediaType.ISO_A5, MediaType.ISO_A6, 91 MediaType.ISO_A7, MediaType.ISO_A8, MediaType.ISO_A9, 92 MediaType.ISO_A10, MediaType.ISO_B0, MediaType.ISO_B1, 93 MediaType.ISO_B2, MediaType.ISO_B3, MediaType.ISO_B4, 94 MediaType.ISO_B5, MediaType.ISO_B6, MediaType.ISO_B7, 95 MediaType.ISO_B8, MediaType.ISO_B9, MediaType.ISO_B10, 96 MediaType.JIS_B0, MediaType.JIS_B1, MediaType.JIS_B2, 97 MediaType.JIS_B3, MediaType.JIS_B4, MediaType.JIS_B5, 98 MediaType.JIS_B6, MediaType.JIS_B7, MediaType.JIS_B8, 99 MediaType.JIS_B9, MediaType.JIS_B10, MediaType.ISO_C0, 100 MediaType.ISO_C1, MediaType.ISO_C2, MediaType.ISO_C3, 101 MediaType.ISO_C4, MediaType.ISO_C5, MediaType.ISO_C6, 102 MediaType.ISO_C7, MediaType.ISO_C8, MediaType.ISO_C9, 103 MediaType.ISO_C10, MediaType.ISO_DESIGNATED_LONG, 104 MediaType.EXECUTIVE, MediaType.FOLIO, MediaType.INVOICE, 105 MediaType.LEDGER, MediaType.NA_LETTER, MediaType.NA_LEGAL, 106 MediaType.QUARTO, MediaType.A, MediaType.B, 107 MediaType.C, MediaType.D, MediaType.E, 108 MediaType.NA_10X15_ENVELOPE, MediaType.NA_10X14_ENVELOPE, 109 MediaType.NA_10X13_ENVELOPE, MediaType.NA_9X12_ENVELOPE, 110 MediaType.NA_9X11_ENVELOPE, MediaType.NA_7X9_ENVELOPE, 111 MediaType.NA_6X9_ENVELOPE, MediaType.NA_NUMBER_9_ENVELOPE, 112 MediaType.NA_NUMBER_10_ENVELOPE, MediaType.NA_NUMBER_11_ENVELOPE, 113 MediaType.NA_NUMBER_12_ENVELOPE, MediaType.NA_NUMBER_14_ENVELOPE, 114 MediaType.INVITE_ENVELOPE, MediaType.ITALY_ENVELOPE, 115 MediaType.MONARCH_ENVELOPE, MediaType.PERSONAL_ENVELOPE 116 }; 117 118 /* This array maps the above array to the objects used by the 119 * javax.print APIs 120 */ 121 private static final MediaSizeName JAVAXSIZES[] = { 122 null, null, MediaSizeName.ISO_A0, 123 MediaSizeName.ISO_A1, MediaSizeName.ISO_A2, MediaSizeName.ISO_A3, 124 MediaSizeName.ISO_A4, MediaSizeName.ISO_A5, MediaSizeName.ISO_A6, 125 MediaSizeName.ISO_A7, MediaSizeName.ISO_A8, MediaSizeName.ISO_A9, 126 MediaSizeName.ISO_A10, MediaSizeName.ISO_B0, MediaSizeName.ISO_B1, 127 MediaSizeName.ISO_B2, MediaSizeName.ISO_B3, MediaSizeName.ISO_B4, 128 MediaSizeName.ISO_B5, MediaSizeName.ISO_B6, MediaSizeName.ISO_B7, 129 MediaSizeName.ISO_B8, MediaSizeName.ISO_B9, MediaSizeName.ISO_B10, 130 MediaSizeName.JIS_B0, MediaSizeName.JIS_B1, MediaSizeName.JIS_B2, 131 MediaSizeName.JIS_B3, MediaSizeName.JIS_B4, MediaSizeName.JIS_B5, 132 MediaSizeName.JIS_B6, MediaSizeName.JIS_B7, MediaSizeName.JIS_B8, 133 MediaSizeName.JIS_B9, MediaSizeName.JIS_B10, MediaSizeName.ISO_C0, 134 MediaSizeName.ISO_C1, MediaSizeName.ISO_C2, MediaSizeName.ISO_C3, 135 MediaSizeName.ISO_C4, MediaSizeName.ISO_C5, MediaSizeName.ISO_C6, 136 null, null, null, null, 137 MediaSizeName.ISO_DESIGNATED_LONG, MediaSizeName.EXECUTIVE, 138 MediaSizeName.FOLIO, MediaSizeName.INVOICE, MediaSizeName.LEDGER, 139 MediaSizeName.NA_LETTER, MediaSizeName.NA_LEGAL, 140 MediaSizeName.QUARTO, MediaSizeName.A, MediaSizeName.B, 141 MediaSizeName.C, MediaSizeName.D, MediaSizeName.E, 142 MediaSizeName.NA_10X15_ENVELOPE, MediaSizeName.NA_10X14_ENVELOPE, 143 MediaSizeName.NA_10X13_ENVELOPE, MediaSizeName.NA_9X12_ENVELOPE, 144 MediaSizeName.NA_9X11_ENVELOPE, MediaSizeName.NA_7X9_ENVELOPE, 145 MediaSizeName.NA_6X9_ENVELOPE, 146 MediaSizeName.NA_NUMBER_9_ENVELOPE, 147 MediaSizeName.NA_NUMBER_10_ENVELOPE, 148 MediaSizeName.NA_NUMBER_11_ENVELOPE, 149 MediaSizeName.NA_NUMBER_12_ENVELOPE, 150 MediaSizeName.NA_NUMBER_14_ENVELOPE, 151 null, MediaSizeName.ITALY_ENVELOPE, 152 MediaSizeName.MONARCH_ENVELOPE, MediaSizeName.PERSONAL_ENVELOPE, 153 }; 154 155 156 // widths and lengths in PostScript points (1/72 in.) 157 private static final int WIDTHS[] = { 158 /*iso-4a0*/ 4768, /*iso-2a0*/ 3370, /*iso-a0*/ 2384, /*iso-a1*/ 1684, 159 /*iso-a2*/ 1191, /*iso-a3*/ 842, /*iso-a4*/ 595, /*iso-a5*/ 420, 160 /*iso-a6*/ 298, /*iso-a7*/ 210, /*iso-a8*/ 147, /*iso-a9*/ 105, 161 /*iso-a10*/ 74, /*iso-b0*/ 2835, /*iso-b1*/ 2004, /*iso-b2*/ 1417, 162 /*iso-b3*/ 1001, /*iso-b4*/ 709, /*iso-b5*/ 499, /*iso-b6*/ 354, 163 /*iso-b7*/ 249, /*iso-b8*/ 176, /*iso-b9*/ 125, /*iso-b10*/ 88, 164 /*jis-b0*/ 2920, /*jis-b1*/ 2064, /*jis-b2*/ 1460, /*jis-b3*/ 1032, 165 /*jis-b4*/ 729, /*jis-b5*/ 516, /*jis-b6*/ 363, /*jis-b7*/ 258, 166 /*jis-b8*/ 181, /*jis-b9*/ 128, /*jis-b10*/ 91, /*iso-c0*/ 2599, 167 /*iso-c1*/ 1837, /*iso-c2*/ 1298, /*iso-c3*/ 918, /*iso-c4*/ 649, 168 /*iso-c5*/ 459, /*iso-c6*/ 323, /*iso-c7*/ 230, /*iso-c8*/ 162, 169 /*iso-c9*/ 113, /*iso-c10*/ 79, /*iso-designated-long*/ 312, 170 /*executive*/ 522, /*folio*/ 612, /*invoice*/ 396, /*ledger*/ 792, 171 /*na-letter*/ 612, /*na-legal*/ 612, /*quarto*/ 609, /*a*/ 612, 172 /*b*/ 792, /*c*/ 1224, /*d*/ 1584, /*e*/ 2448, 173 /*na-10x15-envelope*/ 720, /*na-10x14-envelope*/ 720, 174 /*na-10x13-envelope*/ 720, /*na-9x12-envelope*/ 648, 175 /*na-9x11-envelope*/ 648, /*na-7x9-envelope*/ 504, 176 /*na-6x9-envelope*/ 432, /*na-number-9-envelope*/ 279, 177 /*na-number-10-envelope*/ 297, /*na-number-11-envelope*/ 324, 178 /*na-number-12-envelope*/ 342, /*na-number-14-envelope*/ 360, 179 /*invite-envelope*/ 624, /*italy-envelope*/ 312, 180 /*monarch-envelope*/ 279, /*personal-envelope*/ 261 181 }; 182 private static final int LENGTHS[] = { 183 /*iso-4a0*/ 6741, /*iso-2a0*/ 4768, /*iso-a0*/ 3370, /*iso-a1*/ 2384, 184 /*iso-a2*/ 1684, /*iso-a3*/ 1191, /*iso-a4*/ 842, /*iso-a5*/ 595, 185 /*iso-a6*/ 420, /*iso-a7*/ 298, /*iso-a8*/ 210, /*iso-a9*/ 147, 186 /*iso-a10*/ 105, /*iso-b0*/ 4008, /*iso-b1*/ 2835, /*iso-b2*/ 2004, 187 /*iso-b3*/ 1417, /*iso-b4*/ 1001, /*iso-b5*/ 729, /*iso-b6*/ 499, 188 /*iso-b7*/ 354, /*iso-b8*/ 249, /*iso-b9*/ 176, /*iso-b10*/ 125, 189 /*jis-b0*/ 4127, /*jis-b1*/ 2920, /*jis-b2*/ 2064, /*jis-b3*/ 1460, 190 /*jis-b4*/ 1032, /*jis-b5*/ 729, /*jis-b6*/ 516, /*jis-b7*/ 363, 191 /*jis-b8*/ 258, /*jis-b9*/ 181, /*jis-b10*/ 128, /*iso-c0*/ 3677, 192 /*iso-c1*/ 2599, /*iso-c2*/ 1837, /*iso-c3*/ 1298, /*iso-c4*/ 918, 193 /*iso-c5*/ 649, /*iso-c6*/ 459, /*iso-c7*/ 323, /*iso-c8*/ 230, 194 /*iso-c9*/ 162, /*iso-c10*/ 113, /*iso-designated-long*/ 624, 195 /*executive*/ 756, /*folio*/ 936, /*invoice*/ 612, /*ledger*/ 1224, 196 /*na-letter*/ 792, /*na-legal*/ 1008, /*quarto*/ 780, /*a*/ 792, 197 /*b*/ 1224, /*c*/ 1584, /*d*/ 2448, /*e*/ 3168, 198 /*na-10x15-envelope*/ 1080, /*na-10x14-envelope*/ 1008, 199 /*na-10x13-envelope*/ 936, /*na-9x12-envelope*/ 864, 200 /*na-9x11-envelope*/ 792, /*na-7x9-envelope*/ 648, 201 /*na-6x9-envelope*/ 648, /*na-number-9-envelope*/ 639, 202 /*na-number-10-envelope*/ 684, /*na-number-11-envelope*/ 747, 203 /*na-number-12-envelope*/ 792, /*na-number-14-envelope*/ 828, 204 /*invite-envelope*/ 624, /*italy-envelope*/ 652, 205 /*monarch-envelope*/ 540, /*personal-envelope*/ 468 206 }; 207 208 209 private Frame frame; 210 private String docTitle = ""; 211 private JobAttributes jobAttributes; 212 private PageAttributes pageAttributes; 213 private PrintRequestAttributeSet attributes; 214 215 /* 216 * Displays the native or cross-platform dialog and allows the 217 * user to update job & page attributes 218 */ 219 220 /** 221 * The PrinterJob being uses to implement the PrintJob. 222 */ 223 private PrinterJob printerJob; 224 225 /** 226 * The size of the page being used for the PrintJob. 227 */ 228 private PageFormat pageFormat; 229 230 /** 231 * The PrinterJob and the application run on different 232 * threads and communicate through a pair of message 233 * queues. This queue is the list of Graphics that 234 * the PrinterJob has requested rendering for, but 235 * for which the application has not yet called getGraphics(). 236 * In practice the length of this message queue is always 237 * 0 or 1. 238 */ 239 private MessageQ graphicsToBeDrawn = new MessageQ("tobedrawn"); 240 241 /** 242 * Used to communicate between the application's thread 243 * and the PrinterJob's thread this message queue holds 244 * the list of Graphics into which the application has 245 * finished drawing, but that have not yet been returned 246 * to the PrinterJob thread. Again, in practice, the 247 * length of this message queue is always 0 or 1. 248 */ 249 private MessageQ graphicsDrawn = new MessageQ("drawn"); 250 251 /** 252 * The last Graphics returned to the application via 253 * getGraphics. This is the Graphics into which the 254 * application is currently drawing. 255 */ 256 private Graphics2D currentGraphics; 257 258 /** 259 * The zero based index of the page currently being rendered 260 * by the application. 261 */ 262 private int pageIndex = -1; 263 264 // The following Strings are maintained for backward-compatibility with 265 // Properties based print control. 266 private static final String DEST_PROP = "awt.print.destination"; 267 private static final String PRINTER = "printer"; 268 private static final String FILE = "file"; 269 270 private static final String PRINTER_PROP = "awt.print.printer"; 271 272 private static final String FILENAME_PROP = "awt.print.fileName"; 273 274 private static final String NUMCOPIES_PROP = "awt.print.numCopies"; 275 276 private static final String OPTIONS_PROP = "awt.print.options"; 277 278 private static final String ORIENT_PROP = "awt.print.orientation"; 279 private static final String PORTRAIT = "portrait"; 280 private static final String LANDSCAPE = "landscape"; 281 282 private static final String PAPERSIZE_PROP = "awt.print.paperSize"; 283 private static final String LETTER = "letter"; 284 private static final String LEGAL = "legal"; 285 private static final String EXECUTIVE = "executive"; 286 private static final String A4 = "a4"; 287 288 private Properties props; 289 290 private String options = ""; // REMIND: needs implementation 291 292 /** 293 * The thread on which PrinterJob is running. 294 * This is different than the applications thread. 295 */ 296 private Thread printerJobThread; 297 298 public PrintJob2D(Frame frame, String doctitle, 299 final Properties props) { 300 this.props = props; 301 this.jobAttributes = new JobAttributes(); 302 this.pageAttributes = new PageAttributes(); 303 translateInputProps(); 304 initPrintJob2D(frame, doctitle, 305 this.jobAttributes, this.pageAttributes); 306 } 307 308 public PrintJob2D(Frame frame, String doctitle, 309 JobAttributes jobAttributes, 310 PageAttributes pageAttributes) { 311 initPrintJob2D(frame, doctitle, jobAttributes, pageAttributes); 312 } 313 314 private void initPrintJob2D(Frame frame, String doctitle, 315 JobAttributes jobAttributes, 316 PageAttributes pageAttributes) { 317 318 SecurityManager security = System.getSecurityManager(); 319 if (security != null) { 320 security.checkPrintJobAccess(); 321 } 322 323 if (frame == null && 324 (jobAttributes == null || 325 jobAttributes.getDialog() == DialogType.NATIVE)) { 326 throw new NullPointerException("Frame must not be null"); 327 } 328 this.frame = frame; 329 330 this.docTitle = (doctitle == null) ? "" : doctitle; 331 this.jobAttributes = (jobAttributes != null) 332 ? jobAttributes : new JobAttributes(); 333 this.pageAttributes = (pageAttributes != null) 334 ? pageAttributes : new PageAttributes(); 335 336 // Currently, we always reduce page ranges to xxx or xxx-xxx 337 int[][] pageRanges = this.jobAttributes.getPageRanges(); 338 int first = pageRanges[0][0]; 339 int last = pageRanges[pageRanges.length - 1][1]; 340 this.jobAttributes.setPageRanges(new int[][] { 341 new int[] { first, last } 342 }); 343 this.jobAttributes.setToPage(last); 344 this.jobAttributes.setFromPage(first); 345 346 347 // Verify that the cross feed and feed resolutions are the same 348 int[] res = this.pageAttributes.getPrinterResolution(); 349 if (res[0] != res[1]) { 350 throw new IllegalArgumentException("Differing cross feed and feed"+ 351 " resolutions not supported."); 352 } 353 354 // Verify that the app has access to the file system 355 DestinationType dest= this.jobAttributes.getDestination(); 356 if (dest == DestinationType.FILE) { 357 throwPrintToFile(); 358 359 // check if given filename is valid 360 String destStr = jobAttributes.getFileName(); 361 if ((destStr != null) && 362 (jobAttributes.getDialog() == JobAttributes.DialogType.NONE)) { 363 364 File f = new File(destStr); 365 try { 366 // check if this is a new file and if filename chars are valid 367 // createNewFile returns false if file exists 368 if (f.createNewFile()) { 369 f.delete(); 370 } 371 } catch (IOException ioe) { 372 throw new IllegalArgumentException("Cannot write to file:"+ 373 destStr); 374 } catch (SecurityException se) { 375 //There is already file read/write access so at this point 376 // only delete access is denied. Just ignore it because in 377 // most cases the file created in createNewFile gets overwritten 378 // anyway. 379 } 380 381 File pFile = f.getParentFile(); 382 if ((f.exists() && 383 (!f.isFile() || !f.canWrite())) || 384 ((pFile != null) && 385 (!pFile.exists() || (pFile.exists() && !pFile.canWrite())))) { 386 throw new IllegalArgumentException("Cannot write to file:"+ 387 destStr); 388 } 389 } 390 } 391 } 392 393 public boolean printDialog() { 394 395 boolean proceedWithPrint = false; 396 397 printerJob = PrinterJob.getPrinterJob(); 398 if (printerJob == null) { 399 return false; 400 } 401 DialogType d = this.jobAttributes.getDialog(); 402 PrintService pServ = printerJob.getPrintService(); 403 if ((pServ == null) && (d == DialogType.NONE)){ 404 return false; 405 } 406 copyAttributes(pServ); 407 408 DefaultSelectionType select = 409 this.jobAttributes.getDefaultSelection(); 410 if (select == DefaultSelectionType.RANGE) { 411 attributes.add(SunPageSelection.RANGE); 412 } else if (select == DefaultSelectionType.SELECTION) { 413 attributes.add(SunPageSelection.SELECTION); 414 } else { 415 attributes.add(SunPageSelection.ALL); 416 } 417 418 if (frame != null) { 419 attributes.add(new DialogOwner(frame)); 420 } 421 422 if ( d == DialogType.NONE) { 423 proceedWithPrint = true; 424 } else { 425 if (d == DialogType.NATIVE) { 426 attributes.add(DialogTypeSelection.NATIVE); 427 } else { // (d == DialogType.COMMON) 428 attributes.add(DialogTypeSelection.COMMON); 429 } 430 if (proceedWithPrint = printerJob.printDialog(attributes)) { 431 if (pServ == null) { 432 // Windows gives an option to install a service 433 // when it detects there are no printers so 434 // we make sure we get the updated print service. 435 pServ = printerJob.getPrintService(); 436 if (pServ == null) { 437 return false; 438 } 439 } 440 updateAttributes(); 441 translateOutputProps(); 442 } 443 } 444 445 if (proceedWithPrint) { 446 447 JobName jname = (JobName)attributes.get(JobName.class); 448 if (jname != null) { 449 printerJob.setJobName(jname.toString()); 450 } 451 452 pageFormat = new PageFormat(); 453 454 Media media = (Media)attributes.get(Media.class); 455 MediaSize mediaSize = null; 456 if (media != null && media instanceof MediaSizeName) { 457 mediaSize = MediaSize.getMediaSizeForName((MediaSizeName)media); 458 } 459 460 Paper p = pageFormat.getPaper(); 461 if (mediaSize != null) { 462 p.setSize(mediaSize.getX(MediaSize.INCH)*72.0, 463 mediaSize.getY(MediaSize.INCH)*72.0); 464 } 465 466 if (pageAttributes.getOrigin()==OriginType.PRINTABLE) { 467 // AWT uses 1/4" borders by default 468 p.setImageableArea(18.0, 18.0, 469 p.getWidth()-36.0, 470 p.getHeight()-36.0); 471 } else { 472 p.setImageableArea(0.0,0.0,p.getWidth(),p.getHeight()); 473 } 474 475 pageFormat.setPaper(p); 476 477 OrientationRequested orient = 478 (OrientationRequested)attributes.get(OrientationRequested.class); 479 if (orient!= null && 480 orient == OrientationRequested.REVERSE_LANDSCAPE) { 481 pageFormat.setOrientation(PageFormat.REVERSE_LANDSCAPE); 482 } else if (orient == OrientationRequested.LANDSCAPE) { 483 pageFormat.setOrientation(PageFormat.LANDSCAPE); 484 } else { 485 pageFormat.setOrientation(PageFormat.PORTRAIT); 486 } 487 488 printerJob.setPrintable(this, pageFormat); 489 490 } 491 492 return proceedWithPrint; 493 } 494 495 private void updateAttributes() { 496 Copies c = (Copies)attributes.get(Copies.class); 497 jobAttributes.setCopies(c.getValue()); 498 499 SunPageSelection sel = 500 (SunPageSelection)attributes.get(SunPageSelection.class); 501 if (sel == SunPageSelection.RANGE) { 502 jobAttributes.setDefaultSelection(DefaultSelectionType.RANGE); 503 } else if (sel == SunPageSelection.SELECTION) { 504 jobAttributes.setDefaultSelection(DefaultSelectionType.SELECTION); 505 } else { 506 jobAttributes.setDefaultSelection(DefaultSelectionType.ALL); 507 } 508 509 Destination dest = (Destination)attributes.get(Destination.class); 510 if (dest != null) { 511 jobAttributes.setDestination(DestinationType.FILE); 512 jobAttributes.setFileName(dest.getURI().getPath()); 513 } else { 514 jobAttributes.setDestination(DestinationType.PRINTER); 515 } 516 517 PrintService serv = printerJob.getPrintService(); 518 if (serv != null) { 519 jobAttributes.setPrinter(serv.getName()); 520 } 521 522 PageRanges range = (PageRanges)attributes.get(PageRanges.class); 523 int[][] members = range.getMembers(); 524 jobAttributes.setPageRanges(members); 525 526 SheetCollate collation = 527 (SheetCollate)attributes.get(SheetCollate.class); 528 if (collation == SheetCollate.COLLATED) { 529 jobAttributes.setMultipleDocumentHandling( 530 MultipleDocumentHandlingType.SEPARATE_DOCUMENTS_COLLATED_COPIES); 531 } else { 532 jobAttributes.setMultipleDocumentHandling( 533 MultipleDocumentHandlingType.SEPARATE_DOCUMENTS_UNCOLLATED_COPIES); 534 } 535 536 Sides sides = (Sides)attributes.get(Sides.class); 537 if (sides == Sides.TWO_SIDED_LONG_EDGE) { 538 jobAttributes.setSides(SidesType.TWO_SIDED_LONG_EDGE); 539 } else if (sides == Sides.TWO_SIDED_SHORT_EDGE) { 540 jobAttributes.setSides(SidesType.TWO_SIDED_SHORT_EDGE); 541 } else { 542 jobAttributes.setSides(SidesType.ONE_SIDED); 543 } 544 545 // PageAttributes 546 547 Chromaticity color = 548 (Chromaticity)attributes.get(Chromaticity.class); 549 if (color == Chromaticity.COLOR) { 550 pageAttributes.setColor(ColorType.COLOR); 551 } else { 552 pageAttributes.setColor(ColorType.MONOCHROME); 553 } 554 555 OrientationRequested orient = 556 (OrientationRequested)attributes.get(OrientationRequested.class); 557 if (orient == OrientationRequested.LANDSCAPE) { 558 pageAttributes.setOrientationRequested( 559 OrientationRequestedType.LANDSCAPE); 560 } else { 561 pageAttributes.setOrientationRequested( 562 OrientationRequestedType.PORTRAIT); 563 } 564 565 PrintQuality qual = (PrintQuality)attributes.get(PrintQuality.class); 566 if (qual == PrintQuality.DRAFT) { 567 pageAttributes.setPrintQuality(PrintQualityType.DRAFT); 568 } else if (qual == PrintQuality.HIGH) { 569 pageAttributes.setPrintQuality(PrintQualityType.HIGH); 570 } else { // NORMAL 571 pageAttributes.setPrintQuality(PrintQualityType.NORMAL); 572 } 573 574 Media msn = (Media)attributes.get(Media.class); 575 if (msn != null && msn instanceof MediaSizeName) { 576 MediaType mType = unMapMedia((MediaSizeName)msn); 577 578 if (mType != null) { 579 pageAttributes.setMedia(mType); 580 } 581 } 582 debugPrintAttributes(false, false); 583 } 584 585 private void debugPrintAttributes(boolean ja, boolean pa ) { 586 if (ja) { 587 System.out.println("new Attributes\ncopies = "+ 588 jobAttributes.getCopies()+ 589 "\nselection = "+ 590 jobAttributes.getDefaultSelection()+ 591 "\ndest "+jobAttributes.getDestination()+ 592 "\nfile "+jobAttributes.getFileName()+ 593 "\nfromPage "+jobAttributes.getFromPage()+ 594 "\ntoPage "+jobAttributes.getToPage()+ 595 "\ncollation "+ 596 jobAttributes.getMultipleDocumentHandling()+ 597 "\nPrinter "+jobAttributes.getPrinter()+ 598 "\nSides2 "+jobAttributes.getSides() 599 ); 600 } 601 602 if (pa) { 603 System.out.println("new Attributes\ncolor = "+ 604 pageAttributes.getColor()+ 605 "\norientation = "+ 606 pageAttributes.getOrientationRequested()+ 607 "\nquality "+pageAttributes.getPrintQuality()+ 608 "\nMedia2 "+pageAttributes.getMedia() 609 ); 610 } 611 } 612 613 614 /* From JobAttributes we will copy job name and duplex printing 615 * and destination. 616 * The majority of the rest of the attributes are reflected 617 * attributes. 618 * 619 * From PageAttributes we copy color, media size, orientation, 620 * origin type, resolution and print quality. 621 * We use the media, orientation in creating the page format, and 622 * the origin type to set its imageable area. 623 * 624 * REMIND: Interpretation of resolution, additional media sizes. 625 */ 626 private void copyAttributes(PrintService printServ) { 627 628 attributes = new HashPrintRequestAttributeSet(); 629 attributes.add(new JobName(docTitle, null)); 630 PrintService pServ = printServ; 631 632 String printerName = jobAttributes.getPrinter(); 633 if (printerName != null && printerName != "" 634 && pServ != null && !printerName.equals(pServ.getName())) { 635 636 // Search for the given printerName in the list of PrintServices 637 PrintService []services = PrinterJob.lookupPrintServices(); 638 try { 639 for (int i=0; i<services.length; i++) { 640 if (printerName.equals(services[i].getName())) { 641 printerJob.setPrintService(services[i]); 642 pServ = services[i]; 643 break; 644 } 645 } 646 } catch (PrinterException pe) { 647 } 648 } 649 650 DestinationType dest = jobAttributes.getDestination(); 651 if (dest == DestinationType.FILE && pServ != null && 652 pServ.isAttributeCategorySupported(Destination.class)) { 653 654 String fileName = jobAttributes.getFileName(); 655 656 Destination defaultDest; 657 if (fileName == null && (defaultDest = (Destination)pServ. 658 getDefaultAttributeValue(Destination.class)) != null) { 659 attributes.add(defaultDest); 660 } else { 661 URI uri = null; 662 try { 663 if (fileName != null) { 664 if (fileName.equals("")) { 665 fileName = "."; 666 } 667 } else { 668 // defaultDest should not be null. The following code 669 // is only added to safeguard against a possible 670 // buggy implementation of a PrintService having a 671 // null default Destination. 672 fileName = "out.prn"; 673 } 674 uri = (new File(fileName)).toURI(); 675 } catch (SecurityException se) { 676 try { 677 // '\\' file separator is illegal character in opaque 678 // part and causes URISyntaxException, so we replace 679 // it with '/' 680 fileName = fileName.replace('\\', '/'); 681 uri = new URI("file:"+fileName); 682 } catch (URISyntaxException e) { 683 } 684 } 685 if (uri != null) { 686 attributes.add(new Destination(uri)); 687 } 688 } 689 } 690 attributes.add(new SunMinMaxPage(jobAttributes.getMinPage(), 691 jobAttributes.getMaxPage())); 692 SidesType sType = jobAttributes.getSides(); 693 if (sType == SidesType.TWO_SIDED_LONG_EDGE) { 694 attributes.add(Sides.TWO_SIDED_LONG_EDGE); 695 } else if (sType == SidesType.TWO_SIDED_SHORT_EDGE) { 696 attributes.add(Sides.TWO_SIDED_SHORT_EDGE); 697 } else if (sType == SidesType.ONE_SIDED) { 698 attributes.add(Sides.ONE_SIDED); 699 } 700 701 MultipleDocumentHandlingType hType = 702 jobAttributes.getMultipleDocumentHandling(); 703 if (hType == 704 MultipleDocumentHandlingType.SEPARATE_DOCUMENTS_COLLATED_COPIES) { 705 attributes.add(SheetCollate.COLLATED); 706 } else { 707 attributes.add(SheetCollate.UNCOLLATED); 708 } 709 710 attributes.add(new Copies(jobAttributes.getCopies())); 711 712 attributes.add(new PageRanges(jobAttributes.getFromPage(), 713 jobAttributes.getToPage())); 714 715 if (pageAttributes.getColor() == ColorType.COLOR) { 716 attributes.add(Chromaticity.COLOR); 717 } else { 718 attributes.add(Chromaticity.MONOCHROME); 719 } 720 721 pageFormat = printerJob.defaultPage(); 722 if (pageAttributes.getOrientationRequested() == 723 OrientationRequestedType.LANDSCAPE) { 724 pageFormat.setOrientation(PageFormat.LANDSCAPE); 725 attributes.add(OrientationRequested.LANDSCAPE); 726 } else { 727 pageFormat.setOrientation(PageFormat.PORTRAIT); 728 attributes.add(OrientationRequested.PORTRAIT); 729 } 730 731 MediaType media = pageAttributes.getMedia(); 732 MediaSizeName msn = mapMedia(media); 733 if (msn != null) { 734 attributes.add(msn); 735 } 736 737 PrintQualityType qType = 738 pageAttributes.getPrintQuality(); 739 if (qType == PrintQualityType.DRAFT) { 740 attributes.add(PrintQuality.DRAFT); 741 } else if (qType == PrintQualityType.NORMAL) { 742 attributes.add(PrintQuality.NORMAL); 743 } else if (qType == PrintQualityType.HIGH) { 744 attributes.add(PrintQuality.HIGH); 745 } 746 } 747 748 /** 749 * Gets a Graphics object that will draw to the next page. 750 * The page is sent to the printer when the graphics 751 * object is disposed. This graphics object will also implement 752 * the PrintGraphics interface. 753 * @see java.awt.PrintGraphics 754 */ 755 public Graphics getGraphics() { 756 757 Graphics printGraphics = null; 758 759 synchronized (this) { 760 ++pageIndex; 761 762 // Thread should not be created after end has been called. 763 // One way to detect this is if any of the graphics queue 764 // has been closed. 765 if (pageIndex == 0 && !graphicsToBeDrawn.isClosed()) { 766 767 /* We start a thread on which the PrinterJob will run. 768 * The PrinterJob will ask for pages on that thread 769 * and will use a message queue to fulfill the application's 770 * requests for a Graphics on the application's 771 * thread. 772 */ 773 774 startPrinterJobThread(); 775 776 } 777 notify(); 778 } 779 780 /* If the application has already been handed back 781 * a graphics then we need to put that graphics into 782 * the drawn queue so that the PrinterJob thread can 783 * return to the print system. 784 */ 785 if (currentGraphics != null) { 786 graphicsDrawn.append(currentGraphics); 787 currentGraphics = null; 788 } 789 790 /* We'll block here until a new graphics becomes 791 * available. 792 */ 793 794 currentGraphics = graphicsToBeDrawn.pop(); 795 796 if (currentGraphics instanceof PeekGraphics) { 797 ( (PeekGraphics) currentGraphics).setAWTDrawingOnly(); 798 graphicsDrawn.append(currentGraphics); 799 currentGraphics = graphicsToBeDrawn.pop(); 800 } 801 802 803 if (currentGraphics != null) { 804 805 /* In the PrintJob API, the origin is at the upper- 806 * left of the imageable area when using the new "printable" 807 * origin attribute, otherwise its the physical origin (for 808 * backwards compatibility. We emulate this by createing 809 * a PageFormat which matches and then performing the 810 * translate to the origin. This is a no-op if physical 811 * origin is specified. 812 */ 813 currentGraphics.translate(pageFormat.getImageableX(), 814 pageFormat.getImageableY()); 815 816 /* Scale to accommodate AWT's notion of printer resolution */ 817 double awtScale = 72.0/getPageResolutionInternal(); 818 currentGraphics.scale(awtScale, awtScale); 819 820 /* The caller wants a Graphics instance but we do 821 * not want them to make 2D calls. We can't hand 822 * back a Graphics2D. The returned Graphics also 823 * needs to implement PrintGraphics, so we wrap 824 * the Graphics2D instance. The PrintJob API has 825 * the application dispose of the Graphics so 826 * we create a copy of the one returned by PrinterJob. 827 */ 828 printGraphics = new ProxyPrintGraphics(currentGraphics.create(), 829 this); 830 831 } 832 833 return printGraphics; 834 } 835 836 /** 837 * Returns the dimensions of the page in pixels. 838 * The resolution of the page is chosen so that it 839 * is similar to the screen resolution. 840 * Except (since 1.3) when the application specifies a resolution. 841 * In that case it is scaled accordingly. 842 */ 843 public Dimension getPageDimension() { 844 double wid, hgt, scale; 845 if (pageAttributes != null && 846 pageAttributes.getOrigin()==OriginType.PRINTABLE) { 847 wid = pageFormat.getImageableWidth(); 848 hgt = pageFormat.getImageableHeight(); 849 } else { 850 wid = pageFormat.getWidth(); 851 hgt = pageFormat.getHeight(); 852 } 853 scale = getPageResolutionInternal() / 72.0; 854 return new Dimension((int)(wid * scale), (int)(hgt * scale)); 855 } 856 857 private double getPageResolutionInternal() { 858 if (pageAttributes != null) { 859 int []res = pageAttributes.getPrinterResolution(); 860 if (res[2] == 3) { 861 return res[0]; 862 } else /* if (res[2] == 4) */ { 863 return (res[0] * 2.54); 864 } 865 } else { 866 return 72.0; 867 } 868 } 869 870 /** 871 * Returns the resolution of the page in pixels per inch. 872 * Note that this doesn't have to correspond to the physical 873 * resolution of the printer. 874 */ 875 public int getPageResolution() { 876 return (int)getPageResolutionInternal(); 877 } 878 879 /** 880 * Returns true if the last page will be printed first. 881 */ 882 public boolean lastPageFirst() { 883 return false; 884 } 885 886 /** 887 * Ends the print job and does any necessary cleanup. 888 */ 889 public synchronized void end() { 890 891 /* Prevent the PrinterJob thread from appending any more 892 * graphics to the to-be-drawn queue 893 */ 894 graphicsToBeDrawn.close(); 895 896 /* If we have a currentGraphics it was the last one returned to the 897 * PrintJob client. Append it to the drawn queue so that print() 898 * will return allowing the page to be flushed. 899 * This really ought to happen in dispose() but for whatever reason 900 * that isn't how the old PrintJob worked even though its spec 901 * said dispose() flushed the page. 902 */ 903 if (currentGraphics != null) { 904 graphicsDrawn.append(currentGraphics); 905 } 906 graphicsDrawn.closeWhenEmpty(); 907 908 /* Wait for the PrinterJob.print() thread to terminate, ensuring 909 * that RasterPrinterJob has made its end doc call, and resources 910 * are released, files closed etc. 911 */ 912 if( printerJobThread != null && printerJobThread.isAlive() ){ 913 try { 914 printerJobThread.join(); 915 } catch (InterruptedException e) { 916 } 917 } 918 } 919 920 /** 921 * Ends this print job once it is no longer referenced. 922 * @see #end 923 */ 924 public void finalize() { 925 end(); 926 } 927 928 /** 929 * Prints the page at the specified index into the specified 930 * {@link Graphics} context in the specified 931 * format. A {@code PrinterJob} calls the 932 * {@code Printable} interface to request that a page be 933 * rendered into the context specified by 934 * {@code graphics}. The format of the page to be drawn is 935 * specified by {@code pageFormat}. The zero based index 936 * of the requested page is specified by {@code pageIndex}. 937 * If the requested page does not exist then this method returns 938 * NO_SUCH_PAGE; otherwise PAGE_EXISTS is returned. 939 * The {@code Graphics} class or subclass implements the 940 * {@link java.awt.PrintGraphics} interface to provide additional 941 * information. If the {@code Printable} object 942 * aborts the print job then it throws a {@link PrinterException}. 943 * @param graphics the context into which the page is drawn 944 * @param pageFormat the size and orientation of the page being drawn 945 * @param pageIndex the zero based index of the page to be drawn 946 * @return PAGE_EXISTS if the page is rendered successfully 947 * or NO_SUCH_PAGE if {@code pageIndex} specifies a 948 * non-existent page. 949 * @exception java.awt.print.PrinterException 950 * thrown when the print job is terminated. 951 */ 952 public int print(Graphics graphics, PageFormat pageFormat, int pageIndex) 953 throws PrinterException { 954 955 int result; 956 957 /* This method will be called by the PrinterJob on a thread other 958 * that the application's thread. We hold on to the graphics 959 * until we can rendevous with the application's thread and 960 * hand over the graphics. The application then does all the 961 * drawing. When the application is done drawing we rendevous 962 * again with the PrinterJob thread and release the Graphics 963 * so that it knows we are done. 964 */ 965 966 /* Add the graphics to the message queue of graphics to 967 * be rendered. This is really a one slot queue. The 968 * application's thread will come along and remove the 969 * graphics from the queue when the app asks for a graphics. 970 */ 971 graphicsToBeDrawn.append( (Graphics2D) graphics); 972 973 /* We now wait for the app's thread to finish drawing on 974 * the Graphics. This thread will sleep until the application 975 * release the graphics by placing it in the graphics drawn 976 * message queue. If the application signals that it is 977 * finished drawing the entire document then we'll get null 978 * returned when we try and pop a finished graphic. 979 */ 980 if (graphicsDrawn.pop() != null) { 981 result = PAGE_EXISTS; 982 } else { 983 result = NO_SUCH_PAGE; 984 } 985 986 return result; 987 } 988 989 private void startPrinterJobThread() { 990 printerJobThread = new ManagedLocalsThread(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<Graphics2D> 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 = 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 }