1 /* 2 * Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 import java.nio.file.Files; 27 import java.nio.file.LinkOption; 28 import java.nio.file.Path; 29 import java.nio.file.attribute.FileAttributeView; 30 import java.nio.file.attribute.PosixFileAttributes; 31 import java.nio.file.attribute.PosixFilePermission; 32 import java.nio.file.attribute.PosixFileAttributeView; 33 import java.util.Set; 34 35 /** 36 * Provides the implementation of the Zip file system provider. 37 * The Zip file system provider treats the contents of a Zip or JAR file as a file system. 38 * 39 * <h2>Accessing a Zip File System</h2> 40 * 41 * The {@linkplain java.nio.file.FileSystems FileSystems} {@code newFileSystem} 42 * static factory methods can be used to: 43 * <ul> 44 * <li>Create a Zip file system</li> 45 * <li>Open an existing file as a Zip file system</li> 46 * </ul> 47 * 48 * <h2>URI Scheme Used to Identify the Zip File System</h2> 49 * 50 * The URI {@link java.net.URI#getScheme scheme} that identifies the ZIP file system is {@code jar}. 51 * 52 * <h2>POSIX file attributes</h2> 53 * 54 * A Zip file system supports a file attribute {@link FileAttributeView view} 55 * named "{@code zip}" that defines the following file attribute: 56 * 57 * <blockquote> 58 * <table class="striped"> 59 * <caption style="display:none">Supported attributes</caption> 60 * <thead> 61 * <tr> 62 * <th scope="col">Name</th> 63 * <th scope="col">Type</th> 64 * </tr> 65 * </thead> 66 * <tbody> 67 * <tr> 68 * <th scope="row">permissions</th> 69 * <td>{@link Set}<{@link PosixFilePermission}></td> 70 * </tr> 71 * </tbody> 72 * </table> 73 * </blockquote> 74 * 75 * The "permissions" attribute is the set of access permissions that are optionally 76 * stored for entries in a Zip file. The value of the attribute is {@code null} 77 * for entries that do not have access permissions. Zip file systems do not 78 * enforce access permissions. 79 * 80 * <p> The "permissions" attribute may be read and set using the 81 * {@linkplain Files#getAttribute(Path, String, LinkOption...) Files.getAttribute} and 82 * {@linkplain Files#setAttribute(Path, String, Object, LinkOption...) Files.setAttribute} 83 * methods. The following example uses these methods to read and set the attribute: 84 * <pre> {@code 85 * Set<PosixFilePermission> perms = Files.getAttribute(entry, "zip:permissions"); 86 * if (perms == null) { 87 * perms = PosixFilePermissions.fromString("rw-rw-rw-"); 88 * Files.setAttribute(entry, "zip:permissions", perms); 89 * } 90 * } </pre> 91 * 92 * <p> In addition to the "{@code zip}" view, a Zip file system optionally supports 93 * the {@link PosixFileAttributeView} ("{@code posix}"). 94 * This view extends the "{@code basic}" view with type safe access to the 95 * {@link PosixFileAttributes#owner() owner}, {@link PosixFileAttributes#group() group-owner}, 96 * and {@link PosixFileAttributes#permissions() permissions} attributes. The 97 * "{@code posix}" view is only supported when the Zip file system is created with 98 * the provider property "{@code enablePosixFileAttributes}" set to "{@code true}". 99 * The following creates a file system with this property and reads the access 100 * permissions of a file: 101 * <pre> {@code 102 * var env = Map.of("enablePosixFileAttributes", "true"); 103 * try (FileSystem fs = FileSystems.newFileSystem(file, env) { 104 * Path entry = fs.getPath("entry"); 105 * Set<PosixFilePermission> perms = Files.getPosixFilePermissions(entry); 106 * } 107 * } </pre> 108 * 109 * <p> The file owner and group owner attributes are not persisted, meaning they are 110 * not stored in the zip file. The "{@code defaultOwner}" and "{@code defaultGroup}" 111 * provider properties (listed below) can be used to configure the default values 112 * for these attributes. If these properties are not set then the file owner 113 * defaults to the owner of the zip file, and the group owner defaults to the 114 * zip file's group owner (or the file owner on platforms that don't support a 115 * group owner). 116 * 117 * <p> The "{@code permissions}" attribute is not optional in the "{@code posix}" 118 * view so a default set of permissions are used for entries that do not have 119 * access permissions stored in the Zip file. The default set of permissions 120 * are 121 * <ul> 122 * <li>{@link PosixFilePermission#OWNER_READ OWNER_READ}</li> 123 * <li>{@link PosixFilePermission#OWNER_WRITE OWNER_WRITE}</li> 124 * <li>{@link PosixFilePermission#GROUP_READ GROUP_READ}</li> 125 * </ul> 126 * The default permissions can be configured with the "{@code defaultPermissions}" 127 * property described below. 128 * 129 * <h2>Zip File System Properties</h2> 130 * 131 * The following properties may be specified when creating a Zip 132 * file system: 133 * <table class="striped"> 134 * <caption style="display:none"> 135 * Configurable properties that may be specified when creating 136 * a new Zip file system 137 * </caption> 138 * <thead> 139 * <tr> 140 * <th scope="col">Property Name</th> 141 * <th scope="col">Data Type</th> 142 * <th scope="col">Default Value</th> 143 * <th scope="col">Description</th> 144 * </tr> 145 * </thead> 146 * 147 * <tbody> 148 * <tr> 149 * <th scope="row">create</th> 150 * <td>{@link java.lang.String} or {@link java.lang.Boolean}</td> 151 * <td>false</td> 152 * <td> 153 * If the value is {@code true}, the Zip file system provider 154 * creates a new Zip or JAR file if it does not exist. 155 * </td> 156 * </tr> 157 * <tr> 158 * <th scope="row">encoding</th> 159 * <td>{@link java.lang.String}</td> 160 * <td>UTF-8</td> 161 * <td> 162 * The value indicates the encoding scheme for the 163 * names of the entries in the Zip or JAR file. 164 * </td> 165 * </tr> 166 * <tr> 167 * <th scope="row">enablePosixFileAttributes</th> 168 * <td>{@link java.lang.String} or {@link java.lang.Boolean}</td> 169 * <td>false</td> 170 * <td> 171 * If the value is {@code true}, the Zip file system will support 172 * the {@link java.nio.file.attribute.PosixFileAttributeView PosixFileAttributeView}. 173 * </td> 174 * </tr> 175 * <tr> 176 * <th scope="row">defaultOwner</th> 177 * <td>{@link java.nio.file.attribute.UserPrincipal UserPrincipal}<br> or 178 * {@link java.lang.String}</td> 179 * <td>null/unset</td> 180 * <td> 181 * Override the default owner for entries in the Zip file system.<br> 182 * The value can be a UserPrincipal or a String value that is used as the UserPrincipal's name. 183 * </td> 184 * </tr> 185 * <tr> 186 * <th scope="row">defaultGroup</th> 187 * <td>{@link java.nio.file.attribute.GroupPrincipal GroupPrincipal}<br> or 188 * {@link java.lang.String}</td> 189 * <td>null/unset</td> 190 * <td> 191 * Override the the default group for entries in the Zip file system.<br> 192 * The value can be a GroupPrincipal or a String value that is used as the GroupPrincipal's name. 193 * </td> 194 * </tr> 195 * <tr> 196 * <th scope="row">defaultPermissions</th> 197 * <td>{@link java.util.Set Set}<{@link java.nio.file.attribute.PosixFilePermission PosixFilePermission}><br> 198 * or {@link java.lang.String}</td> 199 * <td>null/unset</td> 200 * <td> 201 * Override the default Set of permissions for entries in the Zip file system.<br> 202 * The value can be a {@link java.util.Set Set}<{@link java.nio.file.attribute.PosixFilePermission PosixFilePermission}> or<br> 203 * a String that is parsed by {@link java.nio.file.attribute.PosixFilePermissions#fromString PosixFilePermissions::fromString} 204 * </td> 205 * </tr> 206 * <tr> 207 * <th scope="row">noCompression</th> 208 * <td>{@link java.lang.String} or {@link java.lang.Boolean}n</td> 209 * <td>false</td> 210 * <td> 211 * If the value is {@code true}, the Zip file system provider will 212 * not compress entries when writing to the Zip file system. 213 * If the value is {@code false}, the Zip file system provider will 214 * use data compression when writing entries to the Zip file system. 215 * </td> 216 * </tr> 217 * <tr> 218 * <th scope="row">releaseVersion</th> 219 * <td>{@link java.lang.String} or {@link java.lang.Integer} or 220 * {@link java.lang.Runtime.Version}</td> 221 * <td>null/unset</td> 222 * <td> 223 * A value representing the version entry to use when accessing a 224 * multi-release JAR. If the JAR is not a multi-release JAR, the value 225 * will be ignored and the JAR will considered un-versioned. 226 * <p> 227 * 228 * <ul> 229 * <li> 230 * If the value is {@code "runtime"} or is a 231 * {@linkplain java.lang.Runtime.Version Version} Object, the 232 * version entry will be determined by invoking 233 * {@linkplain Runtime.Version#feature() Version.feature()}. 234 * </li> 235 * <li> 236 * If the Object is a {@linkplain java.lang.String} or an 237 * {@linkplain java.lang.Integer}, its value must represent a valid 238 * {@linkplain Runtime.Version Java SE Platform version number}, 239 * such as {@code 9}, {@code 11.0.1}, or {@code 14} in order to 240 * determine the version entry. 241 * </li> 242 * <li> 243 * If the value does not represent a valid 244 * {@linkplain Runtime.Version Java SE Platform version number}, 245 * an {@code IllegalArgumentException} will be thrown. 246 * </li> 247 * </ul> 248 * </td> 249 * </tr> 250 * </tbody> 251 * </table> 252 * 253 * <h2>Examples:</h2> 254 * 255 * Construct a new Zip file system that is identified by a URI. If the Zip file does not exist, 256 * it will be created: 257 * <pre> 258 * {@code 259 * 260 * URI uri = URI.create("jar:file:/home/luckydog/tennisTeam.zip"); 261 * Map<String, String> env = Map.of("create", "true"); 262 * FileSystem zipfs = FileSystems.newFileSystem(uri, env); 263 * } 264 * </pre> 265 * 266 * Construct a new Zip file system that is identified by specifying a path 267 * and using automatic file type detection. Iterate from the root of the JAR displaying each 268 * found entry: 269 * <pre> 270 * {@code 271 * 272 * FileSystem zipfs = FileSystems.newFileSystem(Path.of("helloworld.jar")); 273 * Path rootDir = zipfs.getPath("/"); 274 * Files.walk(rootDir) 275 * .forEach(System.out::println); 276 * } 277 * </pre> 278 * @provides java.nio.file.spi.FileSystemProvider 279 * @moduleGraph 280 * @since 9 281 */ 282 module jdk.zipfs { 283 provides java.nio.file.spi.FileSystemProvider with 284 jdk.nio.zipfs.ZipFileSystemProvider; 285 }