1 /*
   2  * Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package org.xml.sax.helpers;
  27 
  28 import java.util.ArrayList;
  29 import java.util.List;
  30 import org.xml.sax.AttributeList;
  31 
  32 
  33 /**
  34  * Default implementation for AttributeList.
  35  *
  36  * <p>AttributeList implements the deprecated SAX1 {@link
  37  * org.xml.sax.AttributeList AttributeList} interface, and has been
  38  * replaced by the new SAX2 {@link org.xml.sax.helpers.AttributesImpl
  39  * AttributesImpl} interface.</p>
  40  *
  41  * <p>This class provides a convenience implementation of the SAX
  42  * {@link org.xml.sax.AttributeList AttributeList} interface.  This
  43  * implementation is useful both for SAX parser writers, who can use
  44  * it to provide attributes to the application, and for SAX application
  45  * writers, who can use it to create a persistent copy of an element's
  46  * attribute specifications:</p>
  47  *
  48  * <pre>
  49  * private AttributeList myatts;
  50  *
  51  * public void startElement (String name, AttributeList atts)
  52  * {
  53  *              // create a persistent copy of the attribute list
  54  *              // for use outside this method
  55  *   myatts = new AttributeListImpl(atts);
  56  *   [...]
  57  * }
  58  * </pre>
  59  *
  60  * <p>Please note that SAX parsers are not required to use this
  61  * class to provide an implementation of AttributeList; it is
  62  * supplied only as an optional convenience.  In particular,
  63  * parser writers are encouraged to invent more efficient
  64  * implementations.</p>
  65  *
  66  * @deprecated This class implements a deprecated interface,
  67  *             {@link org.xml.sax.AttributeList AttributeList};
  68  *             that interface has been replaced by
  69  *             {@link org.xml.sax.Attributes Attributes},
  70  *             which is implemented in the
  71  *             {@link org.xml.sax.helpers.AttributesImpl
  72  *            AttributesImpl} helper class.
  73  * @since 1.4, SAX 1.0
  74  * @author David Megginson
  75  * @see org.xml.sax.AttributeList
  76  * @see org.xml.sax.DocumentHandler#startElement
  77  */
  78 @Deprecated(since="1.5")
  79 public class AttributeListImpl implements AttributeList
  80 {
  81 
  82     /**
  83      * Create an empty attribute list.
  84      *
  85      * <p>This constructor is most useful for parser writers, who
  86      * will use it to create a single, reusable attribute list that
  87      * can be reset with the clear method between elements.</p>
  88      *
  89      * @see #addAttribute
  90      * @see #clear
  91      */
  92     public AttributeListImpl ()
  93     {
  94     }
  95 
  96 
  97     /**
  98      * Construct a persistent copy of an existing attribute list.
  99      *
 100      * <p>This constructor is most useful for application writers,
 101      * who will use it to create a persistent copy of an existing
 102      * attribute list.</p>
 103      *
 104      * @param atts The attribute list to copy
 105      * @see org.xml.sax.DocumentHandler#startElement
 106      */
 107     public AttributeListImpl (AttributeList atts)
 108     {
 109         setAttributeList(atts);
 110     }
 111 
 112 
 113 
 114     ////////////////////////////////////////////////////////////////////
 115     // Methods specific to this class.
 116     ////////////////////////////////////////////////////////////////////
 117 
 118 
 119     /**
 120      * Set the attribute list, discarding previous contents.
 121      *
 122      * <p>This method allows an application writer to reuse an
 123      * attribute list easily.</p>
 124      *
 125      * @param atts The attribute list to copy.
 126      */
 127     public void setAttributeList (AttributeList atts)
 128     {
 129         int count = atts.getLength();
 130 
 131         clear();
 132 
 133         for (int i = 0; i < count; i++) {
 134             addAttribute(atts.getName(i), atts.getType(i), atts.getValue(i));
 135         }
 136     }
 137 
 138 
 139     /**
 140      * Add an attribute to an attribute list.
 141      *
 142      * <p>This method is provided for SAX parser writers, to allow them
 143      * to build up an attribute list incrementally before delivering
 144      * it to the application.</p>
 145      *
 146      * @param name The attribute name.
 147      * @param type The attribute type ("NMTOKEN" for an enumeration).
 148      * @param value The attribute value (must not be null).
 149      * @see #removeAttribute
 150      * @see org.xml.sax.DocumentHandler#startElement
 151      */
 152     public void addAttribute (String name, String type, String value)
 153     {
 154         names.add(name);
 155         types.add(type);
 156         values.add(value);
 157     }
 158 
 159 
 160     /**
 161      * Remove an attribute from the list.
 162      *
 163      * <p>SAX application writers can use this method to filter an
 164      * attribute out of an AttributeList.  Note that invoking this
 165      * method will change the length of the attribute list and
 166      * some of the attribute's indices.</p>
 167      *
 168      * <p>If the requested attribute is not in the list, this is
 169      * a no-op.</p>
 170      *
 171      * @param name The attribute name.
 172      * @see #addAttribute
 173      */
 174     public void removeAttribute (String name)
 175     {
 176         int i = names.indexOf(name);
 177 
 178         if (i >= 0) {
 179             names.remove(i);
 180             types.remove(i);
 181             values.remove(i);
 182         }
 183     }
 184 
 185 
 186     /**
 187      * Clear the attribute list.
 188      *
 189      * <p>SAX parser writers can use this method to reset the attribute
 190      * list between DocumentHandler.startElement events.  Normally,
 191      * it will make sense to reuse the same AttributeListImpl object
 192      * rather than allocating a new one each time.</p>
 193      *
 194      * @see org.xml.sax.DocumentHandler#startElement
 195      */
 196     public void clear ()
 197     {
 198         names.clear();
 199         types.clear();
 200         values.clear();
 201     }
 202 
 203 
 204 
 205     ////////////////////////////////////////////////////////////////////
 206     // Implementation of org.xml.sax.AttributeList
 207     ////////////////////////////////////////////////////////////////////
 208 
 209 
 210     /**
 211      * Return the number of attributes in the list.
 212      *
 213      * @return The number of attributes in the list.
 214      * @see org.xml.sax.AttributeList#getLength
 215      */
 216     public int getLength ()
 217     {
 218         return names.size();
 219     }
 220 
 221 
 222     /**
 223      * Get the name of an attribute (by position).
 224      *
 225      * @param i The position of the attribute in the list.
 226      * @return The attribute name as a string, or null if there
 227      *         is no attribute at that position.
 228      * @see org.xml.sax.AttributeList#getName(int)
 229      */
 230     public String getName (int i)
 231     {
 232         if (i < 0) {
 233             return null;
 234         }
 235         try {
 236             return names.get(i);
 237         } catch (IndexOutOfBoundsException e) {
 238             return null;
 239         }
 240     }
 241 
 242 
 243     /**
 244      * Get the type of an attribute (by position).
 245      *
 246      * @param i The position of the attribute in the list.
 247      * @return The attribute type as a string ("NMTOKEN" for an
 248      *         enumeration, and "CDATA" if no declaration was
 249      *         read), or null if there is no attribute at
 250      *         that position.
 251      * @see org.xml.sax.AttributeList#getType(int)
 252      */
 253     public String getType (int i)
 254     {
 255         if (i < 0) {
 256             return null;
 257         }
 258         try {
 259             return types.get(i);
 260         } catch (IndexOutOfBoundsException e) {
 261             return null;
 262         }
 263     }
 264 
 265 
 266     /**
 267      * Get the value of an attribute (by position).
 268      *
 269      * @param i The position of the attribute in the list.
 270      * @return The attribute value as a string, or null if
 271      *         there is no attribute at that position.
 272      * @see org.xml.sax.AttributeList#getValue(int)
 273      */
 274     public String getValue (int i)
 275     {
 276         if (i < 0) {
 277             return null;
 278         }
 279         try {
 280             return values.get(i);
 281         } catch (IndexOutOfBoundsException e) {
 282             return null;
 283         }
 284     }
 285 
 286 
 287     /**
 288      * Get the type of an attribute (by name).
 289      *
 290      * @param name The attribute name.
 291      * @return The attribute type as a string ("NMTOKEN" for an
 292      *         enumeration, and "CDATA" if no declaration was
 293      *         read).
 294      * @see org.xml.sax.AttributeList#getType(java.lang.String)
 295      */
 296     public String getType (String name)
 297     {
 298         return getType(names.indexOf(name));
 299     }
 300 
 301 
 302     /**
 303      * Get the value of an attribute (by name).
 304      *
 305      * @param name The attribute name.
 306      * @see org.xml.sax.AttributeList#getValue(java.lang.String)
 307      */
 308     public String getValue (String name)
 309     {
 310         return getValue(names.indexOf(name));
 311     }
 312 
 313 
 314 
 315     ////////////////////////////////////////////////////////////////////
 316     // Internal state.
 317     ////////////////////////////////////////////////////////////////////
 318 
 319     List<String> names = new ArrayList<>();
 320     List<String> types = new ArrayList<>();
 321     List<String> values = new ArrayList<>();
 322 
 323 }
 324 
 325 // end of AttributeListImpl.java