1 /*
   2  * Copyright (c) 2000, 2014, 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         private static final long serialVersionUID = -6131802583863447813L;
  81 
  82         private AttributeSet attrset;
  83 
  84         /* Unmodifiable view of the underlying attribute set.
  85          */
  86         public UnmodifiableAttributeSet(AttributeSet attributeSet) {
  87 
  88             attrset = attributeSet;
  89         }
  90 
  91         public Attribute get(Class<?> key) {
  92             return attrset.get(key);
  93         }
  94 
  95         public boolean add(Attribute attribute) {
  96             throw new UnmodifiableSetException();
  97         }
  98 
  99         public synchronized boolean remove(Class<?> category) {
 100             throw new UnmodifiableSetException();
 101         }
 102 
 103         public boolean remove(Attribute attribute) {
 104             throw new UnmodifiableSetException();
 105         }
 106 
 107         public boolean containsKey(Class<?> category) {
 108             return attrset.containsKey(category);
 109         }
 110 
 111         public boolean containsValue(Attribute attribute) {
 112             return attrset.containsValue(attribute);
 113         }
 114 
 115         public boolean addAll(AttributeSet attributes) {
 116             throw new UnmodifiableSetException();
 117         }
 118 
 119         public int size() {
 120             return attrset.size();
 121         }
 122 
 123         public Attribute[] toArray() {
 124             return attrset.toArray();
 125         }
 126 
 127         public void clear() {
 128             throw new UnmodifiableSetException();
 129         }
 130 
 131         public boolean isEmpty() {
 132             return attrset.isEmpty();
 133         }
 134 
 135         public boolean equals(Object o) {
 136             return attrset.equals (o);
 137         }
 138 
 139         public int hashCode() {
 140             return attrset.hashCode();
 141         }
 142 
 143     }
 144 
 145     /**
 146       * @serial include
 147       */
 148     private static class UnmodifiableDocAttributeSet
 149         extends UnmodifiableAttributeSet
 150         implements DocAttributeSet, Serializable {
 151         private static final long serialVersionUID = -6349408326066898956L;
 152 
 153         public UnmodifiableDocAttributeSet(DocAttributeSet attributeSet) {
 154 
 155             super (attributeSet);
 156         }
 157     }
 158 
 159     /**
 160       * @serial include
 161       */
 162     private static class UnmodifiablePrintRequestAttributeSet
 163         extends UnmodifiableAttributeSet
 164         implements PrintRequestAttributeSet, Serializable
 165     {
 166         private static final long serialVersionUID = 7799373532614825073L;
 167         public UnmodifiablePrintRequestAttributeSet
 168             (PrintRequestAttributeSet attributeSet) {
 169 
 170             super (attributeSet);
 171         }
 172     }
 173 
 174     /**
 175       * @serial include
 176       */
 177     private static class UnmodifiablePrintJobAttributeSet
 178         extends UnmodifiableAttributeSet
 179         implements PrintJobAttributeSet, Serializable
 180     {
 181         private static final long serialVersionUID = -8002245296274522112L;
 182         public UnmodifiablePrintJobAttributeSet
 183             (PrintJobAttributeSet attributeSet) {
 184 
 185             super (attributeSet);
 186         }
 187     }
 188 
 189     /**
 190       * @serial include
 191       */
 192     private static class UnmodifiablePrintServiceAttributeSet
 193         extends UnmodifiableAttributeSet
 194         implements PrintServiceAttributeSet, Serializable
 195     {
 196         private static final long serialVersionUID = -7112165137107826819L;
 197         public UnmodifiablePrintServiceAttributeSet
 198             (PrintServiceAttributeSet attributeSet) {
 199 
 200             super (attributeSet);
 201         }
 202     }
 203 
 204     /**
 205      * Creates an unmodifiable view of the given attribute set.
 206      *
 207      * @param  attributeSet  Underlying attribute set.
 208      *
 209      * @return  Unmodifiable view of <CODE>attributeSet</CODE>.
 210      *
 211      * @exception  NullPointerException
 212      *     Thrown if <CODE>attributeSet</CODE> is null. Null is never a
 213      */
 214     public static AttributeSet unmodifiableView(AttributeSet attributeSet) {
 215         if (attributeSet == null) {
 216             throw new NullPointerException();
 217         }
 218 
 219         return new UnmodifiableAttributeSet(attributeSet);
 220     }
 221 
 222     /**
 223      * Creates an unmodifiable view of the given doc attribute set.
 224      *
 225      * @param  attributeSet  Underlying doc attribute set.
 226      *
 227      * @return  Unmodifiable view of <CODE>attributeSet</CODE>.
 228      *
 229      * @exception  NullPointerException
 230      *     Thrown if <CODE>attributeSet</CODE> is null.
 231      */
 232     public static DocAttributeSet unmodifiableView
 233         (DocAttributeSet attributeSet) {
 234         if (attributeSet == null) {
 235             throw new NullPointerException();
 236         }
 237         return new UnmodifiableDocAttributeSet(attributeSet);
 238     }
 239 
 240     /**
 241      * Creates an unmodifiable view of the given print request attribute set.
 242      *
 243      * @param  attributeSet  Underlying print request attribute set.
 244      *
 245      * @return  Unmodifiable view of <CODE>attributeSet</CODE>.
 246      *
 247      * @exception  NullPointerException
 248      *     Thrown if <CODE>attributeSet</CODE> is null.
 249      */
 250     public static PrintRequestAttributeSet
 251         unmodifiableView(PrintRequestAttributeSet attributeSet) {
 252         if (attributeSet == null) {
 253             throw new NullPointerException();
 254         }
 255         return new UnmodifiablePrintRequestAttributeSet(attributeSet);
 256     }
 257 
 258     /**
 259      * Creates an unmodifiable view of the given print job attribute set.
 260      *
 261      * @param  attributeSet  Underlying print job attribute set.
 262      *
 263      * @return  Unmodifiable view of <CODE>attributeSet</CODE>.
 264      *
 265      * @exception  NullPointerException
 266      *     Thrown if <CODE>attributeSet</CODE> is null.
 267      */
 268     public static PrintJobAttributeSet
 269         unmodifiableView(PrintJobAttributeSet attributeSet) {
 270         if (attributeSet == null) {
 271             throw new NullPointerException();
 272         }
 273         return new UnmodifiablePrintJobAttributeSet(attributeSet);
 274     }
 275 
 276     /**
 277      * Creates an unmodifiable view of the given print service attribute set.
 278      *
 279      * @param  attributeSet  Underlying print service attribute set.
 280      *
 281      * @return  Unmodifiable view of <CODE>attributeSet</CODE>.
 282      *
 283      * @exception  NullPointerException
 284      *     Thrown if <CODE>attributeSet</CODE> is null.
 285      */
 286     public static PrintServiceAttributeSet
 287         unmodifiableView(PrintServiceAttributeSet attributeSet) {
 288         if (attributeSet == null) {
 289             throw new NullPointerException();
 290         }
 291         return new UnmodifiablePrintServiceAttributeSet (attributeSet);
 292     }
 293 
 294     /**
 295       * @serial include
 296       */
 297     private static class SynchronizedAttributeSet
 298                         implements AttributeSet, Serializable {
 299         private static final long serialVersionUID = 8365731020128564925L;
 300 
 301         private AttributeSet attrset;
 302 
 303         public SynchronizedAttributeSet(AttributeSet attributeSet) {
 304             attrset = attributeSet;
 305         }
 306 
 307         public synchronized Attribute get(Class<?> category) {
 308             return attrset.get(category);
 309         }
 310 
 311         public synchronized boolean add(Attribute attribute) {
 312             return attrset.add(attribute);
 313         }
 314 
 315         public synchronized boolean remove(Class<?> category) {
 316             return attrset.remove(category);
 317         }
 318 
 319         public synchronized boolean remove(Attribute attribute) {
 320             return attrset.remove(attribute);
 321         }
 322 
 323         public synchronized boolean containsKey(Class<?> category) {
 324             return attrset.containsKey(category);
 325         }
 326 
 327         public synchronized boolean containsValue(Attribute attribute) {
 328             return attrset.containsValue(attribute);
 329         }
 330 
 331         public synchronized boolean addAll(AttributeSet attributes) {
 332             return attrset.addAll(attributes);
 333         }
 334 
 335         public synchronized int size() {
 336             return attrset.size();
 337         }
 338 
 339         public synchronized Attribute[] toArray() {
 340             return attrset.toArray();
 341         }
 342 
 343         public synchronized void clear() {
 344             attrset.clear();
 345         }
 346 
 347         public synchronized boolean isEmpty() {
 348             return attrset.isEmpty();
 349         }
 350 
 351         public synchronized boolean equals(Object o) {
 352             return attrset.equals (o);
 353         }
 354 
 355         public synchronized int hashCode() {
 356             return attrset.hashCode();
 357         }
 358     }
 359 
 360     /**
 361       * @serial include
 362       */
 363     private static class SynchronizedDocAttributeSet
 364         extends SynchronizedAttributeSet
 365         implements DocAttributeSet, Serializable {
 366         private static final long serialVersionUID = 6455869095246629354L;
 367 
 368         public SynchronizedDocAttributeSet(DocAttributeSet attributeSet) {
 369             super(attributeSet);
 370         }
 371     }
 372 
 373     /**
 374       * @serial include
 375       */
 376     private static class SynchronizedPrintRequestAttributeSet
 377         extends SynchronizedAttributeSet
 378         implements PrintRequestAttributeSet, Serializable {
 379         private static final long serialVersionUID = 5671237023971169027L;
 380 
 381         public SynchronizedPrintRequestAttributeSet
 382             (PrintRequestAttributeSet attributeSet) {
 383             super(attributeSet);
 384         }
 385     }
 386 
 387     /**
 388       * @serial include
 389       */
 390     private static class SynchronizedPrintJobAttributeSet
 391         extends SynchronizedAttributeSet
 392         implements PrintJobAttributeSet, Serializable {
 393         private static final long serialVersionUID = 2117188707856965749L;
 394 
 395         public SynchronizedPrintJobAttributeSet
 396             (PrintJobAttributeSet attributeSet) {
 397             super(attributeSet);
 398         }
 399     }
 400 
 401     /**
 402       * @serial include
 403       */
 404     private static class SynchronizedPrintServiceAttributeSet
 405         extends SynchronizedAttributeSet
 406         implements PrintServiceAttributeSet, Serializable {
 407         private static final long serialVersionUID = -2830705374001675073L;
 408 
 409         public SynchronizedPrintServiceAttributeSet
 410             (PrintServiceAttributeSet attributeSet) {
 411             super(attributeSet);
 412         }
 413     }
 414 
 415     /**
 416      * Creates a synchronized view of the given attribute set.
 417      *
 418      * @param  attributeSet  Underlying attribute set.
 419      *
 420      * @return  Synchronized view of <CODE>attributeSet</CODE>.
 421      *
 422      * @exception  NullPointerException
 423      *     Thrown if <CODE>attributeSet</CODE> is null.
 424      */
 425     public static AttributeSet synchronizedView
 426         (AttributeSet attributeSet) {
 427         if (attributeSet == null) {
 428             throw new NullPointerException();
 429         }
 430         return new SynchronizedAttributeSet(attributeSet);
 431     }
 432 
 433     /**
 434      * Creates a synchronized view of the given doc attribute set.
 435      *
 436      * @param  attributeSet  Underlying doc attribute set.
 437      *
 438      * @return  Synchronized view of <CODE>attributeSet</CODE>.
 439      *
 440      * @exception  NullPointerException
 441      *     Thrown if <CODE>attributeSet</CODE> is null.
 442      */
 443     public static DocAttributeSet
 444         synchronizedView(DocAttributeSet attributeSet) {
 445         if (attributeSet == null) {
 446             throw new NullPointerException();
 447         }
 448         return new SynchronizedDocAttributeSet(attributeSet);
 449     }
 450 
 451     /**
 452      * Creates a synchronized view of the given print request attribute set.
 453      *
 454      * @param  attributeSet  Underlying print request attribute set.
 455      *
 456      * @return  Synchronized view of <CODE>attributeSet</CODE>.
 457      *
 458      * @exception  NullPointerException
 459      *     Thrown if <CODE>attributeSet</CODE> is null.
 460      */
 461     public static PrintRequestAttributeSet
 462         synchronizedView(PrintRequestAttributeSet attributeSet) {
 463         if (attributeSet == null) {
 464             throw new NullPointerException();
 465         }
 466         return new SynchronizedPrintRequestAttributeSet(attributeSet);
 467     }
 468 
 469     /**
 470      * Creates a synchronized view of the given print job attribute set.
 471      *
 472      * @param  attributeSet  Underlying print job attribute set.
 473      *
 474      * @return  Synchronized view of <CODE>attributeSet</CODE>.
 475      *
 476      * @exception  NullPointerException
 477      *     Thrown if <CODE>attributeSet</CODE> is null.
 478      */
 479     public static PrintJobAttributeSet
 480         synchronizedView(PrintJobAttributeSet attributeSet) {
 481         if (attributeSet == null) {
 482             throw new NullPointerException();
 483         }
 484         return new SynchronizedPrintJobAttributeSet(attributeSet);
 485     }
 486 
 487     /**
 488      * Creates a synchronized view of the given print service attribute set.
 489      *
 490      * @param  attributeSet  Underlying print service attribute set.
 491      *
 492      * @return  Synchronized view of <CODE>attributeSet</CODE>.
 493      */
 494     public static PrintServiceAttributeSet
 495         synchronizedView(PrintServiceAttributeSet attributeSet) {
 496         if (attributeSet == null) {
 497             throw new NullPointerException();
 498         }
 499         return new SynchronizedPrintServiceAttributeSet(attributeSet);
 500     }
 501 
 502 
 503     /**
 504      * Verify that the given object is a {@link java.lang.Class Class} that
 505      * implements the given interface, which is assumed to be interface {@link
 506      * Attribute Attribute} or a subinterface thereof.
 507      *
 508      * @param  object     Object to test.
 509      * @param  interfaceName  Interface the object must implement.
 510      *
 511      * @return  If <CODE>object</CODE> is a {@link java.lang.Class Class}
 512      *          that implements <CODE>interfaceName</CODE>,
 513      *          <CODE>object</CODE> is returned downcast to type {@link
 514      *          java.lang.Class Class}; otherwise an exception is thrown.
 515      *
 516      * @exception  NullPointerException
 517      *     (unchecked exception) Thrown if <CODE>object</CODE> is null.
 518      * @exception  ClassCastException
 519      *     (unchecked exception) Thrown if <CODE>object</CODE> is not a
 520      *     {@link java.lang.Class Class} that implements
 521      *     <CODE>interfaceName</CODE>.
 522      */
 523     public static Class<?>
 524         verifyAttributeCategory(Object object, Class<?> interfaceName) {
 525 
 526         Class<?> result = (Class<?>) object;
 527         if (interfaceName.isAssignableFrom (result)) {
 528             return result;
 529         }
 530         else {
 531             throw new ClassCastException();
 532         }
 533     }
 534 
 535     /**
 536      * Verify that the given object is an instance of the given interface, which
 537      * is assumed to be interface {@link Attribute Attribute} or a subinterface
 538      * thereof.
 539      *
 540      * @param  object     Object to test.
 541      * @param  interfaceName  Interface of which the object must be an instance.
 542      *
 543      * @return  If <CODE>object</CODE> is an instance of
 544      *          <CODE>interfaceName</CODE>, <CODE>object</CODE> is returned
 545      *          downcast to type {@link Attribute Attribute}; otherwise an
 546      *          exception is thrown.
 547      *
 548      * @exception  NullPointerException
 549      *     (unchecked exception) Thrown if <CODE>object</CODE> is null.
 550      * @exception  ClassCastException
 551      *     (unchecked exception) Thrown if <CODE>object</CODE> is not an
 552      *     instance of <CODE>interfaceName</CODE>.
 553      */
 554     public static Attribute
 555         verifyAttributeValue(Object object, Class<?> interfaceName) {
 556 
 557         if (object == null) {
 558             throw new NullPointerException();
 559         }
 560         else if (interfaceName.isInstance (object)) {
 561             return (Attribute) object;
 562         } else {
 563             throw new ClassCastException();
 564         }
 565     }
 566 
 567     /**
 568      * Verify that the given attribute category object is equal to the
 569      * category of the given attribute value object. If so, this method
 570      * returns doing nothing. If not, this method throws an exception.
 571      *
 572      * @param  category   Attribute category to test.
 573      * @param  attribute  Attribute value to test.
 574      *
 575      * @exception  NullPointerException
 576      *     (unchecked exception) Thrown if the <CODE>category</CODE> is
 577      *     null or if the <CODE>attribute</CODE> is null.
 578      * @exception  IllegalArgumentException
 579      *     (unchecked exception) Thrown if the <CODE>category</CODE> is not
 580      *     equal to the category of the <CODE>attribute</CODE>.
 581      */
 582     public static void
 583         verifyCategoryForValue(Class<?> category, Attribute attribute) {
 584 
 585         if (!category.equals (attribute.getCategory())) {
 586             throw new IllegalArgumentException();
 587         }
 588     }
 589 }