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 enum Type { 034 035 /** 036 * User right readable. 037 */ 038 UserReadable(0x100), 039 040 /** 041 * User right writable. 042 */ 043 UserWritable(0x080), 044 045 /** 046 * User right executable. 047 */ 048 UserExecutable(0x040), 049 050 /** 051 * Group right readable. 052 */ 053 GroupReadable(0x020), 054 055 /** 056 * Group right writable. 057 */ 058 GroupWritable(0x010), 059 060 /** 061 * Group right executable. 062 */ 063 GroupExecutable(0x008), 064 065 /** 066 * Other right readable. 067 */ 068 OtherReadable(0x004), 069 070 /** 071 * Other right writable. 072 */ 073 OtherWritable(0x002), 074 075 /** 076 * Other right executable. 077 */ 078 OtherExecutable(0x001); 079 080 private final int mask; 081 082 /** 083 * Initialize with the mask 084 */ 085 Type(final int mask) { 086 this.mask = mask; 087 } 088 089 /** 090 * Gets the mask for this permission. 091 * 092 * @return the mask for this permission. 093 */ 094 public int getMask() { 095 return mask; 096 } 097 098 } 099 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}