KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > xml > sax > helpers > AttributesImpl


1 // AttributesImpl.java - default implementation of Attributes.
2
// http://www.saxproject.org
3
// Written by David Megginson
4
// NO WARRANTY! This class is in the public domain.
5
// $Id: AttributesImpl.java,v 1.1.24.1 2004/05/01 08:34:45 jsuttor Exp $
6

7 package org.xml.sax.helpers;
8
9 import org.xml.sax.Attributes JavaDoc;
10
11
12 /**
13  * Default implementation of the Attributes interface.
14  *
15  * <blockquote>
16  * <em>This module, both source code and documentation, is in the
17  * Public Domain, and comes with <strong>NO WARRANTY</strong>.</em>
18  * See <a HREF='http://www.saxproject.org'>http://www.saxproject.org</a>
19  * for further information.
20  * </blockquote>
21  *
22  * <p>This class provides a default implementation of the SAX2
23  * {@link org.xml.sax.Attributes Attributes} interface, with the
24  * addition of manipulators so that the list can be modified or
25  * reused.</p>
26  *
27  * <p>There are two typical uses of this class:</p>
28  *
29  * <ol>
30  * <li>to take a persistent snapshot of an Attributes object
31  * in a {@link org.xml.sax.ContentHandler#startElement startElement} event; or</li>
32  * <li>to construct or modify an Attributes object in a SAX2 driver or filter.</li>
33  * </ol>
34  *
35  * <p>This class replaces the now-deprecated SAX1 {@link
36  * org.xml.sax.helpers.AttributeListImpl AttributeListImpl}
37  * class; in addition to supporting the updated Attributes
38  * interface rather than the deprecated {@link org.xml.sax.AttributeList
39  * AttributeList} interface, it also includes a much more efficient
40  * implementation using a single array rather than a set of Vectors.</p>
41  *
42  * @since SAX 2.0
43  * @author David Megginson
44  * @version 2.0.1 (sax2r2)
45  */

