KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > javolution > xml > stream > NamespacesImpl


1 /*
2  * Javolution - Java(TM) Solution for Real-Time and Embedded Systems
3  * Copyright (C) 2006 - Javolution (http://javolution.org/)
4  * All rights reserved.
5  *
6  * Permission to use, copy, modify, and distribute this software is
7  * freely granted, provided that this notice is preserved.
8  */

9 package javolution.xml.stream;
10
11 import j2mex.realtime.MemoryArea;
12 import javolution.lang.Reusable;
13 import javolution.text.CharArray;
14 import javolution.util.FastList;
15 import j2me.lang.CharSequence;
16 import j2me.util.Iterator;
17
18 /**
19  * This class represents the namespaces stack while parsing.
20  *
21  * @author <a HREF="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
22  * @version 3.2, April 2, 2005
23  */

24 final class NamespacesImpl implements Reusable, NamespaceContext {
25
26     /**
27      * Holds the number of predefined namespaces.
28      */

29     static final int NBR_PREDEFINED_NAMESPACES = 3;
30
31     /**
32      * Holds useful CharArray instances (non-static to avoid potential
33      * inter-thread corruption).
34      */

35     final CharArray _nullNsURI = new CharArray(""); // No namespace URI.
36

37     final CharArray _defaultNsPrefix = new CharArray("");
38
39     final CharArray _xml = new CharArray("xml");
40
41     final CharArray _xmlURI = new CharArray(
42             "http://www.w3.org/XML/1998/namespace");
43
44     final CharArray _xmlns = new CharArray("xmlns");
45
46     final CharArray _xmlnsURI = new CharArray("http://www.w3.org/2000/xmlns/");
47
48     /**
49      * Holds the current nesting level.
50      */

51     private int _nesting = 0;
52
53     /**
54      * Holds the currently mapped prefixes.
55      */

56     CharArray[] _prefixes = new CharArray[16];
57
58     /**
59      * Holds the currently mapped namespaces.
60      */

61     CharArray[] _namespaces = new CharArray[_prefixes.length];
62
63     /**
64      * Indicates if the prefix has to been written (when writing).
65      */

66     boolean[] _prefixesWritten = new boolean[_prefixes.length];
67
68     /**
69      * Holds the number of prefix/namespace association per nesting level.
70      */

71     int[] _namespacesCount = new int[16];
72
73     /**
74      * Holds the default namespace.
75      */

76     CharArray _defaultNamespace = _nullNsURI;
77
78     /**
79      * Holds the default namespace index.
80      */

81     int _defaultNamespaceIndex;
82
83     /**
84      * Default constructor.
85      */

86     public NamespacesImpl() {
87         _prefixes[0] = _defaultNsPrefix;
88         _namespaces[0] = _nullNsURI;
89         _prefixes[1] = _xml;
90         _namespaces[1] = _xmlURI;
91         _prefixes[2] = _xmlns;
92         _namespaces[2] = _xmlnsURI;
93         _namespacesCount[0] = NBR_PREDEFINED_NAMESPACES;
94     }
95
96     // Implements NamespaceContext
97
public CharArray getNamespaceURI(CharSequence JavaDoc prefix) {
98         if (prefix == null)
99             throw new IllegalArgumentException JavaDoc("null prefix not allowed");
100         if (prefix.length() == 0)
101             return _defaultNamespace;
102         final int count = _namespacesCount[_nesting];
103         for (int i = count; --i >= 0;) {
104             if (_prefixes[i].equals(prefix))
105                 return _namespaces[i];
106         }
107         return null; // Not bound.
108
}
109
110     // Implements NamespaceContext
111
public CharArray getPrefix(CharSequence JavaDoc uri) {
112         if (uri == null)
113             throw new IllegalArgumentException JavaDoc("null namespace URI not allowed");
114         return _defaultNamespace.equals(uri) ? _defaultNsPrefix : getPrefix(
115                 uri, _namespacesCount[_nesting]);
116     }
117
118     CharArray getPrefix(CharSequence JavaDoc uri, int count) {
119         for (int i = count; --i >= 0;) {
120             CharArray prefix = _prefixes[i];
121             CharArray namespace = _namespaces[i];
122             if (namespace.equals(uri)) { // Find matching uri.
123
// Checks that the prefix has not been overwriten after being set.
124
boolean isPrefixOverwritten = false;
125                 for (int j = i + 1; j < count; j++) {
126                     if (prefix.equals(_prefixes[j])) {
127                         isPrefixOverwritten = true;
128                         break;
129                     }
130                 }
131                 if (!isPrefixOverwritten)
132                     return prefix;
133             }
134         }
135         return null; // Not bound.
136
}
137
138     // Implements NamespaceContext
139
public Iterator getPrefixes(CharSequence JavaDoc namespaceURI) {
140         FastList prefixes = new FastList();
141         for (int i = _namespacesCount[_nesting]; --i >= 0;) {
142             if (_namespaces[i].equals(namespaceURI)) {
143                 prefixes.add(_prefixes[i]);
144             }
145         }
146         return prefixes.iterator();
147     }
148
149     // Null values are not allowed.
150
void setPrefix(CharArray prefix, CharArray uri) {
151         int index = _namespacesCount[_nesting];
152         _prefixes[index] = prefix;
153         _namespaces[index] = uri;
154         if (prefix.length() == 0) { // The default namespace is set.
155
_defaultNamespaceIndex = index;
156             _defaultNamespace = uri;
157         }
158         if (++_namespacesCount[_nesting] >= _prefixes.length)
159             resizePrefixStack();
160     }
161
162     // Used only by XMLStreamWriter (converts CharSequence to CharArray).
163
// Null values are not allowed.
164
void setPrefix(final CharSequence JavaDoc prefix, CharSequence JavaDoc uri,
165             boolean isWritten) {
166         final int index = _namespacesCount[_nesting];
167         _prefixesWritten[index] = isWritten;
168         final int prefixLength = prefix.length();
169         CharArray prefixTmp = _prefixesTmp[index];
170         if ((prefixTmp == null)
171                 || (prefixTmp.array().length < prefixLength)) {
172             MemoryArea.getMemoryArea(this).executeInArea(new Runnable JavaDoc() {
173                 public void run() {
174                     _prefixesTmp[index] = new CharArray().setArray(new char[prefixLength + 32], 0, 0);
175                 }
176             });
177             prefixTmp = _prefixesTmp[index];
178         }
179         for (int i = 0; i < prefixLength; i++) {
180             prefixTmp.array()[i] = prefix.charAt(i);
181         }
182         prefixTmp.setArray(prefixTmp.array(), 0, prefixLength);
183
184         final int uriLength = uri.length();
185         CharArray namespaceTmp = _namespacesTmp[index];
186         if ((namespaceTmp == null)
187                 || (namespaceTmp.array().length < uriLength)) {
188             MemoryArea.getMemoryArea(this).executeInArea(new Runnable JavaDoc() {
189                 public void run() {
190                     _namespacesTmp[index] = new CharArray().setArray(new char[uriLength + 32], 0, 0);
191                 }
192             });
193             namespaceTmp = _namespacesTmp[index];
194         }
195         for (int i = 0; i < uriLength; i++) {
196             namespaceTmp.array()[i] = uri.charAt(i);
197         }
198         namespaceTmp.setArray(namespaceTmp.array(), 0, uriLength);
199         
200         // Sets the prefix using CharArray instances.
201
setPrefix(prefixTmp, namespaceTmp);
202     }
203
204     private CharArray[] _prefixesTmp = new CharArray[_prefixes.length];
205
206     private CharArray[] _namespacesTmp = new CharArray[_prefixes.length];
207
208     void pop() {
209         if (_namespacesCount[--_nesting] <= _defaultNamespaceIndex) {
210             searchDefaultNamespace();
211         }
212     }
213
214     private void searchDefaultNamespace() {
215         int count = _namespacesCount[_nesting];
216         for (int i = count; --i >= 0;) {
217             if (_prefixes[i].length() == 0) {
218                 _defaultNamespaceIndex = i;
219                 return;
220             }
221         }
222         throw new Error JavaDoc("Cannot find default namespace");
223     }
224
225     void push() {
226         _nesting++;
227         if (_nesting >= _namespacesCount.length) {
228             resizeNamespacesCount();
229         }
230         _namespacesCount[_nesting] = _namespacesCount[_nesting - 1];
231     }
232
233     public void reset() {
234         _defaultNamespace = _nullNsURI;
235         _defaultNamespaceIndex = 0;
236         _namespacesCount[0] = NBR_PREDEFINED_NAMESPACES;
237         _nesting = 0;
238     }
239
240     private void resizeNamespacesCount() {
241         MemoryArea.getMemoryArea(this).executeInArea(new Runnable JavaDoc() {
242             public void run() {
243                 final int oldLength = _namespacesCount.length;
244                 final int newLength = oldLength * 2;
245
246                 // Resizes namespaces counts.
247
int[] tmp = new int[newLength];
248                 System.arraycopy(_namespacesCount, 0, tmp, 0, oldLength);
249                 _namespacesCount = tmp;
250             }
251         });
252     }
253
254     // Resizes prefix mapping stack.
255
private void resizePrefixStack() {
256         MemoryArea.getMemoryArea(this).executeInArea(new Runnable JavaDoc() {
257             public void run() {
258                 final int oldLength = _prefixes.length;
259                 final int newLength = oldLength * 2;
260
261                 // Resizes prefixes.
262
CharArray[] tmp0 = new CharArray[newLength];
263                 System.arraycopy(_prefixes, 0, tmp0, 0, oldLength);
264                 _prefixes = tmp0;
265
266                 // Resizes namespaces uri.
267
CharArray[] tmp1 = new CharArray[newLength];
268                 System.arraycopy(_namespaces, 0, tmp1, 0, oldLength);
269                 _namespaces = tmp1;
270
271                 // Resizes prefix sets.
272
boolean[] tmp2 = new boolean[newLength];
273                 System.arraycopy(_prefixesWritten, 0, tmp2, 0, oldLength);
274                 _prefixesWritten = tmp2;
275
276                 // Resizes temporary prefix (CharSequence to CharArray conversion).
277
CharArray[] tmp3 = new CharArray[newLength];
278                 System.arraycopy(_prefixesTmp, 0, tmp3, 0, oldLength);
279                 _prefixesTmp = tmp3;
280
281                 // Resizes temporary namespaces (CharSequence to CharArray conversion).
282
CharArray[] tmp4 = new CharArray[newLength];
283                 System.arraycopy(_namespacesTmp, 0, tmp4, 0, oldLength);
284                 _namespacesTmp = tmp4;
285
286             }
287         });
288     }
289
290
291 }
Popular Tags