OSDN Git Service

Add some org packages.
[pf3gnuchains/gcc-fork.git] / libjava / org / xml / sax / helpers / AttributesImpl.java
1 // AttributesImpl.java - default implementation of Attributes.\r
2 // Written by David Megginson, sax@megginson.com\r
3 // NO WARRANTY!  This class is in the public domain.\r
4 \r
5 // $Id: AttributesImpl.java,v 1.2 2001/05/31 16:03:17 garyp Exp $\r
6 \r
7 \r
8 package org.xml.sax.helpers;\r
9 \r
10 import org.xml.sax.Attributes;\r
11 \r
12 \r
13 /**\r
14  * Default implementation of the Attributes interface.\r
15  *\r
16  * <blockquote>\r
17  * <em>This module, both source code and documentation, is in the\r
18  * Public Domain, and comes with <strong>NO WARRANTY</strong>.</em>\r
19  * </blockquote>\r
20  *\r
21  * <p>This class provides a default implementation of the SAX2\r
22  * {@link org.xml.sax.Attributes Attributes} interface, with the \r
23  * addition of manipulators so that the list can be modified or \r
24  * reused.</p>\r
25  *\r
26  * <p>There are two typical uses of this class:</p>\r
27  *\r
28  * <ol>\r
29  * <li>to take a persistent snapshot of an Attributes object\r
30  *  in a {@link org.xml.sax.ContentHandler#startElement startElement} event; or</li>\r
31  * <li>to construct or modify an Attributes object in a SAX2 driver or filter.</li>\r
32  * </ol>\r
33  *\r
34  * <p>This class replaces the now-deprecated SAX1 {@link \r
35  * org.xml.sax.helpers.AttributeListImpl AttributeListImpl}\r
36  * class; in addition to supporting the updated Attributes\r
37  * interface rather than the deprecated {@link org.xml.sax.AttributeList\r
38  * AttributeList} interface, it also includes a much more efficient \r
39  * implementation using a single array rather than a set of Vectors.</p>\r
40  *\r
41  * @since SAX 2.0\r
42  * @author David Megginson, \r
43  *         <a href="mailto:sax@megginson.com">sax@megginson.com</a>\r
44  * @version 2.0\r
45  */\r
46 public class AttributesImpl implements Attributes\r
47 {\r
48 \r
49 \f\r
50     ////////////////////////////////////////////////////////////////////\r
51     // Constructors.\r
52     ////////////////////////////////////////////////////////////////////\r
53 \r
54 \r
55     /**\r
56      * Construct a new, empty AttributesImpl object.\r
57      */\r
58     public AttributesImpl ()\r
59     {\r
60         length = 0;\r
61         data = null;\r
62     }\r
63 \r
64 \r
65     /**\r
66      * Copy an existing Attributes object.\r
67      *\r
68      * <p>This constructor is especially useful inside a\r
69      * {@link org.xml.sax.ContentHandler#startElement startElement} event.</p>\r
70      *\r
71      * @param atts The existing Attributes object.\r
72      */\r
73     public AttributesImpl (Attributes atts)\r
74     {\r
75         setAttributes(atts);\r
76     }\r
77 \r
78 \r
79 \f\r
80     ////////////////////////////////////////////////////////////////////\r
81     // Implementation of org.xml.sax.Attributes.\r
82     ////////////////////////////////////////////////////////////////////\r
83 \r
84 \r
85     /**\r
86      * Return the number of attributes in the list.\r
87      *\r
88      * @return The number of attributes in the list.\r
89      * @see org.xml.sax.Attributes#getLength\r
90      */\r
91     public int getLength ()\r
92     {\r
93         return length;\r
94     }\r
95 \r
96 \r
97     /**\r
98      * Return an attribute's Namespace URI.\r
99      *\r
100      * @param index The attribute's index (zero-based).\r
101      * @return The Namespace URI, the empty string if none is\r
102      *         available, or null if the index is out of range.\r
103      * @see org.xml.sax.Attributes#getURI\r
104      */\r
105     public String getURI (int index)\r
106     {\r
107         if (index >= 0 && index < length) {\r
108             return data[index*5];\r
109         } else {\r
110             return null;\r
111         }\r
112     }\r
113 \r
114 \r
115     /**\r
116      * Return an attribute's local name.\r
117      *\r
118      * @param index The attribute's index (zero-based).\r
119      * @return The attribute's local name, the empty string if \r
120      *         none is available, or null if the index if out of range.\r
121      * @see org.xml.sax.Attributes#getLocalName\r
122      */\r
123     public String getLocalName (int index)\r
124     {\r
125         if (index >= 0 && index < length) {\r
126             return data[index*5+1];\r
127         } else {\r
128             return null;\r
129         }\r
130     }\r
131 \r
132 \r
133     /**\r
134      * Return an attribute's qualified (prefixed) name.\r
135      *\r
136      * @param index The attribute's index (zero-based).\r
137      * @return The attribute's qualified name, the empty string if \r
138      *         none is available, or null if the index is out of bounds.\r
139      * @see org.xml.sax.Attributes#getQName\r
140      */\r
141     public String getQName (int index)\r
142     {\r
143         if (index >= 0 && index < length) {\r
144             return data[index*5+2];\r
145         } else {\r
146             return null;\r
147         }\r
148     }\r
149 \r
150 \r
151     /**\r
152      * Return an attribute's type by index.\r
153      *\r
154      * @param index The attribute's index (zero-based).\r
155      * @return The attribute's type, "CDATA" if the type is unknown, or null\r
156      *         if the index is out of bounds.\r
157      * @see org.xml.sax.Attributes#getType(int)\r
158      */\r
159     public String getType (int index)\r
160     {\r
161         if (index >= 0 && index < length) {\r
162             return data[index*5+3];\r
163         } else {\r
164             return null;\r
165         }\r
166     }\r
167 \r
168 \r
169     /**\r
170      * Return an attribute's value by index.\r
171      *\r
172      * @param index The attribute's index (zero-based).\r
173      * @return The attribute's value or null if the index is out of bounds.\r
174      * @see org.xml.sax.Attributes#getValue(int)\r
175      */\r
176     public String getValue (int index)\r
177     {\r
178         if (index >= 0 && index < length) {\r
179             return data[index*5+4];\r
180         } else {\r
181             return null;\r
182         }\r
183     }\r
184 \r
185 \r
186     /**\r
187      * Look up an attribute's index by Namespace name.\r
188      *\r
189      * <p>In many cases, it will be more efficient to look up the name once and\r
190      * use the index query methods rather than using the name query methods\r
191      * repeatedly.</p>\r
192      *\r
193      * @param uri The attribute's Namespace URI, or the empty\r
194      *        string if none is available.\r
195      * @param localName The attribute's local name.\r
196      * @return The attribute's index, or -1 if none matches.\r
197      * @see org.xml.sax.Attributes#getIndex(java.lang.String,java.lang.String)\r
198      */\r
199     public int getIndex (String uri, String localName)\r
200     {\r
201         int max = length * 5;\r
202         for (int i = 0; i < max; i += 5) {\r
203             if (data[i].equals(uri) && data[i+1].equals(localName)) {\r
204                 return i / 5;\r
205             }\r
206         } \r
207         return -1;\r
208     }\r
209 \r
210 \r
211     /**\r
212      * Look up an attribute's index by qualified (prefixed) name.\r
213      *\r
214      * @param qName The qualified name.\r
215      * @return The attribute's index, or -1 if none matches.\r
216      * @see org.xml.sax.Attributes#getIndex(java.lang.String)\r
217      */\r
218     public int getIndex (String qName)\r
219     {\r
220         int max = length * 5;\r
221         for (int i = 0; i < max; i += 5) {\r
222             if (data[i+2].equals(qName)) {\r
223                 return i / 5;\r
224             }\r
225         } \r
226         return -1;\r
227     }\r
228 \r
229 \r
230     /**\r
231      * Look up an attribute's type by Namespace-qualified name.\r
232      *\r
233      * @param uri The Namespace URI, or the empty string for a name\r
234      *        with no explicit Namespace URI.\r
235      * @param localName The local name.\r
236      * @return The attribute's type, or null if there is no\r
237      *         matching attribute.\r
238      * @see org.xml.sax.Attributes#getType(java.lang.String,java.lang.String)\r
239      */\r
240     public String getType (String uri, String localName)\r
241     {\r
242         int max = length * 5;\r
243         for (int i = 0; i < max; i += 5) {\r
244             if (data[i].equals(uri) && data[i+1].equals(localName)) {\r
245                 return data[i+3];\r
246             }\r
247         } \r
248         return null;\r
249     }\r
250 \r
251 \r
252     /**\r
253      * Look up an attribute's type by qualified (prefixed) name.\r
254      *\r
255      * @param qName The qualified name.\r
256      * @return The attribute's type, or null if there is no\r
257      *         matching attribute.\r
258      * @see org.xml.sax.Attributes#getType(java.lang.String)\r
259      */\r
260     public String getType (String qName)\r
261     {\r
262         int max = length * 5;\r
263         for (int i = 0; i < max; i += 5) {\r
264             if (data[i+2].equals(qName)) {\r
265                 return data[i+3];\r
266             }\r
267         }\r
268         return null;\r
269     }\r
270 \r
271 \r
272     /**\r
273      * Look up an attribute's value by Namespace-qualified name.\r
274      *\r
275      * @param uri The Namespace URI, or the empty string for a name\r
276      *        with no explicit Namespace URI.\r
277      * @param localName The local name.\r
278      * @return The attribute's value, or null if there is no\r
279      *         matching attribute.\r
280      * @see org.xml.sax.Attributes#getValue(java.lang.String,java.lang.String)\r
281      */\r
282     public String getValue (String uri, String localName)\r
283     {\r
284         int max = length * 5;\r
285         for (int i = 0; i < max; i += 5) {\r
286             if (data[i].equals(uri) && data[i+1].equals(localName)) {\r
287                 return data[i+4];\r
288             }\r
289         }\r
290         return null;\r
291     }\r
292 \r
293 \r
294     /**\r
295      * Look up an attribute's value by qualified (prefixed) name.\r
296      *\r
297      * @param qName The qualified name.\r
298      * @return The attribute's value, or null if there is no\r
299      *         matching attribute.\r
300      * @see org.xml.sax.Attributes#getValue(java.lang.String)\r
301      */\r
302     public String getValue (String qName)\r
303     {\r
304         int max = length * 5;\r
305         for (int i = 0; i < max; i += 5) {\r
306             if (data[i+2].equals(qName)) {\r
307                 return data[i+4];\r
308             }\r
309         }\r
310         return null;\r
311     }\r
312 \r
313 \r
314 \f\r
315     ////////////////////////////////////////////////////////////////////\r
316     // Manipulators.\r
317     ////////////////////////////////////////////////////////////////////\r
318 \r
319 \r
320     /**\r
321      * Clear the attribute list for reuse.\r
322      *\r
323      * <p>Note that no memory is actually freed by this call:\r
324      * the current arrays are kept so that they can be \r
325      * reused.</p>\r
326      */\r
327     public void clear ()\r
328     {\r
329         length = 0;\r
330     }\r
331 \r
332 \r
333     /**\r
334      * Copy an entire Attributes object.\r
335      *\r
336      * <p>It may be more efficient to reuse an existing object\r
337      * rather than constantly allocating new ones.</p>\r
338      * \r
339      * @param atts The attributes to copy.\r
340      */\r
341     public void setAttributes (Attributes atts)\r
342     {\r
343         clear();\r
344         length = atts.getLength();\r
345         data = new String[length*5]; \r
346         for (int i = 0; i < length; i++) {\r
347             data[i*5] = atts.getURI(i);\r
348             data[i*5+1] = atts.getLocalName(i);\r
349             data[i*5+2] = atts.getQName(i);\r
350             data[i*5+3] = atts.getType(i);\r
351             data[i*5+4] = atts.getValue(i);\r
352         }\r
353     }\r
354 \r
355 \r
356     /**\r
357      * Add an attribute to the end of the list.\r
358      *\r
359      * <p>For the sake of speed, this method does no checking\r
360      * to see if the attribute is already in the list: that is\r
361      * the responsibility of the application.</p>\r
362      *\r
363      * @param uri The Namespace URI, or the empty string if\r
364      *        none is available or Namespace processing is not\r
365      *        being performed.\r
366      * @param localName The local name, or the empty string if\r
367      *        Namespace processing is not being performed.\r
368      * @param qName The qualified (prefixed) name, or the empty string\r
369      *        if qualified names are not available.\r
370      * @param type The attribute type as a string.\r
371      * @param value The attribute value.\r
372      */\r
373     public void addAttribute (String uri, String localName, String qName,\r
374                               String type, String value)\r
375     {\r
376         ensureCapacity(length+1);\r
377         data[length*5] = uri;\r
378         data[length*5+1] = localName;\r
379         data[length*5+2] = qName;\r
380         data[length*5+3] = type;\r
381         data[length*5+4] = value;\r
382         length++;\r
383     }\r
384 \r
385 \r
386     /**\r
387      * Set an attribute in the list.\r
388      *\r
389      * <p>For the sake of speed, this method does no checking\r
390      * for name conflicts or well-formedness: such checks are the\r
391      * responsibility of the application.</p>\r
392      *\r
393      * @param index The index of the attribute (zero-based).\r
394      * @param uri The Namespace URI, or the empty string if\r
395      *        none is available or Namespace processing is not\r
396      *        being performed.\r
397      * @param localName The local name, or the empty string if\r
398      *        Namespace processing is not being performed.\r
399      * @param qName The qualified name, or the empty string\r
400      *        if qualified names are not available.\r
401      * @param type The attribute type as a string.\r
402      * @param value The attribute value.\r
403      * @exception java.lang.ArrayIndexOutOfBoundsException When the\r
404      *            supplied index does not point to an attribute\r
405      *            in the list.\r
406      */\r
407     public void setAttribute (int index, String uri, String localName,\r
408                               String qName, String type, String value)\r
409     {\r
410         if (index >= 0 && index < length) {\r
411             data[index*5] = uri;\r
412             data[index*5+1] = localName;\r
413             data[index*5+2] = qName;\r
414             data[index*5+3] = type;\r
415             data[index*5+4] = value;\r
416         } else {\r
417             badIndex(index);\r
418         }\r
419     }\r
420 \r
421 \r
422     /**\r
423      * Remove an attribute from the list.\r
424      *\r
425      * @param index The index of the attribute (zero-based).\r
426      * @exception java.lang.ArrayIndexOutOfBoundsException When the\r
427      *            supplied index does not point to an attribute\r
428      *            in the list.\r
429      */\r
430     public void removeAttribute (int index)\r
431     {\r
432         if (index >= 0 && index < length) {\r
433             data[index*5] = null;\r
434             data[index*5+1] = null;\r
435             data[index*5+2] = null;\r
436             data[index*5+3] = null;\r
437             data[index*5+4] = null;\r
438             if (index < length - 1) {\r
439                 System.arraycopy(data, (index+1)*5, data, index*5,\r
440                                  (length-index-1)*5);\r
441             }\r
442             length--;\r
443         } else {\r
444             badIndex(index);\r
445         }\r
446     }\r
447 \r
448 \r
449     /**\r
450      * Set the Namespace URI of a specific attribute.\r
451      *\r
452      * @param index The index of the attribute (zero-based).\r
453      * @param uri The attribute's Namespace URI, or the empty\r
454      *        string for none.\r
455      * @exception java.lang.ArrayIndexOutOfBoundsException When the\r
456      *            supplied index does not point to an attribute\r
457      *            in the list.\r
458      */\r
459     public void setURI (int index, String uri)\r
460     {\r
461         if (index >= 0 && index < length) {\r
462             data[index*5] = uri;\r
463         } else {\r
464             badIndex(index);\r
465         }\r
466     }\r
467 \r
468 \r
469     /**\r
470      * Set the local name of a specific attribute.\r
471      *\r
472      * @param index The index of the attribute (zero-based).\r
473      * @param localName The attribute's local name, or the empty\r
474      *        string for none.\r
475      * @exception java.lang.ArrayIndexOutOfBoundsException When the\r
476      *            supplied index does not point to an attribute\r
477      *            in the list.\r
478      */\r
479     public void setLocalName (int index, String localName)\r
480     {\r
481         if (index >= 0 && index < length) {\r
482             data[index*5+1] = localName;\r
483         } else {\r
484             badIndex(index);\r
485         }\r
486     }\r
487 \r
488 \r
489     /**\r
490      * Set the qualified name of a specific attribute.\r
491      *\r
492      * @param index The index of the attribute (zero-based).\r
493      * @param qName The attribute's qualified name, or the empty\r
494      *        string for none.\r
495      * @exception java.lang.ArrayIndexOutOfBoundsException When the\r
496      *            supplied index does not point to an attribute\r
497      *            in the list.\r
498      */\r
499     public void setQName (int index, String qName)\r
500     {\r
501         if (index >= 0 && index < length) {\r
502             data[index*5+2] = qName;\r
503         } else {\r
504             badIndex(index);\r
505         }\r
506     }\r
507 \r
508 \r
509     /**\r
510      * Set the type of a specific attribute.\r
511      *\r
512      * @param index The index of the attribute (zero-based).\r
513      * @param type The attribute's type.\r
514      * @exception java.lang.ArrayIndexOutOfBoundsException When the\r
515      *            supplied index does not point to an attribute\r
516      *            in the list.\r
517      */\r
518     public void setType (int index, String type)\r
519     {\r
520         if (index >= 0 && index < length) {\r
521             data[index*5+3] = type;\r
522         } else {\r
523             badIndex(index);\r
524         }\r
525     }\r
526 \r
527 \r
528     /**\r
529      * Set the value of a specific attribute.\r
530      *\r
531      * @param index The index of the attribute (zero-based).\r
532      * @param value The attribute's value.\r
533      * @exception java.lang.ArrayIndexOutOfBoundsException When the\r
534      *            supplied index does not point to an attribute\r
535      *            in the list.\r
536      */\r
537     public void setValue (int index, String value)\r
538     {\r
539         if (index >= 0 && index < length) {\r
540             data[index*5+4] = value;\r
541         } else {\r
542             badIndex(index);\r
543         }\r
544     }\r
545 \r
546 \r
547 \f\r
548     ////////////////////////////////////////////////////////////////////\r
549     // Internal methods.\r
550     ////////////////////////////////////////////////////////////////////\r
551 \r
552 \r
553     /**\r
554      * Ensure the internal array's capacity.\r
555      *\r
556      * @param n The minimum number of attributes that the array must\r
557      *        be able to hold.\r
558      */\r
559     private void ensureCapacity (int n)\r
560     {\r
561         if (n > 0 && data == null) {\r
562             data = new String[25];\r
563         }\r
564 \r
565         int max = data.length;\r
566         if (max >= n * 5) {\r
567             return;\r
568         }\r
569 \r
570 \r
571         while (max < n * 5) {\r
572             max *= 2;\r
573         }\r
574         String newData[] = new String[max];\r
575         System.arraycopy(data, 0, newData, 0, length*5);\r
576         data = newData;\r
577     }\r
578 \r
579 \r
580     /**\r
581      * Report a bad array index in a manipulator.\r
582      *\r
583      * @param index The index to report.\r
584      * @exception java.lang.ArrayIndexOutOfBoundsException Always.\r
585      */\r
586     private void badIndex (int index)\r
587         throws ArrayIndexOutOfBoundsException\r
588     {\r
589         String msg =\r
590             "Attempt to modify attribute at illegal index: " + index;\r
591         throw new ArrayIndexOutOfBoundsException(msg);\r
592     }\r
593 \r
594 \r
595 \f\r
596     ////////////////////////////////////////////////////////////////////\r
597     // Internal state.\r
598     ////////////////////////////////////////////////////////////////////\r
599 \r
600     int length;\r
601     String data [];\r
602 \r
603 }\r
604 \r
605 // end of AttributesImpl.java\r
606 \r