Check if OS isPosix, if it is - use PosixFilePermission, otherwise use standard Java file methods to check permissions, e.g. canExecute.

This allows to use this utility on Windows or other non-posix machine.
This commit is contained in:
Robertas Zamblauskas 2015-09-02 23:36:41 +03:00
parent e31e92e637
commit 3fe6488324

View File

@ -2,9 +2,11 @@ package org.kamranzafar.jtar;
import java.io.File;
import java.io.IOException;
import java.nio.file.FileSystems;
import java.nio.file.Files;
import java.nio.file.attribute.PosixFilePermission;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
@ -13,27 +15,65 @@ import java.util.Set;
*/
public class PermissionUtils {
private static Map<PosixFilePermission, Integer> permissionToInteger = new HashMap<>();
/**
* XXX: When using standard Java permissions, we treat 'owner' and 'group' equally and give no
* permissions for 'others'.
*/
private static enum StandardFilePermission {
EXECUTE(0110), WRITE(0220), READ(0440);
static {
permissionToInteger.put(PosixFilePermission.OWNER_EXECUTE, 0100);
permissionToInteger.put(PosixFilePermission.OWNER_WRITE, 0200);
permissionToInteger.put(PosixFilePermission.OWNER_READ, 0400);
private int mode;
permissionToInteger.put(PosixFilePermission.GROUP_EXECUTE, 0010);
permissionToInteger.put(PosixFilePermission.GROUP_WRITE, 0020);
permissionToInteger.put(PosixFilePermission.GROUP_READ, 0040);
permissionToInteger.put(PosixFilePermission.OTHERS_EXECUTE, 0001);
permissionToInteger.put(PosixFilePermission.OTHERS_WRITE, 0002);
permissionToInteger.put(PosixFilePermission.OTHERS_READ, 0004);
private StandardFilePermission(int mode) {
this.mode = mode;
}
}
public static Integer permissions(File f) {
Integer number = 0;
private static Map<PosixFilePermission, Integer> posixPermissionToInteger = new HashMap<>();
static {
posixPermissionToInteger.put(PosixFilePermission.OWNER_EXECUTE, 0100);
posixPermissionToInteger.put(PosixFilePermission.OWNER_WRITE, 0200);
posixPermissionToInteger.put(PosixFilePermission.OWNER_READ, 0400);
posixPermissionToInteger.put(PosixFilePermission.GROUP_EXECUTE, 0010);
posixPermissionToInteger.put(PosixFilePermission.GROUP_WRITE, 0020);
posixPermissionToInteger.put(PosixFilePermission.GROUP_READ, 0040);
posixPermissionToInteger.put(PosixFilePermission.OTHERS_EXECUTE, 0001);
posixPermissionToInteger.put(PosixFilePermission.OTHERS_WRITE, 0002);
posixPermissionToInteger.put(PosixFilePermission.OTHERS_READ, 0004);
}
/**
* Get file permissions in octal mode, e.g. 0755.
*
* Note: it uses `java.nio.file.attribute.PosixFilePermission` if OS supports this, otherwise reverts to
* using standard Java file operations, e.g. `java.io.File#canExecute()`. In the first case permissions will
* be precisely as reported by the OS, in the second case 'owner' and 'group' will have equal permissions and
* 'others' will have no permissions, e.g. if file on Windows OS is `read-only` permissions will be `0550`.
*
* @throws NullPointerException if file is null.
* @throws IllegalArgumentException if file does not exist.
*/
public static int permissions(File f) {
if(f == null) {
throw new NullPointerException("File is null.");
}
if(!f.exists()) {
throw new IllegalArgumentException("File " + f + " does not exist.");
}
return isPosix ? posixPermissions(f) : standardPermissions(f);
}
private static final boolean isPosix = FileSystems.getDefault().supportedFileAttributeViews().contains("posix");
private static int posixPermissions(File f) {
int number = 0;
try {
Set<PosixFilePermission> permissions = Files.getPosixFilePermissions(f.toPath());
for (Map.Entry<PosixFilePermission, Integer> entry : permissionToInteger.entrySet()) {
for (Map.Entry<PosixFilePermission, Integer> entry : posixPermissionToInteger.entrySet()) {
if (permissions.contains(entry.getKey())) {
number += entry.getValue();
}
@ -43,4 +83,27 @@ public class PermissionUtils {
}
return number;
}
private static Set<StandardFilePermission> readStandardPermissions(File f) {
Set<StandardFilePermission> permissions = new HashSet<>();
if(f.canExecute()) {
permissions.add(StandardFilePermission.EXECUTE);
}
if(f.canWrite()) {
permissions.add(StandardFilePermission.WRITE);
}
if(f.canRead()) {
permissions.add(StandardFilePermission.READ);
}
return permissions;
}
private static Integer standardPermissions(File f) {
int number = 0;
Set<StandardFilePermission> permissions = readStandardPermissions(f);
for (StandardFilePermission permission : permissions) {
number += permission.mode;
}
return number;
}
}