KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sun > xml > fastinfoset > util > PrefixArray


1 /*
2  * Fast Infoset ver. 0.1 software ("Software")
3  *
4  * Copyright, 2004-2005 Sun Microsystems, Inc. All Rights Reserved.
5  *
6  * Software is licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License. You may
8  * obtain a copy of the License at:
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
14  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
15  * License for the specific language governing permissions and limitations.
16  *
17  * Sun supports and benefits from the global community of open source
18  * developers, and thanks the community for its important contributions and
19  * open standards-based technology, which Sun has adopted into many of its
20  * products.
21  *
22  * Please note that portions of Software may be provided with notices and
23  * open source licenses from such communities and third parties that govern the
24  * use of those portions, and any licenses granted hereunder do not alter any
25  * rights and obligations you may have under such open source licenses,
26  * however, the disclaimer of warranty and limitation of liability provisions
27  * in this License will apply to all Software in this distribution.
28  *
29  * You acknowledge that the Software is not designed, licensed or intended
30  * for use in the design, construction, operation or maintenance of any nuclear
31  * facility.
32  *
33  * Apache License
34  * Version 2.0, January 2004
35  * http://www.apache.org/licenses/
36  *
37  */

38
39
40 package com.sun.xml.fastinfoset.util;
41
42 import com.sun.xml.fastinfoset.EncodingConstants;
43 import com.sun.xml.fastinfoset.CommonResourceBundle;
44 import java.util.Iterator JavaDoc;
45 import java.util.NoSuchElementException JavaDoc;
46 import org.jvnet.fastinfoset.FastInfosetException;
47
48 public class PrefixArray extends ValueArray {
49     public static final int PREFIX_MAP_SIZE = 64;
50     
51     private int _initialCapacity;
52     
53     public String JavaDoc[] _array;
54     
55     private PrefixArray _readOnlyArray;
56
57     private static class PrefixEntry {
58         private PrefixEntry next;
59         private int prefixId;
60     }
61
62     private PrefixEntry[] _prefixMap = new PrefixEntry[PREFIX_MAP_SIZE];
63     
64     private PrefixEntry _prefixPool;
65     
66     private static class NamespaceEntry {
67         private NamespaceEntry next;
68         private int declarationId;
69         private int namespaceIndex;
70         
71         private String JavaDoc prefix;
72         private String JavaDoc namespaceName;
73         private int prefixEntryIndex;
74     }
75
76     private NamespaceEntry _namespacePool;
77     
78     private NamespaceEntry[] _inScopeNamespaces;
79     
80     public int[] _currentInScope;
81     
82     public int _declarationId;
83     
84     public PrefixArray(int initialCapacity, int maximumCapacity) {
85         _initialCapacity = initialCapacity;
86         _maximumCapacity = maximumCapacity;
87         
88         _array = new String JavaDoc[initialCapacity];
89         // Sizes of _inScopeNamespaces and _currentInScope need to be two
90
// greater than _array because 0 represents the empty string and
91
// 1 represents the xml prefix
92
_inScopeNamespaces = new NamespaceEntry[initialCapacity + 2];
93         _currentInScope = new int[initialCapacity + 2];
94         
95         increaseNamespacePool(initialCapacity);
96         increasePrefixPool(initialCapacity);
97         
98         initializeEntries();
99     }
100
101     public PrefixArray() {
102         this(DEFAULT_CAPACITY, MAXIMUM_CAPACITY);
103     }
104
105     private final void initializeEntries() {
106         _inScopeNamespaces[0] = _namespacePool;
107         _namespacePool = _namespacePool.next;
108         _inScopeNamespaces[0].next = null;
109         _inScopeNamespaces[0].prefix = "";
110         _inScopeNamespaces[0].namespaceName = "";
111         _inScopeNamespaces[0].namespaceIndex = _currentInScope[0] = 0;
112         
113         int index = KeyIntMap.indexFor(KeyIntMap.hashHash(_inScopeNamespaces[0].prefix.hashCode()), _prefixMap.length);
114         _prefixMap[index] = _prefixPool;
115         _prefixPool = _prefixPool.next;
116         _prefixMap[index].next = null;
117         _prefixMap[index].prefixId = 0;
118         
119         
120         _inScopeNamespaces[1] = _namespacePool;
121         _namespacePool = _namespacePool.next;
122         _inScopeNamespaces[1].next = null;
123         _inScopeNamespaces[1].prefix = EncodingConstants.XML_NAMESPACE_PREFIX;
124         _inScopeNamespaces[1].namespaceName = EncodingConstants.XML_NAMESPACE_NAME;
125         _inScopeNamespaces[1].namespaceIndex = _currentInScope[1] = 1;
126         
127         index = KeyIntMap.indexFor(KeyIntMap.hashHash(_inScopeNamespaces[1].prefix.hashCode()), _prefixMap.length);
128         if (_prefixMap[index] == null) {
129             _prefixMap[index] = _prefixPool;
130             _prefixPool = _prefixPool.next;
131             _prefixMap[index].next = null;
132         } else {
133             final PrefixEntry e = _prefixMap[index];
134             _prefixMap[index] = _prefixPool;
135             _prefixPool = _prefixPool.next;
136             _prefixMap[index].next = e;
137         }
138         _prefixMap[index].prefixId = 1;
139     }
140     
141     private final void increaseNamespacePool(int capacity) {
142         if (_namespacePool == null) {
143             _namespacePool = new NamespaceEntry();
144         }
145         
146         for (int i = 0; i < capacity; i++) {
147             NamespaceEntry ne = new NamespaceEntry();
148             ne.next = _namespacePool;
149             _namespacePool = ne;
150         }
151     }
152     
153     private final void increasePrefixPool(int capacity) {
154         if (_prefixPool == null) {
155             _prefixPool = new PrefixEntry();
156         }
157         
158         for (int i = 0; i < capacity; i++) {
159             PrefixEntry pe = new PrefixEntry();
160             pe.next = _prefixPool;
161             _prefixPool = pe;
162         }
163     }
164
165     public int countNamespacePool() {
166         int i = 0;
167         NamespaceEntry e = _namespacePool;
168         while (e != null) {
169             i++;
170             e = e.next;
171         }
172         return i;
173     }
174     
175     public int countPrefixPool() {
176         int i = 0;
177         PrefixEntry e = _prefixPool;
178         while (e != null) {
179             i++;
180             e = e.next;
181         }
182         return i;
183     }
184     
185     public final void clear() {
186         for (int i = _readOnlyArraySize; i < _size; i++) {
187             _array[i] = null;
188         }
189         _size = _readOnlyArraySize;
190     }
191
192     public final void clearCompletely() {
193         _prefixPool = null;
194         _namespacePool = null;
195         
196         for (int i = 0; i < _size + 2; i++) {
197             _currentInScope[i] = 0;
198             _inScopeNamespaces[i] = null;
199         }
200         
201         for (int i = 0; i < _prefixMap.length; i++) {
202             _prefixMap[i] = null;
203         }
204                 
205         increaseNamespacePool(_initialCapacity);
206         increasePrefixPool(_initialCapacity);
207         
208         initializeEntries();
209         
210         _declarationId = 0;
211         
212         clear();
213     }
214     
215     public final String JavaDoc[] getArray() {
216         return _array;
217     }
218     
219     public final void setReadOnlyArray(ValueArray readOnlyArray, boolean clear) {
220         if (!(readOnlyArray instanceof PrefixArray)) {
221             throw new IllegalArgumentException JavaDoc(CommonResourceBundle.getInstance().
222                     getString("message.illegalClass", new Object JavaDoc[]{readOnlyArray}));
223         }
224         
225         setReadOnlyArray((PrefixArray)readOnlyArray, clear);
226     }
227
228     public final void setReadOnlyArray(PrefixArray readOnlyArray, boolean clear) {
229         if (readOnlyArray != null) {
230             _readOnlyArray = readOnlyArray;
231             _readOnlyArraySize = readOnlyArray.getSize();
232             
233             // Resize according to size of read only arrays
234
_inScopeNamespaces = new NamespaceEntry[_readOnlyArraySize + _inScopeNamespaces.length];
235             _currentInScope = new int[_readOnlyArraySize + _currentInScope.length];
236             // Intialize first two entries
237
initializeEntries();
238             
239             if (clear) {
240                 clear();
241             }
242
243             _array = getCompleteArray();
244             _size = _readOnlyArraySize;
245         }
246     }
247
248     public final String JavaDoc[] getCompleteArray() {
249         if (_readOnlyArray == null) {
250             return _array;
251         } else {
252             final String JavaDoc[] ra = _readOnlyArray.getCompleteArray();
253             final String JavaDoc[] a = new String JavaDoc[_readOnlyArraySize + _array.length];
254             System.arraycopy(ra, 0, a, 0, _readOnlyArraySize);
255             return a;
256         }
257     }
258     
259     public final String JavaDoc get(int i) {
260         return _array[i];
261    }
262  
263     public final int add(String JavaDoc s) {
264         if (_size == _array.length) {
265             resize();
266         }
267             
268        _array[_size++] = s;
269        return _size;
270     }
271     
272     protected final void resize() {
273         if (_size == _maximumCapacity) {
274             throw new ValueArrayResourceException(CommonResourceBundle.getInstance().getString("message.arrayMaxCapacity"));
275         }
276
277         int newSize = _size * 3 / 2 + 1;
278         if (newSize > _maximumCapacity) {
279             newSize = _maximumCapacity;
280         }
281
282         final String JavaDoc[] newArray = new String JavaDoc[newSize];
283         System.arraycopy(_array, 0, newArray, 0, _size);
284         _array = newArray;
285
286         newSize += _readOnlyArraySize;
287         final NamespaceEntry[] newInScopeNamespaces = new NamespaceEntry[newSize + 2];
288         System.arraycopy(_inScopeNamespaces, 0, newInScopeNamespaces, 0, _readOnlyArraySize + _size + 2);
289         _inScopeNamespaces = newInScopeNamespaces;
290
291         final int[] newCurrentInScope = new int[newSize + 2];
292         System.arraycopy(_currentInScope, 0, newCurrentInScope, 0, _readOnlyArraySize + _size + 2);
293         _currentInScope = newCurrentInScope;
294     }
295     
296     public final void clearDeclarationIds() {
297         for (int i = 0; i < _size; i++) {
298             final NamespaceEntry e = _inScopeNamespaces[i];
299             if (e != null) {
300                 e.declarationId = 0;
301             }
302         }
303
304         _declarationId = 1;
305     }
306     
307     public final void pushScope(int prefixIndex, int namespaceIndex) throws FastInfosetException {
308         if (_namespacePool == null) {
309             increaseNamespacePool(16);
310         }
311         
312         final NamespaceEntry e = _namespacePool;
313         _namespacePool = e.next;
314
315         final NamespaceEntry current = _inScopeNamespaces[++prefixIndex];
316         if (current == null) {
317             e.declarationId = _declarationId;
318             e.namespaceIndex = _currentInScope[prefixIndex] = ++namespaceIndex;
319             e.next = null;
320             
321             _inScopeNamespaces[prefixIndex] = e;
322         } else if (current.declarationId < _declarationId) {
323             e.declarationId = _declarationId;
324             e.namespaceIndex = _currentInScope[prefixIndex] = ++namespaceIndex;
325             e.next = current;
326             
327             current.declarationId = 0;
328             _inScopeNamespaces[prefixIndex] = e;
329         } else {
330             throw new FastInfosetException(CommonResourceBundle.getInstance().getString("message.duplicateNamespaceAttribute"));
331         }
332     }
333     
334     public final void pushScopeWithPrefixEntry(String JavaDoc prefix, String JavaDoc namespaceName,
335             int prefixIndex, int namespaceIndex) throws FastInfosetException {
336         if (_namespacePool == null) {
337             increaseNamespacePool(16);
338         }
339         if (_prefixPool == null) {
340             increasePrefixPool(16);
341         }
342         
343         final NamespaceEntry e = _namespacePool;
344         _namespacePool = e.next;
345
346         final NamespaceEntry current = _inScopeNamespaces[++prefixIndex];
347         if (current == null) {
348             e.declarationId = _declarationId;
349             e.namespaceIndex = _currentInScope[prefixIndex] = ++namespaceIndex;
350             e.next = null;
351             
352             _inScopeNamespaces[prefixIndex] = e;
353         } else if (current.declarationId < _declarationId) {
354             e.declarationId = _declarationId;
355             e.namespaceIndex = _currentInScope[prefixIndex] = ++namespaceIndex;
356             e.next = current;
357             
358             current.declarationId = 0;
359             _inScopeNamespaces[prefixIndex] = e;
360         } else {
361             throw new FastInfosetException(CommonResourceBundle.getInstance().getString("message.duplicateNamespaceAttribute"));
362         }
363  
364         final PrefixEntry p = _prefixPool;
365         _prefixPool = _prefixPool.next;
366         p.prefixId = prefixIndex;
367                 
368         e.prefix = prefix;
369         e.namespaceName = namespaceName;
370         e.prefixEntryIndex = KeyIntMap.indexFor(KeyIntMap.hashHash(prefix.hashCode()), _prefixMap.length);
371         
372         final PrefixEntry pCurrent = _prefixMap[e.prefixEntryIndex];
373         p.next = pCurrent;
374         _prefixMap[e.prefixEntryIndex] = p;
375     }
376     
377     public final void popScope(int prefixIndex) {
378         final NamespaceEntry e = _inScopeNamespaces[++prefixIndex];
379         _inScopeNamespaces[prefixIndex] = e.next;
380         _currentInScope[prefixIndex] = (e.next != null) ? e.next.namespaceIndex : 0;
381         
382         e.next = _namespacePool;
383         _namespacePool = e;
384     }
385
386     public final void popScopeWithPrefixEntry(int prefixIndex) {
387         final NamespaceEntry e = _inScopeNamespaces[++prefixIndex];
388         
389         _inScopeNamespaces[prefixIndex] = e.next;
390         _currentInScope[prefixIndex] = (e.next != null) ? e.next.namespaceIndex : 0;
391         
392         e.prefix = e.namespaceName = null;
393         e.next = _namespacePool;
394         _namespacePool = e;
395         
396         PrefixEntry current = _prefixMap[e.prefixEntryIndex];
397         if (current.prefixId == prefixIndex) {
398             _prefixMap[e.prefixEntryIndex] = current.next;
399             current.next = _prefixPool;
400             _prefixPool = current;
401         } else {
402             PrefixEntry prev = current;
403             current = current.next;
404             while (current != null) {
405                 if (current.prefixId == prefixIndex) {
406                     prev.next = current.next;
407                     current.next = _prefixPool;
408                     _prefixPool = current;
409                     break;
410                 }
411                 prev = current;
412                 current = current.next;
413             }
414         }
415     }
416     
417     public final String JavaDoc getNamespaceFromPrefix(String JavaDoc prefix) {
418         final int index = KeyIntMap.indexFor(KeyIntMap.hashHash(prefix.hashCode()), _prefixMap.length);
419         PrefixEntry pe = _prefixMap[index];
420         while (pe != null) {
421             final NamespaceEntry ne = _inScopeNamespaces[pe.prefixId];
422             if (prefix == ne.prefix || prefix.equals(ne.prefix)) {
423                 return ne.namespaceName;
424             }
425             pe = pe.next;
426         }
427         
428         return null;
429     }
430     
431     public final String JavaDoc getPrefixFromNamespace(String JavaDoc namespaceName) {
432         int position = 0;
433         while (++position < _size + 2) {
434             final NamespaceEntry ne = _inScopeNamespaces[position];
435             if (ne != null && namespaceName.equals(ne.namespaceName)) {
436                 return ne.prefix;
437             }
438         }
439         
440         return null;
441     }
442     
443     public final Iterator JavaDoc getPrefixes() {
444         return new Iterator JavaDoc() {
445             int _position = 1;
446             NamespaceEntry _ne = _inScopeNamespaces[_position];
447             
448             public boolean hasNext() {
449                 return _ne != null;
450             }
451             
452             public Object JavaDoc next() {
453                 if (_position == _size + 2) {
454                     throw new NoSuchElementException JavaDoc();
455                 }
456                 
457                 final String JavaDoc prefix = _ne.prefix;
458                 moveToNext();
459                 return prefix;
460             }
461             
462             public void remove() {
463                 throw new UnsupportedOperationException JavaDoc();
464             }
465             
466             private final void moveToNext() {
467                 while (++_position < _size + 2) {
468                     _ne = _inScopeNamespaces[_position];
469                     if (_ne != null) {
470                         return;
471                     }
472                 }
473                 _ne = null;
474             }
475             
476         };
477     }
478     
479     public final Iterator JavaDoc getPrefixesFromNamespace(final String JavaDoc namespaceName) {
480         return new Iterator JavaDoc() {
481             String JavaDoc _namespaceName = namespaceName;
482             int _position = 0;
483             NamespaceEntry _ne;
484             
485             {
486                 moveToNext();
487             }
488             
489             public boolean hasNext() {
490                 return _ne != null;
491             }
492             
493             public Object JavaDoc next() {
494                 if (_position == _size + 2) {
495                     throw new NoSuchElementException JavaDoc();
496                 }
497                                 
498                 final String JavaDoc prefix = _ne.prefix;
499                 moveToNext();
500                 return prefix;
501             }
502             
503             public void remove() {
504                 throw new UnsupportedOperationException JavaDoc();
505             }
506             
507             private final void moveToNext() {
508                 while (++_position < _size + 2) {
509                     _ne = _inScopeNamespaces[_position];
510                     if (_ne != null && _namespaceName.equals(_ne.namespaceName)) {
511                         return;
512                     }
513                 }
514                 _ne = null;
515             }
516         };
517     }
518 }
519
Popular Tags