< prev index next >

src/java.desktop/share/classes/javax/print/attribute/HashAttributeSet.java

Print this page


   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 package javax.print.attribute;
  27 
  28 import java.io.IOException;
  29 import java.io.ObjectInputStream;
  30 import java.io.ObjectOutputStream;
  31 import java.io.Serializable;
  32 import java.util.HashMap;
  33 
  34 /**
  35  * Class HashAttributeSet provides an {@code AttributeSet}
  36  * implementation with characteristics of a hash map.
  37  *
  38  * @author  Alan Kaminsky
  39  */
  40 public class HashAttributeSet implements AttributeSet, Serializable {
  41 



  42     private static final long serialVersionUID = 5311560590283707917L;
  43 
  44     /**
  45      * The interface of which all members of this attribute set must be an
  46      * instance. It is assumed to be interface {@link Attribute Attribute}
  47      * or a subinterface thereof.

  48      * @serial
  49      */
  50     private Class<?> myInterface;
  51 
  52     /*
  53      * A HashMap used by the implementation.
  54      * The serialised form doesn't include this instance variable.
  55      */
  56     private transient HashMap<Class<?>, Attribute> attrMap = new HashMap<>();
  57 
  58     /**
  59      * Write the instance to a stream (ie serialize the object)
  60      *
  61      * @serialData
  62      * The serialized form of an attribute set explicitly writes the

  63      * number of attributes in the set, and each of the attributes.
  64      * This does not guarantee equality of serialized forms since
  65      * the order in which the attributes are written is not defined.
  66      */
  67     private void writeObject(ObjectOutputStream s) throws IOException {
  68 
  69         s.defaultWriteObject();
  70         Attribute [] attrs = toArray();
  71         s.writeInt(attrs.length);
  72         for (int i = 0; i < attrs.length; i++) {
  73             s.writeObject(attrs[i]);
  74         }
  75     }
  76 
  77     /**
  78      * Reconstitute an instance from a stream that is, deserialize it).




  79      */
  80     private void readObject(ObjectInputStream s)
  81         throws ClassNotFoundException, IOException {
  82 
  83         s.defaultReadObject();
  84         attrMap = new HashMap<>();
  85         int count = s.readInt();
  86         Attribute attr;
  87         for (int i = 0; i < count; i++) {
  88             attr = (Attribute)s.readObject();
  89             add(attr);
  90         }
  91     }
  92 
  93     /**
  94      * Construct a new, empty attribute set.
  95      */
  96     public HashAttributeSet() {
  97         this(Attribute.class);
  98     }
  99 
 100     /**
 101      * Construct a new attribute set,
 102      * initially populated with the given attribute.
 103      *
 104      * @param  attribute  Attribute value to add to the set.
 105      *
 106      * @exception  NullPointerException
 107      *     (unchecked exception) Thrown if {@code attribute} is null.
 108      */
 109     public HashAttributeSet(Attribute attribute) {
 110         this (attribute, Attribute.class);
 111     }
 112 
 113     /**
 114      * Construct a new attribute set,
 115      * initially populated with the values from the
 116      * given array. The new attribute set is populated by
 117      * adding the elements of {@code attributes} array to the set in
 118      * sequence, starting at index 0. Thus, later array elements may replace
 119      * earlier array elements if the array contains duplicate attribute
 120      * values or attribute categories.
 121      *
 122      * @param  attributes  Array of attribute values to add to the set.
 123      *                    If null, an empty attribute set is constructed.
 124      *
 125      * @exception  NullPointerException
 126      *     (unchecked exception) Thrown if any element of
 127      *     {@code attributes} is null.
 128      */
 129     public HashAttributeSet(Attribute[] attributes) {
 130         this (attributes, Attribute.class);
 131     }
 132 
 133     /**
 134      * Construct a new attribute set,
 135      * initially populated with the values from the  given set.
 136      *
 137      * @param  attributes Set of attributes from which to initialise this set.
 138      *                 If null, an empty attribute set is constructed.
 139      *


 140      */
 141     public HashAttributeSet(AttributeSet attributes) {
 142         this (attributes, Attribute.class);
 143     }
 144 
 145     /**
 146      * Construct a new, empty attribute set, where the members of
 147      * the attribute set are restricted to the given interface.
 148      *
 149      * @param  interfaceName  The interface of which all members of this
 150      *                     attribute set must be an instance. It is assumed to
 151      *                     be interface {@link Attribute Attribute} or a
 152      *                     subinterface thereof.
 153      * @exception NullPointerException if interfaceName is null.
 154      */
 155     protected HashAttributeSet(Class<?> interfaceName) {
 156         if (interfaceName == null) {
 157             throw new NullPointerException("null interface");
 158         }
 159         myInterface = interfaceName;
 160     }
 161 
 162     /**
 163      * Construct a new attribute set, initially populated with the given
 164      * attribute, where the members of the attribute set are restricted to the
 165      * given interface.
 166      *
 167      * @param  attribute      Attribute value to add to the set.
 168      * @param  interfaceName  The interface of which all members of this
 169      *                    attribute set must be an instance. It is assumed to
 170      *                    be interface {@link Attribute Attribute} or a
 171      *                    subinterface thereof.
 172      *
 173      * @exception  NullPointerException
 174      *     (unchecked exception) Thrown if {@code attribute} is null.
 175      * @exception NullPointerException if interfaceName is null.
 176      * @exception  ClassCastException
 177      *     (unchecked exception) Thrown if {@code attribute} is not an
 178      *     instance of {@code interfaceName}.
 179      */
 180     protected HashAttributeSet(Attribute attribute, Class<?> interfaceName) {
 181         if (interfaceName == null) {
 182             throw new NullPointerException("null interface");
 183         }
 184         myInterface = interfaceName;
 185         add (attribute);
 186     }
 187 
 188     /**
 189      * Construct a new attribute set, where the members of the attribute
 190      * set are restricted to the given interface.
 191      * The new attribute set is populated
 192      * by adding the elements of {@code attributes} array to the set in
 193      * sequence, starting at index 0. Thus, later array elements may replace
 194      * earlier array elements if the array contains duplicate attribute
 195      * values or attribute categories.
 196      *
 197      * @param  attributes Array of attribute values to add to the set. If
 198      *                    null, an empty attribute set is constructed.
 199      * @param  interfaceName  The interface of which all members of this
 200      *                    attribute set must be an instance. It is assumed to
 201      *                    be interface {@link Attribute Attribute} or a
 202      *                    subinterface thereof.
 203      *
 204      * @exception  NullPointerException
 205      *     (unchecked exception) Thrown if any element of
 206      * {@code attributes} is null.
 207      * @exception NullPointerException if interfaceName is null.
 208      * @exception  ClassCastException
 209      *     (unchecked exception) Thrown if any element of
 210      * {@code attributes} is not an instance of
 211      * {@code interfaceName}.
 212      */
 213     protected HashAttributeSet(Attribute[] attributes, Class<?> interfaceName) {
 214         if (interfaceName == null) {
 215             throw new NullPointerException("null interface");
 216         }
 217         myInterface = interfaceName;
 218         int n = attributes == null ? 0 : attributes.length;
 219         for (int i = 0; i < n; ++ i) {
 220             add (attributes[i]);
 221         }
 222     }
 223 
 224     /**
 225      * Construct a new attribute set, initially populated with the
 226      * values from the  given set where the members of the attribute
 227      * set are restricted to the given interface.
 228      *
 229      * @param  attributes set of attribute values to initialise the set. If
 230      *                    null, an empty attribute set is constructed.
 231      * @param  interfaceName  The interface of which all members of this
 232      *                    attribute set must be an instance. It is assumed to
 233      *                    be interface {@link Attribute Attribute} or a
 234      *                    subinterface thereof.
 235      *
 236      * @exception  ClassCastException
 237      *     (unchecked exception) Thrown if any element of
 238      * {@code attributes} is not an instance of
 239      * {@code interfaceName}.
 240      */
 241     protected HashAttributeSet(AttributeSet attributes, Class<?> interfaceName) {
 242       myInterface = interfaceName;
 243       if (attributes != null) {
 244         Attribute[] attribArray = attributes.toArray();
 245         int n = attribArray == null ? 0 : attribArray.length;
 246         for (int i = 0; i < n; ++ i) {
 247           add (attribArray[i]);
 248         }
 249       }
 250     }
 251 
 252     /**
 253      * Returns the attribute value which this attribute set contains in the
 254      * given attribute category. Returns {@code null} if this attribute set
 255      * does not contain any attribute value in the given attribute category.
 256      *
 257      * @param  category  Attribute category whose associated attribute value
 258      *                   is to be returned. It must be a
 259      *                   {@link java.lang.Class Class}
 260      *                   that implements interface {@link Attribute
 261      *                   Attribute}.
 262      *
 263      * @return  The attribute value in the given attribute category contained
 264      *          in this attribute set, or {@code null} if this attribute set
 265      *          does not contain any attribute value in the given attribute
 266      *          category.
 267      *
 268      * @throws  NullPointerException
 269      *     (unchecked exception) Thrown if the {@code category} is null.
 270      * @throws  ClassCastException
 271      *     (unchecked exception) Thrown if the {@code category} is not a
 272      *     {@link java.lang.Class Class} that implements interface {@link
 273      *     Attribute Attribute}.
 274      */
 275     public Attribute get(Class<?> category) {
 276         return attrMap.get(AttributeSetUtilities.
 277                            verifyAttributeCategory(category,
 278                                                    Attribute.class));
 279     }
 280 
 281     /**
 282      * Adds the specified attribute to this attribute set if it is not
 283      * already present, first removing any existing in the same
 284      * attribute category as the specified attribute value.
 285      *
 286      * @param  attribute  Attribute value to be added to this attribute set.
 287      *

 288      * @return  {@code true} if this attribute set changed as a result of the
 289      *          call, i.e., the given attribute value was not already a
 290      *          member of this attribute set.
 291      *
 292      * @throws  NullPointerException
 293      *    (unchecked exception) Thrown if the {@code attribute} is null.
 294      * @throws  UnmodifiableSetException
 295      *    (unchecked exception) Thrown if this attribute set does not support
 296      *     the {@code add()} operation.
 297      */
 298     public boolean add(Attribute attribute) {
 299         Object oldAttribute =
 300             attrMap.put(attribute.getCategory(),
 301                         AttributeSetUtilities.
 302                         verifyAttributeValue(attribute, myInterface));
 303         return (!attribute.equals(oldAttribute));
 304     }
 305 
 306     /**
 307      * Removes any attribute for this category from this attribute set if
 308      * present. If {@code category} is null, then
 309      * {@code remove()} does nothing and returns {@code false}.
 310      *
 311      * @param  category Attribute category to be removed from this
 312      *                  attribute set.
 313      *

 314      * @return  {@code true} if this attribute set changed as a result of the
 315      *         call, i.e., the given attribute category had been a member of
 316      *         this attribute set.
 317      *
 318      * @throws  UnmodifiableSetException
 319      *     (unchecked exception) Thrown if this attribute set does not
 320      *     support the {@code remove()} operation.
 321      */
 322     public boolean remove(Class<?> category) {
 323         return
 324             category != null &&
 325             AttributeSetUtilities.
 326             verifyAttributeCategory(category, Attribute.class) != null &&
 327             attrMap.remove(category) != null;
 328     }
 329 
 330     /**
 331      * Removes the specified attribute from this attribute set if
 332      * present. If {@code attribute} is null, then
 333      * {@code remove()} does nothing and returns {@code false}.
 334      *
 335      * @param attribute Attribute value to be removed from this attribute set.
 336      *

 337      * @return  {@code true} if this attribute set changed as a result of the
 338      *         call, i.e., the given attribute value had been a member of
 339      *         this attribute set.
 340      *
 341      * @throws  UnmodifiableSetException
 342      *     (unchecked exception) Thrown if this attribute set does not
 343      *     support the {@code remove()} operation.
 344      */
 345     public boolean remove(Attribute attribute) {
 346         return
 347             attribute != null &&
 348             attrMap.remove(attribute.getCategory()) != null;
 349     }
 350 
 351     /**
 352      * Returns {@code true} if this attribute set contains an
 353      * attribute for the specified category.
 354      *
 355      * @param  category whose presence in this attribute set is
 356      *            to be tested.
 357      *
 358      * @return  {@code true} if this attribute set contains an attribute
 359      *         value for the specified category.

 360      */
 361     public boolean containsKey(Class<?> category) {
 362         return
 363             category != null &&
 364             AttributeSetUtilities.
 365             verifyAttributeCategory(category, Attribute.class) != null &&
 366             attrMap.get(category) != null;
 367     }
 368 
 369     /**
 370      * Returns {@code true} if this attribute set contains the given
 371      * attribute.
 372      *
 373      * @param  attribute  value whose presence in this attribute set is
 374      *            to be tested.
 375      *
 376      * @return  {@code true} if this attribute set contains the given
 377      *      attribute    value.


 378      */
 379     public boolean containsValue(Attribute attribute) {
 380         return
 381            attribute != null &&
 382            attribute instanceof Attribute &&
 383            attribute.equals(attrMap.get(attribute.getCategory()));
 384     }
 385 
 386     /**
 387      * Adds all of the elements in the specified set to this attribute.
 388      * The outcome is the same as if the
 389      * {@link #add(Attribute) add(Attribute)}
 390      * operation had been applied to this attribute set successively with
 391      * each element from the specified set.
 392      * The behavior of the {@code addAll(AttributeSet)}
 393      * operation is unspecified if the specified set is modified while
 394      * the operation is in progress.
 395      * <P>
 396      * If the {@code addAll(AttributeSet)} operation throws an exception,
 397      * the effect on this attribute set's state is implementation dependent;
 398      * elements from the specified set before the point of the exception may
 399      * or may not have been added to this attribute set.
 400      *
 401      * @param  attributes  whose elements are to be added to this attribute
 402      *            set.
 403      *

 404      * @return  {@code true} if this attribute set changed as a result of the
 405      *          call.
 406      *
 407      * @throws  UnmodifiableSetException
 408      *    (Unchecked exception) Thrown if this attribute set does not
 409      *     support the {@code addAll(AttributeSet)} method.
 410      * @throws  NullPointerException
 411      *     (Unchecked exception) Thrown if some element in the specified
 412      *     set is null, or the set is null.
 413      *
 414      * @see #add(Attribute)
 415      */
 416     public boolean addAll(AttributeSet attributes) {
 417 
 418         Attribute []attrs = attributes.toArray();
 419         boolean result = false;
 420         for (int i=0; i<attrs.length; i++) {
 421             Attribute newValue =
 422                 AttributeSetUtilities.verifyAttributeValue(attrs[i],
 423                                                            myInterface);
 424             Object oldValue = attrMap.put(newValue.getCategory(), newValue);
 425             result = (! newValue.equals(oldValue)) || result;
 426         }
 427         return result;
 428     }
 429 
 430     /**
 431      * Returns the number of attributes in this attribute set. If this
 432      * attribute set contains more than {@code Integer.MAX_VALUE} elements,
 433      * returns  {@code Integer.MAX_VALUE}.
 434      *
 435      * @return  The number of attributes in this attribute set.
 436      */
 437     public int size() {
 438         return attrMap.size();
 439     }
 440 
 441     /**

 442      *
 443      * @return the Attributes contained in this set as an array, zero length
 444      * if the AttributeSet is empty.
 445      */
 446     public Attribute[] toArray() {
 447         Attribute []attrs = new Attribute[size()];
 448         attrMap.values().toArray(attrs);
 449         return attrs;
 450     }
 451 
 452 
 453     /**
 454      * Removes all attributes from this attribute set.
 455      *
 456      * @throws  UnmodifiableSetException
 457      *   (unchecked exception) Thrown if this attribute set does not support
 458      *     the {@code clear()} operation.
 459      */
 460     public void clear() {
 461         attrMap.clear();
 462     }
 463 
 464    /**
 465      * Returns true if this attribute set contains no attributes.
 466      *
 467      * @return true if this attribute set contains no attributes.
 468      */
 469     public boolean isEmpty() {
 470         return attrMap.isEmpty();
 471     }
 472 
 473     /**
 474      * Compares the specified object with this attribute set for equality.
 475      * Returns {@code true} if the given object is also an attribute set and
 476      * the two attribute sets contain the same attribute category-attribute
 477      * value mappings. This ensures that the
 478      * {@code equals()} method works properly across different
 479      * implementations of the AttributeSet interface.
 480      *
 481      * @param  object to be compared for equality with this attribute set.
 482      *
 483      * @return  {@code true} if the specified object is equal to this
 484      *       attribute   set.
 485      */
 486 
 487     public boolean equals(Object object) {
 488         if (object == null || !(object instanceof AttributeSet)) {
 489             return false;
 490         }
 491 
 492         AttributeSet aset = (AttributeSet)object;
 493         if (aset.size() != size()) {
 494             return false;
 495         }
 496 
 497         Attribute[] attrs = toArray();
 498         for (int i=0;i<attrs.length; i++) {
 499             if (!aset.containsValue(attrs[i])) {
 500                 return false;
 501             }
 502         }
 503         return true;
 504     }
 505 
 506     /**
 507      * Returns the hash code value for this attribute set.
 508      * The hash code of an attribute set is defined to be the sum
 509      * of the hash codes of each entry in the AttributeSet.
 510      * This ensures that {@code t1.equals(t2)} implies that
 511      * {@code t1.hashCode()==t2.hashCode()} for any two attribute sets
 512      * {@code t1} and {@code t2}, as required by the general contract of
 513      * {@link java.lang.Object#hashCode() Object.hashCode()}.
 514      *
 515      * @return  The hash code value for this attribute set.
 516      */
 517     public int hashCode() {
 518         int hcode = 0;
 519         Attribute[] attrs = toArray();
 520         for (int i=0;i<attrs.length; i++) {
 521             hcode += attrs[i].hashCode();
 522         }
 523         return hcode;
 524     }
 525 
 526 }
   1 /*
   2  * Copyright (c) 2000, 2017, 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 package javax.print.attribute;
  27 
  28 import java.io.IOException;
  29 import java.io.ObjectInputStream;
  30 import java.io.ObjectOutputStream;
  31 import java.io.Serializable;
  32 import java.util.HashMap;
  33 
  34 /**
  35  * Class {@code HashAttributeSet} provides an {@code AttributeSet}
  36  * implementation with characteristics of a hash map.
  37  *
  38  * @author Alan Kaminsky
  39  */
  40 public class HashAttributeSet implements AttributeSet, Serializable {
  41 
  42     /**
  43      * Use serialVersionUID from JDK 1.4 for interoperability.
  44      */
  45     private static final long serialVersionUID = 5311560590283707917L;
  46 
  47     /**
  48      * The interface of which all members of this attribute set must be an
  49      * instance. It is assumed to be interface {@link Attribute Attribute} or a
  50      * subinterface thereof.
  51      *
  52      * @serial
  53      */
  54     private Class<?> myInterface;
  55 
  56     /**
  57      * A {@code HashMap} used by the implementation. The serialised form doesn't
  58      * include this instance variable.
  59      */
  60     private transient HashMap<Class<?>, Attribute> attrMap = new HashMap<>();
  61 
  62     /**
  63      * Write the instance to a stream (ie serialize the object).
  64      *
  65      * @param  s the output stream
  66      * @throws IOException if an I/O exception has occurred
  67      * @serialData The serialized form of an attribute set explicitly writes the
  68      *             number of attributes in the set, and each of the attributes.
  69      *             This does not guarantee equality of serialized forms since
  70      *             the order in which the attributes are written is not defined.
  71      */
  72     private void writeObject(ObjectOutputStream s) throws IOException {
  73 
  74         s.defaultWriteObject();
  75         Attribute [] attrs = toArray();
  76         s.writeInt(attrs.length);
  77         for (int i = 0; i < attrs.length; i++) {
  78             s.writeObject(attrs[i]);
  79         }
  80     }
  81 
  82     /**
  83      * Reconstitute an instance from a stream that is, deserialize it).
  84      *
  85      * @param  s the input stream
  86      * @throws ClassNotFoundException if the class is not found
  87      * @throws IOException if an I/O exception has occurred
  88      */
  89     private void readObject(ObjectInputStream s)
  90         throws ClassNotFoundException, IOException {
  91 
  92         s.defaultReadObject();
  93         attrMap = new HashMap<>();
  94         int count = s.readInt();
  95         Attribute attr;
  96         for (int i = 0; i < count; i++) {
  97             attr = (Attribute)s.readObject();
  98             add(attr);
  99         }
 100     }
 101 
 102     /**
 103      * Construct a new, empty attribute set.
 104      */
 105     public HashAttributeSet() {
 106         this(Attribute.class);
 107     }
 108 
 109     /**
 110      * Construct a new attribute set, initially populated with the given
 111      * attribute.


 112      *
 113      * @param  attribute attribute value to add to the set
 114      * @throws NullPointerException if {@code attribute} is {@code null}
 115      */
 116     public HashAttributeSet(Attribute attribute) {
 117         this (attribute, Attribute.class);
 118     }
 119 
 120     /**
 121      * Construct a new attribute set, initially populated with the values from
 122      * the given array. The new attribute set is populated by adding the
 123      * elements of {@code attributes} array to the set in sequence, starting at
 124      * index 0. Thus, later array elements may replace earlier array elements if
 125      * the array contains duplicate attribute values or attribute categories.
 126      *
 127      * @param  attributes array of attribute values to add to the set. If
 128      *         {@code null}, an empty attribute set is constructed.
 129      * @throws NullPointerException if any element of {@code attributes} is
 130      *         {@code null}




 131      */
 132     public HashAttributeSet(Attribute[] attributes) {
 133         this (attributes, Attribute.class);
 134     }
 135 
 136     /**
 137      * Construct a new attribute set, initially populated with the values from
 138      * the given set.



 139      *
 140      * @param  attributes set of attributes from which to initialise this set.
 141      *         If {@code null}, an empty attribute set is constructed.
 142      */
 143     public HashAttributeSet(AttributeSet attributes) {
 144         this (attributes, Attribute.class);
 145     }
 146 
 147     /**
 148      * Construct a new, empty attribute set, where the members of the attribute
 149      * set are restricted to the given interface.
 150      *
 151      * @param  interfaceName the interface of which all members of this
 152      *         attribute set must be an instance. It is assumed to be interface
 153      *         {@link Attribute Attribute} or a subinterface thereof.
 154      * @throws NullPointerException if {@code interfaceName} is {@code null}

 155      */
 156     protected HashAttributeSet(Class<?> interfaceName) {
 157         if (interfaceName == null) {
 158             throw new NullPointerException("null interface");
 159         }
 160         myInterface = interfaceName;
 161     }
 162 
 163     /**
 164      * Construct a new attribute set, initially populated with the given
 165      * attribute, where the members of the attribute set are restricted to the
 166      * given interface.
 167      *
 168      * @param  attribute attribute value to add to the set
 169      * @param  interfaceName the interface of which all members of this
 170      *         attribute set must be an instance. It is assumed to be interface
 171      *         {@link Attribute Attribute} or a subinterface thereof.
 172      * @throws NullPointerException if {@code attribute} or
 173      *         {@code interfaceName} are {@code null}
 174      * @throws ClassCastException if {@code attribute} is not an instance of
 175      *         {@code interfaceName}




 176      */
 177     protected HashAttributeSet(Attribute attribute, Class<?> interfaceName) {
 178         if (interfaceName == null) {
 179             throw new NullPointerException("null interface");
 180         }
 181         myInterface = interfaceName;
 182         add (attribute);
 183     }
 184 
 185     /**
 186      * Construct a new attribute set, where the members of the attribute set are
 187      * restricted to the given interface. The new attribute set is populated by
 188      * adding the elements of {@code attributes} array to the set in sequence,
 189      * starting at index 0. Thus, later array elements may replace earlier array
 190      * elements if the array contains duplicate attribute values or attribute
 191      * categories.
 192      *
 193      * @param  attributes array of attribute values to add to the set. If
 194      *         {@code null}, an empty attribute set is constructed.
 195      * @param  interfaceName the interface of which all members of this
 196      *         attribute set must be an instance. It is assumed to be interface
 197      *         {@link Attribute Attribute} or a subinterface thereof.
 198      * @throws NullPointerException if {@code interfaceName} is {@code null}, or
 199      *         if any element of {@code attributes} is {@code null}
 200      * @throws ClassCastException if any element of {@code attributes} is not an
 201      *         instance of {@code interfaceName}







 202      */
 203     protected HashAttributeSet(Attribute[] attributes, Class<?> interfaceName) {
 204         if (interfaceName == null) {
 205             throw new NullPointerException("null interface");
 206         }
 207         myInterface = interfaceName;
 208         int n = attributes == null ? 0 : attributes.length;
 209         for (int i = 0; i < n; ++ i) {
 210             add (attributes[i]);
 211         }
 212     }
 213 
 214     /**
 215      * Construct a new attribute set, initially populated with the values from
 216      * the given set where the members of the attribute set are restricted to
 217      * the given interface.
 218      *
 219      * @param  attributes set of attribute values to initialise the set. If
 220      *         {@code null}, an empty attribute set is constructed.
 221      * @param  interfaceName The interface of which all members of this
 222      *         attribute set must be an instance. It is assumed to be interface
 223      *         {@link Attribute Attribute} or a subinterface thereof.
 224      * @throws ClassCastException if any element of {@code attributes} is not an
 225      *         instance of {@code interfaceName}




 226      */
 227     protected HashAttributeSet(AttributeSet attributes, Class<?> interfaceName) {
 228       myInterface = interfaceName;
 229       if (attributes != null) {
 230         Attribute[] attribArray = attributes.toArray();
 231         int n = attribArray == null ? 0 : attribArray.length;
 232         for (int i = 0; i < n; ++ i) {
 233           add (attribArray[i]);
 234         }
 235       }
 236     }
 237 
 238     /**
 239      * Returns the attribute value which this attribute set contains in the
 240      * given attribute category. Returns {@code null} if this attribute set does
 241      * not contain any attribute value in the given attribute category.
 242      *
 243      * @param  category attribute category whose associated attribute value is
 244      *         to be returned. It must be a {@link Class Class} that implements
 245      *         interface {@link Attribute Attribute}.
 246      * @return the attribute value in the given attribute category contained in
 247      *         this attribute set, or {@code null} if this attribute set does
 248      *         not contain any attribute value in the given attribute category
 249      * @throws NullPointerException if the {@code category} is {@code null}
 250      * @throws ClassCastException if the {@code category} is not a
 251      *         {@link Class Class} that implements interface
 252      *         {@link Attribute Attribute}







 253      */
 254     public Attribute get(Class<?> category) {
 255         return attrMap.get(AttributeSetUtilities.
 256                            verifyAttributeCategory(category,
 257                                                    Attribute.class));
 258     }
 259 
 260     /**
 261      * Adds the specified attribute to this attribute set if it is not already
 262      * present, first removing any existing in the same attribute category as
 263      * the specified attribute value.


 264      *
 265      * @param  attribute attribute value to be added to this attribute set
 266      * @return {@code true} if this attribute set changed as a result of the
 267      *         call, i.e., the given attribute value was not already a member of
 268      *         this attribute set
 269      * @throws NullPointerException if the {@code attribute} is {@code null}
 270      * @throws UnmodifiableSetException if this attribute set does not support
 271      *         the {@code add()} operation



 272      */
 273     public boolean add(Attribute attribute) {
 274         Object oldAttribute =
 275             attrMap.put(attribute.getCategory(),
 276                         AttributeSetUtilities.
 277                         verifyAttributeValue(attribute, myInterface));
 278         return (!attribute.equals(oldAttribute));
 279     }
 280 
 281     /**
 282      * Removes any attribute for this category from this attribute set if
 283      * present. If {@code category} is {@code null}, then {@code remove()} does
 284      * nothing and returns {@code false}.



 285      *
 286      * @param  category attribute category to be removed from this attribute set
 287      * @return {@code true} if this attribute set changed as a result of the
 288      *         call, i.e., the given attribute category had been a member of
 289      *         this attribute set
 290      * @throws UnmodifiableSetException if this attribute set does not support
 291      *         the {@code remove()} operation


 292      */
 293     public boolean remove(Class<?> category) {
 294         return
 295             category != null &&
 296             AttributeSetUtilities.
 297             verifyAttributeCategory(category, Attribute.class) != null &&
 298             attrMap.remove(category) != null;
 299     }
 300 
 301     /**
 302      * Removes the specified attribute from this attribute set if present. If
 303      * {@code attribute} is {@code null}, then {@code remove()} does nothing and
 304      * returns {@code false}.


 305      *
 306      * @param  attribute attribute value to be removed from this attribute set
 307      * @return {@code true} if this attribute set changed as a result of the
 308      *         call, i.e., the given attribute value had been a member of this
 309      *         attribute set
 310      * @throws UnmodifiableSetException if this attribute set does not support
 311      *         the {@code remove()} operation


 312      */
 313     public boolean remove(Attribute attribute) {
 314         return
 315             attribute != null &&
 316             attrMap.remove(attribute.getCategory()) != null;
 317     }
 318 
 319     /**
 320      * Returns {@code true} if this attribute set contains an attribute for the
 321      * specified category.



 322      *
 323      * @param  category whose presence in this attribute set is to be tested
 324      * @return {@code true} if this attribute set contains an attribute value
 325      *         for the specified category
 326      */
 327     public boolean containsKey(Class<?> category) {
 328         return
 329             category != null &&
 330             AttributeSetUtilities.
 331             verifyAttributeCategory(category, Attribute.class) != null &&
 332             attrMap.get(category) != null;
 333     }
 334 
 335     /**
 336      * Returns {@code true} if this attribute set contains the given attribute.




 337      *
 338      * @param  attribute value whose presence in this attribute set is to be
 339      *         tested
 340      * @return {@code true} if this attribute set contains the given attribute
 341      *         value
 342      */
 343     public boolean containsValue(Attribute attribute) {
 344         return
 345            attribute != null &&
 346            attribute instanceof Attribute &&
 347            attribute.equals(attrMap.get(attribute.getCategory()));
 348     }
 349 
 350     /**
 351      * Adds all of the elements in the specified set to this attribute. The
 352      * outcome is the same as if the {@link #add(Attribute) add(Attribute)}
 353      * operation had been applied to this attribute set successively with each
 354      * element from the specified set. The behavior of the
 355      * {@code addAll(AttributeSet)} operation is unspecified if the specified
 356      * set is modified while the operation is in progress.
 357      * <p>
 358      * If the {@code addAll(AttributeSet)} operation throws an exception, the
 359      * effect on this attribute set's state is implementation dependent;
 360      * elements from the specified set before the point of the exception may or
 361      * may not have been added to this attribute set.





 362      *
 363      * @param  attributes whose elements are to be added to this attribute set
 364      * @return {@code true} if this attribute set changed as a result of the
 365      *         call
 366      * @throws UnmodifiableSetException if this attribute set does not support
 367      *         the {@code addAll(AttributeSet)} method
 368      * @throws NullPointerException if some element in the specified set is
 369      *         {@code null}, or the set is {@code null}




 370      * @see #add(Attribute)
 371      */
 372     public boolean addAll(AttributeSet attributes) {
 373 
 374         Attribute []attrs = attributes.toArray();
 375         boolean result = false;
 376         for (int i=0; i<attrs.length; i++) {
 377             Attribute newValue =
 378                 AttributeSetUtilities.verifyAttributeValue(attrs[i],
 379                                                            myInterface);
 380             Object oldValue = attrMap.put(newValue.getCategory(), newValue);
 381             result = (! newValue.equals(oldValue)) || result;
 382         }
 383         return result;
 384     }
 385 
 386     /**
 387      * Returns the number of attributes in this attribute set. If this attribute
 388      * set contains more than {@code Integer.MAX_VALUE} elements, returns
 389      * {@code Integer.MAX_VALUE}.
 390      *
 391      * @return the number of attributes in this attribute set
 392      */
 393     public int size() {
 394         return attrMap.size();
 395     }
 396 
 397     /**
 398      * Returns an array of the attributes contained in this set.
 399      *
 400      * @return the attributes contained in this set as an array, zero length if
 401      *         the {@code AttributeSet} is empty
 402      */
 403     public Attribute[] toArray() {
 404         Attribute []attrs = new Attribute[size()];
 405         attrMap.values().toArray(attrs);
 406         return attrs;
 407     }
 408 

 409     /**
 410      * Removes all attributes from this attribute set.
 411      *
 412      * @throws UnmodifiableSetException if this attribute set does not support
 413      *         the {@code clear()} operation

 414      */
 415     public void clear() {
 416         attrMap.clear();
 417     }
 418 
 419     /**
 420      * Returns {@code true} if this attribute set contains no attributes.
 421      *
 422      * @return {@code true} if this attribute set contains no attributes
 423      */
 424     public boolean isEmpty() {
 425         return attrMap.isEmpty();
 426     }
 427 
 428     /**
 429      * Compares the specified object with this attribute set for equality.
 430      * Returns {@code true} if the given object is also an attribute set and the
 431      * two attribute sets contain the same attribute category-attribute value
 432      * mappings. This ensures that the {@code equals()} method works properly
 433      * across different implementations of the {@code AttributeSet} interface.
 434      *
 435      * @param  object to be compared for equality with this attribute set
 436      * @return {@code true} if the specified object is equal to this attribute
 437      *         set


 438      */

 439     public boolean equals(Object object) {
 440         if (object == null || !(object instanceof AttributeSet)) {
 441             return false;
 442         }
 443 
 444         AttributeSet aset = (AttributeSet)object;
 445         if (aset.size() != size()) {
 446             return false;
 447         }
 448 
 449         Attribute[] attrs = toArray();
 450         for (int i=0;i<attrs.length; i++) {
 451             if (!aset.containsValue(attrs[i])) {
 452                 return false;
 453             }
 454         }
 455         return true;
 456     }
 457 
 458     /**
 459      * Returns the hash code value for this attribute set. The hash code of an
 460      * attribute set is defined to be the sum of the hash codes of each entry in
 461      * the {@code AttributeSet}. This ensures that {@code t1.equals(t2)} implies
 462      * that {@code t1.hashCode()==t2.hashCode()} for any two attribute sets

 463      * {@code t1} and {@code t2}, as required by the general contract of
 464      * {@link Object#hashCode() Object.hashCode()}.
 465      *
 466      * @return the hash code value for this attribute set
 467      */
 468     public int hashCode() {
 469         int hcode = 0;
 470         Attribute[] attrs = toArray();
 471         for (int i=0;i<attrs.length; i++) {
 472             hcode += attrs[i].hashCode();
 473         }
 474         return hcode;
 475     }

 476 }
< prev index next >