jdk/src/java.base/share/classes/jdk/internal/jrtfs/JrtFileSystemProvider.java
changeset 27565 729f9700483a
child 31673 135283550686
equal deleted inserted replaced
27564:eaaa79b68cd5 27565:729f9700483a
       
     1 /*
       
     2  * Copyright (c) 2014, 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 package jdk.internal.jrtfs;
       
    27 
       
    28 import java.io.*;
       
    29 import java.nio.channels.*;
       
    30 import java.nio.file.*;
       
    31 import java.nio.file.DirectoryStream.Filter;
       
    32 import java.nio.file.attribute.*;
       
    33 import java.nio.file.spi.FileSystemProvider;
       
    34 import java.net.URI;
       
    35 import java.net.URISyntaxException;
       
    36 import java.util.HashMap;
       
    37 import java.util.Map;
       
    38 import java.util.Set;
       
    39 import java.util.concurrent.ExecutorService;
       
    40 
       
    41 public final class JrtFileSystemProvider extends FileSystemProvider {
       
    42     private volatile FileSystem theFileSystem;
       
    43 
       
    44     public JrtFileSystemProvider() { }
       
    45 
       
    46     @Override
       
    47     public String getScheme() {
       
    48         return "jrt";
       
    49     }
       
    50 
       
    51     /**
       
    52      * Need FilePermission ${java.home}/-", "read" to create or get jrt:/
       
    53      */
       
    54     private void checkPermission() {
       
    55         SecurityManager sm = System.getSecurityManager();
       
    56         if (sm != null) {
       
    57             String home = SystemImages.RUNTIME_HOME;
       
    58             FilePermission perm =
       
    59                 new FilePermission(home + File.separator + "-", "read");
       
    60             sm.checkPermission(perm);
       
    61         }
       
    62     }
       
    63 
       
    64     private void checkUri(URI uri) {
       
    65         if (!uri.getScheme().equalsIgnoreCase(getScheme()))
       
    66             throw new IllegalArgumentException("URI does not match this provider");
       
    67         if (uri.getAuthority() != null)
       
    68             throw new IllegalArgumentException("Authority component present");
       
    69         if (uri.getPath() == null)
       
    70             throw new IllegalArgumentException("Path component is undefined");
       
    71         if (!uri.getPath().equals("/"))
       
    72             throw new IllegalArgumentException("Path component should be '/'");
       
    73         if (uri.getQuery() != null)
       
    74             throw new IllegalArgumentException("Query component present");
       
    75         if (uri.getFragment() != null)
       
    76             throw new IllegalArgumentException("Fragment component present");
       
    77     }
       
    78 
       
    79     @Override
       
    80     public FileSystem newFileSystem(URI uri, Map<String, ?> env)
       
    81         throws IOException
       
    82     {
       
    83         checkPermission();
       
    84         checkUri(uri);
       
    85         return new JrtFileSystem(this, env);
       
    86     }
       
    87 
       
    88     @Override
       
    89     public Path getPath(URI uri) {
       
    90         checkPermission();
       
    91         if (!uri.getScheme().equalsIgnoreCase(getScheme()))
       
    92             throw new IllegalArgumentException("URI does not match this provider");
       
    93         if (uri.getAuthority() != null)
       
    94             throw new IllegalArgumentException("Authority component present");
       
    95         if (uri.getQuery() != null)
       
    96             throw new IllegalArgumentException("Query component present");
       
    97         if (uri.getFragment() != null)
       
    98             throw new IllegalArgumentException("Fragment component present");
       
    99         String path = uri.getPath();
       
   100         if (path == null || path.charAt(0) != '/')
       
   101             throw new IllegalArgumentException("Invalid path component");
       
   102         return getTheFileSystem().getPath(path);
       
   103     }
       
   104 
       
   105     private FileSystem getTheFileSystem() {
       
   106         checkPermission();
       
   107         FileSystem fs = this.theFileSystem;
       
   108         if (fs == null) {
       
   109             synchronized (this) {
       
   110                 fs = this.theFileSystem;
       
   111                 if (fs == null) {
       
   112                     try {
       
   113                         this.theFileSystem = fs = new JrtFileSystem(this, null) {
       
   114                             @Override public void close() {
       
   115                                 throw new UnsupportedOperationException();
       
   116                             }
       
   117                         };
       
   118                     } catch (IOException ioe) {
       
   119                         throw new InternalError(ioe);
       
   120                     }
       
   121                 }
       
   122             }
       
   123         }
       
   124         return fs;
       
   125     }
       
   126 
       
   127     @Override
       
   128     public FileSystem getFileSystem(URI uri) {
       
   129         checkPermission();
       
   130         checkUri(uri);
       
   131         return getTheFileSystem();
       
   132     }
       
   133 
       
   134     // Checks that the given file is a JrtPath
       
   135     static final JrtPath toJrtPath(Path path) {
       
   136         if (path == null)
       
   137             throw new NullPointerException();
       
   138         if (!(path instanceof JrtPath))
       
   139             throw new ProviderMismatchException();
       
   140         return (JrtPath)path;
       
   141     }
       
   142 
       
   143     @Override
       
   144     public void checkAccess(Path path, AccessMode... modes) throws IOException {
       
   145         toJrtPath(path).checkAccess(modes);
       
   146     }
       
   147 
       
   148     @Override
       
   149     public void copy(Path src, Path target, CopyOption... options)
       
   150         throws IOException
       
   151     {
       
   152         toJrtPath(src).copy(toJrtPath(target), options);
       
   153     }
       
   154 
       
   155     @Override
       
   156     public void createDirectory(Path path, FileAttribute<?>... attrs)
       
   157         throws IOException
       
   158     {
       
   159         toJrtPath(path).createDirectory(attrs);
       
   160     }
       
   161 
       
   162     @Override
       
   163     public final void delete(Path path) throws IOException {
       
   164         toJrtPath(path).delete();
       
   165     }
       
   166 
       
   167     @Override
       
   168     @SuppressWarnings("unchecked")
       
   169     public <V extends FileAttributeView> V
       
   170         getFileAttributeView(Path path, Class<V> type, LinkOption... options)
       
   171     {
       
   172         return JrtFileAttributeView.get(toJrtPath(path), type);
       
   173     }
       
   174 
       
   175     @Override
       
   176     public FileStore getFileStore(Path path) throws IOException {
       
   177         return toJrtPath(path).getFileStore();
       
   178     }
       
   179 
       
   180     @Override
       
   181     public boolean isHidden(Path path) {
       
   182         return toJrtPath(path).isHidden();
       
   183     }
       
   184 
       
   185     @Override
       
   186     public boolean isSameFile(Path path, Path other) throws IOException {
       
   187         return toJrtPath(path).isSameFile(other);
       
   188     }
       
   189 
       
   190     @Override
       
   191     public void move(Path src, Path target, CopyOption... options)
       
   192         throws IOException
       
   193     {
       
   194         toJrtPath(src).move(toJrtPath(target), options);
       
   195     }
       
   196 
       
   197     @Override
       
   198     public AsynchronousFileChannel newAsynchronousFileChannel(Path path,
       
   199             Set<? extends OpenOption> options,
       
   200             ExecutorService exec,
       
   201             FileAttribute<?>... attrs)
       
   202             throws IOException
       
   203     {
       
   204         throw new UnsupportedOperationException();
       
   205     }
       
   206 
       
   207     @Override
       
   208     public SeekableByteChannel newByteChannel(Path path,
       
   209                                               Set<? extends OpenOption> options,
       
   210                                               FileAttribute<?>... attrs)
       
   211         throws IOException
       
   212     {
       
   213         return toJrtPath(path).newByteChannel(options, attrs);
       
   214     }
       
   215 
       
   216     @Override
       
   217     public DirectoryStream<Path> newDirectoryStream(
       
   218         Path path, Filter<? super Path> filter) throws IOException
       
   219     {
       
   220         return toJrtPath(path).newDirectoryStream(filter);
       
   221     }
       
   222 
       
   223     @Override
       
   224     public FileChannel newFileChannel(Path path,
       
   225                                       Set<? extends OpenOption> options,
       
   226                                       FileAttribute<?>... attrs)
       
   227         throws IOException
       
   228     {
       
   229         return toJrtPath(path).newFileChannel(options, attrs);
       
   230     }
       
   231 
       
   232     @Override
       
   233     public InputStream newInputStream(Path path, OpenOption... options)
       
   234         throws IOException
       
   235     {
       
   236         return toJrtPath(path).newInputStream(options);
       
   237     }
       
   238 
       
   239     @Override
       
   240     public OutputStream newOutputStream(Path path, OpenOption... options)
       
   241         throws IOException
       
   242     {
       
   243         return toJrtPath(path).newOutputStream(options);
       
   244     }
       
   245 
       
   246     @Override
       
   247     @SuppressWarnings("unchecked") // Cast to A
       
   248     public <A extends BasicFileAttributes> A
       
   249         readAttributes(Path path, Class<A> type, LinkOption... options)
       
   250         throws IOException
       
   251     {
       
   252         if (type == BasicFileAttributes.class || type == JrtFileAttributes.class)
       
   253             return (A)toJrtPath(path).getAttributes();
       
   254         return null;
       
   255     }
       
   256 
       
   257     @Override
       
   258     public Map<String, Object>
       
   259         readAttributes(Path path, String attribute, LinkOption... options)
       
   260         throws IOException
       
   261     {
       
   262         return toJrtPath(path).readAttributes(attribute, options);
       
   263     }
       
   264 
       
   265     @Override
       
   266     public void setAttribute(Path path, String attribute,
       
   267                              Object value, LinkOption... options)
       
   268         throws IOException
       
   269     {
       
   270         toJrtPath(path).setAttribute(attribute, value, options);
       
   271     }
       
   272 }