001    /* JobAttributes.java -- 
002       Copyright (C) 2002, 2005  Free Software Foundation, Inc.
003    
004    This file is part of GNU Classpath.
005    
006    GNU Classpath is free software; you can redistribute it and/or modify
007    it under the terms of the GNU General Public License as published by
008    the Free Software Foundation; either version 2, or (at your option)
009    any later version.
010    
011    GNU Classpath is distributed in the hope that it will be useful, but
012    WITHOUT ANY WARRANTY; without even the implied warranty of
013    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
014    General Public License for more details.
015    
016    You should have received a copy of the GNU General Public License
017    along with GNU Classpath; see the file COPYING.  If not, write to the
018    Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
019    02110-1301 USA.
020    
021    Linking this library statically or dynamically with other modules is
022    making a combined work based on this library.  Thus, the terms and
023    conditions of the GNU General Public License cover the whole
024    combination.
025    
026    As a special exception, the copyright holders of this library give you
027    permission to link this library with independent modules to produce an
028    executable, regardless of the license terms of these independent
029    modules, and to copy and distribute the resulting executable under
030    terms of your choice, provided that you also meet, for each linked
031    independent module, the terms and conditions of the license of that
032    module.  An independent module is a module which is not derived from
033    or based on this library.  If you modify this library, you may extend
034    this exception to your version of the library, but you are not
035    obligated to do so.  If you do not wish to do so, delete this
036    exception statement from your version. */
037    
038    
039    package java.awt;
040    
041    /**
042     * Needs documentation...
043     *
044     * @author Eric Blake (ebb9@email.byu.edu)
045     * @since 1.3
046     * @status updated to 1.4, lacks documentation
047     */
048    public final class JobAttributes implements Cloneable
049    {
050      public static final class DefaultSelectionType extends AttributeValue
051      {
052        private static final String[] NAMES = { "all", "range", "selection" };
053        public static final DefaultSelectionType ALL
054          = new DefaultSelectionType(0);
055        public static final DefaultSelectionType RANGE
056          = new DefaultSelectionType(1);
057        public static final DefaultSelectionType SELECTION
058          = new DefaultSelectionType(2);
059        private DefaultSelectionType(int value)
060        {
061          super(value, NAMES);
062        }
063      } // class DefaultSelectionType
064    
065      public static final class DestinationType extends AttributeValue
066      {
067        private static final String[] NAMES = { "file", "printer" };
068        public static final DestinationType FILE = new DestinationType(0);
069        public static final DestinationType PRINTER = new DestinationType(1);
070        private DestinationType(int value)
071        {
072          super(value, NAMES);
073        }
074      } // class DestinationType
075    
076      public static final class DialogType extends AttributeValue
077      {
078        private static final String[] NAMES = { "common", "native", "none" };
079        public static final DialogType COMMON = new DialogType(0);
080        public static final DialogType NATIVE = new DialogType(1);
081        public static final DialogType NONE = new DialogType(2);
082        private DialogType(int value)
083        {
084          super(value, NAMES);
085        }
086      } // class DialogType
087    
088      public static final class MultipleDocumentHandlingType
089        extends AttributeValue
090      {
091        private static final String[] NAMES = {
092          "separate-documents-collated-copies",
093          "separate-documents-uncollated-copies"
094        };
095        public static final MultipleDocumentHandlingType
096          SEPARATE_DOCUMENTS_COLLATED_COPIES
097          = new MultipleDocumentHandlingType(0);
098        public static final MultipleDocumentHandlingType
099          SEPARATE_DOCUMENTS_UNCOLLATED_COPIES
100          = new MultipleDocumentHandlingType(1);
101        private MultipleDocumentHandlingType(int value)
102        {
103          super(value, NAMES);
104        }
105      } // class MultipleDocumentHandlingType
106    
107      public static final class SidesType extends AttributeValue
108      {
109        private static final String[] NAMES
110          = { "one-sided", "two-sided-long-edge", "two-sided-short-edge" };
111        public static final SidesType ONE_SIDED = new SidesType(0);
112        public static final SidesType TWO_SIDED_LONG_EDGE = new SidesType(1);
113        public static final SidesType TWO_SIDED_SHORT_EDGE = new SidesType(2);
114        private SidesType(int value)
115        {
116          super(value, NAMES);
117        }
118      } // class SidesType
119    
120      private int copies;
121      private DefaultSelectionType selection;
122      private DestinationType destination;
123      private DialogType dialog;
124      private String filename;
125      private int maxPage;
126      private int minPage;
127      private MultipleDocumentHandlingType multiple;
128      private int[][] pageRanges; // null for default value
129      private int fromPage; // 0 for default value
130      private int toPage; // 0 for default value
131      private String printer;
132      private SidesType sides;
133    
134      public JobAttributes()
135      {
136        copies = 1;
137        selection = DefaultSelectionType.ALL;
138        destination = DestinationType.PRINTER;
139        dialog = DialogType.NATIVE;
140        maxPage = Integer.MAX_VALUE;
141        minPage = 1;
142        multiple
143          = MultipleDocumentHandlingType.SEPARATE_DOCUMENTS_UNCOLLATED_COPIES;
144        sides = SidesType.ONE_SIDED;
145      }
146    
147      public JobAttributes(JobAttributes attr)
148      {
149        set(attr);
150      }
151    
152      public JobAttributes(int copies, DefaultSelectionType selection,
153                           DestinationType destination, DialogType dialog,
154                           String filename, int max, int min,
155                           MultipleDocumentHandlingType multiple,
156                           int[][] pageRanges, String printer, SidesType sides)
157      {
158        if (copies <= 0 || selection == null || destination == null
159            || dialog == null || max < min || min <= 0 || multiple == null
160            || sides == null)
161          throw new IllegalArgumentException();
162        this.copies = copies;
163        this.selection = selection;
164        this.destination = destination;
165        this.dialog = dialog;
166        this.filename = filename;
167        maxPage = max;
168        minPage = min;
169        this.multiple = multiple;
170        setPageRanges(pageRanges);
171        this.printer = printer;
172        this.sides = sides;
173      }
174    
175      public Object clone()
176      {
177        return new JobAttributes(this);
178      }
179    
180      public void set(JobAttributes attr)
181      {
182        copies = attr.copies;
183        selection = attr.selection;
184        destination = attr.destination;
185        dialog = attr.dialog;
186        filename = attr.filename;
187        maxPage = attr.maxPage;
188        minPage = attr.minPage;
189        multiple = attr.multiple;
190        pageRanges = (int[][]) attr.pageRanges.clone();
191        printer = attr.printer;
192        sides = attr.sides;
193        fromPage = attr.fromPage;
194        toPage = attr.toPage;
195      }
196    
197      public int getCopies()
198      {
199        return copies;
200      }
201    
202      public void setCopies(int copies)
203      {
204        if (copies <= 0)
205          throw new IllegalArgumentException();
206        this.copies = copies;
207      }
208    
209      public void setCopiesToDefault()
210      {
211        copies = 1;
212      }
213    
214      public DefaultSelectionType getDefaultSelection()
215      {
216        return selection;
217      }
218    
219      public void setDefaultSelection(DefaultSelectionType selection)
220      {
221        if (selection == null)
222          throw new IllegalArgumentException();
223        this.selection = selection;
224      }
225    
226      public DestinationType getDestination()
227      {
228        return destination;
229      }
230    
231      public void setDestination(DestinationType destination)
232      {
233        if (destination == null)
234          throw new IllegalArgumentException();
235        this.destination = destination;
236      }
237    
238      public DialogType getDialog()
239      {
240        return dialog;
241      }
242    
243      public void setDialog(DialogType dialog)
244      {
245        if (dialog == null)
246          throw new IllegalArgumentException();
247        this.dialog = dialog;
248      }
249    
250      public String getFileName()
251      {
252        return filename;
253      }
254    
255      public void setFileName(String filename)
256      {
257        this.filename = filename;
258      }
259    
260      public int getFromPage()
261      {
262        return fromPage != 0 ? fromPage
263          : pageRanges != null ? pageRanges[0][0]
264          : toPage != 0 ? toPage : minPage;
265      }
266    
267      public void setFromPage(int fromPage)
268      {
269        if (fromPage < minPage || (fromPage > toPage && toPage != 0)
270            || fromPage > maxPage)
271          throw new IllegalArgumentException();
272        if (pageRanges == null)
273          this.fromPage = fromPage;
274      }
275    
276      public int getMaxPage()
277      {
278        return maxPage;
279      }
280    
281      public void setMaxPage(int maxPage)
282      {
283        if (maxPage < minPage)
284          throw new IllegalArgumentException();
285        this.maxPage = maxPage;
286        if (maxPage < fromPage)
287          fromPage = maxPage;
288        if (maxPage < toPage)
289          toPage = maxPage;
290        if (pageRanges != null)
291          {
292            int i = pageRanges.length - 1;
293            while (i >= 0 && maxPage < pageRanges[i][1])
294              i--;
295            if (maxPage >= pageRanges[++i][0])
296              pageRanges[i++][1] = maxPage;
297            if (i == 0)
298              pageRanges = null;
299            else if (i < pageRanges.length)
300              {
301                int[][] tmp = new int[i][];
302                System.arraycopy(pageRanges, 0, tmp, 0, i);
303                pageRanges = tmp;
304              }
305          }
306      }
307    
308      public int getMinPage()
309      {
310        return minPage;
311      }
312    
313      public void setMinPage(int minPage)
314      {
315        if (minPage <= 0 || minPage > maxPage)
316          throw new IllegalArgumentException();
317        this.minPage = minPage;
318        if (minPage > toPage)
319          toPage = minPage;
320        if (minPage > fromPage)
321          fromPage = minPage;
322        if (pageRanges != null)
323          {
324            int size = pageRanges.length;
325            int i = 0;
326            while (i < size && minPage > pageRanges[i][0])
327              i++;
328            if (minPage <= pageRanges[i - 1][1])
329              pageRanges[--i][0] = minPage;
330            if (i == size)
331              pageRanges = null;
332            else if (i > 0)
333              {
334                int[][] tmp = new int[size - i][];
335                System.arraycopy(pageRanges, i, tmp, 0, size - i);
336                pageRanges = tmp;
337              }
338          }
339      }
340    
341      public MultipleDocumentHandlingType getMultipleDocumentHandling()
342      {
343        return multiple;
344      }
345    
346      public void setMultipleDocumentHandling
347        (MultipleDocumentHandlingType multiple)
348      {
349        if (multiple == null)
350          throw new IllegalArgumentException();
351        this.multiple = multiple;
352      }
353    
354      public void setMultipleDocumentHandlingToDefault()
355      {
356        multiple
357          = MultipleDocumentHandlingType.SEPARATE_DOCUMENTS_UNCOLLATED_COPIES;
358      }
359    
360      public int[][] getPageRanges()
361      {
362        if (pageRanges == null)
363          return new int[][] { { getFromPage(), getToPage() } };
364        // Perform a deep clone, so user code cannot affect original arrays.
365        int i = pageRanges.length;
366        int[][] result = new int[i][];
367        while (--i >= 0)
368          result[i] = (int[]) pageRanges[i].clone();
369        return result;
370      }
371    
372      public void setPageRanges(int[][] pageRanges)
373      {
374        int size = pageRanges == null ? 0 : pageRanges.length;
375        if (size == 0)
376          throw new IllegalArgumentException();
377        while (--size >= 0)
378          {
379            int[] range = pageRanges[size];
380            if (range == null || range.length != 2
381                || range[0] < minPage || range[1] < range[0] || range[1] > maxPage
382                || (size != 0 && range[0] <= pageRanges[size - 1][1]))
383              throw new IllegalArgumentException();
384          }
385        size = pageRanges.length;
386        if (fromPage > 0 && pageRanges[0][0] > fromPage)
387          fromPage = pageRanges[0][0];
388        if (toPage > 0 && pageRanges[size - 1][1] < toPage)
389          toPage = pageRanges[size - 1][1];
390        this.pageRanges = new int[size][];
391        while (--size >= 0)
392          this.pageRanges[size] = (int[]) pageRanges[size].clone();
393      }
394    
395      public String getPrinter()
396      {
397        return printer;
398      }
399    
400      public void setPrinter(String printer)
401      {
402        this.printer = printer;
403      }
404    
405      public SidesType getSides()
406      {
407        return sides;
408      }
409    
410      public void setSides(SidesType sides)
411      {
412        if (sides == null)
413          throw new IllegalArgumentException();
414        this.sides = sides;
415      }
416    
417      public void setSidesToDefault()
418      {
419        sides = SidesType.ONE_SIDED;
420      }
421    
422      public int getToPage()
423      {
424        return toPage != 0 ? toPage
425          : pageRanges != null ? pageRanges[pageRanges.length - 1][1]
426          : fromPage != 0 ? fromPage : maxPage;
427      }
428    
429      public void setToPage(int toPage)
430      {
431        if (toPage < minPage || (fromPage > toPage && fromPage != 0)
432            || toPage > maxPage)
433          throw new IllegalArgumentException();
434        if (pageRanges == null)
435          this.toPage = toPage;
436      }
437    
438      public boolean equals(Object o)
439      {
440        if (this == o)
441          return true;
442        if (! (o instanceof JobAttributes))
443          return false;
444        JobAttributes ja = (JobAttributes) o;
445        if (copies != ja.copies || selection != ja.selection
446            || destination != ja.destination || dialog != ja.dialog
447            || ! filename.equals(ja.filename) || maxPage != ja.maxPage
448            || minPage != ja.minPage || multiple != ja.multiple
449            || fromPage != ja.fromPage || toPage != ja.toPage
450            || ! printer.equals(ja.printer) || sides != ja.sides
451            || (pageRanges == null) != (ja.pageRanges == null))
452          return false;
453        if (pageRanges != ja.pageRanges)
454          for (int i = pageRanges.length; --i >= 0; )
455            if (pageRanges[i][0] != ja.pageRanges[i][0]
456                || pageRanges[i][1] != ja.pageRanges[i][1])
457              return false;
458        return true;
459      }
460    
461      public int hashCode()
462      {
463        int hash = (selection.value << 6) ^ (destination.value << 5)
464          ^ (dialog.value << 3) ^ (multiple.value << 2) ^ sides.value
465          ^ (filename == null ? 0 : filename.hashCode())
466          ^ (printer == null ? 0 : printer.hashCode());
467        // The effect of the above fields on the hashcode match the JDK. However,
468        // I am unable to reverse engineer the effect of the fields listed below,
469        // so I am using my own implementation. Note that this still satisfies
470        // the general contract of hashcode, it just doesn't match the JDK.
471        hash ^= (copies << 27) ^ (maxPage << 22) ^ (minPage << 17);
472        if (pageRanges == null)
473          hash ^= (getFromPage() << 13) ^ (getToPage() << 8);
474        else
475          for (int i = pageRanges.length; --i >= 0; )
476            hash ^= (pageRanges[i][0] << 13) ^ (pageRanges[i][1] << 8);
477        return hash;
478      }
479    
480      public String toString()
481      {
482        StringBuffer s = new StringBuffer("copies=").append(copies)
483          .append(",defaultSelection=").append(selection).append(",destination=")
484          .append(destination).append(",dialog=").append(dialog)
485          .append(",fileName=").append(filename).append(",fromPage=")
486          .append(getFromPage()).append(",maxPage=").append(maxPage)
487          .append(",minPage=").append(minPage)
488          .append(",multiple-document-handling=").append(multiple)
489          .append(",page-ranges=[");
490        if (pageRanges == null)
491          s.append(minPage).append(':').append(minPage).append(']');
492        else
493          for (int i = 0; i < pageRanges.length; i++)
494            s.append(pageRanges[i][0]).append(':').append(pageRanges[i][1])
495              .append(',');
496        s.setLength(s.length() - 1);
497        return s.append("],printer=").append(printer).append(",sides=")
498          .append(sides).append(",toPage=").append(getToPage()).toString();
499      }
500    } // class JobAttributes