Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openjdk-multiarch-jdk8u
Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/share/classes/javax/naming/CompoundName.java
38829 views
1
/*
2
* Copyright (c) 1999, 2013, 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
* <h1>Compound Name Syntax</h1>
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 separators 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
*<h1>Multithreaded Access</h1>
140
* A <tt>CompoundName</tt> instance is not synchronized against concurrent
141
* multithreaded access. Multiple threads trying to access and modify a
142
* <tt>CompoundName</tt> 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.
153
* This field is initialized by the constructors and cannot be null.
154
* It should be treated as a read-only variable by subclasses.
155
*/
156
protected transient NameImpl impl;
157
/**
158
* Syntax properties for this compound name.
159
* This field is initialized by the constructors and cannot be null.
160
* It should be treated as a read-only variable by subclasses.
161
* Any necessary changes to mySyntax should be made within constructors
162
* and not after the compound name has been instantiated.
163
*/
164
protected transient Properties mySyntax;
165
166
/**
167
* Constructs a new compound name instance using the components
168
* specified in comps and syntax. This protected method is intended to be
169
* to be used by subclasses of CompoundName when they override
170
* methods such as clone(), getPrefix(), getSuffix().
171
*
172
* @param comps A non-null enumeration of the components to add.
173
* Each element of the enumeration is of class String.
174
* The enumeration will be consumed to extract its
175
* elements.
176
* @param syntax A non-null properties that specify the syntax of
177
* this compound name. See class description for
178
* contents of properties.
179
*/
180
protected CompoundName(Enumeration<String> comps, Properties syntax) {
181
if (syntax == null) {
182
throw new NullPointerException();
183
}
184
mySyntax = syntax;
185
impl = new NameImpl(syntax, comps);
186
}
187
188
/**
189
* Constructs a new compound name instance by parsing the string n
190
* using the syntax specified by the syntax properties supplied.
191
*
192
* @param n The non-null string to parse.
193
* @param syntax A non-null list of properties that specify the syntax of
194
* this compound name. See class description for
195
* contents of properties.
196
* @exception InvalidNameException If 'n' violates the syntax specified
197
* by <code>syntax</code>.
198
*/
199
public CompoundName(String n, Properties syntax) throws InvalidNameException {
200
if (syntax == null) {
201
throw new NullPointerException();
202
}
203
mySyntax = syntax;
204
impl = new NameImpl(syntax, n);
205
}
206
207
/**
208
* Generates the string representation of this compound name, using
209
* the syntax rules of the compound name. The syntax rules
210
* are described in the class description.
211
* An empty component is represented by an empty string.
212
*
213
* The string representation thus generated can be passed to
214
* the CompoundName constructor with the same syntax properties
215
* to create a new equivalent compound name.
216
*
217
* @return A non-null string representation of this compound name.
218
*/
219
public String toString() {
220
return (impl.toString());
221
}
222
223
/**
224
* Determines whether obj is syntactically equal to this compound name.
225
* If obj is null or not a CompoundName, false is returned.
226
* Two compound names are equal if each component in one is "equal"
227
* to the corresponding component in the other.
228
*<p>
229
* Equality is also defined in terms of the syntax of this compound name.
230
* The default implementation of CompoundName uses the syntax properties
231
* jndi.syntax.ignorecase and jndi.syntax.trimblanks when comparing
232
* two components for equality. If case is ignored, two strings
233
* with the same sequence of characters but with different cases
234
* are considered equal. If blanks are being trimmed, leading and trailing
235
* blanks are ignored for the purpose of the comparison.
236
*<p>
237
* Both compound names must have the same number of components.
238
*<p>
239
* Implementation note: Currently the syntax properties of the two compound
240
* names are not compared for equality. They might be in the future.
241
*
242
* @param obj The possibly null object to compare against.
243
* @return true if obj is equal to this compound name, false otherwise.
244
* @see #compareTo(java.lang.Object obj)
245
*/
246
public boolean equals(Object obj) {
247
// %%% check syntax too?
248
return (obj != null &&
249
obj instanceof CompoundName &&
250
impl.equals(((CompoundName)obj).impl));
251
}
252
253
/**
254
* Computes the hash code of this compound name.
255
* The hash code is the sum of the hash codes of the "canonicalized"
256
* forms of individual components of this compound name.
257
* Each component is "canonicalized" according to the
258
* compound name's syntax before its hash code is computed.
259
* For a case-insensitive name, for example, the uppercased form of
260
* a name has the same hash code as its lowercased equivalent.
261
*
262
* @return An int representing the hash code of this name.
263
*/
264
public int hashCode() {
265
return impl.hashCode();
266
}
267
268
/**
269
* Creates a copy of this compound name.
270
* Changes to the components of this compound name won't
271
* affect the new copy and vice versa.
272
* The clone and this compound name share the same syntax.
273
*
274
* @return A non-null copy of this compound name.
275
*/
276
public Object clone() {
277
return (new CompoundName(getAll(), mySyntax));
278
}
279
280
/**
281
* Compares this CompoundName with the specified Object for order.
282
* Returns a
283
* negative integer, zero, or a positive integer as this Name is less
284
* than, equal to, or greater than the given Object.
285
* <p>
286
* If obj is null or not an instance of CompoundName, ClassCastException
287
* is thrown.
288
* <p>
289
* See equals() for what it means for two compound names to be equal.
290
* If two compound names are equal, 0 is returned.
291
*<p>
292
* Ordering of compound names depend on the syntax of the compound name.
293
* By default, they follow lexicographical rules for string comparison
294
* with the extension that this applies to all the components in the
295
* compound name and that comparison of individual components is
296
* affected by the jndi.syntax.ignorecase and jndi.syntax.trimblanks
297
* properties, identical to how they affect equals().
298
* If this compound name is "lexicographically" lesser than obj,
299
* a negative number is returned.
300
* If this compound name is "lexicographically" greater than obj,
301
* a positive number is returned.
302
*<p>
303
* Implementation note: Currently the syntax properties of the two compound
304
* names are not compared when checking order. They might be in the future.
305
* @param obj The non-null object to compare against.
306
* @return a negative integer, zero, or a positive integer as this Name
307
* is less than, equal to, or greater than the given Object.
308
* @exception ClassCastException if obj is not a CompoundName.
309
* @see #equals(java.lang.Object)
310
*/
311
public int compareTo(Object obj) {
312
if (!(obj instanceof CompoundName)) {
313
throw new ClassCastException("Not a CompoundName");
314
}
315
return impl.compareTo(((CompoundName)obj).impl);
316
}
317
318
/**
319
* Retrieves the number of components in this compound name.
320
*
321
* @return The nonnegative number of components in this compound name.
322
*/
323
public int size() {
324
return (impl.size());
325
}
326
327
/**
328
* Determines whether this compound name is empty.
329
* A compound name is empty if it has zero components.
330
*
331
* @return true if this compound name is empty, false otherwise.
332
*/
333
public boolean isEmpty() {
334
return (impl.isEmpty());
335
}
336
337
/**
338
* Retrieves the components of this compound name as an enumeration
339
* of strings.
340
* The effects of updates to this compound name on this enumeration
341
* is undefined.
342
*
343
* @return A non-null enumeration of the components of this
344
* compound name. Each element of the enumeration is of class String.
345
*/
346
public Enumeration<String> getAll() {
347
return (impl.getAll());
348
}
349
350
/**
351
* Retrieves a component of this compound name.
352
*
353
* @param posn The 0-based index of the component to retrieve.
354
* Must be in the range [0,size()).
355
* @return The component at index posn.
356
* @exception ArrayIndexOutOfBoundsException if posn is outside the
357
* specified range.
358
*/
359
public String get(int posn) {
360
return (impl.get(posn));
361
}
362
363
/**
364
* Creates a compound name whose components consist of a prefix of the
365
* components in this compound name.
366
* The result and this compound name share the same syntax.
367
* Subsequent changes to
368
* this compound name does not affect the name that is returned and
369
* vice versa.
370
*
371
* @param posn The 0-based index of the component at which to stop.
372
* Must be in the range [0,size()].
373
* @return A compound name consisting of the components at indexes in
374
* the range [0,posn).
375
* @exception ArrayIndexOutOfBoundsException
376
* If posn is outside the specified range.
377
*/
378
public Name getPrefix(int posn) {
379
Enumeration<String> comps = impl.getPrefix(posn);
380
return (new CompoundName(comps, mySyntax));
381
}
382
383
/**
384
* Creates a compound name whose components consist of a suffix of the
385
* components in this compound name.
386
* The result and this compound name share the same syntax.
387
* Subsequent changes to
388
* this compound name does not affect the name that is returned.
389
*
390
* @param posn The 0-based index of the component at which to start.
391
* Must be in the range [0,size()].
392
* @return A compound name consisting of the components at indexes in
393
* the range [posn,size()). If posn is equal to
394
* size(), an empty compound name is returned.
395
* @exception ArrayIndexOutOfBoundsException
396
* If posn is outside the specified range.
397
*/
398
public Name getSuffix(int posn) {
399
Enumeration<String> comps = impl.getSuffix(posn);
400
return (new CompoundName(comps, mySyntax));
401
}
402
403
/**
404
* Determines whether a compound name is a prefix of this compound name.
405
* A compound name 'n' is a prefix if it is equal to
406
* getPrefix(n.size())--in other words, this compound name
407
* starts with 'n'.
408
* If n is null or not a compound name, false is returned.
409
*<p>
410
* Implementation note: Currently the syntax properties of n
411
* are not used when doing the comparison. They might be in the future.
412
* @param n The possibly null compound name to check.
413
* @return true if n is a CompoundName and
414
* is a prefix of this compound name, false otherwise.
415
*/
416
public boolean startsWith(Name n) {
417
if (n instanceof CompoundName) {
418
return (impl.startsWith(n.size(), n.getAll()));
419
} else {
420
return false;
421
}
422
}
423
424
/**
425
* Determines whether a compound name is a suffix of this compound name.
426
* A compound name 'n' is a suffix if it it is equal to
427
* getSuffix(size()-n.size())--in other words, this
428
* compound name ends with 'n'.
429
* If n is null or not a compound name, false is returned.
430
*<p>
431
* Implementation note: Currently the syntax properties of n
432
* are not used when doing the comparison. They might be in the future.
433
* @param n The possibly null compound name to check.
434
* @return true if n is a CompoundName and
435
* is a suffix of this compound name, false otherwise.
436
*/
437
public boolean endsWith(Name n) {
438
if (n instanceof CompoundName) {
439
return (impl.endsWith(n.size(), n.getAll()));
440
} else {
441
return false;
442
}
443
}
444
445
/**
446
* Adds the components of a compound name -- in order -- to the end of
447
* this compound name.
448
*<p>
449
* Implementation note: Currently the syntax properties of suffix
450
* is not used or checked. They might be in the future.
451
* @param suffix The non-null components to add.
452
* @return The updated CompoundName, not a new one. Cannot be null.
453
* @exception InvalidNameException If suffix is not a compound name,
454
* or if the addition of the components violates the syntax
455
* of this compound name (e.g. exceeding number of components).
456
*/
457
public Name addAll(Name suffix) throws InvalidNameException {
458
if (suffix instanceof CompoundName) {
459
impl.addAll(suffix.getAll());
460
return this;
461
} else {
462
throw new InvalidNameException("Not a compound name: " +
463
suffix.toString());
464
}
465
}
466
467
/**
468
* Adds the components of a compound name -- in order -- at a specified
469
* position within this compound name.
470
* Components of this compound name at or after the index of the first
471
* new component are shifted up (away from index 0)
472
* to accommodate the new components.
473
*<p>
474
* Implementation note: Currently the syntax properties of suffix
475
* is not used or checked. They might be in the future.
476
*
477
* @param n The non-null components to add.
478
* @param posn The index in this name at which to add the new
479
* components. Must be in the range [0,size()].
480
* @return The updated CompoundName, not a new one. Cannot be null.
481
* @exception ArrayIndexOutOfBoundsException
482
* If posn is outside the specified range.
483
* @exception InvalidNameException If n is not a compound name,
484
* or if the addition of the components violates the syntax
485
* of this compound name (e.g. exceeding number of components).
486
*/
487
public Name addAll(int posn, Name n) throws InvalidNameException {
488
if (n instanceof CompoundName) {
489
impl.addAll(posn, n.getAll());
490
return this;
491
} else {
492
throw new InvalidNameException("Not a compound name: " +
493
n.toString());
494
}
495
}
496
497
/**
498
* Adds a single component to the end of this compound name.
499
*
500
* @param comp The non-null component to add.
501
* @return The updated CompoundName, not a new one. Cannot be null.
502
* @exception InvalidNameException If adding comp at end of the name
503
* would violate the compound name's syntax.
504
*/
505
public Name add(String comp) throws InvalidNameException{
506
impl.add(comp);
507
return this;
508
}
509
510
/**
511
* Adds a single component at a specified position within this
512
* compound name.
513
* Components of this compound name at or after the index of the new
514
* component are shifted up by one (away from index 0)
515
* to accommodate the new component.
516
*
517
* @param comp The non-null component to add.
518
* @param posn The index at which to add the new component.
519
* Must be in the range [0,size()].
520
* @exception ArrayIndexOutOfBoundsException
521
* If posn is outside the specified range.
522
* @return The updated CompoundName, not a new one. Cannot be null.
523
* @exception InvalidNameException If adding comp at the specified position
524
* would violate the compound name's syntax.
525
*/
526
public Name add(int posn, String comp) throws InvalidNameException{
527
impl.add(posn, comp);
528
return this;
529
}
530
531
/**
532
* Deletes a component from this compound name.
533
* The component of this compound name at position 'posn' is removed,
534
* and components at indices greater than 'posn'
535
* are shifted down (towards index 0) by one.
536
*
537
* @param posn The index of the component to delete.
538
* Must be in the range [0,size()).
539
* @return The component removed (a String).
540
* @exception ArrayIndexOutOfBoundsException
541
* If posn is outside the specified range (includes case where
542
* compound name is empty).
543
* @exception InvalidNameException If deleting the component
544
* would violate the compound name's syntax.
545
*/
546
public Object remove(int posn) throws InvalidNameException {
547
return impl.remove(posn);
548
}
549
550
/**
551
* Overridden to avoid implementation dependency.
552
* @serialData The syntax <tt>Properties</tt>, followed by
553
* the number of components (an <tt>int</tt>), and the individual
554
* components (each a <tt>String</tt>).
555
*/
556
private void writeObject(java.io.ObjectOutputStream s)
557
throws java.io.IOException {
558
s.writeObject(mySyntax);
559
s.writeInt(size());
560
Enumeration<String> comps = getAll();
561
while (comps.hasMoreElements()) {
562
s.writeObject(comps.nextElement());
563
}
564
}
565
566
/**
567
* Overridden to avoid implementation dependency.
568
*/
569
private void readObject(java.io.ObjectInputStream s)
570
throws java.io.IOException, ClassNotFoundException {
571
mySyntax = (Properties)s.readObject();
572
impl = new NameImpl(mySyntax);
573
int n = s.readInt(); // number of components
574
try {
575
while (--n >= 0) {
576
add((String)s.readObject());
577
}
578
} catch (InvalidNameException e) {
579
throw (new java.io.StreamCorruptedException("Invalid name"));
580
}
581
}
582
583
/**
584
* Use serialVersionUID from JNDI 1.1.1 for interoperability
585
*/
586
private static final long serialVersionUID = 3513100557083972036L;
587
588
/*
589
// For testing
590
591
public static void main(String[] args) {
592
Properties dotSyntax = new Properties();
593
dotSyntax.put("jndi.syntax.direction", "right_to_left");
594
dotSyntax.put("jndi.syntax.separator", ".");
595
dotSyntax.put("jndi.syntax.ignorecase", "true");
596
dotSyntax.put("jndi.syntax.escape", "\\");
597
// dotSyntax.put("jndi.syntax.beginquote", "\"");
598
// dotSyntax.put("jndi.syntax.beginquote2", "'");
599
600
Name first = null;
601
try {
602
for (int i = 0; i < args.length; i++) {
603
Name name;
604
Enumeration e;
605
System.out.println("Given name: " + args[i]);
606
name = new CompoundName(args[i], dotSyntax);
607
if (first == null) {
608
first = name;
609
}
610
e = name.getComponents();
611
while (e.hasMoreElements()) {
612
System.out.println("Element: " + e.nextElement());
613
}
614
System.out.println("Constructed name: " + name.toString());
615
616
System.out.println("Compare " + first.toString() + " with "
617
+ name.toString() + " = " + first.compareTo(name));
618
}
619
} catch (Exception ne) {
620
ne.printStackTrace();
621
}
622
}
623
*/
624
}
625
626