Home » openjdk-7 » com.sun.tools.javac.nio » [javadoc | source]

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

Home » openjdk-7 » com.sun.tools.javac.nio » [javadoc | source]