001/* JobAttributes.java --
002   Copyright (C) 2002, 2005  Free Software Foundation, Inc.
003
004This file is part of GNU Classpath.
005
006GNU Classpath is free software; you can redistribute it and/or modify
007it under the terms of the GNU General Public License as published by
008the Free Software Foundation; either version 2, or (at your option)
009any later version.
010
011GNU Classpath is distributed in the hope that it will be useful, but
012WITHOUT ANY WARRANTY; without even the implied warranty of
013MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
014General Public License for more details.
015
016You should have received a copy of the GNU General Public License
017along with GNU Classpath; see the file COPYING.  If not, write to the
018Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
01902110-1301 USA.
020
021Linking this library statically or dynamically with other modules is
022making a combined work based on this library.  Thus, the terms and
023conditions of the GNU General Public License cover the whole
024combination.
025
026As a special exception, the copyright holders of this library give you
027permission to link this library with independent modules to produce an
028executable, regardless of the license terms of these independent
029modules, and to copy and distribute the resulting executable under
030terms of your choice, provided that you also meet, for each linked
031independent module, the terms and conditions of the license of that
032module.  An independent module is a module which is not derived from
033or based on this library.  If you modify this library, you may extend
034this exception to your version of the library, but you are not
035obligated to do so.  If you do not wish to do so, delete this
036exception statement from your version. */
037
038
039package java.awt;
040
041import 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 */
050public 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