Source for javax.print.attribute.HashAttributeSet

   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: }