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