KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > enhydra > apache > xerces > framework > XMLAttrList


1 /*
2  * The Apache Software License, Version 1.1
3  *
4  *
5  * Copyright (c) 1999,2000 The Apache Software Foundation. All rights
6  * reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  *
12  * 1. Redistributions of source code must retain the above copyright
13  * notice, this list of conditions and the following disclaimer.
14  *
15  * 2. Redistributions in binary form must reproduce the above copyright
16  * notice, this list of conditions and the following disclaimer in
17  * the documentation and/or other materials provided with the
18  * distribution.
19  *
20  * 3. The end-user documentation included with the redistribution,
21  * if any, must include the following acknowledgment:
22  * "This product includes software developed by the
23  * Apache Software Foundation (http://www.apache.org/)."
24  * Alternately, this acknowledgment may appear in the software itself,
25  * if and wherever such third-party acknowledgments normally appear.
26  *
27  * 4. The names "Xerces" and "Apache Software Foundation" must
28  * not be used to endorse or promote products derived from this
29  * software without prior written permission. For written
30  * permission, please contact apache@apache.org.
31  *
32  * 5. Products derived from this software may not be called "Apache",
33  * nor may "Apache" appear in their name, without prior written
34  * permission of the Apache Software Foundation.
35  *
36  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
37  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
38  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
39  * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
40  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
41  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
42  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
43  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
44  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
45  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
46  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
47  * SUCH DAMAGE.
48  * ====================================================================
49  *
50  * This software consists of voluntary contributions made by many
51  * individuals on behalf of the Apache Software Foundation and was
52  * originally based on software copyright (c) 1999, International
53  * Business Machines, Inc., http://www.apache.org. For more
54  * information on the Apache Software Foundation, please see
55  * <http://www.apache.org/>.
56  */

57
58 package org.enhydra.apache.xerces.framework;
59
60 import org.enhydra.apache.xerces.utils.QName;
61 import org.enhydra.apache.xerces.utils.StringPool;
62 import org.xml.sax.AttributeList JavaDoc;
63
64 /**
65  * An instance of this class is used to represent the set of attributes
66  * for an element that are either directly specified or provided through
67  * a default value in the grammar for the document. XMLAttrList carries
68  * the attributes associated with an element from the scanner up to the
69  * application level (via the SAX AtributeList). Because all the attributes
70  * are bundled up together before being presented to the application, we don't
71  * have a way to build up an attribute value from pieces, most notably entity
72  * references.
73  * <p>
74  * There is typically one instance of this class for each instance of a
75  * parser. The parser may either use this object to hold the attributes
76  * of a single element, calling releaseAttrList() before each new element,
77  * or it may use this object to hold the attributes of all of the elements
78  * in the document.
79  * <p>
80  * To start saving a new set of attributes, the startAttrList() method is
81  * called, returning a handle for the attribute list. All addAttr() calls
82  * will be added to the set until a call is made to endAttrList(). A handle
83  * of -1 is used to indicate that there are no attributes in the set.
84  * <p>
85  * When an attribute is added to the set, the type of the attribute and an
86  * indicator of whether it was specified explicitly or through a default is
87  * provided.
88  * <p>
89  * The attributes in the set may be accessed either through the getFirstAttr()
90  * and getNextAttr() iteration interface, or the getAttributeList() method
91  * may be used to access the attribute list through the SAX <code>AttributeList</code>
92  * interface.
93  *
94  * @version $Id: XMLAttrList.java,v 1.2 2005/01/26 08:28:44 jkjome Exp $
95  */

