- /*
- * @(#)MuxingAttributeSet.java 1.4 03/12/19
- *
- * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
- * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
- */
- package javax.swing.text.html;
-
- import javax.swing.text.*;
- import java.io.Serializable;
- import java.util.*;
-
- /**
- * An implementation of <code>AttributeSet</code> that can multiplex
- * across a set of <code>AttributeSet</code>s.
- *
- * @version 1.4 12/19/03
- */
- class MuxingAttributeSet implements AttributeSet, Serializable {
- /**
- * Creates a <code>MuxingAttributeSet</code> with the passed in
- * attributes.
- */
- public MuxingAttributeSet(AttributeSet[] attrs) {
- this.attrs = attrs;
- }
-
- /**
- * Creates an empty <code>MuxingAttributeSet</code>. This is intended for
- * use by subclasses only, and it is also intended that subclasses will
- * set the constituent <code>AttributeSet</code>s before invoking any
- * of the <code>AttributeSet</code> methods.
- */
- protected MuxingAttributeSet() {
- }
-
- /**
- * Directly sets the <code>AttributeSet</code>s that comprise this
- * <code>MuxingAttributeSet</code>.
- */
- protected synchronized void setAttributes(AttributeSet[] attrs) {
- this.attrs = attrs;
- }
-
- /**
- * Returns the <code>AttributeSet</code>s multiplexing too. When the
- * <code>AttributeSet</code>s need to be referenced, this should be called.
- */
- protected synchronized AttributeSet[] getAttributes() {
- return attrs;
- }
-
- /**
- * Inserts <code>as</code> at <code>index</code>. This assumes
- * the value of <code>index</code> is between 0 and attrs.length,
- * inclusive.
- */
- protected synchronized void insertAttributeSetAt(AttributeSet as,
- int index) {
- int numAttrs = attrs.length;
- AttributeSet newAttrs[] = new AttributeSet[numAttrs + 1];
- if (index < numAttrs) {
- if (index > 0) {
- System.arraycopy(attrs, 0, newAttrs, 0, index);
- System.arraycopy(attrs, index, newAttrs, index + 1,
- numAttrs - index);
- }
- else {
- System.arraycopy(attrs, 0, newAttrs, 1, numAttrs);
- }
- }
- else {
- System.arraycopy(attrs, 0, newAttrs, 0, numAttrs);
- }
- newAttrs[index] = as;
- attrs = newAttrs;
- }
-
- /**
- * Removes the AttributeSet at <code>index</code>. This assumes
- * the value of <code>index</code> is greater than or equal to 0,
- * and less than attrs.length.
- */
- protected synchronized void removeAttributeSetAt(int index) {
- int numAttrs = attrs.length;
- AttributeSet[] newAttrs = new AttributeSet[numAttrs - 1];
- if (numAttrs > 0) {
- if (index == 0) {
- // FIRST
- System.arraycopy(attrs, 1, newAttrs, 0, numAttrs - 1);
- }
- else if (index < (numAttrs - 1)) {
- // MIDDLE
- System.arraycopy(attrs, 0, newAttrs, 0, index);
- System.arraycopy(attrs, index + 1, newAttrs, index,
- numAttrs - index - 1);
- }
- else {
- // END
- System.arraycopy(attrs, 0, newAttrs, 0, numAttrs - 1);
- }
- }
- attrs = newAttrs;
- }
-
- // --- AttributeSet methods ----------------------------
-
- /**
- * Gets the number of attributes that are defined.
- *
- * @return the number of attributes
- * @see AttributeSet#getAttributeCount
- */
- public int getAttributeCount() {
- AttributeSet[] as = getAttributes();
- int n = 0;
- for (int i = 0; i < as.length; i++) {
- n += as[i].getAttributeCount();
- }
- return n;
- }
-
- /**
- * Checks whether a given attribute is defined.
- * This will convert the key over to CSS if the
- * key is a StyleConstants key that has a CSS
- * mapping.
- *
- * @param key the attribute key
- * @return true if the attribute is defined
- * @see AttributeSet#isDefined
- */
- public boolean isDefined(Object key) {
- AttributeSet[] as = getAttributes();
- for (int i = 0; i < as.length; i++) {
- if (as[i].isDefined(key)) {
- return true;
- }
- }
- return false;
- }
-
- /**
- * Checks whether two attribute sets are equal.
- *
- * @param attr the attribute set to check against
- * @return true if the same
- * @see AttributeSet#isEqual
- */
- public boolean isEqual(AttributeSet attr) {
- return ((getAttributeCount() == attr.getAttributeCount()) &&
- containsAttributes(attr));
- }
-
- /**
- * Copies a set of attributes.
- *
- * @return the copy
- * @see AttributeSet#copyAttributes
- */
- public AttributeSet copyAttributes() {
- AttributeSet[] as = getAttributes();
- MutableAttributeSet a = new SimpleAttributeSet();
- int n = 0;
- for (int i = as.length - 1; i >= 0; i--) {
- a.addAttributes(as[i]);
- }
- return a;
- }
-
- /**
- * Gets the value of an attribute. If the requested
- * attribute is a StyleConstants attribute that has
- * a CSS mapping, the request will be converted.
- *
- * @param key the attribute name
- * @return the attribute value
- * @see AttributeSet#getAttribute
- */
- public Object getAttribute(Object key) {
- AttributeSet[] as = getAttributes();
- int n = as.length;
- for (int i = 0; i < n; i++) {
- Object o = as[i].getAttribute(key);
- if (o != null) {
- return o;
- }
- }
- return null;
- }
-
- /**
- * Gets the names of all attributes.
- *
- * @return the attribute names
- * @see AttributeSet#getAttributeNames
- */
- public Enumeration getAttributeNames() {
- return new MuxingAttributeNameEnumeration();
- }
-
- /**
- * Checks whether a given attribute name/value is defined.
- *
- * @param name the attribute name
- * @param value the attribute value
- * @return true if the name/value is defined
- * @see AttributeSet#containsAttribute
- */
- public boolean containsAttribute(Object name, Object value) {
- return value.equals(getAttribute(name));
- }
-
- /**
- * Checks whether the attribute set contains all of
- * the given attributes.
- *
- * @param attrs the attributes to check
- * @return true if the element contains all the attributes
- * @see AttributeSet#containsAttributes
- */
- public boolean containsAttributes(AttributeSet attrs) {
- boolean result = true;
-
- Enumeration names = attrs.getAttributeNames();
- while (result && names.hasMoreElements()) {
- Object name = names.nextElement();
- result = attrs.getAttribute(name).equals(getAttribute(name));
- }
-
- return result;
- }
-
- /**
- * Returns null, subclasses may wish to do something more
- * intelligent with this.
- */
- public AttributeSet getResolveParent() {
- return null;
- }
-
- /**
- * The <code>AttributeSet</code>s that make up the resulting
- * <code>AttributeSet</code>.
- */
- private AttributeSet[] attrs;
-
-
- /**
- * An Enumeration of the Attribute names in a MuxingAttributeSet.
- * This may return the same name more than once.
- */
- private class MuxingAttributeNameEnumeration implements Enumeration {
-
- MuxingAttributeNameEnumeration() {
- updateEnum();
- }
-
- public boolean hasMoreElements() {
- if (currentEnum == null) {
- return false;
- }
- return currentEnum.hasMoreElements();
- }
-
- public Object nextElement() {
- if (currentEnum == null) {
- throw new NoSuchElementException("No more names");
- }
- Object retObject = currentEnum.nextElement();
- if (!currentEnum.hasMoreElements()) {
- updateEnum();
- }
- return retObject;
- }
-
- void updateEnum() {
- AttributeSet[] as = getAttributes();
- currentEnum = null;
- while (currentEnum == null && attrIndex < as.length) {
- currentEnum = as[attrIndex++].getAttributeNames();
- if (!currentEnum.hasMoreElements()) {
- currentEnum = null;
- }
- }
- }
-
-
- /** Index into attrs the current Enumeration came from. */
- private int attrIndex;
- /** Enumeration from attrs. */
- private Enumeration currentEnum;
- }
- }