Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/src/java.naming/share/classes/javax/naming/NameImpl.java
41152 views
1
/*
2
* Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved.
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
7
* published by the Free Software Foundation. Oracle designates this
8
* particular file as subject to the "Classpath" exception as provided
9
* by Oracle in the LICENSE file that accompanied this code.
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
*
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.
24
*/
25
26
package javax.naming;
27
28
import java.util.Locale;
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
49
private Vector<String> components;
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
101
private final int extractComp(String name, int i, int len, Vector<String> comps)
102
throws InvalidNameException {
103
String beginQuote;
104
String endQuote;
105
boolean start = true;
106
boolean one = false;
107
StringBuilder answer = new StringBuilder(len);
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).append(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) {
220
return ((name != null) &&
221
name.toLowerCase(Locale.ENGLISH).equals("true"));
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 +
235
" is not a valid value for the jndi.syntax.direction property");
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
}
275
components = new Vector<>();
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
289
? components.firstElement()
290
: components.lastElement();
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
309
NameImpl(Properties syntax, Enumeration<String> comps) {
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 =
460
stringifyComp(components.elementAt(size - 1 - i));
461
} else {
462
comp = stringifyComp(components.elementAt(i));
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()) {
479
Enumeration<String> mycomps = getAll();
480
Enumeration<String> comps = target.getAll();
481
while (mycomps.hasMoreElements()) {
482
// %% comps could shrink in the middle.
483
String my = mycomps.nextElement();
484
String his = comps.nextElement();
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
}
531
532
int local;
533
if (syntaxCaseInsensitive) {
534
local = comp1.compareToIgnoreCase(comp2);
535
} else {
536
local = comp1.compareTo(comp2);
537
}
538
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
551
public Enumeration<String> getAll() {
552
return components.elements();
553
}
554
555
public String get(int posn) {
556
return components.elementAt(posn);
557
}
558
559
public Enumeration<String> getPrefix(int posn) {
560
if (posn < 0 || posn > size()) {
561
throw new ArrayIndexOutOfBoundsException(posn);
562
}
563
return new NameImplEnumerator(components, 0, posn);
564
}
565
566
public Enumeration<String> getSuffix(int posn) {
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
578
public boolean startsWith(int posn, Enumeration<String> prefix) {
579
if (posn < 0 || posn > size()) {
580
return false;
581
}
582
try {
583
Enumeration<String> mycomps = getPrefix(posn);
584
while (mycomps.hasMoreElements()) {
585
String my = mycomps.nextElement();
586
String his = prefix.nextElement();
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
605
public boolean endsWith(int posn, Enumeration<String> suffix) {
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 {
615
Enumeration<String> mycomps = getSuffix(startIndex);
616
while (mycomps.hasMoreElements()) {
617
String my = mycomps.nextElement();
618
String his = suffix.nextElement();
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
637
public boolean addAll(Enumeration<String> comps) throws InvalidNameException {
638
boolean added = false;
639
while (comps.hasMoreElements()) {
640
try {
641
String comp = comps.nextElement();
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
655
public boolean addAll(int posn, Enumeration<String> comps)
656
throws InvalidNameException {
657
boolean added = false;
658
for (int i = posn; comps.hasMoreElements(); i++) {
659
try {
660
String comp = comps.nextElement();
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;
698
for (Enumeration<String> e = getAll(); e.hasMoreElements();) {
699
String comp = e.nextElement();
700
if (syntaxTrimBlanks) {
701
comp = comp.trim();
702
}
703
if (syntaxCaseInsensitive) {
704
comp = comp.toLowerCase(Locale.ENGLISH);
705
}
706
707
hash += comp.hashCode();
708
}
709
return hash;
710
}
711
}
712
713
final
714
class NameImplEnumerator implements Enumeration<String> {
715
Vector<String> vector;
716
int count;
717
int limit;
718
719
NameImplEnumerator(Vector<String> v, int start, int lim) {
720
vector = v;
721
count = start;
722
limit = lim;
723
}
724
725
public boolean hasMoreElements() {
726
return count < limit;
727
}
728
729
public String nextElement() {
730
if (count < limit) {
731
return vector.elementAt(count++);
732
}
733
throw new NoSuchElementException("NameImplEnumerator");
734
}
735
}
736
737