001    // SAX default implementation for AttributeList.
002    // http://www.saxproject.org
003    // No warranty; no copyright -- use this as you will.
004    // $Id: AttributeListImpl.java,v 1.1 2004/12/23 22:38:42 mark Exp $
005    
006    package org.xml.sax.helpers;
007    
008    import org.xml.sax.AttributeList;
009    
010    import java.util.Vector;
011    
012    
013    /**
014     * Default implementation for AttributeList.
015     *
016     * <blockquote>
017     * <em>This module, both source code and documentation, is in the
018     * Public Domain, and comes with <strong>NO WARRANTY</strong>.</em>
019     * See <a href='http://www.saxproject.org'>http://www.saxproject.org</a>
020     * for further information.
021     * </blockquote>
022     *
023     * <p>AttributeList implements the deprecated SAX1 {@link
024     * org.xml.sax.AttributeList AttributeList} interface, and has been
025     * replaced by the new SAX2 {@link org.xml.sax.helpers.AttributesImpl
026     * AttributesImpl} interface.</p>
027     *
028     * <p>This class provides a convenience implementation of the SAX
029     * {@link org.xml.sax.AttributeList AttributeList} interface.  This 
030     * implementation is useful both for SAX parser writers, who can use 
031     * it to provide attributes to the application, and for SAX application 
032     * writers, who can use it to create a persistent copy of an element's 
033     * attribute specifications:</p>
034     *
035     * <pre>
036     * private AttributeList myatts;
037     *
038     * public void startElement (String name, AttributeList atts)
039     * {
040     *              // create a persistent copy of the attribute list
041     *              // for use outside this method
042     *   myatts = new AttributeListImpl(atts);
043     *   [...]
044     * }
045     * </pre>
046     *
047     * <p>Please note that SAX parsers are not required to use this
048     * class to provide an implementation of AttributeList; it is
049     * supplied only as an optional convenience.  In particular, 
050     * parser writers are encouraged to invent more efficient
051     * implementations.</p>
052     *
053     * @deprecated This class implements a deprecated interface,
054     *             {@link org.xml.sax.AttributeList AttributeList};
055     *             that interface has been replaced by
056     *             {@link org.xml.sax.Attributes Attributes},
057     *             which is implemented in the
058     *             {@link org.xml.sax.helpers.AttributesImpl 
059     *            AttributesImpl} helper class.
060     * @since SAX 1.0
061     * @author David Megginson
062     * @version 2.0.1 (sax2r2)
063     * @see org.xml.sax.AttributeList
064     * @see org.xml.sax.DocumentHandler#startElement 
065     */
066    public class AttributeListImpl implements AttributeList
067    {
068        
069        /**
070         * Create an empty attribute list.
071         *
072         * <p>This constructor is most useful for parser writers, who
073         * will use it to create a single, reusable attribute list that
074         * can be reset with the clear method between elements.</p>
075         *
076         * @see #addAttribute
077         * @see #clear
078         */
079        public AttributeListImpl ()
080        {
081        }
082        
083        
084        /**
085         * Construct a persistent copy of an existing attribute list.
086         *
087         * <p>This constructor is most useful for application writers,
088         * who will use it to create a persistent copy of an existing
089         * attribute list.</p>
090         *
091         * @param atts The attribute list to copy
092         * @see org.xml.sax.DocumentHandler#startElement
093         */
094        public AttributeListImpl (AttributeList atts)
095        {
096            setAttributeList(atts);
097        }
098        
099        
100    
101        ////////////////////////////////////////////////////////////////////
102        // Methods specific to this class.
103        ////////////////////////////////////////////////////////////////////
104        
105        
106        /**
107         * Set the attribute list, discarding previous contents.
108         *
109         * <p>This method allows an application writer to reuse an
110         * attribute list easily.</p>
111         *
112         * @param atts The attribute list to copy.
113         */
114        public void setAttributeList (AttributeList atts)
115        {
116            int count = atts.getLength();
117            
118            clear();
119            
120            for (int i = 0; i < count; i++) {
121                addAttribute(atts.getName(i), atts.getType(i), atts.getValue(i));
122            }
123        }
124        
125        
126        /**
127         * Add an attribute to an attribute list.
128         *
129         * <p>This method is provided for SAX parser writers, to allow them
130         * to build up an attribute list incrementally before delivering
131         * it to the application.</p>
132         *
133         * @param name The attribute name.
134         * @param type The attribute type ("NMTOKEN" for an enumeration).
135         * @param value The attribute value (must not be null).
136         * @see #removeAttribute
137         * @see org.xml.sax.DocumentHandler#startElement
138         */
139        public void addAttribute (String name, String type, String value)
140        {
141            names.addElement(name);
142            types.addElement(type);
143            values.addElement(value);
144        }
145        
146        
147        /**
148         * Remove an attribute from the list.
149         *
150         * <p>SAX application writers can use this method to filter an
151         * attribute out of an AttributeList.  Note that invoking this
152         * method will change the length of the attribute list and
153         * some of the attribute's indices.</p>
154         *
155         * <p>If the requested attribute is not in the list, this is
156         * a no-op.</p>
157         *
158         * @param name The attribute name.
159         * @see #addAttribute
160         */
161        public void removeAttribute (String name)
162        {
163            int i = names.indexOf(name);
164            
165            if (i >= 0) {
166                names.removeElementAt(i);
167                types.removeElementAt(i);
168                values.removeElementAt(i);
169            }
170        }
171        
172        
173        /**
174         * Clear the attribute list.
175         *
176         * <p>SAX parser writers can use this method to reset the attribute
177         * list between DocumentHandler.startElement events.  Normally,
178         * it will make sense to reuse the same AttributeListImpl object
179         * rather than allocating a new one each time.</p>
180         *
181         * @see org.xml.sax.DocumentHandler#startElement
182         */
183        public void clear ()
184        {
185            names.removeAllElements();
186            types.removeAllElements();
187            values.removeAllElements();
188        }
189        
190        
191    
192        ////////////////////////////////////////////////////////////////////
193        // Implementation of org.xml.sax.AttributeList
194        ////////////////////////////////////////////////////////////////////
195        
196        
197        /**
198         * Return the number of attributes in the list.
199         *
200         * @return The number of attributes in the list.
201         * @see org.xml.sax.AttributeList#getLength
202         */
203        public int getLength ()
204        {
205            return names.size();
206        }
207        
208        
209        /**
210         * Get the name of an attribute (by position).
211         *
212         * @param i The position of the attribute in the list.
213         * @return The attribute name as a string, or null if there
214         *         is no attribute at that position.
215         * @see org.xml.sax.AttributeList#getName(int)
216         */
217        public String getName (int i)
218        {
219            if (i < 0) {
220                return null;
221            }
222            try {
223                return (String)names.elementAt(i);
224            } catch (ArrayIndexOutOfBoundsException e) {
225                return null;
226            }
227        }
228        
229        
230        /**
231         * Get the type of an attribute (by position).
232         *
233         * @param i The position of the attribute in the list.
234         * @return The attribute type as a string ("NMTOKEN" for an
235         *         enumeration, and "CDATA" if no declaration was
236         *         read), or null if there is no attribute at
237         *         that position.
238         * @see org.xml.sax.AttributeList#getType(int)
239         */
240        public String getType (int i)
241        {
242            if (i < 0) {
243                return null;
244            }
245            try {
246                return (String)types.elementAt(i);
247            } catch (ArrayIndexOutOfBoundsException e) {
248                return null;
249            }
250        }
251        
252        
253        /**
254         * Get the value of an attribute (by position).
255         *
256         * @param i The position of the attribute in the list.
257         * @return The attribute value as a string, or null if
258         *         there is no attribute at that position.
259         * @see org.xml.sax.AttributeList#getValue(int)
260         */
261        public String getValue (int i)
262        {
263            if (i < 0) {
264                return null;
265            }
266            try {
267                return (String)values.elementAt(i);
268            } catch (ArrayIndexOutOfBoundsException e) {
269                return null;
270            }
271        }
272        
273        
274        /**
275         * Get the type of an attribute (by name).
276         *
277         * @param name The attribute name.
278         * @return The attribute type as a string ("NMTOKEN" for an
279         *         enumeration, and "CDATA" if no declaration was
280         *         read).
281         * @see org.xml.sax.AttributeList#getType(java.lang.String)
282         */
283        public String getType (String name)
284        {
285            return getType(names.indexOf(name));
286        }
287        
288        
289        /**
290         * Get the value of an attribute (by name).
291         *
292         * @param name The attribute name.
293         * @see org.xml.sax.AttributeList#getValue(java.lang.String)
294         */
295        public String getValue (String name)
296        {
297            return getValue(names.indexOf(name));
298        }
299        
300        
301    
302        ////////////////////////////////////////////////////////////////////
303        // Internal state.
304        ////////////////////////////////////////////////////////////////////
305    
306        Vector names = new Vector();
307        Vector types = new Vector();
308        Vector values = new Vector();
309    
310    }
311    
312    // end of AttributeListImpl.java