com.palantir.giraffe.file.base.attribute.ChmodFilePermissions Maven / Gradle / Ivy
/**
* Copyright 2015 Palantir Technologies, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.palantir.giraffe.file.base.attribute;
import static com.google.common.base.Preconditions.checkArgument;
import java.nio.file.attribute.PosixFilePermission;
import java.util.EnumSet;
import java.util.Map.Entry;
import java.util.Set;
import com.google.common.collect.ImmutableMap;
/**
* Converts {@link PosixFilePermission}s to and from representations used by the
* {@code chmod} command and system call.
*
* @author bkeyes
*/
public final class ChmodFilePermissions {
private static final int R_BIT = 0x4;
private static final int W_BIT = 0x2;
private static final int E_BIT = 0x1;
private static final int U_SHIFT = 6;
private static final int G_SHIFT = 3;
private static final int O_SHIFT = 0;
private static final int MASK = 0x7;
private static final ImmutableMap permissionsBitMap;
static {
ImmutableMap.Builder builder = ImmutableMap.builder();
builder.put(PosixFilePermission.OWNER_READ, R_BIT << U_SHIFT);
builder.put(PosixFilePermission.OWNER_WRITE, W_BIT << U_SHIFT);
builder.put(PosixFilePermission.OWNER_EXECUTE, E_BIT << U_SHIFT);
builder.put(PosixFilePermission.GROUP_READ, R_BIT << G_SHIFT);
builder.put(PosixFilePermission.GROUP_WRITE, W_BIT << G_SHIFT);
builder.put(PosixFilePermission.GROUP_EXECUTE, E_BIT << G_SHIFT);
builder.put(PosixFilePermission.OTHERS_READ, R_BIT << O_SHIFT);
builder.put(PosixFilePermission.OTHERS_WRITE, W_BIT << O_SHIFT);
builder.put(PosixFilePermission.OTHERS_EXECUTE, E_BIT << O_SHIFT);
permissionsBitMap = builder.build();
}
/**
* Converts the specified bit field representation into a
* {@code PosixFilePermission} set. Unknown bits are ignored.
*
* @param bits the bit field representation of the permissions. Octal
* notation is traditionally used when specifying the bit field
* directly.
*/
public static Set toPermissions(int bits) {
EnumSet permissions = EnumSet.noneOf(PosixFilePermission.class);
for (Entry e : permissionsBitMap.entrySet()) {
if ((bits & e.getValue()) != 0) {
permissions.add(e.getKey());
}
}
return permissions;
}
/**
* Converts the specified {@code PosixFilePermission} set into a bit field
* representation.
*
* @param permissions the set of permissions
*/
public static int toBits(Set permissions) {
int bits = 0;
for (PosixFilePermission perm : permissions) {
bits |= permissionsBitMap.get(perm);
}
return bits;
}
/**
* Converts the specified {@code PosixFilePermission} set and change type
* into a {@code chmod} mode string.
*
* @param change the type of change
* @param permissions the permissions to change
*
* @return a mode string representing the specified permissions change
*
* @throws IllegalArgumentException if {@code permissions} is empty and
* {@code change} is not {@code PermissionChange.SET}
*/
public static String toMode(PermissionChange change, Set permissions) {
checkArgument(!permissions.isEmpty() || change == PermissionChange.SET,
"permission set is empty but change type is not SET");
StringBuilder modes = new StringBuilder();
int bits = toBits(permissions);
int ubits = (bits >> U_SHIFT) & MASK;
if (ubits != 0) {
writeMode(modes.append("u").append(change.getOperator()), ubits);
}
int gbits = (bits >> G_SHIFT) & MASK;
if (gbits != 0) {
if (modes.length() > 0) {
modes.append(',');
}
writeMode(modes.append("g").append(change.getOperator()), gbits);
}
int obits = (bits >> O_SHIFT) & MASK;
if (obits != 0) {
if (modes.length() > 0) {
modes.append(',');
}
writeMode(modes.append("o").append(change.getOperator()), obits);
}
return modes.toString();
}
private static void writeMode(StringBuilder mode, int bits) {
if ((bits & R_BIT) != 0) {
mode.append('r');
}
if ((bits & W_BIT) != 0) {
mode.append('w');
}
if ((bits & E_BIT) != 0) {
mode.append('x');
}
}
private ChmodFilePermissions() {
throw new UnsupportedOperationException();
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy