langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/StandardDocFileFactory.java
changeset 40587 1c355ea550ed
parent 36526 3b41f1c69604
child 45417 f7479ee8de69
equal deleted inserted replaced
40519:e17429a7e843 40587:1c355ea550ed
    40 import java.nio.file.Paths;
    40 import java.nio.file.Paths;
    41 import java.util.ArrayList;
    41 import java.util.ArrayList;
    42 import java.util.Arrays;
    42 import java.util.Arrays;
    43 import java.util.LinkedHashSet;
    43 import java.util.LinkedHashSet;
    44 import java.util.List;
    44 import java.util.List;
       
    45 import java.util.Objects;
    45 import java.util.Set;
    46 import java.util.Set;
    46 
    47 
    47 import javax.tools.DocumentationTool;
    48 import javax.tools.DocumentationTool;
    48 import javax.tools.FileObject;
    49 import javax.tools.FileObject;
    49 import javax.tools.JavaFileManager.Location;
    50 import javax.tools.JavaFileManager.Location;
    70     public StandardDocFileFactory(Configuration configuration) {
    71     public StandardDocFileFactory(Configuration configuration) {
    71         super(configuration);
    72         super(configuration);
    72         fileManager = (StandardJavaFileManager) configuration.getFileManager();
    73         fileManager = (StandardJavaFileManager) configuration.getFileManager();
    73     }
    74     }
    74 
    75 
       
    76     @Override
       
    77     public void setDestDir(String destDirName) throws SimpleDocletException {
       
    78         if (destDir != null)
       
    79             throw new AssertionError("destDir already initialized: " + destDir);
       
    80 
       
    81         if (!destDirName.isEmpty()
       
    82                 || !fileManager.hasLocation(DocumentationTool.Location.DOCUMENTATION_OUTPUT)) {
       
    83             try {
       
    84                 String dirName = destDirName.isEmpty() ? "." : destDirName;
       
    85                 Path dir = Paths.get(dirName);
       
    86                 fileManager.setLocationFromPaths(DocumentationTool.Location.DOCUMENTATION_OUTPUT, Arrays.asList(dir));
       
    87             } catch (IOException e) {
       
    88                 // generic IOException from file manager, setting location, e.g. file not a directory
       
    89                 String message = configuration.getResources().getText("doclet.error.initializing.dest.dir", e);
       
    90                 throw new SimpleDocletException(message, e);
       
    91             }
       
    92         }
       
    93 
       
    94         destDir = fileManager.getLocationAsPaths(DocumentationTool.Location.DOCUMENTATION_OUTPUT).iterator().next();
       
    95     }
       
    96 
    75     private Path getDestDir() {
    97     private Path getDestDir() {
    76         if (destDir == null) {
    98         Objects.requireNonNull(destDir, "destDir not initialized");
    77             if (!configuration.destDirName.isEmpty()
       
    78                     || !fileManager.hasLocation(DocumentationTool.Location.DOCUMENTATION_OUTPUT)) {
       
    79                 try {
       
    80                     String dirName = configuration.destDirName.isEmpty() ? "." : configuration.destDirName;
       
    81                     Path dir = Paths.get(dirName);
       
    82                     fileManager.setLocationFromPaths(DocumentationTool.Location.DOCUMENTATION_OUTPUT, Arrays.asList(dir));
       
    83                 } catch (IOException e) {
       
    84                     throw new DocletAbortException(e);
       
    85                 }
       
    86             }
       
    87 
       
    88             destDir = fileManager.getLocationAsPaths(DocumentationTool.Location.DOCUMENTATION_OUTPUT).iterator().next();
       
    89         }
       
    90         return destDir;
    99         return destDir;
    91     }
   100     }
    92 
   101 
       
   102     @Override
    93     public DocFile createFileForDirectory(String file) {
   103     public DocFile createFileForDirectory(String file) {
    94         return new StandardDocFile(Paths.get(file));
   104         return new StandardDocFile(Paths.get(file));
    95     }
   105     }
    96 
   106 
       
   107     @Override
    97     public DocFile createFileForInput(String file) {
   108     public DocFile createFileForInput(String file) {
    98         return new StandardDocFile(Paths.get(file));
   109         return new StandardDocFile(Paths.get(file));
    99     }
   110     }
   100 
   111 
       
   112     @Override
   101     public DocFile createFileForOutput(DocPath path) {
   113     public DocFile createFileForOutput(DocPath path) {
   102         return new StandardDocFile(DocumentationTool.Location.DOCUMENTATION_OUTPUT, path);
   114         return new StandardDocFile(DocumentationTool.Location.DOCUMENTATION_OUTPUT, path);
   103     }
   115     }
   104 
   116 
   105     @Override
   117     @Override
   123     private static Path newFile(Path dir, String path) {
   135     private static Path newFile(Path dir, String path) {
   124         return (dir == null) ? Paths.get(path) : dir.resolve(path);
   136         return (dir == null) ? Paths.get(path) : dir.resolve(path);
   125     }
   137     }
   126 
   138 
   127     class StandardDocFile extends DocFile {
   139     class StandardDocFile extends DocFile {
   128         private Path file;
   140         private final Path file;
   129 
   141 
   130         /** Create a StandardDocFile for a given file. */
   142         /** Create a StandardDocFile for a given file. */
   131         private StandardDocFile(Path file) {
   143         private StandardDocFile(Path file) {
   132             super(configuration);
       
   133             this.file = file;
   144             this.file = file;
   134         }
   145         }
   135 
   146 
   136         /** Create a StandardDocFile for a given location and relative path. */
   147         /** Create a StandardDocFile for a given location and relative path. */
   137         private StandardDocFile(Location location, DocPath path) {
   148         private StandardDocFile(Location location, DocPath path) {
   138             super(configuration, location, path);
   149             super(location, path);
   139             Assert.check(location == DocumentationTool.Location.DOCUMENTATION_OUTPUT);
   150             Assert.check(location == DocumentationTool.Location.DOCUMENTATION_OUTPUT);
   140             this.file = newFile(getDestDir(), path.getPath());
   151             this.file = newFile(getDestDir(), path.getPath());
   141         }
   152         }
   142 
   153 
   143         /** Open an input stream for the file. */
   154         /**
   144         public InputStream openInputStream() throws IOException {
   155          * Open an input stream for the file.
   145             JavaFileObject fo = getJavaFileObjectForInput(file);
   156          *
   146             return new BufferedInputStream(fo.openInputStream());
   157          * @throws DocFileIOException if there is a problem while opening stream
       
   158          */
       
   159         @Override
       
   160         public InputStream openInputStream() throws DocFileIOException {
       
   161             try {
       
   162                 JavaFileObject fo = getJavaFileObjectForInput(file);
       
   163                 return new BufferedInputStream(fo.openInputStream());
       
   164             } catch (IOException e) {
       
   165                 throw new DocFileIOException(this, DocFileIOException.Mode.READ, e);
       
   166             }
   147         }
   167         }
   148 
   168 
   149         /**
   169         /**
   150          * Open an output stream for the file.
   170          * Open an output stream for the file.
   151          * The file must have been created with a location of
   171          * The file must have been created with a location of
   152          * {@link DocumentationTool.Location#DOCUMENTATION_OUTPUT} and a corresponding relative path.
   172          * {@link DocumentationTool.Location#DOCUMENTATION_OUTPUT} and a corresponding relative path.
   153          */
   173          *
   154         public OutputStream openOutputStream() throws IOException, UnsupportedEncodingException {
   174          * @throws DocFileIOException if there is a problem while opening stream
       
   175          */
       
   176         @Override
       
   177         public OutputStream openOutputStream() throws DocFileIOException {
   155             if (location != DocumentationTool.Location.DOCUMENTATION_OUTPUT)
   178             if (location != DocumentationTool.Location.DOCUMENTATION_OUTPUT)
   156                 throw new IllegalStateException();
   179                 throw new IllegalStateException();
   157 
   180 
   158             OutputStream out = getFileObjectForOutput(path).openOutputStream();
   181             try {
   159             return new BufferedOutputStream(out);
   182                 OutputStream out = getFileObjectForOutput(path).openOutputStream();
       
   183                 return new BufferedOutputStream(out);
       
   184             } catch (IOException e) {
       
   185                 throw new DocFileIOException(this, DocFileIOException.Mode.WRITE, e);
       
   186             }
   160         }
   187         }
   161 
   188 
   162         /**
   189         /**
   163          * Open an writer for the file, using the encoding (if any) given in the
   190          * Open an writer for the file, using the encoding (if any) given in the
   164          * doclet configuration.
   191          * doclet configuration.
   165          * The file must have been created with a location of
   192          * The file must have been created with a location of
   166          * {@link DocumentationTool.Location#DOCUMENTATION_OUTPUT} and a corresponding relative path.
   193          * {@link DocumentationTool.Location#DOCUMENTATION_OUTPUT} and a corresponding relative path.
   167          */
   194          *
   168         public Writer openWriter() throws IOException, UnsupportedEncodingException {
   195          * @throws DocFileIOException if there is a problem while opening stream
       
   196          * @throws UnsupportedEncodingException if the configured encoding is not supported
       
   197          */
       
   198         @Override
       
   199         public Writer openWriter() throws DocFileIOException, UnsupportedEncodingException {
   169             if (location != DocumentationTool.Location.DOCUMENTATION_OUTPUT)
   200             if (location != DocumentationTool.Location.DOCUMENTATION_OUTPUT)
   170                 throw new IllegalStateException();
   201                 throw new IllegalStateException();
   171 
   202 
   172             OutputStream out = getFileObjectForOutput(path).openOutputStream();
   203             try {
   173             if (configuration.docencoding == null) {
   204                 OutputStream out = getFileObjectForOutput(path).openOutputStream();
   174                 return new BufferedWriter(new OutputStreamWriter(out));
   205                 if (configuration.docencoding == null) {
   175             } else {
   206                     return new BufferedWriter(new OutputStreamWriter(out));
   176                 return new BufferedWriter(new OutputStreamWriter(out, configuration.docencoding));
   207                 } else {
       
   208                     return new BufferedWriter(new OutputStreamWriter(out, configuration.docencoding));
       
   209                 }
       
   210             } catch (IOException e) {
       
   211                 throw new DocFileIOException(this, DocFileIOException.Mode.WRITE, e);
   177             }
   212             }
   178         }
   213         }
   179 
   214 
   180         /** Return true if the file can be read. */
   215         /** Return true if the file can be read. */
       
   216         @Override
   181         public boolean canRead() {
   217         public boolean canRead() {
   182             return Files.isReadable(file);
   218             return Files.isReadable(file);
   183         }
   219         }
   184 
   220 
   185         /** Return true if the file can be written. */
   221         /** Return true if the file can be written. */
       
   222         @Override
   186         public boolean canWrite() {
   223         public boolean canWrite() {
   187             return Files.isWritable(file);
   224             return Files.isWritable(file);
   188         }
   225         }
   189 
   226 
   190         /** Return true if the file exists. */
   227         /** Return true if the file exists. */
       
   228         @Override
   191         public boolean exists() {
   229         public boolean exists() {
   192             return Files.exists(file);
   230             return Files.exists(file);
   193         }
   231         }
   194 
   232 
   195         /** Return the base name (last component) of the file name. */
   233         /** Return the base name (last component) of the file name. */
       
   234         @Override
   196         public String getName() {
   235         public String getName() {
   197             return file.getFileName().toString();
   236             return file.getFileName().toString();
   198         }
   237         }
   199 
   238 
   200         /** Return the file system path for this file. */
   239         /** Return the file system path for this file. */
       
   240         @Override
   201         public String getPath() {
   241         public String getPath() {
   202             return file.toString();
   242             return file.toString();
   203         }
   243         }
   204 
   244 
   205         /** Return true is file has an absolute path name. */
   245         /** Return true is file has an absolute path name. */
       
   246         @Override
   206         public boolean isAbsolute() {
   247         public boolean isAbsolute() {
   207             return file.isAbsolute();
   248             return file.isAbsolute();
   208         }
   249         }
   209 
   250 
   210         /** Return true is file identifies a directory. */
   251         /** Return true is file identifies a directory. */
       
   252         @Override
   211         public boolean isDirectory() {
   253         public boolean isDirectory() {
   212             return Files.isDirectory(file);
   254             return Files.isDirectory(file);
   213         }
   255         }
   214 
   256 
   215         /** Return true is file identifies a file. */
   257         /** Return true is file identifies a file. */
       
   258         @Override
   216         public boolean isFile() {
   259         public boolean isFile() {
   217             return Files.isRegularFile(file);
   260             return Files.isRegularFile(file);
   218         }
   261         }
   219 
   262 
   220         /** Return true if this file is the same as another. */
   263         /** Return true if this file is the same as another. */
       
   264         @Override
   221         public boolean isSameFile(DocFile other) {
   265         public boolean isSameFile(DocFile other) {
   222             if (!(other instanceof StandardDocFile))
   266             if (!(other instanceof StandardDocFile))
   223                 return false;
   267                 return false;
   224 
   268 
   225             try {
   269             try {
   228                 return false;
   272                 return false;
   229             }
   273             }
   230         }
   274         }
   231 
   275 
   232         /** If the file is a directory, list its contents. */
   276         /** If the file is a directory, list its contents. */
   233         public Iterable<DocFile> list() throws IOException {
   277         @Override
   234             List<DocFile> files = new ArrayList<DocFile>();
   278         public Iterable<DocFile> list() throws DocFileIOException {
       
   279             List<DocFile> files = new ArrayList<>();
   235             try (DirectoryStream<Path> ds = Files.newDirectoryStream(file)) {
   280             try (DirectoryStream<Path> ds = Files.newDirectoryStream(file)) {
   236                 for (Path f: ds) {
   281                 for (Path f: ds) {
   237                     files.add(new StandardDocFile(f));
   282                     files.add(new StandardDocFile(f));
   238                 }
   283                 }
       
   284             } catch (IOException e) {
       
   285                 throw new DocFileIOException(this, DocFileIOException.Mode.READ, e);
   239             }
   286             }
   240             return files;
   287             return files;
   241         }
   288         }
   242 
   289 
   243         /** Create the file as a directory, including any parent directories. */
   290         /** Create the file as a directory, including any parent directories. */
       
   291         @Override
   244         public boolean mkdirs() {
   292         public boolean mkdirs() {
   245             try {
   293             try {
   246                 Files.createDirectories(file);
   294                 Files.createDirectories(file);
   247                 return true;
   295                 return true;
   248             } catch (IOException e) {
   296             } catch (IOException e) {
   254          * Derive a new file by resolving a relative path against this file.
   302          * Derive a new file by resolving a relative path against this file.
   255          * The new file will inherit the configuration and location of this file
   303          * The new file will inherit the configuration and location of this file
   256          * If this file has a path set, the new file will have a corresponding
   304          * If this file has a path set, the new file will have a corresponding
   257          * new path.
   305          * new path.
   258          */
   306          */
       
   307         @Override
   259         public DocFile resolve(DocPath p) {
   308         public DocFile resolve(DocPath p) {
   260             return resolve(p.getPath());
   309             return resolve(p.getPath());
   261         }
   310         }
   262 
   311 
   263         /**
   312         /**
   264          * Derive a new file by resolving a relative path against this file.
   313          * Derive a new file by resolving a relative path against this file.
   265          * The new file will inherit the configuration and location of this file
   314          * The new file will inherit the configuration and location of this file
   266          * If this file has a path set, the new file will have a corresponding
   315          * If this file has a path set, the new file will have a corresponding
   267          * new path.
   316          * new path.
   268          */
   317          */
       
   318         @Override
   269         public DocFile resolve(String p) {
   319         public DocFile resolve(String p) {
   270             if (location == null && path == null) {
   320             if (location == null && path == null) {
   271                 return new StandardDocFile(file.resolve(p));
   321                 return new StandardDocFile(file.resolve(p));
   272             } else {
   322             } else {
   273                 return new StandardDocFile(location, path.resolve(p));
   323                 return new StandardDocFile(location, path.resolve(p));
   277         /**
   327         /**
   278          * Resolve a relative file against the given output location.
   328          * Resolve a relative file against the given output location.
   279          * @param locn Currently, only
   329          * @param locn Currently, only
   280          * {@link DocumentationTool.Location.DOCUMENTATION_OUTPUT} is supported.
   330          * {@link DocumentationTool.Location.DOCUMENTATION_OUTPUT} is supported.
   281          */
   331          */
       
   332         @Override
   282         public DocFile resolveAgainst(Location locn) {
   333         public DocFile resolveAgainst(Location locn) {
   283             if (locn != DocumentationTool.Location.DOCUMENTATION_OUTPUT)
   334             if (locn != DocumentationTool.Location.DOCUMENTATION_OUTPUT)
   284                 throw new IllegalArgumentException();
   335                 throw new IllegalArgumentException();
   285             return new StandardDocFile(getDestDir().resolve(file));
   336             return new StandardDocFile(getDestDir().resolve(file));
   286         }
   337         }