KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > javolution > xml > pull > Namespaces


1 /*
2  * Javolution - Java(TM) Solution for Real-Time and Embedded Systems
3  * Copyright (C) 2005 - 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.pull;
10
11 import javolution.lang.PersistentReference;
12 import j2me.lang.CharSequence;
13
14 /**
15  * This class represents the namespaces stack when parsing.
16  *
17  * @author <a HREF="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
18  * @version 3.2, April 2, 2005
19  */

20 final class Namespaces {
21
22     /**
23      * Holds the configurable nominal size to avoid resizing.
24      */

25     private static final PersistentReference SIZE = new PersistentReference(
26             "javolution.xml.pull.Namespaces#SIZE", new Integer(64));
27
28     /**
29      * Holds the number of namespace per depth level.
30      */

31     private int[] _nspCounts = new int[((Integer) SIZE.get()).intValue()];
32
33     /**
34      * Holds the current number being mapped.
35      */

36     private int _mapCount;
37
38     /**
39      * Holds the namespace mapping [uri, prefix] pairs.
40      */

41     private CharSequenceImpl[] _namespaces = new CharSequenceImpl[((Integer) SIZE
42             .get()).intValue()];
43
44     /**
45      * Holds the current depth.
46      */

47     private int _depth;
48
49     /**
50      * Holds the default namespace URI.
51      */

52     private CharSequenceImpl _default = CharSequenceImpl.EMPTY;
53
54     /**
55      * Default constructor.
56      */

57     public Namespaces() {
58     }
59
60     /**
61      * Returns the numbers of elements in the namespace stack for the given
62      * depth.
63      *
64      * @param depth the element depth.
65      */

66     public int getNamespaceCount(int depth) {
67         if (depth > _depth)
68             return _nspCounts[_depth];
69         return _nspCounts[depth];
70     }
71
72     /**
73      * Returns the namespace prefix at the specified position.
74      *
75      * @param pos the position in the namespace stack.
76      * @return the namespace prefix.
77      */

78     public CharSequenceImpl getNamespacePrefix(int pos) {
79         return _namespaces[pos << 1];
80     }
81
82     /**
83      * Returns the namespace uri at the specified position.
84      *
85      * @param pos the position in the namespace stack.
86      * @return the namespace uri.
87      */

88     public CharSequenceImpl getNamespaceUri(int pos) {
89         return _namespaces[(pos << 1) + 1];
90     }
91
92     /**
93      * Returns the namespace for the specified prefix or the default
94      * namespace is the prefix is <code>null</code>.
95      *
96      * @param prefix the prefix to search for or <code>null</code>.
97      * @return the associated namespace uri.
98      */

99     public CharSequenceImpl getNamespaceUri(CharSequence prefix) {
100         if (prefix == null)
101             return _default;
102         for (int i = _nspCounts[_depth] + _mapCount; i > 0;) {
103             CharSequenceImpl pfx = _namespaces[--i << 1];
104             if ((pfx != null) && pfx.equals(prefix))
105                 return _namespaces[(i << 1) + 1];
106         }
107         if (XML_PREFIX.equals(prefix))
108             return XML_URI;
109         if (XMLNS_PREFIX.equals(prefix))
110             return XMLNS_URI;
111         return null;
112     }
113
114     private static final CharSequenceImpl XML_PREFIX = new CharSequenceImpl(
115             "xml");
116
117     private static final CharSequenceImpl XML_URI = new CharSequenceImpl(
118             "http://www.w3.org/XML/1998/namespace");
119
120     private static final CharSequenceImpl XMLNS_PREFIX = new CharSequenceImpl(
121             "xmlns");
122
123     private static final CharSequenceImpl XMLNS_URI = new CharSequenceImpl(
124             "http://www.w3.org/2000/xmlns/");
125
126     /**
127      * Adds the specified mapping to the current mapping buffer.
128      *
129      * @param prefix the prefix to be mapped or <code>null</code> to
130      * map the defaut namespace.
131      * @param uri the associated uri.
132      * @throws SAXException any SAX exception, possibly wrapping another
133      * exception.
134      */

135     public void map(CharSequenceImpl prefix, CharSequenceImpl uri) {
136         final int i = (_nspCounts[_depth] + _mapCount++) << 1;
137         if (i + 1 >= _namespaces.length) resize();
138         _namespaces[i] = prefix;
139         _namespaces[i + 1] = uri;
140         if (prefix == null) { // Maps default namespace.
141
_default = uri;
142         }
143     }
144
145     /**
146      * Flushes the current mapping buffer (equivalent to push() then pop()).
147      */

148     public void flush() {
149         if (_mapCount != 0) {
150             push();
151             pop();
152         }
153     }
154
155     /**
156      * Pushes the current namespaces.
157      */

158     public void push() {
159         if (++_depth >= _nspCounts.length) resize();
160         _nspCounts[_depth] = _nspCounts[_depth - 1] + _mapCount;
161         _mapCount = 0;
162     }
163
164     /**
165      * Pops the current namespaces.
166      */

167     public void pop() {
168         _mapCount = 0;
169         final int oldCount = _nspCounts[_depth];
170         final int newCount = _nspCounts[--_depth];
171         for (int i = oldCount; i > newCount;) {
172             if (_namespaces[--i << 1] == null) { // Unmaps default namespace.
173
_default = CharSequenceImpl.EMPTY;
174                 for (int j = i; j > 0;) { // Searches current default.
175
if (_namespaces[--j << 1] == null) {
176                         _default = _namespaces[(j << 1) + 1];
177                         break;
178                     }
179                 }
180             }
181         }
182     }
183
184     /**
185      * Resets this {@link Namespaces} for reuse.
186      */

187     public void reset() {
188         _depth = 0;
189         _nspCounts[0] = 0;
190         _default = CharSequenceImpl.EMPTY;
191     }
192
193     /**
194      * Resizes internal arrays.
195      */

196     private void resize() {
197         final int size = _nspCounts.length; // = _namepaces.length;
198
int[] tmp0 = new int[size * 2];
199         System.arraycopy(_nspCounts, 0, tmp0, 0, size);
200         _nspCounts = tmp0;
201         CharSequenceImpl[] tmp1 = new CharSequenceImpl[size * 2];
202         System.arraycopy(_namespaces, 0, tmp1, 0, size);
203         _namespaces = tmp1;
204         SIZE.set(new Integer(size * 2));
205     }
206 }
Popular Tags