1 /* 2 * Copyright (c) 2000, 2021, 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.DialogOwner; 64 import javax.print.attribute.standard.JobName; 65 import javax.print.attribute.standard.MediaSize; 66 import javax.print.attribute.standard.PrintQuality; 67 import javax.print.attribute.standard.PrinterResolution; 68 import javax.print.attribute.standard.SheetCollate; 69 import javax.print.attribute.standard.Sides; 70 import javax.print.attribute.standard.Media; 71 import javax.print.attribute.standard.OrientationRequested; 72 import javax.print.attribute.standard.MediaSizeName; 73 import javax.print.attribute.standard.PageRanges; 74 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 PrintJob2D(Frame frame, String doctitle, final Properties props)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 PrintJob2D(Frame frame, String doctitle, JobAttributes jobAttributes, PageAttributes pageAttributes)308 public PrintJob2D(Frame frame, String doctitle, 309 JobAttributes jobAttributes, 310 PageAttributes pageAttributes) { 311 initPrintJob2D(frame, doctitle, jobAttributes, pageAttributes); 312 } 313 initPrintJob2D(Frame frame, String doctitle, JobAttributes jobAttributes, PageAttributes pageAttributes)314 private void initPrintJob2D(Frame frame, String doctitle, 315 JobAttributes jobAttributes, 316 PageAttributes pageAttributes) { 317 318 @SuppressWarnings("removal") 319 SecurityManager security = System.getSecurityManager(); 320 if (security != null) { 321 security.checkPrintJobAccess(); 322 } 323 324 if (frame == null && 325 (jobAttributes == null || 326 jobAttributes.getDialog() == DialogType.NATIVE)) { 327 throw new NullPointerException("Frame must not be null"); 328 } 329 this.frame = frame; 330 331 this.docTitle = (doctitle == null) ? "" : doctitle; 332 this.jobAttributes = (jobAttributes != null) 333 ? jobAttributes : new JobAttributes(); 334 this.pageAttributes = (pageAttributes != null) 335 ? pageAttributes : new PageAttributes(); 336 337 // Currently, we always reduce page ranges to xxx or xxx-xxx 338 int[][] pageRanges = this.jobAttributes.getPageRanges(); 339 int first = pageRanges[0][0]; 340 int last = pageRanges[pageRanges.length - 1][1]; 341 this.jobAttributes.setPageRanges(new int[][] { 342 new int[] { first, last } 343 }); 344 this.jobAttributes.setToPage(last); 345 this.jobAttributes.setFromPage(first); 346 347 348 // Verify that the cross feed and feed resolutions are the same 349 int[] res = this.pageAttributes.getPrinterResolution(); 350 if (res[0] != res[1]) { 351 throw new IllegalArgumentException("Differing cross feed and feed"+ 352 " resolutions not supported."); 353 } 354 355 // Verify that the app has access to the file system 356 DestinationType dest= this.jobAttributes.getDestination(); 357 if (dest == DestinationType.FILE) { 358 throwPrintToFile(); 359 360 // check if given filename is valid 361 String destStr = jobAttributes.getFileName(); 362 if ((destStr != null) && 363 (jobAttributes.getDialog() == JobAttributes.DialogType.NONE)) { 364 365 File f = new File(destStr); 366 try { 367 // check if this is a new file and if filename chars are valid 368 // createNewFile returns false if file exists 369 if (f.createNewFile()) { 370 f.delete(); 371 } 372 } catch (IOException ioe) { 373 throw new IllegalArgumentException("Cannot write to file:"+ 374 destStr); 375 } catch (SecurityException se) { 376 //There is already file read/write access so at this point 377 // only delete access is denied. Just ignore it because in 378 // most cases the file created in createNewFile gets overwritten 379 // anyway. 380 } 381 382 File pFile = f.getParentFile(); 383 if ((f.exists() && 384 (!f.isFile() || !f.canWrite())) || 385 ((pFile != null) && 386 (!pFile.exists() || (pFile.exists() && !pFile.canWrite())))) { 387 throw new IllegalArgumentException("Cannot write to file:"+ 388 destStr); 389 } 390 } 391 } 392 } 393 printDialog()394 public boolean printDialog() { 395 396 boolean proceedWithPrint = false; 397 398 printerJob = PrinterJob.getPrinterJob(); 399 if (printerJob == null) { 400 return false; 401 } 402 DialogType d = this.jobAttributes.getDialog(); 403 PrintService pServ = printerJob.getPrintService(); 404 if ((pServ == null) && (d == DialogType.NONE)){ 405 return false; 406 } 407 copyAttributes(pServ); 408 409 DefaultSelectionType select = 410 this.jobAttributes.getDefaultSelection(); 411 if (select == DefaultSelectionType.RANGE) { 412 attributes.add(SunPageSelection.RANGE); 413 } else if (select == DefaultSelectionType.SELECTION) { 414 attributes.add(SunPageSelection.SELECTION); 415 } else { 416 attributes.add(SunPageSelection.ALL); 417 } 418 419 if (frame != null) { 420 attributes.add(new DialogOwner(frame)); 421 } 422 423 if ( d == DialogType.NONE) { 424 proceedWithPrint = true; 425 } else { 426 if (d == DialogType.NATIVE) { 427 attributes.add(DialogTypeSelection.NATIVE); 428 } else { // (d == DialogType.COMMON) 429 attributes.add(DialogTypeSelection.COMMON); 430 } 431 if (proceedWithPrint = printerJob.printDialog(attributes)) { 432 if (pServ == null) { 433 // Windows gives an option to install a service 434 // when it detects there are no printers so 435 // we make sure we get the updated print service. 436 pServ = printerJob.getPrintService(); 437 if (pServ == null) { 438 return false; 439 } 440 } 441 updateAttributes(); 442 translateOutputProps(); 443 } 444 } 445 446 if (proceedWithPrint) { 447 448 JobName jname = (JobName)attributes.get(JobName.class); 449 if (jname != null) { 450 printerJob.setJobName(jname.toString()); 451 } 452 453 pageFormat = new PageFormat(); 454 455 Media media = (Media)attributes.get(Media.class); 456 MediaSize mediaSize = null; 457 if (media != null && media instanceof MediaSizeName) { 458 mediaSize = MediaSize.getMediaSizeForName((MediaSizeName)media); 459 } 460 461 Paper p = pageFormat.getPaper(); 462 if (mediaSize != null) { 463 p.setSize(mediaSize.getX(MediaSize.INCH)*72.0, 464 mediaSize.getY(MediaSize.INCH)*72.0); 465 } 466 467 if (pageAttributes.getOrigin()==OriginType.PRINTABLE) { 468 // AWT uses 1/4" borders by default 469 p.setImageableArea(18.0, 18.0, 470 p.getWidth()-36.0, 471 p.getHeight()-36.0); 472 } else { 473 p.setImageableArea(0.0,0.0,p.getWidth(),p.getHeight()); 474 } 475 476 pageFormat.setPaper(p); 477 478 OrientationRequested orient = 479 (OrientationRequested)attributes.get(OrientationRequested.class); 480 if (orient!= null && 481 orient == OrientationRequested.REVERSE_LANDSCAPE) { 482 pageFormat.setOrientation(PageFormat.REVERSE_LANDSCAPE); 483 } else if (orient == OrientationRequested.LANDSCAPE) { 484 pageFormat.setOrientation(PageFormat.LANDSCAPE); 485 } else { 486 pageFormat.setOrientation(PageFormat.PORTRAIT); 487 } 488 489 PageRanges pageRangesAttr 490 = (PageRanges) attributes.get(PageRanges.class); 491 if (pageRangesAttr != null) { 492 // Get the PageRanges from print dialog. 493 int[][] range = pageRangesAttr.getMembers(); 494 495 int prevFromPage = this.jobAttributes.getFromPage(); 496 int prevToPage = this.jobAttributes.getToPage(); 497 498 int currFromPage = range[0][0]; 499 int currToPage = range[range.length - 1][1]; 500 501 // if from < to update fromPage first followed by toPage 502 // else update toPage first followed by fromPage 503 if (currFromPage < prevToPage) { 504 this.jobAttributes.setFromPage(currFromPage); 505 this.jobAttributes.setToPage(currToPage); 506 } else { 507 this.jobAttributes.setToPage(currToPage); 508 this.jobAttributes.setFromPage(currFromPage); 509 } 510 } 511 printerJob.setPrintable(this, pageFormat); 512 513 } 514 515 return proceedWithPrint; 516 } 517 updateAttributes()518 private void updateAttributes() { 519 Copies c = (Copies)attributes.get(Copies.class); 520 jobAttributes.setCopies(c.getValue()); 521 522 SunPageSelection sel = 523 (SunPageSelection)attributes.get(SunPageSelection.class); 524 if (sel == SunPageSelection.RANGE) { 525 jobAttributes.setDefaultSelection(DefaultSelectionType.RANGE); 526 } else if (sel == SunPageSelection.SELECTION) { 527 jobAttributes.setDefaultSelection(DefaultSelectionType.SELECTION); 528 } else { 529 jobAttributes.setDefaultSelection(DefaultSelectionType.ALL); 530 } 531 532 Destination dest = (Destination)attributes.get(Destination.class); 533 if (dest != null) { 534 jobAttributes.setDestination(DestinationType.FILE); 535 jobAttributes.setFileName(dest.getURI().getPath()); 536 } else { 537 jobAttributes.setDestination(DestinationType.PRINTER); 538 } 539 540 PrintService serv = printerJob.getPrintService(); 541 if (serv != null) { 542 jobAttributes.setPrinter(serv.getName()); 543 } 544 545 PageRanges range = (PageRanges)attributes.get(PageRanges.class); 546 int[][] members = range.getMembers(); 547 jobAttributes.setPageRanges(members); 548 549 SheetCollate collation = 550 (SheetCollate)attributes.get(SheetCollate.class); 551 if (collation == SheetCollate.COLLATED) { 552 jobAttributes.setMultipleDocumentHandling( 553 MultipleDocumentHandlingType.SEPARATE_DOCUMENTS_COLLATED_COPIES); 554 } else { 555 jobAttributes.setMultipleDocumentHandling( 556 MultipleDocumentHandlingType.SEPARATE_DOCUMENTS_UNCOLLATED_COPIES); 557 } 558 559 Sides sides = (Sides)attributes.get(Sides.class); 560 if (sides == Sides.TWO_SIDED_LONG_EDGE) { 561 jobAttributes.setSides(SidesType.TWO_SIDED_LONG_EDGE); 562 } else if (sides == Sides.TWO_SIDED_SHORT_EDGE) { 563 jobAttributes.setSides(SidesType.TWO_SIDED_SHORT_EDGE); 564 } else { 565 jobAttributes.setSides(SidesType.ONE_SIDED); 566 } 567 568 // PageAttributes 569 570 Chromaticity color = 571 (Chromaticity)attributes.get(Chromaticity.class); 572 if (color == Chromaticity.COLOR) { 573 pageAttributes.setColor(ColorType.COLOR); 574 } else { 575 pageAttributes.setColor(ColorType.MONOCHROME); 576 } 577 578 OrientationRequested orient = 579 (OrientationRequested)attributes.get(OrientationRequested.class); 580 if (orient == OrientationRequested.LANDSCAPE) { 581 pageAttributes.setOrientationRequested( 582 OrientationRequestedType.LANDSCAPE); 583 } else { 584 pageAttributes.setOrientationRequested( 585 OrientationRequestedType.PORTRAIT); 586 } 587 588 PrintQuality qual = (PrintQuality)attributes.get(PrintQuality.class); 589 if (qual == PrintQuality.DRAFT) { 590 pageAttributes.setPrintQuality(PrintQualityType.DRAFT); 591 } else if (qual == PrintQuality.HIGH) { 592 pageAttributes.setPrintQuality(PrintQualityType.HIGH); 593 } else { // NORMAL 594 pageAttributes.setPrintQuality(PrintQualityType.NORMAL); 595 } 596 597 Media msn = (Media)attributes.get(Media.class); 598 if (msn != null && msn instanceof MediaSizeName) { 599 MediaType mType = unMapMedia((MediaSizeName)msn); 600 601 if (mType != null) { 602 pageAttributes.setMedia(mType); 603 } 604 } 605 debugPrintAttributes(false, false); 606 } 607 debugPrintAttributes(boolean ja, boolean pa )608 private void debugPrintAttributes(boolean ja, boolean pa ) { 609 if (ja) { 610 System.out.println("new Attributes\ncopies = "+ 611 jobAttributes.getCopies()+ 612 "\nselection = "+ 613 jobAttributes.getDefaultSelection()+ 614 "\ndest "+jobAttributes.getDestination()+ 615 "\nfile "+jobAttributes.getFileName()+ 616 "\nfromPage "+jobAttributes.getFromPage()+ 617 "\ntoPage "+jobAttributes.getToPage()+ 618 "\ncollation "+ 619 jobAttributes.getMultipleDocumentHandling()+ 620 "\nPrinter "+jobAttributes.getPrinter()+ 621 "\nSides2 "+jobAttributes.getSides() 622 ); 623 } 624 625 if (pa) { 626 System.out.println("new Attributes\ncolor = "+ 627 pageAttributes.getColor()+ 628 "\norientation = "+ 629 pageAttributes.getOrientationRequested()+ 630 "\nquality "+pageAttributes.getPrintQuality()+ 631 "\nMedia2 "+pageAttributes.getMedia() 632 ); 633 } 634 } 635 636 637 /* From JobAttributes we will copy job name and duplex printing 638 * and destination. 639 * The majority of the rest of the attributes are reflected 640 * attributes. 641 * 642 * From PageAttributes we copy color, media size, orientation, 643 * origin type, resolution and print quality. 644 * We use the media, orientation in creating the page format, and 645 * the origin type to set its imageable area. 646 * 647 * REMIND: Interpretation of resolution, additional media sizes. 648 */ copyAttributes(PrintService printServ)649 private void copyAttributes(PrintService printServ) { 650 651 attributes = new HashPrintRequestAttributeSet(); 652 attributes.add(new JobName(docTitle, null)); 653 PrintService pServ = printServ; 654 655 String printerName = jobAttributes.getPrinter(); 656 if (printerName != null && printerName != "" 657 && pServ != null && !printerName.equals(pServ.getName())) { 658 659 // Search for the given printerName in the list of PrintServices 660 PrintService []services = PrinterJob.lookupPrintServices(); 661 try { 662 for (int i=0; i<services.length; i++) { 663 if (printerName.equals(services[i].getName())) { 664 printerJob.setPrintService(services[i]); 665 pServ = services[i]; 666 break; 667 } 668 } 669 } catch (PrinterException pe) { 670 } 671 } 672 673 DestinationType dest = jobAttributes.getDestination(); 674 if (dest == DestinationType.FILE && pServ != null && 675 pServ.isAttributeCategorySupported(Destination.class)) { 676 677 String fileName = jobAttributes.getFileName(); 678 679 Destination defaultDest; 680 if (fileName == null && (defaultDest = (Destination)pServ. 681 getDefaultAttributeValue(Destination.class)) != null) { 682 attributes.add(defaultDest); 683 } else { 684 URI uri = null; 685 try { 686 if (fileName != null) { 687 if (fileName.isEmpty()) { 688 fileName = "."; 689 } 690 } else { 691 // defaultDest should not be null. The following code 692 // is only added to safeguard against a possible 693 // buggy implementation of a PrintService having a 694 // null default Destination. 695 fileName = "out.prn"; 696 } 697 uri = (new File(fileName)).toURI(); 698 } catch (SecurityException se) { 699 try { 700 // '\\' file separator is illegal character in opaque 701 // part and causes URISyntaxException, so we replace 702 // it with '/' 703 fileName = fileName.replace('\\', '/'); 704 uri = new URI("file:"+fileName); 705 } catch (URISyntaxException e) { 706 } 707 } 708 if (uri != null) { 709 attributes.add(new Destination(uri)); 710 } 711 } 712 } 713 attributes.add(new SunMinMaxPage(jobAttributes.getMinPage(), 714 jobAttributes.getMaxPage())); 715 SidesType sType = jobAttributes.getSides(); 716 if (sType == SidesType.TWO_SIDED_LONG_EDGE) { 717 attributes.add(Sides.TWO_SIDED_LONG_EDGE); 718 } else if (sType == SidesType.TWO_SIDED_SHORT_EDGE) { 719 attributes.add(Sides.TWO_SIDED_SHORT_EDGE); 720 } else if (sType == SidesType.ONE_SIDED) { 721 attributes.add(Sides.ONE_SIDED); 722 } 723 724 MultipleDocumentHandlingType hType = 725 jobAttributes.getMultipleDocumentHandling(); 726 if (hType == 727 MultipleDocumentHandlingType.SEPARATE_DOCUMENTS_COLLATED_COPIES) { 728 attributes.add(SheetCollate.COLLATED); 729 } else { 730 attributes.add(SheetCollate.UNCOLLATED); 731 } 732 733 attributes.add(new Copies(jobAttributes.getCopies())); 734 735 attributes.add(new PageRanges(jobAttributes.getFromPage(), 736 jobAttributes.getToPage())); 737 738 if (pageAttributes.getColor() == ColorType.COLOR) { 739 attributes.add(Chromaticity.COLOR); 740 } else { 741 attributes.add(Chromaticity.MONOCHROME); 742 } 743 744 pageFormat = printerJob.defaultPage(); 745 if (pageAttributes.getOrientationRequested() == 746 OrientationRequestedType.LANDSCAPE) { 747 pageFormat.setOrientation(PageFormat.LANDSCAPE); 748 attributes.add(OrientationRequested.LANDSCAPE); 749 } else { 750 pageFormat.setOrientation(PageFormat.PORTRAIT); 751 attributes.add(OrientationRequested.PORTRAIT); 752 } 753 754 MediaType media = pageAttributes.getMedia(); 755 MediaSizeName msn = mapMedia(media); 756 if (msn != null) { 757 attributes.add(msn); 758 } 759 760 PrintQualityType qType = 761 pageAttributes.getPrintQuality(); 762 if (qType == PrintQualityType.DRAFT) { 763 attributes.add(PrintQuality.DRAFT); 764 } else if (qType == PrintQualityType.NORMAL) { 765 attributes.add(PrintQuality.NORMAL); 766 } else if (qType == PrintQualityType.HIGH) { 767 attributes.add(PrintQuality.HIGH); 768 } 769 } 770 771 /** 772 * Gets a Graphics object that will draw to the next page. 773 * The page is sent to the printer when the graphics 774 * object is disposed. This graphics object will also implement 775 * the PrintGraphics interface. 776 * @see java.awt.PrintGraphics 777 */ getGraphics()778 public Graphics getGraphics() { 779 780 Graphics printGraphics = null; 781 782 synchronized (this) { 783 ++pageIndex; 784 785 // Thread should not be created after end has been called. 786 // One way to detect this is if any of the graphics queue 787 // has been closed. 788 if (pageIndex == 0 && !graphicsToBeDrawn.isClosed()) { 789 790 /* We start a thread on which the PrinterJob will run. 791 * The PrinterJob will ask for pages on that thread 792 * and will use a message queue to fulfill the application's 793 * requests for a Graphics on the application's 794 * thread. 795 */ 796 797 startPrinterJobThread(); 798 799 } 800 notify(); 801 } 802 803 /* If the application has already been handed back 804 * a graphics then we need to put that graphics into 805 * the drawn queue so that the PrinterJob thread can 806 * return to the print system. 807 */ 808 if (currentGraphics != null) { 809 graphicsDrawn.append(currentGraphics); 810 currentGraphics = null; 811 } 812 813 /* We'll block here until a new graphics becomes 814 * available. 815 */ 816 817 currentGraphics = graphicsToBeDrawn.pop(); 818 819 if (currentGraphics instanceof PeekGraphics) { 820 ( (PeekGraphics) currentGraphics).setAWTDrawingOnly(); 821 graphicsDrawn.append(currentGraphics); 822 currentGraphics = graphicsToBeDrawn.pop(); 823 } 824 825 826 if (currentGraphics != null) { 827 828 /* In the PrintJob API, the origin is at the upper- 829 * left of the imageable area when using the new "printable" 830 * origin attribute, otherwise its the physical origin (for 831 * backwards compatibility. We emulate this by createing 832 * a PageFormat which matches and then performing the 833 * translate to the origin. This is a no-op if physical 834 * origin is specified. 835 */ 836 currentGraphics.translate(pageFormat.getImageableX(), 837 pageFormat.getImageableY()); 838 839 /* Scale to accommodate AWT's notion of printer resolution */ 840 double awtScale = 72.0/getPageResolutionInternal(); 841 currentGraphics.scale(awtScale, awtScale); 842 843 /* The caller wants a Graphics instance but we do 844 * not want them to make 2D calls. We can't hand 845 * back a Graphics2D. The returned Graphics also 846 * needs to implement PrintGraphics, so we wrap 847 * the Graphics2D instance. The PrintJob API has 848 * the application dispose of the Graphics so 849 * we create a copy of the one returned by PrinterJob. 850 */ 851 printGraphics = new ProxyPrintGraphics(currentGraphics.create(), 852 this); 853 854 } 855 856 return printGraphics; 857 } 858 859 /** 860 * Returns the dimensions of the page in pixels. 861 * The resolution of the page is chosen so that it 862 * is similar to the screen resolution. 863 * Except (since 1.3) when the application specifies a resolution. 864 * In that case it is scaled accordingly. 865 */ getPageDimension()866 public Dimension getPageDimension() { 867 double wid, hgt, scale; 868 if (pageAttributes != null && 869 pageAttributes.getOrigin()==OriginType.PRINTABLE) { 870 wid = pageFormat.getImageableWidth(); 871 hgt = pageFormat.getImageableHeight(); 872 } else { 873 wid = pageFormat.getWidth(); 874 hgt = pageFormat.getHeight(); 875 } 876 scale = getPageResolutionInternal() / 72.0; 877 return new Dimension((int)(wid * scale), (int)(hgt * scale)); 878 } 879 getPageResolutionInternal()880 private double getPageResolutionInternal() { 881 if (pageAttributes != null) { 882 int []res = pageAttributes.getPrinterResolution(); 883 if (res[2] == 3) { 884 return res[0]; 885 } else /* if (res[2] == 4) */ { 886 return (res[0] * 2.54); 887 } 888 } else { 889 return 72.0; 890 } 891 } 892 893 /** 894 * Returns the resolution of the page in pixels per inch. 895 * Note that this doesn't have to correspond to the physical 896 * resolution of the printer. 897 */ getPageResolution()898 public int getPageResolution() { 899 return (int)getPageResolutionInternal(); 900 } 901 902 /** 903 * Returns true if the last page will be printed first. 904 */ lastPageFirst()905 public boolean lastPageFirst() { 906 return false; 907 } 908 909 /** 910 * Ends the print job and does any necessary cleanup. 911 */ end()912 public synchronized void end() { 913 914 /* Prevent the PrinterJob thread from appending any more 915 * graphics to the to-be-drawn queue 916 */ 917 graphicsToBeDrawn.close(); 918 919 /* If we have a currentGraphics it was the last one returned to the 920 * PrintJob client. Append it to the drawn queue so that print() 921 * will return allowing the page to be flushed. 922 * This really ought to happen in dispose() but for whatever reason 923 * that isn't how the old PrintJob worked even though its spec 924 * said dispose() flushed the page. 925 */ 926 if (currentGraphics != null) { 927 graphicsDrawn.append(currentGraphics); 928 } 929 graphicsDrawn.closeWhenEmpty(); 930 931 /* Wait for the PrinterJob.print() thread to terminate, ensuring 932 * that RasterPrinterJob has made its end doc call, and resources 933 * are released, files closed etc. 934 */ 935 if( printerJobThread != null && printerJobThread.isAlive() ){ 936 try { 937 printerJobThread.join(); 938 } catch (InterruptedException e) { 939 } 940 } 941 } 942 943 /** 944 * Ends this print job once it is no longer referenced. 945 * @see #end 946 */ 947 @SuppressWarnings("deprecation") finalize()948 public void finalize() { 949 end(); 950 } 951 952 /** 953 * Prints the page at the specified index into the specified 954 * {@link Graphics} context in the specified 955 * format. A {@code PrinterJob} calls the 956 * {@code Printable} interface to request that a page be 957 * rendered into the context specified by 958 * {@code graphics}. The format of the page to be drawn is 959 * specified by {@code pageFormat}. The zero based index 960 * of the requested page is specified by {@code pageIndex}. 961 * If the requested page does not exist then this method returns 962 * NO_SUCH_PAGE; otherwise PAGE_EXISTS is returned. 963 * The {@code Graphics} class or subclass implements the 964 * {@link java.awt.PrintGraphics} interface to provide additional 965 * information. If the {@code Printable} object 966 * aborts the print job then it throws a {@link PrinterException}. 967 * @param graphics the context into which the page is drawn 968 * @param pageFormat the size and orientation of the page being drawn 969 * @param pageIndex the zero based index of the page to be drawn 970 * @return PAGE_EXISTS if the page is rendered successfully 971 * or NO_SUCH_PAGE if {@code pageIndex} specifies a 972 * non-existent page. 973 * @exception java.awt.print.PrinterException 974 * thrown when the print job is terminated. 975 */ print(Graphics graphics, PageFormat pageFormat, int pageIndex)976 public int print(Graphics graphics, PageFormat pageFormat, int pageIndex) 977 throws PrinterException { 978 979 int result; 980 981 /* This method will be called by the PrinterJob on a thread other 982 * that the application's thread. We hold on to the graphics 983 * until we can rendevous with the application's thread and 984 * hand over the graphics. The application then does all the 985 * drawing. When the application is done drawing we rendevous 986 * again with the PrinterJob thread and release the Graphics 987 * so that it knows we are done. 988 */ 989 990 /* Add the graphics to the message queue of graphics to 991 * be rendered. This is really a one slot queue. The 992 * application's thread will come along and remove the 993 * graphics from the queue when the app asks for a graphics. 994 */ 995 graphicsToBeDrawn.append( (Graphics2D) graphics); 996 997 /* We now wait for the app's thread to finish drawing on 998 * the Graphics. This thread will sleep until the application 999 * release the graphics by placing it in the graphics drawn 1000 * message queue. If the application signals that it is 1001 * finished drawing the entire document then we'll get null 1002 * returned when we try and pop a finished graphic. 1003 */ 1004 if (graphicsDrawn.pop() != null) { 1005 result = PAGE_EXISTS; 1006 } else { 1007 result = NO_SUCH_PAGE; 1008 } 1009 1010 return result; 1011 } 1012 startPrinterJobThread()1013 private void startPrinterJobThread() { 1014 printerJobThread = 1015 new Thread(null, this, "printerJobThread", 0, false); 1016 printerJobThread.start(); 1017 } 1018 1019 run()1020 public void run() { 1021 1022 try { 1023 attributes.remove(PageRanges.class); 1024 printerJob.print(attributes); 1025 } catch (PrinterException e) { 1026 //REMIND: need to store this away and not rethrow it. 1027 } 1028 1029 /* Close the message queues so that nobody is stuck 1030 * waiting for one. 1031 */ 1032 graphicsToBeDrawn.closeWhenEmpty(); 1033 graphicsDrawn.close(); 1034 } 1035 1036 private class MessageQ { 1037 1038 private String qid="noname"; 1039 1040 private ArrayList<Graphics2D> queue = new ArrayList<>(); 1041 MessageQ(String id)1042 MessageQ(String id) { 1043 qid = id; 1044 } 1045 closeWhenEmpty()1046 synchronized void closeWhenEmpty() { 1047 1048 while (queue != null && queue.size() > 0) { 1049 try { 1050 wait(1000); 1051 } catch (InterruptedException e) { 1052 // do nothing. 1053 } 1054 } 1055 1056 queue = null; 1057 notifyAll(); 1058 } 1059 close()1060 synchronized void close() { 1061 queue = null; 1062 notifyAll(); 1063 } 1064 append(Graphics2D g)1065 synchronized boolean append(Graphics2D g) { 1066 1067 boolean queued = false; 1068 1069 if (queue != null) { 1070 queue.add(g); 1071 queued = true; 1072 notify(); 1073 } 1074 1075 return queued; 1076 } 1077 pop()1078 synchronized Graphics2D pop() { 1079 Graphics2D g = null; 1080 1081 while (g == null && queue != null) { 1082 1083 if (queue.size() > 0) { 1084 g = queue.remove(0); 1085 notify(); 1086 1087 } else { 1088 try { 1089 wait(2000); 1090 } catch (InterruptedException e) { 1091 // do nothing. 1092 } 1093 } 1094 } 1095 1096 return g; 1097 } 1098 isClosed()1099 synchronized boolean isClosed() { 1100 return queue == null; 1101 } 1102 1103 } 1104 1105 getSize(MediaType mType)1106 private static int[] getSize(MediaType mType) { 1107 int []dim = new int[2]; 1108 dim[0] = 612; 1109 dim[1] = 792; 1110 1111 for (int i=0; i < SIZES.length; i++) { 1112 if (SIZES[i] == mType) { 1113 dim[0] = WIDTHS[i]; 1114 dim[1] = LENGTHS[i]; 1115 break; 1116 } 1117 } 1118 return dim; 1119 } 1120 mapMedia(MediaType mType)1121 public static MediaSizeName mapMedia(MediaType mType) { 1122 MediaSizeName media = null; 1123 1124 // JAVAXSIZES.length and SIZES.length must be equal! 1125 // Attempt to recover by getting the smaller size. 1126 int length = Math.min(SIZES.length, JAVAXSIZES.length); 1127 1128 for (int i=0; i < length; i++) { 1129 if (SIZES[i] == mType) { 1130 if ((JAVAXSIZES[i] != null) && 1131 MediaSize.getMediaSizeForName(JAVAXSIZES[i]) != null) { 1132 media = JAVAXSIZES[i]; 1133 break; 1134 } else { 1135 /* create Custom Media */ 1136 media = new CustomMediaSizeName(SIZES[i].toString()); 1137 1138 float w = (float)Math.rint(WIDTHS[i] / 72.0); 1139 float h = (float)Math.rint(LENGTHS[i] / 72.0); 1140 if (w > 0.0 && h > 0.0) { 1141 // add new created MediaSize to our static map 1142 // so it will be found when we call findMedia 1143 new MediaSize(w, h, Size2DSyntax.INCH, media); 1144 } 1145 1146 break; 1147 } 1148 } 1149 } 1150 return media; 1151 } 1152 1153 unMapMedia(MediaSizeName mSize)1154 public static MediaType unMapMedia(MediaSizeName mSize) { 1155 MediaType media = null; 1156 1157 // JAVAXSIZES.length and SIZES.length must be equal! 1158 // Attempt to recover by getting the smaller size. 1159 int length = Math.min(SIZES.length, JAVAXSIZES.length); 1160 1161 for (int i=0; i < length; i++) { 1162 if (JAVAXSIZES[i] == mSize) { 1163 if (SIZES[i] != null) { 1164 media = SIZES[i]; 1165 break; 1166 } 1167 } 1168 } 1169 return media; 1170 } 1171 translateInputProps()1172 private void translateInputProps() { 1173 if (props == null) { 1174 return; 1175 } 1176 1177 String str; 1178 1179 str = props.getProperty(DEST_PROP); 1180 if (str != null) { 1181 if (str.equals(PRINTER)) { 1182 jobAttributes.setDestination(DestinationType.PRINTER); 1183 } else if (str.equals(FILE)) { 1184 jobAttributes.setDestination(DestinationType.FILE); 1185 } 1186 } 1187 str = props.getProperty(PRINTER_PROP); 1188 if (str != null) { 1189 jobAttributes.setPrinter(str); 1190 } 1191 str = props.getProperty(FILENAME_PROP); 1192 if (str != null) { 1193 jobAttributes.setFileName(str); 1194 } 1195 str = props.getProperty(NUMCOPIES_PROP); 1196 if (str != null) { 1197 jobAttributes.setCopies(Integer.parseInt(str)); 1198 } 1199 1200 this.options = props.getProperty(OPTIONS_PROP, ""); 1201 1202 str = props.getProperty(ORIENT_PROP); 1203 if (str != null) { 1204 if (str.equals(PORTRAIT)) { 1205 pageAttributes.setOrientationRequested( 1206 OrientationRequestedType.PORTRAIT); 1207 } else if (str.equals(LANDSCAPE)) { 1208 pageAttributes.setOrientationRequested( 1209 OrientationRequestedType.LANDSCAPE); 1210 } 1211 } 1212 str = props.getProperty(PAPERSIZE_PROP); 1213 if (str != null) { 1214 if (str.equals(LETTER)) { 1215 pageAttributes.setMedia(SIZES[MediaType.LETTER.hashCode()]); 1216 } else if (str.equals(LEGAL)) { 1217 pageAttributes.setMedia(SIZES[MediaType.LEGAL.hashCode()]); 1218 } else if (str.equals(EXECUTIVE)) { 1219 pageAttributes.setMedia(SIZES[MediaType.EXECUTIVE.hashCode()]); 1220 } else if (str.equals(A4)) { 1221 pageAttributes.setMedia(SIZES[MediaType.A4.hashCode()]); 1222 } 1223 } 1224 } 1225 translateOutputProps()1226 private void translateOutputProps() { 1227 if (props == null) { 1228 return; 1229 } 1230 1231 String str; 1232 1233 props.setProperty(DEST_PROP, 1234 (jobAttributes.getDestination() == DestinationType.PRINTER) ? 1235 PRINTER : FILE); 1236 str = jobAttributes.getPrinter(); 1237 if (str != null && !str.isEmpty()) { 1238 props.setProperty(PRINTER_PROP, str); 1239 } 1240 str = jobAttributes.getFileName(); 1241 if (str != null && !str.isEmpty()) { 1242 props.setProperty(FILENAME_PROP, str); 1243 } 1244 int copies = jobAttributes.getCopies(); 1245 if (copies > 0) { 1246 props.setProperty(NUMCOPIES_PROP, "" + copies); 1247 } 1248 str = this.options; 1249 if (str != null && !str.isEmpty()) { 1250 props.setProperty(OPTIONS_PROP, str); 1251 } 1252 props.setProperty(ORIENT_PROP, 1253 (pageAttributes.getOrientationRequested() == 1254 OrientationRequestedType.PORTRAIT) 1255 ? PORTRAIT : LANDSCAPE); 1256 MediaType media = SIZES[pageAttributes.getMedia().hashCode()]; 1257 if (media == MediaType.LETTER) { 1258 str = LETTER; 1259 } else if (media == MediaType.LEGAL) { 1260 str = LEGAL; 1261 } else if (media == MediaType.EXECUTIVE) { 1262 str = EXECUTIVE; 1263 } else if (media == MediaType.A4) { 1264 str = A4; 1265 } else { 1266 str = media.toString(); 1267 } 1268 props.setProperty(PAPERSIZE_PROP, str); 1269 } 1270 throwPrintToFile()1271 private void throwPrintToFile() { 1272 @SuppressWarnings("removal") 1273 SecurityManager security = System.getSecurityManager(); 1274 FilePermission printToFilePermission = null; 1275 if (security != null) { 1276 if (printToFilePermission == null) { 1277 printToFilePermission = 1278 new FilePermission("<<ALL FILES>>", "read,write"); 1279 } 1280 security.checkPermission(printToFilePermission); 1281 } 1282 } 1283 1284 } 1285