All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.zeroturnaround.zip.Java7Nio2ApiPermissionsStrategy Maven / Gradle / Ivy

Go to download

The project is intended to have a small, easy and fast library to process ZIP archives. Either create, modify or explode them. On disk or in memory.

There is a newer version: 1.17
Show newest version
package org.zeroturnaround.zip;

import java.io.File;
import java.lang.reflect.Array;
import java.lang.reflect.Method;
import java.util.HashSet;
import java.util.Set;

/**
 * ZTFilePermissionsStrategy which uses Java 7 posix file permissions
 * 
 * @author VIktor Karabut
 */
class Java7Nio2ApiPermissionsStrategy implements ZTFilePermissionsStrategy {
  private final Class> posixFilePermissionClass;
  private final Class filesClass;
  private final Class pathClass;
  private final Class> linkOptionClass;
  private final Enum[] linkOptionsArray;
  
  private final Method toPathMethod;
  private final Method setPosixFilePermissionsMethod;
  private final Method getPosixFilePermissionsMethod;
  
  private final Object OWNER_READ;
  private final Object OWNER_WRITE;
  private final Object OWNER_EXECUTE;
  private final Object GROUP_READ;
  private final Object GROUP_WRITE;
  private final Object GROUP_EXECUTE;
  private final Object OTHERS_READ;
  private final Object OTHERS_WRITE;
  private final Object OTHERS_EXECUTE;
  
  
  @SuppressWarnings("unchecked")
  public Java7Nio2ApiPermissionsStrategy() {
    if (!isPosix()) {
      throw new ZipException("File system does not support POSIX file attributes");
    }
    
    posixFilePermissionClass = 
        (Class>) ZTZipReflectionUtil.getClassForName("java.nio.file.attribute.PosixFilePermission", Enum.class);
    Enum[] constants = posixFilePermissionClass.getEnumConstants();
    OWNER_READ = constants[0];
    OWNER_WRITE = constants[1];
    OWNER_EXECUTE = constants[2];
    GROUP_READ = constants[3];
    GROUP_WRITE = constants[4];
    GROUP_EXECUTE = constants[5];
    OTHERS_READ = constants[6];
    OTHERS_WRITE = constants[7];
    OTHERS_EXECUTE = constants[8];
    
    linkOptionClass = 
        (Class>) ZTZipReflectionUtil.getClassForName("java.nio.file.LinkOption", Enum.class);
    linkOptionsArray = (Enum[]) Array.newInstance(linkOptionClass, 1);
    linkOptionsArray[0] = (Enum) linkOptionClass.getEnumConstants()[0]; // LinkOption.NOFOLLOW_LINKS;
    
    filesClass = ZTZipReflectionUtil.getClassForName("java.nio.file.Files", Object.class);
    pathClass = ZTZipReflectionUtil.getClassForName("java.nio.file.Path", Object.class);
    
    toPathMethod = ZTZipReflectionUtil.getDeclaredMethod(File.class, "toPath");
    setPosixFilePermissionsMethod = ZTZipReflectionUtil.getDeclaredMethod(filesClass, "setPosixFilePermissions", pathClass, Set.class);
    getPosixFilePermissionsMethod = ZTZipReflectionUtil.getDeclaredMethod(filesClass, "getPosixFilePermissions", pathClass, linkOptionsArray.getClass());
  }

  public ZTFilePermissions getPermissions(File file) {
    ZTFilePermissions permissions = new ZTFilePermissions();
    permissions.setDirectory(file.isDirectory());
    
    Set posixFilePermissions = getPosixFilePermissions(file);
    
    permissions.setOwnerCanRead(   posixFilePermissions.contains(OWNER_READ));
    permissions.setOwnerCanWrite(  posixFilePermissions.contains(OWNER_WRITE));
    permissions.setOwnerCanExecute(posixFilePermissions.contains(OWNER_EXECUTE));
    
    permissions.setGroupCanRead(   posixFilePermissions.contains(GROUP_READ));
    permissions.setGroupCanWrite(  posixFilePermissions.contains(GROUP_WRITE));
    permissions.setGroupCanExecute(posixFilePermissions.contains(GROUP_EXECUTE));
    
    permissions.setOthersCanRead(   posixFilePermissions.contains(OTHERS_READ));
    permissions.setOthersCanWrite(  posixFilePermissions.contains(OTHERS_WRITE));
    permissions.setOthersCanExecute(posixFilePermissions.contains(OTHERS_EXECUTE));
    
    return permissions;
  }

  public void setPermissions(File file, ZTFilePermissions permissions) {
    Set set = new HashSet();
    addIf(permissions.isOwnerCanRead(), set, OWNER_READ);
    addIf(permissions.isOwnerCanRead(),   set,OWNER_READ);
    addIf(permissions.isOwnerCanWrite(),  set,OWNER_WRITE);
    addIf(permissions.isOwnerCanExecute(),set,OWNER_EXECUTE);
    
    addIf(permissions.isGroupCanRead(),   set,GROUP_READ);
    addIf(permissions.isGroupCanWrite(),  set,GROUP_WRITE);
    addIf(permissions.isGroupCanExecute(),set,GROUP_EXECUTE);
    
    addIf(permissions.isOthersCanRead(),   set,OTHERS_READ);
    addIf(permissions.isOthersCanWrite(),  set,OTHERS_WRITE);
    addIf(permissions.isOthersCanExecute(),set,OTHERS_EXECUTE);
    
    setPosixFilePermissions(file, set);
  }
  
  private  void addIf(boolean condition, Set set, E el) {
    if (condition) {
      set.add(el);
    }
  }
  
  /**
   * Construct java.nio.file.Path object from abstract path.
   * Invokes JDK7 file.toPath() method through reflection.
   * 
   * @param file
   * @return instance of java.nio.file.Path object
   */
  private Object toPath(File file) {
    return ZTZipReflectionUtil.invoke(toPathMethod, file);
  }
  
  // Files.setPosixFilePermissions(file.toPath(), set);
  private void setPosixFilePermissions(File file, Set set) {
    ZTZipReflectionUtil.invoke(setPosixFilePermissionsMethod, null, toPath(file), set);
  }
  
  // Files.getPosixFilePermissions(file.toPath(), new LinkOption[]{ LinkOption.NOFOLLOW_LINKS });
  private Set getPosixFilePermissions(File file) {
    return (Set) ZTZipReflectionUtil.invoke(getPosixFilePermissionsMethod, null, toPath(file), linkOptionsArray);
  }
  
  // FileSystems.getDefault().supportedFileAttrubuteViews().contains("posix");
  private static boolean isPosix() {
    Method getDefaultMethod = ZTZipReflectionUtil.getDeclaredMethod(
        ZTZipReflectionUtil.getClassForName("java.nio.file.FileSystems", Object.class), "getDefault");
    Method supportedFileAttributeViewsMethod = ZTZipReflectionUtil.getDeclaredMethod(
        ZTZipReflectionUtil.getClassForName("java.nio.file.FileSystem", Object.class), "supportedFileAttributeViews");
    
    Object fileSystem = ZTZipReflectionUtil.invoke(getDefaultMethod, null);
    @SuppressWarnings("unchecked")
    Set views = (Set) ZTZipReflectionUtil.invoke(supportedFileAttributeViewsMethod, fileSystem);
    
    return views.contains("posix");
  }
}