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      /**
32       * Permission types.
33       */
34      public static enum Type
35      {
36          /**
37           * User right readable.
38           */
39          UserReadable(00400),
40  
41          /**
42           * User right writable.
43           */
44          UserWritable(00200),
45  
46          /**
47           * User right executable.
48           */
49          UserExecutable(00100),
50  
51          /**
52           * Group right readable.
53           */
54          GroupReadable(00040),
55  
56          /**
57           * Group right writable.
58           */
59          GroupWritable(00020),
60  
61          /**
62           * Group right executable.
63           */
64          GroupExecutable(00010),
65  
66          /**
67           * Other right readable.
68           */
69          OtherReadable(00004),
70  
71          /**
72           * Other right writable.
73           */
74          OtherWritable(00002),
75  
76          /**
77           * Other right executable.
78           */
79          OtherExecutable(00001);
80  
81          private final int mask;
82  
83          /**
84           * Initialize with the mask
85           */
86          private Type(final int mask)
87          {
88              this.mask = mask;
89          }
90  
91          /**
92           * Return the mask for this permission.
93           *
94           * @return the mask for this permission.
95           */
96          public int getMask()
97          {
98              return this.mask;
99          }
100 
101     }
102 
103     /**
104      * Current permissions.
105      */
106     private final int permissions;
107 
108     /**
109      * If the user is the owner of the file.
110      */
111     private final boolean isOwner;
112 
113     /**
114      * If one user group is the group of the file.
115      */
116     private final boolean isInGroup;
117 
118     /**
119      * Creates a new PosixPermissions object.
120      *
121      * @param permissions
122      *            The permissions
123      * @param isOwner
124      *            true if the user is the owner of the file
125      * @param isInGroup
126      *            true if the user is a group owner of the file
127      */
128     public PosixPermissions(final int permissions, final boolean isOwner, final boolean isInGroup)
129     {
130         this.permissions = permissions;
131         this.isOwner = isOwner;
132         this.isInGroup = isInGroup;
133     }
134 
135     /**
136      * Computes new permission from old ones.
137      *
138      * @param values
139      *            The permissions to set.
140      * @return The new permissions.
141      */
142     private int computeNewPermissions(final Map<Type, Boolean> values)
143     {
144         int newPerms = this.permissions;
145         for (final Map.Entry<Type, Boolean> entry : values.entrySet())
146         {
147             final Type type = entry.getKey();
148             if (entry.getValue())
149             {
150                 newPerms |= type.getMask();
151             }
152             else
153             {
154                 newPerms &= ~type.getMask();
155             }
156         }
157         return newPerms;
158     }
159 
160     /**
161      * Tests whether the bit corresponding to the permission is set.
162      *
163      * @return whether the bit corresponding to the permission is set.
164      */
165     private boolean get(final Type type)
166     {
167         return (type.getMask() & this.permissions) != 0;
168     }
169 
170     /**
171      * Gets permissions.
172      *
173      * @return permissions.
174      */
175     public int getPermissions()
176     {
177         return this.permissions;
178     }
179 
180     /**
181      * Gets whether the permissions are executable.
182      *
183      * @return whether the permissions are executable.
184      */
185     public boolean isExecutable()
186     {
187         if (this.isOwner)
188         {
189             return this.get(Type.UserExecutable);
190         }
191         if (this.isInGroup)
192         {
193             return this.get(Type.GroupExecutable);
194         }
195         return this.get(Type.OtherExecutable);
196     }
197 
198     /**
199      * Gets whether the permissions are readable.
200      *
201      * @return whether the permissions are readable.
202      */
203     public boolean isReadable()
204     {
205         if (this.isOwner)
206         {
207             return this.get(Type.UserReadable);
208         }
209         if (this.isInGroup)
210         {
211             return this.get(Type.GroupReadable);
212         }
213         return this.get(Type.OtherReadable);
214     }
215 
216     /**
217      * Gets whether the permissions are writable.
218      *
219      * @return whether the permissions are writable.
220      */
221     public boolean isWritable()
222     {
223         if (this.isOwner)
224         {
225             return this.get(Type.UserWritable);
226         }
227         if (this.isInGroup)
228         {
229             return this.get(Type.GroupWritable);
230         }
231         return this.get(Type.OtherWritable);
232     }
233 
234     /**
235      * Creates new permissions based on these permissions.
236      *
237      * @param executable
238      *            Whether the new permissions should be readable.
239      * @param ownerOnly
240      *            Whether the new permissions are only for the owner.
241      * @return the new permissions.
242      */
243     public int makeExecutable(final boolean executable, final boolean ownerOnly)
244     {
245         final EnumMap<Type, Boolean> map = new EnumMap<Type, Boolean>(Type.class);
246         map.put(Type.UserExecutable, executable);
247         if (!ownerOnly)
248         {
249             map.put(Type.GroupExecutable, executable);
250             map.put(Type.OtherExecutable, executable);
251         }
252         return this.computeNewPermissions(map);
253     }
254 
255     /**
256      * Creates new permissions based on these permissions.
257      *
258      * @param readable
259      *            Whether the new permissions should be readable.
260      * @param ownerOnly
261      *            Whether the new permissions are only for the owner.
262      * @return the new permissions.
263      */
264     public Integer makeReadable(final boolean readable, final boolean ownerOnly)
265     {
266         final EnumMap<Type, Boolean> map = new EnumMap<Type, Boolean>(Type.class);
267         map.put(Type.UserReadable, readable);
268         if (!ownerOnly)
269         {
270             map.put(Type.GroupReadable, readable);
271             map.put(Type.OtherReadable, readable);
272         }
273         return this.computeNewPermissions(map);
274     }
275 
276     /**
277      * Creates new permissions based on these permissions.
278      *
279      * @param writable
280      *            Whether the new permissions should be readable.
281      * @param ownerOnly
282      *            Whether the new permissions are only for the owner.
283      * @return the new permissions.
284      */
285     public Integer makeWritable(final boolean writable, final boolean ownerOnly)
286     {
287         final EnumMap<Type, Boolean> map = new EnumMap<Type, Boolean>(Type.class);
288         map.put(Type.UserWritable, writable);
289         if (!ownerOnly)
290         {
291             map.put(Type.GroupWritable, writable);
292             map.put(Type.OtherWritable, writable);
293         }
294         return this.computeNewPermissions(map);
295     }
296 }