View Javadoc
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 }