/* HashAttributeSet.java -- 
   Copyright (C) 2003, 2004, 2005, 2006  Free Software Foundation, Inc.

This file is part of GNU Classpath.

GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.

GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
General Public License for more details.

You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING.  If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.

Linking this library statically or dynamically with other modules is
making a combined work based on this library.  Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.

As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module.  An independent module is a module which is not derived from
or based on this library.  If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so.  If you do not wish to do so, delete this
exception statement from your version. */

package javax.print.attribute;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.HashMap;
import java.util.Iterator;

/**
 * <code>HashAttributeSet</code> provides an implementation of
 * {@link javax.print.attribute.AttributeSet}.
 */
public class HashAttributeSet implements AttributeSet, Serializable
{
  private static final long serialVersionUID = 5311560590283707917L;
  
  private Class myInterface;
  private transient HashMap attributeMap = new HashMap();

  /**
   * Creates an empty <code>HashAttributeSet</code> object.
   */
  public HashAttributeSet()
  {
    this(Attribute.class);
  }

  /**
   * Creates a <code>HashAttributeSet</code> object with the given
   * attribute in it.
   *
   * @param attribute the attribute to put into the set
   *
   * @exception NullPointerException if attribute is null
   */
  public HashAttributeSet(Attribute attribute)
  {
    this(attribute, Attribute.class);
  }

  /**
   * Creates a <code>HashAttributeSet</code> object with the given
   * attributes in it.
   *
   * @param attributes the array of attributes to put into the set. If
   * <code>null</code> an empty set is created.
   *
   * @exception NullPointerException if one of the attributes of the given
   * array is null.
   */
  public HashAttributeSet(Attribute[] attributes)
  {
    this(attributes, Attribute.class);
  }

  /**
   * Creates a <code>HashAttributeSet</code> object with attributes
   * of the given attributes set in it.
   *
   * @param attributes the attributes set to put into the set. If 
   * <code>null</code> an empty set is created.
   */
  public HashAttributeSet(AttributeSet attributes)
  {
    this(attributes, Attribute.class);
  }

  /**
   * Creates an empty <code>HashAttributeSet</code> object.
   *
   * @param interfaceName the interface that all members must implement
   *
   * @exception NullPointerException if interfaceName is null
   */
  protected HashAttributeSet(Class interfaceName)
  {
    if (interfaceName == null)
      throw new NullPointerException("interfaceName may not be null");
    
    myInterface = interfaceName;
  }
  
  /**
   * Creates a <code>HashAttributeSet</code> object with the given
   * attribute in it.
   * 
   * @param attribute the attribute to put into the set.
   * @param interfaceName the interface that all members must implement.
   *
   * @exception ClassCastException if attribute is not an interface of
   * interfaceName
   * @exception NullPointerException if attribute or interfaceName is null
   */
  protected HashAttributeSet(Attribute attribute, Class interfaceName)
  {
    this(interfaceName);
    
    if (attribute == null)
      throw new NullPointerException();
    
    addInternal(attribute, interfaceName);
  }

  /**
   * Creates a <code>HashAttributeSet</code> object with the given
   * attributes in it.
   *
   * @param attributes the array of attributes to put into the set. If
   * <code>null</code> an empty set is created.
   * @param interfaceName the interface that all members must implement.
   *
   * @exception ClassCastException if any element of attributes is not an
   * interface of interfaceName
   * @exception NullPointerException if attributes or interfaceName is null
   */
  protected HashAttributeSet(Attribute[] attributes, Class interfaceName)
  {
    this(interfaceName);
    
    if (attributes != null)
      {
        for (int index = 0; index < attributes.length; index++)
          addInternal(attributes[index], interfaceName);
      }
  }

  /**
   * Creates a <code>HashAttributeSet</code> object with attributes
   * of the given attributes set in it.
   *
   * @param attributes the attributes set to put into the set. If 
   * <code>null</code> an empty set is created.
   * @param interfaceName the interface that all members must implement.
   *
   * @exception ClassCastException if any element of attributes is not an
   * interface of interfaceName
   */
  protected HashAttributeSet(AttributeSet attributes, Class interfaceName)
  {
    this(interfaceName);
    
    if (attributes != null)
      addAllInternal(attributes, interfaceName);
  }

  /**
   * Adds the specified attribute value to this attribute set 
   * if it is not already present.
   * 
   * This operation removes any existing attribute of the same category 
   * before adding the given attribute to the set. 
   * 
   * @param attribute the attribute to add.
   * @return <code>true</code> if the set is changed, false otherwise.
   * @throws NullPointerException if the attribute is <code>null</code>.
   * @throws UnmodifiableSetException if the set does not support modification.
   */
  public boolean add(Attribute attribute)
  {
    return addInternal(attribute, myInterface);
  }

  private boolean addInternal(Attribute attribute, Class interfaceName)
  {
    if (attribute == null)
      throw new NullPointerException("attribute may not be null");

    AttributeSetUtilities.verifyAttributeCategory(interfaceName,
                                                  myInterface);

    Object old = attributeMap.put
      (attribute.getCategory(), AttributeSetUtilities.verifyAttributeValue
                                  (attribute, interfaceName));
    return !attribute.equals(old);
  }

