src/share/classes/com/sun/tools/javac/nio/PathFileObject.java

Thu, 31 Aug 2017 15:17:03 +0800

author
aoqi
date
Thu, 31 Aug 2017 15:17:03 +0800
changeset 2525
2eb010b6cb22
parent 1357
c75be5bc5283
parent 0
959103a6100f
permissions
-rw-r--r--

merge

     1 /*
     2  * Copyright (c) 2009, 2012, 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  */
    26 package com.sun.tools.javac.nio;
    28 import java.io.IOException;
    29 import java.io.InputStream;
    30 import java.io.InputStreamReader;
    31 import java.io.OutputStream;
    32 import java.io.OutputStreamWriter;
    33 import java.io.Reader;
    34 import java.io.Writer;
    35 import java.net.URI;
    36 import java.nio.ByteBuffer;
    37 import java.nio.CharBuffer;
    38 import java.nio.charset.CharsetDecoder;
    39 import java.nio.file.Files;
    40 import java.nio.file.LinkOption;
    41 import java.nio.file.Path;
    42 import javax.lang.model.element.Modifier;
    43 import javax.lang.model.element.NestingKind;
    44 import javax.tools.JavaFileObject;
    46 import com.sun.tools.javac.util.BaseFileManager;
    49 /**
    50  *  Implementation of JavaFileObject using java.nio.file API.
    51  *
    52  *  <p>PathFileObjects are, for the most part, straightforward wrappers around
    53  *  Path objects. The primary complexity is the support for "inferBinaryName".
    54  *  This is left as an abstract method, implemented by each of a number of
    55  *  different factory methods, which compute the binary name based on
    56  *  information available at the time the file object is created.
    57  *
    58  *  <p><b>This is NOT part of any supported API.
    59  *  If you write code that depends on this, you do so at your own risk.
    60  *  This code and its internal interfaces are subject to change or
    61  *  deletion without notice.</b>
    62  */
    63 abstract class PathFileObject implements JavaFileObject {
    64     private JavacPathFileManager fileManager;
    65     private Path path;
    67     /**
    68      * Create a PathFileObject within a directory, such that the binary name
    69      * can be inferred from the relationship to the parent directory.
    70      */
    71     static PathFileObject createDirectoryPathFileObject(JavacPathFileManager fileManager,
    72             final Path path, final Path dir) {
    73         return new PathFileObject(fileManager, path) {
    74             @Override
    75             String inferBinaryName(Iterable<? extends Path> paths) {
    76                 return toBinaryName(dir.relativize(path));
    77             }
    78         };
    79     }
    81     /**
    82      * Create a PathFileObject in a file system such as a jar file, such that
    83      * the binary name can be inferred from its position within the filesystem.
    84      */
    85     static PathFileObject createJarPathFileObject(JavacPathFileManager fileManager,
    86             final Path path) {
    87         return new PathFileObject(fileManager, path) {
    88             @Override
    89             String inferBinaryName(Iterable<? extends Path> paths) {
    90                 return toBinaryName(path);
    91             }
    92         };
    93     }
    95     /**
    96      * Create a PathFileObject whose binary name can be inferred from the
    97      * relative path to a sibling.
    98      */
    99     static PathFileObject createSiblingPathFileObject(JavacPathFileManager fileManager,
   100             final Path path, final String relativePath) {
   101         return new PathFileObject(fileManager, path) {
   102             @Override
   103             String inferBinaryName(Iterable<? extends Path> paths) {
   104                 return toBinaryName(relativePath, "/");
   105             }
   106         };
   107     }
   109     /**
   110      * Create a PathFileObject whose binary name might be inferred from its
   111      * position on a search path.
   112      */
   113     static PathFileObject createSimplePathFileObject(JavacPathFileManager fileManager,
   114             final Path path) {
   115         return new PathFileObject(fileManager, path) {
   116             @Override
   117             String inferBinaryName(Iterable<? extends Path> paths) {
   118                 Path absPath = path.toAbsolutePath();
   119                 for (Path p: paths) {
   120                     Path ap = p.toAbsolutePath();
   121                     if (absPath.startsWith(ap)) {
   122                         try {
   123                             Path rp = ap.relativize(absPath);
   124                             if (rp != null) // maybe null if absPath same as ap
   125                                 return toBinaryName(rp);
   126                         } catch (IllegalArgumentException e) {
   127                             // ignore this p if cannot relativize path to p
   128                         }
   129                     }
   130                 }
   131                 return null;
   132             }
   133         };
   134     }
   136     protected PathFileObject(JavacPathFileManager fileManager, Path path) {
   137         fileManager.getClass(); // null check
   138         path.getClass();        // null check
   139         this.fileManager = fileManager;
   140         this.path = path;
   141     }
   143     abstract String inferBinaryName(Iterable<? extends Path> paths);
   145     /**
   146      * Return the Path for this object.
   147      * @return the Path for this object.
   148      */
   149     Path getPath() {
   150         return path;
   151     }
   153     @Override
   154     public Kind getKind() {
   155         return BaseFileManager.getKind(path.getFileName().toString());
   156     }
   158     @Override
   159     public boolean isNameCompatible(String simpleName, Kind kind) {
   160         simpleName.getClass();
   161         // null check
   162         if (kind == Kind.OTHER && getKind() != kind) {
   163             return false;
   164         }
   165         String sn = simpleName + kind.extension;
   166         String pn = path.getFileName().toString();
   167         if (pn.equals(sn)) {
   168             return true;
   169         }
   170         if (pn.equalsIgnoreCase(sn)) {
   171             try {
   172                 // allow for Windows
   173                 return path.toRealPath(LinkOption.NOFOLLOW_LINKS).getFileName().toString().equals(sn);
   174             } catch (IOException e) {
   175             }
   176         }
   177         return false;
   178     }
   180     @Override
   181     public NestingKind getNestingKind() {
   182         return null;
   183     }
   185     @Override
   186     public Modifier getAccessLevel() {
   187         return null;
   188     }
   190     @Override
   191     public URI toUri() {
   192         return path.toUri();
   193     }
   195     @Override
   196     public String getName() {
   197         return path.toString();
   198     }
   200     @Override
   201     public InputStream openInputStream() throws IOException {
   202         return Files.newInputStream(path);
   203     }
   205     @Override
   206     public OutputStream openOutputStream() throws IOException {
   207         fileManager.flushCache(this);
   208         ensureParentDirectoriesExist();
   209         return Files.newOutputStream(path);
   210     }
   212     @Override
   213     public Reader openReader(boolean ignoreEncodingErrors) throws IOException {
   214         CharsetDecoder decoder = fileManager.getDecoder(fileManager.getEncodingName(), ignoreEncodingErrors);
   215         return new InputStreamReader(openInputStream(), decoder);
   216     }
   218     @Override
   219     public CharSequence getCharContent(boolean ignoreEncodingErrors) throws IOException {
   220         CharBuffer cb = fileManager.getCachedContent(this);
   221         if (cb == null) {
   222             InputStream in = openInputStream();
   223             try {
   224                 ByteBuffer bb = fileManager.makeByteBuffer(in);
   225                 JavaFileObject prev = fileManager.log.useSource(this);
   226                 try {
   227                     cb = fileManager.decode(bb, ignoreEncodingErrors);
   228                 } finally {
   229                     fileManager.log.useSource(prev);
   230                 }
   231                 fileManager.recycleByteBuffer(bb);
   232                 if (!ignoreEncodingErrors) {
   233                     fileManager.cache(this, cb);
   234                 }
   235             } finally {
   236                 in.close();
   237             }
   238         }
   239         return cb;
   240     }
   242     @Override
   243     public Writer openWriter() throws IOException {
   244         fileManager.flushCache(this);
   245         ensureParentDirectoriesExist();
   246         return new OutputStreamWriter(Files.newOutputStream(path), fileManager.getEncodingName());
   247     }
   249     @Override
   250     public long getLastModified() {
   251         try {
   252             return Files.getLastModifiedTime(path).toMillis();
   253         } catch (IOException e) {
   254             return -1;
   255         }
   256     }
   258     @Override
   259     public boolean delete() {
   260         try {
   261             Files.delete(path);
   262             return true;
   263         } catch (IOException e) {
   264             return false;
   265         }
   266     }
   268     public boolean isSameFile(PathFileObject other) {
   269         try {
   270             return Files.isSameFile(path, other.path);
   271         } catch (IOException e) {
   272             return false;
   273         }
   274     }
   276     @Override
   277     public boolean equals(Object other) {
   278         return (other instanceof PathFileObject && path.equals(((PathFileObject) other).path));
   279     }
   281     @Override
   282     public int hashCode() {
   283         return path.hashCode();
   284     }
   286     @Override
   287     public String toString() {
   288         return getClass().getSimpleName() + "[" + path + "]";
   289     }
   291     private void ensureParentDirectoriesExist() throws IOException {
   292         Path parent = path.getParent();
   293         if (parent != null)
   294             Files.createDirectories(parent);
   295     }
   297     private long size() {
   298         try {
   299             return Files.size(path);
   300         } catch (IOException e) {
   301             return -1;
   302         }
   303     }
   305     protected static String toBinaryName(Path relativePath) {
   306         return toBinaryName(relativePath.toString(),
   307                 relativePath.getFileSystem().getSeparator());
   308     }
   310     protected static String toBinaryName(String relativePath, String sep) {
   311         return removeExtension(relativePath).replace(sep, ".");
   312     }
   314     protected static String removeExtension(String fileName) {
   315         int lastDot = fileName.lastIndexOf(".");
   316         return (lastDot == -1 ? fileName : fileName.substring(0, lastDot));
   317     }
   318 }

mercurial