Frames | No Frames |
1: /* HashAttributeSet.java -- 2: Copyright (C) 2003, 2004, 2005, 2006 Free Software Foundation, Inc. 3: 4: This file is part of GNU Classpath. 5: 6: GNU Classpath is free software; you can redistribute it and/or modify 7: it under the terms of the GNU General Public License as published by 8: the Free Software Foundation; either version 2, or (at your option) 9: any later version. 10: 11: GNU Classpath is distributed in the hope that it will be useful, but 12: WITHOUT ANY WARRANTY; without even the implied warranty of 13: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14: General Public License for more details. 15: 16: You should have received a copy of the GNU General Public License 17: along with GNU Classpath; see the file COPYING. If not, write to the 18: Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 19: 02110-1301 USA. 20: 21: Linking this library statically or dynamically with other modules is 22: making a combined work based on this library. Thus, the terms and 23: conditions of the GNU General Public License cover the whole 24: combination. 25: 26: As a special exception, the copyright holders of this library give you 27: permission to link this library with independent modules to produce an 28: executable, regardless of the license terms of these independent 29: modules, and to copy and distribute the resulting executable under 30: terms of your choice, provided that you also meet, for each linked 31: independent module, the terms and conditions of the license of that 32: module. An independent module is a module which is not derived from 33: or based on this library. If you modify this library, you may extend 34: this exception to your version of the library, but you are not 35: obligated to do so. If you do not wish to do so, delete this 36: exception statement from your version. */ 37: 38: package javax.print.attribute; 39: 40: import java.io.IOException; 41: import java.io.ObjectInputStream; 42: import java.io.ObjectOutputStream; 43: import java.io.Serializable; 44: import java.util.HashMap; 45: import java.util.Iterator; 46: 47: /** 48: * <code>HashAttributeSet</code> provides an implementation of 49: * {@link javax.print.attribute.AttributeSet}. 50: */ 51: public class HashAttributeSet implements AttributeSet, Serializable 52: { 53: private static final long serialVersionUID = 5311560590283707917L; 54: 55: private Class myInterface; 56: private transient HashMap attributeMap = new HashMap(); 57: 58: /** 59: * Creates an empty <code>HashAttributeSet</code> object. 60: */ 61: public HashAttributeSet() 62: { 63: this(Attribute.class); 64: } 65: 66: /** 67: * Creates a <code>HashAttributeSet</code> object with the given 68: * attribute in it. 69: * 70: * @param attribute the attribute to put into the set 71: * 72: * @exception NullPointerException if attribute is null 73: */ 74: public HashAttributeSet(Attribute attribute) 75: { 76: this(attribute, Attribute.class); 77: } 78: 79: /** 80: * Creates a <code>HashAttributeSet</code> object with the given 81: * attributes in it. 82: * 83: * @param attributes the array of attributes to put into the set. If 84: * <code>null</code> an empty set is created. 85: * 86: * @exception NullPointerException if one of the attributes of the given 87: * array is null. 88: */ 89: public HashAttributeSet(Attribute[] attributes) 90: { 91: this(attributes, Attribute.class); 92: } 93: 94: /** 95: * Creates a <code>HashAttributeSet</code> object with attributes 96: * of the given attributes set in it. 97: * 98: * @param attributes the attributes set to put into the set. If 99: * <code>null</code> an empty set is created. 100: */ 101: public HashAttributeSet(AttributeSet attributes) 102: { 103: this(attributes, Attribute.class); 104: } 105: 106: /** 107: * Creates an empty <code>HashAttributeSet</code> object. 108: * 109: * @param interfaceName the interface that all members must implement 110: * 111: * @exception NullPointerException if interfaceName is null 112: */ 113: protected HashAttributeSet(Class<?> interfaceName) 114: { 115: if (interfaceName == null) 116: throw new NullPointerException("interfaceName may not be null"); 117: 118: myInterface = interfaceName; 119: } 120: 121: /** 122: * Creates a <code>HashAttributeSet</code> object with the given 123: * attribute in it. 124: * 125: * @param attribute the attribute to put into the set. 126: * @param interfaceName the interface that all members must implement. 127: * 128: * @exception ClassCastException if attribute is not an interface of 129: * interfaceName 130: * @exception NullPointerException if attribute or interfaceName is null 131: */ 132: protected HashAttributeSet(Attribute attribute, Class<?> interfaceName) 133: { 134: this(interfaceName); 135: 136: if (attribute == null) 137: throw new NullPointerException(); 138: 139: addInternal(attribute, interfaceName); 140: } 141: 142: /** 143: * Creates a <code>HashAttributeSet</code> object with the given 144: * attributes in it. 145: * 146: * @param attributes the array of attributes to put into the set. If 147: * <code>null</code> an empty set is created. 148: * @param interfaceName the interface that all members must implement. 149: * 150: * @exception ClassCastException if any element of attributes is not an 151: * interface of interfaceName 152: * @exception NullPointerException if attributes or interfaceName is null 153: */ 154: protected HashAttributeSet(Attribute[] attributes, Class<?> interfaceName) 155: { 156: this(interfaceName); 157: 158: if (attributes != null) 159: { 160: for (int index = 0; index < attributes.length; index++) 161: addInternal(attributes[index], interfaceName); 162: } 163: } 164: 165: /** 166: * Creates a <code>HashAttributeSet</code> object with attributes 167: * of the given attributes set in it. 168: * 169: * @param attributes the attributes set to put into the set. If 170: * <code>null</code> an empty set is created. 171: * @param interfaceName the interface that all members must implement. 172: * 173: * @exception ClassCastException if any element of attributes is not an 174: * interface of interfaceName 175: */ 176: protected HashAttributeSet(AttributeSet attributes, Class<?> interfaceName) 177: { 178: this(interfaceName); 179: 180: if (attributes != null) 181: addAllInternal(attributes, interfaceName); 182: } 183: 184: /** 185: * Adds the specified attribute value to this attribute set 186: * if it is not already present. 187: * 188: * This operation removes any existing attribute of the same category 189: * before adding the given attribute to the set. 190: * 191: * @param attribute the attribute to add. 192: * @return <code>true</code> if the set is changed, false otherwise. 193: * @throws NullPointerException if the attribute is <code>null</code>. 194: * @throws UnmodifiableSetException if the set does not support modification. 195: */ 196: public boolean add(Attribute attribute) 197: { 198: return addInternal(attribute, myInterface); 199: } 200: 201: private boolean addInternal(Attribute attribute, Class interfaceName) 202: { 203: if (attribute == null) 204: throw new NullPointerException("attribute may not be null"); 205: 206: AttributeSetUtilities.verifyAttributeCategory(interfaceName, 207: myInterface); 208: 209: Object old = attributeMap.put 210: (attribute.getCategory(), AttributeSetUtilities.verifyAttributeValue 211: (attribute, interfaceName)); 212: return !attribute.equals(old); 213: } 214: 215: /** 216: * Adds all of the elements in the specified set to this attribute set. 217: * 218: * @param attributes the set of attributes to add. 219: * @return <code>true</code> if the set is changed, false otherwise. 220: * @throws UnmodifiableSetException if the set does not support modification. 221: * 222: * @see #add(Attribute) 223: */ 224: public boolean addAll(AttributeSet attributes) 225: { 226: return addAllInternal(attributes, myInterface); 227: } 228: 229: private boolean addAllInternal(AttributeSet attributes, Class interfaceName) 230: { 231: boolean modified = false; 232: Attribute[] array = attributes.toArray(); 233: 234: for (int index = 0; index < array.length; index++) 235: if (addInternal(array[index], interfaceName)) 236: modified = true; 237: 238: return modified; 239: } 240: 241: /** 242: * Removes all attributes from this attribute set. 243: * 244: * @throws UnmodifiableSetException if the set does not support modification. 245: */ 246: public void clear() 247: { 248: attributeMap.clear(); 249: } 250: 251: /** 252: * Checks if this attributes set contains an attribute with the given 253: * category. 254: * 255: * @param category the category to test for. 256: * @return <code>true</code> if an attribute of the category is contained 257: * in the set, <code>false</code> otherwise. 258: */ 259: public boolean containsKey(Class<?> category) 260: { 261: return attributeMap.containsKey(category); 262: } 263: 264: /** 265: * Checks if this attribute set contains the given attribute. 266: * 267: * @param attribute the attribute to test for. 268: * @return <code>true</code> if the attribute is contained in the set, 269: * <code>false</code> otherwise. 270: */ 271: public boolean containsValue(Attribute attribute) 272: { 273: return attributeMap.containsValue(attribute); 274: } 275: 276: /** 277: * Tests this set for equality with the given object. <code>true</code> is 278: * returned, if the given object is also of type <code>AttributeSet</code> 279: * and the contained attributes are the same as in this set. 280: * 281: * @param obj the Object to test. 282: * @return <code>true</code> if equal, false otherwise. 283: */ 284: public boolean equals(Object obj) 285: { 286: if (! (obj instanceof HashAttributeSet)) 287: return false; 288: 289: return attributeMap.equals(((HashAttributeSet) obj).attributeMap); 290: } 291: 292: /** 293: * Returns the attribute object contained in this set for the given attribute 294: * category. 295: * 296: * @param category the category of the attribute. A <code>Class</code> 297: * instance of a class implementing the <code>Attribute</code> interface. 298: * @return The attribute for this category or <code>null</code> if no 299: * attribute is contained for the given category. 300: * @throws NullPointerException if category is null. 301: * @throws ClassCastException if category is not implementing 302: * <code>Attribute</code>. 303: */ 304: public Attribute get(Class<?> category) 305: { 306: if (category == null) 307: throw new NullPointerException("category may not be null"); 308: 309: return (Attribute) attributeMap.get(category); 310: } 311: 312: /** 313: * Returns the hashcode value. The hashcode value is the sum of all hashcodes 314: * of the attributes contained in this set. 315: * 316: * @return The hashcode for this attribute set. 317: */ 318: public int hashCode() 319: { 320: int hashcode = 0; 321: Iterator it = attributeMap.values().iterator(); 322: while (it.hasNext()) 323: hashcode = hashcode + it.next().hashCode(); 324: 325: return hashcode; 326: } 327: 328: /** 329: * Checks if the attribute set is empty. 330: * 331: * @return <code>true</code> if the attribute set is empty, false otherwise. 332: */ 333: public boolean isEmpty() 334: { 335: return attributeMap.isEmpty(); 336: } 337: 338: /** 339: * Removes the given attribute from the set. If the given attribute is <code>null</code> 340: * nothing is done and <code>false</code> is returned. 341: * 342: * @param attribute the attribute to remove. 343: * @return <code>true</code> if removed, false in all other cases. 344: * @throws UnmodifiableSetException if the set does not support modification. 345: */ 346: public boolean remove(Attribute attribute) 347: { 348: if (attribute == null) 349: return false; 350: 351: return attributeMap.remove(attribute.getCategory()) != null; 352: } 353: 354: /** 355: * Removes the attribute entry of the given category from the set. If the given 356: * category is <code>null</code> nothing is done and <code>false</code> is returned. 357: * 358: * @param category the category of the entry to be removed. 359: * @return <code>true</code> if an attribute is removed, false in all other cases. 360: * @throws UnmodifiableSetException if the set does not support modification. 361: */ 362: public boolean remove(Class<?> category) 363: { 364: if (category == null) 365: return false; 366: 367: return attributeMap.remove(category) != null; 368: } 369: 370: /** 371: * Returns the number of elements in this attribute set. 372: * 373: * @return The number of elements. 374: */ 375: public int size() 376: { 377: return attributeMap.size(); 378: } 379: 380: /** 381: * Returns the content of the attribute set as an array 382: * 383: * @return An array of attributes. 384: */ 385: public Attribute[] toArray() 386: { 387: int index = 0; 388: Iterator it = attributeMap.values().iterator(); 389: Attribute[] array = new Attribute[size()]; 390: 391: while (it.hasNext()) 392: { 393: array[index] = (Attribute) it.next(); 394: index++; 395: } 396: 397: return array; 398: } 399: 400: // Implemented as specified in serialized form 401: private void readObject(ObjectInputStream s) 402: throws ClassNotFoundException, IOException 403: { 404: myInterface = (Class) s.readObject(); 405: int size = s.readInt(); 406: attributeMap = new HashMap(size); 407: for (int i=0; i < size; i++) 408: add((Attribute) s.readObject()); 409: } 410: 411: private void writeObject(ObjectOutputStream s) throws IOException 412: { 413: s.writeObject(myInterface); 414: s.writeInt(size()); 415: Iterator it = attributeMap.values().iterator(); 416: while (it.hasNext()) 417: s.writeObject(it.next()); 418: } 419: }