0001: /*
0002: * Copyright 1999-2006 Sun Microsystems, Inc. All Rights Reserved.
0003: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
0004: *
0005: * This code is free software; you can redistribute it and/or modify it
0006: * under the terms of the GNU General Public License version 2 only, as
0007: * published by the Free Software Foundation. Sun designates this
0008: * particular file as subject to the "Classpath" exception as provided
0009: * by Sun in the LICENSE file that accompanied this code.
0010: *
0011: * This code is distributed in the hope that it will be useful, but WITHOUT
0012: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
0013: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
0014: * version 2 for more details (a copy is included in the LICENSE file that
0015: * accompanied this code).
0016: *
0017: * You should have received a copy of the GNU General Public License version
0018: * 2 along with this work; if not, write to the Free Software Foundation,
0019: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
0020: *
0021: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
0022: * CA 95054 USA or visit www.sun.com if you need additional information or
0023: * have any questions.
0024: */
0025:
0026: package java.awt;
0027:
0028: /**
0029: * A set of attributes which control a print job.
0030: * <p>
0031: * Instances of this class control the number of copies, default selection,
0032: * destination, print dialog, file and printer names, page ranges, multiple
0033: * document handling (including collation), and multi-page imposition (such
0034: * as duplex) of every print job which uses the instance. Attribute names are
0035: * compliant with the Internet Printing Protocol (IPP) 1.1 where possible.
0036: * Attribute values are partially compliant where possible.
0037: * <p>
0038: * To use a method which takes an inner class type, pass a reference to
0039: * one of the constant fields of the inner class. Client code cannot create
0040: * new instances of the inner class types because none of those classes
0041: * has a public constructor. For example, to set the print dialog type to
0042: * the cross-platform, pure Java print dialog, use the following code:
0043: * <pre>
0044: * import java.awt.JobAttributes;
0045: *
0046: * public class PureJavaPrintDialogExample {
0047: * public void setPureJavaPrintDialog(JobAttributes jobAttributes) {
0048: * jobAttributes.setDialog(JobAttributes.DialogType.COMMON);
0049: * }
0050: * }
0051: * </pre>
0052: * <p>
0053: * Every IPP attribute which supports an <i>attributeName</i>-default value
0054: * has a corresponding <code>set<i>attributeName</i>ToDefault</code> method.
0055: * Default value fields are not provided.
0056: *
0057: * @version 1.17, 05/05/07
0058: * @author David Mendenhall
0059: * @since 1.3
0060: */
0061: public final class JobAttributes implements Cloneable {
0062: /**
0063: * A type-safe enumeration of possible default selection states.
0064: * @since 1.3
0065: */
0066: public static final class DefaultSelectionType extends
0067: AttributeValue {
0068: private static final int I_ALL = 0;
0069: private static final int I_RANGE = 1;
0070: private static final int I_SELECTION = 2;
0071:
0072: private static final String NAMES[] = { "all", "range",
0073: "selection" };
0074:
0075: /**
0076: * The <code>DefaultSelectionType</code> instance to use for
0077: * specifying that all pages of the job should be printed.
0078: */
0079: public static final DefaultSelectionType ALL = new DefaultSelectionType(
0080: I_ALL);
0081: /**
0082: * The <code>DefaultSelectionType</code> instance to use for
0083: * specifying that a range of pages of the job should be printed.
0084: */
0085: public static final DefaultSelectionType RANGE = new DefaultSelectionType(
0086: I_RANGE);
0087: /**
0088: * The <code>DefaultSelectionType</code> instance to use for
0089: * specifying that the current selection should be printed.
0090: */
0091: public static final DefaultSelectionType SELECTION = new DefaultSelectionType(
0092: I_SELECTION);
0093:
0094: private DefaultSelectionType(int type) {
0095: super (type, NAMES);
0096: }
0097: }
0098:
0099: /**
0100: * A type-safe enumeration of possible job destinations.
0101: * @since 1.3
0102: */
0103: public static final class DestinationType extends AttributeValue {
0104: private static final int I_FILE = 0;
0105: private static final int I_PRINTER = 1;
0106:
0107: private static final String NAMES[] = { "file", "printer" };
0108:
0109: /**
0110: * The <code>DestinationType</code> instance to use for
0111: * specifying print to file.
0112: */
0113: public static final DestinationType FILE = new DestinationType(
0114: I_FILE);
0115: /**
0116: * The <code>DestinationType</code> instance to use for
0117: * specifying print to printer.
0118: */
0119: public static final DestinationType PRINTER = new DestinationType(
0120: I_PRINTER);
0121:
0122: private DestinationType(int type) {
0123: super (type, NAMES);
0124: }
0125: }
0126:
0127: /**
0128: * A type-safe enumeration of possible dialogs to display to the user.
0129: * @since 1.3
0130: */
0131: public static final class DialogType extends AttributeValue {
0132: private static final int I_COMMON = 0;
0133: private static final int I_NATIVE = 1;
0134: private static final int I_NONE = 2;
0135:
0136: private static final String NAMES[] = { "common", "native",
0137: "none" };
0138:
0139: /**
0140: * The <code>DialogType</code> instance to use for
0141: * specifying the cross-platform, pure Java print dialog.
0142: */
0143: public static final DialogType COMMON = new DialogType(I_COMMON);
0144: /**
0145: * The <code>DialogType</code> instance to use for
0146: * specifying the platform's native print dialog.
0147: */
0148: public static final DialogType NATIVE = new DialogType(I_NATIVE);
0149: /**
0150: * The <code>DialogType</code> instance to use for
0151: * specifying no print dialog.
0152: */
0153: public static final DialogType NONE = new DialogType(I_NONE);
0154:
0155: private DialogType(int type) {
0156: super (type, NAMES);
0157: }
0158: }
0159:
0160: /**
0161: * A type-safe enumeration of possible multiple copy handling states.
0162: * It is used to control how the sheets of multiple copies of a single
0163: * document are collated.
0164: * @since 1.3
0165: */
0166: public static final class MultipleDocumentHandlingType extends
0167: AttributeValue {
0168: private static final int I_SEPARATE_DOCUMENTS_COLLATED_COPIES = 0;
0169: private static final int I_SEPARATE_DOCUMENTS_UNCOLLATED_COPIES = 1;
0170:
0171: private static final String NAMES[] = {
0172: "separate-documents-collated-copies",
0173: "separate-documents-uncollated-copies" };
0174:
0175: /**
0176: * The <code>MultipleDocumentHandlingType</code> instance to use for specifying
0177: * that the job should be divided into separate, collated copies.
0178: */
0179: public static final MultipleDocumentHandlingType SEPARATE_DOCUMENTS_COLLATED_COPIES = new MultipleDocumentHandlingType(
0180: I_SEPARATE_DOCUMENTS_COLLATED_COPIES);
0181: /**
0182: * The <code>MultipleDocumentHandlingType</code> instance to use for specifying
0183: * that the job should be divided into separate, uncollated copies.
0184: */
0185: public static final MultipleDocumentHandlingType SEPARATE_DOCUMENTS_UNCOLLATED_COPIES = new MultipleDocumentHandlingType(
0186: I_SEPARATE_DOCUMENTS_UNCOLLATED_COPIES);
0187:
0188: private MultipleDocumentHandlingType(int type) {
0189: super (type, NAMES);
0190: }
0191: }
0192:
0193: /**
0194: * A type-safe enumeration of possible multi-page impositions. These
0195: * impositions are in compliance with IPP 1.1.
0196: * @since 1.3
0197: */
0198: public static final class SidesType extends AttributeValue {
0199: private static final int I_ONE_SIDED = 0;
0200: private static final int I_TWO_SIDED_LONG_EDGE = 1;
0201: private static final int I_TWO_SIDED_SHORT_EDGE = 2;
0202:
0203: private static final String NAMES[] = { "one-sided",
0204: "two-sided-long-edge", "two-sided-short-edge" };
0205:
0206: /**
0207: * The <code>SidesType</code> instance to use for specifying that
0208: * consecutive job pages should be printed upon the same side of
0209: * consecutive media sheets.
0210: */
0211: public static final SidesType ONE_SIDED = new SidesType(
0212: I_ONE_SIDED);
0213: /**
0214: * The <code>SidesType</code> instance to use for specifying that
0215: * consecutive job pages should be printed upon front and back sides
0216: * of consecutive media sheets, such that the orientation of each pair
0217: * of pages on the medium would be correct for the reader as if for
0218: * binding on the long edge.
0219: */
0220: public static final SidesType TWO_SIDED_LONG_EDGE = new SidesType(
0221: I_TWO_SIDED_LONG_EDGE);
0222: /**
0223: * The <code>SidesType</code> instance to use for specifying that
0224: * consecutive job pages should be printed upon front and back sides
0225: * of consecutive media sheets, such that the orientation of each pair
0226: * of pages on the medium would be correct for the reader as if for
0227: * binding on the short edge.
0228: */
0229: public static final SidesType TWO_SIDED_SHORT_EDGE = new SidesType(
0230: I_TWO_SIDED_SHORT_EDGE);
0231:
0232: private SidesType(int type) {
0233: super (type, NAMES);
0234: }
0235: }
0236:
0237: private int copies;
0238: private DefaultSelectionType defaultSelection;
0239: private DestinationType destination;
0240: private DialogType dialog;
0241: private String fileName;
0242: private int fromPage;
0243: private int maxPage;
0244: private int minPage;
0245: private MultipleDocumentHandlingType multipleDocumentHandling;
0246: private int[][] pageRanges;
0247: private int prFirst;
0248: private int prLast;
0249: private String printer;
0250: private SidesType sides;
0251: private int toPage;
0252:
0253: /**
0254: * Constructs a <code>JobAttributes</code> instance with default
0255: * values for every attribute. The dialog defaults to
0256: * <code>DialogType.NATIVE</code>. Min page defaults to
0257: * <code>1</code>. Max page defaults to <code>Integer.MAX_VALUE</code>.
0258: * Destination defaults to <code>DestinationType.PRINTER</code>.
0259: * Selection defaults to <code>DefaultSelectionType.ALL</code>.
0260: * Number of copies defaults to <code>1</code>. Multiple document handling defaults
0261: * to <code>MultipleDocumentHandlingType.SEPARATE_DOCUMENTS_UNCOLLATED_COPIES</code>.
0262: * Sides defaults to <code>SidesType.ONE_SIDED</code>. File name defaults
0263: * to <code>null</code>.
0264: */
0265: public JobAttributes() {
0266: setCopiesToDefault();
0267: setDefaultSelection(DefaultSelectionType.ALL);
0268: setDestination(DestinationType.PRINTER);
0269: setDialog(DialogType.NATIVE);
0270: setMaxPage(Integer.MAX_VALUE);
0271: setMinPage(1);
0272: setMultipleDocumentHandlingToDefault();
0273: setSidesToDefault();
0274: }
0275:
0276: /**
0277: * Constructs a <code>JobAttributes</code> instance which is a copy
0278: * of the supplied <code>JobAttributes</code>.
0279: *
0280: * @param obj the <code>JobAttributes</code> to copy
0281: */
0282: public JobAttributes(JobAttributes obj) {
0283: set(obj);
0284: }
0285:
0286: /**
0287: * Constructs a <code>JobAttributes</code> instance with the
0288: * specified values for every attribute.
0289: *
0290: * @param copies an integer greater than 0
0291: * @param defaultSelection <code>DefaultSelectionType.ALL</code>,
0292: * <code>DefaultSelectionType.RANGE</code>, or
0293: * <code>DefaultSelectionType.SELECTION</code>
0294: * @param destination <code>DesintationType.FILE</code> or
0295: * <code>DesintationType.PRINTER</code>
0296: * @param dialog <code>DialogType.COMMON</code>,
0297: * <code>DialogType.NATIVE</code>, or
0298: * <code>DialogType.NONE</code>
0299: * @param fileName the possibly <code>null</code> file name
0300: * @param maxPage an integer greater than zero and greater than or equal
0301: * to <i>minPage</i>
0302: * @param minPage an integer greater than zero and less than or equal
0303: * to <i>maxPage</i>
0304: * @param multipleDocumentHandling
0305: * <code>MultipleDocumentHandlingType.SEPARATE_DOCUMENTS_COLLATED_COPIES</code> or
0306: * <code>MultipleDocumentHandlingType.SEPARATE_DOCUMENTS_UNCOLLATED_COPIES</code>
0307: * @param pageRanges an array of integer arrays of two elements; an array
0308: * is interpreted as a range spanning all pages including and
0309: * between the specified pages; ranges must be in ascending
0310: * order and must not overlap; specified page numbers cannot be
0311: * less than <i>minPage</i> nor greater than <i>maxPage</i>;
0312: * for example:
0313: * <pre>
0314: * (new int[][] { new int[] { 1, 3 }, new int[] { 5, 5 },
0315: * new int[] { 15, 19 } }),
0316: * </pre>
0317: * specifies pages 1, 2, 3, 5, 15, 16, 17, 18, and 19. Note that
0318: * (<code>new int[][] { new int[] { 1, 1 }, new int[] { 1, 2 } }</code>),
0319: * is an invalid set of page ranges because the two ranges
0320: * overlap
0321: * @param printer the possibly <code>null</code> printer name
0322: * @param sides <code>SidesType.ONE_SIDED</code>,
0323: * <code>SidesType.TWO_SIDED_LONG_EDGE</code>, or
0324: * <code>SidesType.TWO_SIDED_SHORT_EDGE</code>
0325: * @throws IllegalArgumentException if one or more of the above
0326: * conditions is violated
0327: */
0328: public JobAttributes(int copies,
0329: DefaultSelectionType defaultSelection,
0330: DestinationType destination, DialogType dialog,
0331: String fileName, int maxPage, int minPage,
0332: MultipleDocumentHandlingType multipleDocumentHandling,
0333: int[][] pageRanges, String printer, SidesType sides) {
0334: setCopies(copies);
0335: setDefaultSelection(defaultSelection);
0336: setDestination(destination);
0337: setDialog(dialog);
0338: setFileName(fileName);
0339: setMaxPage(maxPage);
0340: setMinPage(minPage);
0341: setMultipleDocumentHandling(multipleDocumentHandling);
0342: setPageRanges(pageRanges);
0343: setPrinter(printer);
0344: setSides(sides);
0345: }
0346:
0347: /**
0348: * Creates and returns a copy of this <code>JobAttributes</code>.
0349: *
0350: * @return the newly created copy; it is safe to cast this Object into
0351: * a <code>JobAttributes</code>
0352: */
0353: public Object clone() {
0354: try {
0355: return super .clone();
0356: } catch (CloneNotSupportedException e) {
0357: // Since we implement Cloneable, this should never happen
0358: throw new InternalError();
0359: }
0360: }
0361:
0362: /**
0363: * Sets all of the attributes of this <code>JobAttributes</code> to
0364: * the same values as the attributes of obj.
0365: *
0366: * @param obj the <code>JobAttributes</code> to copy
0367: */
0368: public void set(JobAttributes obj) {
0369: copies = obj.copies;
0370: defaultSelection = obj.defaultSelection;
0371: destination = obj.destination;
0372: dialog = obj.dialog;
0373: fileName = obj.fileName;
0374: fromPage = obj.fromPage;
0375: maxPage = obj.maxPage;
0376: minPage = obj.minPage;
0377: multipleDocumentHandling = obj.multipleDocumentHandling;
0378: // okay because we never modify the contents of pageRanges
0379: pageRanges = obj.pageRanges;
0380: prFirst = obj.prFirst;
0381: prLast = obj.prLast;
0382: printer = obj.printer;
0383: sides = obj.sides;
0384: toPage = obj.toPage;
0385: }
0386:
0387: /**
0388: * Returns the number of copies the application should render for jobs
0389: * using these attributes. This attribute is updated to the value chosen
0390: * by the user.
0391: *
0392: * @return an integer greater than 0.
0393: */
0394: public int getCopies() {
0395: return copies;
0396: }
0397:
0398: /**
0399: * Specifies the number of copies the application should render for jobs
0400: * using these attributes. Not specifying this attribute is equivalent to
0401: * specifying <code>1</code>.
0402: *
0403: * @param copies an integer greater than 0
0404: * @throws IllegalArgumentException if <code>copies</code> is less than
0405: * or equal to 0
0406: */
0407: public void setCopies(int copies) {
0408: if (copies <= 0) {
0409: throw new IllegalArgumentException(
0410: "Invalid value for attribute " + "copies");
0411: }
0412: this .copies = copies;
0413: }
0414:
0415: /**
0416: * Sets the number of copies the application should render for jobs using
0417: * these attributes to the default. The default number of copies is 1.
0418: */
0419: public void setCopiesToDefault() {
0420: setCopies(1);
0421: }
0422:
0423: /**
0424: * Specifies whether, for jobs using these attributes, the application
0425: * should print all pages, the range specified by the return value of
0426: * <code>getPageRanges</code>, or the current selection. This attribute
0427: * is updated to the value chosen by the user.
0428: *
0429: * @return DefaultSelectionType.ALL, DefaultSelectionType.RANGE, or
0430: * DefaultSelectionType.SELECTION
0431: */
0432: public DefaultSelectionType getDefaultSelection() {
0433: return defaultSelection;
0434: }
0435:
0436: /**
0437: * Specifies whether, for jobs using these attributes, the application
0438: * should print all pages, the range specified by the return value of
0439: * <code>getPageRanges</code>, or the current selection. Not specifying
0440: * this attribute is equivalent to specifying DefaultSelectionType.ALL.
0441: *
0442: * @param defaultSelection DefaultSelectionType.ALL,
0443: * DefaultSelectionType.RANGE, or DefaultSelectionType.SELECTION.
0444: * @throws IllegalArgumentException if defaultSelection is <code>null</code>
0445: */
0446: public void setDefaultSelection(
0447: DefaultSelectionType defaultSelection) {
0448: if (defaultSelection == null) {
0449: throw new IllegalArgumentException(
0450: "Invalid value for attribute " + "defaultSelection");
0451: }
0452: this .defaultSelection = defaultSelection;
0453: }
0454:
0455: /**
0456: * Specifies whether output will be to a printer or a file for jobs using
0457: * these attributes. This attribute is updated to the value chosen by the
0458: * user.
0459: *
0460: * @return DesintationType.FILE or DesintationType.PRINTER
0461: */
0462: public DestinationType getDestination() {
0463: return destination;
0464: }
0465:
0466: /**
0467: * Specifies whether output will be to a printer or a file for jobs using
0468: * these attributes. Not specifying this attribute is equivalent to
0469: * specifying DesintationType.PRINTER.
0470: *
0471: * @param destination DesintationType.FILE or DesintationType.PRINTER.
0472: * @throws IllegalArgumentException if destination is null.
0473: */
0474: public void setDestination(DestinationType destination) {
0475: if (destination == null) {
0476: throw new IllegalArgumentException(
0477: "Invalid value for attribute " + "destination");
0478: }
0479: this .destination = destination;
0480: }
0481:
0482: /**
0483: * Returns whether, for jobs using these attributes, the user should see
0484: * a print dialog in which to modify the print settings, and which type of
0485: * print dialog should be displayed. DialogType.COMMON denotes a cross-
0486: * platform, pure Java print dialog. DialogType.NATIVE denotes the
0487: * platform's native print dialog. If a platform does not support a native
0488: * print dialog, the pure Java print dialog is displayed instead.
0489: * DialogType.NONE specifies no print dialog (i.e., background printing).
0490: * This attribute cannot be modified by, and is not subject to any
0491: * limitations of, the implementation or the target printer.
0492: *
0493: * @return <code>DialogType.COMMON</code>, <code>DialogType.NATIVE</code>, or
0494: * <code>DialogType.NONE</code>
0495: */
0496: public DialogType getDialog() {
0497: return dialog;
0498: }
0499:
0500: /**
0501: * Specifies whether, for jobs using these attributes, the user should see
0502: * a print dialog in which to modify the print settings, and which type of
0503: * print dialog should be displayed. DialogType.COMMON denotes a cross-
0504: * platform, pure Java print dialog. DialogType.NATIVE denotes the
0505: * platform's native print dialog. If a platform does not support a native
0506: * print dialog, the pure Java print dialog is displayed instead.
0507: * DialogType.NONE specifies no print dialog (i.e., background printing).
0508: * Not specifying this attribute is equivalent to specifying
0509: * DialogType.NATIVE.
0510: *
0511: * @param dialog DialogType.COMMON, DialogType.NATIVE, or
0512: * DialogType.NONE.
0513: * @throws IllegalArgumentException if dialog is null.
0514: */
0515: public void setDialog(DialogType dialog) {
0516: if (dialog == null) {
0517: throw new IllegalArgumentException(
0518: "Invalid value for attribute " + "dialog");
0519: }
0520: this .dialog = dialog;
0521: }
0522:
0523: /**
0524: * Specifies the file name for the output file for jobs using these
0525: * attributes. This attribute is updated to the value chosen by the user.
0526: *
0527: * @return the possibly <code>null</code> file name
0528: */
0529: public String getFileName() {
0530: return fileName;
0531: }
0532:
0533: /**
0534: * Specifies the file name for the output file for jobs using these
0535: * attributes. Default is platform-dependent and implementation-defined.
0536: *
0537: * @param fileName the possibly null file name.
0538: */
0539: public void setFileName(String fileName) {
0540: this .fileName = fileName;
0541: }
0542:
0543: /**
0544: * Returns, for jobs using these attributes, the first page to be
0545: * printed, if a range of pages is to be printed. This attribute is
0546: * updated to the value chosen by the user. An application should ignore
0547: * this attribute on output, unless the return value of the <code>
0548: * getDefaultSelection</code> method is DefaultSelectionType.RANGE. An
0549: * application should honor the return value of <code>getPageRanges</code>
0550: * over the return value of this method, if possible.
0551: *
0552: * @return an integer greater than zero and less than or equal to
0553: * <i>toPage</i> and greater than or equal to <i>minPage</i> and
0554: * less than or equal to <i>maxPage</i>.
0555: */
0556: public int getFromPage() {
0557: if (fromPage != 0) {
0558: return fromPage;
0559: } else if (toPage != 0) {
0560: return getMinPage();
0561: } else if (pageRanges != null) {
0562: return prFirst;
0563: } else {
0564: return getMinPage();
0565: }
0566: }
0567:
0568: /**
0569: * Specifies, for jobs using these attributes, the first page to be
0570: * printed, if a range of pages is to be printed. If this attribute is not
0571: * specified, then the values from the pageRanges attribute are used. If
0572: * pageRanges and either or both of fromPage and toPage are specified,
0573: * pageRanges takes precedence. Specifying none of pageRanges, fromPage,
0574: * or toPage is equivalent to calling
0575: * setPageRanges(new int[][] { new int[] { <i>minPage</i> } });
0576: *
0577: * @param fromPage an integer greater than zero and less than or equal to
0578: * <i>toPage</i> and greater than or equal to <i>minPage</i> and
0579: * less than or equal to <i>maxPage</i>.
0580: * @throws IllegalArgumentException if one or more of the above
0581: * conditions is violated.
0582: */
0583: public void setFromPage(int fromPage) {
0584: if (fromPage <= 0 || (toPage != 0 && fromPage > toPage)
0585: || fromPage < minPage || fromPage > maxPage) {
0586: throw new IllegalArgumentException(
0587: "Invalid value for attribute " + "fromPage");
0588: }
0589: this .fromPage = fromPage;
0590: }
0591:
0592: /**
0593: * Specifies the maximum value the user can specify as the last page to
0594: * be printed for jobs using these attributes. This attribute cannot be
0595: * modified by, and is not subject to any limitations of, the
0596: * implementation or the target printer.
0597: *
0598: * @return an integer greater than zero and greater than or equal
0599: * to <i>minPage</i>.
0600: */
0601: public int getMaxPage() {
0602: return maxPage;
0603: }
0604:
0605: /**
0606: * Specifies the maximum value the user can specify as the last page to
0607: * be printed for jobs using these attributes. Not specifying this
0608: * attribute is equivalent to specifying <code>Integer.MAX_VALUE</code>.
0609: *
0610: * @param maxPage an integer greater than zero and greater than or equal
0611: * to <i>minPage</i>
0612: * @throws IllegalArgumentException if one or more of the above
0613: * conditions is violated
0614: */
0615: public void setMaxPage(int maxPage) {
0616: if (maxPage <= 0 || maxPage < minPage) {
0617: throw new IllegalArgumentException(
0618: "Invalid value for attribute " + "maxPage");
0619: }
0620: this .maxPage = maxPage;
0621: }
0622:
0623: /**
0624: * Specifies the minimum value the user can specify as the first page to
0625: * be printed for jobs using these attributes. This attribute cannot be
0626: * modified by, and is not subject to any limitations of, the
0627: * implementation or the target printer.
0628: *
0629: * @return an integer greater than zero and less than or equal
0630: * to <i>maxPage</i>.
0631: */
0632: public int getMinPage() {
0633: return minPage;
0634: }
0635:
0636: /**
0637: * Specifies the minimum value the user can specify as the first page to
0638: * be printed for jobs using these attributes. Not specifying this
0639: * attribute is equivalent to specifying <code>1</code>.
0640: *
0641: * @param minPage an integer greater than zero and less than or equal
0642: * to <i>maxPage</i>.
0643: * @throws IllegalArgumentException if one or more of the above
0644: * conditions is violated.
0645: */
0646: public void setMinPage(int minPage) {
0647: if (minPage <= 0 || minPage > maxPage) {
0648: throw new IllegalArgumentException(
0649: "Invalid value for attribute " + "minPage");
0650: }
0651: this .minPage = minPage;
0652: }
0653:
0654: /**
0655: * Specifies the handling of multiple copies, including collation, for
0656: * jobs using these attributes. This attribute is updated to the value
0657: * chosen by the user.
0658: *
0659: * @return
0660: * MultipleDocumentHandlingType.SEPARATE_DOCUMENTS_COLLATED_COPIES or
0661: * MultipleDocumentHandlingType.SEPARATE_DOCUMENTS_UNCOLLATED_COPIES.
0662: */
0663: public MultipleDocumentHandlingType getMultipleDocumentHandling() {
0664: return multipleDocumentHandling;
0665: }
0666:
0667: /**
0668: * Specifies the handling of multiple copies, including collation, for
0669: * jobs using these attributes. Not specifying this attribute is equivalent
0670: * to specifying
0671: * MultipleDocumentHandlingType.SEPARATE_DOCUMENTS_UNCOLLATED_COPIES.
0672: *
0673: * @param multipleDocumentHandling
0674: * MultipleDocumentHandlingType.SEPARATE_DOCUMENTS_COLLATED_COPIES or
0675: * MultipleDocumentHandlingType.SEPARATE_DOCUMENTS_UNCOLLATED_COPIES.
0676: * @throws IllegalArgumentException if multipleDocumentHandling is null.
0677: */
0678: public void setMultipleDocumentHandling(
0679: MultipleDocumentHandlingType multipleDocumentHandling) {
0680: if (multipleDocumentHandling == null) {
0681: throw new IllegalArgumentException(
0682: "Invalid value for attribute "
0683: + "multipleDocumentHandling");
0684: }
0685: this .multipleDocumentHandling = multipleDocumentHandling;
0686: }
0687:
0688: /**
0689: * Sets the handling of multiple copies, including collation, for jobs
0690: * using these attributes to the default. The default handling is
0691: * MultipleDocumentHandlingType.SEPARATE_DOCUMENTS_UNCOLLATED_COPIES.
0692: */
0693: public void setMultipleDocumentHandlingToDefault() {
0694: setMultipleDocumentHandling(MultipleDocumentHandlingType.SEPARATE_DOCUMENTS_UNCOLLATED_COPIES);
0695: }
0696:
0697: /**
0698: * Specifies, for jobs using these attributes, the ranges of pages to be
0699: * printed, if a range of pages is to be printed. All range numbers are
0700: * inclusive. This attribute is updated to the value chosen by the user.
0701: * An application should ignore this attribute on output, unless the
0702: * return value of the <code>getDefaultSelection</code> method is
0703: * DefaultSelectionType.RANGE.
0704: *
0705: * @return an array of integer arrays of 2 elements. An array
0706: * is interpreted as a range spanning all pages including and
0707: * between the specified pages. Ranges must be in ascending
0708: * order and must not overlap. Specified page numbers cannot be
0709: * less than <i>minPage</i> nor greater than <i>maxPage</i>.
0710: * For example:
0711: * (new int[][] { new int[] { 1, 3 }, new int[] { 5, 5 },
0712: * new int[] { 15, 19 } }),
0713: * specifies pages 1, 2, 3, 5, 15, 16, 17, 18, and 19.
0714: */
0715: public int[][] getPageRanges() {
0716: if (pageRanges != null) {
0717: // Return a copy because otherwise client code could circumvent the
0718: // the checks made in setPageRanges by modifying the returned
0719: // array.
0720: int[][] copy = new int[pageRanges.length][2];
0721: for (int i = 0; i < pageRanges.length; i++) {
0722: copy[i][0] = pageRanges[i][0];
0723: copy[i][1] = pageRanges[i][1];
0724: }
0725: return copy;
0726: } else if (fromPage != 0 || toPage != 0) {
0727: int fromPage = getFromPage();
0728: int toPage = getToPage();
0729: return new int[][] { new int[] { fromPage, toPage } };
0730: } else {
0731: int minPage = getMinPage();
0732: return new int[][] { new int[] { minPage, minPage } };
0733: }
0734: }
0735:
0736: /**
0737: * Specifies, for jobs using these attributes, the ranges of pages to be
0738: * printed, if a range of pages is to be printed. All range numbers are
0739: * inclusive. If this attribute is not specified, then the values from the
0740: * fromPage and toPages attributes are used. If pageRanges and either or
0741: * both of fromPage and toPage are specified, pageRanges takes precedence.
0742: * Specifying none of pageRanges, fromPage, or toPage is equivalent to
0743: * calling setPageRanges(new int[][] { new int[] { <i>minPage</i>,
0744: * <i>minPage</i> } });
0745: *
0746: * @param pageRanges an array of integer arrays of 2 elements. An array
0747: * is interpreted as a range spanning all pages including and
0748: * between the specified pages. Ranges must be in ascending
0749: * order and must not overlap. Specified page numbers cannot be
0750: * less than <i>minPage</i> nor greater than <i>maxPage</i>.
0751: * For example:
0752: * (new int[][] { new int[] { 1, 3 }, new int[] { 5, 5 },
0753: * new int[] { 15, 19 } }),
0754: * specifies pages 1, 2, 3, 5, 15, 16, 17, 18, and 19. Note that
0755: * (new int[][] { new int[] { 1, 1 }, new int[] { 1, 2 } }),
0756: * is an invalid set of page ranges because the two ranges
0757: * overlap.
0758: * @throws IllegalArgumentException if one or more of the above
0759: * conditions is violated.
0760: */
0761: public void setPageRanges(int[][] pageRanges) {
0762: String xcp = "Invalid value for attribute pageRanges";
0763: int first = 0;
0764: int last = 0;
0765:
0766: if (pageRanges == null) {
0767: throw new IllegalArgumentException(xcp);
0768: }
0769:
0770: for (int i = 0; i < pageRanges.length; i++) {
0771: if (pageRanges[i] == null || pageRanges[i].length != 2
0772: || pageRanges[i][0] <= last
0773: || pageRanges[i][1] < pageRanges[i][0]) {
0774: throw new IllegalArgumentException(xcp);
0775: }
0776: last = pageRanges[i][1];
0777: if (first == 0) {
0778: first = pageRanges[i][0];
0779: }
0780: }
0781:
0782: if (first < minPage || last > maxPage) {
0783: throw new IllegalArgumentException(xcp);
0784: }
0785:
0786: // Store a copy because otherwise client code could circumvent the
0787: // the checks made above by holding a reference to the array and
0788: // modifying it after calling setPageRanges.
0789: int[][] copy = new int[pageRanges.length][2];
0790: for (int i = 0; i < pageRanges.length; i++) {
0791: copy[i][0] = pageRanges[i][0];
0792: copy[i][1] = pageRanges[i][1];
0793: }
0794: this .pageRanges = copy;
0795: this .prFirst = first;
0796: this .prLast = last;
0797: }
0798:
0799: /**
0800: * Returns the destination printer for jobs using these attributes. This
0801: * attribute is updated to the value chosen by the user.
0802: *
0803: * @return the possibly null printer name.
0804: */
0805: public String getPrinter() {
0806: return printer;
0807: }
0808:
0809: /**
0810: * Specifies the destination printer for jobs using these attributes.
0811: * Default is platform-dependent and implementation-defined.
0812: *
0813: * @param printer the possibly null printer name.
0814: */
0815: public void setPrinter(String printer) {
0816: this .printer = printer;
0817: }
0818:
0819: /**
0820: * Returns how consecutive pages should be imposed upon the sides of the
0821: * print medium for jobs using these attributes. SidesType.ONE_SIDED
0822: * imposes each consecutive page upon the same side of consecutive media
0823: * sheets. This imposition is sometimes called <i>simplex</i>.
0824: * SidesType.TWO_SIDED_LONG_EDGE imposes each consecutive pair of pages
0825: * upon front and back sides of consecutive media sheets, such that the
0826: * orientation of each pair of pages on the medium would be correct for
0827: * the reader as if for binding on the long edge. This imposition is
0828: * sometimes called <i>duplex</i>. SidesType.TWO_SIDED_SHORT_EDGE imposes
0829: * each consecutive pair of pages upon front and back sides of consecutive
0830: * media sheets, such that the orientation of each pair of pages on the
0831: * medium would be correct for the reader as if for binding on the short
0832: * edge. This imposition is sometimes called <i>tumble</i>. This attribute
0833: * is updated to the value chosen by the user.
0834: *
0835: * @return SidesType.ONE_SIDED, SidesType.TWO_SIDED_LONG_EDGE, or
0836: * SidesType.TWO_SIDED_SHORT_EDGE.
0837: */
0838: public SidesType getSides() {
0839: return sides;
0840: }
0841:
0842: /**
0843: * Specifies how consecutive pages should be imposed upon the sides of the
0844: * print medium for jobs using these attributes. SidesType.ONE_SIDED
0845: * imposes each consecutive page upon the same side of consecutive media
0846: * sheets. This imposition is sometimes called <i>simplex</i>.
0847: * SidesType.TWO_SIDED_LONG_EDGE imposes each consecutive pair of pages
0848: * upon front and back sides of consecutive media sheets, such that the
0849: * orientation of each pair of pages on the medium would be correct for
0850: * the reader as if for binding on the long edge. This imposition is
0851: * sometimes called <i>duplex</i>. SidesType.TWO_SIDED_SHORT_EDGE imposes
0852: * each consecutive pair of pages upon front and back sides of consecutive
0853: * media sheets, such that the orientation of each pair of pages on the
0854: * medium would be correct for the reader as if for binding on the short
0855: * edge. This imposition is sometimes called <i>tumble</i>. Not specifying
0856: * this attribute is equivalent to specifying SidesType.ONE_SIDED.
0857: *
0858: * @param sides SidesType.ONE_SIDED, SidesType.TWO_SIDED_LONG_EDGE, or
0859: * SidesType.TWO_SIDED_SHORT_EDGE.
0860: * @throws IllegalArgumentException if sides is null.
0861: */
0862: public void setSides(SidesType sides) {
0863: if (sides == null) {
0864: throw new IllegalArgumentException(
0865: "Invalid value for attribute " + "sides");
0866: }
0867: this .sides = sides;
0868: }
0869:
0870: /**
0871: * Sets how consecutive pages should be imposed upon the sides of the
0872: * print medium for jobs using these attributes to the default. The
0873: * default imposition is SidesType.ONE_SIDED.
0874: */
0875: public void setSidesToDefault() {
0876: setSides(SidesType.ONE_SIDED);
0877: }
0878:
0879: /**
0880: * Returns, for jobs using these attributes, the last page (inclusive)
0881: * to be printed, if a range of pages is to be printed. This attribute is
0882: * updated to the value chosen by the user. An application should ignore
0883: * this attribute on output, unless the return value of the <code>
0884: * getDefaultSelection</code> method is DefaultSelectionType.RANGE. An
0885: * application should honor the return value of <code>getPageRanges</code>
0886: * over the return value of this method, if possible.
0887: *
0888: * @return an integer greater than zero and greater than or equal
0889: * to <i>toPage</i> and greater than or equal to <i>minPage</i>
0890: * and less than or equal to <i>maxPage</i>.
0891: */
0892: public int getToPage() {
0893: if (toPage != 0) {
0894: return toPage;
0895: } else if (fromPage != 0) {
0896: return fromPage;
0897: } else if (pageRanges != null) {
0898: return prLast;
0899: } else {
0900: return getMinPage();
0901: }
0902: }
0903:
0904: /**
0905: * Specifies, for jobs using these attributes, the last page (inclusive)
0906: * to be printed, if a range of pages is to be printed.
0907: * If this attribute is not specified, then the values from the pageRanges
0908: * attribute are used. If pageRanges and either or both of fromPage and
0909: * toPage are specified, pageRanges takes precedence. Specifying none of
0910: * pageRanges, fromPage, or toPage is equivalent to calling
0911: * setPageRanges(new int[][] { new int[] { <i>minPage</i> } });
0912: *
0913: * @param toPage an integer greater than zero and greater than or equal
0914: * to <i>fromPage</i> and greater than or equal to <i>minPage</i>
0915: * and less than or equal to <i>maxPage</i>.
0916: * @throws IllegalArgumentException if one or more of the above
0917: * conditions is violated.
0918: */
0919: public void setToPage(int toPage) {
0920: if (toPage <= 0 || (fromPage != 0 && toPage < fromPage)
0921: || toPage < minPage || toPage > maxPage) {
0922: throw new IllegalArgumentException(
0923: "Invalid value for attribute " + "toPage");
0924: }
0925: this .toPage = toPage;
0926: }
0927:
0928: /**
0929: * Determines whether two JobAttributes are equal to each other.
0930: * <p>
0931: * Two JobAttributes are equal if and only if each of their attributes are
0932: * equal. Attributes of enumeration type are equal if and only if the
0933: * fields refer to the same unique enumeration object. A set of page
0934: * ranges is equal if and only if the sets are of equal length, each range
0935: * enumerates the same pages, and the ranges are in the same order.
0936: *
0937: * @param obj the object whose equality will be checked.
0938: * @return whether obj is equal to this JobAttribute according to the
0939: * above criteria.
0940: */
0941: public boolean equals(Object obj) {
0942: if (!(obj instanceof JobAttributes)) {
0943: return false;
0944: }
0945: JobAttributes rhs = (JobAttributes) obj;
0946:
0947: if (fileName == null) {
0948: if (rhs.fileName != null) {
0949: return false;
0950: }
0951: } else {
0952: if (!fileName.equals(rhs.fileName)) {
0953: return false;
0954: }
0955: }
0956:
0957: if (pageRanges == null) {
0958: if (rhs.pageRanges != null) {
0959: return false;
0960: }
0961: } else {
0962: if (rhs.pageRanges == null
0963: || pageRanges.length != rhs.pageRanges.length) {
0964: return false;
0965: }
0966: for (int i = 0; i < pageRanges.length; i++) {
0967: if (pageRanges[i][0] != rhs.pageRanges[i][0]
0968: || pageRanges[i][1] != rhs.pageRanges[i][1]) {
0969: return false;
0970: }
0971: }
0972: }
0973:
0974: if (printer == null) {
0975: if (rhs.printer != null) {
0976: return false;
0977: }
0978: } else {
0979: if (!printer.equals(rhs.printer)) {
0980: return false;
0981: }
0982: }
0983:
0984: return (copies == rhs.copies
0985: && defaultSelection == rhs.defaultSelection
0986: && destination == rhs.destination
0987: && dialog == rhs.dialog
0988: && fromPage == rhs.fromPage
0989: && maxPage == rhs.maxPage
0990: && minPage == rhs.minPage
0991: && multipleDocumentHandling == rhs.multipleDocumentHandling
0992: && prFirst == rhs.prFirst && prLast == rhs.prLast
0993: && sides == rhs.sides && toPage == rhs.toPage);
0994: }
0995:
0996: /**
0997: * Returns a hash code value for this JobAttributes.
0998: *
0999: * @return the hash code.
1000: */
1001: public int hashCode() {
1002: int rest = ((copies + fromPage + maxPage + minPage + prFirst
1003: + prLast + toPage) * 31) << 21;
1004: if (pageRanges != null) {
1005: int sum = 0;
1006: for (int i = 0; i < pageRanges.length; i++) {
1007: sum += pageRanges[i][0] + pageRanges[i][1];
1008: }
1009: rest ^= (sum * 31) << 11;
1010: }
1011: if (fileName != null) {
1012: rest ^= fileName.hashCode();
1013: }
1014: if (printer != null) {
1015: rest ^= printer.hashCode();
1016: }
1017: return (defaultSelection.hashCode() << 6
1018: ^ destination.hashCode() << 5 ^ dialog.hashCode() << 3
1019: ^ multipleDocumentHandling.hashCode() << 2
1020: ^ sides.hashCode() ^ rest);
1021: }
1022:
1023: /**
1024: * Returns a string representation of this JobAttributes.
1025: *
1026: * @return the string representation.
1027: */
1028: public String toString() {
1029: int[][] pageRanges = getPageRanges();
1030: String prStr = "[";
1031: boolean first = true;
1032: for (int i = 0; i < pageRanges.length; i++) {
1033: if (first) {
1034: first = false;
1035: } else {
1036: prStr += ",";
1037: }
1038: prStr += pageRanges[i][0] + ":" + pageRanges[i][1];
1039: }
1040: prStr += "]";
1041:
1042: return "copies=" + getCopies() + ",defaultSelection="
1043: + getDefaultSelection() + ",destination="
1044: + getDestination() + ",dialog=" + getDialog()
1045: + ",fileName=" + getFileName() + ",fromPage="
1046: + getFromPage() + ",maxPage=" + getMaxPage()
1047: + ",minPage=" + getMinPage()
1048: + ",multiple-document-handling="
1049: + getMultipleDocumentHandling() + ",page-ranges="
1050: + prStr + ",printer=" + getPrinter() + ",sides="
1051: + getSides() + ",toPage=" + getToPage();
1052: }
1053: }
|