/*
* @(#)JobAttributes.java 1.11 06/04/07
*
* Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
*/
package java.awt;
/**
* A set of attributes which control a print job.
* <p>
* Instances of this class control the number of copies, default selection,
* destination, print dialog, file and printer names, page ranges, multiple
* document handling (including collation), and multi-page imposition (such
* as duplex) of every print job which uses the instance. Attribute names are
* compliant with the Internet Printing Protocol (IPP) 1.1 where possible.
* Attribute values are partially compliant where possible.
* <p>
* To use a method which takes an inner class type, pass a reference to
* one of the constant fields of the inner class. Client code cannot create
* new instances of the inner class types because none of those classes
* has a public constructor. For example, to set the print dialog type to
* the cross-platform, pure Java print dialog, use the following code:
* <pre>
* import java.awt.JobAttributes;
*
* public class PureJavaPrintDialogExample {
* public void setPureJavaPrintDialog(JobAttributes jobAttributes) {
* jobAttributes.setDialog(JobAttributes.DialogType.COMMON);
* }
* }
* </pre>
* <p>
* Every IPP attribute which supports an <i>attributeName</i>-default value
* has a corresponding <code>set<i>attributeName</i>ToDefault</code> method.
* Default value fields are not provided.
*
* @version 1.11, 04/07/06
* @author David Mendenhall
* @since 1.3
*/
public final class JobAttributes implements Cloneable {
/**
* A type-safe enumeration of possible default selection states.
* @since 1.3
*/
public static final class DefaultSelectionType extends AttributeValue {
private static final int I_ALL = 0;
private static final int I_RANGE = 1;
private static final int I_SELECTION = 2;
private static final String NAMES[] = {
"all", "range", "selection"
};
/**
* The <code>DefaultSelectionType</code> instance to use for
* specifying that all pages of the job should be printed.
*/
public static final DefaultSelectionType ALL =
new DefaultSelectionType(I_ALL);
/**
* The <code>DefaultSelectionType</code> instance to use for
* specifying that a range of pages of the job should be printed.
*/
public static final DefaultSelectionType RANGE =
new DefaultSelectionType(I_RANGE);
/**
* The <code>DefaultSelectionType</code> instance to use for
* specifying that the current selection should be printed.
*/
public static final DefaultSelectionType SELECTION =
new DefaultSelectionType(I_SELECTION);
private DefaultSelectionType(int type) {
super(type, NAMES);
}
}
/**
* A type-safe enumeration of possible job destinations.
* @since 1.3
*/
public static final class DestinationType extends AttributeValue {
private static final int I_FILE = 0;
private static final int I_PRINTER = 1;
private static final String NAMES[] = {
"file", "printer"
};
/**
* The <code>DestinationType</code> instance to use for
* specifying print to file.
*/
public static final DestinationType FILE =
new DestinationType(I_FILE);
/**
* The <code>DestinationType</code> instance to use for
* specifying print to printer.
*/
public static final DestinationType PRINTER =
new DestinationType(I_PRINTER);
private DestinationType(int type) {
super(type, NAMES);
}
}
/**
* A type-safe enumeration of possible dialogs to display to the user.
* @since 1.3
*/
public static final class DialogType extends AttributeValue {
private static final int I_COMMON = 0;
private static final int I_NATIVE = 1;
private static final int I_NONE = 2;
private static final String NAMES[] = {
"common", "native", "none"
};
/**
* The <code>DialogType</code> instance to use for
* specifying the cross-platform, pure Java print dialog.
*/
public static final DialogType COMMON = new DialogType(I_COMMON);
/**
* The <code>DialogType</code> instance to use for
* specifying the platform's native print dialog.
*/
public static final DialogType NATIVE = new DialogType(I_NATIVE);
/**
* The <code>DialogType</code> instance to use for
* specifying no print dialog.
*/
public static final DialogType NONE = new DialogType(I_NONE);
private DialogType(int type) {
super(type, NAMES);
}
}
/**
* A type-safe enumeration of possible multiple copy handling states.
* It is used to control how the sheets of multiple copies of a single
* document are collated.
* @since 1.3
*/
public static final class MultipleDocumentHandlingType extends
AttributeValue {
private static final int I_SEPARATE_DOCUMENTS_COLLATED_COPIES = 0;
private static final int I_SEPARATE_DOCUMENTS_UNCOLLATED_COPIES = 1;
private static final String NAMES[] = {
"separate-documents-collated-copies",
"separate-documents-uncollated-copies"
};
/**
* The <code>MultipleDocumentHandlingType</code> instance to use for specifying
* that the job should be divided into separate, collated copies.
*/
public static final MultipleDocumentHandlingType
SEPARATE_DOCUMENTS_COLLATED_COPIES =
new MultipleDocumentHandlingType(
I_SEPARATE_DOCUMENTS_COLLATED_COPIES);
/**
* The <code>MultipleDocumentHandlingType</code> instance to use for specifying
* that the job should be divided into separate, uncollated copies.
*/
public static final MultipleDocumentHandlingType
SEPARATE_DOCUMENTS_UNCOLLATED_COPIES =
new MultipleDocumentHandlingType(
I_SEPARATE_DOCUMENTS_UNCOLLATED_COPIES);
private MultipleDocumentHandlingType(int type) {
super(type, NAMES);
}
}
/**
* A type-safe enumeration of possible multi-page impositions. These
* impositions are in compliance with IPP 1.1.
* @since 1.3
*/
public static final class SidesType extends AttributeValue {
private static final int I_ONE_SIDED = 0;
private static final int I_TWO_SIDED_LONG_EDGE = 1;
private static final int I_TWO_SIDED_SHORT_EDGE = 2;
private static final String NAMES[] = {
"one-sided", "two-sided-long-edge", "two-sided-short-edge"
};
/**
* The <code>SidesType</code> instance to use for specifying that
* consecutive job pages should be printed upon the same side of
* consecutive media sheets.
*/
public static final SidesType ONE_SIDED = new SidesType(I_ONE_SIDED);
/**
* The <code>SidesType</code> instance to use for specifying that
* consecutive job pages should be printed upon front and back sides
* of consecutive media sheets, such that the orientation of each pair
* of pages on the medium would be correct for the reader as if for
* binding on the long edge.
*/
public static final SidesType TWO_SIDED_LONG_EDGE =
new SidesType(I_TWO_SIDED_LONG_EDGE);
/**
* The <code>SidesType</code> instance to use for specifying that
* consecutive job pages should be printed upon front and back sides
* of consecutive media sheets, such that the orientation of each pair
* of pages on the medium would be correct for the reader as if for
* binding on the short edge.
*/
public static final SidesType TWO_SIDED_SHORT_EDGE =
new SidesType(I_TWO_SIDED_SHORT_EDGE);
private SidesType(int type) {
super(type, NAMES);
}
}
private int copies;
private DefaultSelectionType defaultSelection;
private DestinationType destination;
private DialogType dialog;
private String fileName;
private int fromPage;
private int maxPage;
private int minPage;
private MultipleDocumentHandlingType multipleDocumentHandling;
private int[][] pageRanges;
private int prFirst;
private int prLast;
private String printer;
private SidesType sides;
private int toPage;
/**
* Constructs a <code>JobAttributes</code> instance with default
* values for every attribute. The dialog defaults to
* <code>DialogType.NATIVE</code>. Min page defaults to
* <code>1</code>. Max page defaults to <code>Integer.MAX_VALUE</code>.
* Destination defaults to <code>DestinationType.PRINTER</code>.
* Selection defaults to <code>DefaultSelectionType.ALL</code>.
* Number of copies defaults to <code>1</code>. Multiple document handling defaults
* to <code>MultipleDocumentHandlingType.SEPARATE_DOCUMENTS_UNCOLLATED_COPIES</code>.
* Sides defaults to <code>SidesType.ONE_SIDED</code>. File name defaults
* to <code>null</code>.
*/
public JobAttributes() {
setCopiesToDefault();
setDefaultSelection(DefaultSelectionType.ALL);
setDestination(DestinationType.PRINTER);
setDialog(DialogType.NATIVE);
setMaxPage(Integer.MAX_VALUE);
setMinPage(1);
setMultipleDocumentHandlingToDefault();
setSidesToDefault();
}
/**
* Constructs a <code>JobAttributes</code> instance which is a copy
* of the supplied <code>JobAttributes</code>.
*
* @param obj the <code>JobAttributes</code> to copy
*/
public JobAttributes(JobAttributes obj) {
set(obj);
}
/**
* Constructs a <code>JobAttributes</code> instance with the
* specified values for every attribute.
*
* @param copies an integer greater than 0
* @param defaultSelection <code>DefaultSelectionType.ALL</code>,
* <code>DefaultSelectionType.RANGE</code>, or
* <code>DefaultSelectionType.SELECTION</code>
* @param destination <code>DesintationType.FILE</code> or
* <code>DesintationType.PRINTER</code>
* @param dialog <code>DialogType.COMMON</code>,
* <code>DialogType.NATIVE</code>, or
* <code>DialogType.NONE</code>
* @param fileName the possibly <code>null</code> file name
* @param maxPage an integer greater than zero and greater than or equal
* to <i>minPage</i>
* @param minPage an integer greater than zero and less than or equal
* to <i>maxPage</i>
* @param multipleDocumentHandling
* <code>MultipleDocumentHandlingType.SEPARATE_DOCUMENTS_COLLATED_COPIES</code> or
* <code>MultipleDocumentHandlingType.SEPARATE_DOCUMENTS_UNCOLLATED_COPIES</code>
* @param pageRanges an array of integer arrays of two elements; an array
* is interpreted as a range spanning all pages including and
* between the specified pages; ranges must be in ascending
* order and must not overlap; specified page numbers cannot be
* less than <i>minPage</i> nor greater than <i>maxPage</i>;
* for example:
* <pre>
* (new int[][] { new int[] { 1, 3 }, new int[] { 5, 5 },
* new int[] { 15, 19 } }),
* </pre>
* specifies pages 1, 2, 3, 5, 15, 16, 17, 18, and 19. Note that
* (<code>new int[][] { new int[] { 1, 1 }, new int[] { 1, 2 } }</code>),
* is an invalid set of page ranges because the two ranges
* overlap
* @param printer the possibly <code>null</code> printer name
* @param sides <code>SidesType.ONE_SIDED</code>,
* <code>SidesType.TWO_SIDED_LONG_EDGE</code>, or
* <code>SidesType.TWO_SIDED_SHORT_EDGE</code>
* @throws IllegalArgumentException if one or more of the above
* conditions is violated
*/
public JobAttributes(int copies, DefaultSelectionType defaultSelection,
DestinationType destination, DialogType dialog,
String fileName, int maxPage, int minPage,
MultipleDocumentHandlingType multipleDocumentHandling,
int[][] pageRanges, String printer, SidesType sides) {
setCopies(copies);
setDefaultSelection(defaultSelection);
setDestination(destination);
setDialog(dialog);
setFileName(fileName);
setMaxPage(maxPage);
setMinPage(minPage);
setMultipleDocumentHandling(multipleDocumentHandling);
setPageRanges(pageRanges);
setPrinter(printer);
setSides(sides);
}
/**
* Creates and returns a copy of this <code>JobAttributes</code>.
*
* @return the newly created copy; it is safe to cast this Object into
* a <code>JobAttributes</code>
*/
public Object clone() {
try {
return super.clone();
} catch (CloneNotSupportedException e) {
// Since we implement Cloneable, this should never happen
throw new InternalError();
}
}
/**
* Sets all of the attributes of this <code>JobAttributes</code> to
* the same values as the attributes of obj.
*
* @param obj the <code>JobAttributes</code> to copy
*/
public void set(JobAttributes obj) {
copies = obj.copies;
defaultSelection = obj.defaultSelection;
destination = obj.destination;
dialog = obj.dialog;
fileName = obj.fileName;
fromPage = obj.fromPage;
maxPage = obj.maxPage;
minPage = obj.minPage;
multipleDocumentHandling = obj.multipleDocumentHandling;
// okay because we never modify the contents of pageRanges
pageRanges = obj.pageRanges;
prFirst = obj.prFirst;
prLast = obj.prLast;
printer = obj.printer;
sides = obj.sides;
toPage = obj.toPage;
}
/**
* Returns the number of copies the application should render for jobs
* using these attributes. This attribute is updated to the value chosen
* by the user.
*
* @return an integer greater than 0.
*/
public int getCopies() {
return copies;
}
/**
* Specifies the number of copies the application should render for jobs
* using these attributes. Not specifying this attribute is equivalent to
* specifying <code>1</code>.
*
* @param copies an integer greater than 0
* @throws IllegalArgumentException if <code>copies</code> is less than
* or equal to 0
*/
public void setCopies(int copies) {
if (copies <= 0) {
throw new IllegalArgumentException("Invalid value for attribute "+
"copies");
}
this.copies = copies;
}
/**
* Sets the number of copies the application should render for jobs using
* these attributes to the default. The default number of copies is 1.
*/
public void setCopiesToDefault() {
setCopies(1);
}
/**
* Specifies whether, for jobs using these attributes, the application
* should print all pages, the range specified by the return value of
* <code>getPageRanges</code>, or the current selection. This attribute
* is updated to the value chosen by the user.
*
* @return DefaultSelectionType.ALL, DefaultSelectionType.RANGE, or
* DefaultSelectionType.SELECTION
*/
public DefaultSelectionType getDefaultSelection() {
return defaultSelection;
}
/**
* Specifies whether, for jobs using these attributes, the application
* should print all pages, the range specified by the return value of
* <code>getPageRanges</code>, or the current selection. Not specifying
* this attribute is equivalent to specifying DefaultSelectionType.ALL.
*
* @param defaultSelection DefaultSelectionType.ALL,
* DefaultSelectionType.RANGE, or DefaultSelectionType.SELECTION.
* @throws IllegalArgumentException if defaultSelection is <code>null</code>
*/
public void setDefaultSelection(DefaultSelectionType defaultSelection) {
if (defaultSelection == null) {
throw new IllegalArgumentException("Invalid value for attribute "+
"defaultSelection");
}
this.defaultSelection = defaultSelection;
}
/**
* Specifies whether output will be to a printer or a file for jobs using
* these attributes. This attribute is updated to the value chosen by the
* user.
*
* @return DesintationType.FILE or DesintationType.PRINTER
*/
public DestinationType getDestination() {
return destination;
}
/**
* Specifies whether output will be to a printer or a file for jobs using
* these attributes. Not specifying this attribute is equivalent to
* specifying DesintationType.PRINTER.
*
* @param destination DesintationType.FILE or DesintationType.PRINTER.
* @throws IllegalArgumentException if destination is null.
*/
public void setDestination(DestinationType destination) {
if (destination == null) {
throw new IllegalArgumentException("Invalid value for attribute "+
"destination");
}
this.destination = destination;
}
/**
* Returns whether, for jobs using these attributes, the user should see
* a print dialog in which to modify the print settings, and which type of
* print dialog should be displayed. DialogType.COMMON denotes a cross-
* platform, pure Java print dialog. DialogType.NATIVE denotes the
* platform's native print dialog. If a platform does not support a native
* print dialog, the pure Java print dialog is displayed instead.
* DialogType.NONE specifies no print dialog (i.e., background printing).
* This attribute cannot be modified by, and is not subject to any
* limitations of, the implementation or the target printer.
*
* @return <code>DialogType.COMMON</code>, <code>DialogType.NATIVE</code>, or
* <code>DialogType.NONE</code>
*/
public DialogType getDialog() {
return dialog;
}
/**
* Specifies whether, for jobs using these attributes, the user should see
* a print dialog in which to modify the print settings, and which type of
* print dialog should be displayed. DialogType.COMMON denotes a cross-
* platform, pure Java print dialog. DialogType.NATIVE denotes the
* platform's native print dialog. If a platform does not support a native
* print dialog, the pure Java print dialog is displayed instead.
* DialogType.NONE specifies no print dialog (i.e., background printing).
* Not specifying this attribute is equivalent to specifying
* DialogType.NATIVE.
*
* @param dialog DialogType.COMMON, DialogType.NATIVE, or
* DialogType.NONE.
* @throws IllegalArgumentException if dialog is null.
*/
public void setDialog(DialogType dialog) {
if (dialog == null) {
throw new IllegalArgumentException("Invalid value for attribute "+
"dialog");
}
this.dialog = dialog;
}
/**
* Specifies the file name for the output file for jobs using these
* attributes. This attribute is updated to the value chosen by the user.
*
* @return the possibly <code>null</code> file name
*/
public String getFileName() {
return fileName;
}
/**
* Specifies the file name for the output file for jobs using these
* attributes. Default is platform-dependent and implementation-defined.
*
* @param fileName the possibly null file name.
*/
public void setFileName(String fileName) {
this.fileName = fileName;
}
/**
* Returns, for jobs using these attributes, the first page to be
* printed, if a range of pages is to be printed. This attribute is
* updated to the value chosen by the user. An application should ignore
* this attribute on output, unless the return value of the <code>
* getDefaultSelection</code> method is DefaultSelectionType.RANGE. An
* application should honor the return value of <code>getPageRanges</code>
* over the return value of this method, if possible.
*
* @return an integer greater than zero and less than or equal to
* <i>toPage</i> and greater than or equal to <i>minPage</i> and
* less than or equal to <i>maxPage</i>.
*/
public int getFromPage() {
if (fromPage != 0) {
return fromPage;
} else if (toPage != 0) {
return getMinPage();
} else if (pageRanges != null) {
return prFirst;
} else {
return getMinPage();
}
}
/**
* Specifies, for jobs using these attributes, the first page to be
* printed, if a range of pages is to be printed. If this attribute is not
* specified, then the values from the pageRanges attribute are used. If
* pageRanges and either or both of fromPage and toPage are specified,
* pageRanges takes precedence. Specifying none of pageRanges, fromPage,
* or toPage is equivalent to calling
* setPageRanges(new int[][] { new int[] { <i>minPage</i> } });
*
* @param fromPage an integer greater than zero and less than or equal to
* <i>toPage</i> and greater than or equal to <i>minPage</i> and
* less than or equal to <i>maxPage</i>.
* @throws IllegalArgumentException if one or more of the above
* conditions is violated.
*/
public void setFromPage(int fromPage) {
if (fromPage <= 0 ||
(toPage != 0 && fromPage > toPage) ||
fromPage < minPage ||
fromPage > maxPage) {
throw new IllegalArgumentException("Invalid value for attribute "+
"fromPage");
}
this.fromPage = fromPage;
}
/**
* Specifies the maximum value the user can specify as the last page to
* be printed for jobs using these attributes. This attribute cannot be
* modified by, and is not subject to any limitations of, the
* implementation or the target printer.
*
* @return an integer greater than zero and greater than or equal
* to <i>minPage</i>.
*/
public int getMaxPage() {
return maxPage;
}
/**
* Specifies the maximum value the user can specify as the last page to
* be printed for jobs using these attributes. Not specifying this
* attribute is equivalent to specifying <code>Integer.MAX_VALUE</code>.
*
* @param maxPage an integer greater than zero and greater than or equal
* to <i>minPage</i>
* @throws IllegalArgumentException if one or more of the above
* conditions is violated
*/
public void setMaxPage(int maxPage) {
if (maxPage <= 0 || maxPage < minPage) {
throw new IllegalArgumentException("Invalid value for attribute "+
"maxPage");
}
this.maxPage = maxPage;
}
/**
* Specifies the minimum value the user can specify as the first page to
* be printed for jobs using these attributes. This attribute cannot be
* modified by, and is not subject to any limitations of, the
* implementation or the target printer.
*
* @return an integer greater than zero and less than or equal
* to <i>maxPage</i>.
*/
public int getMinPage() {
return minPage;
}
/**
* Specifies the minimum value the user can specify as the first page to
* be printed for jobs using these attributes. Not specifying this
* attribute is equivalent to specifying <code>1</code>.
*
* @param minPage an integer greater than zero and less than or equal
* to <i>maxPage</i>.
* @throws IllegalArgumentException if one or more of the above
* conditions is violated.
*/
public void setMinPage(int minPage) {
if (minPage <= 0 || minPage > maxPage) {
throw new IllegalArgumentException("Invalid value for attribute "+
"minPage");
}
this.minPage = minPage;
}
/**
* Specifies the handling of multiple copies, including collation, for
* jobs using these attributes. This attribute is updated to the value
* chosen by the user.
*
* @return
* MultipleDocumentHandlingType.SEPARATE_DOCUMENTS_COLLATED_COPIES or
* MultipleDocumentHandlingType.SEPARATE_DOCUMENTS_UNCOLLATED_COPIES.
*/
public MultipleDocumentHandlingType getMultipleDocumentHandling() {
return multipleDocumentHandling;
}
/**
* Specifies the handling of multiple copies, including collation, for
* jobs using these attributes. Not specifying this attribute is equivalent
* to specifying
* MultipleDocumentHandlingType.SEPARATE_DOCUMENTS_UNCOLLATED_COPIES.
*
* @param multipleDocumentHandling
* MultipleDocumentHandlingType.SEPARATE_DOCUMENTS_COLLATED_COPIES or
* MultipleDocumentHandlingType.SEPARATE_DOCUMENTS_UNCOLLATED_COPIES.
* @throws IllegalArgumentException if multipleDocumentHandling is null.
*/
public void setMultipleDocumentHandling(MultipleDocumentHandlingType
multipleDocumentHandling) {
if (multipleDocumentHandling == null) {
throw new IllegalArgumentException("Invalid value for attribute "+
"multipleDocumentHandling");
}
this.multipleDocumentHandling = multipleDocumentHandling;
}
/**
* Sets the handling of multiple copies, including collation, for jobs
* using these attributes to the default. The default handling is
* MultipleDocumentHandlingType.SEPARATE_DOCUMENTS_UNCOLLATED_COPIES.
*/
public void setMultipleDocumentHandlingToDefault() {
setMultipleDocumentHandling(
MultipleDocumentHandlingType.SEPARATE_DOCUMENTS_UNCOLLATED_COPIES);
}
/**
* Specifies, for jobs using these attributes, the ranges of pages to be
* printed, if a range of pages is to be printed. All range numbers are
* inclusive. This attribute is updated to the value chosen by the user.
* An application should ignore this attribute on output, unless the
* return value of the <code>getDefaultSelection</code> method is
* DefaultSelectionType.RANGE.
*
* @return an array of integer arrays of 2 elements. An array
* is interpreted as a range spanning all pages including and
* between the specified pages. Ranges must be in ascending
* order and must not overlap. Specified page numbers cannot be
* less than <i>minPage</i> nor greater than <i>maxPage</i>.
* For example:
* (new int[][] { new int[] { 1, 3 }, new int[] { 5, 5 },
* new int[] { 15, 19 } }),
* specifies pages 1, 2, 3, 5, 15, 16, 17, 18, and 19.
*/
public int[][] getPageRanges() {
if (pageRanges != null) {
// Return a copy because otherwise client code could circumvent the
// the checks made in setPageRanges by modifying the returned
// array.
int[][] copy = new int[pageRanges.length][2];
for (int i = 0; i < pageRanges.length; i++) {
copy[i][0] = pageRanges[i][0];
copy[i][1] = pageRanges[i][1];
}
return copy;
} else if (fromPage != 0 || toPage != 0) {
int fromPage = getFromPage();
int toPage = getToPage();
return new int[][] { new int[] { fromPage, toPage } };
} else {
int minPage = getMinPage();
return new int[][] { new int[] { minPage, minPage } };
}
}
/**
* Specifies, for jobs using these attributes, the ranges of pages to be
* printed, if a range of pages is to be printed. All range numbers are
* inclusive. If this attribute is not specified, then the values from the
* fromPage and toPages attributes are used. If pageRanges and either or
* both of fromPage and toPage are specified, pageRanges takes precedence.
* Specifying none of pageRanges, fromPage, or toPage is equivalent to
* calling setPageRanges(new int[][] { new int[] { <i>minPage</i>,
* <i>minPage</i> } });
*
* @param pageRanges an array of integer arrays of 2 elements. An array
* is interpreted as a range spanning all pages including and
* between the specified pages. Ranges must be in ascending
* order and must not overlap. Specified page numbers cannot be
* less than <i>minPage</i> nor greater than <i>maxPage</i>.
* For example:
* (new int[][] { new int[] { 1, 3 }, new int[] { 5, 5 },
* new int[] { 15, 19 } }),
* specifies pages 1, 2, 3, 5, 15, 16, 17, 18, and 19. Note that
* (new int[][] { new int[] { 1, 1 }, new int[] { 1, 2 } }),
* is an invalid set of page ranges because the two ranges
* overlap.
* @throws IllegalArgumentException if one or more of the above
* conditions is violated.
*/
public void setPageRanges(int[][] pageRanges) {
String xcp = "Invalid value for attribute pageRanges";
int first = 0;
int last = 0;
if (pageRanges == null) {
throw new IllegalArgumentException(xcp);
}
for (int i = 0; i < pageRanges.length; i++) {
if (pageRanges[i] == null ||
pageRanges[i].length != 2 ||
pageRanges[i][0] <= last ||
pageRanges[i][1] < pageRanges[i][0]) {
throw new IllegalArgumentException(xcp);
}
last = pageRanges[i][1];
if (first == 0) {
first = pageRanges[i][0];
}
}
if (first < minPage || last > maxPage) {
throw new IllegalArgumentException(xcp);
}
// Store a copy because otherwise client code could circumvent the
// the checks made above by holding a reference to the array and
// modifying it after calling setPageRanges.
int[][] copy = new int[pageRanges.length][2];
for (int i = 0; i < pageRanges.length; i++) {
copy[i][0] = pageRanges[i][0];
copy[i][1] = pageRanges[i][1];
}
this.pageRanges = copy;
this.prFirst = first;
this.prLast = last;
}
/**
* Returns the destination printer for jobs using these attributes. This
* attribute is updated to the value chosen by the user.
*
* @return the possibly null printer name.
*/
public String getPrinter() {
return printer;
}
/**
* Specifies the destination printer for jobs using these attributes.
* Default is platform-dependent and implementation-defined.
*
* @param printer the possibly null printer name.
*/
public void setPrinter(String printer) {
this.printer = printer;
}
/**
* Returns how consecutive pages should be imposed upon the sides of the
* print medium for jobs using these attributes. SidesType.ONE_SIDED
* imposes each consecutive page upon the same side of consecutive media
* sheets. This imposition is sometimes called <i>simplex</i>.
* SidesType.TWO_SIDED_LONG_EDGE imposes each consecutive pair of pages
* upon front and back sides of consecutive media sheets, such that the
* orientation of each pair of pages on the medium would be correct for
* the reader as if for binding on the long edge. This imposition is
* sometimes called <i>duplex</i>. SidesType.TWO_SIDED_SHORT_EDGE imposes
* each consecutive pair of pages upon front and back sides of consecutive
* media sheets, such that the orientation of each pair of pages on the
* medium would be correct for the reader as if for binding on the short
* edge. This imposition is sometimes called <i>tumble</i>. This attribute
* is updated to the value chosen by the user.
*
* @return SidesType.ONE_SIDED, SidesType.TWO_SIDED_LONG_EDGE, or
* SidesType.TWO_SIDED_SHORT_EDGE.
*/
public SidesType getSides() {
return sides;
}
/**
* Specifies how consecutive pages should be imposed upon the sides of the
* print medium for jobs using these attributes. SidesType.ONE_SIDED
* imposes each consecutive page upon the same side of consecutive media
* sheets. This imposition is sometimes called <i>simplex</i>.
* SidesType.TWO_SIDED_LONG_EDGE imposes each consecutive pair of pages
* upon front and back sides of consecutive media sheets, such that the
* orientation of each pair of pages on the medium would be correct for
* the reader as if for binding on the long edge. This imposition is
* sometimes called <i>duplex</i>. SidesType.TWO_SIDED_SHORT_EDGE imposes
* each consecutive pair of pages upon front and back sides of consecutive
* media sheets, such that the orientation of each pair of pages on the
* medium would be correct for the reader as if for binding on the short
* edge. This imposition is sometimes called <i>tumble</i>. Not specifying
* this attribute is equivalent to specifying SidesType.ONE_SIDED.
*
* @param sides SidesType.ONE_SIDED, SidesType.TWO_SIDED_LONG_EDGE, or
* SidesType.TWO_SIDED_SHORT_EDGE.
* @throws IllegalArgumentException if sides is null.
*/
public void setSides(SidesType sides) {
if (sides == null) {
throw new IllegalArgumentException("Invalid value for attribute "+
"sides");
}
this.sides = sides;
}
/**
* Sets how consecutive pages should be imposed upon the sides of the
* print medium for jobs using these attributes to the default. The
* default imposition is SidesType.ONE_SIDED.
*/
public void setSidesToDefault() {
setSides(SidesType.ONE_SIDED);
}
/**
* Returns, for jobs using these attributes, the last page (inclusive)
* to be printed, if a range of pages is to be printed. This attribute is
* updated to the value chosen by the user. An application should ignore
* this attribute on output, unless the return value of the <code>
* getDefaultSelection</code> method is DefaultSelectionType.RANGE. An
* application should honor the return value of <code>getPageRanges</code>
* over the return value of this method, if possible.
*
* @return an integer greater than zero and greater than or equal
* to <i>toPage</i> and greater than or equal to <i>minPage</i>
* and less than or equal to <i>maxPage</i>.
*/
public int getToPage() {
if (toPage != 0) {
return toPage;
} else if (fromPage != 0) {
return fromPage;
} else if (pageRanges != null) {
return prLast;
} else {
return getMinPage();
}
}
/**
* Specifies, for jobs using these attributes, the last page (inclusive)
* to be printed, if a range of pages is to be printed.
* If this attribute is not specified, then the values from the pageRanges
* attribute are used. If pageRanges and either or both of fromPage and
* toPage are specified, pageRanges takes precedence. Specifying none of
* pageRanges, fromPage, or toPage is equivalent to calling
* setPageRanges(new int[][] { new int[] { <i>minPage</i> } });
*
* @param toPage an integer greater than zero and greater than or equal
* to <i>fromPage</i> and greater than or equal to <i>minPage</i>
* and less than or equal to <i>maxPage</i>.
* @throws IllegalArgumentException if one or more of the above
* conditions is violated.
*/
public void setToPage(int toPage) {
if (toPage <= 0 ||
(fromPage != 0 && toPage < fromPage) ||
toPage < minPage ||
toPage > maxPage) {
throw new IllegalArgumentException("Invalid value for attribute "+
"toPage");
}
this.toPage = toPage;
}
/**
* Determines whether two JobAttributes are equal to each other.
* <p>
* Two JobAttributes are equal if and only if each of their attributes are
* equal. Attributes of enumeration type are equal if and only if the
* fields refer to the same unique enumeration object. A set of page
* ranges is equal if and only if the sets are of equal length, each range
* enumerates the same pages, and the ranges are in the same order.
*
* @param obj the object whose equality will be checked.
* @return whether obj is equal to this JobAttribute according to the
* above criteria.
*/
public boolean equals(Object obj) {
if (!(obj instanceof JobAttributes)) {
return false;
}
JobAttributes rhs = (JobAttributes)obj;
if (fileName == null) {
if (rhs.fileName != null) {
return false;
}
} else {
if (!fileName.equals(rhs.fileName)) {
return false;
}
}
if (pageRanges == null) {
if (rhs.pageRanges != null) {
return false;
}
} else {
if (rhs.pageRanges == null ||
pageRanges.length != rhs.pageRanges.length) {
return false;
}
for (int i = 0; i < pageRanges.length; i++) {
if (pageRanges[i][0] != rhs.pageRanges[i][0] ||
pageRanges[i][1] != rhs.pageRanges[i][1]) {
return false;
}
}
}
if (printer == null) {
if (rhs.printer != null) {
return false;
}
} else {
if (!printer.equals(rhs.printer)) {
return false;
}
}
return (copies == rhs.copies &&
defaultSelection == rhs.defaultSelection &&
destination == rhs.destination &&
dialog == rhs.dialog &&
fromPage == rhs.fromPage &&
maxPage == rhs.maxPage &&
minPage == rhs.minPage &&
multipleDocumentHandling == rhs.multipleDocumentHandling &&
prFirst == rhs.prFirst &&
prLast == rhs.prLast &&
sides == rhs.sides &&
toPage == rhs.toPage);
}
/**
* Returns a hash code value for this JobAttributes.
*
* @return the hash code.
*/
public int hashCode() {
int rest = ((copies + fromPage + maxPage + minPage + prFirst + prLast +
toPage) * 31) << 21;
if (pageRanges != null) {
int sum = 0;
for (int i = 0; i < pageRanges.length; i++) {
sum += pageRanges[i][0] + pageRanges[i][1];
}
rest ^= (sum * 31) << 11;
}
if (fileName != null) {
rest ^= fileName.hashCode();
}
if (printer != null) {
rest ^= printer.hashCode();
}
return (defaultSelection.hashCode() << 6 ^
destination.hashCode() << 5 ^
dialog.hashCode() << 3 ^
multipleDocumentHandling.hashCode() << 2 ^
sides.hashCode() ^
rest);
}
/**
* Returns a string representation of this JobAttributes.
*
* @return the string representation.
*/
public String toString() {
int[][] pageRanges = getPageRanges();
String prStr = "[";
boolean first = true;
for (int i = 0; i < pageRanges.length; i++) {
if (first) {
first = false;
} else {
prStr += ",";
}
prStr += pageRanges[i][0] + ":" + pageRanges[i][1];
}
prStr += "]";
return "copies=" + getCopies() + ",defaultSelection=" +
getDefaultSelection() + ",destination=" + getDestination() +
",dialog=" + getDialog() + ",fileName=" + getFileName() +
",fromPage=" + getFromPage() + ",maxPage=" + getMaxPage() +
",minPage=" + getMinPage() + ",multiple-document-handling=" +
getMultipleDocumentHandling() + ",page-ranges=" + prStr +
",printer=" + getPrinter() + ",sides=" + getSides() + ",toPage=" +
getToPage();
}
}