< prev index next >

src/jdk.zipfs/share/classes/jdk/nio/zipfs/ZipUtils.java

Print this page
rev 52310 : 8213031: (zipfs) Add support for POSIX file permissions

@@ -1,7 +1,7 @@
 /*
- * Copyright (c) 2009, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 2018, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License version 2 only, as
  * published by the Free Software Foundation.  Oracle designates this

@@ -25,26 +25,168 @@
 
 package jdk.nio.zipfs;
 
 import java.io.IOException;
 import java.io.OutputStream;
+import java.nio.file.attribute.PosixFilePermission;
 import java.time.DateTimeException;
 import java.time.Instant;
 import java.time.LocalDateTime;
 import java.time.ZoneId;
 import java.util.Arrays;
+import java.util.Collections;
 import java.util.Date;
-import java.util.regex.PatternSyntaxException;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+import java.util.WeakHashMap;
 import java.util.concurrent.TimeUnit;
+import java.util.regex.PatternSyntaxException;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
 
 /**
- *
  * @author Xueming Shen
  */
-
 class ZipUtils {
 
+    /**
+     * The value indicating unix file attributes in CEN field "version made by".
+     */
+    static final int FILE_ATTRIBUTES_UNIX = 3;
+
+    /**
+     * Constant used to calculate "version made by".
+     */
+    static final int VERSION_BASE_UNIX = FILE_ATTRIBUTES_UNIX << 8;
+
+    /**
+     * The bit flag used to specify read permission by the owner.
+     */
+    static final int POSIX_USER_READ = 0400;
+
+    /**
+     * The bit flag used to specify write permission by the owner.
+     */
+    static final int POSIX_USER_WRITE = 0200;
+
+    /**
+     * The bit flag used to specify execute permission by the owner.
+     */
+    static final int POSIX_USER_EXECUTE = 0100;
+
+    /**
+     * The bit flag used to specify read permission by the group.
+     */
+    static final int POSIX_GROUP_READ = 040;
+
+    /**
+     * The bit flag used to specify write permission by the group.
+     */
+    static final int POSIX_GROUP_WRITE = 020;
+
+    /**
+     * The bit flag used to specify execute permission by the group.
+     */
+    static final int POSIX_GROUP_EXECUTE = 010;
+
+    /**
+     * The bit flag used to specify read permission by others.
+     */
+    static final int POSIX_OTHER_READ = 04;
+
+    /**
+     * The bit flag used to specify write permission by others.
+     */
+    static final int POSIX_OTHER_WRITE = 02;
+
+    /**
+     * The bit flag used to specify execute permission by others.
+     */
+    static final int POSIX_OTHER_EXECUTE = 01;
+
+    /**
+     * This weak hashmap contains pre-calculated permission sets.
+     */
+    private static final Map<Integer, Set<PosixFilePermission>> permCache = new WeakHashMap<>();
+
+    /**
+     * Convert a {@link PosixFilePermission} object into the appropriate bit
+     * flag.
+     *
+     * @param perm The {@link PosixFilePermission} object.
+     * @return The bit flag as int.
+     */
+    private static int permToFlag(PosixFilePermission perm) {
+        switch(perm) {
+        case OWNER_READ:
+            return POSIX_USER_READ;
+        case OWNER_WRITE:
+            return POSIX_USER_WRITE;
+        case OWNER_EXECUTE:
+            return POSIX_USER_EXECUTE;
+        case GROUP_READ:
+            return POSIX_GROUP_READ;
+        case GROUP_WRITE:
+            return POSIX_GROUP_WRITE;
+        case GROUP_EXECUTE:
+            return POSIX_GROUP_EXECUTE;
+        case OTHERS_READ:
+            return POSIX_OTHER_READ;
+        case OTHERS_WRITE:
+            return POSIX_OTHER_WRITE;
+        case OTHERS_EXECUTE:
+            return POSIX_OTHER_EXECUTE;
+        default:
+            return 0;
+        }
+    }
+
+    /**
+     * Converts a set of {@link PosixFilePermission}s into an int value where
+     * the according bits are set.
+     *
+     * @param perms A Set of {@link PosixFilePermission} objects.
+     *
+     * @return A bit mask representing the input Set.
+     */
+    static int permsToFlags(Set<PosixFilePermission> perms) {
+        if (perms == null) {
+            return -1;
+        }
+        int flags = 0;
+        for (PosixFilePermission perm : perms) {
+            flags |= permToFlag(perm);
+        }
+        return flags;
+    }
+
+    /**
+     * Converts a bit mask of Posix file permissions into a set of
+     * {@link PosixFilePermission} objects.
+     *
+     * @param flags The bit mask containing the flags.
+     *
+     * @return A set of {@link PosixFilePermission} objects matching the input
+     *         flags.
+     */
+    static Set<PosixFilePermission> permsFromFlags(int flags) {
+        if (flags == 0) {
+            return Collections.<PosixFilePermission>emptySet();
+        }
+        Set<PosixFilePermission> perms = permCache.get(flags);
+        if (perms == null) {
+            perms = Stream.of(PosixFilePermission.values())
+                .filter(perm -> 0 != (flags & permToFlag(perm)))
+                .collect(Collectors.toSet());
+            synchronized (permCache) {
+                permCache.put(flags, perms);
+            }
+        }
+        return new HashSet<>(perms);
+    }
+
     /*
      * Writes a 16-bit short to the output stream in little-endian byte order.
      */
     public static void writeShort(OutputStream os, int v) throws IOException {
         os.write(v & 0xff);
< prev index next >