1 /*
   2  * Copyright (c) 2000, 2004, 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 
  27 package javax.print.attribute;
  28 
  29 import java.io.Serializable;
  30 
  31 /**
  32  * Class AttributeSetUtilities provides static methods for manipulating
  33  * AttributeSets.
  34  * <ul>
  35  * <li>Methods for creating unmodifiable and synchronized views of attribute
  36  * sets.
  37  * <li>operations useful for building
  38  * implementations of interface {@link AttributeSet AttributeSet}
  39  * </ul>
  40  * <P>
  41  * An <B>unmodifiable view</B> <I>U</I> of an AttributeSet <I>S</I> provides a
  42  * client with "read-only" access to <I>S</I>. Query operations on <I>U</I>
  43  * "read through" to <I>S</I>; thus, changes in <I>S</I> are reflected in
  44  * <I>U</I>. However, any attempt to modify <I>U</I>,
  45  *  results in an UnmodifiableSetException.
  46  * The unmodifiable view object <I>U</I> will be serializable if the
  47  * attribute set object <I>S</I> is serializable.
  48  * <P>
  49  * A <B>synchronized view</B> <I>V</I> of an attribute set <I>S</I> provides a
  50  * client with synchronized (multiple thread safe) access to <I>S</I>. Each
  51  * operation of <I>V</I> is synchronized using <I>V</I> itself as the lock
  52  * object and then merely invokes the corresponding operation of <I>S</I>. In
  53  * order to guarantee mutually exclusive access, it is critical that all
  54  * access to <I>S</I> is accomplished through <I>V</I>. The synchronized view
  55  * object <I>V</I> will be serializable if the attribute set object <I>S</I>
  56  * is serializable.
  57  * <P>
  58  * As mentioned in the package description of javax.print, a null reference
  59  * parameter to methods is
  60  * incorrect unless explicitly documented on the method as having a meaningful
  61  * interpretation.  Usage to the contrary is incorrect coding and may result in
  62  * a run time exception either immediately
  63  * or at some later time. IllegalArgumentException and NullPointerException
  64  * are examples of typical and acceptable run time exceptions for such cases.
  65  *
  66  * @author  Alan Kaminsky
  67  */
  68 public final class AttributeSetUtilities {
  69 
  70     /* Suppress default constructor, ensuring non-instantiability.
  71      */
  72     private AttributeSetUtilities() {
  73     }
  74 
  75     /**
  76       * @serial include
  77       */
  78     private static class UnmodifiableAttributeSet
  79         implements AttributeSet, Serializable {
  80 
  81         private AttributeSet attrset;
  82 
  83         /* Unmodifiable view of the underlying attribute set.
  84          */
  85         public UnmodifiableAttributeSet(AttributeSet attributeSet) {
  86 
  87             attrset = attributeSet;
  88         }
  89 
  90         public Attribute get(Class<?> key) {
  91             return attrset.get(key);
  92         }
  93 
  94         public boolean add(Attribute attribute) {
  95             throw new UnmodifiableSetException();
  96         }
  97 
  98         public synchronized boolean remove(Class<?> category) {
  99             throw new UnmodifiableSetException();
 100         }
 101 
 102         public boolean remove(Attribute attribute) {
 103             throw new UnmodifiableSetException();
 104         }
 105 
 106         public boolean containsKey(Class<?> category) {
 107             return attrset.containsKey(category);
 108         }
 109 
 110         public boolean containsValue(Attribute attribute) {
 111             return attrset.containsValue(attribute);
 112         }
 113 
 114         public boolean addAll(AttributeSet attributes) {
 115             throw new UnmodifiableSetException();
 116         }
 117 
 118         public int size() {
 119             return attrset.size();
 120         }
 121 
 122         public Attribute[] toArray() {
 123             return attrset.toArray();
 124         }
 125 
 126         public void clear() {
 127             throw new UnmodifiableSetException();
 128         }
 129 
 130         public boolean isEmpty() {
 131             return attrset.isEmpty();
 132         }
 133 
 134         public boolean equals(Object o) {
 135             return attrset.equals (o);
 136         }
 137 
 138         public int hashCode() {
 139             return attrset.hashCode();
 140         }
 141 
 142     }
 143 
 144     /**
 145       * @serial include
 146       */
 147     private static class UnmodifiableDocAttributeSet
 148         extends UnmodifiableAttributeSet
 149         implements DocAttributeSet, Serializable {
 150 
 151         public UnmodifiableDocAttributeSet(DocAttributeSet attributeSet) {
 152 
 153             super (attributeSet);
 154         }
 155     }
 156 
 157     /**
 158       * @serial include
 159       */
 160     private static class UnmodifiablePrintRequestAttributeSet
 161         extends UnmodifiableAttributeSet
 162         implements PrintRequestAttributeSet, Serializable
 163     {
 164         public UnmodifiablePrintRequestAttributeSet
 165             (PrintRequestAttributeSet attributeSet) {
 166 
 167             super (attributeSet);
 168         }
 169     }
 170 
 171     /**
 172       * @serial include
 173       */
 174     private static class UnmodifiablePrintJobAttributeSet
 175         extends UnmodifiableAttributeSet
 176         implements PrintJobAttributeSet, Serializable
 177     {
 178         public UnmodifiablePrintJobAttributeSet
 179             (PrintJobAttributeSet attributeSet) {
 180 
 181             super (attributeSet);
 182         }
 183     }
 184 
 185     /**
 186       * @serial include
 187       */
 188     private static class UnmodifiablePrintServiceAttributeSet
 189         extends UnmodifiableAttributeSet
 190         implements PrintServiceAttributeSet, Serializable
 191     {
 192         public UnmodifiablePrintServiceAttributeSet
 193             (PrintServiceAttributeSet attributeSet) {
 194 
 195             super (attributeSet);
 196         }
 197     }
 198 
 199     /**
 200      * Creates an unmodifiable view of the given attribute set.
 201      *
 202      * @param  attributeSet  Underlying attribute set.
 203      *
 204      * @return  Unmodifiable view of <CODE>attributeSet</CODE>.
 205      *
 206      * @exception  NullPointerException
 207      *     Thrown if <CODE>attributeSet</CODE> is null. Null is never a
 208      */
 209     public static AttributeSet unmodifiableView(AttributeSet attributeSet) {
 210         if (attributeSet == null) {
 211             throw new NullPointerException();
 212         }
 213 
 214         return new UnmodifiableAttributeSet(attributeSet);
 215     }
 216 
 217     /**
 218      * Creates an unmodifiable view of the given doc attribute set.
 219      *
 220      * @param  attributeSet  Underlying doc attribute set.
 221      *
 222      * @return  Unmodifiable view of <CODE>attributeSet</CODE>.
 223      *
 224      * @exception  NullPointerException
 225      *     Thrown if <CODE>attributeSet</CODE> is null.
 226      */
 227     public static DocAttributeSet unmodifiableView
 228         (DocAttributeSet attributeSet) {
 229         if (attributeSet == null) {
 230             throw new NullPointerException();
 231         }
 232         return new UnmodifiableDocAttributeSet(attributeSet);
 233     }
 234 
 235     /**
 236      * Creates an unmodifiable view of the given print request attribute set.
 237      *
 238      * @param  attributeSet  Underlying print request attribute set.
 239      *
 240      * @return  Unmodifiable view of <CODE>attributeSet</CODE>.
 241      *
 242      * @exception  NullPointerException
 243      *     Thrown if <CODE>attributeSet</CODE> is null.
 244      */
 245     public static PrintRequestAttributeSet
 246         unmodifiableView(PrintRequestAttributeSet attributeSet) {
 247         if (attributeSet == null) {
 248             throw new NullPointerException();
 249         }
 250         return new UnmodifiablePrintRequestAttributeSet(attributeSet);
 251     }
 252 
 253     /**
 254      * Creates an unmodifiable view of the given print job attribute set.
 255      *
 256      * @param  attributeSet  Underlying print job attribute set.
 257      *
 258      * @return  Unmodifiable view of <CODE>attributeSet</CODE>.
 259      *
 260      * @exception  NullPointerException
 261      *     Thrown if <CODE>attributeSet</CODE> is null.
 262      */
 263     public static PrintJobAttributeSet
 264         unmodifiableView(PrintJobAttributeSet attributeSet) {
 265         if (attributeSet == null) {
 266             throw new NullPointerException();
 267         }
 268         return new UnmodifiablePrintJobAttributeSet(attributeSet);
 269     }
 270 
 271     /**
 272      * Creates an unmodifiable view of the given print service attribute set.
 273      *
 274      * @param  attributeSet  Underlying print service attribute set.
 275      *
 276      * @return  Unmodifiable view of <CODE>attributeSet</CODE>.
 277      *
 278      * @exception  NullPointerException
 279      *     Thrown if <CODE>attributeSet</CODE> is null.
 280      */
 281     public static PrintServiceAttributeSet
 282         unmodifiableView(PrintServiceAttributeSet attributeSet) {
 283         if (attributeSet == null) {
 284             throw new NullPointerException();
 285         }
 286         return new UnmodifiablePrintServiceAttributeSet (attributeSet);
 287     }
 288 
 289     /**
 290       * @serial include
 291       */
 292     private static class SynchronizedAttributeSet
 293                         implements AttributeSet, Serializable {
 294 
 295         private AttributeSet attrset;
 296 
 297         public SynchronizedAttributeSet(AttributeSet attributeSet) {
 298             attrset = attributeSet;
 299         }
 300 
 301         public synchronized Attribute get(Class<?> category) {
 302             return attrset.get(category);
 303         }
 304 
 305         public synchronized boolean add(Attribute attribute) {
 306             return attrset.add(attribute);
 307         }
 308 
 309         public synchronized boolean remove(Class<?> category) {
 310             return attrset.remove(category);
 311         }
 312 
 313         public synchronized boolean remove(Attribute attribute) {
 314             return attrset.remove(attribute);
 315         }
 316 
 317         public synchronized boolean containsKey(Class<?> category) {
 318             return attrset.containsKey(category);
 319         }
 320 
 321         public synchronized boolean containsValue(Attribute attribute) {
 322             return attrset.containsValue(attribute);
 323         }
 324 
 325         public synchronized boolean addAll(AttributeSet attributes) {
 326             return attrset.addAll(attributes);
 327         }
 328 
 329         public synchronized int size() {
 330             return attrset.size();
 331         }
 332 
 333         public synchronized Attribute[] toArray() {
 334             return attrset.toArray();
 335         }
 336 
 337         public synchronized void clear() {
 338             attrset.clear();
 339         }
 340 
 341         public synchronized boolean isEmpty() {
 342             return attrset.isEmpty();
 343         }
 344 
 345         public synchronized boolean equals(Object o) {
 346             return attrset.equals (o);
 347         }
 348 
 349         public synchronized int hashCode() {
 350             return attrset.hashCode();
 351         }
 352     }
 353 
 354     /**
 355       * @serial include
 356       */
 357     private static class SynchronizedDocAttributeSet
 358         extends SynchronizedAttributeSet
 359         implements DocAttributeSet, Serializable {
 360 
 361         public SynchronizedDocAttributeSet(DocAttributeSet attributeSet) {
 362             super(attributeSet);
 363         }
 364     }
 365 
 366     /**
 367       * @serial include
 368       */
 369     private static class SynchronizedPrintRequestAttributeSet
 370         extends SynchronizedAttributeSet
 371         implements PrintRequestAttributeSet, Serializable {
 372 
 373         public SynchronizedPrintRequestAttributeSet
 374             (PrintRequestAttributeSet attributeSet) {
 375             super(attributeSet);
 376         }
 377     }
 378 
 379     /**
 380       * @serial include
 381       */
 382     private static class SynchronizedPrintJobAttributeSet
 383         extends SynchronizedAttributeSet
 384         implements PrintJobAttributeSet, Serializable {
 385 
 386         public SynchronizedPrintJobAttributeSet
 387             (PrintJobAttributeSet attributeSet) {
 388             super(attributeSet);
 389         }
 390     }
 391 
 392     /**
 393       * @serial include
 394       */
 395     private static class SynchronizedPrintServiceAttributeSet
 396         extends SynchronizedAttributeSet
 397         implements PrintServiceAttributeSet, Serializable {
 398         public SynchronizedPrintServiceAttributeSet
 399             (PrintServiceAttributeSet attributeSet) {
 400             super(attributeSet);
 401         }
 402     }
 403 
 404     /**
 405      * Creates a synchronized view of the given attribute set.
 406      *
 407      * @param  attributeSet  Underlying attribute set.
 408      *
 409      * @return  Synchronized view of <CODE>attributeSet</CODE>.
 410      *
 411      * @exception  NullPointerException
 412      *     Thrown if <CODE>attributeSet</CODE> is null.
 413      */
 414     public static AttributeSet synchronizedView
 415         (AttributeSet attributeSet) {
 416         if (attributeSet == null) {
 417             throw new NullPointerException();
 418         }
 419         return new SynchronizedAttributeSet(attributeSet);
 420     }
 421 
 422     /**
 423      * Creates a synchronized view of the given doc attribute set.
 424      *
 425      * @param  attributeSet  Underlying doc attribute set.
 426      *
 427      * @return  Synchronized view of <CODE>attributeSet</CODE>.
 428      *
 429      * @exception  NullPointerException
 430      *     Thrown if <CODE>attributeSet</CODE> is null.
 431      */
 432     public static DocAttributeSet
 433         synchronizedView(DocAttributeSet attributeSet) {
 434         if (attributeSet == null) {
 435             throw new NullPointerException();
 436         }
 437         return new SynchronizedDocAttributeSet(attributeSet);
 438     }
 439 
 440     /**
 441      * Creates a synchronized view of the given print request attribute set.
 442      *
 443      * @param  attributeSet  Underlying print request attribute set.
 444      *
 445      * @return  Synchronized view of <CODE>attributeSet</CODE>.
 446      *
 447      * @exception  NullPointerException
 448      *     Thrown if <CODE>attributeSet</CODE> is null.
 449      */
 450     public static PrintRequestAttributeSet
 451         synchronizedView(PrintRequestAttributeSet attributeSet) {
 452         if (attributeSet == null) {
 453             throw new NullPointerException();
 454         }
 455         return new SynchronizedPrintRequestAttributeSet(attributeSet);
 456     }
 457 
 458     /**
 459      * Creates a synchronized view of the given print job attribute set.
 460      *
 461      * @param  attributeSet  Underlying print job attribute set.
 462      *
 463      * @return  Synchronized view of <CODE>attributeSet</CODE>.
 464      *
 465      * @exception  NullPointerException
 466      *     Thrown if <CODE>attributeSet</CODE> is null.
 467      */
 468     public static PrintJobAttributeSet
 469         synchronizedView(PrintJobAttributeSet attributeSet) {
 470         if (attributeSet == null) {
 471             throw new NullPointerException();
 472         }
 473         return new SynchronizedPrintJobAttributeSet(attributeSet);
 474     }
 475 
 476     /**
 477      * Creates a synchronized view of the given print service attribute set.
 478      *
 479      * @param  attributeSet  Underlying print service attribute set.
 480      *
 481      * @return  Synchronized view of <CODE>attributeSet</CODE>.
 482      */
 483     public static PrintServiceAttributeSet
 484         synchronizedView(PrintServiceAttributeSet attributeSet) {
 485         if (attributeSet == null) {
 486             throw new NullPointerException();
 487         }
 488         return new SynchronizedPrintServiceAttributeSet(attributeSet);
 489     }
 490 
 491 
 492     /**
 493      * Verify that the given object is a {@link java.lang.Class Class} that
 494      * implements the given interface, which is assumed to be interface {@link
 495      * Attribute Attribute} or a subinterface thereof.
 496      *
 497      * @param  object     Object to test.
 498      * @param  interfaceName  Interface the object must implement.
 499      *
 500      * @return  If <CODE>object</CODE> is a {@link java.lang.Class Class}
 501      *          that implements <CODE>interfaceName</CODE>,
 502      *          <CODE>object</CODE> is returned downcast to type {@link
 503      *          java.lang.Class Class}; otherwise an exception is thrown.
 504      *
 505      * @exception  NullPointerException
 506      *     (unchecked exception) Thrown if <CODE>object</CODE> is null.
 507      * @exception  ClassCastException
 508      *     (unchecked exception) Thrown if <CODE>object</CODE> is not a
 509      *     {@link java.lang.Class Class} that implements
 510      *     <CODE>interfaceName</CODE>.
 511      */
 512     public static Class<?>
 513         verifyAttributeCategory(Object object, Class<?> interfaceName) {
 514 
 515         Class result = (Class) object;
 516         if (interfaceName.isAssignableFrom (result)) {
 517             return result;
 518         }
 519         else {
 520             throw new ClassCastException();
 521         }
 522     }
 523 
 524     /**
 525      * Verify that the given object is an instance of the given interface, which
 526      * is assumed to be interface {@link Attribute Attribute} or a subinterface
 527      * thereof.
 528      *
 529      * @param  object     Object to test.
 530      * @param  interfaceName  Interface of which the object must be an instance.
 531      *
 532      * @return  If <CODE>object</CODE> is an instance of
 533      *          <CODE>interfaceName</CODE>, <CODE>object</CODE> is returned
 534      *          downcast to type {@link Attribute Attribute}; otherwise an
 535      *          exception is thrown.
 536      *
 537      * @exception  NullPointerException
 538      *     (unchecked exception) Thrown if <CODE>object</CODE> is null.
 539      * @exception  ClassCastException
 540      *     (unchecked exception) Thrown if <CODE>object</CODE> is not an
 541      *     instance of <CODE>interfaceName</CODE>.
 542      */
 543     public static Attribute
 544         verifyAttributeValue(Object object, Class<?> interfaceName) {
 545 
 546         if (object == null) {
 547             throw new NullPointerException();
 548         }
 549         else if (interfaceName.isInstance (object)) {
 550             return (Attribute) object;
 551         } else {
 552             throw new ClassCastException();
 553         }
 554     }
 555 
 556     /**
 557      * Verify that the given attribute category object is equal to the
 558      * category of the given attribute value object. If so, this method
 559      * returns doing nothing. If not, this method throws an exception.
 560      *
 561      * @param  category   Attribute category to test.
 562      * @param  attribute  Attribute value to test.
 563      *
 564      * @exception  NullPointerException
 565      *     (unchecked exception) Thrown if the <CODE>category</CODE> is
 566      *     null or if the <CODE>attribute</CODE> is null.
 567      * @exception  IllegalArgumentException
 568      *     (unchecked exception) Thrown if the <CODE>category</CODE> is not
 569      *     equal to the category of the <CODE>attribute</CODE>.
 570      */
 571     public static void
 572         verifyCategoryForValue(Class<?> category, Attribute attribute) {
 573 
 574         if (!category.equals (attribute.getCategory())) {
 575             throw new IllegalArgumentException();
 576         }
 577     }
 578 }