Source for org.xml.sax.ext.Attributes2Impl

   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: }