  /**
   * Adds all of the elements in the specified set to this attribute set.
   * 
   * @param attributes the set of attributes to add.
   * @return <code>true</code> if the set is changed, false otherwise.
   * @throws UnmodifiableSetException if the set does not support modification.
   * 
   * @see #add(Attribute)
   */
  public boolean addAll(AttributeSet attributes)
  {
    return addAllInternal(attributes, myInterface);
  }

  private boolean addAllInternal(AttributeSet attributes, Class interfaceName)
  {
    boolean modified = false;
    Attribute[] array = attributes.toArray();

    for (int index = 0; index < array.length; index++)
      if (addInternal(array[index], interfaceName))
        modified = true;

    return modified;
  }

  /**
   * Removes all attributes from this attribute set.
   * 
   * @throws UnmodifiableSetException if the set does not support modification.
   */
  public void clear()
  {
    attributeMap.clear();
  }

  /**
   * Checks if this attributes set contains an attribute with the given 
   * category.
   * 
   * @param category the category to test for.
   * @return <code>true</code> if an attribute of the category is contained
   * in the set, <code>false</code> otherwise.
   */
  public boolean containsKey(Class category)
  {
    return attributeMap.containsKey(category);
  }

  /**
   * Checks if this attribute set contains the given attribute.
   * 
   * @param attribute the attribute to test for.
   * @return <code>true</code> if the attribute is contained in the set,
   * <code>false</code> otherwise.
   */
  public boolean containsValue(Attribute attribute)
  {
    return attributeMap.containsValue(attribute);
  }

  /**
   * Tests this set for equality with the given object. <code>true</code> is
   * returned, if the given object is also of type <code>AttributeSet</code>
   * and the contained attributes are the same as in this set.
   * 
   * @param obj the Object to test.
   * @return <code>true</code> if equal, false otherwise.
   */
  public boolean equals(Object obj)
  {
    if (! (obj instanceof HashAttributeSet))
      return false;

    return attributeMap.equals(((HashAttributeSet) obj).attributeMap);
  }

  /**
   * Returns the attribute object contained in this set for the given attribute
   * category. 
   * 
   * @param category the category of the attribute. A <code>Class</code> 
   * instance of a class implementing the <code>Attribute</code> interface. 
   * @return The attribute for this category or <code>null</code> if no 
   * attribute is contained for the given category. 
   * @throws NullPointerException if category is null.
   * @throws ClassCastException if category is not implementing 
   * <code>Attribute</code>.
   */
  public Attribute get(Class category)
  {
    if (category == null)
      throw new NullPointerException("category may not be null");
    
    return (Attribute) attributeMap.get(category);
  }
  
  /**
   * Returns the hashcode value. The hashcode value is the sum of all hashcodes
   * of the attributes contained in this set.
   * 
   * @return The hashcode for this attribute set.
   */
  public int hashCode()
  {
    int hashcode = 0;
    Iterator it = attributeMap.values().iterator();
    while (it.hasNext())
      hashcode = hashcode + it.next().hashCode();
          
    return hashcode;
  }

  /**
   * Checks if the attribute set is empty.
   *
   * @return <code>true</code> if the attribute set is empty, false otherwise.
   */
  public boolean isEmpty()
  {
    return attributeMap.isEmpty();
  }

  /**
   * Removes the given attribute from the set. If the given attribute is <code>null</code>
   * nothing is done and <code>false</code> is returned.
   * 
   * @param attribute the attribute to remove.  
   * @return <code>true</code> if removed, false in all other cases. 
   * @throws UnmodifiableSetException if the set does not support modification.
   */
  public boolean remove(Attribute attribute)
  {
    if (attribute == null)
      return false;

    return attributeMap.remove(attribute.getCategory()) != null;
  }

  /**
   * Removes the attribute entry of the given category from the set. If the given
   * category is <code>null</code> nothing is done and <code>false</code> is returned.
   * 
   * @param category the category of the entry to be removed.
   * @return <code>true</code> if an attribute is removed, false in all other cases. 
   * @throws UnmodifiableSetException if the set does not support modification.
   */
  public boolean remove(Class category)
  {
    if (category == null)
      return false;

    return attributeMap.remove(category) != null;
  }

  /**
   * Returns the number of elements in this attribute set.
   *
   * @return The number of elements.
   */
  public int size()
  {
    return attributeMap.size();
  }

  /**
   * Returns the content of the attribute set as an array
   *
   * @return An array of attributes.
   */
  public Attribute[] toArray()
  {
    int index = 0;
    Iterator it = attributeMap.values().iterator();
    Attribute[] array = new Attribute[size()];

    while (it.hasNext())
      {
        array[index] = (Attribute) it.next();
        index++;
      }
    
    return array;
  }
  
  // Implemented as specified in serialized form
  private void readObject(ObjectInputStream s)
    throws ClassNotFoundException, IOException
  {
    myInterface = (Class) s.readObject();
    int size = s.readInt();
    attributeMap = new HashMap(size);
    for (int i=0; i < size; i++)
      add((Attribute) s.readObject());
  }
         
  private void writeObject(ObjectOutputStream s) throws IOException
  {
    s.writeObject(myInterface);
    s.writeInt(size());
    Iterator it = attributeMap.values().iterator();
    while (it.hasNext())
      s.writeObject(it.next());    
  }
}
