KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > icl > saxon > tree > AttributeCollection


1 package com.icl.saxon.tree;
2 import com.icl.saxon.om.*;
3 import org.xml.sax.Attributes JavaDoc;
4
5
6     /**
7     * AttributeCollection is an implementation of the SAX2 interface Attributes
8     * that also provides the ability to manipulate namespaces and to convert attributes
9     * into Nodes.
10     *
11     * It is extremely similar (both in interface and in implementation) to the SAX2 Attributes
12     * class, but was defined before SAX2 was available.
13     */

14
15 public final class AttributeCollection implements Attributes JavaDoc
16 {
17
18     // we use a single array for economy. The elements of this array are arranged
19
// in groups of three, being respectively the nameCode, the
20
// type, and the value
21

22     private NamePool namePool;
23     private Object JavaDoc[] list = null;
24     private int used = 0;
25
26     private static int RECSIZE = 3;
27     private static int NAMECODE = 0;
28     private static int TYPE = 1;
29     private static int VALUE = 2;
30
31     /**
32     * Create an empty attribute list.
33     */

34     
35     public AttributeCollection (NamePool pool) {
36         namePool = pool;
37         list = null;
38         used = 0;
39     }
40
41     /**
42     * Create an empty attribute list with space for n attributes
43     */

44     
45     public AttributeCollection (NamePool pool, int n) {
46         namePool = pool;
47         list = new Object JavaDoc[n*RECSIZE];
48         used = 0;
49     }
50
51     /**
52     * Create a new attribute collection as a clone
53     */

54
55     public AttributeCollection (AttributeCollection atts) {
56         this.namePool = atts.namePool;
57         this.list = new Object JavaDoc[atts.used];
58         if (atts.used > 0 ) {
59             System.arraycopy(atts.list, 0, this.list, 0, atts.used);
60         }
61         this.used = atts.used;
62     }
63
64     /**
65     * Create a new attribute collection as a clone
66     */

67
68     public AttributeCollection (NamePool pool, Attributes JavaDoc atts) {
69         namePool = pool;
70         int len = atts.getLength();
71         used = len*RECSIZE;
72         this.list = new Object JavaDoc[used];
73
74         for (int a=0; a<len; a++) {
75             int j = a*RECSIZE;
76             String JavaDoc qname = atts.getQName(a);
77             String JavaDoc prefix = Name.getPrefix(qname);
78             String JavaDoc uri = atts.getURI(a);
79             String JavaDoc localName = atts.getLocalName(a);
80             int nameCode = namePool.allocate(prefix, uri, localName);
81             list[j+NAMECODE] = new Integer JavaDoc(nameCode);
82             list[j+TYPE] = atts.getType(a);
83             list[j+VALUE] = atts.getValue(a);
84         }
85     }
86
87     /**
88     * Add an attribute to an attribute list.
89     * @param name The attribute name.
90     * @param type The attribute type ("NMTOKEN" for an enumeration).
91     * @param value The attribute value (must not be null).
92     * @see org.xml.sax.DocumentHandler#startElement
93     */

94     
95     public void addAttribute (int nameCode, String JavaDoc type, String JavaDoc value)
96     {
97        if (list==null) {
98             list = new Object JavaDoc[5*RECSIZE];
99             used = 0;
100         }
101         if (list.length == used) {
102             int newsize = (used==0 ? 5*RECSIZE : used*2);
103             Object JavaDoc[] newlist = new Object JavaDoc[newsize];
104             System.arraycopy(list, 0, newlist, 0, used);
105             list = newlist;
106         }
107         list[used++] = new Integer JavaDoc(nameCode);
108         list[used++] = type;
109         list[used++] = value;
110     }
111
112     /**
113     * Add an attribute to an attribute list.
114     * @param prefix The namespace prefix of the attribute name.
115     * @param uri The namespace uri of the attribute name.
116     * @param localname The local part of the attribute name.
117     * @param type The attribute type (e.g. "NMTOKEN").
118     * @param value The attribute value (must not be null).
119     * @see org.xml.sax.DocumentHandler#startElement
120     */

121     
122     public void addAttribute (String JavaDoc prefix, String JavaDoc uri, String JavaDoc localName, String JavaDoc type, String JavaDoc value)
123     {
124         addAttribute(namePool.allocate(prefix, uri, localName), type, value);
125     }
126
127     /**
128     * Set an attribute value
129     * @param name the name of the attribute
130     * @param type the type of the attribute (e.g. CDATA)
131     * @param value the value of the attribute
132     */

133
134     public void setAttribute(String JavaDoc prefix, String JavaDoc uri, String JavaDoc localName, String JavaDoc type, String JavaDoc value)
135     {
136         int nameCode = namePool.allocate(prefix, uri, localName);
137         int offset = findByFingerprint(nameCode&0xfffff);
138         if (offset<0) {
139             addAttribute(prefix, uri, localName, type, value);
140         } else {
141             list[offset + NAMECODE] = new Integer JavaDoc(nameCode);
142             list[offset + TYPE] = type;
143             list[offset + VALUE] = value;
144         }
145     }
146
147     /**
148     * Set an attribute value
149     * @param name the name of the attribute
150     * @param type the type of the attribute (e.g. CDATA)
151     * @param value the value of the attribute
152     */

153
154     public void setAttribute(int nameCode, String JavaDoc type, String JavaDoc value)
155     {
156         int offset = findByFingerprint(nameCode&0xfffff);
157         if (offset<0) {
158             addAttribute(nameCode, type, value);
159         } else {
160             list[offset + NAMECODE] = new Integer JavaDoc(nameCode);
161             list[offset + TYPE] = type;
162             list[offset + VALUE] = value;
163         }
164     }
165
166     /**
167     * Clear the attribute list.
168     */

169
170     public void clear ()
171     {
172         used = 0;
173     }
174
175     /**
176     * Compact the attribute list to avoid wasting memory
177     */

178
179     public void compact() {
180         if (used==0) {
181             list = null;
182         } else if (list.length > used) {
183             Object JavaDoc[] newlist = new Object JavaDoc[used];
184             System.arraycopy(list, 0, newlist, 0, used);
185             list = newlist;
186         }
187     }
188
189
190     //////////////////////////////////////////////////////////////////////
191
// Implementation of org.xml.sax.Attributes
192
//////////////////////////////////////////////////////////////////////
193

194
195     /**
196     * Return the number of attributes in the list.
197     * @return The number of attributes in the list.
198     */

199
200     public int getLength ()
201     {
202         return (list==null ? 0 : used / RECSIZE );
203     }
204
205     /**
206     * Get the namecode of an attribute (by position).
207     *
208     * @param i The position of the attribute in the list.
209     * @return The display name of the attribute as a string, or null if there
210     * is no attribute at that position.
211     */

212
213     public int getNameCode (int index)
214     {
215         int offset = index*RECSIZE;
216         if (list==null) return -1;
217         if (offset >= used) return -1;
218         
219         return ((Integer JavaDoc)list[offset+NAMECODE]).intValue();
220     }
221
222     /**
223     * Get the display name of an attribute (by position).
224     *
225     * @param i The position of the attribute in the list.
226     * @return The display name of the attribute as a string, or null if there
227     * is no attribute at that position.
228     */

229
230     public String JavaDoc getQName (int index)
231     {
232         int offset = index*RECSIZE;
233         if (list==null) return null;
234         if (offset >= used) return null;
235         return namePool.getDisplayName(getNameCode(index));
236     }
237
238     /**
239     * Get the local name of an attribute (by position).
240     *
241     * @param i The position of the attribute in the list.
242     * @return The local name of the attribute as a string, or null if there
243     * is no attribute at that position.
244     */

245
246     public String JavaDoc getLocalName (int index)
247     {
248         if (list==null) return null;
249         if (index*RECSIZE >= used) return null;
250         return namePool.getLocalName(getNameCode(index));
251     }
252
253     /**
254     * Get the namespace URI of an attribute (by position).
255     *
256     * @param index The position of the attribute in the list.
257     * @return The local name of the attribute as a string, or null if there
258     * is no attribute at that position.
259     */

260
261     public String JavaDoc getURI (int index)
262     {
263         if (list==null) return null;
264         if (index*RECSIZE >= used) return null;
265         return namePool.getURI(getNameCode(index));
266     }
267
268
269
270     /**
271     * Get the type of an attribute (by position).
272     * @param index The position of the attribute in the list.
273     * @return The attribute type as a string ("NMTOKEN" for an
274     * enumeration, and "CDATA" if no declaration was
275     * read), or null if there is no attribute at
276     * that position.
277     */

278     
279     public String JavaDoc getType (int index)
280     {
281         int offset = index*RECSIZE;
282         if (list==null) return null;
283         if (offset >= used) return null;
284         return (String JavaDoc)list[offset+TYPE];
285     }
286
287     /**
288     * Get the type of an attribute (by name).
289     *
290     * @param uri The namespace uri of the attribute.
291     * @param localname The local name of the attribute.
292     * @return The index position of the attribute
293     */

294     
295     public String JavaDoc getType (String JavaDoc uri, String JavaDoc localname)
296     {
297         int offset = findByName(uri, localname);
298         return ( offset<0 ? null : (String JavaDoc)list[offset+TYPE]);
299     }
300
301     /**
302     * Get the value of an attribute (by position).
303     *
304     * @param index The position of the attribute in the list.
305     * @return The attribute value as a string, or null if
306     * there is no attribute at that position.
307     */

308     
309     public String JavaDoc getValue (int index) {
310         int offset = index*RECSIZE;
311         if (list==null) return null;
312         if (offset >= used) return null;
313         return (String JavaDoc)list[offset+VALUE];
314     }
315
316     /**
317     * Get the value of an attribute (by name).
318     *
319     * @param uri The namespace uri of the attribute.
320     * @param localname The local name of the attribute.
321     * @return The index position of the attribute
322     */

323     
324     public String JavaDoc getValue (String JavaDoc uri, String JavaDoc localname)
325     {
326         int offset = findByName(uri, localname);
327         return ( offset<0 ? null : (String JavaDoc)list[offset+VALUE]);
328     }
329
330     /**
331     * Get the attribute value using its fingerprint
332     */

333     
334     public String JavaDoc getValueByFingerprint(int fingerprint) {
335         int offset = findByFingerprint(fingerprint);
336         return ( offset<0 ? null : (String JavaDoc)list[offset+VALUE]);
337     }
338
339     /**
340     * Get the index of an attribute (by name).
341     *
342     * @param name The display name of the attribute.
343     * @return The index position of the attribute
344     */

345     
346     public int getIndex (String JavaDoc name)
347     {
348         int offset = findByDisplayName(name);
349         return ( offset<0 ? -1 : offset / RECSIZE);
350     }
351
352     /**
353     * Get the index of an attribute (by name).
354     *
355     * @param uri The namespace uri of the attribute.
356     * @param localname The local name of the attribute.
357     * @return The index position of the attribute
358     */

359     
360     public int getIndex (String JavaDoc uri, String JavaDoc localname)
361     {
362         int offset = findByName(uri, localname);
363         return ( offset<0 ? -1 : offset / RECSIZE);
364     }
365
366     /**
367     * Get the index, given the fingerprint
368     */

369     
370     public int getIndexByFingerprint(int fingerprint) {
371         int offset = findByFingerprint(fingerprint);
372         return ( offset<0 ? -1 : offset / RECSIZE);
373     }
374
375     /**
376     * Get the type of an attribute (by name).
377     *
378     * @param name The display name of the attribute.
379     * @return The attribute type as a string ("NMTOKEN" for an
380     * enumeration, and "CDATA" if no declaration was
381     * read).
382     */

383     
384     public String JavaDoc getType (String JavaDoc name)
385     {
386         int offset = findByDisplayName(name);
387         return ( offset<0 ? null : (String JavaDoc)list[offset+TYPE]);
388     }
389
390
391     /**
392     * Get the value of an attribute (by name).
393     *
394     * @param name The attribute name.
395     */

396     
397     public String JavaDoc getValue (String JavaDoc name)
398     {
399         int offset = findByDisplayName(name);
400         return ( offset<0 ? null : (String JavaDoc)list[offset+VALUE]);
401     }
402
403     //////////////////////////////////////////////////////////////////////
404
// Additional methods for handling structured Names
405
//////////////////////////////////////////////////////////////////////
406

407     /**
408     * Find an attribute by name
409     * @return the offset of the attribute, or -1 if absent
410     */

411
412     private int findByName(String JavaDoc uri, String JavaDoc localName) {
413         if (namePool==null) return -1; // indicates an empty attribute set
414
int f = namePool.getFingerprint(uri, localName);
415         if (f==-1) return -1;
416         return findByFingerprint(f);
417     }
418
419     /**
420     * Find an attribute by fingerprint
421     * @return the offset of the attribute, or -1 if absent
422     */

423     
424     private int findByFingerprint(int fingerprint) {
425         if (list==null) return -1;
426         for (int i=0; i<used; i+=RECSIZE) {
427             if (fingerprint==(((Integer JavaDoc)list[i+NAMECODE]).intValue()&0xfffff)) {
428                 return i;
429             }
430         }
431         return -1;
432     }
433
434     /**
435     * Find an attribute by display name
436     * @return the offset of the attribute
437     */

438
439     private int findByDisplayName(String JavaDoc qname) {
440         if (list==null) return -1;
441         String JavaDoc prefix = Name.getPrefix(qname);
442         if (prefix.equals("")) {
443             return findByName("", qname);
444         } else {
445             String JavaDoc localName = Name.getLocalName(qname);
446             for (int i=0; i<getLength(); i++) {
447                 String JavaDoc lname=namePool.getLocalName(getNameCode(i));
448                 String JavaDoc ppref=namePool.getPrefix(getNameCode(i));
449                 if (localName.equals(lname) && prefix.equals(ppref)) {
450                     return i;
451                 }
452             }
453             return -1;
454         }
455     }
456     
457 }
458
459 //
460
// The contents of this file are subject to the Mozilla Public License Version 1.0 (the "License");
461
// you may not use this file except in compliance with the License. You may obtain a copy of the
462
// License at http://www.mozilla.org/MPL/
463
//
464
// Software distributed under the License is distributed on an "AS IS" basis,
465
// WITHOUT WARRANTY OF ANY KIND, either express or implied.
466
// See the License for the specific language governing rights and limitations under the License.
467
//
468
// The Original Code is: all this file.
469
//
470
// The Initial Developer of the Original Code is
471
// Michael Kay of International Computers Limited (mhkay@iclway.co.uk).
472
//
473
// Portions created by (your name) are Copyright (C) (your legal entity). All Rights Reserved.
474
//
475
// Contributor(s): none.
476
//
477
Popular Tags