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