/*
* Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
* ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*/
package javax.swing.text;
import java.util.
Hashtable;
import java.util.
Enumeration;
import java.util.
Collections;
import java.io.
IOException;
import java.io.
ObjectInputStream;
import java.io.
Serializable;
import java.util.
AbstractMap;
import java.util.
LinkedHashMap;
/**
* A straightforward implementation of MutableAttributeSet using a
* hash table.
* <p>
* <strong>Warning:</strong>
* Serialized objects of this class will not be compatible with
* future Swing releases. The current serialization support is
* appropriate for short term storage or RMI between applications running
* the same version of Swing. As of 1.4, support for long term storage
* of all JavaBeans™
* has been added to the <code>java.beans</code> package.
* Please see {@link java.beans.XMLEncoder}.
*
* @author Tim Prinzing
*/
public class
SimpleAttributeSet implements
MutableAttributeSet,
Serializable,
Cloneable
{
private static final long
serialVersionUID = -6631553454711782652L;
/**
* An empty attribute set.
*/
public static final
AttributeSet EMPTY = new
EmptyAttributeSet();
private transient
LinkedHashMap<
Object,
Object>
table = new
LinkedHashMap<>(3);
/**
* Creates a new attribute set.
*/
public
SimpleAttributeSet() {
}
/**
* Creates a new attribute set based on a supplied set of attributes.
*
* @param source the set of attributes
*/
public
SimpleAttributeSet(
AttributeSet source) {
addAttributes(
source);
}
/**
* Checks whether the set of attributes is empty.
*
* @return true if the set is empty else false
*/
public boolean
isEmpty()
{
return
table.
isEmpty();
}
/**
* Gets a count of the number of attributes.
*
* @return the count
*/
public int
getAttributeCount() {
return
table.
size();
}
/**
* Tells whether a given attribute is defined.
*
* @param attrName the attribute name
* @return true if the attribute is defined
*/
public boolean
isDefined(
Object attrName) {
return
table.
containsKey(
attrName);
}
/**
* Compares two attribute sets.
*
* @param attr the second attribute set
* @return true if the sets are equal, false otherwise
*/
public boolean
isEqual(
AttributeSet attr) {
return ((
getAttributeCount() ==
attr.
getAttributeCount()) &&
containsAttributes(
attr));
}
/**
* Makes a copy of the attributes.
*
* @return the copy
*/
public
AttributeSet copyAttributes() {
return (
AttributeSet)
clone();
}
/**
* Gets the names of the attributes in the set.
*
* @return the names as an <code>Enumeration</code>
*/
public
Enumeration<?>
getAttributeNames() {
return
Collections.
enumeration(
table.
keySet());
}
/**
* Gets the value of an attribute.
*
* @param name the attribute name
* @return the value
*/
public
Object getAttribute(
Object name) {
Object value =
table.
get(
name);
if (
value == null) {
AttributeSet parent =
getResolveParent();
if (
parent != null) {
value =
parent.
getAttribute(
name);
}
}
return
value;
}
/**
* Checks whether the attribute list contains a
* specified attribute name/value pair.
*
* @param name the name
* @param value the value
* @return true if the name/value pair is in the list
*/
public boolean
containsAttribute(
Object name,
Object value) {
return
value.
equals(
getAttribute(
name));
}
/**
* Checks whether the attribute list contains all the
* specified name/value pairs.
*
* @param attributes the attribute list
* @return true if the list contains all the name/value pairs
*/
public boolean
containsAttributes(
AttributeSet attributes) {
boolean
result = true;
Enumeration names =
attributes.
getAttributeNames();
while (
result &&
names.
hasMoreElements()) {
Object name =
names.
nextElement();
result =
attributes.
getAttribute(
name).
equals(
getAttribute(
name));
}
return
result;
}
/**
* Adds an attribute to the list.
*
* @param name the attribute name
* @param value the attribute value
*/
public void
addAttribute(
Object name,
Object value) {
table.
put(
name,
value);
}
/**
* Adds a set of attributes to the list.
*
* @param attributes the set of attributes to add
*/
public void
addAttributes(
AttributeSet attributes) {
Enumeration names =
attributes.
getAttributeNames();
while (
names.
hasMoreElements()) {
Object name =
names.
nextElement();
addAttribute(
name,
attributes.
getAttribute(
name));
}
}
/**
* Removes an attribute from the list.
*
* @param name the attribute name
*/
public void
removeAttribute(
Object name) {
table.
remove(
name);
}
/**
* Removes a set of attributes from the list.
*
* @param names the set of names to remove
*/
public void
removeAttributes(
Enumeration<?>
names) {
while (
names.
hasMoreElements())
removeAttribute(
names.
nextElement());
}
/**
* Removes a set of attributes from the list.
*
* @param attributes the set of attributes to remove
*/
public void
removeAttributes(
AttributeSet attributes) {
if (
attributes == this) {
table.
clear();
}
else {
Enumeration names =
attributes.
getAttributeNames();
while (
names.
hasMoreElements()) {
Object name =
names.
nextElement();
Object value =
attributes.
getAttribute(
name);
if (
value.
equals(
getAttribute(
name)))
removeAttribute(
name);
}
}
}
/**
* Gets the resolving parent. This is the set
* of attributes to resolve through if an attribute
* isn't defined locally. This is null if there
* are no other sets of attributes to resolve
* through.
*
* @return the parent
*/
public
AttributeSet getResolveParent() {
return (
AttributeSet)
table.
get(
StyleConstants.
ResolveAttribute);
}
/**
* Sets the resolving parent.
*
* @param parent the parent
*/
public void
setResolveParent(
AttributeSet parent) {
addAttribute(
StyleConstants.
ResolveAttribute,
parent);
}
// --- Object methods ---------------------------------
/**
* Clones a set of attributes.
*
* @return the new set of attributes
*/
public
Object clone() {
SimpleAttributeSet attr;
try {
attr = (
SimpleAttributeSet) super.clone();
attr.
table = (
LinkedHashMap)
table.
clone();
} catch (
CloneNotSupportedException cnse) {
attr = null;
}
return
attr;
}
/**
* Returns a hashcode for this set of attributes.
* @return a hashcode value for this set of attributes.
*/
public int
hashCode() {
return
table.
hashCode();
}
/**
* Compares this object to the specified object.
* The result is <code>true</code> if the object is an equivalent
* set of attributes.
* @param obj the object to compare this attribute set with
* @return <code>true</code> if the objects are equal;
* <code>false</code> otherwise
*/
public boolean
equals(
Object obj) {
if (this ==
obj) {
return true;
}
if (
obj instanceof
AttributeSet) {
AttributeSet attrs = (
AttributeSet)
obj;
return
isEqual(
attrs);
}
return false;
}
/**
* Converts the attribute set to a String.
*
* @return the string
*/
public
String toString() {
String s = "";
Enumeration names =
getAttributeNames();
while (
names.
hasMoreElements()) {
Object key =
names.
nextElement();
Object value =
getAttribute(
key);
if (
value instanceof
AttributeSet) {
// don't go recursive
s =
s +
key + "=**AttributeSet** ";
} else {
s =
s +
key + "=" +
value + " ";
}
}
return
s;
}
private void
writeObject(java.io.
ObjectOutputStream s) throws
IOException {
s.
defaultWriteObject();
StyleContext.
writeAttributeSet(
s, this);
}
private void
readObject(
ObjectInputStream s)
throws
ClassNotFoundException,
IOException {
s.
defaultReadObject();
table = new
LinkedHashMap<>(3);
StyleContext.
readAttributeSet(
s, this);
}
/**
* An AttributeSet that is always empty.
*/
static class
EmptyAttributeSet implements
AttributeSet,
Serializable {
static final long
serialVersionUID = -8714803568785904228L;
public int
getAttributeCount() {
return 0;
}
public boolean
isDefined(
Object attrName) {
return false;
}
public boolean
isEqual(
AttributeSet attr) {
return (
attr.
getAttributeCount() == 0);
}
public
AttributeSet copyAttributes() {
return this;
}
public
Object getAttribute(
Object key) {
return null;
}
public
Enumeration getAttributeNames() {
return
Collections.
emptyEnumeration();
}
public boolean
containsAttribute(
Object name,
Object value) {
return false;
}
public boolean
containsAttributes(
AttributeSet attributes) {
return (
attributes.
getAttributeCount() == 0);
}
public
AttributeSet getResolveParent() {
return null;
}
public boolean
equals(
Object obj) {
if (this ==
obj) {
return true;
}
return ((
obj instanceof
AttributeSet) &&
(((
AttributeSet)
obj).
getAttributeCount() == 0));
}
public int
hashCode() {
return 0;
}
}
}