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