--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/java/nio/file/attribute/AclEntry.java Sun Feb 15 12:25:54 2009 +0000
@@ -0,0 +1,394 @@
+/*
+ * Copyright 2007-2009 Sun Microsystems, Inc. All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package java.nio.file.attribute;
+
+import java.util.*;
+
+/**
+ * An entry in an access control list (ACL).
+ *
+ * <p> The ACL entry represented by this class is based on the ACL model
+ * specified in <a href="http://www.ietf.org/rfc/rfc3530.txt"><i>RFC 3530:
+ * Network File System (NFS) version 4 Protocol</i></a>. Each entry has four
+ * components as follows:
+ *
+ * <ol>
+ * <li><p> The {@link #type() type} component determines if the entry
+ * grants or denies access. </p></li>
+ *
+ * <li><p> The {@link #principal() principal} component, sometimes called the
+ * "who" component, is a {@link UserPrincipal} corresponding to the identity
+ * that the entry grants or denies access
+ * </p></li>
+ *
+ * <li><p> The {@link #permissions permissions} component is a set of
+ * {@link AclEntryPermission permissions}
+ * </p></li>
+ *
+ * <li><p> The {@link #flags flags} component is a set of {@link AclEntryFlag
+ * flags} to indicate how entries are inherited and propagated </p></li>
+ * </ol>
+ *
+ * <p> ACL entries are created using an associated {@link Builder} object by
+ * invoking its {@link Builder#build build} method.
+ *
+ * <p> ACL entries are immutable and are safe for use by multiple concurrent
+ * threads.
+ *
+ * @since 1.7
+ */
+
+public final class AclEntry {
+
+ private final AclEntryType type;
+ private final UserPrincipal who;
+ private final Set<AclEntryPermission> perms;
+ private final Set<AclEntryFlag> flags;
+
+ // cached hash code
+ private volatile int hash;
+
+ // private constructor
+ private AclEntry(AclEntryType type,
+ UserPrincipal who,
+ Set<AclEntryPermission> perms,
+ Set<AclEntryFlag> flags)
+ {
+ this.type = type;
+ this.who = who;
+ this.perms = perms;
+ this.flags = flags;
+ }
+
+ /**
+ * A builder of {@link AclEntry} objects.
+ *
+ * <p> A {@code Builder} object is obtained by invoking one of the {@link
+ * AclEntry#newBuilder newBuilder} methods defined by the {@code AclEntry}
+ * class.
+ *
+ * <p> Builder objects are mutable and are not safe for use by multiple
+ * concurrent threads without appropriate synchronization.
+ *
+ * @since 1.7
+ */
+ public static final class Builder {
+ private AclEntryType type;
+ private UserPrincipal who;
+ private Set<AclEntryPermission> perms;
+ private Set<AclEntryFlag> flags;
+
+ private Builder(AclEntryType type,
+ UserPrincipal who,
+ Set<AclEntryPermission> perms,
+ Set<AclEntryFlag> flags)
+ {
+ assert perms != null && flags != null;
+ this.type = type;
+ this.who = who;
+ this.perms = perms;
+ this.flags = flags;
+ }
+
+ /**
+ * Constructs an {@link AclEntry} from the components of this builder.
+ * The type and who components are required to have been set in order
+ * to construct an {@code AclEntry}.
+ *
+ * @return A new ACL entry
+ *
+ * @throws IllegalStateException
+ * If the type or who component have not been set.
+ */
+ public AclEntry build() {
+ if (type == null)
+ throw new IllegalStateException("Missing type component");
+ if (who == null)
+ throw new IllegalStateException("Missing who component");
+ return new AclEntry(type, who, perms, flags);
+ }
+
+ /**
+ * Sets the type component of this builder.
+ *
+ * @return This builder
+ */
+ public Builder setType(AclEntryType type) {
+ if (type == null)
+ throw new NullPointerException();
+ this.type = type;
+ return this;
+ }
+
+ /**
+ * Sets the principal component of this builder.
+ *
+ * @return This builder
+ */
+ public Builder setPrincipal(UserPrincipal who) {
+ if (who == null)
+ throw new NullPointerException();
+ this.who = who;
+ return this;
+ }
+
+ // check set only contains elements of the given type
+ private static void checkSet(Set<?> set, Class<?> type) {
+ for (Object e: set) {
+ if (e == null)
+ throw new NullPointerException();
+ type.cast(e);
+ }
+ }
+
+ /**
+ * Sets the permissions component of this builder. On return, the
+ * permissions component of this builder is a copy of the given set.
+ *
+ * @return This builder
+ *
+ * @throws ClassCastException
+ * If the sets contains elements that are not of type {@code
+ * AclEntryPermission}
+ */
+ public Builder setPermissions(Set<AclEntryPermission> perms) {
+ // copy and check for erroneous elements
+ perms = new HashSet<AclEntryPermission>(perms);
+ checkSet(perms, AclEntryPermission.class);
+ this.perms = perms;
+ return this;
+ }
+
+ /**
+ * Sets the permissions component of this builder. On return, the
+ * permissions component of this builder is a copy of the permissions in
+ * the given array.
+ *
+ * @return This builder
+ */
+ public Builder setPermissions(AclEntryPermission... perms) {
+ Set<AclEntryPermission> set =
+ new HashSet<AclEntryPermission>(perms.length);
+ // copy and check for null elements
+ for (AclEntryPermission p: perms) {
+ if (p == null)
+ throw new NullPointerException();
+ set.add(p);
+ }
+ this.perms = set;
+ return this;
+ }
+
+ /**
+ * Sets the flags component of this builder. On return, the flags
+ * component of this builder is a copy of the given set.
+ *
+ * @return This builder
+ *
+ * @throws ClassCastException
+ * If the sets contains elements that are not of type {@code
+ * AclEntryFlag}
+ */
+ public Builder setFlags(Set<AclEntryFlag> flags) {
+ // copy and check for erroneous elements
+ flags = new HashSet<AclEntryFlag>(flags);
+ checkSet(flags, AclEntryFlag.class);
+ this.flags = flags;
+ return this;
+ }
+
+ /**
+ * Sets the flags component of this builder. On return, the flags
+ * component of this builder is a copy of the flags in the given
+ * array.
+ *
+ * @return This builder
+ */
+ public Builder setFlags(AclEntryFlag... flags) {
+ Set<AclEntryFlag> set = new HashSet<AclEntryFlag>(flags.length);
+ // copy and check for null elements
+ for (AclEntryFlag f: flags) {
+ if (f == null)
+ throw new NullPointerException();
+ set.add(f);
+ }
+ this.flags = set;
+ return this;
+ }
+ }
+
+ /**
+ * Constructs a new builder. The initial value of the type and who
+ * components is {@code null}. The initial value of the permissions and
+ * flags components is the empty set.
+ *
+ * @return A new builder
+ */
+ public static Builder newBuilder() {
+ Set<AclEntryPermission> perms = Collections.emptySet();
+ Set<AclEntryFlag> flags = Collections.emptySet();
+ return new Builder(null, null, perms, flags);
+ }
+
+ /**
+ * Constructs a new builder with the components of an existing ACL entry.
+ *
+ * @param entry
+ * An ACL entry
+ *
+ * @return A new builder
+ */
+ public static Builder newBuilder(AclEntry entry) {
+ return new Builder(entry.type, entry.who, entry.perms, entry.flags);
+ }
+
+ /**
+ * Returns the ACL entry type.
+ */
+ public AclEntryType type() {
+ return type;
+ }
+
+ /**
+ * Returns the principal component.
+ */
+ public UserPrincipal principal() {
+ return who;
+ }
+
+ /**
+ * Returns a copy of the permissions component.
+ *
+ * <p> The returned set is a modifiable copy of the permissions.
+ */
+ public Set<AclEntryPermission> permissions() {
+ return new HashSet<AclEntryPermission>(perms);
+ }
+
+ /**
+ * Returns a copy of the flags component.
+ *
+ * <p> The returned set is a modifiable copy of the flags.
+ */
+ public Set<AclEntryFlag> flags() {
+ return new HashSet<AclEntryFlag>(flags);
+ }
+
+ /**
+ * Compares the specified object with this ACL entry for equality.
+ *
+ * <p> If the given object is not an {@code AclEntry} then this method
+ * immediately returns {@code false}.
+ *
+ * <p> For two ACL entries to be considered equals requires that they are
+ * both the same type, their who components are equal, their permissions
+ * components are equal, and their flags components are equal.
+ *
+ * <p> This method satisfies the general contract of the {@link
+ * java.lang.Object#equals(Object) Object.equals} method. </p>
+ *
+ * @param ob The object to which this object is to be compared
+ *
+ * @return {@code true} if, and only if, the given object is an AclEntry that
+ * is identical to this AclEntry
+ */
+ @Override
+ public boolean equals(Object ob) {
+ if (ob == this)
+ return true;
+ if (ob == null || !(ob instanceof AclEntry))
+ return false;
+ AclEntry other = (AclEntry)ob;
+ if (this.type != other.type)
+ return false;
+ if (!this.who.equals(other.who))
+ return false;
+ if (!this.perms.equals(other.perms))
+ return false;
+ if (!this.flags.equals(other.flags))
+ return false;
+ return true;
+ }
+
+ private static int hash(int h, Object o) {
+ return h * 127 + o.hashCode();
+ }
+
+ /**
+ * Returns the hash-code value for this ACL entry.
+ *
+ * <p> This method satisfies the general contract of the {@link
+ * Object#hashCode method}.
+ */
+ @Override
+ public int hashCode() {
+ // return cached hash if available
+ if (hash != 0)
+ return hash;
+ int h = type.hashCode();
+ h = hash(h, who);
+ h = hash(h, perms);
+ h = hash(h, flags);
+ hash = h;
+ return hash;
+ }
+
+ /**
+ * Returns the string representation of this ACL entry.
+ *
+ * @return The string representation of this entry
+ */
+ @Override
+ public String toString() {
+ StringBuilder sb = new StringBuilder();
+
+ // who
+ sb.append(who.getName());
+ sb.append(':');
+
+ // permissions
+ for (AclEntryPermission perm: perms) {
+ sb.append(perm.name());
+ sb.append('/');
+ }
+ sb.setLength(sb.length()-1); // drop final slash
+ sb.append(':');
+
+ // flags
+ if (!flags.isEmpty()) {
+ for (AclEntryFlag flag: flags) {
+ sb.append(flag.name());
+ sb.append('/');
+ }
+ sb.setLength(sb.length()-1); // drop final slash
+ sb.append(':');
+ }
+
+ // type
+ sb.append(type.name());
+ return sb.toString();
+ }
+}