1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.apache.wss4j.common.util;
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40 public class NSStack {
41 private static final org.slf4j.Logger LOG =
42 org.slf4j.LoggerFactory.getLogger(NSStack.class);
43
44 private Mapping[] stack;
45 private int top;
46 private int iterator;
47 private int currentDefaultNS = -1;
48
49
50
51 private final boolean traceEnabled = LOG.isTraceEnabled();
52
53 public NSStack() {
54 stack = new Mapping[32];
55 stack[0] = null;
56 }
57
58
59
60
61 public void push() {
62 top++;
63 if (top >= stack.length) {
64 Mapping[] newstack = new Mapping[stack.length * 2];
65 System.arraycopy(stack, 0, newstack, 0, stack.length);
66 stack = newstack;
67 }
68 if (traceEnabled) {
69 LOG.trace("NSPush (" + stack.length + ")");
70 }
71 stack[top] = null;
72 }
73
74
75
76
77 public void pop() {
78 clearFrame();
79 top--;
80
81
82
83 if (top < currentDefaultNS) {
84
85 currentDefaultNS = top;
86 while (currentDefaultNS > 0) {
87 if (stack[currentDefaultNS] != null
88 && stack[currentDefaultNS].getPrefix().length() == 0) {
89 break;
90 }
91 currentDefaultNS--;
92 }
93 }
94 if (top == 0) {
95 if (traceEnabled) {
96 LOG.trace("NSPop (empty)");
97 }
98 return;
99 }
100 if (traceEnabled) {
101 LOG.trace("NSPop (" + stack.length + ")");
102 }
103 }
104
105
106
107
108 private void clearFrame() {
109 while (stack[top] != null) {
110 top--;
111 }
112 }
113
114
115
116
117
118
119
120 public Mapping topOfFrame() {
121 iterator = top;
122 while (stack[iterator] != null) {
123 iterator--;
124 }
125 iterator++;
126 return next();
127 }
128
129
130
131
132 public Mapping next() {
133 if (iterator > top) {
134 return null;
135 } else {
136 return stack[iterator++];
137 }
138 }
139
140
141
142
143
144
145 public void add(String namespaceURI, String prefix) {
146 int idx = top;
147 try {
148
149 for (int cursor = top; stack[cursor] != null; cursor--) {
150 if (stack[cursor].getPrefix().equals(prefix)) {
151 stack[cursor].setNamespaceURI(namespaceURI);
152 idx = cursor;
153 return;
154 }
155 }
156 push();
157 stack[top] = new Mapping(namespaceURI, prefix);
158 idx = top;
159 } finally {
160
161
162 if (prefix.length() == 0) {
163 currentDefaultNS = idx;
164 }
165 }
166 }
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183 public String getPrefix(String namespaceURI, boolean noDefault) {
184 if (namespaceURI == null || namespaceURI.isEmpty()) {
185 return null;
186 }
187 int hash = namespaceURI.hashCode();
188
189
190
191 if (!noDefault && currentDefaultNS > 0 && stack[currentDefaultNS] != null
192 && namespaceURI.equals(stack[currentDefaultNS].getNamespaceURI())) {
193 return "";
194 }
195 for (int cursor = top; cursor > 0; cursor--) {
196 Mapping map = stack[cursor];
197 if (map == null) {
198 continue;
199 }
200 if (map.getNamespaceHash() == hash && map.getNamespaceURI().equals(namespaceURI)) {
201 String possiblePrefix = map.getPrefix();
202 if (noDefault && possiblePrefix.length() == 0) {
203 continue;
204 }
205
206
207
208 int ppHash = possiblePrefix.hashCode();
209 for (int cursor2 = top; true; cursor2--) {
210 if (cursor2 == cursor) {
211 return possiblePrefix;
212 }
213 map = stack[cursor2];
214 if (map == null) {
215 continue;
216 }
217 if (ppHash == map.getPrefixHash() && possiblePrefix.equals(map.getPrefix())) {
218 break;
219 }
220 }
221 }
222 }
223 return null;
224 }
225
226
227
228
229
230 public String getPrefix(String namespaceURI) {
231 return getPrefix(namespaceURI, false);
232 }
233
234
235
236
237 public String getNamespaceURI(String prefix) {
238 String pfix = prefix;
239 if (pfix == null) {
240 pfix = "";
241 }
242 int hash = pfix.hashCode();
243 for (int cursor = top; cursor > 0; cursor--) {
244 Mapping map = stack[cursor];
245 if (map == null) {
246 continue;
247 }
248 if (map.getPrefixHash() == hash && map.getPrefix().equals(pfix)) {
249 return map.getNamespaceURI();
250 }
251 }
252 return null;
253 }
254
255
256
257
258
259 public void dump(String dumpPrefix) {
260 for (int cursor = top; cursor > 0; cursor--) {
261 Mapping map = stack[cursor];
262 if (map == null) {
263 LOG.trace(dumpPrefix + "stackFrame00");
264 } else {
265 LOG.trace(dumpPrefix + map.getNamespaceURI() + " -> " + map.getPrefix());
266 }
267 }
268 }
269 }