Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/share/classes/javax/print/attribute/HashAttributeSet.java
38918 views
/*1* Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425package javax.print.attribute;2627import java.io.IOException;28import java.io.ObjectInputStream;29import java.io.ObjectOutputStream;30import java.io.Serializable;31import java.util.HashMap;3233/**34* Class HashAttributeSet provides an <code>AttributeSet</code>35* implementation with characteristics of a hash map.36* <P>37*38* @author Alan Kaminsky39*/40public class HashAttributeSet implements AttributeSet, Serializable {4142private static final long serialVersionUID = 5311560590283707917L;4344/**45* The interface of which all members of this attribute set must be an46* instance. It is assumed to be interface {@link Attribute Attribute}47* or a subinterface thereof.48* @serial49*/50private Class myInterface;5152/*53* A HashMap used by the implementation.54* The serialised form doesn't include this instance variable.55*/56private transient HashMap attrMap = new HashMap();5758/**59* Write the instance to a stream (ie serialize the object)60*61* @serialData62* The serialized form of an attribute set explicitly writes the63* number of attributes in the set, and each of the attributes.64* This does not guarantee equality of serialized forms since65* the order in which the attributes are written is not defined.66*/67private void writeObject(ObjectOutputStream s) throws IOException {6869s.defaultWriteObject();70Attribute [] attrs = toArray();71s.writeInt(attrs.length);72for (int i = 0; i < attrs.length; i++) {73s.writeObject(attrs[i]);74}75}7677/**78* Reconstitute an instance from a stream that is, deserialize it).79*/80private void readObject(ObjectInputStream s)81throws ClassNotFoundException, IOException {8283s.defaultReadObject();84attrMap = new HashMap();85int count = s.readInt();86Attribute attr;87for (int i = 0; i < count; i++) {88attr = (Attribute)s.readObject();89add(attr);90}91}9293/**94* Construct a new, empty attribute set.95*/96public HashAttributeSet() {97this(Attribute.class);98}99100/**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 NullPointerException107* (unchecked exception) Thrown if <CODE>attribute</CODE> is null.108*/109public HashAttributeSet(Attribute attribute) {110this (attribute, Attribute.class);111}112113/**114* Construct a new attribute set,115* initially populated with the values from the116* given array. The new attribute set is populated by117* adding the elements of <CODE>attributes</CODE> array to the set in118* sequence, starting at index 0. Thus, later array elements may replace119* earlier array elements if the array contains duplicate attribute120* 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 NullPointerException126* (unchecked exception) Thrown if any element of127* <CODE>attributes</CODE> is null.128*/129public HashAttributeSet(Attribute[] attributes) {130this (attributes, Attribute.class);131}132133/**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*/141public HashAttributeSet(AttributeSet attributes) {142this (attributes, Attribute.class);143}144145/**146* Construct a new, empty attribute set, where the members of147* the attribute set are restricted to the given interface.148*149* @param interfaceName The interface of which all members of this150* attribute set must be an instance. It is assumed to151* be interface {@link Attribute Attribute} or a152* subinterface thereof.153* @exception NullPointerException if interfaceName is null.154*/155protected HashAttributeSet(Class<?> interfaceName) {156if (interfaceName == null) {157throw new NullPointerException("null interface");158}159myInterface = interfaceName;160}161162/**163* Construct a new attribute set, initially populated with the given164* attribute, where the members of the attribute set are restricted to the165* given interface.166*167* @param attribute Attribute value to add to the set.168* @param interfaceName The interface of which all members of this169* attribute set must be an instance. It is assumed to170* be interface {@link Attribute Attribute} or a171* subinterface thereof.172*173* @exception NullPointerException174* (unchecked exception) Thrown if <CODE>attribute</CODE> is null.175* @exception NullPointerException if interfaceName is null.176* @exception ClassCastException177* (unchecked exception) Thrown if <CODE>attribute</CODE> is not an178* instance of <CODE>interfaceName</CODE>.179*/180protected HashAttributeSet(Attribute attribute, Class<?> interfaceName) {181if (interfaceName == null) {182throw new NullPointerException("null interface");183}184myInterface = interfaceName;185add (attribute);186}187188/**189* Construct a new attribute set, where the members of the attribute190* set are restricted to the given interface.191* The new attribute set is populated192* by adding the elements of <CODE>attributes</CODE> array to the set in193* sequence, starting at index 0. Thus, later array elements may replace194* earlier array elements if the array contains duplicate attribute195* values or attribute categories.196*197* @param attributes Array of attribute values to add to the set. If198* null, an empty attribute set is constructed.199* @param interfaceName The interface of which all members of this200* attribute set must be an instance. It is assumed to201* be interface {@link Attribute Attribute} or a202* subinterface thereof.203*204* @exception NullPointerException205* (unchecked exception) Thrown if any element of206* <CODE>attributes</CODE> is null.207* @exception NullPointerException if interfaceName is null.208* @exception ClassCastException209* (unchecked exception) Thrown if any element of210* <CODE>attributes</CODE> is not an instance of211* <CODE>interfaceName</CODE>.212*/213protected HashAttributeSet(Attribute[] attributes, Class<?> interfaceName) {214if (interfaceName == null) {215throw new NullPointerException("null interface");216}217myInterface = interfaceName;218int n = attributes == null ? 0 : attributes.length;219for (int i = 0; i < n; ++ i) {220add (attributes[i]);221}222}223224/**225* Construct a new attribute set, initially populated with the226* values from the given set where the members of the attribute227* set are restricted to the given interface.228*229* @param attributes set of attribute values to initialise the set. If230* null, an empty attribute set is constructed.231* @param interfaceName The interface of which all members of this232* attribute set must be an instance. It is assumed to233* be interface {@link Attribute Attribute} or a234* subinterface thereof.235*236* @exception ClassCastException237* (unchecked exception) Thrown if any element of238* <CODE>attributes</CODE> is not an instance of239* <CODE>interfaceName</CODE>.240*/241protected HashAttributeSet(AttributeSet attributes, Class<?> interfaceName) {242myInterface = interfaceName;243if (attributes != null) {244Attribute[] attribArray = attributes.toArray();245int n = attribArray == null ? 0 : attribArray.length;246for (int i = 0; i < n; ++ i) {247add (attribArray[i]);248}249}250}251252/**253* Returns the attribute value which this attribute set contains in the254* given attribute category. Returns <tt>null</tt> if this attribute set255* does not contain any attribute value in the given attribute category.256*257* @param category Attribute category whose associated attribute value258* is to be returned. It must be a259* {@link java.lang.Class Class}260* that implements interface {@link Attribute261* Attribute}.262*263* @return The attribute value in the given attribute category contained264* in this attribute set, or <tt>null</tt> if this attribute set265* does not contain any attribute value in the given attribute266* category.267*268* @throws NullPointerException269* (unchecked exception) Thrown if the <CODE>category</CODE> is null.270* @throws ClassCastException271* (unchecked exception) Thrown if the <CODE>category</CODE> is not a272* {@link java.lang.Class Class} that implements interface {@link273* Attribute Attribute}.274*/275public Attribute get(Class<?> category) {276return (Attribute)277attrMap.get(AttributeSetUtilities.278verifyAttributeCategory(category,279Attribute.class));280}281282/**283* Adds the specified attribute to this attribute set if it is not284* already present, first removing any existing in the same285* attribute category as the specified attribute value.286*287* @param attribute Attribute value to be added to this attribute set.288*289* @return <tt>true</tt> if this attribute set changed as a result of the290* call, i.e., the given attribute value was not already a291* member of this attribute set.292*293* @throws NullPointerException294* (unchecked exception) Thrown if the <CODE>attribute</CODE> is null.295* @throws UnmodifiableSetException296* (unchecked exception) Thrown if this attribute set does not support297* the <CODE>add()</CODE> operation.298*/299public boolean add(Attribute attribute) {300Object oldAttribute =301attrMap.put(attribute.getCategory(),302AttributeSetUtilities.303verifyAttributeValue(attribute, myInterface));304return (!attribute.equals(oldAttribute));305}306307/**308* Removes any attribute for this category from this attribute set if309* present. If <CODE>category</CODE> is null, then310* <CODE>remove()</CODE> does nothing and returns <tt>false</tt>.311*312* @param category Attribute category to be removed from this313* attribute set.314*315* @return <tt>true</tt> if this attribute set changed as a result of the316* call, i.e., the given attribute category had been a member of317* this attribute set.318*319* @throws UnmodifiableSetException320* (unchecked exception) Thrown if this attribute set does not321* support the <CODE>remove()</CODE> operation.322*/323public boolean remove(Class<?> category) {324return325category != null &&326AttributeSetUtilities.327verifyAttributeCategory(category, Attribute.class) != null &&328attrMap.remove(category) != null;329}330331/**332* Removes the specified attribute from this attribute set if333* present. If <CODE>attribute</CODE> is null, then334* <CODE>remove()</CODE> does nothing and returns <tt>false</tt>.335*336* @param attribute Attribute value to be removed from this attribute set.337*338* @return <tt>true</tt> if this attribute set changed as a result of the339* call, i.e., the given attribute value had been a member of340* this attribute set.341*342* @throws UnmodifiableSetException343* (unchecked exception) Thrown if this attribute set does not344* support the <CODE>remove()</CODE> operation.345*/346public boolean remove(Attribute attribute) {347return348attribute != null &&349attrMap.remove(attribute.getCategory()) != null;350}351352/**353* Returns <tt>true</tt> if this attribute set contains an354* attribute for the specified category.355*356* @param category whose presence in this attribute set is357* to be tested.358*359* @return <tt>true</tt> if this attribute set contains an attribute360* value for the specified category.361*/362public boolean containsKey(Class<?> category) {363return364category != null &&365AttributeSetUtilities.366verifyAttributeCategory(category, Attribute.class) != null &&367attrMap.get(category) != null;368}369370/**371* Returns <tt>true</tt> if this attribute set contains the given372* attribute.373*374* @param attribute value whose presence in this attribute set is375* to be tested.376*377* @return <tt>true</tt> if this attribute set contains the given378* attribute value.379*/380public boolean containsValue(Attribute attribute) {381return382attribute != null &&383attribute instanceof Attribute &&384attribute.equals(attrMap.get(((Attribute)attribute).getCategory()));385}386387/**388* Adds all of the elements in the specified set to this attribute.389* The outcome is the same as if the390* {@link #add(Attribute) add(Attribute)}391* operation had been applied to this attribute set successively with392* each element from the specified set.393* The behavior of the <CODE>addAll(AttributeSet)</CODE>394* operation is unspecified if the specified set is modified while395* the operation is in progress.396* <P>397* If the <CODE>addAll(AttributeSet)</CODE> operation throws an exception,398* the effect on this attribute set's state is implementation dependent;399* elements from the specified set before the point of the exception may400* or may not have been added to this attribute set.401*402* @param attributes whose elements are to be added to this attribute403* set.404*405* @return <tt>true</tt> if this attribute set changed as a result of the406* call.407*408* @throws UnmodifiableSetException409* (Unchecked exception) Thrown if this attribute set does not410* support the <tt>addAll(AttributeSet)</tt> method.411* @throws NullPointerException412* (Unchecked exception) Thrown if some element in the specified413* set is null, or the set is null.414*415* @see #add(Attribute)416*/417public boolean addAll(AttributeSet attributes) {418419Attribute []attrs = attributes.toArray();420boolean result = false;421for (int i=0; i<attrs.length; i++) {422Attribute newValue =423AttributeSetUtilities.verifyAttributeValue(attrs[i],424myInterface);425Object oldValue = attrMap.put(newValue.getCategory(), newValue);426result = (! newValue.equals(oldValue)) || result;427}428return result;429}430431/**432* Returns the number of attributes in this attribute set. If this433* attribute set contains more than <tt>Integer.MAX_VALUE</tt> elements,434* returns <tt>Integer.MAX_VALUE</tt>.435*436* @return The number of attributes in this attribute set.437*/438public int size() {439return attrMap.size();440}441442/**443*444* @return the Attributes contained in this set as an array, zero length445* if the AttributeSet is empty.446*/447public Attribute[] toArray() {448Attribute []attrs = new Attribute[size()];449attrMap.values().toArray(attrs);450return attrs;451}452453454/**455* Removes all attributes from this attribute set.456*457* @throws UnmodifiableSetException458* (unchecked exception) Thrown if this attribute set does not support459* the <CODE>clear()</CODE> operation.460*/461public void clear() {462attrMap.clear();463}464465/**466* Returns true if this attribute set contains no attributes.467*468* @return true if this attribute set contains no attributes.469*/470public boolean isEmpty() {471return attrMap.isEmpty();472}473474/**475* Compares the specified object with this attribute set for equality.476* Returns <tt>true</tt> if the given object is also an attribute set and477* the two attribute sets contain the same attribute category-attribute478* value mappings. This ensures that the479* <tt>equals()</tt> method works properly across different480* implementations of the AttributeSet interface.481*482* @param object to be compared for equality with this attribute set.483*484* @return <tt>true</tt> if the specified object is equal to this485* attribute set.486*/487488public boolean equals(Object object) {489if (object == null || !(object instanceof AttributeSet)) {490return false;491}492493AttributeSet aset = (AttributeSet)object;494if (aset.size() != size()) {495return false;496}497498Attribute[] attrs = toArray();499for (int i=0;i<attrs.length; i++) {500if (!aset.containsValue(attrs[i])) {501return false;502}503}504return true;505}506507/**508* Returns the hash code value for this attribute set.509* The hash code of an attribute set is defined to be the sum510* of the hash codes of each entry in the AttributeSet.511* This ensures that <tt>t1.equals(t2)</tt> implies that512* <tt>t1.hashCode()==t2.hashCode()</tt> for any two attribute sets513* <tt>t1</tt> and <tt>t2</tt>, as required by the general contract of514* {@link java.lang.Object#hashCode() Object.hashCode()}.515*516* @return The hash code value for this attribute set.517*/518public int hashCode() {519int hcode = 0;520Attribute[] attrs = toArray();521for (int i=0;i<attrs.length; i++) {522hcode += attrs[i].hashCode();523}524return hcode;525}526527}528529530