0N/A/*
2362N/A * Copyright (c) 2001, Oracle and/or its affiliates. All rights reserved.
0N/A * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
0N/A *
0N/A * This code is free software; you can redistribute it and/or modify it
0N/A * under the terms of the GNU General Public License version 2 only, as
2362N/A * published by the Free Software Foundation. Oracle designates this
0N/A * particular file as subject to the "Classpath" exception as provided
2362N/A * by Oracle in the LICENSE file that accompanied this code.
0N/A *
0N/A * This code is distributed in the hope that it will be useful, but WITHOUT
0N/A * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
0N/A * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
0N/A * version 2 for more details (a copy is included in the LICENSE file that
0N/A * accompanied this code).
0N/A *
0N/A * You should have received a copy of the GNU General Public License version
0N/A * 2 along with this work; if not, write to the Free Software Foundation,
0N/A * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
0N/A *
2362N/A * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
2362N/A * or visit www.oracle.com if you need additional information or have any
2362N/A * questions.
0N/A */
0N/Apackage javax.swing.text.html;
0N/A
0N/Aimport javax.swing.text.*;
0N/Aimport java.io.Serializable;
0N/Aimport java.util.*;
0N/A
0N/A/**
0N/A * An implementation of <code>AttributeSet</code> that can multiplex
0N/A * across a set of <code>AttributeSet</code>s.
0N/A *
0N/A */
0N/Aclass MuxingAttributeSet implements AttributeSet, Serializable {
0N/A /**
0N/A * Creates a <code>MuxingAttributeSet</code> with the passed in
0N/A * attributes.
0N/A */
0N/A public MuxingAttributeSet(AttributeSet[] attrs) {
0N/A this.attrs = attrs;
0N/A }
0N/A
0N/A /**
0N/A * Creates an empty <code>MuxingAttributeSet</code>. This is intended for
0N/A * use by subclasses only, and it is also intended that subclasses will
0N/A * set the constituent <code>AttributeSet</code>s before invoking any
0N/A * of the <code>AttributeSet</code> methods.
0N/A */
0N/A protected MuxingAttributeSet() {
0N/A }
0N/A
0N/A /**
0N/A * Directly sets the <code>AttributeSet</code>s that comprise this
0N/A * <code>MuxingAttributeSet</code>.
0N/A */
0N/A protected synchronized void setAttributes(AttributeSet[] attrs) {
0N/A this.attrs = attrs;
0N/A }
0N/A
0N/A /**
0N/A * Returns the <code>AttributeSet</code>s multiplexing too. When the
0N/A * <code>AttributeSet</code>s need to be referenced, this should be called.
0N/A */
0N/A protected synchronized AttributeSet[] getAttributes() {
0N/A return attrs;
0N/A }
0N/A
0N/A /**
0N/A * Inserts <code>as</code> at <code>index</code>. This assumes
0N/A * the value of <code>index</code> is between 0 and attrs.length,
0N/A * inclusive.
0N/A */
0N/A protected synchronized void insertAttributeSetAt(AttributeSet as,
0N/A int index) {
0N/A int numAttrs = attrs.length;
0N/A AttributeSet newAttrs[] = new AttributeSet[numAttrs + 1];
0N/A if (index < numAttrs) {
0N/A if (index > 0) {
0N/A System.arraycopy(attrs, 0, newAttrs, 0, index);
0N/A System.arraycopy(attrs, index, newAttrs, index + 1,
0N/A numAttrs - index);
0N/A }
0N/A else {
0N/A System.arraycopy(attrs, 0, newAttrs, 1, numAttrs);
0N/A }
0N/A }
0N/A else {
0N/A System.arraycopy(attrs, 0, newAttrs, 0, numAttrs);
0N/A }
0N/A newAttrs[index] = as;
0N/A attrs = newAttrs;
0N/A }
0N/A
0N/A /**
0N/A * Removes the AttributeSet at <code>index</code>. This assumes
0N/A * the value of <code>index</code> is greater than or equal to 0,
0N/A * and less than attrs.length.
0N/A */
0N/A protected synchronized void removeAttributeSetAt(int index) {
0N/A int numAttrs = attrs.length;
0N/A AttributeSet[] newAttrs = new AttributeSet[numAttrs - 1];
0N/A if (numAttrs > 0) {
0N/A if (index == 0) {
0N/A // FIRST
0N/A System.arraycopy(attrs, 1, newAttrs, 0, numAttrs - 1);
0N/A }
0N/A else if (index < (numAttrs - 1)) {
0N/A // MIDDLE
0N/A System.arraycopy(attrs, 0, newAttrs, 0, index);
0N/A System.arraycopy(attrs, index + 1, newAttrs, index,
0N/A numAttrs - index - 1);
0N/A }
0N/A else {
0N/A // END
0N/A System.arraycopy(attrs, 0, newAttrs, 0, numAttrs - 1);
0N/A }
0N/A }
0N/A attrs = newAttrs;
0N/A }
0N/A
0N/A // --- AttributeSet methods ----------------------------
0N/A
0N/A /**
0N/A * Gets the number of attributes that are defined.
0N/A *
0N/A * @return the number of attributes
0N/A * @see AttributeSet#getAttributeCount
0N/A */
0N/A public int getAttributeCount() {
0N/A AttributeSet[] as = getAttributes();
0N/A int n = 0;
0N/A for (int i = 0; i < as.length; i++) {
0N/A n += as[i].getAttributeCount();
0N/A }
0N/A return n;
0N/A }
0N/A
0N/A /**
0N/A * Checks whether a given attribute is defined.
0N/A * This will convert the key over to CSS if the
0N/A * key is a StyleConstants key that has a CSS
0N/A * mapping.
0N/A *
0N/A * @param key the attribute key
0N/A * @return true if the attribute is defined
0N/A * @see AttributeSet#isDefined
0N/A */
0N/A public boolean isDefined(Object key) {
0N/A AttributeSet[] as = getAttributes();
0N/A for (int i = 0; i < as.length; i++) {
0N/A if (as[i].isDefined(key)) {
0N/A return true;
0N/A }
0N/A }
0N/A return false;
0N/A }
0N/A
0N/A /**
0N/A * Checks whether two attribute sets are equal.
0N/A *
0N/A * @param attr the attribute set to check against
0N/A * @return true if the same
0N/A * @see AttributeSet#isEqual
0N/A */
0N/A public boolean isEqual(AttributeSet attr) {
0N/A return ((getAttributeCount() == attr.getAttributeCount()) &&
0N/A containsAttributes(attr));
0N/A }
0N/A
0N/A /**
0N/A * Copies a set of attributes.
0N/A *
0N/A * @return the copy
0N/A * @see AttributeSet#copyAttributes
0N/A */
0N/A public AttributeSet copyAttributes() {
0N/A AttributeSet[] as = getAttributes();
0N/A MutableAttributeSet a = new SimpleAttributeSet();
0N/A int n = 0;
0N/A for (int i = as.length - 1; i >= 0; i--) {
0N/A a.addAttributes(as[i]);
0N/A }
0N/A return a;
0N/A }
0N/A
0N/A /**
0N/A * Gets the value of an attribute. If the requested
0N/A * attribute is a StyleConstants attribute that has
0N/A * a CSS mapping, the request will be converted.
0N/A *
0N/A * @param key the attribute name
0N/A * @return the attribute value
0N/A * @see AttributeSet#getAttribute
0N/A */
0N/A public Object getAttribute(Object key) {
0N/A AttributeSet[] as = getAttributes();
0N/A int n = as.length;
0N/A for (int i = 0; i < n; i++) {
0N/A Object o = as[i].getAttribute(key);
0N/A if (o != null) {
0N/A return o;
0N/A }
0N/A }
0N/A return null;
0N/A }
0N/A
0N/A /**
0N/A * Gets the names of all attributes.
0N/A *
0N/A * @return the attribute names
0N/A * @see AttributeSet#getAttributeNames
0N/A */
0N/A public Enumeration getAttributeNames() {
0N/A return new MuxingAttributeNameEnumeration();
0N/A }
0N/A
0N/A /**
0N/A * Checks whether a given attribute name/value is defined.
0N/A *
0N/A * @param name the attribute name
0N/A * @param value the attribute value
0N/A * @return true if the name/value is defined
0N/A * @see AttributeSet#containsAttribute
0N/A */
0N/A public boolean containsAttribute(Object name, Object value) {
0N/A return value.equals(getAttribute(name));
0N/A }
0N/A
0N/A /**
0N/A * Checks whether the attribute set contains all of
0N/A * the given attributes.
0N/A *
0N/A * @param attrs the attributes to check
0N/A * @return true if the element contains all the attributes
0N/A * @see AttributeSet#containsAttributes
0N/A */
0N/A public boolean containsAttributes(AttributeSet attrs) {
0N/A boolean result = true;
0N/A
0N/A Enumeration names = attrs.getAttributeNames();
0N/A while (result && names.hasMoreElements()) {
0N/A Object name = names.nextElement();
0N/A result = attrs.getAttribute(name).equals(getAttribute(name));
0N/A }
0N/A
0N/A return result;
0N/A }
0N/A
0N/A /**
0N/A * Returns null, subclasses may wish to do something more
0N/A * intelligent with this.
0N/A */
0N/A public AttributeSet getResolveParent() {
0N/A return null;
0N/A }
0N/A
0N/A /**
0N/A * The <code>AttributeSet</code>s that make up the resulting
0N/A * <code>AttributeSet</code>.
0N/A */
0N/A private AttributeSet[] attrs;
0N/A
0N/A
0N/A /**
0N/A * An Enumeration of the Attribute names in a MuxingAttributeSet.
0N/A * This may return the same name more than once.
0N/A */
0N/A private class MuxingAttributeNameEnumeration implements Enumeration {
0N/A
0N/A MuxingAttributeNameEnumeration() {
0N/A updateEnum();
0N/A }
0N/A
0N/A public boolean hasMoreElements() {
0N/A if (currentEnum == null) {
0N/A return false;
0N/A }
0N/A return currentEnum.hasMoreElements();
0N/A }
0N/A
0N/A public Object nextElement() {
0N/A if (currentEnum == null) {
0N/A throw new NoSuchElementException("No more names");
0N/A }
0N/A Object retObject = currentEnum.nextElement();
0N/A if (!currentEnum.hasMoreElements()) {
0N/A updateEnum();
0N/A }
0N/A return retObject;
0N/A }
0N/A
0N/A void updateEnum() {
0N/A AttributeSet[] as = getAttributes();
0N/A currentEnum = null;
0N/A while (currentEnum == null && attrIndex < as.length) {
0N/A currentEnum = as[attrIndex++].getAttributeNames();
0N/A if (!currentEnum.hasMoreElements()) {
0N/A currentEnum = null;
0N/A }
0N/A }
0N/A }
0N/A
0N/A
0N/A /** Index into attrs the current Enumeration came from. */
0N/A private int attrIndex;
0N/A /** Enumeration from attrs. */
0N/A private Enumeration currentEnum;
0N/A }
0N/A}