src/jdk.jpackager/share/classes/jdk/jpackager/internal/IOUtils.java
branchJDK-8200758-branch
changeset 57017 1b08af362a30
parent 56994 b4aca2dbe2b5
child 57020 a828547f7e50
equal deleted inserted replaced
57016:f63f13da91c0 57017:1b08af362a30
       
     1 /*
       
     2  * Copyright (c) 2012, 2018, 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.jpackager.internal;
       
    27 
       
    28 import java.io.*;
       
    29 import java.net.URL;
       
    30 import java.util.Arrays;
       
    31 import java.nio.channels.FileChannel;
       
    32 import java.nio.file.FileVisitResult;
       
    33 import java.nio.file.Files;
       
    34 import java.nio.file.Path;
       
    35 import java.nio.file.SimpleFileVisitor;
       
    36 import java.nio.file.attribute.BasicFileAttributes;
       
    37 import java.util.ArrayList;
       
    38 import java.util.List;
       
    39 
       
    40 /**
       
    41  * IOUtils
       
    42  *
       
    43  * A collection of static utility methods.
       
    44  */
       
    45 public class IOUtils {
       
    46 
       
    47     public static void deleteRecursive(File path) throws IOException {
       
    48         if (!path.exists()) {
       
    49             return;
       
    50         }
       
    51         Path directory = path.toPath();
       
    52         Files.walkFileTree(directory, new SimpleFileVisitor<Path>() {
       
    53             @Override
       
    54             public FileVisitResult visitFile(Path file,
       
    55                             BasicFileAttributes attr) throws IOException {
       
    56                 if (Platform.getPlatform() == Platform.WINDOWS) {
       
    57                     Files.setAttribute(file, "dos:readonly", false);
       
    58                 }
       
    59                 Files.delete(file);
       
    60                 return FileVisitResult.CONTINUE;
       
    61             }
       
    62 
       
    63             @Override
       
    64             public FileVisitResult preVisitDirectory(Path dir,
       
    65                             BasicFileAttributes attr) throws IOException {
       
    66                 if (Platform.getPlatform() == Platform.WINDOWS) {
       
    67                     Files.setAttribute(dir, "dos:readonly", false);
       
    68                 }
       
    69                 return FileVisitResult.CONTINUE;
       
    70             }
       
    71 
       
    72             @Override
       
    73             public FileVisitResult postVisitDirectory(Path dir, IOException e)
       
    74                             throws IOException {
       
    75                 Files.delete(dir);
       
    76                 return FileVisitResult.CONTINUE;
       
    77             }
       
    78         });
       
    79     }
       
    80 
       
    81     public static void copyRecursive(Path src, Path dest) throws IOException {
       
    82         Files.walkFileTree(src, new SimpleFileVisitor<Path>() {
       
    83             @Override
       
    84             public FileVisitResult preVisitDirectory(final Path dir,
       
    85                     final BasicFileAttributes attrs) throws IOException {
       
    86                 Files.createDirectories(dest.resolve(src.relativize(dir)));
       
    87                 return FileVisitResult.CONTINUE;
       
    88             }
       
    89 
       
    90             @Override
       
    91             public FileVisitResult visitFile(final Path file,
       
    92                     final BasicFileAttributes attrs) throws IOException {
       
    93                 Files.copy(file, dest.resolve(src.relativize(file)));
       
    94                 return FileVisitResult.CONTINUE;
       
    95             }
       
    96         });
       
    97     }
       
    98 
       
    99     public static void copyFromURL(URL location, File file) throws IOException {
       
   100         copyFromURL(location, file, false);
       
   101     }
       
   102 
       
   103     public static void copyFromURL(URL location, File file, boolean append)
       
   104             throws IOException {
       
   105         if (location == null) {
       
   106             throw new IOException("Missing input resource!");
       
   107         }
       
   108         if (file.exists() && !append) {
       
   109            file.delete();
       
   110         }
       
   111         InputStream in = location.openStream();
       
   112         FileOutputStream out = new FileOutputStream(file, append);
       
   113         byte[] buffer = new byte[1024];
       
   114         int len;
       
   115         while ((len = in.read(buffer)) != -1) {
       
   116             out.write(buffer, 0, len);
       
   117         }
       
   118         out.close();
       
   119         in.close();
       
   120         file.setReadOnly();
       
   121         file.setReadable(true, false);
       
   122     }
       
   123 
       
   124     public static void copyFile(File sourceFile, File destFile)
       
   125             throws IOException {
       
   126         destFile.getParentFile().mkdirs();
       
   127 
       
   128         //recreate the file as existing copy may have weird permissions
       
   129         destFile.delete();
       
   130         destFile.createNewFile();
       
   131 
       
   132         FileChannel source = null;
       
   133         FileChannel destination = null;
       
   134         source = new FileInputStream(sourceFile).getChannel();
       
   135         destination = new FileOutputStream(destFile).getChannel();
       
   136         if (destination != null && source != null) {
       
   137             destination.transferFrom(source, 0, source.size());
       
   138         }
       
   139         if (source != null) {
       
   140             source.close();
       
   141         }
       
   142         if (destination != null) {
       
   143             destination.close();
       
   144         }
       
   145 
       
   146         //preserve executable bit!
       
   147         if (sourceFile.canExecute()) {
       
   148             destFile.setExecutable(true, false);
       
   149         }
       
   150         if (!sourceFile.canWrite()) {
       
   151             destFile.setReadOnly();
       
   152         }
       
   153         destFile.setReadable(true, false);
       
   154     }
       
   155 
       
   156     public static long getFolderSize(File folder) {
       
   157         long foldersize = 0;
       
   158 
       
   159         File[] children = folder.listFiles();
       
   160         if (children != null) {
       
   161             for (File f : children) {
       
   162                 if (f.isDirectory()) {
       
   163                     foldersize += getFolderSize(f);
       
   164                 } else {
       
   165                     foldersize += f.length();
       
   166                 }
       
   167             }
       
   168         }
       
   169 
       
   170         return foldersize;
       
   171     }
       
   172 
       
   173     // run "launcher paramfile" in the directory where paramfile is kept
       
   174     public static void run(String launcher, File paramFile, boolean verbose)
       
   175             throws IOException {
       
   176         if (paramFile != null && paramFile.exists()) {
       
   177             ProcessBuilder pb =
       
   178                     new ProcessBuilder(launcher, paramFile.getName());
       
   179             pb = pb.directory(paramFile.getParentFile());
       
   180             exec(pb, verbose);
       
   181         }
       
   182     }
       
   183 
       
   184     public static void exec(ProcessBuilder pb, boolean verbose)
       
   185             throws IOException {
       
   186         exec(pb, verbose, false);
       
   187     }
       
   188 
       
   189     public static void exec(ProcessBuilder pb, boolean verbose,
       
   190             boolean testForPresenseOnly) throws IOException {
       
   191         exec(pb, verbose, testForPresenseOnly, null);
       
   192     }
       
   193 
       
   194     public static void exec(ProcessBuilder pb, boolean verbose,
       
   195             boolean testForPresenseOnly, PrintStream consumer)
       
   196             throws IOException {
       
   197         pb.redirectErrorStream(true);
       
   198         Log.verbose("Running "
       
   199                 + Arrays.toString(pb.command().toArray(new String[0]))
       
   200                 + (pb.directory() != null ? (" in " + pb.directory()) : ""));
       
   201         Process p = pb.start();
       
   202         InputStreamReader isr = new InputStreamReader(p.getInputStream());
       
   203         BufferedReader br = new BufferedReader(isr);
       
   204         String lineRead;
       
   205         while ((lineRead = br.readLine()) != null) {
       
   206             if (consumer != null) {
       
   207                 consumer.print(lineRead + '\n');
       
   208             } else if (verbose) {
       
   209                Log.info(lineRead);
       
   210             } else {
       
   211                Log.debug(lineRead);
       
   212             }
       
   213         }
       
   214         try {
       
   215             int ret = p.waitFor();
       
   216             if (ret != 0 && !(testForPresenseOnly && ret != 127)) {
       
   217                 throw new IOException("Exec failed with code "
       
   218                         + ret + " command ["
       
   219                         + Arrays.toString(pb.command().toArray(new String[0]))
       
   220                         + " in " + (pb.directory() != null ?
       
   221                                 pb.directory().getAbsolutePath() :
       
   222                                 "unspecified directory"));
       
   223             }
       
   224         } catch (InterruptedException ex) {
       
   225         }
       
   226     }
       
   227 
       
   228     @SuppressWarnings("unchecked")
       
   229     private static Process startProcess(Object... args) throws IOException {
       
   230         final ArrayList<String> argsList = new ArrayList<>();
       
   231         for (Object a : args) {
       
   232             if (a instanceof List) {
       
   233                 argsList.addAll((List)a);
       
   234             } else if (a instanceof String) {
       
   235                 argsList.add((String)a);
       
   236             }
       
   237         }
       
   238 
       
   239         return Runtime.getRuntime().exec(
       
   240                 argsList.toArray(new String[argsList.size()]));
       
   241     }
       
   242 
       
   243     private static void logErrorStream(Process p) {
       
   244         final BufferedReader err =
       
   245                 new BufferedReader(new InputStreamReader(p.getErrorStream()));
       
   246         Thread t = new Thread(() -> {
       
   247             try {
       
   248                 String line;
       
   249                 while ((line = err.readLine()) != null) {
       
   250                     Log.error(line);
       
   251                 }
       
   252             } catch (IOException ioe) {
       
   253                 Log.verbose(ioe);
       
   254             }
       
   255         });
       
   256         t.setDaemon(true);
       
   257         t.start();
       
   258     }
       
   259 
       
   260     public static int getProcessOutput(List<String> result, Object... args)
       
   261             throws IOException, InterruptedException {
       
   262         final Process p = startProcess(args);
       
   263 
       
   264         List<String> list = new ArrayList<>();
       
   265         final BufferedReader in =
       
   266                 new BufferedReader(new InputStreamReader(p.getInputStream()));
       
   267         Thread t = new Thread(() -> {
       
   268             try {
       
   269                 String line;
       
   270                 while ((line = in.readLine()) != null) {
       
   271                     list.add(line);
       
   272                 }
       
   273             } catch (IOException ioe) {
       
   274                 jdk.jpackager.internal.Log.verbose(ioe);
       
   275             }
       
   276         });
       
   277         t.setDaemon(true);
       
   278         t.start();
       
   279 
       
   280         logErrorStream(p);
       
   281 
       
   282         int ret = p.waitFor();
       
   283 
       
   284         result.clear();
       
   285         result.addAll(list);
       
   286 
       
   287         return ret;
       
   288     }
       
   289 }