1 /*
2 * Licensed to the Apache Software Foundation (ASF) under one or more
3 * contributor license agreements. See the NOTICE file distributed with
4 * this work for additional information regarding copyright ownership.
5 * The ASF licenses this file to You under the Apache License, Version 2.0
6 * (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18 package org.apache.commons.vfs2.util;
19
20 import java.util.EnumMap;
21 import java.util.Map;
22
23 /**
24 * Unix permissions.
25 *
26 * @since 2.1
27 */
28 public class PosixPermissions {
29
30 /**
31 * Permission types.
32 */
33 public enum Type {
34
35 /**
36 * User right readable.
37 */
38 UserReadable(0x100),
39
40 /**
41 * User right writable.
42 */
43 UserWritable(0x080),
44
45 /**
46 * User right executable.
47 */
48 UserExecutable(0x040),
49
50 /**
51 * Group right readable.
52 */
53 GroupReadable(0x020),
54
55 /**
56 * Group right writable.
57 */
58 GroupWritable(0x010),
59
60 /**
61 * Group right executable.
62 */
63 GroupExecutable(0x008),
64
65 /**
66 * Other right readable.
67 */
68 OtherReadable(0x004),
69
70 /**
71 * Other right writable.
72 */
73 OtherWritable(0x002),
74
75 /**
76 * Other right executable.
77 */
78 OtherExecutable(0x001);
79
80 private final int mask;
81
82 /**
83 * Initialize with the mask
84 */
85 Type(final int mask) {
86 this.mask = mask;
87 }
88
89 /**
90 * Gets the mask for this permission.
91 *
92 * @return the mask for this permission.
93 */
94 public int getMask() {
95 return mask;
96 }
97
98 }
99
100 /**
101 * Current permissions.
102 */
103 private final int permissions;
104
105 /**
106 * If the user is the owner of the file.
107 */
108 private final boolean isOwner;
109
110 /**
111 * If one user group is the group of the file.
112 */
113 private final boolean isInGroup;
114
115 /**
116 * Creates a new PosixPermissions object.
117 *
118 * @param permissions The permissions
119 * @param isOwner true if the user is the owner of the file
120 * @param isInGroup true if the user is a group owner of the file
121 */
122 public PosixPermissions(final int permissions, final boolean isOwner, final boolean isInGroup) {
123 this.permissions = permissions;
124 this.isOwner = isOwner;
125 this.isInGroup = isInGroup;
126 }
127
128 /**
129 * Computes new permission from old ones.
130 *
131 * @param values The permissions to set.
132 * @return The new permissions.
133 */
134 private int computeNewPermissions(final Map<Type, Boolean> values) {
135 int newPerms = permissions;
136 for (final Map.Entry<Type, Boolean> entry : values.entrySet()) {
137 final Type type = entry.getKey();
138 if (entry.getValue()) {
139 newPerms |= type.getMask();
140 } else {
141 newPerms &= ~type.getMask();
142 }
143 }
144 return newPerms;
145 }
146
147 /**
148 * Tests whether the bit corresponding to the permission is set.
149 *
150 * @return whether the bit corresponding to the permission is set.
151 */
152 private boolean get(final Type type) {
153 return (type.getMask() & permissions) != 0;
154 }
155
156 /**
157 * Gets permissions.
158 *
159 * @return permissions.
160 */
161 public int getPermissions() {
162 return permissions;
163 }
164
165 /**
166 * Gets whether the permissions are executable.
167 *
168 * @return whether the permissions are executable.
169 */
170 public boolean isExecutable() {
171 if (isOwner) {
172 return get(Type.UserExecutable);
173 }
174 if (isInGroup) {
175 return get(Type.GroupExecutable);
176 }
177 return get(Type.OtherExecutable);
178 }
179
180 /**
181 * Gets whether the permissions are readable.
182 *
183 * @return whether the permissions are readable.
184 */
185 public boolean isReadable() {
186 if (isOwner) {
187 return get(Type.UserReadable);
188 }
189 if (isInGroup) {
190 return get(Type.GroupReadable);
191 }
192 return get(Type.OtherReadable);
193 }
194
195 /**
196 * Gets whether the permissions are writable.
197 *
198 * @return whether the permissions are writable.
199 */
200 public boolean isWritable() {
201 if (isOwner) {
202 return get(Type.UserWritable);
203 }
204 if (isInGroup) {
205 return get(Type.GroupWritable);
206 }
207 return get(Type.OtherWritable);
208 }
209
210 /**
211 * Creates new permissions based on these permissions.
212 *
213 * @param executable Whether the new permissions should be readable.
214 * @param ownerOnly Whether the new permissions are only for the owner.
215 * @return the new permissions.
216 */
217 public int makeExecutable(final boolean executable, final boolean ownerOnly) {
218 final EnumMap<Type, Boolean> map = new EnumMap<>(Type.class);
219 map.put(Type.UserExecutable, executable);
220 if (!ownerOnly) {
221 map.put(Type.GroupExecutable, executable);
222 map.put(Type.OtherExecutable, executable);
223 }
224 return computeNewPermissions(map);
225 }
226
227 /**
228 * Creates new permissions based on these permissions.
229 *
230 * @param readable Whether the new permissions should be readable.
231 * @param ownerOnly Whether the new permissions are only for the owner.
232 * @return the new permissions.
233 */
234 public Integer makeReadable(final boolean readable, final boolean ownerOnly) {
235 final EnumMap<Type, Boolean> map = new EnumMap<>(Type.class);
236 map.put(Type.UserReadable, readable);
237 if (!ownerOnly) {
238 map.put(Type.GroupReadable, readable);
239 map.put(Type.OtherReadable, readable);
240 }
241 return computeNewPermissions(map);
242 }
243
244 /**
245 * Creates new permissions based on these permissions.
246 *
247 * @param writable Whether the new permissions should be readable.
248 * @param ownerOnly Whether the new permissions are only for the owner.
249 * @return the new permissions.
250 */
251 public Integer makeWritable(final boolean writable, final boolean ownerOnly) {
252 final EnumMap<Type, Boolean> map = new EnumMap<>(Type.class);
253 map.put(Type.UserWritable, writable);
254 if (!ownerOnly) {
255 map.put(Type.GroupWritable, writable);
256 map.put(Type.OtherWritable, writable);
257 }
258 return computeNewPermissions(map);
259 }
260 }