Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/src/java.naming/share/classes/javax/naming/CompoundName.java
41152 views
1
/*
2
* Copyright (c) 1999, 2020, 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.Enumeration;
29
import java.util.Properties;
30
31
/**
32
* This class represents a compound name -- a name from
33
* a hierarchical name space.
34
* Each component in a compound name is an atomic name.
35
* <p>
36
* The components of a compound name are numbered. The indexes of a
37
* compound name with N components range from 0 up to, but not including, N.
38
* This range may be written as [0,N).
39
* The most significant component is at index 0.
40
* An empty compound name has no components.
41
*
42
* <h2>Compound Name Syntax</h2>
43
* The syntax of a compound name is specified using a set of properties:
44
*<dl>
45
* <dt>jndi.syntax.direction
46
* <dd>Direction for parsing ("right_to_left", "left_to_right", "flat").
47
* If unspecified, defaults to "flat", which means the namespace is flat
48
* with no hierarchical structure.
49
*
50
* <dt>jndi.syntax.separator
51
* <dd>Separator between atomic name components.
52
* Required unless direction is "flat".
53
*
54
* <dt>jndi.syntax.ignorecase
55
* <dd>If present, "true" means ignore the case when comparing name
56
* components. If its value is not "true", or if the property is not
57
* present, case is considered when comparing name components.
58
*
59
* <dt>jndi.syntax.escape
60
* <dd>If present, specifies the escape string for overriding separator,
61
* escapes and quotes.
62
*
63
* <dt>jndi.syntax.beginquote
64
* <dd>If present, specifies the string delimiting start of a quoted string.
65
*
66
* <dt>jndi.syntax.endquote
67
* <dd>String delimiting end of quoted string.
68
* If present, specifies the string delimiting the end of a quoted string.
69
* If not present, use syntax.beginquote as end quote.
70
* <dt>jndi.syntax.beginquote2
71
* <dd>Alternative set of begin/end quotes.
72
*
73
* <dt>jndi.syntax.endquote2
74
* <dd>Alternative set of begin/end quotes.
75
*
76
* <dt>jndi.syntax.trimblanks
77
* <dd>If present, "true" means trim any leading and trailing whitespaces
78
* in a name component for comparison purposes. If its value is not
79
* "true", or if the property is not present, blanks are significant.
80
* <dt>jndi.syntax.separator.ava
81
* <dd>If present, specifies the string that separates
82
* attribute-value-assertions when specifying multiple attribute/value
83
* pairs. (e.g. "," in age=65,gender=male).
84
* <dt>jndi.syntax.separator.typeval
85
* <dd>If present, specifies the string that separates attribute
86
* from value (e.g. "=" in "age=65")
87
*</dl>
88
* These properties are interpreted according to the following rules:
89
*<ol>
90
*<li>
91
* In a string without quotes or escapes, any instance of the
92
* separator delimits two atomic names. Each atomic name is referred
93
* to as a <em>component</em>.
94
*<li>
95
* A separator, quote or escape is escaped if preceded immediately
96
* (on the left) by the escape.
97
*<li>
98
* If there are two sets of quotes, a specific begin-quote must be matched
99
* by its corresponding end-quote.
100
*<li>
101
* A non-escaped begin-quote which precedes a component must be
102
* matched by a non-escaped end-quote at the end of the component.
103
* A component thus quoted is referred to as a
104
* <em>quoted component</em>. It is parsed by
105
* removing the being- and end- quotes, and by treating the intervening
106
* characters as ordinary characters unless one of the rules involving
107
* quoted components listed below applies.
108
*<li>
109
* Quotes embedded in non-quoted components are treated as ordinary strings
110
* and need not be matched.
111
*<li>
112
* A separator that is escaped or appears between non-escaped
113
* quotes is treated as an ordinary string and not a separator.
114
*<li>
115
* An escape string within a quoted component acts as an escape only when
116
* followed by the corresponding end-quote string.
117
* This can be used to embed an escaped quote within a quoted component.
118
*<li>
119
* An escaped escape string is not treated as an escape string.
120
*<li>
121
* An escape string that does not precede a meta string (quotes or separator)
122
* and is not at the end of a component is treated as an ordinary string.
123
*<li>
124
* A leading separator (the compound name string begins with
125
* a separator) denotes a leading empty atomic component (consisting
126
* of an empty string).
127
* A trailing separator (the compound name string ends with
128
* a separator) denotes a trailing empty atomic component.
129
* Adjacent separators denote an empty atomic component.
130
*</ol>
131
* <p>
132
* The string form of the compound name follows the syntax described above.
133
* When the components of the compound name are turned into their
134
* string representation, the reserved syntax rules described above are
135
* applied (e.g. embedded separators are escaped or quoted)
136
* so that when the same string is parsed, it will yield the same components
137
* of the original compound name.
138
*
139
*<h2>Multithreaded Access</h2>
140
* A {@code CompoundName} instance is not synchronized against concurrent
141
* multithreaded access. Multiple threads trying to access and modify a
142
* {@code CompoundName} should lock the object.
143
*
144
* @author Rosanna Lee
145
* @author Scott Seligman
146
* @since 1.3
147
*/
148
149
public class CompoundName implements Name {
150
151
/**
152
* Implementation of this compound name. This field is initialized by the
153
* constructors and cannot be null.
154
*/
155
private transient NameImpl impl;
156
/**
157
* Syntax properties for this compound name.
158
* This field is initialized by the constructors and cannot be null.
159
* It should be treated as a read-only variable by subclasses.
160
* Any necessary changes to mySyntax should be made within constructors
161
* and not after the compound name has been instantiated.
162
*/
163
protected transient Properties mySyntax;
164
165
/**
166
* Constructs a new compound name instance using the components
167
* specified in comps and syntax. This protected method is intended
168
* to be used by subclasses of CompoundName when they override
169
* methods such as clone(), getPrefix(), getSuffix().
170
*
171
* @param comps A non-null enumeration of the components to add.
172
* Each element of the enumeration is of class String.
173
* The enumeration will be consumed to extract its
174
* elements.
175
* @param syntax A non-null properties that specify the syntax of
176
* this compound name. See class description for
177
* contents of properties.
178
*/
179
protected CompoundName(Enumeration<String> comps, Properties syntax) {
180
if (syntax == null) {
181
throw new NullPointerException();
182
}
183
mySyntax = syntax;
184
impl = new NameImpl(syntax, comps);
185
}
186
187
/**
188
* Constructs a new compound name instance by parsing the string n
189
* using the syntax specified by the syntax properties supplied.
190
*
191
* @param n The non-null string to parse.
192
* @param syntax A non-null list of properties that specify the syntax of
193
* this compound name. See class description for
194
* contents of properties.
195
* @throws InvalidNameException If 'n' violates the syntax specified
196
* by {@code syntax}.
197
*/
198
public CompoundName(String n, Properties syntax) throws InvalidNameException {
199
if (syntax == null) {
200
throw new NullPointerException();
201
}
202
mySyntax = syntax;
203
impl = new NameImpl(syntax, n);
204
}
205
206
/**
207
* Generates the string representation of this compound name, using
208
* the syntax rules of the compound name. The syntax rules
209
* are described in the class description.
210
* An empty component is represented by an empty string.
211
*
212
* The string representation thus generated can be passed to
213
* the CompoundName constructor with the same syntax properties
214
* to create a new equivalent compound name.
215
*
216
* @return A non-null string representation of this compound name.
217
*/
218
public String toString() {
219
return (impl.toString());
220
}
221
222
/**
223
* Determines whether obj is syntactically equal to this compound name.
224
* If obj is null or not a CompoundName, false is returned.
225
* Two compound names are equal if each component in one is "equal"
226
* to the corresponding component in the other.
227
*<p>
228
* Equality is also defined in terms of the syntax of this compound name.
229
* The default implementation of CompoundName uses the syntax properties
230
* jndi.syntax.ignorecase and jndi.syntax.trimblanks when comparing
231
* two components for equality. If case is ignored, two strings
232
* with the same sequence of characters but with different cases
233
* are considered equal. If blanks are being trimmed, leading and trailing
234
* blanks are ignored for the purpose of the comparison.
235
*<p>
236
* Both compound names must have the same number of components.
237
*<p>
238
* Implementation note: Currently the syntax properties of the two compound
239
* names are not compared for equality. They might be in the future.
240
*
241
* @param obj The possibly null object to compare against.
242
* @return true if obj is equal to this compound name, false otherwise.
243
* @see #compareTo(java.lang.Object obj)
244
*/
245
public boolean equals(Object obj) {
246
// %%% check syntax too?
247
return (obj != null &&
248
obj instanceof CompoundName &&
249
impl.equals(((CompoundName)obj).impl));
250
}
251
252
/**
253
* Computes the hash code of this compound name.
254
* The hash code is the sum of the hash codes of the "canonicalized"
255
* forms of individual components of this compound name.
256
* Each component is "canonicalized" according to the
257
* compound name's syntax before its hash code is computed.
258
* For a case-insensitive name, for example, the uppercased form of
259
* a name has the same hash code as its lowercased equivalent.
260
*
261
* @return An int representing the hash code of this name.
262
*/
263
public int hashCode() {
264
return impl.hashCode();
265
}
266
267
/**
268
* Creates a copy of this compound name.
269
* Changes to the components of this compound name won't
270
* affect the new copy and vice versa.
271
* The clone and this compound name share the same syntax.
272
*
273
* @return A non-null copy of this compound name.
274
*/
275
public Object clone() {
276
return (new CompoundName(getAll(), mySyntax));
277
}
278
279
/**
280
* Compares this CompoundName with the specified Object for order.
281
* Returns a
282
* negative integer, zero, or a positive integer as this Name is less
283
* than, equal to, or greater than the given Object.
284
* <p>
285
* If obj is null or not an instance of CompoundName, ClassCastException
286
* is thrown.
287
* <p>
288
* See equals() for what it means for two compound names to be equal.
289
* If two compound names are equal, 0 is returned.
290
*<p>
291
* Ordering of compound names depend on the syntax of the compound name.
292
* By default, they follow lexicographical rules for string comparison
293
* with the extension that this applies to all the components in the
294
* compound name and that comparison of individual components is
295
* affected by the jndi.syntax.ignorecase and jndi.syntax.trimblanks
296
* properties, identical to how they affect equals().
297
* If this compound name is "lexicographically" lesser than obj,
298
* a negative number is returned.
299
* If this compound name is "lexicographically" greater than obj,
300
* a positive number is returned.
301
*<p>
302
* Implementation note: Currently the syntax properties of the two compound
303
* names are not compared when checking order. They might be in the future.
304
* @param obj The non-null object to compare against.
305
* @return a negative integer, zero, or a positive integer as this Name
306
* is less than, equal to, or greater than the given Object.
307
* @throws ClassCastException if obj is not a CompoundName.
308
* @see #equals(java.lang.Object)
309
*/
310
public int compareTo(Object obj) {
311
if (!(obj instanceof CompoundName)) {
312
throw new ClassCastException("Not a CompoundName");
313
}
314
return impl.compareTo(((CompoundName)obj).impl);
315
}
316
317
/**
318
* Retrieves the number of components in this compound name.
319
*
320
* @return The nonnegative number of components in this compound name.
321
*/
322
public int size() {
323
return (impl.size());
324
}
325
326
/**
327
* Determines whether this compound name is empty.
328
* A compound name is empty if it has zero components.
329
*
330
* @return true if this compound name is empty, false otherwise.
331
*/
332
public boolean isEmpty() {
333
return (impl.isEmpty());
334
}
335
336
/**
337
* Retrieves the components of this compound name as an enumeration
338
* of strings.
339
* The effects of updates to this compound name on this enumeration
340
* is undefined.
341
*
342
* @return A non-null enumeration of the components of this
343
* compound name. Each element of the enumeration is of class String.
344
*/
345
public Enumeration<String> getAll() {
346
return (impl.getAll());
347
}
348
349
/**
350
* Retrieves a component of this compound name.
351
*
352
* @param posn The 0-based index of the component to retrieve.
353
* Must be in the range [0,size()).
354
* @return The component at index posn.
355
* @throws ArrayIndexOutOfBoundsException if posn is outside the
356
* specified range.
357
*/
358
public String get(int posn) {
359
return (impl.get(posn));
360
}
361
362
/**
363
* Creates a compound name whose components consist of a prefix of the
364
* components in this compound name.
365
* The result and this compound name share the same syntax.
366
* Subsequent changes to
367
* this compound name do not affect the name that is returned and
368
* vice versa.
369
*
370
* @param posn The 0-based index of the component at which to stop.
371
* Must be in the range [0,size()].
372
* @return A compound name consisting of the components at indexes in
373
* the range [0,posn).
374
* @throws ArrayIndexOutOfBoundsException
375
* If posn is outside the specified range.
376
*/
377
public Name getPrefix(int posn) {
378
Enumeration<String> comps = impl.getPrefix(posn);
379
return (new CompoundName(comps, mySyntax));
380
}
381
382
/**
383
* Creates a compound name whose components consist of a suffix of the
384
* components in this compound name.
385
* The result and this compound name share the same syntax.
386
* Subsequent changes to
387
* this compound name do not affect the name that is returned.
388
*
389
* @param posn The 0-based index of the component at which to start.
390
* Must be in the range [0,size()].
391
* @return A compound name consisting of the components at indexes in
392
* the range [posn,size()). If posn is equal to
393
* size(), an empty compound name is returned.
394
* @throws ArrayIndexOutOfBoundsException
395
* If posn is outside the specified range.
396
*/
397
public Name getSuffix(int posn) {
398
Enumeration<String> comps = impl.getSuffix(posn);
399
return (new CompoundName(comps, mySyntax));
400
}
401
402
/**
403
* Determines whether a compound name is a prefix of this compound name.
404
* A compound name 'n' is a prefix if it is equal to
405
* getPrefix(n.size())--in other words, this compound name
406
* starts with 'n'.
407
* If n is null or not a compound name, false is returned.
408
*<p>
409
* Implementation note: Currently the syntax properties of n
410
* are not used when doing the comparison. They might be in the future.
411
* @param n The possibly null compound name to check.
412
* @return true if n is a CompoundName and
413
* is a prefix of this compound name, false otherwise.
414
*/
415
public boolean startsWith(Name n) {
416
if (n instanceof CompoundName) {
417
return (impl.startsWith(n.size(), n.getAll()));
418
} else {
419
return false;
420
}
421
}
422
423
/**
424
* Determines whether a compound name is a suffix of this compound name.
425
* A compound name 'n' is a suffix if it is equal to
426
* getSuffix(size()-n.size())--in other words, this
427
* compound name ends with 'n'.
428
* If n is null or not a compound name, false is returned.
429
*<p>
430
* Implementation note: Currently the syntax properties of n
431
* are not used when doing the comparison. They might be in the future.
432
* @param n The possibly null compound name to check.
433
* @return true if n is a CompoundName and
434
* is a suffix of this compound name, false otherwise.
435
*/
436
public boolean endsWith(Name n) {
437
if (n instanceof CompoundName) {
438
return (impl.endsWith(n.size(), n.getAll()));
439
} else {
440
return false;
441
}
442
}
443
444
/**
445
* Adds the components of a compound name -- in order -- to the end of
446
* this compound name.
447
*<p>
448
* Implementation note: Currently the syntax properties of suffix
449
* is not used or checked. They might be in the future.
450
* @param suffix The non-null components to add.
451
* @return The updated CompoundName, not a new one. Cannot be null.
452
* @throws InvalidNameException If suffix is not a compound name,
453
* or if the addition of the components violates the syntax
454
* of this compound name (e.g. exceeding number of components).
455
*/
456
public Name addAll(Name suffix) throws InvalidNameException {
457
if (suffix instanceof CompoundName) {
458
impl.addAll(suffix.getAll());
459
return this;
460
} else {
461
throw new InvalidNameException("Not a compound name: " +
462
suffix.toString());
463
}
464
}
465
466
/**
467
* Adds the components of a compound name -- in order -- at a specified
468
* position within this compound name.
469
* Components of this compound name at or after the index of the first
470
* new component are shifted up (away from index 0)
471
* to accommodate the new components.
472
*<p>
473
* Implementation note: Currently the syntax properties of suffix
474
* is not used or checked. They might be in the future.
475
*
476
* @param n The non-null components to add.
477
* @param posn The index in this name at which to add the new
478
* components. Must be in the range [0,size()].
479
* @return The updated CompoundName, not a new one. Cannot be null.
480
* @throws ArrayIndexOutOfBoundsException
481
* If posn is outside the specified range.
482
* @throws InvalidNameException If n is not a compound name,
483
* or if the addition of the components violates the syntax
484
* of this compound name (e.g. exceeding number of components).
485
*/
486
public Name addAll(int posn, Name n) throws InvalidNameException {
487
if (n instanceof CompoundName) {
488
impl.addAll(posn, n.getAll());
489
return this;
490
} else {
491
throw new InvalidNameException("Not a compound name: " +
492
n.toString());
493
}
494
}
495
496
/**
497
* Adds a single component to the end of this compound name.
498
*
499
* @param comp The non-null component to add.
500
* @return The updated CompoundName, not a new one. Cannot be null.
501
* @throws InvalidNameException If adding comp at end of the name
502
* would violate the compound name's syntax.
503
*/
504
public Name add(String comp) throws InvalidNameException{
505
impl.add(comp);
506
return this;
507
}
508
509
/**
510
* Adds a single component at a specified position within this
511
* compound name.
512
* Components of this compound name at or after the index of the new
513
* component are shifted up by one (away from index 0)
514
* to accommodate the new component.
515
*
516
* @param comp The non-null component to add.
517
* @param posn The index at which to add the new component.
518
* Must be in the range [0,size()].
519
* @throws ArrayIndexOutOfBoundsException
520
* If posn is outside the specified range.
521
* @return The updated CompoundName, not a new one. Cannot be null.
522
* @throws InvalidNameException If adding comp at the specified position
523
* would violate the compound name's syntax.
524
*/
525
public Name add(int posn, String comp) throws InvalidNameException{
526
impl.add(posn, comp);
527
return this;
528
}
529
530
/**
531
* Deletes a component from this compound name.
532
* The component of this compound name at position 'posn' is removed,
533
* and components at indices greater than 'posn'
534
* are shifted down (towards index 0) by one.
535
*
536
* @param posn The index of the component to delete.
537
* Must be in the range [0,size()).
538
* @return The component removed (a String).
539
* @throws ArrayIndexOutOfBoundsException
540
* If posn is outside the specified range (includes case where
541
* compound name is empty).
542
* @throws InvalidNameException If deleting the component
543
* would violate the compound name's syntax.
544
*/
545
public Object remove(int posn) throws InvalidNameException {
546
return impl.remove(posn);
547
}
548
549
/**
550
* The writeObject method is called to save the state of the
551
* {@code CompoundName} to a stream.
552
*
553
* @serialData The syntax {@code Properties}, followed by
554
* the number of components (an {@code int}), and the individual
555
* components (each a {@code String}).
556
*
557
* @param s the {@code ObjectOutputStream} to write to
558
* @throws java.io.IOException if an I/O error occurs
559
*/
560
@java.io.Serial
561
private void writeObject(java.io.ObjectOutputStream s)
562
throws java.io.IOException {
563
// Overridden to avoid implementation dependency
564
s.writeObject(mySyntax);
565
s.writeInt(size());
566
Enumeration<String> comps = getAll();
567
while (comps.hasMoreElements()) {
568
s.writeObject(comps.nextElement());
569
}
570
}
571
572
/**
573
* The readObject method is called to restore the state of
574
* the {@code CompoundName} from a stream.
575
*
576
* See {@code writeObject} for a description of the serial form.
577
*
578
* @param s the {@code ObjectInputStream} to read from
579
* @throws java.io.IOException if an I/O error occurs
580
* @throws ClassNotFoundException if the class of a serialized object
581
* could not be found
582
*/
583
@java.io.Serial
584
private void readObject(java.io.ObjectInputStream s)
585
throws java.io.IOException, ClassNotFoundException {
586
// Overridden to avoid implementation dependency.
587
mySyntax = (Properties)s.readObject();
588
impl = new NameImpl(mySyntax);
589
int n = s.readInt(); // number of components
590
try {
591
while (--n >= 0) {
592
add((String)s.readObject());
593
}
594
} catch (InvalidNameException e) {
595
throw (new java.io.StreamCorruptedException("Invalid name"));
596
}
597
}
598
599
/**
600
* Use serialVersionUID from JNDI 1.1.1 for interoperability
601
*/
602
@java.io.Serial
603
private static final long serialVersionUID = 3513100557083972036L;
604
605
/*
606
// For testing
607
608
public static void main(String[] args) {
609
Properties dotSyntax = new Properties();
610
dotSyntax.put("jndi.syntax.direction", "right_to_left");
611
dotSyntax.put("jndi.syntax.separator", ".");
612
dotSyntax.put("jndi.syntax.ignorecase", "true");
613
dotSyntax.put("jndi.syntax.escape", "\\");
614
// dotSyntax.put("jndi.syntax.beginquote", "\"");
615
// dotSyntax.put("jndi.syntax.beginquote2", "'");
616
617
Name first = null;
618
try {
619
for (int i = 0; i < args.length; i++) {
620
Name name;
621
Enumeration e;
622
System.out.println("Given name: " + args[i]);
623
name = new CompoundName(args[i], dotSyntax);
624
if (first == null) {
625
first = name;
626
}
627
e = name.getComponents();
628
while (e.hasMoreElements()) {
629
System.out.println("Element: " + e.nextElement());
630
}
631
System.out.println("Constructed name: " + name.toString());
632
633
System.out.println("Compare " + first.toString() + " with "
634
+ name.toString() + " = " + first.compareTo(name));
635
}
636
} catch (Exception ne) {
637
ne.printStackTrace();
638
}
639
}
640
*/
641
}
642
643