1 /*
   2  * Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package javax.print.attribute.standard;
  27 
  28 import javax.print.attribute.Attribute;
  29 import javax.print.attribute.DocAttribute;
  30 import javax.print.attribute.PrintJobAttribute;
  31 import javax.print.attribute.PrintRequestAttribute;
  32 import javax.print.attribute.SetOfIntegerSyntax;
  33 
  34 /**
  35  * Class {@code PageRanges} is a printing attribute class, a set of integers,
  36  * that identifies the range(s) of print-stream pages that the Printer object
  37  * uses for each copy of each document which are to be printed. Nothing is
  38  * printed for any pages identified that do not exist in the document(s). The
  39  * attribute is associated with <i>print-stream</i> pages, not
  40  * application-numbered pages (for example, the page numbers found in the
  41  * headers and or footers for certain word processing applications).
  42  * <p>
  43  * In most cases, the exact pages to be printed will be generated by a device
  44  * driver and this attribute would not be required. However, when printing an
  45  * archived document which has already been formatted, the end user may elect to
  46  * print just a subset of the pages contained in the document. In this case, if
  47  * a page range of <code>"<i>n</i>-<i>m</i>"</code> is specified, the first page
  48  * to be printed will be page <i>n.</i> All subsequent pages of the document
  49  * will be printed through and including page <i>m.</i>
  50  * <p>
  51  * If a {@code PageRanges} attribute is not specified for a print job, all pages
  52  * of the document will be printed. In other words, the default value for the
  53  * {@code PageRanges} attribute is always {@code {{1, Integer.MAX_VALUE}}}.
  54  * <p>
  55  * The effect of a {@code PageRanges} attribute on a multidoc print job (a job
  56  * with multiple documents) depends on whether all the docs have the same page
  57  * ranges specified or whether different docs have different page ranges
  58  * specified, and on the (perhaps defaulted) value of the
  59  * {@link MultipleDocumentHandling MultipleDocumentHandling} attribute.
  60  * <ul>
  61  *   <li>If all the docs have the same page ranges specified, then any value of
  62  *   {@link MultipleDocumentHandling MultipleDocumentHandling} makes sense, and
  63  *   the printer's processing depends on the
  64  *   {@link MultipleDocumentHandling MultipleDocumentHandling} value:
  65  *   <ul>
  66  *     <li>{@code SINGLE_DOCUMENT} -- All the input docs will be combined
  67  *     together into one output document. The specified page ranges of that
  68  *     output document will be printed.
  69  *     <li>{@code SINGLE_DOCUMENT_NEW_SHEET} -- All the input docs will be
  70  *     combined together into one output document, and the first impression of
  71  *     each input doc will always start on a new media sheet. The specified page
  72  *     ranges of that output document will be printed.
  73  *     <li>{@code SEPARATE_DOCUMENTS_UNCOLLATED_COPIES} -- For each separate
  74  *     input doc, the specified page ranges will be printed.
  75  *     <li>{@code SEPARATE_DOCUMENTS_COLLATED_COPIES} -- For each separate input
  76  *     doc, the specified page ranges will be printed.
  77  *   </ul>
  78  *   <ul>
  79  *     <li>{@code SEPARATE_DOCUMENTS_UNCOLLATED_COPIES} -- For each separate
  80  *     input doc, its own specified page ranges will be printed.
  81  *     <li>{@code SEPARATE_DOCUMENTS_COLLATED_COPIES} -- For each separate input
  82  *     doc, its own specified page ranges will be printed.
  83  *   </ul>
  84  * </ul>
  85  * <p>
  86  * <b>IPP Compatibility:</b> The PageRanges attribute's canonical array form
  87  * gives the lower and upper bound for each range of pages to be included in and
  88  * IPP "page-ranges" attribute. See class
  89  * {@link SetOfIntegerSyntax SetOfIntegerSyntax} for an explanation of canonical
  90  * array form. The category name returned by {@code getName()} gives the IPP
  91  * attribute name.
  92  *
  93  * @author David Mendenhall
  94  * @author Alan Kaminsky
  95  */
  96 public final class PageRanges   extends SetOfIntegerSyntax
  97         implements DocAttribute, PrintRequestAttribute, PrintJobAttribute {
  98 
  99     /**
 100      * Use serialVersionUID from JDK 1.4 for interoperability.
 101      */
 102     private static final long serialVersionUID = 8639895197656148392L;
 103 
 104     /**
 105      * Construct a new page ranges attribute with the given members. The members
 106      * are specified in "array form;" see class
 107      * {@link SetOfIntegerSyntax SetOfIntegerSyntax} for an explanation of array
 108      * form.
 109      *
 110      * @param  members set members in array form
 111      * @throws NullPointerException if {@code members} is {@code null} or any
 112      *         element of {@code members} is {@code null}
 113      * @throws IllegalArgumentException if any element of {@code members} is not
 114      *         a length-one or length-two array. Also if {@code members} is a
 115      *         zero-length array or if any member of the set is less than 1.
 116      */
 117     public PageRanges(int[][] members) {
 118         super (members);
 119         if (members == null) {
 120             throw new NullPointerException("members is null");
 121         }
 122         myPageRanges();
 123     }
 124 
 125     /**
 126      * Construct a new page ranges attribute with the given members in string
 127      * form. See class {@link SetOfIntegerSyntax SetOfIntegerSyntax} for
 128      * explanation of the syntax.
 129      *
 130      * @param  members set members in string form
 131      * @throws NullPointerException if {@code members} is {@code null} or any
 132      * element of {@code members} is {@code null}
 133      * @throws IllegalArgumentException if {@code members} does not obey the
 134      *         proper syntax. Also if the constructed set-of-integer is a
 135      *         zero-length array or if any member of the set is less than 1.
 136      */
 137     public PageRanges(String members) {
 138         super(members);
 139         if (members == null) {
 140             throw new NullPointerException("members is null");
 141         }
 142         myPageRanges();
 143     }
 144 
 145     /**
 146      * Validates the page ranges.
 147      */
 148     private void myPageRanges() {
 149         int[][] myMembers = getMembers();
 150         int n = myMembers.length;
 151         if (n == 0) {
 152             throw new IllegalArgumentException("members is zero-length");
 153         }
 154         int i;
 155         for (i = 0; i < n; ++ i) {
 156           if (myMembers[i][0] < 1) {
 157             throw new IllegalArgumentException("Page value < 1 specified");
 158           }
 159         }
 160     }
 161 
 162     /**
 163      * Construct a new page ranges attribute containing a single integer. That
 164      * is, only the one page is to be printed.
 165      *
 166      * @param  member set member
 167      * @throws IllegalArgumentException if {@code member < 1}
 168      */
 169     public PageRanges(int member) {
 170         super (member);
 171         if (member < 1) {
 172             throw new IllegalArgumentException("Page value < 1 specified");
 173         }
 174     }
 175 
 176     /**
 177      * Construct a new page ranges attribute containing a single range of
 178      * integers. That is, only those pages in the one range are to be printed.
 179      *
 180      * @param  lowerBound lower bound of the range
 181      * @param  upperBound upper bound of the range
 182      * @throws IllegalArgumentException if a {@code null} range is specified or
 183      *         if a {@code non-null} range is specified with {@code lowerBound}
 184      *         less than 1
 185      */
 186     public PageRanges(int lowerBound, int upperBound) {
 187         super (lowerBound, upperBound);
 188         if (lowerBound > upperBound) {
 189             throw new IllegalArgumentException("Null range specified");
 190         } else if (lowerBound < 1) {
 191             throw new IllegalArgumentException("Page value < 1 specified");
 192         }
 193     }
 194 
 195     /**
 196      * Returns whether this page ranges attribute is equivalent to the passed in
 197      * object. To be equivalent, all of the following conditions must be true:
 198      * <ol type=1>
 199      *   <li>{@code object} is not {@code null}.
 200      *   <li>{@code object} is an instance of class {@code PageRanges}.
 201      *   <li>This page ranges attribute's members and {@code object}'s members
 202      *   are the same.
 203      * </ol>
 204      *
 205      * @param  object {@code Object} to compare to
 206      * @return {@code true} if {@code object} is equivalent to this page ranges
 207      *         attribute, {@code false} otherwise
 208      */
 209     public boolean equals(Object object) {
 210         return (super.equals(object) && object instanceof PageRanges);
 211     }
 212 
 213     /**
 214      * Get the printing attribute class which is to be used as the "category"
 215      * for this printing attribute value.
 216      * <p>
 217      * For class {@code PageRanges}, the category is class
 218      * {@code PageRanges} itself.
 219      *
 220      * @return printing attribute class (category), an instance of class
 221      *         {@link Class java.lang.Class}
 222      */
 223     public final Class<? extends Attribute> getCategory() {
 224         return PageRanges.class;
 225     }
 226 
 227     /**
 228      * Get the name of the category of which this attribute value is an
 229      * instance.
 230      * <p>
 231      * For class {@code PageRanges}, the category name is {@code "page-ranges"}.
 232      *
 233      * @return attribute category name
 234      */
 235     public final String getName() {
 236         return "page-ranges";
 237     }
 238 }