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