blob: 3b11089352ff8416a1f508601bfbc2149e3beb25 [file] [log] [blame]
J. Duke319a3b92007-12-01 00:00:00 +00001/*
2 * Copyright 1999-2006 Sun Microsystems, Inc. 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. Sun designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
22 * CA 95054 USA or visit www.sun.com if you need additional information or
23 * have any questions.
24 */
25
26package java.awt;
27
28/**
29 * A set of attributes which control a print job.
30 * <p>
31 * Instances of this class control the number of copies, default selection,
32 * destination, print dialog, file and printer names, page ranges, multiple
33 * document handling (including collation), and multi-page imposition (such
34 * as duplex) of every print job which uses the instance. Attribute names are
35 * compliant with the Internet Printing Protocol (IPP) 1.1 where possible.
36 * Attribute values are partially compliant where possible.
37 * <p>
38 * To use a method which takes an inner class type, pass a reference to
39 * one of the constant fields of the inner class. Client code cannot create
40 * new instances of the inner class types because none of those classes
41 * has a public constructor. For example, to set the print dialog type to
42 * the cross-platform, pure Java print dialog, use the following code:
43 * <pre>
44 * import java.awt.JobAttributes;
45 *
46 * public class PureJavaPrintDialogExample {
47 * public void setPureJavaPrintDialog(JobAttributes jobAttributes) {
48 * jobAttributes.setDialog(JobAttributes.DialogType.COMMON);
49 * }
50 * }
51 * </pre>
52 * <p>
53 * Every IPP attribute which supports an <i>attributeName</i>-default value
54 * has a corresponding <code>set<i>attributeName</i>ToDefault</code> method.
55 * Default value fields are not provided.
56 *
57 * @author David Mendenhall
58 * @since 1.3
59 */
60public final class JobAttributes implements Cloneable {
61 /**
62 * A type-safe enumeration of possible default selection states.
63 * @since 1.3
64 */
65 public static final class DefaultSelectionType extends AttributeValue {
66 private static final int I_ALL = 0;
67 private static final int I_RANGE = 1;
68 private static final int I_SELECTION = 2;
69
70 private static final String NAMES[] = {
71 "all", "range", "selection"
72 };
73
74 /**
75 * The <code>DefaultSelectionType</code> instance to use for
76 * specifying that all pages of the job should be printed.
77 */
78 public static final DefaultSelectionType ALL =
79 new DefaultSelectionType(I_ALL);
80 /**
81 * The <code>DefaultSelectionType</code> instance to use for
82 * specifying that a range of pages of the job should be printed.
83 */
84 public static final DefaultSelectionType RANGE =
85 new DefaultSelectionType(I_RANGE);
86 /**
87 * The <code>DefaultSelectionType</code> instance to use for
88 * specifying that the current selection should be printed.
89 */
90 public static final DefaultSelectionType SELECTION =
91 new DefaultSelectionType(I_SELECTION);
92
93 private DefaultSelectionType(int type) {
94 super(type, NAMES);
95 }
96 }
97
98 /**
99 * A type-safe enumeration of possible job destinations.
100 * @since 1.3
101 */
102 public static final class DestinationType extends AttributeValue {
103 private static final int I_FILE = 0;
104 private static final int I_PRINTER = 1;
105
106 private static final String NAMES[] = {
107 "file", "printer"
108 };
109
110 /**
111 * The <code>DestinationType</code> instance to use for
112 * specifying print to file.
113 */
114 public static final DestinationType FILE =
115 new DestinationType(I_FILE);
116 /**
117 * The <code>DestinationType</code> instance to use for
118 * specifying print to printer.
119 */
120 public static final DestinationType PRINTER =
121 new DestinationType(I_PRINTER);
122
123 private DestinationType(int type) {
124 super(type, NAMES);
125 }
126 }
127
128 /**
129 * A type-safe enumeration of possible dialogs to display to the user.
130 * @since 1.3
131 */
132 public static final class DialogType extends AttributeValue {
133 private static final int I_COMMON = 0;
134 private static final int I_NATIVE = 1;
135 private static final int I_NONE = 2;
136
137 private static final String NAMES[] = {
138 "common", "native", "none"
139 };
140
141 /**
142 * The <code>DialogType</code> instance to use for
143 * specifying the cross-platform, pure Java print dialog.
144 */
145 public static final DialogType COMMON = new DialogType(I_COMMON);
146 /**
147 * The <code>DialogType</code> instance to use for
148 * specifying the platform's native print dialog.
149 */
150 public static final DialogType NATIVE = new DialogType(I_NATIVE);
151 /**
152 * The <code>DialogType</code> instance to use for
153 * specifying no print dialog.
154 */
155 public static final DialogType NONE = new DialogType(I_NONE);
156
157 private DialogType(int type) {
158 super(type, NAMES);
159 }
160 }
161
162 /**
163 * A type-safe enumeration of possible multiple copy handling states.
164 * It is used to control how the sheets of multiple copies of a single
165 * document are collated.
166 * @since 1.3
167 */
168 public static final class MultipleDocumentHandlingType extends
169 AttributeValue {
170 private static final int I_SEPARATE_DOCUMENTS_COLLATED_COPIES = 0;
171 private static final int I_SEPARATE_DOCUMENTS_UNCOLLATED_COPIES = 1;
172
173 private static final String NAMES[] = {
174 "separate-documents-collated-copies",
175 "separate-documents-uncollated-copies"
176 };
177
178 /**
179 * The <code>MultipleDocumentHandlingType</code> instance to use for specifying
180 * that the job should be divided into separate, collated copies.
181 */
182 public static final MultipleDocumentHandlingType
183 SEPARATE_DOCUMENTS_COLLATED_COPIES =
184 new MultipleDocumentHandlingType(
185 I_SEPARATE_DOCUMENTS_COLLATED_COPIES);
186 /**
187 * The <code>MultipleDocumentHandlingType</code> instance to use for specifying
188 * that the job should be divided into separate, uncollated copies.
189 */
190 public static final MultipleDocumentHandlingType
191 SEPARATE_DOCUMENTS_UNCOLLATED_COPIES =
192 new MultipleDocumentHandlingType(
193 I_SEPARATE_DOCUMENTS_UNCOLLATED_COPIES);
194
195 private MultipleDocumentHandlingType(int type) {
196 super(type, NAMES);
197 }
198 }
199
200 /**
201 * A type-safe enumeration of possible multi-page impositions. These
202 * impositions are in compliance with IPP 1.1.
203 * @since 1.3
204 */
205 public static final class SidesType extends AttributeValue {
206 private static final int I_ONE_SIDED = 0;
207 private static final int I_TWO_SIDED_LONG_EDGE = 1;
208 private static final int I_TWO_SIDED_SHORT_EDGE = 2;
209
210 private static final String NAMES[] = {
211 "one-sided", "two-sided-long-edge", "two-sided-short-edge"
212 };
213
214 /**
215 * The <code>SidesType</code> instance to use for specifying that
216 * consecutive job pages should be printed upon the same side of
217 * consecutive media sheets.
218 */
219 public static final SidesType ONE_SIDED = new SidesType(I_ONE_SIDED);
220 /**
221 * The <code>SidesType</code> instance to use for specifying that
222 * consecutive job pages should be printed upon front and back sides
223 * of consecutive media sheets, such that the orientation of each pair
224 * of pages on the medium would be correct for the reader as if for
225 * binding on the long edge.
226 */
227 public static final SidesType TWO_SIDED_LONG_EDGE =
228 new SidesType(I_TWO_SIDED_LONG_EDGE);
229 /**
230 * The <code>SidesType</code> instance to use for specifying that
231 * consecutive job pages should be printed upon front and back sides
232 * of consecutive media sheets, such that the orientation of each pair
233 * of pages on the medium would be correct for the reader as if for
234 * binding on the short edge.
235 */
236 public static final SidesType TWO_SIDED_SHORT_EDGE =
237 new SidesType(I_TWO_SIDED_SHORT_EDGE);
238
239 private SidesType(int type) {
240 super(type, NAMES);
241 }
242 }
243
244 private int copies;
245 private DefaultSelectionType defaultSelection;
246 private DestinationType destination;
247 private DialogType dialog;
248 private String fileName;
249 private int fromPage;
250 private int maxPage;
251 private int minPage;
252 private MultipleDocumentHandlingType multipleDocumentHandling;
253 private int[][] pageRanges;
254 private int prFirst;
255 private int prLast;
256 private String printer;
257 private SidesType sides;
258 private int toPage;
259
260 /**
261 * Constructs a <code>JobAttributes</code> instance with default
262 * values for every attribute. The dialog defaults to
263 * <code>DialogType.NATIVE</code>. Min page defaults to
264 * <code>1</code>. Max page defaults to <code>Integer.MAX_VALUE</code>.
265 * Destination defaults to <code>DestinationType.PRINTER</code>.
266 * Selection defaults to <code>DefaultSelectionType.ALL</code>.
267 * Number of copies defaults to <code>1</code>. Multiple document handling defaults
268 * to <code>MultipleDocumentHandlingType.SEPARATE_DOCUMENTS_UNCOLLATED_COPIES</code>.
269 * Sides defaults to <code>SidesType.ONE_SIDED</code>. File name defaults
270 * to <code>null</code>.
271 */
272 public JobAttributes() {
273 setCopiesToDefault();
274 setDefaultSelection(DefaultSelectionType.ALL);
275 setDestination(DestinationType.PRINTER);
276 setDialog(DialogType.NATIVE);
277 setMaxPage(Integer.MAX_VALUE);
278 setMinPage(1);
279 setMultipleDocumentHandlingToDefault();
280 setSidesToDefault();
281 }
282
283 /**
284 * Constructs a <code>JobAttributes</code> instance which is a copy
285 * of the supplied <code>JobAttributes</code>.
286 *
287 * @param obj the <code>JobAttributes</code> to copy
288 */
289 public JobAttributes(JobAttributes obj) {
290 set(obj);
291 }
292
293 /**
294 * Constructs a <code>JobAttributes</code> instance with the
295 * specified values for every attribute.
296 *
297 * @param copies an integer greater than 0
298 * @param defaultSelection <code>DefaultSelectionType.ALL</code>,
299 * <code>DefaultSelectionType.RANGE</code>, or
300 * <code>DefaultSelectionType.SELECTION</code>
301 * @param destination <code>DesintationType.FILE</code> or
302 * <code>DesintationType.PRINTER</code>
303 * @param dialog <code>DialogType.COMMON</code>,
304 * <code>DialogType.NATIVE</code>, or
305 * <code>DialogType.NONE</code>
306 * @param fileName the possibly <code>null</code> file name
307 * @param maxPage an integer greater than zero and greater than or equal
308 * to <i>minPage</i>
309 * @param minPage an integer greater than zero and less than or equal
310 * to <i>maxPage</i>
311 * @param multipleDocumentHandling
312 * <code>MultipleDocumentHandlingType.SEPARATE_DOCUMENTS_COLLATED_COPIES</code> or
313 * <code>MultipleDocumentHandlingType.SEPARATE_DOCUMENTS_UNCOLLATED_COPIES</code>
314 * @param pageRanges an array of integer arrays of two elements; an array
315 * is interpreted as a range spanning all pages including and
316 * between the specified pages; ranges must be in ascending
317 * order and must not overlap; specified page numbers cannot be
318 * less than <i>minPage</i> nor greater than <i>maxPage</i>;
319 * for example:
320 * <pre>
321 * (new int[][] { new int[] { 1, 3 }, new int[] { 5, 5 },
322 * new int[] { 15, 19 } }),
323 * </pre>
324 * specifies pages 1, 2, 3, 5, 15, 16, 17, 18, and 19. Note that
325 * (<code>new int[][] { new int[] { 1, 1 }, new int[] { 1, 2 } }</code>),
326 * is an invalid set of page ranges because the two ranges
327 * overlap
328 * @param printer the possibly <code>null</code> printer name
329 * @param sides <code>SidesType.ONE_SIDED</code>,
330 * <code>SidesType.TWO_SIDED_LONG_EDGE</code>, or
331 * <code>SidesType.TWO_SIDED_SHORT_EDGE</code>
332 * @throws IllegalArgumentException if one or more of the above
333 * conditions is violated
334 */
335 public JobAttributes(int copies, DefaultSelectionType defaultSelection,
336 DestinationType destination, DialogType dialog,
337 String fileName, int maxPage, int minPage,
338 MultipleDocumentHandlingType multipleDocumentHandling,
339 int[][] pageRanges, String printer, SidesType sides) {
340 setCopies(copies);
341 setDefaultSelection(defaultSelection);
342 setDestination(destination);
343 setDialog(dialog);
344 setFileName(fileName);
345 setMaxPage(maxPage);
346 setMinPage(minPage);
347 setMultipleDocumentHandling(multipleDocumentHandling);
348 setPageRanges(pageRanges);
349 setPrinter(printer);
350 setSides(sides);
351 }
352
353 /**
354 * Creates and returns a copy of this <code>JobAttributes</code>.
355 *
356 * @return the newly created copy; it is safe to cast this Object into
357 * a <code>JobAttributes</code>
358 */
359 public Object clone() {
360 try {
361 return super.clone();
362 } catch (CloneNotSupportedException e) {
363 // Since we implement Cloneable, this should never happen
364 throw new InternalError();
365 }
366 }
367
368 /**
369 * Sets all of the attributes of this <code>JobAttributes</code> to
370 * the same values as the attributes of obj.
371 *
372 * @param obj the <code>JobAttributes</code> to copy
373 */
374 public void set(JobAttributes obj) {
375 copies = obj.copies;
376 defaultSelection = obj.defaultSelection;
377 destination = obj.destination;
378 dialog = obj.dialog;
379 fileName = obj.fileName;
380 fromPage = obj.fromPage;
381 maxPage = obj.maxPage;
382 minPage = obj.minPage;
383 multipleDocumentHandling = obj.multipleDocumentHandling;
384 // okay because we never modify the contents of pageRanges
385 pageRanges = obj.pageRanges;
386 prFirst = obj.prFirst;
387 prLast = obj.prLast;
388 printer = obj.printer;
389 sides = obj.sides;
390 toPage = obj.toPage;
391 }
392
393 /**
394 * Returns the number of copies the application should render for jobs
395 * using these attributes. This attribute is updated to the value chosen
396 * by the user.
397 *
398 * @return an integer greater than 0.
399 */
400 public int getCopies() {
401 return copies;
402 }
403
404 /**
405 * Specifies the number of copies the application should render for jobs
406 * using these attributes. Not specifying this attribute is equivalent to
407 * specifying <code>1</code>.
408 *
409 * @param copies an integer greater than 0
410 * @throws IllegalArgumentException if <code>copies</code> is less than
411 * or equal to 0
412 */
413 public void setCopies(int copies) {
414 if (copies <= 0) {
415 throw new IllegalArgumentException("Invalid value for attribute "+
416 "copies");
417 }
418 this.copies = copies;
419 }
420
421 /**
422 * Sets the number of copies the application should render for jobs using
423 * these attributes to the default. The default number of copies is 1.
424 */
425 public void setCopiesToDefault() {
426 setCopies(1);
427 }
428
429 /**
430 * Specifies whether, for jobs using these attributes, the application
431 * should print all pages, the range specified by the return value of
432 * <code>getPageRanges</code>, or the current selection. This attribute
433 * is updated to the value chosen by the user.
434 *
435 * @return DefaultSelectionType.ALL, DefaultSelectionType.RANGE, or
436 * DefaultSelectionType.SELECTION
437 */
438 public DefaultSelectionType getDefaultSelection() {
439 return defaultSelection;
440 }
441
442 /**
443 * Specifies whether, for jobs using these attributes, the application
444 * should print all pages, the range specified by the return value of
445 * <code>getPageRanges</code>, or the current selection. Not specifying
446 * this attribute is equivalent to specifying DefaultSelectionType.ALL.
447 *
448 * @param defaultSelection DefaultSelectionType.ALL,
449 * DefaultSelectionType.RANGE, or DefaultSelectionType.SELECTION.
450 * @throws IllegalArgumentException if defaultSelection is <code>null</code>
451 */
452 public void setDefaultSelection(DefaultSelectionType defaultSelection) {
453 if (defaultSelection == null) {
454 throw new IllegalArgumentException("Invalid value for attribute "+
455 "defaultSelection");
456 }
457 this.defaultSelection = defaultSelection;
458 }
459
460 /**
461 * Specifies whether output will be to a printer or a file for jobs using
462 * these attributes. This attribute is updated to the value chosen by the
463 * user.
464 *
465 * @return DesintationType.FILE or DesintationType.PRINTER
466 */
467 public DestinationType getDestination() {
468 return destination;
469 }
470
471 /**
472 * Specifies whether output will be to a printer or a file for jobs using
473 * these attributes. Not specifying this attribute is equivalent to
474 * specifying DesintationType.PRINTER.
475 *
476 * @param destination DesintationType.FILE or DesintationType.PRINTER.
477 * @throws IllegalArgumentException if destination is null.
478 */
479 public void setDestination(DestinationType destination) {
480 if (destination == null) {
481 throw new IllegalArgumentException("Invalid value for attribute "+
482 "destination");
483 }
484 this.destination = destination;
485 }
486
487 /**
488 * Returns whether, for jobs using these attributes, the user should see
489 * a print dialog in which to modify the print settings, and which type of
490 * print dialog should be displayed. DialogType.COMMON denotes a cross-
491 * platform, pure Java print dialog. DialogType.NATIVE denotes the
492 * platform's native print dialog. If a platform does not support a native
493 * print dialog, the pure Java print dialog is displayed instead.
494 * DialogType.NONE specifies no print dialog (i.e., background printing).
495 * This attribute cannot be modified by, and is not subject to any
496 * limitations of, the implementation or the target printer.
497 *
498 * @return <code>DialogType.COMMON</code>, <code>DialogType.NATIVE</code>, or
499 * <code>DialogType.NONE</code>
500 */
501 public DialogType getDialog() {
502 return dialog;
503 }
504
505 /**
506 * Specifies whether, for jobs using these attributes, the user should see
507 * a print dialog in which to modify the print settings, and which type of
508 * print dialog should be displayed. DialogType.COMMON denotes a cross-
509 * platform, pure Java print dialog. DialogType.NATIVE denotes the
510 * platform's native print dialog. If a platform does not support a native
511 * print dialog, the pure Java print dialog is displayed instead.
512 * DialogType.NONE specifies no print dialog (i.e., background printing).
513 * Not specifying this attribute is equivalent to specifying
514 * DialogType.NATIVE.
515 *
516 * @param dialog DialogType.COMMON, DialogType.NATIVE, or
517 * DialogType.NONE.
518 * @throws IllegalArgumentException if dialog is null.
519 */
520 public void setDialog(DialogType dialog) {
521 if (dialog == null) {
522 throw new IllegalArgumentException("Invalid value for attribute "+
523 "dialog");
524 }
525 this.dialog = dialog;
526 }
527
528 /**
529 * Specifies the file name for the output file for jobs using these
530 * attributes. This attribute is updated to the value chosen by the user.
531 *
532 * @return the possibly <code>null</code> file name
533 */
534 public String getFileName() {
535 return fileName;
536 }
537
538 /**
539 * Specifies the file name for the output file for jobs using these
540 * attributes. Default is platform-dependent and implementation-defined.
541 *
542 * @param fileName the possibly null file name.
543 */
544 public void setFileName(String fileName) {
545 this.fileName = fileName;
546 }
547
548 /**
549 * Returns, for jobs using these attributes, the first page to be
550 * printed, if a range of pages is to be printed. This attribute is
551 * updated to the value chosen by the user. An application should ignore
552 * this attribute on output, unless the return value of the <code>
553 * getDefaultSelection</code> method is DefaultSelectionType.RANGE. An
554 * application should honor the return value of <code>getPageRanges</code>
555 * over the return value of this method, if possible.
556 *
557 * @return an integer greater than zero and less than or equal to
558 * <i>toPage</i> and greater than or equal to <i>minPage</i> and
559 * less than or equal to <i>maxPage</i>.
560 */
561 public int getFromPage() {
562 if (fromPage != 0) {
563 return fromPage;
564 } else if (toPage != 0) {
565 return getMinPage();
566 } else if (pageRanges != null) {
567 return prFirst;
568 } else {
569 return getMinPage();
570 }
571 }
572
573 /**
574 * Specifies, for jobs using these attributes, the first page to be
575 * printed, if a range of pages is to be printed. If this attribute is not
576 * specified, then the values from the pageRanges attribute are used. If
577 * pageRanges and either or both of fromPage and toPage are specified,
578 * pageRanges takes precedence. Specifying none of pageRanges, fromPage,
579 * or toPage is equivalent to calling
580 * setPageRanges(new int[][] { new int[] { <i>minPage</i> } });
581 *
582 * @param fromPage an integer greater than zero and less than or equal to
583 * <i>toPage</i> and greater than or equal to <i>minPage</i> and
584 * less than or equal to <i>maxPage</i>.
585 * @throws IllegalArgumentException if one or more of the above
586 * conditions is violated.
587 */
588 public void setFromPage(int fromPage) {
589 if (fromPage <= 0 ||
590 (toPage != 0 && fromPage > toPage) ||
591 fromPage < minPage ||
592 fromPage > maxPage) {
593 throw new IllegalArgumentException("Invalid value for attribute "+
594 "fromPage");
595 }
596 this.fromPage = fromPage;
597 }
598
599 /**
600 * Specifies the maximum value the user can specify as the last page to
601 * be printed for jobs using these attributes. This attribute cannot be
602 * modified by, and is not subject to any limitations of, the
603 * implementation or the target printer.
604 *
605 * @return an integer greater than zero and greater than or equal
606 * to <i>minPage</i>.
607 */
608 public int getMaxPage() {
609 return maxPage;
610 }
611
612 /**
613 * Specifies the maximum value the user can specify as the last page to
614 * be printed for jobs using these attributes. Not specifying this
615 * attribute is equivalent to specifying <code>Integer.MAX_VALUE</code>.
616 *
617 * @param maxPage an integer greater than zero and greater than or equal
618 * to <i>minPage</i>
619 * @throws IllegalArgumentException if one or more of the above
620 * conditions is violated
621 */
622 public void setMaxPage(int maxPage) {
623 if (maxPage <= 0 || maxPage < minPage) {
624 throw new IllegalArgumentException("Invalid value for attribute "+
625 "maxPage");
626 }
627 this.maxPage = maxPage;
628 }
629
630 /**
631 * Specifies the minimum value the user can specify as the first page to
632 * be printed for jobs using these attributes. This attribute cannot be
633 * modified by, and is not subject to any limitations of, the
634 * implementation or the target printer.
635 *
636 * @return an integer greater than zero and less than or equal
637 * to <i>maxPage</i>.
638 */
639 public int getMinPage() {
640 return minPage;
641 }
642
643 /**
644 * Specifies the minimum value the user can specify as the first page to
645 * be printed for jobs using these attributes. Not specifying this
646 * attribute is equivalent to specifying <code>1</code>.
647 *
648 * @param minPage an integer greater than zero and less than or equal
649 * to <i>maxPage</i>.
650 * @throws IllegalArgumentException if one or more of the above
651 * conditions is violated.
652 */
653 public void setMinPage(int minPage) {
654 if (minPage <= 0 || minPage > maxPage) {
655 throw new IllegalArgumentException("Invalid value for attribute "+
656 "minPage");
657 }
658 this.minPage = minPage;
659 }
660
661 /**
662 * Specifies the handling of multiple copies, including collation, for
663 * jobs using these attributes. This attribute is updated to the value
664 * chosen by the user.
665 *
666 * @return
667 * MultipleDocumentHandlingType.SEPARATE_DOCUMENTS_COLLATED_COPIES or
668 * MultipleDocumentHandlingType.SEPARATE_DOCUMENTS_UNCOLLATED_COPIES.
669 */
670 public MultipleDocumentHandlingType getMultipleDocumentHandling() {
671 return multipleDocumentHandling;
672 }
673
674 /**
675 * Specifies the handling of multiple copies, including collation, for
676 * jobs using these attributes. Not specifying this attribute is equivalent
677 * to specifying
678 * MultipleDocumentHandlingType.SEPARATE_DOCUMENTS_UNCOLLATED_COPIES.
679 *
680 * @param multipleDocumentHandling
681 * MultipleDocumentHandlingType.SEPARATE_DOCUMENTS_COLLATED_COPIES or
682 * MultipleDocumentHandlingType.SEPARATE_DOCUMENTS_UNCOLLATED_COPIES.
683 * @throws IllegalArgumentException if multipleDocumentHandling is null.
684 */
685 public void setMultipleDocumentHandling(MultipleDocumentHandlingType
686 multipleDocumentHandling) {
687 if (multipleDocumentHandling == null) {
688 throw new IllegalArgumentException("Invalid value for attribute "+
689 "multipleDocumentHandling");
690 }
691 this.multipleDocumentHandling = multipleDocumentHandling;
692 }
693
694 /**
695 * Sets the handling of multiple copies, including collation, for jobs
696 * using these attributes to the default. The default handling is
697 * MultipleDocumentHandlingType.SEPARATE_DOCUMENTS_UNCOLLATED_COPIES.
698 */
699 public void setMultipleDocumentHandlingToDefault() {
700 setMultipleDocumentHandling(
701 MultipleDocumentHandlingType.SEPARATE_DOCUMENTS_UNCOLLATED_COPIES);
702 }
703
704 /**
705 * Specifies, for jobs using these attributes, the ranges of pages to be
706 * printed, if a range of pages is to be printed. All range numbers are
707 * inclusive. This attribute is updated to the value chosen by the user.
708 * An application should ignore this attribute on output, unless the
709 * return value of the <code>getDefaultSelection</code> method is
710 * DefaultSelectionType.RANGE.
711 *
712 * @return an array of integer arrays of 2 elements. An array
713 * is interpreted as a range spanning all pages including and
714 * between the specified pages. Ranges must be in ascending
715 * order and must not overlap. Specified page numbers cannot be
716 * less than <i>minPage</i> nor greater than <i>maxPage</i>.
717 * For example:
718 * (new int[][] { new int[] { 1, 3 }, new int[] { 5, 5 },
719 * new int[] { 15, 19 } }),
720 * specifies pages 1, 2, 3, 5, 15, 16, 17, 18, and 19.
721 */
722 public int[][] getPageRanges() {
723 if (pageRanges != null) {
724 // Return a copy because otherwise client code could circumvent the
725 // the checks made in setPageRanges by modifying the returned
726 // array.
727 int[][] copy = new int[pageRanges.length][2];
728 for (int i = 0; i < pageRanges.length; i++) {
729 copy[i][0] = pageRanges[i][0];
730 copy[i][1] = pageRanges[i][1];
731 }
732 return copy;
733 } else if (fromPage != 0 || toPage != 0) {
734 int fromPage = getFromPage();
735 int toPage = getToPage();
736 return new int[][] { new int[] { fromPage, toPage } };
737 } else {
738 int minPage = getMinPage();
739 return new int[][] { new int[] { minPage, minPage } };
740 }
741 }
742
743 /**
744 * Specifies, for jobs using these attributes, the ranges of pages to be
745 * printed, if a range of pages is to be printed. All range numbers are
746 * inclusive. If this attribute is not specified, then the values from the
747 * fromPage and toPages attributes are used. If pageRanges and either or
748 * both of fromPage and toPage are specified, pageRanges takes precedence.
749 * Specifying none of pageRanges, fromPage, or toPage is equivalent to
750 * calling setPageRanges(new int[][] { new int[] { <i>minPage</i>,
751 * <i>minPage</i> } });
752 *
753 * @param pageRanges an array of integer arrays of 2 elements. An array
754 * is interpreted as a range spanning all pages including and
755 * between the specified pages. Ranges must be in ascending
756 * order and must not overlap. Specified page numbers cannot be
757 * less than <i>minPage</i> nor greater than <i>maxPage</i>.
758 * For example:
759 * (new int[][] { new int[] { 1, 3 }, new int[] { 5, 5 },
760 * new int[] { 15, 19 } }),
761 * specifies pages 1, 2, 3, 5, 15, 16, 17, 18, and 19. Note that
762 * (new int[][] { new int[] { 1, 1 }, new int[] { 1, 2 } }),
763 * is an invalid set of page ranges because the two ranges
764 * overlap.
765 * @throws IllegalArgumentException if one or more of the above
766 * conditions is violated.
767 */
768 public void setPageRanges(int[][] pageRanges) {
769 String xcp = "Invalid value for attribute pageRanges";
770 int first = 0;
771 int last = 0;
772
773 if (pageRanges == null) {
774 throw new IllegalArgumentException(xcp);
775 }
776
777 for (int i = 0; i < pageRanges.length; i++) {
778 if (pageRanges[i] == null ||
779 pageRanges[i].length != 2 ||
780 pageRanges[i][0] <= last ||
781 pageRanges[i][1] < pageRanges[i][0]) {
782 throw new IllegalArgumentException(xcp);
783 }
784 last = pageRanges[i][1];
785 if (first == 0) {
786 first = pageRanges[i][0];
787 }
788 }
789
790 if (first < minPage || last > maxPage) {
791 throw new IllegalArgumentException(xcp);
792 }
793
794 // Store a copy because otherwise client code could circumvent the
795 // the checks made above by holding a reference to the array and
796 // modifying it after calling setPageRanges.
797 int[][] copy = new int[pageRanges.length][2];
798 for (int i = 0; i < pageRanges.length; i++) {
799 copy[i][0] = pageRanges[i][0];
800 copy[i][1] = pageRanges[i][1];
801 }
802 this.pageRanges = copy;
803 this.prFirst = first;
804 this.prLast = last;
805 }
806
807 /**
808 * Returns the destination printer for jobs using these attributes. This
809 * attribute is updated to the value chosen by the user.
810 *
811 * @return the possibly null printer name.
812 */
813 public String getPrinter() {
814 return printer;
815 }
816
817 /**
818 * Specifies the destination printer for jobs using these attributes.
819 * Default is platform-dependent and implementation-defined.
820 *
821 * @param printer the possibly null printer name.
822 */
823 public void setPrinter(String printer) {
824 this.printer = printer;
825 }
826
827 /**
828 * Returns how consecutive pages should be imposed upon the sides of the
829 * print medium for jobs using these attributes. SidesType.ONE_SIDED
830 * imposes each consecutive page upon the same side of consecutive media
831 * sheets. This imposition is sometimes called <i>simplex</i>.
832 * SidesType.TWO_SIDED_LONG_EDGE imposes each consecutive pair of pages
833 * upon front and back sides of consecutive media sheets, such that the
834 * orientation of each pair of pages on the medium would be correct for
835 * the reader as if for binding on the long edge. This imposition is
836 * sometimes called <i>duplex</i>. SidesType.TWO_SIDED_SHORT_EDGE imposes
837 * each consecutive pair of pages upon front and back sides of consecutive
838 * media sheets, such that the orientation of each pair of pages on the
839 * medium would be correct for the reader as if for binding on the short
840 * edge. This imposition is sometimes called <i>tumble</i>. This attribute
841 * is updated to the value chosen by the user.
842 *
843 * @return SidesType.ONE_SIDED, SidesType.TWO_SIDED_LONG_EDGE, or
844 * SidesType.TWO_SIDED_SHORT_EDGE.
845 */
846 public SidesType getSides() {
847 return sides;
848 }
849
850 /**
851 * Specifies how consecutive pages should be imposed upon the sides of the
852 * print medium for jobs using these attributes. SidesType.ONE_SIDED
853 * imposes each consecutive page upon the same side of consecutive media
854 * sheets. This imposition is sometimes called <i>simplex</i>.
855 * SidesType.TWO_SIDED_LONG_EDGE imposes each consecutive pair of pages
856 * upon front and back sides of consecutive media sheets, such that the
857 * orientation of each pair of pages on the medium would be correct for
858 * the reader as if for binding on the long edge. This imposition is
859 * sometimes called <i>duplex</i>. SidesType.TWO_SIDED_SHORT_EDGE imposes
860 * each consecutive pair of pages upon front and back sides of consecutive
861 * media sheets, such that the orientation of each pair of pages on the
862 * medium would be correct for the reader as if for binding on the short
863 * edge. This imposition is sometimes called <i>tumble</i>. Not specifying
864 * this attribute is equivalent to specifying SidesType.ONE_SIDED.
865 *
866 * @param sides SidesType.ONE_SIDED, SidesType.TWO_SIDED_LONG_EDGE, or
867 * SidesType.TWO_SIDED_SHORT_EDGE.
868 * @throws IllegalArgumentException if sides is null.
869 */
870 public void setSides(SidesType sides) {
871 if (sides == null) {
872 throw new IllegalArgumentException("Invalid value for attribute "+
873 "sides");
874 }
875 this.sides = sides;
876 }
877
878 /**
879 * Sets how consecutive pages should be imposed upon the sides of the
880 * print medium for jobs using these attributes to the default. The
881 * default imposition is SidesType.ONE_SIDED.
882 */
883 public void setSidesToDefault() {
884 setSides(SidesType.ONE_SIDED);
885 }
886
887 /**
888 * Returns, for jobs using these attributes, the last page (inclusive)
889 * to be printed, if a range of pages is to be printed. This attribute is
890 * updated to the value chosen by the user. An application should ignore
891 * this attribute on output, unless the return value of the <code>
892 * getDefaultSelection</code> method is DefaultSelectionType.RANGE. An
893 * application should honor the return value of <code>getPageRanges</code>
894 * over the return value of this method, if possible.
895 *
896 * @return an integer greater than zero and greater than or equal
897 * to <i>toPage</i> and greater than or equal to <i>minPage</i>
898 * and less than or equal to <i>maxPage</i>.
899 */
900 public int getToPage() {
901 if (toPage != 0) {
902 return toPage;
903 } else if (fromPage != 0) {
904 return fromPage;
905 } else if (pageRanges != null) {
906 return prLast;
907 } else {
908 return getMinPage();
909 }
910 }
911
912 /**
913 * Specifies, for jobs using these attributes, the last page (inclusive)
914 * to be printed, if a range of pages is to be printed.
915 * If this attribute is not specified, then the values from the pageRanges
916 * attribute are used. If pageRanges and either or both of fromPage and
917 * toPage are specified, pageRanges takes precedence. Specifying none of
918 * pageRanges, fromPage, or toPage is equivalent to calling
919 * setPageRanges(new int[][] { new int[] { <i>minPage</i> } });
920 *
921 * @param toPage an integer greater than zero and greater than or equal
922 * to <i>fromPage</i> and greater than or equal to <i>minPage</i>
923 * and less than or equal to <i>maxPage</i>.
924 * @throws IllegalArgumentException if one or more of the above
925 * conditions is violated.
926 */
927 public void setToPage(int toPage) {
928 if (toPage <= 0 ||
929 (fromPage != 0 && toPage < fromPage) ||
930 toPage < minPage ||
931 toPage > maxPage) {
932 throw new IllegalArgumentException("Invalid value for attribute "+
933 "toPage");
934 }
935 this.toPage = toPage;
936 }
937
938 /**
939 * Determines whether two JobAttributes are equal to each other.
940 * <p>
941 * Two JobAttributes are equal if and only if each of their attributes are
942 * equal. Attributes of enumeration type are equal if and only if the
943 * fields refer to the same unique enumeration object. A set of page
944 * ranges is equal if and only if the sets are of equal length, each range
945 * enumerates the same pages, and the ranges are in the same order.
946 *
947 * @param obj the object whose equality will be checked.
948 * @return whether obj is equal to this JobAttribute according to the
949 * above criteria.
950 */
951 public boolean equals(Object obj) {
952 if (!(obj instanceof JobAttributes)) {
953 return false;
954 }
955 JobAttributes rhs = (JobAttributes)obj;
956
957 if (fileName == null) {
958 if (rhs.fileName != null) {
959 return false;
960 }
961 } else {
962 if (!fileName.equals(rhs.fileName)) {
963 return false;
964 }
965 }
966
967 if (pageRanges == null) {
968 if (rhs.pageRanges != null) {
969 return false;
970 }
971 } else {
972 if (rhs.pageRanges == null ||
973 pageRanges.length != rhs.pageRanges.length) {
974 return false;
975 }
976 for (int i = 0; i < pageRanges.length; i++) {
977 if (pageRanges[i][0] != rhs.pageRanges[i][0] ||
978 pageRanges[i][1] != rhs.pageRanges[i][1]) {
979 return false;
980 }
981 }
982 }
983
984 if (printer == null) {
985 if (rhs.printer != null) {
986 return false;
987 }
988 } else {
989 if (!printer.equals(rhs.printer)) {
990 return false;
991 }
992 }
993
994 return (copies == rhs.copies &&
995 defaultSelection == rhs.defaultSelection &&
996 destination == rhs.destination &&
997 dialog == rhs.dialog &&
998 fromPage == rhs.fromPage &&
999 maxPage == rhs.maxPage &&
1000 minPage == rhs.minPage &&
1001 multipleDocumentHandling == rhs.multipleDocumentHandling &&
1002 prFirst == rhs.prFirst &&
1003 prLast == rhs.prLast &&
1004 sides == rhs.sides &&
1005 toPage == rhs.toPage);
1006 }
1007
1008 /**
1009 * Returns a hash code value for this JobAttributes.
1010 *
1011 * @return the hash code.
1012 */
1013 public int hashCode() {
1014 int rest = ((copies + fromPage + maxPage + minPage + prFirst + prLast +
1015 toPage) * 31) << 21;
1016 if (pageRanges != null) {
1017 int sum = 0;
1018 for (int i = 0; i < pageRanges.length; i++) {
1019 sum += pageRanges[i][0] + pageRanges[i][1];
1020 }
1021 rest ^= (sum * 31) << 11;
1022 }
1023 if (fileName != null) {
1024 rest ^= fileName.hashCode();
1025 }
1026 if (printer != null) {
1027 rest ^= printer.hashCode();
1028 }
1029 return (defaultSelection.hashCode() << 6 ^
1030 destination.hashCode() << 5 ^
1031 dialog.hashCode() << 3 ^
1032 multipleDocumentHandling.hashCode() << 2 ^
1033 sides.hashCode() ^
1034 rest);
1035 }
1036
1037 /**
1038 * Returns a string representation of this JobAttributes.
1039 *
1040 * @return the string representation.
1041 */
1042 public String toString() {
1043 int[][] pageRanges = getPageRanges();
1044 String prStr = "[";
1045 boolean first = true;
1046 for (int i = 0; i < pageRanges.length; i++) {
1047 if (first) {
1048 first = false;
1049 } else {
1050 prStr += ",";
1051 }
1052 prStr += pageRanges[i][0] + ":" + pageRanges[i][1];
1053 }
1054 prStr += "]";
1055
1056 return "copies=" + getCopies() + ",defaultSelection=" +
1057 getDefaultSelection() + ",destination=" + getDestination() +
1058 ",dialog=" + getDialog() + ",fileName=" + getFileName() +
1059 ",fromPage=" + getFromPage() + ",maxPage=" + getMaxPage() +
1060 ",minPage=" + getMinPage() + ",multiple-document-handling=" +
1061 getMultipleDocumentHandling() + ",page-ranges=" + prStr +
1062 ",printer=" + getPrinter() + ",sides=" + getSides() + ",toPage=" +
1063 getToPage();
1064 }
1065}