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    import gnu.java.lang.CPStringBuilder;
042    
043    /**
044     * Needs documentation...
045     *
046     * @author Eric Blake (ebb9@email.byu.edu)
047     * @since 1.3
048     * @status updated to 1.4, lacks documentation
049     */
050    public final class JobAttributes implements Cloneable
051    {
052      public static final class DefaultSelectionType extends AttributeValue
053      {
054        private static final String[] NAMES = { "all", "range", "selection" };
055        public static final DefaultSelectionType ALL
056          = new DefaultSelectionType(0);
057        public static final DefaultSelectionType RANGE
058          = new DefaultSelectionType(1);
059        public static final DefaultSelectionType SELECTION
060          = new DefaultSelectionType(2);
061        private DefaultSelectionType(int value)
062        {
063          super(value, NAMES);
064        }
065      } // class DefaultSelectionType
066    
067      public static final class DestinationType extends AttributeValue
068      {
069        private static final String[] NAMES = { "file", "printer" };
070        public static final DestinationType FILE = new DestinationType(0);
071        public static final DestinationType PRINTER = new DestinationType(1);
072        private DestinationType(int value)
073        {
074          super(value, NAMES);
075        }
076      } // class DestinationType
077    
078      public static final class DialogType extends AttributeValue
079      {
080        private static final String[] NAMES = { "common", "native", "none" };
081        public static final DialogType COMMON = new DialogType(0);
082        public static final DialogType NATIVE = new DialogType(1);
083        public static final DialogType NONE = new DialogType(2);
084        private DialogType(int value)
085        {
086          super(value, NAMES);
087        }
088      } // class DialogType
089    
090      public static final class MultipleDocumentHandlingType
091        extends AttributeValue
092      {
093        private static final String[] NAMES = {
094          "separate-documents-collated-copies",
095          "separate-documents-uncollated-copies"
096        };
097        public static final MultipleDocumentHandlingType
098          SEPARATE_DOCUMENTS_COLLATED_COPIES
099          = new MultipleDocumentHandlingType(0);
100        public static final MultipleDocumentHandlingType
101          SEPARATE_DOCUMENTS_UNCOLLATED_COPIES
102          = new MultipleDocumentHandlingType(1);
103        private MultipleDocumentHandlingType(int value)
104        {
105          super(value, NAMES);
106        }
107      } // class MultipleDocumentHandlingType
108    
109      public static final class SidesType extends AttributeValue
110      {
111        private static final String[] NAMES
112          = { "one-sided", "two-sided-long-edge", "two-sided-short-edge" };
113        public static final SidesType ONE_SIDED = new SidesType(0);
114        public static final SidesType TWO_SIDED_LONG_EDGE = new SidesType(1);
115        public static final SidesType TWO_SIDED_SHORT_EDGE = new SidesType(2);
116        private SidesType(int value)
117        {
118          super(value, NAMES);
119        }
120      } // class SidesType
121    
122      private int copies;
123      private DefaultSelectionType selection;
124      private DestinationType destination;
125      private DialogType dialog;
126      private String filename;
127      private int maxPage;
128      private int minPage;
129      private MultipleDocumentHandlingType multiple;
130      private int[][] pageRanges; // null for default value
131      private int fromPage; // 0 for default value
132      private int toPage; // 0 for default value
133      private String printer;
134      private SidesType sides;
135    
136      public JobAttributes()
137      {
138        copies = 1;
139        selection = DefaultSelectionType.ALL;
140        destination = DestinationType.PRINTER;
141        dialog = DialogType.NATIVE;
142        maxPage = Integer.MAX_VALUE;
143        minPage = 1;
144        multiple
145          = MultipleDocumentHandlingType.SEPARATE_DOCUMENTS_UNCOLLATED_COPIES;
146        sides = SidesType.ONE_SIDED;
147      }
148    
149      public JobAttributes(JobAttributes attr)
150      {
151        set(attr);
152      }
153    
154      public JobAttributes(int copies, DefaultSelectionType selection,
155                           DestinationType destination, DialogType dialog,
156                           String filename, int max, int min,
157                           MultipleDocumentHandlingType multiple,
158                           int[][] pageRanges, String printer, SidesType sides)
159      {
160        if (copies <= 0 || selection == null || destination == null
161            || dialog == null || max < min || min <= 0 || multiple == null
162            || sides == null)
163          throw new IllegalArgumentException();
164        this.copies = copies;
165        this.selection = selection;
166        this.destination = destination;
167        this.dialog = dialog;
168        this.filename = filename;
169        maxPage = max;
170        minPage = min;
171        this.multiple = multiple;
172        setPageRanges(pageRanges);
173        this.printer = printer;
174        this.sides = sides;
175      }
176    
177      public Object clone()
178      {
179        return new JobAttributes(this);
180      }
181    
182      public void set(JobAttributes attr)
183      {
184        copies = attr.copies;
185        selection = attr.selection;
186        destination = attr.destination;
187        dialog = attr.dialog;
188        filename = attr.filename;
189        maxPage = attr.maxPage;
190        minPage = attr.minPage;
191        multiple = attr.multiple;
192        pageRanges = (int[][]) attr.pageRanges.clone();
193        printer = attr.printer;
194        sides = attr.sides;
195        fromPage = attr.fromPage;
196        toPage = attr.toPage;
197      }
198    
199      public int getCopies()
200      {
201        return copies;
202      }
203    
204      public void setCopies(int copies)
205      {
206        if (copies <= 0)
207          throw new IllegalArgumentException();
208        this.copies = copies;
209      }
210    
211      public void setCopiesToDefault()
212      {
213        copies = 1;
214      }
215    
216      public DefaultSelectionType getDefaultSelection()
217      {
218        return selection;
219      }
220    
221      public void setDefaultSelection(DefaultSelectionType selection)
222      {
223        if (selection == null)
224          throw new IllegalArgumentException();
225        this.selection = selection;
226      }
227    
228      public DestinationType getDestination()
229      {
230        return destination;
231      }
232    
233      public void setDestination(DestinationType destination)
234      {
235        if (destination == null)
236          throw new IllegalArgumentException();
237        this.destination = destination;
238      }
239    
240      public DialogType getDialog()
241      {
242        return dialog;
243      }
244    
245      public void setDialog(DialogType dialog)
246      {
247        if (dialog == null)
248          throw new IllegalArgumentException();
249        this.dialog = dialog;
250      }
251    
252      public String getFileName()
253      {
254        return filename;
255      }
256    
257      public void setFileName(String filename)
258      {
259        this.filename = filename;
260      }
261    
262      public int getFromPage()
263      {
264        return fromPage != 0 ? fromPage
265          : pageRanges != null ? pageRanges[0][0]
266          : toPage != 0 ? toPage : minPage;
267      }
268    
269      public void setFromPage(int fromPage)
270      {
271        if (fromPage < minPage || (fromPage > toPage && toPage != 0)
272            || fromPage > maxPage)
273          throw new IllegalArgumentException();
274        if (pageRanges == null)
275          this.fromPage = fromPage;
276      }
277    
278      public int getMaxPage()
279      {
280        return maxPage;
281      }
282    
283      public void setMaxPage(int maxPage)
284      {
285        if (maxPage < minPage)
286          throw new IllegalArgumentException();
287        this.maxPage = maxPage;
288        if (maxPage < fromPage)
289          fromPage = maxPage;
290        if (maxPage < toPage)
291          toPage = maxPage;
292        if (pageRanges != null)
293          {
294            int i = pageRanges.length - 1;
295            while (i >= 0 && maxPage < pageRanges[i][1])
296              i--;
297            if (maxPage >= pageRanges[++i][0])
298              pageRanges[i++][1] = maxPage;
299            if (i == 0)
300              pageRanges = null;
301            else if (i < pageRanges.length)
302              {
303                int[][] tmp = new int[i][];
304                System.arraycopy(pageRanges, 0, tmp, 0, i);
305                pageRanges = tmp;
306              }
307          }
308      }
309    
310      public int getMinPage()
311      {
312        return minPage;
313      }
314    
315      public void setMinPage(int minPage)
316      {
317        if (minPage <= 0 || minPage > maxPage)
318          throw new IllegalArgumentException();
319        this.minPage = minPage;
320        if (minPage > toPage)
321          toPage = minPage;
322        if (minPage > fromPage)
323          fromPage = minPage;
324        if (pageRanges != null)
325          {
326            int size = pageRanges.length;
327            int i = 0;
328            while (i < size && minPage > pageRanges[i][0])
329              i++;
330            if (minPage <= pageRanges[i - 1][1])
331              pageRanges[--i][0] = minPage;
332            if (i == size)
333              pageRanges = null;
334            else if (i > 0)
335              {
336                int[][] tmp = new int[size - i][];
337                System.arraycopy(pageRanges, i, tmp, 0, size - i);
338                pageRanges = tmp;
339              }
340          }
341      }
342    
343      public MultipleDocumentHandlingType getMultipleDocumentHandling()
344      {
345        return multiple;
346      }
347    
348      public void setMultipleDocumentHandling
349        (MultipleDocumentHandlingType multiple)
350      {
351        if (multiple == null)
352          throw new IllegalArgumentException();
353        this.multiple = multiple;
354      }
355    
356      public void setMultipleDocumentHandlingToDefault()
357      {
358        multiple
359          = MultipleDocumentHandlingType.SEPARATE_DOCUMENTS_UNCOLLATED_COPIES;
360      }
361    
362      public int[][] getPageRanges()
363      {
364        if (pageRanges == null)
365          return new int[][] { { getFromPage(), getToPage() } };
366        // Perform a deep clone, so user code cannot affect original arrays.
367        int i = pageRanges.length;
368        int[][] result = new int[i][];
369        while (--i >= 0)
370          result[i] = (int[]) pageRanges[i].clone();
371        return result;
372      }
373    
374      public void setPageRanges(int[][] pageRanges)
375      {
376        int size = pageRanges == null ? 0 : pageRanges.length;
377        if (size == 0)
378          throw new IllegalArgumentException();
379        while (--size >= 0)
380          {
381            int[] range = pageRanges[size];
382            if (range == null || range.length != 2
383                || range[0] < minPage || range[1] < range[0] || range[1] > maxPage
384                || (size != 0 && range[0] <= pageRanges[size - 1][1]))
385              throw new IllegalArgumentException();
386          }
387        size = pageRanges.length;
388        if (fromPage > 0 && pageRanges[0][0] > fromPage)
389          fromPage = pageRanges[0][0];
390        if (toPage > 0 && pageRanges[size - 1][1] < toPage)
391          toPage = pageRanges[size - 1][1];
392        this.pageRanges = new int[size][];
393        while (--size >= 0)
394          this.pageRanges[size] = (int[]) pageRanges[size].clone();
395      }
396    
397      public String getPrinter()
398      {
399        return printer;
400      }
401    
402      public void setPrinter(String printer)
403      {
404        this.printer = printer;
405      }
406    
407      public SidesType getSides()
408      {
409        return sides;
410      }
411    
412      public void setSides(SidesType sides)
413      {
414        if (sides == null)
415          throw new IllegalArgumentException();
416        this.sides = sides;
417      }
418    
419      public void setSidesToDefault()
420      {
421        sides = SidesType.ONE_SIDED;
422      }
423    
424      public int getToPage()
425      {
426        return toPage != 0 ? toPage
427          : pageRanges != null ? pageRanges[pageRanges.length - 1][1]
428          : fromPage != 0 ? fromPage : maxPage;
429      }
430    
431      public void setToPage(int toPage)
432      {
433        if (toPage < minPage || (fromPage > toPage && fromPage != 0)
434            || toPage > maxPage)
435          throw new IllegalArgumentException();
436        if (pageRanges == null)
437          this.toPage = toPage;
438      }
439    
440      public boolean equals(Object o)
441      {
442        if (this == o)
443          return true;
444        if (! (o instanceof JobAttributes))
445          return false;
446        JobAttributes ja = (JobAttributes) o;
447        if (copies != ja.copies || selection != ja.selection
448            || destination != ja.destination || dialog != ja.dialog
449            || ! filename.equals(ja.filename) || maxPage != ja.maxPage
450            || minPage != ja.minPage || multiple != ja.multiple
451            || fromPage != ja.fromPage || toPage != ja.toPage
452            || ! printer.equals(ja.printer) || sides != ja.sides
453            || (pageRanges == null) != (ja.pageRanges == null))
454          return false;
455        if (pageRanges != ja.pageRanges)
456          for (int i = pageRanges.length; --i >= 0; )
457            if (pageRanges[i][0] != ja.pageRanges[i][0]
458                || pageRanges[i][1] != ja.pageRanges[i][1])
459              return false;
460        return true;
461      }
462    
463      public int hashCode()
464      {
465        int hash = (selection.value << 6) ^ (destination.value << 5)
466          ^ (dialog.value << 3) ^ (multiple.value << 2) ^ sides.value
467          ^ (filename == null ? 0 : filename.hashCode())
468          ^ (printer == null ? 0 : printer.hashCode());
469        // The effect of the above fields on the hashcode match the JDK. However,
470        // I am unable to reverse engineer the effect of the fields listed below,
471        // so I am using my own implementation. Note that this still satisfies
472        // the general contract of hashcode, it just doesn't match the JDK.
473        hash ^= (copies << 27) ^ (maxPage << 22) ^ (minPage << 17);
474        if (pageRanges == null)
475          hash ^= (getFromPage() << 13) ^ (getToPage() << 8);
476        else
477          for (int i = pageRanges.length; --i >= 0; )
478            hash ^= (pageRanges[i][0] << 13) ^ (pageRanges[i][1] << 8);
479        return hash;
480      }
481    
482      public String toString()
483      {
484        CPStringBuilder s = new CPStringBuilder("copies=").append(copies)
485          .append(",defaultSelection=").append(selection).append(",destination=")
486          .append(destination).append(",dialog=").append(dialog)
487          .append(",fileName=").append(filename).append(",fromPage=")
488          .append(getFromPage()).append(",maxPage=").append(maxPage)
489          .append(",minPage=").append(minPage)
490          .append(",multiple-document-handling=").append(multiple)
491          .append(",page-ranges=[");
492        if (pageRanges == null)
493          s.append(minPage).append(':').append(minPage).append(']');
494        else
495          for (int i = 0; i < pageRanges.length; i++)
496            s.append(pageRanges[i][0]).append(':').append(pageRanges[i][1])
497              .append(',');
498        s.setLength(s.length() - 1);
499        return s.append("],printer=").append(printer).append(",sides=")
500          .append(sides).append(",toPage=").append(getToPage()).toString();
501      }
502    } // class JobAttributes