Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/src/java.naming/share/classes/javax/naming/directory/BasicAttributes.java
41159 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
27
package javax.naming.directory;
28
29
import java.util.Hashtable;
30
import java.util.Enumeration;
31
import java.util.Locale;
32
33
import javax.naming.NamingException;
34
import javax.naming.NamingEnumeration;
35
36
/**
37
* This class provides a basic implementation
38
* of the Attributes interface.
39
*<p>
40
* BasicAttributes is either case-sensitive or case-insensitive (case-ignore).
41
* This property is determined at the time the BasicAttributes constructor
42
* is called.
43
* In a case-insensitive BasicAttributes, the case of its attribute identifiers
44
* is ignored when searching for an attribute, or adding attributes.
45
* In a case-sensitive BasicAttributes, the case is significant.
46
*<p>
47
* When the BasicAttributes class needs to create an Attribute, it
48
* uses BasicAttribute. There is no other dependency on BasicAttribute.
49
*<p>
50
* Note that updates to BasicAttributes (such as adding or removing an attribute)
51
* does not affect the corresponding representation in the directory.
52
* Updates to the directory can only be effected
53
* using operations in the DirContext interface.
54
*<p>
55
* A BasicAttributes instance is not synchronized against concurrent
56
* multithreaded access. Multiple threads trying to access and modify
57
* a single BasicAttributes instance should lock the object.
58
*
59
* @author Rosanna Lee
60
* @author Scott Seligman
61
*
62
* @see DirContext#getAttributes
63
* @see DirContext#modifyAttributes
64
* @see DirContext#bind
65
* @see DirContext#rebind
66
* @see DirContext#createSubcontext
67
* @see DirContext#search
68
* @since 1.3
69
*/
70
71
public class BasicAttributes implements Attributes {
72
/**
73
* Indicates whether case of attribute ids is ignored.
74
* @serial
75
*/
76
private boolean ignoreCase = false;
77
78
// The 'key' in attrs is stored in the 'right case'.
79
// If ignoreCase is true, key is aways lowercase.
80
// If ignoreCase is false, key is stored as supplied by put().
81
// %%% Not declared "private" due to bug 4064984.
82
transient Hashtable<String,Attribute> attrs = new Hashtable<>(11);
83
84
/**
85
* Constructs a new instance of Attributes.
86
* The character case of attribute identifiers
87
* is significant when subsequently retrieving or adding attributes.
88
*/
89
public BasicAttributes() {
90
}
91
92
/**
93
* Constructs a new instance of Attributes.
94
* If <code>ignoreCase</code> is true, the character case of attribute
95
* identifiers is ignored; otherwise the case is significant.
96
* @param ignoreCase true means this attribute set will ignore
97
* the case of its attribute identifiers
98
* when retrieving or adding attributes;
99
* false means case is respected.
100
*/
101
public BasicAttributes(boolean ignoreCase) {
102
this.ignoreCase = ignoreCase;
103
}
104
105
/**
106
* Constructs a new instance of Attributes with one attribute.
107
* The attribute specified by attrID and val are added to the newly
108
* created attribute.
109
* The character case of attribute identifiers
110
* is significant when subsequently retrieving or adding attributes.
111
* @param attrID non-null The id of the attribute to add.
112
* @param val The value of the attribute to add. If null, a null
113
* value is added to the attribute.
114
*/
115
public BasicAttributes(String attrID, Object val) {
116
this();
117
this.put(new BasicAttribute(attrID, val));
118
}
119
120
/**
121
* Constructs a new instance of Attributes with one attribute.
122
* The attribute specified by attrID and val are added to the newly
123
* created attribute.
124
* If <code>ignoreCase</code> is true, the character case of attribute
125
* identifiers is ignored; otherwise the case is significant.
126
* @param attrID non-null The id of the attribute to add.
127
* If this attribute set ignores the character
128
* case of its attribute ids, the case of attrID
129
* is ignored.
130
* @param val The value of the attribute to add. If null, a null
131
* value is added to the attribute.
132
* @param ignoreCase true means this attribute set will ignore
133
* the case of its attribute identifiers
134
* when retrieving or adding attributes;
135
* false means case is respected.
136
*/
137
public BasicAttributes(String attrID, Object val, boolean ignoreCase) {
138
this(ignoreCase);
139
this.put(new BasicAttribute(attrID, val));
140
}
141
142
@SuppressWarnings("unchecked")
143
public Object clone() {
144
BasicAttributes attrset;
145
try {
146
attrset = (BasicAttributes)super.clone();
147
} catch (CloneNotSupportedException e) {
148
attrset = new BasicAttributes(ignoreCase);
149
}
150
attrset.attrs = (Hashtable<String,Attribute>)attrs.clone();
151
return attrset;
152
}
153
154
public boolean isCaseIgnored() {
155
return ignoreCase;
156
}
157
158
public int size() {
159
return attrs.size();
160
}
161
162
public Attribute get(String attrID) {
163
Attribute attr = attrs.get(
164
ignoreCase ? attrID.toLowerCase(Locale.ENGLISH) : attrID);
165
return (attr);
166
}
167
168
public NamingEnumeration<Attribute> getAll() {
169
return new AttrEnumImpl();
170
}
171
172
public NamingEnumeration<String> getIDs() {
173
return new IDEnumImpl();
174
}
175
176
public Attribute put(String attrID, Object val) {
177
return this.put(new BasicAttribute(attrID, val));
178
}
179
180
public Attribute put(Attribute attr) {
181
String id = attr.getID();
182
if (ignoreCase) {
183
id = id.toLowerCase(Locale.ENGLISH);
184
}
185
return attrs.put(id, attr);
186
}
187
188
public Attribute remove(String attrID) {
189
String id = (ignoreCase ? attrID.toLowerCase(Locale.ENGLISH) : attrID);
190
return attrs.remove(id);
191
}
192
193
/**
194
* Generates the string representation of this attribute set.
195
* The string consists of each attribute identifier and the contents
196
* of each attribute. The contents of this string is useful
197
* for debugging and is not meant to be interpreted programmatically.
198
*
199
* @return A non-null string listing the contents of this attribute set.
200
*/
201
public String toString() {
202
if (attrs.size() == 0) {
203
return("No attributes");
204
} else {
205
return attrs.toString();
206
}
207
}
208
209
/**
210
* Determines whether this {@code BasicAttributes} is equal to another
211
* {@code Attributes}
212
* Two {@code Attributes} are equal if they are both instances of
213
* {@code Attributes},
214
* treat the case of attribute IDs the same way, and contain the
215
* same attributes. Each {@code Attribute} in this {@code BasicAttributes}
216
* is checked for equality using {@code Object.equals()}, which may have
217
* be overridden by implementations of {@code Attribute}).
218
* If a subclass overrides {@code equals()},
219
* it should override {@code hashCode()}
220
* as well so that two {@code Attributes} instances that are equal
221
* have the same hash code.
222
* @param obj the possibly null object to compare against.
223
*
224
* @return true If obj is equal to this BasicAttributes.
225
* @see #hashCode
226
*/
227
public boolean equals(Object obj) {
228
if ((obj != null) && (obj instanceof Attributes)) {
229
Attributes target = (Attributes)obj;
230
231
// Check case first
232
if (ignoreCase != target.isCaseIgnored()) {
233
return false;
234
}
235
236
if (size() == target.size()) {
237
Attribute their, mine;
238
try {
239
NamingEnumeration<?> theirs = target.getAll();
240
while (theirs.hasMore()) {
241
their = (Attribute)theirs.next();
242
mine = get(their.getID());
243
if (!their.equals(mine)) {
244
return false;
245
}
246
}
247
} catch (NamingException e) {
248
return false;
249
}
250
return true;
251
}
252
}
253
return false;
254
}
255
256
/**
257
* Calculates the hash code of this BasicAttributes.
258
*<p>
259
* The hash code is computed by adding the hash code of
260
* the attributes of this object. If this BasicAttributes
261
* ignores case of its attribute IDs, one is added to the hash code.
262
* If a subclass overrides {@code hashCode()},
263
* it should override {@code equals()}
264
* as well so that two {@code Attributes} instances that are equal
265
* have the same hash code.
266
*
267
* @return an int representing the hash code of this BasicAttributes instance.
268
* @see #equals
269
*/
270
public int hashCode() {
271
int hash = (ignoreCase ? 1 : 0);
272
try {
273
NamingEnumeration<?> all = getAll();
274
while (all.hasMore()) {
275
hash += all.next().hashCode();
276
}
277
} catch (NamingException e) {}
278
return hash;
279
}
280
281
/**
282
* The writeObject method is called to save the state of the
283
* {@code BasicAttributes} to a stream.
284
*
285
* @serialData Default field (ignoreCase flag - a {@code boolean}), followed by
286
* the number of attributes in the set
287
* (an {@code int}), and then the individual {@code Attribute} objects.
288
*
289
* @param s the {@code ObjectOutputStream} to write to
290
* @throws java.io.IOException if an I/O error occurs
291
*/
292
@java.io.Serial
293
private void writeObject(java.io.ObjectOutputStream s)
294
throws java.io.IOException {
295
// Overridden to avoid exposing implementation details
296
s.defaultWriteObject(); // write out the ignoreCase flag
297
s.writeInt(attrs.size());
298
Enumeration<Attribute> attrEnum = attrs.elements();
299
while (attrEnum.hasMoreElements()) {
300
s.writeObject(attrEnum.nextElement());
301
}
302
}
303
304
/**
305
* The readObject method is called to restore the state of
306
* the {@code BasicAttributes} from a stream.
307
*
308
* See {@code writeObject} for a description of the serial form.
309
*
310
* @param s the {@code ObjectInputStream} to read from
311
* @throws java.io.IOException if an I/O error occurs
312
* @throws ClassNotFoundException if the class of a serialized object
313
* could not be found
314
*/
315
@java.io.Serial
316
private void readObject(java.io.ObjectInputStream s)
317
throws java.io.IOException, ClassNotFoundException {
318
// Overridden to avoid exposing implementation details.
319
s.defaultReadObject(); // read in the ignoreCase flag
320
int n = s.readInt(); // number of attributes
321
attrs = (n >= 1)
322
? new Hashtable<>(1 + (int) (Math.min(768, n) / .75f))
323
: new Hashtable<>(2); // can't have initial size of 0 (grrr...)
324
while (--n >= 0) {
325
put((Attribute)s.readObject());
326
}
327
}
328
329
330
class AttrEnumImpl implements NamingEnumeration<Attribute> {
331
332
Enumeration<Attribute> elements;
333
334
public AttrEnumImpl() {
335
this.elements = attrs.elements();
336
}
337
338
public boolean hasMoreElements() {
339
return elements.hasMoreElements();
340
}
341
342
public Attribute nextElement() {
343
return elements.nextElement();
344
}
345
346
public boolean hasMore() throws NamingException {
347
return hasMoreElements();
348
}
349
350
public Attribute next() throws NamingException {
351
return nextElement();
352
}
353
354
public void close() throws NamingException {
355
elements = null;
356
}
357
}
358
359
class IDEnumImpl implements NamingEnumeration<String> {
360
361
Enumeration<Attribute> elements;
362
363
public IDEnumImpl() {
364
// Walking through the elements, rather than the keys, gives
365
// us attribute IDs that have not been converted to lowercase.
366
this.elements = attrs.elements();
367
}
368
369
public boolean hasMoreElements() {
370
return elements.hasMoreElements();
371
}
372
373
public String nextElement() {
374
Attribute attr = elements.nextElement();
375
return attr.getID();
376
}
377
378
public boolean hasMore() throws NamingException {
379
return hasMoreElements();
380
}
381
382
public String next() throws NamingException {
383
return nextElement();
384
}
385
386
public void close() throws NamingException {
387
elements = null;
388
}
389
}
390
391
/**
392
* Use serialVersionUID from JNDI 1.1.1 for interoperability.
393
*/
394
@java.io.Serial
395
private static final long serialVersionUID = 4980164073184639448L;
396
}
397
398