author | psandoz |
Mon, 16 Jun 2014 17:45:26 +0100 | |
changeset 24969 | afa6934dd8e8 |
parent 23882 | 7dbf42ed83ef |
permissions | -rw-r--r-- |
2 | 1 |
/* |
10324
e28265130e4f
7072353: JNDI libraries do not build with javac -Xlint:all -Werror
jjg
parents:
5506
diff
changeset
|
2 |
* Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved. |
2 | 3 |
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 |
* |
|
5 |
* This code is free software; you can redistribute it and/or modify it |
|
6 |
* under the terms of the GNU General Public License version 2 only, as |
|
5506 | 7 |
* published by the Free Software Foundation. Oracle designates this |
2 | 8 |
* particular file as subject to the "Classpath" exception as provided |
5506 | 9 |
* by Oracle in the LICENSE file that accompanied this code. |
2 | 10 |
* |
11 |
* This code is distributed in the hope that it will be useful, but WITHOUT |
|
12 |
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
|
13 |
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
|
14 |
* version 2 for more details (a copy is included in the LICENSE file that |
|
15 |
* accompanied this code). |
|
16 |
* |
|
17 |
* You should have received a copy of the GNU General Public License version |
|
18 |
* 2 along with this work; if not, write to the Free Software Foundation, |
|
19 |
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
|
20 |
* |
|
5506 | 21 |
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
22 |
* or visit www.oracle.com if you need additional information or have any |
|
23 |
* questions. |
|
2 | 24 |
*/ |
25 |
||
26 |
package javax.naming; |
|
27 |
||
10369
e9d2e59e53f0
7059542: JNDI name operations should be locale independent
xuelei
parents:
10324
diff
changeset
|
28 |
import java.util.Locale; |
2 | 29 |
import java.util.Vector; |
30 |
import java.util.Enumeration; |
|
31 |
import java.util.Properties; |
|
32 |
import java.util.NoSuchElementException; |
|
33 |
||
34 |
/** |
|
35 |
* The implementation class for CompoundName and CompositeName. |
|
36 |
* This class is package private. |
|
37 |
* |
|
38 |
* @author Rosanna Lee |
|
39 |
* @author Scott Seligman |
|
40 |
* @author Aravindan Ranganathan |
|
41 |
* @since 1.3 |
|
42 |
*/ |
|
43 |
||
44 |
class NameImpl { |
|
45 |
private static final byte LEFT_TO_RIGHT = 1; |
|
46 |
private static final byte RIGHT_TO_LEFT = 2; |
|
47 |
private static final byte FLAT = 0; |
|
48 |
||
10324
e28265130e4f
7072353: JNDI libraries do not build with javac -Xlint:all -Werror
jjg
parents:
5506
diff
changeset
|
49 |
private Vector<String> components; |
2 | 50 |
|
51 |
private byte syntaxDirection = LEFT_TO_RIGHT; |
|
52 |
private String syntaxSeparator = "/"; |
|
53 |
private String syntaxSeparator2 = null; |
|
54 |
private boolean syntaxCaseInsensitive = false; |
|
55 |
private boolean syntaxTrimBlanks = false; |
|
56 |
private String syntaxEscape = "\\"; |
|
57 |
private String syntaxBeginQuote1 = "\""; |
|
58 |
private String syntaxEndQuote1 = "\""; |
|
59 |
private String syntaxBeginQuote2 = "'"; |
|
60 |
private String syntaxEndQuote2 = "'"; |
|
61 |
private String syntaxAvaSeparator = null; |
|
62 |
private String syntaxTypevalSeparator = null; |
|
63 |
||
64 |
// escapingStyle gives the method used at creation time for |
|
65 |
// quoting or escaping characters in the name. It is set to the |
|
66 |
// first style of quote or escape encountered if and when the name |
|
67 |
// is parsed. |
|
68 |
private static final int STYLE_NONE = 0; |
|
69 |
private static final int STYLE_QUOTE1 = 1; |
|
70 |
private static final int STYLE_QUOTE2 = 2; |
|
71 |
private static final int STYLE_ESCAPE = 3; |
|
72 |
private int escapingStyle = STYLE_NONE; |
|
73 |
||
74 |
// Returns true if "match" is not null, and n contains "match" at |
|
75 |
// position i. |
|
76 |
private final boolean isA(String n, int i, String match) { |
|
77 |
return (match != null && n.startsWith(match, i)); |
|
78 |
} |
|
79 |
||
80 |
private final boolean isMeta(String n, int i) { |
|
81 |
return (isA(n, i, syntaxEscape) || |
|
82 |
isA(n, i, syntaxBeginQuote1) || |
|
83 |
isA(n, i, syntaxBeginQuote2) || |
|
84 |
isSeparator(n, i)); |
|
85 |
} |
|
86 |
||
87 |
private final boolean isSeparator(String n, int i) { |
|
88 |
return (isA(n, i, syntaxSeparator) || |
|
89 |
isA(n, i, syntaxSeparator2)); |
|
90 |
} |
|
91 |
||
92 |
private final int skipSeparator(String name, int i) { |
|
93 |
if (isA(name, i, syntaxSeparator)) { |
|
94 |
i += syntaxSeparator.length(); |
|
95 |
} else if (isA(name, i, syntaxSeparator2)) { |
|
96 |
i += syntaxSeparator2.length(); |
|
97 |
} |
|
98 |
return (i); |
|
99 |
} |
|
100 |
||
10324
e28265130e4f
7072353: JNDI libraries do not build with javac -Xlint:all -Werror
jjg
parents:
5506
diff
changeset
|
101 |
private final int extractComp(String name, int i, int len, Vector<String> comps) |
2 | 102 |
throws InvalidNameException { |
103 |
String beginQuote; |
|
104 |
String endQuote; |
|
105 |
boolean start = true; |
|
106 |
boolean one = false; |
|
24969
afa6934dd8e8
8041679: Replace uses of StringBuffer with StringBuilder within core library classes
psandoz
parents:
23882
diff
changeset
|
107 |
StringBuilder answer = new StringBuilder(len); |
2 | 108 |
|
109 |
while (i < len) { |
|
110 |
// handle quoted strings |
|
111 |
if (start && ((one = isA(name, i, syntaxBeginQuote1)) || |
|
112 |
isA(name, i, syntaxBeginQuote2))) { |
|
113 |
||
114 |
// record choice of quote chars being used |
|
115 |
beginQuote = one ? syntaxBeginQuote1 : syntaxBeginQuote2; |
|
116 |
endQuote = one ? syntaxEndQuote1 : syntaxEndQuote2; |
|
117 |
if (escapingStyle == STYLE_NONE) { |
|
118 |
escapingStyle = one ? STYLE_QUOTE1 : STYLE_QUOTE2; |
|
119 |
} |
|
120 |
||
121 |
// consume string until matching quote |
|
122 |
for (i += beginQuote.length(); |
|
123 |
((i < len) && !name.startsWith(endQuote, i)); |
|
124 |
i++) { |
|
125 |
// skip escape character if it is escaping ending quote |
|
126 |
// otherwise leave as is. |
|
127 |
if (isA(name, i, syntaxEscape) && |
|
128 |
isA(name, i + syntaxEscape.length(), endQuote)) { |
|
129 |
i += syntaxEscape.length(); |
|
130 |
} |
|
131 |
answer.append(name.charAt(i)); // copy char |
|
132 |
} |
|
133 |
||
134 |
// no ending quote found |
|
135 |
if (i >= len) |
|
136 |
throw |
|
137 |
new InvalidNameException(name + ": no close quote"); |
|
138 |
// new Exception("no close quote"); |
|
139 |
||
140 |
i += endQuote.length(); |
|
141 |
||
142 |
// verify that end-quote occurs at separator or end of string |
|
143 |
if (i == len || isSeparator(name, i)) { |
|
144 |
break; |
|
145 |
} |
|
146 |
// throw (new Exception( |
|
147 |
throw (new InvalidNameException(name + |
|
148 |
": close quote appears before end of component")); |
|
149 |
||
150 |
} else if (isSeparator(name, i)) { |
|
151 |
break; |
|
152 |
||
153 |
} else if (isA(name, i, syntaxEscape)) { |
|
154 |
if (isMeta(name, i + syntaxEscape.length())) { |
|
155 |
// if escape precedes meta, consume escape and let |
|
156 |
// meta through |
|
157 |
i += syntaxEscape.length(); |
|
158 |
if (escapingStyle == STYLE_NONE) { |
|
159 |
escapingStyle = STYLE_ESCAPE; |
|
160 |
} |
|
161 |
} else if (i + syntaxEscape.length() >= len) { |
|
162 |
throw (new InvalidNameException(name + |
|
163 |
": unescaped " + syntaxEscape + " at end of component")); |
|
164 |
} |
|
165 |
} else if (isA(name, i, syntaxTypevalSeparator) && |
|
166 |
((one = isA(name, i+syntaxTypevalSeparator.length(), syntaxBeginQuote1)) || |
|
167 |
isA(name, i+syntaxTypevalSeparator.length(), syntaxBeginQuote2))) { |
|
168 |
// Handle quote occurring after typeval separator |
|
169 |
beginQuote = one ? syntaxBeginQuote1 : syntaxBeginQuote2; |
|
170 |
endQuote = one ? syntaxEndQuote1 : syntaxEndQuote2; |
|
171 |
||
172 |
i += syntaxTypevalSeparator.length(); |
|
173 |
answer.append(syntaxTypevalSeparator+beginQuote); // add back |
|
174 |
||
175 |
// consume string until matching quote |
|
176 |
for (i += beginQuote.length(); |
|
177 |
((i < len) && !name.startsWith(endQuote, i)); |
|
178 |
i++) { |
|
179 |
// skip escape character if it is escaping ending quote |
|
180 |
// otherwise leave as is. |
|
181 |
if (isA(name, i, syntaxEscape) && |
|
182 |
isA(name, i + syntaxEscape.length(), endQuote)) { |
|
183 |
i += syntaxEscape.length(); |
|
184 |
} |
|
185 |
answer.append(name.charAt(i)); // copy char |
|
186 |
} |
|
187 |
||
188 |
// no ending quote found |
|
189 |
if (i >= len) |
|
190 |
throw |
|
191 |
new InvalidNameException(name + ": typeval no close quote"); |
|
192 |
||
193 |
i += endQuote.length(); |
|
194 |
answer.append(endQuote); // add back |
|
195 |
||
196 |
// verify that end-quote occurs at separator or end of string |
|
197 |
if (i == len || isSeparator(name, i)) { |
|
198 |
break; |
|
199 |
} |
|
200 |
throw (new InvalidNameException(name.substring(i) + |
|
201 |
": typeval close quote appears before end of component")); |
|
202 |
} |
|
203 |
||
204 |
answer.append(name.charAt(i++)); |
|
205 |
start = false; |
|
206 |
} |
|
207 |
||
208 |
if (syntaxDirection == RIGHT_TO_LEFT) |
|
209 |
comps.insertElementAt(answer.toString(), 0); |
|
210 |
else |
|
211 |
comps.addElement(answer.toString()); |
|
212 |
return i; |
|
213 |
} |
|
214 |
||
215 |
private static boolean getBoolean(Properties p, String name) { |
|
216 |
return toBoolean(p.getProperty(name)); |
|
217 |
} |
|
218 |
||
219 |
private static boolean toBoolean(String name) { |
|
10369
e9d2e59e53f0
7059542: JNDI name operations should be locale independent
xuelei
parents:
10324
diff
changeset
|
220 |
return ((name != null) && |
e9d2e59e53f0
7059542: JNDI name operations should be locale independent
xuelei
parents:
10324
diff
changeset
|
221 |
name.toLowerCase(Locale.ENGLISH).equals("true")); |
2 | 222 |
} |
223 |
||
224 |
private final void recordNamingConvention(Properties p) { |
|
225 |
String syntaxDirectionStr = |
|
226 |
p.getProperty("jndi.syntax.direction", "flat"); |
|
227 |
if (syntaxDirectionStr.equals("left_to_right")) { |
|
228 |
syntaxDirection = LEFT_TO_RIGHT; |
|
229 |
} else if (syntaxDirectionStr.equals("right_to_left")) { |
|
230 |
syntaxDirection = RIGHT_TO_LEFT; |
|
231 |
} else if (syntaxDirectionStr.equals("flat")) { |
|
232 |
syntaxDirection = FLAT; |
|
233 |
} else { |
|
234 |
throw new IllegalArgumentException(syntaxDirectionStr + |
|
23882
7dbf42ed83ef
8009637: Some error messages are missing a space
igerasim
parents:
10369
diff
changeset
|
235 |
" is not a valid value for the jndi.syntax.direction property"); |
2 | 236 |
} |
237 |
||
238 |
if (syntaxDirection != FLAT) { |
|
239 |
syntaxSeparator = p.getProperty("jndi.syntax.separator"); |
|
240 |
syntaxSeparator2 = p.getProperty("jndi.syntax.separator2"); |
|
241 |
if (syntaxSeparator == null) { |
|
242 |
throw new IllegalArgumentException( |
|
243 |
"jndi.syntax.separator property required for non-flat syntax"); |
|
244 |
} |
|
245 |
} else { |
|
246 |
syntaxSeparator = null; |
|
247 |
} |
|
248 |
syntaxEscape = p.getProperty("jndi.syntax.escape"); |
|
249 |
||
250 |
syntaxCaseInsensitive = getBoolean(p, "jndi.syntax.ignorecase"); |
|
251 |
syntaxTrimBlanks = getBoolean(p, "jndi.syntax.trimblanks"); |
|
252 |
||
253 |
syntaxBeginQuote1 = p.getProperty("jndi.syntax.beginquote"); |
|
254 |
syntaxEndQuote1 = p.getProperty("jndi.syntax.endquote"); |
|
255 |
if (syntaxEndQuote1 == null && syntaxBeginQuote1 != null) |
|
256 |
syntaxEndQuote1 = syntaxBeginQuote1; |
|
257 |
else if (syntaxBeginQuote1 == null && syntaxEndQuote1 != null) |
|
258 |
syntaxBeginQuote1 = syntaxEndQuote1; |
|
259 |
syntaxBeginQuote2 = p.getProperty("jndi.syntax.beginquote2"); |
|
260 |
syntaxEndQuote2 = p.getProperty("jndi.syntax.endquote2"); |
|
261 |
if (syntaxEndQuote2 == null && syntaxBeginQuote2 != null) |
|
262 |
syntaxEndQuote2 = syntaxBeginQuote2; |
|
263 |
else if (syntaxBeginQuote2 == null && syntaxEndQuote2 != null) |
|
264 |
syntaxBeginQuote2 = syntaxEndQuote2; |
|
265 |
||
266 |
syntaxAvaSeparator = p.getProperty("jndi.syntax.separator.ava"); |
|
267 |
syntaxTypevalSeparator = |
|
268 |
p.getProperty("jndi.syntax.separator.typeval"); |
|
269 |
} |
|
270 |
||
271 |
NameImpl(Properties syntax) { |
|
272 |
if (syntax != null) { |
|
273 |
recordNamingConvention(syntax); |
|
274 |
} |
|
10324
e28265130e4f
7072353: JNDI libraries do not build with javac -Xlint:all -Werror
jjg
parents:
5506
diff
changeset
|
275 |
components = new Vector<>(); |
2 | 276 |
} |
277 |
||
278 |
NameImpl(Properties syntax, String n) throws InvalidNameException { |
|
279 |
this(syntax); |
|
280 |
||
281 |
boolean rToL = (syntaxDirection == RIGHT_TO_LEFT); |
|
282 |
boolean compsAllEmpty = true; |
|
283 |
int len = n.length(); |
|
284 |
||
285 |
for (int i = 0; i < len; ) { |
|
286 |
i = extractComp(n, i, len, components); |
|
287 |
||
288 |
String comp = rToL |
|
10324
e28265130e4f
7072353: JNDI libraries do not build with javac -Xlint:all -Werror
jjg
parents:
5506
diff
changeset
|
289 |
? components.firstElement() |
e28265130e4f
7072353: JNDI libraries do not build with javac -Xlint:all -Werror
jjg
parents:
5506
diff
changeset
|
290 |
: components.lastElement(); |
2 | 291 |
if (comp.length() >= 1) { |
292 |
compsAllEmpty = false; |
|
293 |
} |
|
294 |
||
295 |
if (i < len) { |
|
296 |
i = skipSeparator(n, i); |
|
297 |
if ((i == len) && !compsAllEmpty) { |
|
298 |
// Trailing separator found. Add an empty component. |
|
299 |
if (rToL) { |
|
300 |
components.insertElementAt("", 0); |
|
301 |
} else { |
|
302 |
components.addElement(""); |
|
303 |
} |
|
304 |
} |
|
305 |
} |
|
306 |
} |
|
307 |
} |
|
308 |
||
10324
e28265130e4f
7072353: JNDI libraries do not build with javac -Xlint:all -Werror
jjg
parents:
5506
diff
changeset
|
309 |
NameImpl(Properties syntax, Enumeration<String> comps) { |
2 | 310 |
this(syntax); |
311 |
||
312 |
// %% comps could shrink in the middle. |
|
313 |
while (comps.hasMoreElements()) |
|
314 |
components.addElement(comps.nextElement()); |
|
315 |
} |
|
316 |
/* |
|
317 |
// Determines whether this component needs any escaping. |
|
318 |
private final boolean escapingNeeded(String comp) { |
|
319 |
int len = comp.length(); |
|
320 |
for (int i = 0; i < len; i++) { |
|
321 |
if (i == 0) { |
|
322 |
if (isA(comp, 0, syntaxBeginQuote1) || |
|
323 |
isA(comp, 0, syntaxBeginQuote2)) { |
|
324 |
return (true); |
|
325 |
} |
|
326 |
} |
|
327 |
if (isSeparator(comp, i)) { |
|
328 |
return (true); |
|
329 |
} |
|
330 |
if (isA(comp, i, syntaxEscape)) { |
|
331 |
i += syntaxEscape.length(); |
|
332 |
if (i >= len || isMeta(comp, i)) { |
|
333 |
return (true); |
|
334 |
} |
|
335 |
} |
|
336 |
} |
|
337 |
return (false); |
|
338 |
} |
|
339 |
*/ |
|
340 |
private final String stringifyComp(String comp) { |
|
341 |
int len = comp.length(); |
|
342 |
boolean escapeSeparator = false, escapeSeparator2 = false; |
|
343 |
String beginQuote = null, endQuote = null; |
|
344 |
StringBuffer strbuf = new StringBuffer(len); |
|
345 |
||
346 |
// determine whether there are any separators; if so escape |
|
347 |
// or quote them |
|
348 |
if (syntaxSeparator != null && |
|
349 |
comp.indexOf(syntaxSeparator) >= 0) { |
|
350 |
if (syntaxBeginQuote1 != null) { |
|
351 |
beginQuote = syntaxBeginQuote1; |
|
352 |
endQuote = syntaxEndQuote1; |
|
353 |
} else if (syntaxBeginQuote2 != null) { |
|
354 |
beginQuote = syntaxBeginQuote2; |
|
355 |
endQuote = syntaxEndQuote2; |
|
356 |
} else if (syntaxEscape != null) |
|
357 |
escapeSeparator = true; |
|
358 |
} |
|
359 |
if (syntaxSeparator2 != null && |
|
360 |
comp.indexOf(syntaxSeparator2) >= 0) { |
|
361 |
if (syntaxBeginQuote1 != null) { |
|
362 |
if (beginQuote == null) { |
|
363 |
beginQuote = syntaxBeginQuote1; |
|
364 |
endQuote = syntaxEndQuote1; |
|
365 |
} |
|
366 |
} else if (syntaxBeginQuote2 != null) { |
|
367 |
if (beginQuote == null) { |
|
368 |
beginQuote = syntaxBeginQuote2; |
|
369 |
endQuote = syntaxEndQuote2; |
|
370 |
} |
|
371 |
} else if (syntaxEscape != null) |
|
372 |
escapeSeparator2 = true; |
|
373 |
} |
|
374 |
||
375 |
// if quoting component, |
|
376 |
if (beginQuote != null) { |
|
377 |
||
378 |
// start string off with opening quote |
|
379 |
strbuf = strbuf.append(beginQuote); |
|
380 |
||
381 |
// component is being quoted, so we only need to worry about |
|
382 |
// escaping end quotes that occur in component |
|
383 |
for (int i = 0; i < len; ) { |
|
384 |
if (comp.startsWith(endQuote, i)) { |
|
385 |
// end-quotes must be escaped when inside a quoted string |
|
386 |
strbuf.append(syntaxEscape).append(endQuote); |
|
387 |
i += endQuote.length(); |
|
388 |
} else { |
|
389 |
// no special treatment required |
|
390 |
strbuf.append(comp.charAt(i++)); |
|
391 |
} |
|
392 |
} |
|
393 |
||
394 |
// end with closing quote |
|
395 |
strbuf.append(endQuote); |
|
396 |
||
397 |
} else { |
|
398 |
||
399 |
// When component is not quoted, add escape for: |
|
400 |
// 1. leading quote |
|
401 |
// 2. an escape preceding any meta char |
|
402 |
// 3. an escape at the end of a component |
|
403 |
// 4. separator |
|
404 |
||
405 |
// go through characters in component and escape where necessary |
|
406 |
boolean start = true; |
|
407 |
for (int i = 0; i < len; ) { |
|
408 |
// leading quote must be escaped |
|
409 |
if (start && isA(comp, i, syntaxBeginQuote1)) { |
|
410 |
strbuf.append(syntaxEscape).append(syntaxBeginQuote1); |
|
411 |
i += syntaxBeginQuote1.length(); |
|
412 |
} else if (start && isA(comp, i, syntaxBeginQuote2)) { |
|
413 |
strbuf.append(syntaxEscape).append(syntaxBeginQuote2); |
|
414 |
i += syntaxBeginQuote2.length(); |
|
415 |
} else |
|
416 |
||
417 |
// Escape an escape preceding meta characters, or at end. |
|
418 |
// Other escapes pass through. |
|
419 |
if (isA(comp, i, syntaxEscape)) { |
|
420 |
if (i + syntaxEscape.length() >= len) { |
|
421 |
// escape an ending escape |
|
422 |
strbuf.append(syntaxEscape); |
|
423 |
} else if (isMeta(comp, i + syntaxEscape.length())) { |
|
424 |
// escape meta strings |
|
425 |
strbuf.append(syntaxEscape); |
|
426 |
} |
|
427 |
strbuf.append(syntaxEscape); |
|
428 |
i += syntaxEscape.length(); |
|
429 |
} else |
|
430 |
||
431 |
// escape unescaped separator |
|
432 |
if (escapeSeparator && comp.startsWith(syntaxSeparator, i)) { |
|
433 |
// escape separator |
|
434 |
strbuf.append(syntaxEscape).append(syntaxSeparator); |
|
435 |
i += syntaxSeparator.length(); |
|
436 |
} else if (escapeSeparator2 && |
|
437 |
comp.startsWith(syntaxSeparator2, i)) { |
|
438 |
// escape separator2 |
|
439 |
strbuf.append(syntaxEscape).append(syntaxSeparator2); |
|
440 |
i += syntaxSeparator2.length(); |
|
441 |
} else { |
|
442 |
// no special treatment required |
|
443 |
strbuf.append(comp.charAt(i++)); |
|
444 |
} |
|
445 |
start = false; |
|
446 |
} |
|
447 |
} |
|
448 |
return (strbuf.toString()); |
|
449 |
} |
|
450 |
||
451 |
public String toString() { |
|
452 |
StringBuffer answer = new StringBuffer(); |
|
453 |
String comp; |
|
454 |
boolean compsAllEmpty = true; |
|
455 |
int size = components.size(); |
|
456 |
||
457 |
for (int i = 0; i < size; i++) { |
|
458 |
if (syntaxDirection == RIGHT_TO_LEFT) { |
|
459 |
comp = |
|
10324
e28265130e4f
7072353: JNDI libraries do not build with javac -Xlint:all -Werror
jjg
parents:
5506
diff
changeset
|
460 |
stringifyComp(components.elementAt(size - 1 - i)); |
2 | 461 |
} else { |
10324
e28265130e4f
7072353: JNDI libraries do not build with javac -Xlint:all -Werror
jjg
parents:
5506
diff
changeset
|
462 |
comp = stringifyComp(components.elementAt(i)); |
2 | 463 |
} |
464 |
if ((i != 0) && (syntaxSeparator != null)) |
|
465 |
answer.append(syntaxSeparator); |
|
466 |
if (comp.length() >= 1) |
|
467 |
compsAllEmpty = false; |
|
468 |
answer = answer.append(comp); |
|
469 |
} |
|
470 |
if (compsAllEmpty && (size >= 1) && (syntaxSeparator != null)) |
|
471 |
answer = answer.append(syntaxSeparator); |
|
472 |
return (answer.toString()); |
|
473 |
} |
|
474 |
||
475 |
public boolean equals(Object obj) { |
|
476 |
if ((obj != null) && (obj instanceof NameImpl)) { |
|
477 |
NameImpl target = (NameImpl)obj; |
|
478 |
if (target.size() == this.size()) { |
|
10324
e28265130e4f
7072353: JNDI libraries do not build with javac -Xlint:all -Werror
jjg
parents:
5506
diff
changeset
|
479 |
Enumeration<String> mycomps = getAll(); |
e28265130e4f
7072353: JNDI libraries do not build with javac -Xlint:all -Werror
jjg
parents:
5506
diff
changeset
|
480 |
Enumeration<String> comps = target.getAll(); |
2 | 481 |
while (mycomps.hasMoreElements()) { |
482 |
// %% comps could shrink in the middle. |
|
10324
e28265130e4f
7072353: JNDI libraries do not build with javac -Xlint:all -Werror
jjg
parents:
5506
diff
changeset
|
483 |
String my = mycomps.nextElement(); |
e28265130e4f
7072353: JNDI libraries do not build with javac -Xlint:all -Werror
jjg
parents:
5506
diff
changeset
|
484 |
String his = comps.nextElement(); |
2 | 485 |
if (syntaxTrimBlanks) { |
486 |
my = my.trim(); |
|
487 |
his = his.trim(); |
|
488 |
} |
|
489 |
if (syntaxCaseInsensitive) { |
|
490 |
if (!(my.equalsIgnoreCase(his))) |
|
491 |
return false; |
|
492 |
} else { |
|
493 |
if (!(my.equals(his))) |
|
494 |
return false; |
|
495 |
} |
|
496 |
} |
|
497 |
return true; |
|
498 |
} |
|
499 |
} |
|
500 |
return false; |
|
501 |
} |
|
502 |
||
503 |
/** |
|
504 |
* Compares obj to this NameImpl to determine ordering. |
|
505 |
* Takes into account syntactic properties such as |
|
506 |
* elimination of blanks, case-ignore, etc, if relevant. |
|
507 |
* |
|
508 |
* Note: using syntax of this NameImpl and ignoring |
|
509 |
* that of comparison target. |
|
510 |
*/ |
|
511 |
public int compareTo(NameImpl obj) { |
|
512 |
if (this == obj) { |
|
513 |
return 0; |
|
514 |
} |
|
515 |
||
516 |
int len1 = size(); |
|
517 |
int len2 = obj.size(); |
|
518 |
int n = Math.min(len1, len2); |
|
519 |
||
520 |
int index1 = 0, index2 = 0; |
|
521 |
||
522 |
while (n-- != 0) { |
|
523 |
String comp1 = get(index1++); |
|
524 |
String comp2 = obj.get(index2++); |
|
525 |
||
526 |
// normalize according to syntax |
|
527 |
if (syntaxTrimBlanks) { |
|
528 |
comp1 = comp1.trim(); |
|
529 |
comp2 = comp2.trim(); |
|
530 |
} |
|
10369
e9d2e59e53f0
7059542: JNDI name operations should be locale independent
xuelei
parents:
10324
diff
changeset
|
531 |
|
e9d2e59e53f0
7059542: JNDI name operations should be locale independent
xuelei
parents:
10324
diff
changeset
|
532 |
int local; |
2 | 533 |
if (syntaxCaseInsensitive) { |
10369
e9d2e59e53f0
7059542: JNDI name operations should be locale independent
xuelei
parents:
10324
diff
changeset
|
534 |
local = comp1.compareToIgnoreCase(comp2); |
e9d2e59e53f0
7059542: JNDI name operations should be locale independent
xuelei
parents:
10324
diff
changeset
|
535 |
} else { |
e9d2e59e53f0
7059542: JNDI name operations should be locale independent
xuelei
parents:
10324
diff
changeset
|
536 |
local = comp1.compareTo(comp2); |
2 | 537 |
} |
10369
e9d2e59e53f0
7059542: JNDI name operations should be locale independent
xuelei
parents:
10324
diff
changeset
|
538 |
|
2 | 539 |
if (local != 0) { |
540 |
return local; |
|
541 |
} |
|
542 |
} |
|
543 |
||
544 |
return len1 - len2; |
|
545 |
} |
|
546 |
||
547 |
public int size() { |
|
548 |
return (components.size()); |
|
549 |
} |
|
550 |
||
10324
e28265130e4f
7072353: JNDI libraries do not build with javac -Xlint:all -Werror
jjg
parents:
5506
diff
changeset
|
551 |
public Enumeration<String> getAll() { |
2 | 552 |
return components.elements(); |
553 |
} |
|
554 |
||
555 |
public String get(int posn) { |
|
10324
e28265130e4f
7072353: JNDI libraries do not build with javac -Xlint:all -Werror
jjg
parents:
5506
diff
changeset
|
556 |
return components.elementAt(posn); |
2 | 557 |
} |
558 |
||
10324
e28265130e4f
7072353: JNDI libraries do not build with javac -Xlint:all -Werror
jjg
parents:
5506
diff
changeset
|
559 |
public Enumeration<String> getPrefix(int posn) { |
2 | 560 |
if (posn < 0 || posn > size()) { |
561 |
throw new ArrayIndexOutOfBoundsException(posn); |
|
562 |
} |
|
563 |
return new NameImplEnumerator(components, 0, posn); |
|
564 |
} |
|
565 |
||
10324
e28265130e4f
7072353: JNDI libraries do not build with javac -Xlint:all -Werror
jjg
parents:
5506
diff
changeset
|
566 |
public Enumeration<String> getSuffix(int posn) { |
2 | 567 |
int cnt = size(); |
568 |
if (posn < 0 || posn > cnt) { |
|
569 |
throw new ArrayIndexOutOfBoundsException(posn); |
|
570 |
} |
|
571 |
return new NameImplEnumerator(components, posn, cnt); |
|
572 |
} |
|
573 |
||
574 |
public boolean isEmpty() { |
|
575 |
return (components.isEmpty()); |
|
576 |
} |
|
577 |
||
10324
e28265130e4f
7072353: JNDI libraries do not build with javac -Xlint:all -Werror
jjg
parents:
5506
diff
changeset
|
578 |
public boolean startsWith(int posn, Enumeration<String> prefix) { |
2 | 579 |
if (posn < 0 || posn > size()) { |
580 |
return false; |
|
581 |
} |
|
582 |
try { |
|
10324
e28265130e4f
7072353: JNDI libraries do not build with javac -Xlint:all -Werror
jjg
parents:
5506
diff
changeset
|
583 |
Enumeration<String> mycomps = getPrefix(posn); |
2 | 584 |
while (mycomps.hasMoreElements()) { |
10324
e28265130e4f
7072353: JNDI libraries do not build with javac -Xlint:all -Werror
jjg
parents:
5506
diff
changeset
|
585 |
String my = mycomps.nextElement(); |
e28265130e4f
7072353: JNDI libraries do not build with javac -Xlint:all -Werror
jjg
parents:
5506
diff
changeset
|
586 |
String his = prefix.nextElement(); |
2 | 587 |
if (syntaxTrimBlanks) { |
588 |
my = my.trim(); |
|
589 |
his = his.trim(); |
|
590 |
} |
|
591 |
if (syntaxCaseInsensitive) { |
|
592 |
if (!(my.equalsIgnoreCase(his))) |
|
593 |
return false; |
|
594 |
} else { |
|
595 |
if (!(my.equals(his))) |
|
596 |
return false; |
|
597 |
} |
|
598 |
} |
|
599 |
} catch (NoSuchElementException e) { |
|
600 |
return false; |
|
601 |
} |
|
602 |
return true; |
|
603 |
} |
|
604 |
||
10324
e28265130e4f
7072353: JNDI libraries do not build with javac -Xlint:all -Werror
jjg
parents:
5506
diff
changeset
|
605 |
public boolean endsWith(int posn, Enumeration<String> suffix) { |
2 | 606 |
// posn is number of elements in suffix |
607 |
// startIndex is the starting position in this name |
|
608 |
// at which to start the comparison. It is calculated by |
|
609 |
// subtracting 'posn' from size() |
|
610 |
int startIndex = size() - posn; |
|
611 |
if (startIndex < 0 || startIndex > size()) { |
|
612 |
return false; |
|
613 |
} |
|
614 |
try { |
|
10324
e28265130e4f
7072353: JNDI libraries do not build with javac -Xlint:all -Werror
jjg
parents:
5506
diff
changeset
|
615 |
Enumeration<String> mycomps = getSuffix(startIndex); |
2 | 616 |
while (mycomps.hasMoreElements()) { |
10324
e28265130e4f
7072353: JNDI libraries do not build with javac -Xlint:all -Werror
jjg
parents:
5506
diff
changeset
|
617 |
String my = mycomps.nextElement(); |
e28265130e4f
7072353: JNDI libraries do not build with javac -Xlint:all -Werror
jjg
parents:
5506
diff
changeset
|
618 |
String his = suffix.nextElement(); |
2 | 619 |
if (syntaxTrimBlanks) { |
620 |
my = my.trim(); |
|
621 |
his = his.trim(); |
|
622 |
} |
|
623 |
if (syntaxCaseInsensitive) { |
|
624 |
if (!(my.equalsIgnoreCase(his))) |
|
625 |
return false; |
|
626 |
} else { |
|
627 |
if (!(my.equals(his))) |
|
628 |
return false; |
|
629 |
} |
|
630 |
} |
|
631 |
} catch (NoSuchElementException e) { |
|
632 |
return false; |
|
633 |
} |
|
634 |
return true; |
|
635 |
} |
|
636 |
||
10324
e28265130e4f
7072353: JNDI libraries do not build with javac -Xlint:all -Werror
jjg
parents:
5506
diff
changeset
|
637 |
public boolean addAll(Enumeration<String> comps) throws InvalidNameException { |
2 | 638 |
boolean added = false; |
639 |
while (comps.hasMoreElements()) { |
|
640 |
try { |
|
10324
e28265130e4f
7072353: JNDI libraries do not build with javac -Xlint:all -Werror
jjg
parents:
5506
diff
changeset
|
641 |
String comp = comps.nextElement(); |
2 | 642 |
if (size() > 0 && syntaxDirection == FLAT) { |
643 |
throw new InvalidNameException( |
|
644 |
"A flat name can only have a single component"); |
|
645 |
} |
|
646 |
components.addElement(comp); |
|
647 |
added = true; |
|
648 |
} catch (NoSuchElementException e) { |
|
649 |
break; // "comps" has shrunk. |
|
650 |
} |
|
651 |
} |
|
652 |
return added; |
|
653 |
} |
|
654 |
||
10324
e28265130e4f
7072353: JNDI libraries do not build with javac -Xlint:all -Werror
jjg
parents:
5506
diff
changeset
|
655 |
public boolean addAll(int posn, Enumeration<String> comps) |
2 | 656 |
throws InvalidNameException { |
657 |
boolean added = false; |
|
658 |
for (int i = posn; comps.hasMoreElements(); i++) { |
|
659 |
try { |
|
10324
e28265130e4f
7072353: JNDI libraries do not build with javac -Xlint:all -Werror
jjg
parents:
5506
diff
changeset
|
660 |
String comp = comps.nextElement(); |
2 | 661 |
if (size() > 0 && syntaxDirection == FLAT) { |
662 |
throw new InvalidNameException( |
|
663 |
"A flat name can only have a single component"); |
|
664 |
} |
|
665 |
components.insertElementAt(comp, i); |
|
666 |
added = true; |
|
667 |
} catch (NoSuchElementException e) { |
|
668 |
break; // "comps" has shrunk. |
|
669 |
} |
|
670 |
} |
|
671 |
return added; |
|
672 |
} |
|
673 |
||
674 |
public void add(String comp) throws InvalidNameException { |
|
675 |
if (size() > 0 && syntaxDirection == FLAT) { |
|
676 |
throw new InvalidNameException( |
|
677 |
"A flat name can only have a single component"); |
|
678 |
} |
|
679 |
components.addElement(comp); |
|
680 |
} |
|
681 |
||
682 |
public void add(int posn, String comp) throws InvalidNameException { |
|
683 |
if (size() > 0 && syntaxDirection == FLAT) { |
|
684 |
throw new InvalidNameException( |
|
685 |
"A flat name can only zero or one component"); |
|
686 |
} |
|
687 |
components.insertElementAt(comp, posn); |
|
688 |
} |
|
689 |
||
690 |
public Object remove(int posn) { |
|
691 |
Object r = components.elementAt(posn); |
|
692 |
components.removeElementAt(posn); |
|
693 |
return r; |
|
694 |
} |
|
695 |
||
696 |
public int hashCode() { |
|
697 |
int hash = 0; |
|
10324
e28265130e4f
7072353: JNDI libraries do not build with javac -Xlint:all -Werror
jjg
parents:
5506
diff
changeset
|
698 |
for (Enumeration<String> e = getAll(); e.hasMoreElements();) { |
e28265130e4f
7072353: JNDI libraries do not build with javac -Xlint:all -Werror
jjg
parents:
5506
diff
changeset
|
699 |
String comp = e.nextElement(); |
2 | 700 |
if (syntaxTrimBlanks) { |
701 |
comp = comp.trim(); |
|
702 |
} |
|
703 |
if (syntaxCaseInsensitive) { |
|
10369
e9d2e59e53f0
7059542: JNDI name operations should be locale independent
xuelei
parents:
10324
diff
changeset
|
704 |
comp = comp.toLowerCase(Locale.ENGLISH); |
2 | 705 |
} |
706 |
||
707 |
hash += comp.hashCode(); |
|
708 |
} |
|
709 |
return hash; |
|
710 |
} |
|
711 |
} |
|
712 |
||
713 |
final |
|
10324
e28265130e4f
7072353: JNDI libraries do not build with javac -Xlint:all -Werror
jjg
parents:
5506
diff
changeset
|
714 |
class NameImplEnumerator implements Enumeration<String> { |
e28265130e4f
7072353: JNDI libraries do not build with javac -Xlint:all -Werror
jjg
parents:
5506
diff
changeset
|
715 |
Vector<String> vector; |
2 | 716 |
int count; |
717 |
int limit; |
|
718 |
||
10324
e28265130e4f
7072353: JNDI libraries do not build with javac -Xlint:all -Werror
jjg
parents:
5506
diff
changeset
|
719 |
NameImplEnumerator(Vector<String> v, int start, int lim) { |
2 | 720 |
vector = v; |
721 |
count = start; |
|
722 |
limit = lim; |
|
723 |
} |
|
724 |
||
725 |
public boolean hasMoreElements() { |
|
726 |
return count < limit; |
|
727 |
} |
|
728 |
||
10324
e28265130e4f
7072353: JNDI libraries do not build with javac -Xlint:all -Werror
jjg
parents:
5506
diff
changeset
|
729 |
public String nextElement() { |
2 | 730 |
if (count < limit) { |
731 |
return vector.elementAt(count++); |
|
732 |
} |
|
733 |
throw new NoSuchElementException("NameImplEnumerator"); |
|
734 |
} |
|
735 |
} |