Frames | No Frames |
1: // Attributes2Impl.java - extended AttributesImpl 2: // http://www.saxproject.org 3: // Public Domain: no warranty. 4: // $Id: Attributes2Impl.java,v 1.1 2004/12/23 22:38:42 mark Exp $ 5: 6: package org.xml.sax.ext; 7: 8: import org.xml.sax.Attributes; 9: import org.xml.sax.helpers.AttributesImpl; 10: 11: 12: /** 13: * SAX2 extension helper for additional Attributes information, 14: * implementing the {@link Attributes2} interface. 15: * 16: * <blockquote> 17: * <em>This module, both source code and documentation, is in the 18: * Public Domain, and comes with <strong>NO WARRANTY</strong>.</em> 19: * </blockquote> 20: * 21: * <p>This is not part of core-only SAX2 distributions.</p> 22: * 23: * <p>The <em>specified</em> flag for each attribute will always 24: * be true, unless it has been set to false in the copy constructor 25: * or using {@link #setSpecified}. 26: * Similarly, the <em>declared</em> flag for each attribute will 27: * always be false, except for defaulted attributes (<em>specified</em> 28: * is false), non-CDATA attributes, or when it is set to true using 29: * {@link #setDeclared}. 30: * If you change an attribute's type by hand, you may need to modify 31: * its <em>declared</em> flag to match. 32: * </p> 33: * 34: * @since SAX 2.0 (extensions 1.1 alpha) 35: * @author David Brownell 36: * @version TBS 37: */ 38: public class Attributes2Impl extends AttributesImpl implements Attributes2 39: { 40: private boolean declared []; 41: private boolean specified []; 42: 43: 44: /** 45: * Construct a new, empty Attributes2Impl object. 46: */ 47: public Attributes2Impl () { } 48: 49: 50: /** 51: * Copy an existing Attributes or Attributes2 object. 52: * If the object implements Attributes2, values of the 53: * <em>specified</em> and <em>declared</em> flags for each 54: * attribute are copied. 55: * Otherwise the flag values are defaulted to assume no DTD was used, 56: * unless there is evidence to the contrary (such as attributes with 57: * type other than CDATA, which must have been <em>declared</em>). 58: * 59: * <p>This constructor is especially useful inside a 60: * {@link org.xml.sax.ContentHandler#startElement startElement} event.</p> 61: * 62: * @param atts The existing Attributes object. 63: */ 64: public Attributes2Impl (Attributes atts) 65: { 66: super (atts); 67: } 68: 69: 70: //////////////////////////////////////////////////////////////////// 71: // Implementation of Attributes2 72: //////////////////////////////////////////////////////////////////// 73: 74: 75: /** 76: * Returns the current value of the attribute's "declared" flag. 77: */ 78: // javadoc mostly from interface 79: public boolean isDeclared (int index) 80: { 81: if (index < 0 || index >= getLength ()) 82: throw new ArrayIndexOutOfBoundsException ( 83: "No attribute at index: " + index); 84: return declared [index]; 85: } 86: 87: 88: /** 89: * Returns the current value of the attribute's "declared" flag. 90: */ 91: // javadoc mostly from interface 92: public boolean isDeclared (String uri, String localName) 93: { 94: int index = getIndex (uri, localName); 95: 96: if (index < 0) 97: throw new IllegalArgumentException ( 98: "No such attribute: local=" + localName 99: + ", namespace=" + uri); 100: return declared [index]; 101: } 102: 103: 104: /** 105: * Returns the current value of the attribute's "declared" flag. 106: */ 107: // javadoc mostly from interface 108: public boolean isDeclared (String qName) 109: { 110: int index = getIndex (qName); 111: 112: if (index < 0) 113: throw new IllegalArgumentException ( 114: "No such attribute: " + qName); 115: return declared [index]; 116: } 117: 118: 119: /** 120: * Returns the current value of an attribute's "specified" flag. 121: * 122: * @param index The attribute index (zero-based). 123: * @return current flag value 124: * @exception java.lang.ArrayIndexOutOfBoundsException When the 125: * supplied index does not identify an attribute. 126: */ 127: public boolean isSpecified (int index) 128: { 129: if (index < 0 || index >= getLength ()) 130: throw new ArrayIndexOutOfBoundsException ( 131: "No attribute at index: " + index); 132: return specified [index]; 133: } 134: 135: 136: /** 137: * Returns the current value of an attribute's "specified" flag. 138: * 139: * @param uri The Namespace URI, or the empty string if 140: * the name has no Namespace URI. 141: * @param localName The attribute's local name. 142: * @return current flag value 143: * @exception java.lang.IllegalArgumentException When the 144: * supplied names do not identify an attribute. 145: */ 146: public boolean isSpecified (String uri, String localName) 147: { 148: int index = getIndex (uri, localName); 149: 150: if (index < 0) 151: throw new IllegalArgumentException ( 152: "No such attribute: local=" + localName 153: + ", namespace=" + uri); 154: return specified [index]; 155: } 156: 157: 158: /** 159: * Returns the current value of an attribute's "specified" flag. 160: * 161: * @param qName The XML qualified (prefixed) name. 162: * @return current flag value 163: * @exception java.lang.IllegalArgumentException When the 164: * supplied name does not identify an attribute. 165: */ 166: public boolean isSpecified (String qName) 167: { 168: int index = getIndex (qName); 169: 170: if (index < 0) 171: throw new IllegalArgumentException ( 172: "No such attribute: " + qName); 173: return specified [index]; 174: } 175: 176: 177: //////////////////////////////////////////////////////////////////// 178: // Manipulators 179: //////////////////////////////////////////////////////////////////// 180: 181: 182: /** 183: * Copy an entire Attributes object. The "specified" flags are 184: * assigned as true, and "declared" flags as false (except when 185: * an attribute's type is not CDATA), 186: * unless the object is an Attributes2 object. 187: * In that case those flag values are all copied. 188: * 189: * @see AttributesImpl#setAttributes 190: */ 191: public void setAttributes (Attributes atts) 192: { 193: int length = atts.getLength (); 194: 195: super.setAttributes (atts); 196: declared = new boolean [length]; 197: specified = new boolean [length]; 198: 199: if (atts instanceof Attributes2) { 200: Attributes2 a2 = (Attributes2) atts; 201: for (int i = 0; i < length; i++) { 202: declared [i] = a2.isDeclared (i); 203: specified [i] = a2.isSpecified (i); 204: } 205: } else { 206: for (int i = 0; i < length; i++) { 207: declared [i] = !"CDATA".equals (atts.getType (i)); 208: specified [i] = true; 209: } 210: } 211: } 212: 213: 214: /** 215: * Add an attribute to the end of the list, setting its 216: * "specified" flag to true. To set that flag's value 217: * to false, use {@link #setSpecified}. 218: * 219: * <p>Unless the attribute <em>type</em> is CDATA, this attribute 220: * is marked as being declared in the DTD. To set that flag's value 221: * to true for CDATA attributes, use {@link #setDeclared}. 222: * 223: * @see AttributesImpl#addAttribute 224: */ 225: public void addAttribute (String uri, String localName, String qName, 226: String type, String value) 227: { 228: super.addAttribute (uri, localName, qName, type, value); 229: 230: int length = getLength (); 231: 232: if (length < specified.length) { 233: boolean newFlags []; 234: 235: newFlags = new boolean [length]; 236: System.arraycopy (declared, 0, newFlags, 0, declared.length); 237: declared = newFlags; 238: 239: newFlags = new boolean [length]; 240: System.arraycopy (specified, 0, newFlags, 0, specified.length); 241: specified = newFlags; 242: } 243: 244: specified [length - 1] = true; 245: declared [length - 1] = !"CDATA".equals (type); 246: } 247: 248: 249: // javadoc entirely from superclass 250: public void removeAttribute (int index) 251: { 252: int origMax = getLength () - 1; 253: 254: super.removeAttribute (index); 255: if (index != origMax) { 256: System.arraycopy (declared, index + 1, declared, index, 257: origMax - index); 258: System.arraycopy (specified, index + 1, specified, index, 259: origMax - index); 260: } 261: } 262: 263: 264: /** 265: * Assign a value to the "declared" flag of a specific attribute. 266: * This is normally needed only for attributes of type CDATA, 267: * including attributes whose type is changed to or from CDATA. 268: * 269: * @param index The index of the attribute (zero-based). 270: * @param value The desired flag value. 271: * @exception java.lang.ArrayIndexOutOfBoundsException When the 272: * supplied index does not identify an attribute. 273: * @see #setType 274: */ 275: public void setDeclared (int index, boolean value) 276: { 277: if (index < 0 || index >= getLength ()) 278: throw new ArrayIndexOutOfBoundsException ( 279: "No attribute at index: " + index); 280: declared [index] = value; 281: } 282: 283: 284: /** 285: * Assign a value to the "specified" flag of a specific attribute. 286: * This is the only way this flag can be cleared, except clearing 287: * by initialization with the copy constructor. 288: * 289: * @param index The index of the attribute (zero-based). 290: * @param value The desired flag value. 291: * @exception java.lang.ArrayIndexOutOfBoundsException When the 292: * supplied index does not identify an attribute. 293: */ 294: public void setSpecified (int index, boolean value) 295: { 296: if (index < 0 || index >= getLength ()) 297: throw new ArrayIndexOutOfBoundsException ( 298: "No attribute at index: " + index); 299: specified [index] = value; 300: } 301: }