Home | History | Annotate | Download | only in ext
      1 // Attributes2Impl.java - extended AttributesImpl
      2 // http://www.saxproject.org
      3 // Public Domain: no warranty.
      4 // $Id: Attributes2Impl.java,v 1.5 2004/03/08 13:01:01 dmegginson 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         // BEGIN android-added
     49         declared = new boolean[0];
     50         specified = new boolean[0];
     51         // END android-added
     52     }
     53 
     54 
     55     /**
     56      * Copy an existing Attributes or Attributes2 object.
     57      * If the object implements Attributes2, values of the
     58      * <em>specified</em> and <em>declared</em> flags for each
     59      * attribute are copied.
     60      * Otherwise the flag values are defaulted to assume no DTD was used,
     61      * unless there is evidence to the contrary (such as attributes with
     62      * type other than CDATA, which must have been <em>declared</em>).
     63      *
     64      * <p>This constructor is especially useful inside a
     65      * {@link org.xml.sax.ContentHandler#startElement startElement} event.</p>
     66      *
     67      * @param atts The existing Attributes object.
     68      */
     69     public Attributes2Impl (Attributes atts)
     70     {
     71     super (atts);
     72     }
     73 
     74 
     75     ////////////////////////////////////////////////////////////////////
     76     // Implementation of Attributes2
     77     ////////////////////////////////////////////////////////////////////
     78 
     79 
     80     /*
     81      * Returns the current value of the attribute's "declared" flag.
     82      */
     83     // javadoc mostly from interface
     84     public boolean isDeclared (int index)
     85     {
     86     if (index < 0 || index >= getLength ())
     87         throw new ArrayIndexOutOfBoundsException (
     88         "No attribute at index: " + index);
     89     return declared [index];
     90     }
     91 
     92 
     93     /*
     94      * Returns the current value of the attribute's "declared" flag.
     95      */
     96     // javadoc mostly from interface
     97     public boolean isDeclared (String uri, String localName)
     98     {
     99     int index = getIndex (uri, localName);
    100 
    101     if (index < 0)
    102         throw new IllegalArgumentException (
    103         "No such attribute: local=" + localName
    104         + ", namespace=" + uri);
    105     return declared [index];
    106     }
    107 
    108 
    109     /*
    110      * Returns the current value of the attribute's "declared" flag.
    111      */
    112     // javadoc mostly from interface
    113     public boolean isDeclared (String qName)
    114     {
    115     int index = getIndex (qName);
    116 
    117     if (index < 0)
    118         throw new IllegalArgumentException (
    119         "No such attribute: " + qName);
    120     return declared [index];
    121     }
    122 
    123 
    124     /**
    125      * Returns the current value of an attribute's "specified" flag.
    126      *
    127      * @param index The attribute index (zero-based).
    128      * @return current flag value
    129      * @exception java.lang.ArrayIndexOutOfBoundsException When the
    130      *            supplied index does not identify an attribute.
    131      */
    132     public boolean isSpecified (int index)
    133     {
    134     if (index < 0 || index >= getLength ())
    135         throw new ArrayIndexOutOfBoundsException (
    136         "No attribute at index: " + index);
    137     return specified [index];
    138     }
    139 
    140 
    141     /**
    142      * Returns the current value of an attribute's "specified" flag.
    143      *
    144      * @param uri The Namespace URI, or the empty string if
    145      *        the name has no Namespace URI.
    146      * @param localName The attribute's local name.
    147      * @return current flag value
    148      * @exception java.lang.IllegalArgumentException When the
    149      *            supplied names do not identify an attribute.
    150      */
    151     public boolean isSpecified (String uri, String localName)
    152     {
    153     int index = getIndex (uri, localName);
    154 
    155     if (index < 0)
    156         throw new IllegalArgumentException (
    157         "No such attribute: local=" + localName
    158         + ", namespace=" + uri);
    159     return specified [index];
    160     }
    161 
    162 
    163     /**
    164      * Returns the current value of an attribute's "specified" flag.
    165      *
    166      * @param qName The XML qualified (prefixed) name.
    167      * @return current flag value
    168      * @exception java.lang.IllegalArgumentException When the
    169      *            supplied name does not identify an attribute.
    170      */
    171     public boolean isSpecified (String qName)
    172     {
    173     int index = getIndex (qName);
    174 
    175     if (index < 0)
    176         throw new IllegalArgumentException (
    177         "No such attribute: " + qName);
    178     return specified [index];
    179     }
    180 
    181 
    182     ////////////////////////////////////////////////////////////////////
    183     // Manipulators
    184     ////////////////////////////////////////////////////////////////////
    185 
    186 
    187     /**
    188      * Copy an entire Attributes object.  The "specified" flags are
    189      * assigned as true, and "declared" flags as false (except when
    190      * an attribute's type is not CDATA),
    191      * unless the object is an Attributes2 object.
    192      * In that case those flag values are all copied.
    193      *
    194      * @param atts The attributes to copy.
    195      *
    196      * @see AttributesImpl#setAttributes
    197      */
    198     public void setAttributes (Attributes atts)
    199     {
    200     int length = atts.getLength ();
    201 
    202     super.setAttributes (atts);
    203     declared = new boolean [length];
    204     specified = new boolean [length];
    205 
    206     if (atts instanceof Attributes2) {
    207         Attributes2    a2 = (Attributes2) atts;
    208         for (int i = 0; i < length; i++) {
    209         declared [i] = a2.isDeclared (i);
    210         specified [i] = a2.isSpecified (i);
    211         }
    212     } else {
    213         for (int i = 0; i < length; i++) {
    214         declared [i] = !"CDATA".equals (atts.getType (i));
    215         specified [i] = true;
    216         }
    217     }
    218     }
    219 
    220 
    221     /**
    222      * Add an attribute to the end of the list, setting its
    223      * "specified" flag to true.  To set that flag's value
    224      * to false, use {@link #setSpecified}.
    225      *
    226      * <p>Unless the attribute <em>type</em> is CDATA, this attribute
    227      * is marked as being declared in the DTD.  To set that flag's value
    228      * to true for CDATA attributes, use {@link #setDeclared}.
    229      *
    230      * @param uri The Namespace URI, or the empty string if
    231      *        none is available or Namespace processing is not
    232      *        being performed.
    233      * @param localName The local name, or the empty string if
    234      *        Namespace processing is not being performed.
    235      * @param qName The qualified (prefixed) name, or the empty string
    236      *        if qualified names are not available.
    237      * @param type The attribute type as a string.
    238      * @param value The attribute value.
    239      *
    240      * @see AttributesImpl#addAttribute
    241      */
    242     public void addAttribute (String uri, String localName, String qName,
    243                   String type, String value)
    244     {
    245     super.addAttribute (uri, localName, qName, type, value);
    246 
    247     int length = getLength ();
    248 
    249     // BEGIN android-changed
    250     if (length > specified.length) {
    251     // END android-changed
    252         boolean    newFlags [];
    253 
    254         newFlags = new boolean [length];
    255         System.arraycopy (declared, 0, newFlags, 0, declared.length);
    256         declared = newFlags;
    257 
    258         newFlags = new boolean [length];
    259         System.arraycopy (specified, 0, newFlags, 0, specified.length);
    260         specified = newFlags;
    261     }
    262 
    263     specified [length - 1] = true;
    264     declared [length - 1] = !"CDATA".equals (type);
    265     }
    266 
    267 
    268     // javadoc entirely from superclass
    269     public void removeAttribute (int index)
    270     {
    271     int origMax = getLength () - 1;
    272 
    273     super.removeAttribute (index);
    274     if (index != origMax) {
    275         System.arraycopy (declared, index + 1, declared, index,
    276             origMax - index);
    277         System.arraycopy (specified, index + 1, specified, index,
    278             origMax - index);
    279     }
    280     }
    281 
    282 
    283     /**
    284      * Assign a value to the "declared" flag of a specific attribute.
    285      * This is normally needed only for attributes of type CDATA,
    286      * including attributes whose type is changed to or from CDATA.
    287      *
    288      * @param index The index of the attribute (zero-based).
    289      * @param value The desired flag value.
    290      * @exception java.lang.ArrayIndexOutOfBoundsException When the
    291      *            supplied index does not identify an attribute.
    292      * @see #setType
    293      */
    294     public void setDeclared (int index, boolean value)
    295     {
    296     if (index < 0 || index >= getLength ())
    297         throw new ArrayIndexOutOfBoundsException (
    298         "No attribute at index: " + index);
    299     declared [index] = value;
    300     }
    301 
    302 
    303     /**
    304      * Assign a value to the "specified" flag of a specific attribute.
    305      * This is the only way this flag can be cleared, except clearing
    306      * by initialization with the copy constructor.
    307      *
    308      * @param index The index of the attribute (zero-based).
    309      * @param value The desired flag value.
    310      * @exception java.lang.ArrayIndexOutOfBoundsException When the
    311      *            supplied index does not identify an attribute.
    312      */
    313     public void setSpecified (int index, boolean value)
    314     {
    315     if (index < 0 || index >= getLength ())
    316         throw new ArrayIndexOutOfBoundsException (
    317         "No attribute at index: " + index);
    318     specified [index] = value;
    319     }
    320 }
    321