Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/src/java.base/share/classes/java/nio/file/attribute/AclEntry.java
41161 views
1
/*
2
* Copyright (c) 2007, 2017, 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 java.nio.file.attribute;
27
28
import java.util.*;
29
30
/**
31
* An entry in an access control list (ACL).
32
*
33
* <p> The ACL entry represented by this class is based on the ACL model
34
* specified in <a href="http://www.ietf.org/rfc/rfc3530.txt"><i>RFC&nbsp;3530:
35
* Network File System (NFS) version 4 Protocol</i></a>. Each entry has four
36
* components as follows:
37
*
38
* <ol>
39
* <li><p> The {@link #type() type} component determines if the entry
40
* grants or denies access. </p></li>
41
*
42
* <li><p> The {@link #principal() principal} component, sometimes called the
43
* "who" component, is a {@link UserPrincipal} corresponding to the identity
44
* that the entry grants or denies access
45
* </p></li>
46
*
47
* <li><p> The {@link #permissions permissions} component is a set of
48
* {@link AclEntryPermission permissions}
49
* </p></li>
50
*
51
* <li><p> The {@link #flags() flags} component is a set of {@link AclEntryFlag
52
* flags} to indicate how entries are inherited and propagated </p></li>
53
* </ol>
54
*
55
* <p> ACL entries are created using an associated {@link Builder} object by
56
* invoking its {@link Builder#build build} method.
57
*
58
* <p> ACL entries are immutable and are safe for use by multiple concurrent
59
* threads.
60
*
61
* @since 1.7
62
*/
63
64
public final class AclEntry {
65
66
private final AclEntryType type;
67
private final UserPrincipal who;
68
private final Set<AclEntryPermission> perms;
69
private final Set<AclEntryFlag> flags;
70
71
// cached hash code
72
private volatile int hash;
73
74
// private constructor
75
private AclEntry(AclEntryType type,
76
UserPrincipal who,
77
Set<AclEntryPermission> perms,
78
Set<AclEntryFlag> flags)
79
{
80
this.type = type;
81
this.who = who;
82
this.perms = perms;
83
this.flags = flags;
84
}
85
86
/**
87
* A builder of {@link AclEntry} objects.
88
*
89
* <p> A {@code Builder} object is obtained by invoking one of the {@link
90
* AclEntry#newBuilder newBuilder} methods defined by the {@code AclEntry}
91
* class.
92
*
93
* <p> Builder objects are mutable and are not safe for use by multiple
94
* concurrent threads without appropriate synchronization.
95
*
96
* @since 1.7
97
*/
98
public static final class Builder {
99
private AclEntryType type;
100
private UserPrincipal who;
101
private Set<AclEntryPermission> perms;
102
private Set<AclEntryFlag> flags;
103
104
private Builder(AclEntryType type,
105
UserPrincipal who,
106
Set<AclEntryPermission> perms,
107
Set<AclEntryFlag> flags)
108
{
109
assert perms != null && flags != null;
110
this.type = type;
111
this.who = who;
112
this.perms = perms;
113
this.flags = flags;
114
}
115
116
/**
117
* Constructs an {@link AclEntry} from the components of this builder.
118
* The type and who components are required to have been set in order
119
* to construct an {@code AclEntry}.
120
*
121
* @return a new ACL entry
122
*
123
* @throws IllegalStateException
124
* if the type or who component have not been set
125
*/
126
public AclEntry build() {
127
if (type == null)
128
throw new IllegalStateException("Missing type component");
129
if (who == null)
130
throw new IllegalStateException("Missing who component");
131
return new AclEntry(type, who, perms, flags);
132
}
133
134
/**
135
* Sets the type component of this builder.
136
*
137
* @param type the component type
138
* @return this builder
139
*/
140
public Builder setType(AclEntryType type) {
141
if (type == null)
142
throw new NullPointerException();
143
this.type = type;
144
return this;
145
}
146
147
/**
148
* Sets the principal component of this builder.
149
*
150
* @param who the principal component
151
* @return this builder
152
*/
153
public Builder setPrincipal(UserPrincipal who) {
154
if (who == null)
155
throw new NullPointerException();
156
this.who = who;
157
return this;
158
}
159
160
// check set only contains elements of the given type
161
private static void checkSet(Set<?> set, Class<?> type) {
162
for (Object e: set) {
163
if (e == null)
164
throw new NullPointerException();
165
type.cast(e);
166
}
167
}
168
169
/**
170
* Sets the permissions component of this builder. On return, the
171
* permissions component of this builder is a copy of the given set.
172
*
173
* @param perms the permissions component
174
* @return this builder
175
*
176
* @throws ClassCastException
177
* if the set contains elements that are not of type {@code
178
* AclEntryPermission}
179
*/
180
public Builder setPermissions(Set<AclEntryPermission> perms) {
181
if (perms.isEmpty()) {
182
// EnumSet.copyOf does not allow empty set
183
perms = Collections.emptySet();
184
} else {
185
// copy and check for erroneous elements
186
perms = EnumSet.copyOf(perms);
187
checkSet(perms, AclEntryPermission.class);
188
}
189
190
this.perms = perms;
191
return this;
192
}
193
194
/**
195
* Sets the permissions component of this builder. On return, the
196
* permissions component of this builder is a copy of the permissions in
197
* the given array.
198
*
199
* @param perms the permissions component
200
* @return this builder
201
*/
202
public Builder setPermissions(AclEntryPermission... perms) {
203
Set<AclEntryPermission> set = EnumSet.noneOf(AclEntryPermission.class);
204
// copy and check for null elements
205
for (AclEntryPermission p: perms) {
206
if (p == null)
207
throw new NullPointerException();
208
set.add(p);
209
}
210
this.perms = set;
211
return this;
212
}
213
214
/**
215
* Sets the flags component of this builder. On return, the flags
216
* component of this builder is a copy of the given set.
217
*
218
* @param flags the flags component
219
* @return this builder
220
*
221
* @throws ClassCastException
222
* if the set contains elements that are not of type {@code
223
* AclEntryFlag}
224
*/
225
public Builder setFlags(Set<AclEntryFlag> flags) {
226
if (flags.isEmpty()) {
227
// EnumSet.copyOf does not allow empty set
228
flags = Collections.emptySet();
229
} else {
230
// copy and check for erroneous elements
231
flags = EnumSet.copyOf(flags);
232
checkSet(flags, AclEntryFlag.class);
233
}
234
235
this.flags = flags;
236
return this;
237
}
238
239
/**
240
* Sets the flags component of this builder. On return, the flags
241
* component of this builder is a copy of the flags in the given
242
* array.
243
*
244
* @param flags the flags component
245
* @return this builder
246
*/
247
public Builder setFlags(AclEntryFlag... flags) {
248
Set<AclEntryFlag> set = EnumSet.noneOf(AclEntryFlag.class);
249
// copy and check for null elements
250
for (AclEntryFlag f: flags) {
251
if (f == null)
252
throw new NullPointerException();
253
set.add(f);
254
}
255
this.flags = set;
256
return this;
257
}
258
}
259
260
/**
261
* Constructs a new builder. The initial value of the type and who
262
* components is {@code null}. The initial value of the permissions and
263
* flags components is the empty set.
264
*
265
* @return a new builder
266
*/
267
public static Builder newBuilder() {
268
Set<AclEntryPermission> perms = Collections.emptySet();
269
Set<AclEntryFlag> flags = Collections.emptySet();
270
return new Builder(null, null, perms, flags);
271
}
272
273
/**
274
* Constructs a new builder with the components of an existing ACL entry.
275
*
276
* @param entry an ACL entry
277
* @return a new builder
278
*/
279
public static Builder newBuilder(AclEntry entry) {
280
return new Builder(entry.type, entry.who, entry.perms, entry.flags);
281
}
282
283
/**
284
* Returns the ACL entry type.
285
*
286
* @return the ACL entry type
287
*/
288
public AclEntryType type() {
289
return type;
290
}
291
292
/**
293
* Returns the principal component.
294
*
295
* @return the principal component
296
*/
297
public UserPrincipal principal() {
298
return who;
299
}
300
301
/**
302
* Returns a copy of the permissions component.
303
*
304
* <p> The returned set is a modifiable copy of the permissions.
305
*
306
* @return the permissions component
307
*/
308
public Set<AclEntryPermission> permissions() {
309
return new HashSet<>(perms);
310
}
311
312
/**
313
* Returns a copy of the flags component.
314
*
315
* <p> The returned set is a modifiable copy of the flags.
316
*
317
* @return the flags component
318
*/
319
public Set<AclEntryFlag> flags() {
320
return new HashSet<>(flags);
321
}
322
323
/**
324
* Compares the specified object with this ACL entry for equality.
325
*
326
* <p> If the given object is not an {@code AclEntry} then this method
327
* immediately returns {@code false}.
328
*
329
* <p> For two ACL entries to be considered equals requires that they are
330
* both the same type, their who components are equal, their permissions
331
* components are equal, and their flags components are equal.
332
*
333
* <p> This method satisfies the general contract of the {@link
334
* java.lang.Object#equals(Object) Object.equals} method. </p>
335
*
336
* @param ob the object to which this object is to be compared
337
*
338
* @return {@code true} if, and only if, the given object is an AclEntry that
339
* is identical to this AclEntry
340
*/
341
@Override
342
public boolean equals(Object ob) {
343
if (ob == this)
344
return true;
345
if (!(ob instanceof AclEntry other))
346
return false;
347
if (this.type != other.type)
348
return false;
349
if (!this.who.equals(other.who))
350
return false;
351
if (!this.perms.equals(other.perms))
352
return false;
353
if (!this.flags.equals(other.flags))
354
return false;
355
return true;
356
}
357
358
private static int hash(int h, Object o) {
359
return h * 127 + o.hashCode();
360
}
361
362
/**
363
* Returns the hash-code value for this ACL entry.
364
*
365
* <p> This method satisfies the general contract of the {@link
366
* Object#hashCode} method.
367
*/
368
@Override
369
public int hashCode() {
370
// return cached hash if available
371
if (hash != 0)
372
return hash;
373
int h = type.hashCode();
374
h = hash(h, who);
375
h = hash(h, perms);
376
h = hash(h, flags);
377
hash = h;
378
return hash;
379
}
380
381
/**
382
* Returns the string representation of this ACL entry.
383
*
384
* @return the string representation of this entry
385
*/
386
@Override
387
public String toString() {
388
StringBuilder sb = new StringBuilder();
389
390
// who
391
sb.append(who.getName());
392
sb.append(':');
393
394
// permissions
395
for (AclEntryPermission perm: perms) {
396
sb.append(perm.name());
397
sb.append('/');
398
}
399
sb.setLength(sb.length()-1); // drop final slash
400
sb.append(':');
401
402
// flags
403
if (!flags.isEmpty()) {
404
for (AclEntryFlag flag: flags) {
405
sb.append(flag.name());
406
sb.append('/');
407
}
408
sb.setLength(sb.length()-1); // drop final slash
409
sb.append(':');
410
}
411
412
// type
413
sb.append(type.name());
414
return sb.toString();
415
}
416
}
417
418