46 public class AttributesImpl implements Attributes JavaDoc
47 {
48
49
50     ////////////////////////////////////////////////////////////////////
51
// Constructors.
52
////////////////////////////////////////////////////////////////////
53

54
55     /**
56      * Construct a new, empty AttributesImpl object.
57      */

58     public AttributesImpl ()
59     {
60     length = 0;
61     data = null;
62     }
63
64
65     /**
66      * Copy an existing Attributes object.
67      *
68      * <p>This constructor is especially useful inside a
69      * {@link org.xml.sax.ContentHandler#startElement startElement} event.</p>
70      *
71      * @param atts The existing Attributes object.
72      */

73     public AttributesImpl (Attributes JavaDoc atts)
74     {
75     setAttributes(atts);
76     }
77
78
79
80     ////////////////////////////////////////////////////////////////////
81
// Implementation of org.xml.sax.Attributes.
82
////////////////////////////////////////////////////////////////////
83

84
85     /**
86      * Return the number of attributes in the list.
87      *
88      * @return The number of attributes in the list.
89      * @see org.xml.sax.Attributes#getLength
90      */

91     public int getLength ()
92     {
93     return length;
94     }
95
96
97     /**
98      * Return an attribute's Namespace URI.
99      *
100      * @param index The attribute's index (zero-based).
101      * @return The Namespace URI, the empty string if none is
102      * available, or null if the index is out of range.
103      * @see org.xml.sax.Attributes#getURI
104      */

105     public String JavaDoc getURI (int index)
106     {
107     if (index >= 0 && index < length) {
108         return data[index*5];
109     } else {
110         return null;
111     }
112     }
113
114
115     /**
116      * Return an attribute's local name.
117      *
118      * @param index The attribute's index (zero-based).
119      * @return The attribute's local name, the empty string if
120      * none is available, or null if the index if out of range.
121      * @see org.xml.sax.Attributes#getLocalName
122      */

123     public String JavaDoc getLocalName (int index)
124     {
125     if (index >= 0 && index < length) {
126         return data[index*5+1];
127     } else {
128         return null;
129     }
130     }
131
132
133     /**
134      * Return an attribute's qualified (prefixed) name.
135      *
136      * @param index The attribute's index (zero-based).
137      * @return The attribute's qualified name, the empty string if
138      * none is available, or null if the index is out of bounds.
139      * @see org.xml.sax.Attributes#getQName
140      */

141     public String JavaDoc getQName (int index)
142     {
143     if (index >= 0 && index < length) {
144         return data[index*5+2];
145     } else {
146         return null;
147     }
148     }
149
150
151     /**
152      * Return an attribute's type by index.
153      *
154      * @param index The attribute's index (zero-based).
155      * @return The attribute's type, "CDATA" if the type is unknown, or null
156      * if the index is out of bounds.
157      * @see org.xml.sax.Attributes#getType(int)
158      */

159     public String JavaDoc getType (int index)
160     {
161     if (index >= 0 && index < length) {
162         return data[index*5+3];
163     } else {
164         return null;
165     }
166     }
167
168
169     /**
170      * Return an attribute's value by index.
171      *
172      * @param index The attribute's index (zero-based).
173      * @return The attribute's value or null if the index is out of bounds.
174      * @see org.xml.sax.Attributes#getValue(int)
175      */

176     public String JavaDoc getValue (int index)
177     {
178     if (index >= 0 && index < length) {
179         return data[index*5+4];
180     } else {
181         return null;
182     }
183     }
184
185
186     /**
187      * Look up an attribute's index by Namespace name.
188      *
189      * <p>In many cases, it will be more efficient to look up the name once and
190      * use the index query methods rather than using the name query methods
191      * repeatedly.</p>
192      *
193      * @param uri The attribute's Namespace URI, or the empty
194      * string if none is available.
195      * @param localName The attribute's local name.
196      * @return The attribute's index, or -1 if none matches.
197      * @see org.xml.sax.Attributes#getIndex(java.lang.String,java.lang.String)
198      */

199     public int getIndex (String JavaDoc uri, String JavaDoc localName)
200     {
201     int max = length * 5;
202     for (int i = 0; i < max; i += 5) {
203         if (data[i].equals(uri) && data[i+1].equals(localName)) {
204         return i / 5;
205         }
206     }
207     return -1;
208     }
209
210
211     /**
212      * Look up an attribute's index by qualified (prefixed) name.
213      *
214      * @param qName The qualified name.
215      * @return The attribute's index, or -1 if none matches.
216      * @see org.xml.sax.Attributes#getIndex(java.lang.String)
217      */

218     public int getIndex (String JavaDoc qName)
219     {
220     int max = length * 5;
221     for (int i = 0; i < max; i += 5) {
222         if (data[i+2].equals(qName)) {
223         return i / 5;
224         }
225     }
226     return -1;
227     }
228
229
230     /**
231      * Look up an attribute's type by Namespace-qualified name.
232      *
233      * @param uri The Namespace URI, or the empty string for a name
234      * with no explicit Namespace URI.
235      * @param localName The local name.
236      * @return The attribute's type, or null if there is no
237      * matching attribute.
238      * @see org.xml.sax.Attributes#getType(java.lang.String,java.lang.String)
239      */

240     public String JavaDoc getType (String JavaDoc uri, String JavaDoc localName)
241     {
242     int max = length * 5;
243     for (int i = 0; i < max; i += 5) {
244         if (data[i].equals(uri) && data[i+1].equals(localName)) {
245         return data[i+3];
246         }
247     }
248     return null;
249     }
250
251
252     /**
253      * Look up an attribute's type by qualified (prefixed) name.
254      *
255      * @param qName The qualified name.
256      * @return The attribute's type, or null if there is no
257      * matching attribute.
258      * @see org.xml.sax.Attributes#getType(java.lang.String)
259      */

260     public String JavaDoc getType (String JavaDoc qName)
261     {
262     int max = length * 5;
263     for (int i = 0; i < max; i += 5) {
264         if (data[i+2].equals(qName)) {
265         return data[i+3];
266         }
267     }
268     return null;
269     }
270
271
272     /**
273      * Look up an attribute's value by Namespace-qualified name.
274      *
275      * @param uri The Namespace URI, or the empty string for a name
276      * with no explicit Namespace URI.
277      * @param localName The local name.
278      * @return The attribute's value, or null if there is no
279      * matching attribute.
280      * @see org.xml.sax.Attributes#getValue(java.lang.String,java.lang.String)
281      */

282     public String JavaDoc getValue (String JavaDoc uri, String JavaDoc localName)
283     {
284     int max = length * 5;
285     for (int i = 0; i < max; i += 5) {
286         if (data[i].equals(uri) && data[i+1].equals(localName)) {
287         return data[i+4];
288         }
289     }
290     return null;
291     }
292
293
294     /**
295      * Look up an attribute's value by qualified (prefixed) name.
296      *
297      * @param qName The qualified name.
298      * @return The attribute's value, or null if there is no
299      * matching attribute.
300      * @see org.xml.sax.Attributes#getValue(java.lang.String)
301      */

302     public String JavaDoc getValue (String JavaDoc qName)
303     {
304     int max = length * 5;
305     for (int i = 0; i < max; i += 5) {
306         if (data[i+2].equals(qName)) {
307         return data[i+4];
308         }
309     }
310     return null;
311     }
312
313
314
315     ////////////////////////////////////////////////////////////////////
316
// Manipulators.
317
////////////////////////////////////////////////////////////////////
318

319
320     /**
321      * Clear the attribute list for reuse.
322      *
323      * <p>Note that little memory is freed by this call:
324      * the current array is kept so it can be
325      * reused.</p>
326      */

327     public void clear ()
328     {
329     if (data != null) {
330         for (int i = 0; i < (length * 5); i++)
331         data [i] = null;
332     }
333     length = 0;
334     }
335
336
337     /**
338      * Copy an entire Attributes object.
339      *
340      * <p>It may be more efficient to reuse an existing object
341      * rather than constantly allocating new ones.</p>
342      *
343      * @param atts The attributes to copy.
344      */

345     public void setAttributes (Attributes JavaDoc atts)
346     {
347         clear();
348         length = atts.getLength();
349         if (length > 0) {
350             data = new String JavaDoc[length*5];
351             for (int i = 0; i < length; i++) {
352                 data[i*5] = atts.getURI(i);
353                 data[i*5+1] = atts.getLocalName(i);
354                 data[i*5+2] = atts.getQName(i);
355                 data[i*5+3] = atts.getType(i);
356                 data[i*5+4] = atts.getValue(i);
357             }
358     }
359     }
360
361
362     /**
363      * Add an attribute to the end of the list.
364      *
365      * <p>For the sake of speed, this method does no checking
366      * to see if the attribute is already in the list: that is
367      * the responsibility of the application.</p>
368      *
369      * @param uri The Namespace URI, or the empty string if
370      * none is available or Namespace processing is not
371      * being performed.
372      * @param localName The local name, or the empty string if
373      * Namespace processing is not being performed.
374      * @param qName The qualified (prefixed) name, or the empty string
375      * if qualified names are not available.
376      * @param type The attribute type as a string.
377      * @param value The attribute value.
378      */

379     public void addAttribute (String JavaDoc uri, String JavaDoc localName, String JavaDoc qName,
380                   String JavaDoc type, String JavaDoc value)
381     {
382     ensureCapacity(length+1);
383     data[length*5] = uri;
384     data[length*5+1] = localName;
385     data[length*5+2] = qName;
386     data[length*5+3] = type;
387     data[length*5+4] = value;
388     length++;
389     }
390
391
392     /**
393      * Set an attribute in the list.
394      *
395      * <p>For the sake of speed, this method does no checking
396      * for name conflicts or well-formedness: such checks are the
397      * responsibility of the application.</p>
398      *
399      * @param index The index of the attribute (zero-based).
400      * @param uri The Namespace URI, or the empty string if
401      * none is available or Namespace processing is not
402      * being performed.
403      * @param localName The local name, or the empty string if
404      * Namespace processing is not being performed.
405      * @param qName The qualified name, or the empty string
406      * if qualified names are not available.
407      * @param type The attribute type as a string.
408      * @param value The attribute value.
409      * @exception java.lang.ArrayIndexOutOfBoundsException When the
410      * supplied index does not point to an attribute
411      * in the list.
412      */

413     public void setAttribute (int index, String JavaDoc uri, String JavaDoc localName,
414                   String JavaDoc qName, String JavaDoc type, String JavaDoc value)
415     {
416     if (index >= 0 && index < length) {
417         data[index*5] = uri;
418         data[index*5+1] = localName;
419         data[index*5+2] = qName;
420         data[index*5+3] = type;
421         data[index*5+4] = value;
422     } else {
423         badIndex(index);
424     }
425     }
426
427
428     /**
429      * Remove an attribute from the list.
430      *
431      * @param index The index of the attribute (zero-based).
432      * @exception java.lang.ArrayIndexOutOfBoundsException When the
433      * supplied index does not point to an attribute
434      * in the list.
435      */

436     public void removeAttribute (int index)
437     {
438     if (index >= 0 && index < length) {
439         if (index < length - 1) {
440         System.arraycopy(data, (index+1)*5, data, index*5,
441                  (length-index-1)*5);
442         }
443         index = (length - 1) * 5;
444         data [index++] = null;
445         data [index++] = null;
446         data [index++] = null;
447         data [index++] = null;
448         data [index] = null;
449         length--;
450     } else {
451         badIndex(index);
452     }
453     }
454
455
456     /**
457      * Set the Namespace URI of a specific attribute.
458      *
459      * @param index The index of the attribute (zero-based).
460      * @param uri The attribute's Namespace URI, or the empty
461      * string for none.
462      * @exception java.lang.ArrayIndexOutOfBoundsException When the
463      * supplied index does not point to an attribute
464      * in the list.
465      */

466     public void setURI (int index, String JavaDoc uri)
467     {
468     if (index >= 0 && index < length) {
469         data[index*5] = uri;
470     } else {
471         badIndex(index);
472     }
473     }
474
475
476     /**
477      * Set the local name of a specific attribute.
478      *
479      * @param index The index of the attribute (zero-based).
480      * @param localName The attribute's local name, or the empty
481      * string for none.
482      * @exception java.lang.ArrayIndexOutOfBoundsException When the
483      * supplied index does not point to an attribute
484      * in the list.
485      */

486     public void setLocalName (int index, String JavaDoc localName)
487     {
488     if (index >= 0 && index < length) {
489         data[index*5+1] = localName;
490     } else {
491         badIndex(index);
492     }
493     }
494
495
496     /**
497      * Set the qualified name of a specific attribute.
498      *
499      * @param index The index of the attribute (zero-based).
500      * @param qName The attribute's qualified name, or the empty
501      * string for none.
502      * @exception java.lang.ArrayIndexOutOfBoundsException When the
503      * supplied index does not point to an attribute
504      * in the list.
505      */

506     public void setQName (int index, String JavaDoc qName)
507     {
508     if (index >= 0 && index < length) {
509         data[index*5+2] = qName;
510     } else {
511         badIndex(index);
512     }
513     }
514
515
516     /**
517      * Set the type of a specific attribute.
518      *
519      * @param index The index of the attribute (zero-based).
520      * @param type The attribute's type.
521      * @exception java.lang.ArrayIndexOutOfBoundsException When the
522      * supplied index does not point to an attribute
523      * in the list.
524      */

525     public void setType (int index, String JavaDoc type)
526     {
527     if (index >= 0 && index < length) {
528         data[index*5+3] = type;
529     } else {
530         badIndex(index);
531     }
532     }
533
534
535     /**
536      * Set the value of a specific attribute.
537      *
538      * @param index The index of the attribute (zero-based).
539      * @param value The attribute's value.
540      * @exception java.lang.ArrayIndexOutOfBoundsException When the
541      * supplied index does not point to an attribute
542      * in the list.
543      */

544     public void setValue (int index, String JavaDoc value)
545     {
546     if (index >= 0 && index < length) {
547         data[index*5+4] = value;
548     } else {
549         badIndex(index);
550     }
551     }
552
553
554
555     ////////////////////////////////////////////////////////////////////
556
// Internal methods.
557
////////////////////////////////////////////////////////////////////
558

559
560     /**
561      * Ensure the internal array's capacity.
562      *
563      * @param n The minimum number of attributes that the array must
564      * be able to hold.
565      */

566     private void ensureCapacity (int n) {
567         if (n <= 0) {
568             return;
569         }
570         int max;
571         if (data == null || data.length == 0) {
572             max = 25;
573         }
574         else if (data.length >= n * 5) {
575             return;
576         }
577         else {
578             max = data.length;
579         }
580         while (max < n * 5) {
581             max *= 2;
582         }
583
584         String JavaDoc newData[] = new String JavaDoc[max];
585         if (length > 0) {
586             System.arraycopy(data, 0, newData, 0, length*5);
587         }
588         data = newData;
589     }
590
591
592     /**
593      * Report a bad array index in a manipulator.
594      *
595      * @param index The index to report.
596      * @exception java.lang.ArrayIndexOutOfBoundsException Always.
597      */

598     private void badIndex (int index)
599     throws ArrayIndexOutOfBoundsException JavaDoc
600     {
601     String JavaDoc msg =
602         "Attempt to modify attribute at illegal index: " + index;
603     throw new ArrayIndexOutOfBoundsException JavaDoc(msg);
604     }
605
606
607
608     ////////////////////////////////////////////////////////////////////
609
// Internal state.
610
////////////////////////////////////////////////////////////////////
611

612     int length;
613     String JavaDoc data [];
614
615 }
616
617 // end of AttributesImpl.java
618

619
Popular Tags