96 public final class XMLAttrList
97     implements AttributeList JavaDoc {
98
99     //
100
// Constants
101
//
102

103     // Chunk size constants
104

105     private static final int CHUNK_SHIFT = 5; // 2^5 = 32
106
private static final int CHUNK_SIZE = (1 << CHUNK_SHIFT);
107     private static final int CHUNK_MASK = CHUNK_SIZE - 1;
108     private static final int INITIAL_CHUNK_COUNT = (1 << (10 - CHUNK_SHIFT)); // 2^10 = 1k
109

110     // Flags (bits)
111

112     private static final int ATTFLAG_SPECIFIED = 1;
113     private static final int ATTFLAG_LASTATTR = 2;
114     private static final int ATTFLAG_NEEDSEARCH = 4;
115
116     //
117
// Data
118
//
119

120     // Instance variables
121

122     private StringPool fStringPool = null;
123     private int fCurrentHandle = -1;
124     private int fAttributeListHandle = -1;
125     private int fAttributeListLength = 0;
126     private int fAttrCount = 0;
127     private int[][] fAttPrefix = new int[INITIAL_CHUNK_COUNT][];
128     private int[][] fAttLocalpart = new int[INITIAL_CHUNK_COUNT][];
129     private int[][] fAttName = new int[INITIAL_CHUNK_COUNT][];
130     private int[][] fAttURI = new int[INITIAL_CHUNK_COUNT][];
131     private int[][] fAttValue = new int[INITIAL_CHUNK_COUNT][];
132     private int[][] fAttType = new int[INITIAL_CHUNK_COUNT][];
133     private byte[][] fAttFlags = new byte[INITIAL_CHUNK_COUNT][];
134
135     // utility
136

137     private QName fAttributeQName = new QName();
138
139     /**
140      * Constructor
141      *
142      * @param stringPool The string pool instance to use.
143      */

144     public XMLAttrList(StringPool stringPool) {
145         fStringPool = stringPool;
146     }
147
148     /**
149      * Reset this instance to an "empty" state.
150      *
151      * @param stringPool The string pool instance to use.
152      */

153     public void reset(StringPool stringPool) {
154         fStringPool = stringPool;
155         fCurrentHandle = -1;
156         fAttributeListHandle = -1;
157         fAttributeListLength = 0;
158         fAttrCount = 0;
159     }
160
161     public int addAttr(int attrName, int attValue,
162                        int attType, boolean specified, boolean search) throws Exception JavaDoc
163     {
164         fAttributeQName.setValues(-1, attrName, attrName);
165         return addAttr(fAttributeQName, attValue, attType, specified, search);
166     }
167     /**
168      * Add an attribute to the current set.
169      *
170      * @param attrName The name of the attribute, an index in the string pool.
171      * @param attValue The value of the attribute, an index in the string pool.
172      * @param attType The type of the attribute, an index in the string pool.
173      * @param specified <code>true</code> if the attribute is specified directly; otherwise
174      * <code>false</code> is the attribute is provided through a default.
175      * @param search <code>true</code> if the list should be searched for a duplicate.
176      * @return The index of this attribute; or -1 is <code>search</code> was <code>true</code>
177      * and <code>attrName</code> was already present.
178      */

179     public int addAttr(QName attribute,
180                        int attValue, int attType,
181                        boolean specified, boolean search) throws Exception JavaDoc {
182
183         int chunk;
184         int index;
185         if (search) {
186             chunk = fCurrentHandle >> CHUNK_SHIFT;
187             index = fCurrentHandle & CHUNK_MASK;
188             for (int attrIndex = fCurrentHandle; attrIndex < fAttrCount; attrIndex++) {
189                 // check on rawname, as required by XML1.0
190
// we check qname later in endAttrList
191
if (fStringPool.equalNames(fAttName[chunk][index], attribute.rawname)) {
192                     return -1;
193                 }
194                 if (++index == CHUNK_SIZE) {
195                     chunk++;
196                     index = 0;
197                 }
198             }
199         } else {
200             chunk = fAttrCount >> CHUNK_SHIFT;
201             index = fAttrCount & CHUNK_MASK;
202         }
203
204         ensureCapacity(chunk, index);
205         fAttPrefix[chunk][index] = attribute.prefix;
206         fAttLocalpart[chunk][index] = attribute.localpart;
207         fAttName[chunk][index] = attribute.rawname;
208         fAttURI[chunk][index] = attribute.uri;
209         fAttValue[chunk][index] = attValue;
210         fAttType[chunk][index] = attType;
211         fAttFlags[chunk][index] = (byte)((specified ? ATTFLAG_SPECIFIED : 0) | (search ? ATTFLAG_NEEDSEARCH : 0));
212         return fAttrCount++;
213
214     } // addAttr(QName,int,int,boolean,boolean):int
215

216     /**
217      * Start a new set of attributes.
218      *
219      * @return The handle for the new set of attributes.
220      */

221     public int startAttrList() {
222         fCurrentHandle = fAttrCount;
223         return fCurrentHandle;
224     }
225
226     /**
227      * Terminate the current set of attributes.
228      */

229     public int[] endAttrList() {
230         if (fCurrentHandle == -1)
231             return null;
232         int oldHandle = fCurrentHandle;
233
234         int attrIndex = fAttrCount - 1;
235         int chunk = attrIndex >> CHUNK_SHIFT;
236         int index = attrIndex & CHUNK_MASK;
237         fAttFlags[chunk][index] |= ATTFLAG_LASTATTR;
238         fCurrentHandle = -1;
239
240         int dupCount = 0;
241         int dupNames[] = null;
242
243         int attrIndex1 = oldHandle + 1, attrIndex2;
244         int chunk1 = attrIndex1 >> CHUNK_SHIFT;
245         int index1 = attrIndex1 & CHUNK_MASK;
246         int chunk2, index2;
247         for (; attrIndex1 < fAttrCount; attrIndex1++) {
248             if ((fAttFlags[chunk1][index1] & ATTFLAG_NEEDSEARCH) == 0)
249                 continue;
250             chunk2 = chunk1;
251             index2 = index1;
252             for (attrIndex2 = oldHandle; attrIndex2 < attrIndex1; attrIndex2++) {
253                 if (--index2 == -1) {
254                     chunk2--;
255                     index2 = CHUNK_SIZE-1;
256                 }
257                 if (fStringPool.equalNames(fAttURI[chunk1][index1], fAttURI[chunk2][index2]) &&
258                     fStringPool.equalNames(fAttLocalpart[chunk1][index1], fAttLocalpart[chunk2][index2])) {
259                     if (dupCount == 0)
260                         dupNames = new int[fAttrCount - oldHandle];
261                     dupNames[dupCount++] = fAttName[chunk1][index1];
262                 }
263             }
264             if (++index1 == CHUNK_SIZE) {
265                 chunk1++;
266                 index1 = 0;
267             }
268         }
269
270         if (dupCount > 0) {
271             int[] names = new int[dupCount];
272             System.arraycopy(dupNames, 0, names, 0, dupCount);
273             dupNames = names;
274         }
275
276         return dupNames;
277     }
278
279     /**
280      * Get the prefix of the attribute.
281      */

282     public int getAttrPrefix(int attrIndex) {
283         if (attrIndex < 0 || attrIndex >= fAttrCount)
284             return -1;
285         int chunk = attrIndex >> CHUNK_SHIFT;
286         int index = attrIndex & CHUNK_MASK;
287         return fAttPrefix[chunk][index];
288     }
289
290     /**
291      * Return the localpart of the attribute.
292      */

293     public int getAttrLocalpart(int attrIndex) {
294         if (attrIndex < 0 || attrIndex >= fAttrCount)
295             return -1;
296         int chunk = attrIndex >> CHUNK_SHIFT;
297         int index = attrIndex & CHUNK_MASK;
298         return fAttLocalpart[chunk][index];
299     }
300
301     // REVISIT: Should this be renamed "getAttrRawname" to match?
302
/**
303      * Get the name of the attribute
304      *
305      * @param attrIndex The index of the attribute.
306      * @return The name of the attribute, an index in the string pool.
307      */

308     public int getAttrName(int attrIndex) {
309         if (attrIndex < 0 || attrIndex >= fAttrCount)
310             return -1;
311         int chunk = attrIndex >> CHUNK_SHIFT;
312         int index = attrIndex & CHUNK_MASK;
313         return fAttName[chunk][index];
314     }
315
316     /** Sets the uri of the attribute. */
317     public void setAttrURI(int attrIndex, int uri) {
318         if (attrIndex < 0 || attrIndex >= fAttrCount)
319             return;
320         int chunk = attrIndex >> CHUNK_SHIFT;
321         int index = attrIndex & CHUNK_MASK;
322         fAttURI[chunk][index] = uri;
323     }
324
325     /** Return the uri of the attribute. */
326     public int getAttrURI(int attrIndex) {
327         if (attrIndex < 0 || attrIndex >= fAttrCount)
328             return -1;
329         int chunk = attrIndex >> CHUNK_SHIFT;
330         int index = attrIndex & CHUNK_MASK;
331         return fAttURI[chunk][index];
332     }
333
334     /**
335      * Get the value of the attribute
336      *
337      * @param attrIndex The index of the attribute.
338      * @return The value of the attribute, an index in the string pool.
339      */

340     public int getAttValue(int attrIndex) {
341         if (attrIndex < 0 || attrIndex >= fAttrCount)
342             return -1;
343         int chunk = attrIndex >> CHUNK_SHIFT;
344         int index = attrIndex & CHUNK_MASK;
345         return fAttValue[chunk][index];
346     }
347
348     /**
349      * Sets the value of the attribute.
350      */

351     public void setAttValue(int attrIndex, int attrValue) {
352         if (attrIndex < 0 || attrIndex >= fAttrCount)
353             return;
354         int chunk = attrIndex >> CHUNK_SHIFT;
355         int index = attrIndex & CHUNK_MASK;
356         fAttValue[chunk][index] = attrValue;
357     }
358
359     /** Sets the type of the attribute. */
360     public void setAttType(int attrIndex, int attTypeIndex) {
361         if (attrIndex < 0 || attrIndex >= fAttrCount)
362             return;
363         int chunk = attrIndex >> CHUNK_SHIFT;
364         int index = attrIndex & CHUNK_MASK;
365         fAttType[chunk][index] = attTypeIndex;
366     }
367
368     /**
369      * Get the type of the attribute
370      *
371      * @param attrIndex The index of the attribute.
372      * @return The type of the attribute, an index in the string pool.
373      */

374     public int getAttType(int attrIndex) {
375         if (attrIndex < 0 || attrIndex >= fAttrCount)
376             return -1;
377         int chunk = attrIndex >> CHUNK_SHIFT;
378         int index = attrIndex & CHUNK_MASK;
379         return fAttType[chunk][index];
380     }
381
382     /**
383      * Was the attribute explicitly supplied or was it provided through a default?
384      *
385      * @param attrIndex The index of the attribute.
386      * @return <code>true</code> if the attribute was specified directly; otherwise
387      * <code>false</code> is the attribute was provided through a default.
388      */

389     public boolean isSpecified(int attrIndex) {
390         if (attrIndex < 0 || attrIndex >= fAttrCount)
391             return true;
392         int chunk = attrIndex >> CHUNK_SHIFT;
393         int index = attrIndex & CHUNK_MASK;
394         return (fAttFlags[chunk][index] & ATTFLAG_SPECIFIED) != 0;
395     }
396
397     /**
398      * Make the resources of the current attribute list available for reuse.
399      *
400      * @param The attribute list handle.
401      */

402     public void releaseAttrList(int attrListHandle) {
403         if (attrListHandle == -1)
404             return;
405         int chunk = attrListHandle >> CHUNK_SHIFT;
406         int index = attrListHandle & CHUNK_MASK;
407         while (true) {
408             boolean last = (fAttFlags[chunk][index] & ATTFLAG_LASTATTR) != 0;
409             fAttPrefix[chunk][index] = -1;
410             fAttLocalpart[chunk][index] = -1;
411             fAttName[chunk][index] = -1;
412             fAttURI[chunk][index] = StringPool.EMPTY_STRING;
413             if ((fAttFlags[chunk][index] & ATTFLAG_SPECIFIED) != 0)
414                 fStringPool.releaseString(fAttValue[chunk][index]);
415             fAttValue[chunk][index] = -1;
416             if (++index == CHUNK_SIZE) {
417                 chunk++;
418                 index = 0;
419             }
420             if (last)
421                 break;
422         }
423         int lastIndex = (chunk << CHUNK_SHIFT) + index;
424         if (fAttrCount == lastIndex)
425             fAttrCount = attrListHandle;
426     }
427
428     /**
429      * Get the first attribute in the attribute list.
430      *
431      * @param attrListHandle The attribute list handle.
432      * @return The index of the first attribute in the specified
433      * attribute list or -1 if the handle is invalid.
434      */

435     public int getFirstAttr(int attrListHandle) {
436         if (attrListHandle < 0 || attrListHandle >= fAttrCount) {
437             return -1;
438         }
439         // the first attribute in a list is implemented as
440
// the same index of the attribute list handle
441
return attrListHandle;
442     }
443
444     /**
445      * Get the next attribute in the attribute list.
446      *
447      * @param attrIndex The attribute index.
448      * @return The index of the next attribute after <code>attrIndex</code> in
449      * the same attribute list or -1 if there is no next index.
450      */

451     public int getNextAttr(int attrIndex) {
452         if (attrIndex < 0 || attrIndex + 1 >= fAttrCount) {
453             return -1;
454         }
455         int chunk = attrIndex >> CHUNK_SHIFT;
456         int index = attrIndex & CHUNK_MASK;
457         if ((fAttFlags[chunk][index] & ATTFLAG_LASTATTR) != 0) {
458             return -1;
459         }
460         // attribute lists are implemented in the
461
// chunks one after another with the last
462
// attribute having a "last" flag set
463
return attrIndex + 1;
464     }
465
466     /* AttributeList support */
467
468     /**
469      * Setup this instance to respond as an <code>AttributeList</code> implementation.
470      *
471      * @return This instance as an <code>AttributeList</code>.
472      */

473     public AttributeList JavaDoc getAttributeList(int attrListHandle) {
474         fAttributeListHandle = attrListHandle;
475         if (fAttributeListHandle == -1)
476             fAttributeListLength = 0;
477         else {
478             int chunk = fAttributeListHandle >> CHUNK_SHIFT;
479             int index = fAttributeListHandle & CHUNK_MASK;
480             fAttributeListLength = 1;
481             while ((fAttFlags[chunk][index] & ATTFLAG_LASTATTR) == 0) {
482                 if (++index == CHUNK_SIZE) {
483                     chunk++;
484                     index = 0;
485                 }
486                 fAttributeListLength++;
487             }
488         }
489         return this;
490     }
491
492     /**
493      * Return the number of attributes in this list.
494      *
495      * <p>The SAX parser may provide attributes in any
496      * arbitrary order, regardless of the order in which they were
497      * declared or specified. The number of attributes may be
498      * zero.</p>
499      *
500      * @return The number of attributes in the list.
501      */

502     public int getLength() {
503         return fAttributeListLength;
504     }
505
506     /**
507      * Return the prefix of an attribute in this list (by position).
508      */

509     public String JavaDoc getPrefix(int i) {
510         if (i < 0 || i >= fAttributeListLength) {
511             return null;
512         }
513         int chunk = (fAttributeListHandle + i) >> CHUNK_SHIFT;
514         int index = (fAttributeListHandle + i) & CHUNK_MASK;
515         return fStringPool.toString(fAttPrefix[chunk][index]);
516     }
517
518     /**
519      * Return the local part of an attribute in this list (by position).
520      */

521     public String JavaDoc getLocalpart(int i) {
522         if (i < 0 || i >= fAttributeListLength) {
523             return null;
524         }
525         int chunk = (fAttributeListHandle + i) >> CHUNK_SHIFT;
526         int index = (fAttributeListHandle + i) & CHUNK_MASK;
527         return fStringPool.toString(fAttLocalpart[chunk][index]);
528     }
529
530     /**
531      * Return the name of an attribute in this list (by position).
532      *
533      * <p>The names must be unique: the SAX parser shall not include the
534      * same attribute twice. Attributes without values (those declared
535      * #IMPLIED without a value specified in the start tag) will be
536      * omitted from the list.</p>
537      *
538      * <p>If the attribute name has a namespace prefix, the prefix
539      * will still be attached.</p>
540      *
541      * @param i The index of the attribute in the list (starting at 0).
542      * @return The name of the indexed attribute, or null
543      * if the index is out of range.
544      * @see #getLength
545      */

546     public String JavaDoc getName(int i) {
547         if (i < 0 || i >= fAttributeListLength)
548             return null;
549         int chunk = (fAttributeListHandle + i) >> CHUNK_SHIFT;
550         int index = (fAttributeListHandle + i) & CHUNK_MASK;
551         return fStringPool.toString(fAttName[chunk][index]);
552     }
553
554     /** Returns the URI of an attribute in this list (by position). */
555     public String JavaDoc getURI(int i) {
556         if (i < 0 || i >= fAttributeListLength)
557             return null;
558         int chunk = (fAttributeListHandle + i) >> CHUNK_SHIFT;
559         int index = (fAttributeListHandle + i) & CHUNK_MASK;
560         return fStringPool.toString(fAttURI[chunk][index]);
561     }
562
563     /**
564      * Return the type of an attribute in the list (by position).
565      *
566      * <p>The attribute type is one of the strings "CDATA", "ID",
567      * "IDREF", "IDREFS", "NMTOKEN", "NMTOKENS", "ENTITY", "ENTITIES",
568      * or "NOTATION" (always in upper case).</p>
569      *
570      * <p>If the parser has not read a declaration for the attribute,
571      * or if the parser does not report attribute types, then it must
572      * return the value "CDATA" as stated in the XML 1.0 Recommentation
573      * (clause 3.3.3, "Attribute-Value Normalization").</p>
574      *
575      * <p>For an enumerated attribute that is not a notation, the
576      * parser will report the type as "NMTOKEN".</p>
577      *
578      * @param i The index of the attribute in the list (starting at 0).
579      * @return The attribute type as a string, or
580      * null if the index is out of range.
581      * @see #getLength
582      * @see #getType(java.lang.String)
583      */

584     public String JavaDoc getType(int i) {
585         if (i < 0 || i >= fAttributeListLength)
586             return null;
587         int chunk = (fAttributeListHandle + i) >> CHUNK_SHIFT;
588         int index = (fAttributeListHandle + i) & CHUNK_MASK;
589         int attType = fAttType[chunk][index];
590         if (attType == fStringPool.addSymbol("ENUMERATION"))
591             attType = fStringPool.addSymbol("NMTOKEN");
592         return fStringPool.toString(attType);
593     }
594
595     /**
596      * Return the value of an attribute in the list (by position).
597      *
598      * <p>If the attribute value is a list of tokens (IDREFS,
599      * ENTITIES, or NMTOKENS), the tokens will be concatenated
600      * into a single string separated by whitespace.</p>
601      *
602      * @param i The index of the attribute in the list (starting at 0).
603      * @return The attribute value as a string, or
604      * null if the index is out of range.
605      * @see #getLength
606      * @see #getValue(java.lang.String)
607      */

608     public String JavaDoc getValue(int i) {
609         if (i < 0 || i >= fAttributeListLength)
610             return null;
611         int chunk = (fAttributeListHandle + i) >> CHUNK_SHIFT;
612         int index = (fAttributeListHandle + i) & CHUNK_MASK;
613         return fStringPool.toString(fAttValue[chunk][index]);
614     }
615
616     /**
617      * Return the type of an attribute in the list (by name).
618      *
619      * <p>The return value is the same as the return value for
620      * getType(int).</p>
621      *
622      * <p>If the attribute name has a namespace prefix in the document,
623      * the application must include the prefix here.</p>
624      *
625      * @param name The name of the attribute.
626      * @return The attribute type as a string, or null if no
627      * such attribute exists.
628      * @see #getType(int)
629      */

630     public String JavaDoc getType(String JavaDoc name) {
631         int nameIndex = fStringPool.addSymbol(name);
632         if (nameIndex == -1)
633             return null;
634         int chunk = fAttributeListHandle >> CHUNK_SHIFT;
635         int index = fAttributeListHandle & CHUNK_MASK;
636         for (int i = 0; i < fAttributeListLength; i++) {
637             if (fStringPool.equalNames(fAttName[chunk][index], nameIndex)) {
638                 int attType = fAttType[chunk][index];
639                 if (attType == fStringPool.addSymbol("ENUMERATION"))
640                     attType = fStringPool.addSymbol("NMTOKEN");
641                 return fStringPool.toString(attType);
642             }
643             if (++index == CHUNK_SIZE) {
644                 chunk++;
645                 index = 0;
646             }
647         }
648         return null;
649     }
650
651     /**
652      * Return the value of an attribute in the list (by name).
653      *
654      * <p>The return value is the same as the return value for
655      * getValue(int).</p>
656      *
657      * <p>If the attribute name has a namespace prefix in the document,
658      * the application must include the prefix here.</p>
659      *
660      * @param i The index of the attribute in the list.
661      * @return The attribute value as a string, or null if
662      * no such attribute exists.
663      * @see #getValue(int)
664      */

665     public String JavaDoc getValue(String JavaDoc name) {
666         int nameIndex = fStringPool.addSymbol(name);
667         if (nameIndex == -1)
668             return null;
669         int chunk = fAttributeListHandle >> CHUNK_SHIFT;
670         int index = fAttributeListHandle & CHUNK_MASK;
671         for (int i = 0; i < fAttributeListLength; i++) {
672             if (fStringPool.equalNames(fAttName[chunk][index], nameIndex))
673                 return fStringPool.toString(fAttValue[chunk][index]);
674             if (++index == CHUNK_SIZE) {
675                 chunk++;
676                 index = 0;
677             }
678         }
679         return null;
680     }
681
682     //
683
// Private methods
684
//
685

686     /* Expand our internal data structures as needed. */
687     private void ensureCapacity(int chunk, int index) {
688           if (chunk >= fAttPrefix.length) {
689             int[][] newIntArray = new int[chunk * 2][];
690             System.arraycopy(fAttPrefix, 0, newIntArray, 0, chunk);
691             fAttPrefix = newIntArray;
692             newIntArray = new int[chunk * 2][];
693             System.arraycopy(fAttLocalpart, 0, newIntArray, 0, chunk);
694             fAttLocalpart = newIntArray;
695             newIntArray = new int[chunk * 2][];
696             System.arraycopy(fAttName, 0, newIntArray, 0, chunk);
697             fAttName = newIntArray;
698             newIntArray = new int[chunk * 2][];
699             System.arraycopy(fAttURI, 0, newIntArray, 0, chunk);
700             fAttURI = newIntArray;
701             newIntArray = new int[chunk * 2][];
702             System.arraycopy(fAttValue, 0, newIntArray, 0, chunk);
703             fAttValue = newIntArray;
704             newIntArray = new int[chunk * 2][];
705             System.arraycopy(fAttType, 0, newIntArray, 0, chunk);
706             fAttType = newIntArray;
707             byte[][] newByteArray = new byte[chunk * 2][];
708             System.arraycopy(fAttFlags, 0, newByteArray, 0, chunk);
709             fAttFlags = newByteArray;
710         }
711         else if (fAttPrefix[chunk] != null) {
712             return;
713         }
714         fAttPrefix[chunk] = new int[CHUNK_SIZE];
715         fAttLocalpart[chunk] = new int[CHUNK_SIZE];
716         fAttName[chunk] = new int[CHUNK_SIZE];
717         fAttURI[chunk] = new int[CHUNK_SIZE];
718         fAttValue[chunk] = new int[CHUNK_SIZE];
719         fAttType[chunk] = new int[CHUNK_SIZE];
720         fAttFlags[chunk] = new byte[CHUNK_SIZE];
721         return;
722
723     } // ensureCapacity(int,int):void
724

725 } // class XMLAttrList
726
Popular Tags