|
1 /* |
|
2 * Licensed to the Apache Software Foundation (ASF) under one |
|
3 * or more contributor license agreements. See the NOTICE file |
|
4 * distributed with this work for additional information |
|
5 * regarding copyright ownership. The ASF licenses this file |
|
6 * to you under the Apache License, Version 2.0 (the "License"); |
|
7 * you may not use this file except in compliance with the License. |
|
8 * You may 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, |
|
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
15 * See the License for the specific language governing permissions and |
|
16 * limitations under the License. |
|
17 */ |
|
18 /* |
|
19 * $Id: $ |
|
20 */ |
|
21 |
|
22 package com.sun.org.apache.xml.internal.serializer.dom3; |
|
23 |
|
24 import java.util.Enumeration; |
|
25 import java.util.NoSuchElementException; |
|
26 |
|
27 /** |
|
28 * Namespace support for XML document handlers. This class doesn't |
|
29 * perform any error checking and assumes that all strings passed |
|
30 * as arguments to methods are unique symbols. The SymbolTable class |
|
31 * can be used for this purpose. |
|
32 * |
|
33 * Derived from org.apache.xerces.util.NamespaceSupport |
|
34 * |
|
35 * @author Andy Clark, IBM |
|
36 * |
|
37 * @version $Id: Exp $ |
|
38 */ |
|
39 public class NamespaceSupport { |
|
40 |
|
41 static final String PREFIX_XML = "xml".intern(); |
|
42 |
|
43 static final String PREFIX_XMLNS = "xmlns".intern(); |
|
44 |
|
45 /** |
|
46 * The XML Namespace ("http://www.w3.org/XML/1998/namespace"). This is |
|
47 * the Namespace URI that is automatically mapped to the "xml" prefix. |
|
48 */ |
|
49 public final static String XML_URI = "http://www.w3.org/XML/1998/namespace".intern(); |
|
50 |
|
51 /** |
|
52 * XML Information Set REC |
|
53 * all namespace attributes (including those named xmlns, |
|
54 * whose [prefix] property has no value) have a namespace URI of http://www.w3.org/2000/xmlns/ |
|
55 */ |
|
56 public final static String XMLNS_URI = "http://www.w3.org/2000/xmlns/".intern(); |
|
57 |
|
58 // |
|
59 // Data |
|
60 // |
|
61 |
|
62 /** |
|
63 * Namespace binding information. This array is composed of a |
|
64 * series of tuples containing the namespace binding information: |
|
65 * <prefix, uri>. The default size can be set to anything |
|
66 * as long as it is a power of 2 greater than 1. |
|
67 * |
|
68 * @see #fNamespaceSize |
|
69 * @see #fContext |
|
70 */ |
|
71 protected String[] fNamespace = new String[16 * 2]; |
|
72 |
|
73 /** The top of the namespace information array. */ |
|
74 protected int fNamespaceSize; |
|
75 |
|
76 // NOTE: The constructor depends on the initial context size |
|
77 // being at least 1. -Ac |
|
78 |
|
79 /** |
|
80 * Context indexes. This array contains indexes into the namespace |
|
81 * information array. The index at the current context is the start |
|
82 * index of declared namespace bindings and runs to the size of the |
|
83 * namespace information array. |
|
84 * |
|
85 * @see #fNamespaceSize |
|
86 */ |
|
87 protected int[] fContext = new int[8]; |
|
88 |
|
89 /** The current context. */ |
|
90 protected int fCurrentContext; |
|
91 |
|
92 protected String[] fPrefixes = new String[16]; |
|
93 |
|
94 // |
|
95 // Constructors |
|
96 // |
|
97 |
|
98 /** Default constructor. */ |
|
99 public NamespaceSupport() { |
|
100 } // <init>() |
|
101 |
|
102 // |
|
103 // Public methods |
|
104 // |
|
105 |
|
106 /** |
|
107 * @see org.apache.xerces.xni.NamespaceContext#reset() |
|
108 */ |
|
109 public void reset() { |
|
110 |
|
111 // reset namespace and context info |
|
112 fNamespaceSize = 0; |
|
113 fCurrentContext = 0; |
|
114 fContext[fCurrentContext] = fNamespaceSize; |
|
115 |
|
116 // bind "xml" prefix to the XML uri |
|
117 fNamespace[fNamespaceSize++] = PREFIX_XML; |
|
118 fNamespace[fNamespaceSize++] = XML_URI; |
|
119 // bind "xmlns" prefix to the XMLNS uri |
|
120 fNamespace[fNamespaceSize++] = PREFIX_XMLNS; |
|
121 fNamespace[fNamespaceSize++] = XMLNS_URI; |
|
122 ++fCurrentContext; |
|
123 |
|
124 } // reset(SymbolTable) |
|
125 |
|
126 |
|
127 /** |
|
128 * @see org.apache.xerces.xni.NamespaceContext#pushContext() |
|
129 */ |
|
130 public void pushContext() { |
|
131 |
|
132 // extend the array, if necessary |
|
133 if (fCurrentContext + 1 == fContext.length) { |
|
134 int[] contextarray = new int[fContext.length * 2]; |
|
135 System.arraycopy(fContext, 0, contextarray, 0, fContext.length); |
|
136 fContext = contextarray; |
|
137 } |
|
138 |
|
139 // push context |
|
140 fContext[++fCurrentContext] = fNamespaceSize; |
|
141 |
|
142 } // pushContext() |
|
143 |
|
144 |
|
145 /** |
|
146 * @see org.apache.xerces.xni.NamespaceContext#popContext() |
|
147 */ |
|
148 public void popContext() { |
|
149 fNamespaceSize = fContext[fCurrentContext--]; |
|
150 } // popContext() |
|
151 |
|
152 /** |
|
153 * @see org.apache.xerces.xni.NamespaceContext#declarePrefix(String, String) |
|
154 */ |
|
155 public boolean declarePrefix(String prefix, String uri) { |
|
156 // ignore "xml" and "xmlns" prefixes |
|
157 if (prefix == PREFIX_XML || prefix == PREFIX_XMLNS) { |
|
158 return false; |
|
159 } |
|
160 |
|
161 // see if prefix already exists in current context |
|
162 for (int i = fNamespaceSize; i > fContext[fCurrentContext]; i -= 2) { |
|
163 //if (fNamespace[i - 2] == prefix) { |
|
164 if (fNamespace[i - 2].equals(prefix) ) { |
|
165 // REVISIT: [Q] Should the new binding override the |
|
166 // previously declared binding or should it |
|
167 // it be ignored? -Ac |
|
168 // NOTE: The SAX2 "NamespaceSupport" helper allows |
|
169 // re-bindings with the new binding overwriting |
|
170 // the previous binding. -Ac |
|
171 fNamespace[i - 1] = uri; |
|
172 return true; |
|
173 } |
|
174 } |
|
175 |
|
176 // resize array, if needed |
|
177 if (fNamespaceSize == fNamespace.length) { |
|
178 String[] namespacearray = new String[fNamespaceSize * 2]; |
|
179 System.arraycopy(fNamespace, 0, namespacearray, 0, fNamespaceSize); |
|
180 fNamespace = namespacearray; |
|
181 } |
|
182 |
|
183 // bind prefix to uri in current context |
|
184 fNamespace[fNamespaceSize++] = prefix; |
|
185 fNamespace[fNamespaceSize++] = uri; |
|
186 |
|
187 return true; |
|
188 |
|
189 } // declarePrefix(String,String):boolean |
|
190 |
|
191 /** |
|
192 * @see org.apache.xerces.xni.NamespaceContext#getURI(String) |
|
193 */ |
|
194 public String getURI(String prefix) { |
|
195 |
|
196 // find prefix in current context |
|
197 for (int i = fNamespaceSize; i > 0; i -= 2) { |
|
198 //if (fNamespace[i - 2] == prefix) { |
|
199 if (fNamespace[i - 2].equals(prefix) ) { |
|
200 return fNamespace[i - 1]; |
|
201 } |
|
202 } |
|
203 |
|
204 // prefix not found |
|
205 return null; |
|
206 |
|
207 } // getURI(String):String |
|
208 |
|
209 |
|
210 /** |
|
211 * @see org.apache.xerces.xni.NamespaceContext#getPrefix(String) |
|
212 */ |
|
213 public String getPrefix(String uri) { |
|
214 |
|
215 // find uri in current context |
|
216 for (int i = fNamespaceSize; i > 0; i -= 2) { |
|
217 //if (fNamespace[i - 1] == uri) { |
|
218 if (fNamespace[i - 1].equals(uri) ) { |
|
219 //if (getURI(fNamespace[i - 2]) == uri) |
|
220 if (getURI(fNamespace[i - 2]).equals(uri) ) |
|
221 return fNamespace[i - 2]; |
|
222 } |
|
223 } |
|
224 |
|
225 // uri not found |
|
226 return null; |
|
227 |
|
228 } // getPrefix(String):String |
|
229 |
|
230 |
|
231 /** |
|
232 * @see org.apache.xerces.xni.NamespaceContext#getDeclaredPrefixCount() |
|
233 */ |
|
234 public int getDeclaredPrefixCount() { |
|
235 return (fNamespaceSize - fContext[fCurrentContext]) / 2; |
|
236 } // getDeclaredPrefixCount():int |
|
237 |
|
238 /** |
|
239 * @see org.apache.xerces.xni.NamespaceContext#getDeclaredPrefixAt(int) |
|
240 */ |
|
241 public String getDeclaredPrefixAt(int index) { |
|
242 return fNamespace[fContext[fCurrentContext] + index * 2]; |
|
243 } // getDeclaredPrefixAt(int):String |
|
244 |
|
245 /** |
|
246 * @see org.apache.xerces.xni.NamespaceContext#getAllPrefixes() |
|
247 */ |
|
248 public Enumeration getAllPrefixes() { |
|
249 int count = 0; |
|
250 if (fPrefixes.length < (fNamespace.length/2)) { |
|
251 // resize prefix array |
|
252 String[] prefixes = new String[fNamespaceSize]; |
|
253 fPrefixes = prefixes; |
|
254 } |
|
255 String prefix = null; |
|
256 boolean unique = true; |
|
257 for (int i = 2; i < (fNamespaceSize-2); i += 2) { |
|
258 prefix = fNamespace[i + 2]; |
|
259 for (int k=0;k<count;k++){ |
|
260 if (fPrefixes[k]==prefix){ |
|
261 unique = false; |
|
262 break; |
|
263 } |
|
264 } |
|
265 if (unique){ |
|
266 fPrefixes[count++] = prefix; |
|
267 } |
|
268 unique = true; |
|
269 } |
|
270 return new Prefixes(fPrefixes, count); |
|
271 } |
|
272 |
|
273 protected final class Prefixes implements Enumeration { |
|
274 private String[] prefixes; |
|
275 private int counter = 0; |
|
276 private int size = 0; |
|
277 |
|
278 /** |
|
279 * Constructor for Prefixes. |
|
280 */ |
|
281 public Prefixes(String [] prefixes, int size) { |
|
282 this.prefixes = prefixes; |
|
283 this.size = size; |
|
284 } |
|
285 |
|
286 /** |
|
287 * @see java.util.Enumeration#hasMoreElements() |
|
288 */ |
|
289 public boolean hasMoreElements() { |
|
290 return (counter< size); |
|
291 } |
|
292 |
|
293 /** |
|
294 * @see java.util.Enumeration#nextElement() |
|
295 */ |
|
296 public Object nextElement() { |
|
297 if (counter< size){ |
|
298 return fPrefixes[counter++]; |
|
299 } |
|
300 throw new NoSuchElementException("Illegal access to Namespace prefixes enumeration."); |
|
301 } |
|
302 |
|
303 public String toString(){ |
|
304 StringBuffer buf = new StringBuffer(); |
|
305 for (int i=0;i<size;i++){ |
|
306 buf.append(prefixes[i]); |
|
307 buf.append(" "); |
|
308 } |
|
309 |
|
310 return buf.toString(); |
|
311 } |
|
312 |
|
313 } |
|
314 |
|
315 } // class NamespaceSupport |