Frames | No Frames |
1: /* SmallHtmlAttributeSet.java -- Small fixed HTML attribute set 2: Copyright (C) 2006 Free Software Foundation, Inc. 3: 4: This file is part of GNU Classpath. 5: 6: GNU Classpath is free software; you can redistribute it and/or modify 7: it under the terms of the GNU General Public License as published by 8: the Free Software Foundation; either version 2, or (at your option) 9: any later version. 10: 11: GNU Classpath is distributed in the hope that it will be useful, but 12: WITHOUT ANY WARRANTY; without even the implied warranty of 13: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14: General Public License for more details. 15: 16: You should have received a copy of the GNU General Public License 17: along with GNU Classpath; see the file COPYING. If not, write to the 18: Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 19: 02110-1301 USA. 20: 21: Linking this library statically or dynamically with other modules is 22: making a combined work based on this library. Thus, the terms and 23: conditions of the GNU General Public License cover the whole 24: combination. 25: 26: As a special exception, the copyright holders of this library give you 27: permission to link this library with independent modules to produce an 28: executable, regardless of the license terms of these independent 29: modules, and to copy and distribute the resulting executable under 30: terms of your choice, provided that you also meet, for each linked 31: independent module, the terms and conditions of the license of that 32: module. An independent module is a module which is not derived from 33: or based on this library. If you modify this library, you may extend 34: this exception to your version of the library, but you are not 35: obligated to do so. If you do not wish to do so, delete this 36: exception statement from your version. */ 37: 38: 39: package gnu.javax.swing.text.html.parser; 40: 41: import java.io.Serializable; 42: import java.util.Enumeration; 43: import java.util.NoSuchElementException; 44: 45: import javax.swing.text.AttributeSet; 46: import javax.swing.text.html.HTML.Attribute; 47: import javax.swing.text.html.HTML.Tag; 48: 49: /** 50: * Small fixed HTML attribute set. The most of the HTML elements contain only 51: * several attributes. With four attributes, the number of operations in more 52: * complex algorithms is not larger than using the naive algorithm. 53: * 54: * Same as HtmlAttributeSet, this set allows both strings and non-string as 55: * keys. The strings are case insensitive, the non strings are compared with 56: * .equals. 57: * 58: * @author Audrius Meskauskas (AudriusA@Bioinformatics.org) 59: */ 60: public class SmallHtmlAttributeSet 61: implements AttributeSet, Cloneable, Serializable 62: { 63: private static final long serialVersionUID = 1; 64: 65: /** 66: * The keys, stored in this attribute set. 67: */ 68: final Object[] keys; 69: 70: /** 71: * The values, stored in this attribute set. 72: */ 73: final Object[] values; 74: 75: /** 76: * The parent, used for resolving the values, not found in this set. 77: */ 78: final AttributeSet parent; 79: 80: /** 81: * Create a new small fixed attribute set that contains the unchangeable copy 82: * of the passed attribute set and inherits its parent. 83: * 84: * @param copyFrom the attribute set, containing the attribute values to copy. 85: */ 86: public SmallHtmlAttributeSet(AttributeSet copyFrom) 87: { 88: int n = copyFrom.getAttributeCount(); 89: 90: keys = new Object[n]; 91: values = new Object[n]; 92: parent = copyFrom.getResolveParent(); 93: 94: Enumeration en = copyFrom.getAttributeNames(); 95: Object key; 96: Object value; 97: 98: for (int i = 0; i < n; i++) 99: { 100: key = en.nextElement(); 101: keys[i] = key; 102: value = copyFrom.getAttribute(key); 103: values[i] = value; 104: } 105: } 106: 107: public boolean containsAttribute(Object name, Object value) 108: { 109: Object contains = getAttribute(name); 110: if (value == null) 111: return value == contains; 112: else 113: return value.equals(contains); 114: } 115: 116: public boolean containsAttributes(AttributeSet attributes) 117: { 118: if (attributes == this) 119: return true; 120: Object v; 121: for (int i = 0; i < keys.length; i++) 122: { 123: v = attributes.getAttribute(keys[i]); 124: if (v != values[i]) 125: { 126: if (values[i] == null) 127: return false; 128: else if (! values[i].equals(v)) 129: return false; 130: } 131: } 132: return true; 133: } 134: 135: /** 136: * THIS can be safely returned as the set is not mutable. 137: */ 138: public AttributeSet copyAttributes() 139: { 140: return this; 141: } 142: 143: /** 144: * Get the attribute value, matching this key. If not found in this set, the 145: * call is delegated to parent. 146: * 147: * @return the value, matching key (or null if none). 148: */ 149: public Object getAttribute(Object key) 150: { 151: // Null and HTML attributes or tags can be searched by direct comparison. 152: if (key == null || key instanceof Attribute || key instanceof Tag) 153: { 154: for (int i = 0; i < keys.length; i++) 155: { 156: if (keys[i] == key) 157: return values[i]; 158: } 159: } 160: 161: // Strings are case insensitive. Only string can be match the string. 162: else if (key instanceof String) 163: { 164: String ks = (String) key; 165: for (int i = 0; i < keys.length; i++) 166: { 167: if (keys[i] instanceof String) 168: if (ks.equalsIgnoreCase((String) keys[i])) 169: return values[i]; 170: } 171: } 172: 173: // Otherwise, defaults to .equals 174: else 175: { 176: for (int i = 0; i < keys.length; i++) 177: { 178: if (key.equals(keys[i])) 179: return values[i]; 180: } 181: } 182: 183: if (parent != null) 184: return parent.getAttribute(key); 185: else 186: return null; 187: } 188: 189: /** 190: * Get the number of the stored attributes. 191: */ 192: public int getAttributeCount() 193: { 194: return keys.length; 195: } 196: 197: /** 198: * Get enumeration, containing the attribute names. No guard agains the 199: * concurent modification is required as the set is not mutable. 200: */ 201: public Enumeration getAttributeNames() 202: { 203: return new Enumeration() 204: { 205: int p = 0; 206: 207: public boolean hasMoreElements() 208: { 209: return p < keys.length; 210: } 211: 212: public Object nextElement() 213: { 214: if (p < keys.length) 215: return keys[p++]; 216: else 217: throw new NoSuchElementException(); 218: } 219: }; 220: } 221: 222: /** 223: * Get the parent that this set uses to resolve the not found attributes. 224: */ 225: public AttributeSet getResolveParent() 226: { 227: return parent; 228: } 229: 230: /** 231: * Check if the given attribute is defined in this set (not in the parent). 232: */ 233: public boolean isDefined(Object attrName) 234: { 235: if (attrName instanceof String) 236: attrName = ((String) attrName).toLowerCase(); 237: 238: for (int i = 0; i < keys.length; i++) 239: { 240: if (attrName.equals(keys[i])) 241: return true; 242: } 243: return false; 244: } 245: 246: /** 247: * Check this set and another set for equality by content. 248: */ 249: public boolean isEqual(AttributeSet attr) 250: { 251: return keys.length == attr.getAttributeCount() && containsAttributes(attr); 252: } 253: 254: /** 255: * It is safe to return THIS on cloning, if one happens. 256: */ 257: protected Object clone() 258: { 259: return this; 260: } 261: }