001/* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017 018package org.apache.commons.vfs2.util; 019 020import java.util.EnumMap; 021import java.util.Map; 022 023/** 024 * UNIX permissions. 025 * 026 * @since 2.1 027 */ 028public class PosixPermissions { 029 030 /** 031 * Permission types. 032 */ 033 public static enum Type { 034 /** 035 * User right readable. 036 */ 037 UserReadable(00400), 038 039 /** 040 * User right writable. 041 */ 042 UserWritable(00200), 043 044 /** 045 * User right executable. 046 */ 047 UserExecutable(00100), 048 049 /** 050 * Group right readable. 051 */ 052 GroupReadable(00040), 053 054 /** 055 * Group right writable. 056 */ 057 GroupWritable(00020), 058 059 /** 060 * Group right executable. 061 */ 062 GroupExecutable(00010), 063 064 /** 065 * Other right readable. 066 */ 067 OtherReadable(00004), 068 069 /** 070 * Other right writable. 071 */ 072 OtherWritable(00002), 073 074 /** 075 * Other right executable. 076 */ 077 OtherExecutable(00001); 078 079 private final int mask; 080 081 /** 082 * Initialize with the mask 083 */ 084 private Type(final int mask) { 085 this.mask = mask; 086 } 087 088 /** 089 * Return the mask for this permission. 090 * 091 * @return the mask for this permission. 092 */ 093 public int getMask() { 094 return this.mask; 095 } 096 097 } 098 099 /** 100 * Current permissions. 101 */ 102 private final int permissions; 103 104 /** 105 * If the user is the owner of the file. 106 */ 107 private final boolean isOwner; 108 109 /** 110 * If one user group is the group of the file. 111 */ 112 private final boolean isInGroup; 113 114 /** 115 * Creates a new PosixPermissions object. 116 * 117 * @param permissions The permissions 118 * @param isOwner true if the user is the owner of the file 119 * @param isInGroup true if the user is a group owner of the file 120 */ 121 public PosixPermissions(final int permissions, final boolean isOwner, final boolean isInGroup) { 122 this.permissions = permissions; 123 this.isOwner = isOwner; 124 this.isInGroup = isInGroup; 125 } 126 127 /** 128 * Computes new permission from old ones. 129 * 130 * @param values The permissions to set. 131 * @return The new permissions. 132 */ 133 private int computeNewPermissions(final Map<Type, Boolean> values) { 134 int newPerms = this.permissions; 135 for (final Map.Entry<Type, Boolean> entry : values.entrySet()) { 136 final Type type = entry.getKey(); 137 if (entry.getValue()) { 138 newPerms |= type.getMask(); 139 } else { 140 newPerms &= ~type.getMask(); 141 } 142 } 143 return newPerms; 144 } 145 146 /** 147 * Tests whether the bit corresponding to the permission is set. 148 * 149 * @return whether the bit corresponding to the permission is set. 150 */ 151 private boolean get(final Type type) { 152 return (type.getMask() & this.permissions) != 0; 153 } 154 155 /** 156 * Gets permissions. 157 * 158 * @return permissions. 159 */ 160 public int getPermissions() { 161 return this.permissions; 162 } 163 164 /** 165 * Gets whether the permissions are executable. 166 * 167 * @return whether the permissions are executable. 168 */ 169 public boolean isExecutable() { 170 if (this.isOwner) { 171 return this.get(Type.UserExecutable); 172 } 173 if (this.isInGroup) { 174 return this.get(Type.GroupExecutable); 175 } 176 return this.get(Type.OtherExecutable); 177 } 178 179 /** 180 * Gets whether the permissions are readable. 181 * 182 * @return whether the permissions are readable. 183 */ 184 public boolean isReadable() { 185 if (this.isOwner) { 186 return this.get(Type.UserReadable); 187 } 188 if (this.isInGroup) { 189 return this.get(Type.GroupReadable); 190 } 191 return this.get(Type.OtherReadable); 192 } 193 194 /** 195 * Gets whether the permissions are writable. 196 * 197 * @return whether the permissions are writable. 198 */ 199 public boolean isWritable() { 200 if (this.isOwner) { 201 return this.get(Type.UserWritable); 202 } 203 if (this.isInGroup) { 204 return this.get(Type.GroupWritable); 205 } 206 return this.get(Type.OtherWritable); 207 } 208 209 /** 210 * Creates new permissions based on these permissions. 211 * 212 * @param executable Whether the new permissions should be readable. 213 * @param ownerOnly Whether the new permissions are only for the owner. 214 * @return the new permissions. 215 */ 216 public int makeExecutable(final boolean executable, final boolean ownerOnly) { 217 final EnumMap<Type, Boolean> map = new EnumMap<>(Type.class); 218 map.put(Type.UserExecutable, executable); 219 if (!ownerOnly) { 220 map.put(Type.GroupExecutable, executable); 221 map.put(Type.OtherExecutable, executable); 222 } 223 return this.computeNewPermissions(map); 224 } 225 226 /** 227 * Creates new permissions based on these permissions. 228 * 229 * @param readable Whether the new permissions should be readable. 230 * @param ownerOnly Whether the new permissions are only for the owner. 231 * @return the new permissions. 232 */ 233 public Integer makeReadable(final boolean readable, final boolean ownerOnly) { 234 final EnumMap<Type, Boolean> map = new EnumMap<>(Type.class); 235 map.put(Type.UserReadable, readable); 236 if (!ownerOnly) { 237 map.put(Type.GroupReadable, readable); 238 map.put(Type.OtherReadable, readable); 239 } 240 return this.computeNewPermissions(map); 241 } 242 243 /** 244 * Creates new permissions based on these permissions. 245 * 246 * @param writable Whether the new permissions should be readable. 247 * @param ownerOnly Whether the new permissions are only for the owner. 248 * @return the new permissions. 249 */ 250 public Integer makeWritable(final boolean writable, final boolean ownerOnly) { 251 final EnumMap<Type, Boolean> map = new EnumMap<>(Type.class); 252 map.put(Type.UserWritable, writable); 253 if (!ownerOnly) { 254 map.put(Type.GroupWritable, writable); 255 map.put(Type.OtherWritable, writable); 256 } 257 return this.computeNewPermissions(map); 258 } 259}