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