< prev index next >

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

Print this page




  71 import static jdk.nio.zipfs.ZipUtils.*;
  72 
  73 /**
  74  * A FileSystem built on a zip file
  75  *
  76  * @author Xueming Shen
  77  */
  78 class ZipFileSystem extends FileSystem {
  79     // statics
  80     private static final boolean isWindows = AccessController.doPrivileged(
  81         (PrivilegedAction<Boolean>)()->System.getProperty("os.name")
  82                                              .startsWith("Windows"));
  83     private static final byte[] ROOTPATH = new byte[] { '/' };
  84     private static final String OPT_POSIX = "enablePosixFileAttributes";
  85     private static final String OPT_DEFAULT_OWNER = "defaultOwner";
  86     private static final String OPT_DEFAULT_GROUP = "defaultGroup";
  87     private static final String OPT_DEFAULT_PERMISSIONS = "defaultPermissions";
  88 
  89     private static final Set<PosixFilePermission> DEFAULT_PERMISSIONS =
  90         PosixFilePermissions.fromString("rwxrwxrwx");






  91 
  92     private final ZipFileSystemProvider provider;
  93     private final Path zfpath;
  94     final ZipCoder zc;
  95     private final ZipPath rootdir;
  96     private boolean readOnly; // readonly file system, false by default
  97 
  98     // default time stamp for pseudo entries
  99     private final long zfsDefaultTimeStamp = System.currentTimeMillis();
 100 
 101     // configurable by env map
 102     private final boolean noExtt;        // see readExtra()
 103     private final boolean useTempFile;   // use a temp file for newOS, default
 104                                          // is to use BAOS for better performance
 105     private final boolean forceEnd64;
 106     private final int defaultCompressionMethod; // METHOD_STORED if "noCompression=true"
 107                                                 // METHOD_DEFLATED otherwise
 108 
 109     // POSIX support
 110     final boolean supportPosix;
 111     private final UserPrincipal defaultOwner;
 112     private final GroupPrincipal defaultGroup;
 113     private final Set<PosixFilePermission> defaultPermissions;
 114 
 115     private final Set<String> supportedFileAttributeViews;
 116 
 117     ZipFileSystem(ZipFileSystemProvider provider,
 118                   Path zfpath,
 119                   Map<String, ?> env) throws IOException
 120     {
 121         // default encoding for name/comment
 122         String nameEncoding = env.containsKey("encoding") ?
 123             (String)env.get("encoding") : "UTF-8";
 124         this.noExtt = "false".equals(env.get("zipinfo-time"));
 125         this.useTempFile  = isTrue(env, "useTempFile");
 126         this.forceEnd64 = isTrue(env, "forceZIP64End");
 127         this.defaultCompressionMethod = isTrue(env, "noCompression") ? METHOD_STORED : METHOD_DEFLATED;
 128         this.supportPosix = isTrue(env, OPT_POSIX);
 129         this.defaultOwner = initOwner(zfpath, env);
 130         this.defaultGroup = initGroup(zfpath, env);
 131         this.defaultPermissions = initPermissions(env);
 132         this.supportedFileAttributeViews = supportPosix ?
 133             Set.of("basic", "posix", "zip") : Set.of("basic", "zip");
 134         if (Files.notExists(zfpath)) {
 135             // create a new zip if it doesn't exist
 136             if (isTrue(env, "create")) {
 137                 try (OutputStream os = Files.newOutputStream(zfpath, CREATE_NEW, WRITE)) {
 138                     new END().write(os, 0, forceEnd64);
 139                 }
 140             } else {
 141                 throw new FileSystemNotFoundException(zfpath.toString());
 142             }
 143         }
 144         // sm and existence check
 145         zfpath.getFileSystem().provider().checkAccess(zfpath, AccessMode.READ);
 146         boolean writeable = AccessController.doPrivileged(
 147             (PrivilegedAction<Boolean>)()->Files.isWritable(zfpath));
 148         this.readOnly = !writeable;
 149         this.zc = ZipCoder.get(nameEncoding);
 150         this.rootdir = new ZipPath(this, new byte[]{'/'});
 151         this.ch = Files.newByteChannel(zfpath, READ);
 152         try {
 153             this.cen = initCEN();
 154         } catch (IOException x) {
 155             try {
 156                 this.ch.close();
 157             } catch (IOException xx) {
 158                 x.addSuppressed(xx);
 159             }
 160             throw x;
 161         }
 162         this.provider = provider;
 163         this.zfpath = zfpath;
 164     }
 165 











































 166     // returns true if there is a name=true/"true" setting in env
 167     private static boolean isTrue(Map<String, ?> env, String name) {
 168         return "true".equals(env.get(name)) || TRUE.equals(env.get(name));
 169     }
 170 
 171     // Initialize the default owner for files inside the zip archive.
 172     // If not specified in env, it is the owner of the archive. If no owner can
 173     // be determined, we try to go with system property "user.name". If that's not
 174     // accessible, we return "<zipfs_default>".
 175     private UserPrincipal initOwner(Path zfpath, Map<String, ?> env) throws IOException {
 176         Object o = env.get(OPT_DEFAULT_OWNER);
 177         if (o == null) {
 178             try {
 179                 PrivilegedExceptionAction<UserPrincipal> pa = ()->Files.getOwner(zfpath);
 180                 return AccessController.doPrivileged(pa);
 181             } catch (UnsupportedOperationException | PrivilegedActionException e) {
 182                 if (e instanceof UnsupportedOperationException ||
 183                     e.getCause() instanceof NoSuchFileException)
 184                 {
 185                     PrivilegedAction<String> pa = ()->System.getProperty("user.name");




  71 import static jdk.nio.zipfs.ZipUtils.*;
  72 
  73 /**
  74  * A FileSystem built on a zip file
  75  *
  76  * @author Xueming Shen
  77  */
  78 class ZipFileSystem extends FileSystem {
  79     // statics
  80     private static final boolean isWindows = AccessController.doPrivileged(
  81         (PrivilegedAction<Boolean>)()->System.getProperty("os.name")
  82                                              .startsWith("Windows"));
  83     private static final byte[] ROOTPATH = new byte[] { '/' };
  84     private static final String OPT_POSIX = "enablePosixFileAttributes";
  85     private static final String OPT_DEFAULT_OWNER = "defaultOwner";
  86     private static final String OPT_DEFAULT_GROUP = "defaultGroup";
  87     private static final String OPT_DEFAULT_PERMISSIONS = "defaultPermissions";
  88 
  89     private static final Set<PosixFilePermission> DEFAULT_PERMISSIONS =
  90         PosixFilePermissions.fromString("rwxrwxrwx");
  91     // Property used to specify the compression mode to use
  92     private static final String COMPRESSION_METHOD = "compressionMethod";
  93     // Value specified for compressionMethod property to compress Zip entries
  94     public static final String DEFLATED_COMPRESSION_METHOD = "DEFLATED";
  95     // Value specified for compressionMethod property to not compress Zip entries
  96     public static final String STORED_COMPRESSION_METHOD = "STORED";
  97 
  98     private final ZipFileSystemProvider provider;
  99     private final Path zfpath;
 100     final ZipCoder zc;
 101     private final ZipPath rootdir;
 102     private boolean readOnly; // readonly file system, false by default
 103 
 104     // default time stamp for pseudo entries
 105     private final long zfsDefaultTimeStamp = System.currentTimeMillis();
 106 
 107     // configurable by env map
 108     private final boolean noExtt;        // see readExtra()
 109     private final boolean useTempFile;   // use a temp file for newOS, default
 110                                          // is to use BAOS for better performance
 111     private final boolean forceEnd64;
 112     private final int defaultCompressionMethod; // METHOD_STORED if "noCompression=true"
 113                                                 // METHOD_DEFLATED otherwise
 114 
 115     // POSIX support
 116     final boolean supportPosix;
 117     private final UserPrincipal defaultOwner;
 118     private final GroupPrincipal defaultGroup;
 119     private final Set<PosixFilePermission> defaultPermissions;
 120 
 121     private final Set<String> supportedFileAttributeViews;
 122 
 123     ZipFileSystem(ZipFileSystemProvider provider,
 124                   Path zfpath,
 125                   Map<String, ?> env) throws IOException
 126     {
 127         // default encoding for name/comment
 128         String nameEncoding = env.containsKey("encoding") ?
 129             (String)env.get("encoding") : "UTF-8";
 130         this.noExtt = "false".equals(env.get("zipinfo-time"));
 131         this.useTempFile  = isTrue(env, "useTempFile");
 132         this.forceEnd64 = isTrue(env, "forceZIP64End");
 133         this.defaultCompressionMethod = getDefaultCompressionMethod(env);
 134         this.supportPosix = isTrue(env, OPT_POSIX);
 135         this.defaultOwner = initOwner(zfpath, env);
 136         this.defaultGroup = initGroup(zfpath, env);
 137         this.defaultPermissions = initPermissions(env);
 138         this.supportedFileAttributeViews = supportPosix ?
 139             Set.of("basic", "posix", "zip") : Set.of("basic", "zip");
 140         if (Files.notExists(zfpath)) {
 141             // create a new zip if it doesn't exist
 142             if (isTrue(env, "create")) {
 143                 try (OutputStream os = Files.newOutputStream(zfpath, CREATE_NEW, WRITE)) {
 144                     new END().write(os, 0, forceEnd64);
 145                 }
 146             } else {
 147                 throw new FileSystemNotFoundException(zfpath.toString());
 148             }
 149         }
 150         // sm and existence check
 151         zfpath.getFileSystem().provider().checkAccess(zfpath, AccessMode.READ);
 152         boolean writeable = AccessController.doPrivileged(
 153             (PrivilegedAction<Boolean>)()->Files.isWritable(zfpath));
 154         this.readOnly = !writeable;
 155         this.zc = ZipCoder.get(nameEncoding);
 156         this.rootdir = new ZipPath(this, new byte[]{'/'});
 157         this.ch = Files.newByteChannel(zfpath, READ);
 158         try {
 159             this.cen = initCEN();
 160         } catch (IOException x) {
 161             try {
 162                 this.ch.close();
 163             } catch (IOException xx) {
 164                 x.addSuppressed(xx);
 165             }
 166             throw x;
 167         }
 168         this.provider = provider;
 169         this.zfpath = zfpath;
 170     }
 171 
 172     /**
 173      * Return the compression method to use(STORED or DEFLATED).  If the
 174      * property {@code commpressionMethod} is set use its value to determine
 175      * the compression method to use.  If the property is not set, then the
 176      * default compression is DEFLATED unless the property {@code noCompression}
 177      * is set which is supported for backwards compatability.
 178      * @param env Zip FS map of properties
 179      * @return The Compression method to use
 180      */
 181     private int getDefaultCompressionMethod(Map<String, ?> env) {
 182         int result =
 183                 isTrue(env, "noCompression") ? METHOD_STORED : METHOD_DEFLATED;
 184         if(env.containsKey(COMPRESSION_METHOD)) {
 185             Object compressionMethod =  env.get(COMPRESSION_METHOD);
 186             if(compressionMethod != null) {
 187                 if(compressionMethod instanceof String) {
 188                     switch(((String) compressionMethod).toUpperCase()) {
 189                         case STORED_COMPRESSION_METHOD:
 190                             result = METHOD_STORED;
 191                             break;
 192                         case DEFLATED_COMPRESSION_METHOD:
 193                             result = METHOD_DEFLATED;
 194                             break;
 195                         default:
 196                             throw new IllegalArgumentException(String.format(
 197                                     "The value for the %s property must be %s or %s",
 198                                     COMPRESSION_METHOD, STORED_COMPRESSION_METHOD,
 199                                     DEFLATED_COMPRESSION_METHOD));
 200                     }
 201                 } else {
 202                     throw new IllegalArgumentException(String.format(
 203                             "The Object type for the %s property must be a String"));
 204                 }
 205             } else {
 206                 throw new IllegalArgumentException(String.format(
 207                         "The value for the %s property must be %s or %s",
 208                         COMPRESSION_METHOD, STORED_COMPRESSION_METHOD,
 209                         DEFLATED_COMPRESSION_METHOD));
 210             }
 211         }
 212         return result;
 213     }
 214 
 215     // returns true if there is a name=true/"true" setting in env
 216     private static boolean isTrue(Map<String, ?> env, String name) {
 217         return "true".equals(env.get(name)) || TRUE.equals(env.get(name));
 218     }
 219 
 220     // Initialize the default owner for files inside the zip archive.
 221     // If not specified in env, it is the owner of the archive. If no owner can
 222     // be determined, we try to go with system property "user.name". If that's not
 223     // accessible, we return "<zipfs_default>".
 224     private UserPrincipal initOwner(Path zfpath, Map<String, ?> env) throws IOException {
 225         Object o = env.get(OPT_DEFAULT_OWNER);
 226         if (o == null) {
 227             try {
 228                 PrivilegedExceptionAction<UserPrincipal> pa = ()->Files.getOwner(zfpath);
 229                 return AccessController.doPrivileged(pa);
 230             } catch (UnsupportedOperationException | PrivilegedActionException e) {
 231                 if (e instanceof UnsupportedOperationException ||
 232                     e.getCause() instanceof NoSuchFileException)
 233                 {
 234                     PrivilegedAction<String> pa = ()->System.getProperty("user.name");


< prev index next >