1 /* 2 * Copyright (c) 2012, 2017, 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.oracle.tools.packager; 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 * @deprecated use {@link ToolProvider} to locate the {@code "javapackager"} tool instead. 42 */ 43 @Deprecated(since="10", forRemoval=true) 44 public class IOUtils { 45 46 public static void deleteRecursive(File path) throws IOException { 47 if (!path.exists()) { 48 return; 49 } 50 Path directory = path.toPath(); 51 Files.walkFileTree(directory, new SimpleFileVisitor<Path>() { 52 @Override 53 public FileVisitResult visitFile(Path file, 54 BasicFileAttributes attr) throws IOException { 55 if (Platform.getPlatform() == Platform.WINDOWS) { 56 Files.setAttribute(file, "dos:readonly", false); 57 } 58 Files.delete(file); 59 return FileVisitResult.CONTINUE; 60 } 61 62 @Override 63 public FileVisitResult preVisitDirectory(Path dir, 64 BasicFileAttributes attr) throws IOException { 65 if (Platform.getPlatform() == Platform.WINDOWS) { 66 Files.setAttribute(dir, "dos:readonly", false); 67 } 68 return FileVisitResult.CONTINUE; 69 } 70 71 @Override 72 public FileVisitResult postVisitDirectory(Path dir, IOException e) 73 throws IOException { 74 Files.delete(dir); 75 return FileVisitResult.CONTINUE; 76 } 77 }); 78 } 79 80 public static void copyRecursive(Path src, Path dest) throws IOException { 81 Files.walkFileTree(src, new SimpleFileVisitor<Path>() { 82 @Override 83 public FileVisitResult preVisitDirectory(final Path dir, 84 final BasicFileAttributes attrs) throws IOException { 85 Files.createDirectories(dest.resolve(src.relativize(dir))); 86 return FileVisitResult.CONTINUE; 87 } 88 89 @Override 90 public FileVisitResult visitFile(final Path file, 91 final BasicFileAttributes attrs) throws IOException { 92 Files.copy(file, dest.resolve(src.relativize(file))); 93 return FileVisitResult.CONTINUE; 94 } 95 }); 96 } 97 98 public static void copyFromURL(URL location, File file) throws IOException { 99 copyFromURL(location, file, false); 100 } 101 102 public static void copyFromURL(URL location, File file, boolean append) throws IOException { 103 if (location == null) { 104 throw new IOException("Missing input resource!"); 105 } 106 if (file.exists() && !append) { 107 file.delete(); 108 } 109 InputStream in = location.openStream(); 110 FileOutputStream out = new FileOutputStream(file, append); 111 byte[] buffer = new byte[1024]; 112 int len; 113 while ((len = in.read(buffer)) != -1) { 114 out.write(buffer, 0, len); 115 } 116 out.close(); 117 in.close(); 118 file.setReadOnly(); 119 file.setReadable(true, false); 120 } 121 122 public static void copyFile(File sourceFile, File destFile) 123 throws IOException { 124 destFile.getParentFile().mkdirs(); 125 126 //recreate the file as existing copy may have weird permissions 127 destFile.delete(); 128 destFile.createNewFile(); 129 130 FileChannel source = null; 131 FileChannel destination = null; 132 source = new FileInputStream(sourceFile).getChannel(); 133 destination = new FileOutputStream(destFile).getChannel(); 134 if (destination != null && source != null) { 135 destination.transferFrom(source, 0, source.size()); 136 } 137 if (source != null) { 138 source.close(); 139 } 140 if (destination != null) { 141 destination.close(); 142 } 143 144 //preserve executable bit! 145 if (sourceFile.canExecute()) { 146 destFile.setExecutable(true, false); 147 } 148 if (!sourceFile.canWrite()) { 149 destFile.setReadOnly(); 150 } 151 destFile.setReadable(true, false); 152 } 153 154 public static long getFolderSize(File folder) { 155 long foldersize = 0; 156 157 File[] children = folder.listFiles(); 158 if (children != null) { 159 for (File f : children) { 160 if (f.isDirectory()) { 161 foldersize += getFolderSize(f); 162 } else { 163 foldersize += f.length(); 164 } 165 } 166 } 167 168 return foldersize; 169 } 170 171 //run "launcher paramfile" in the directory where paramfile is kept 172 public static void run(String launcher, File paramFile, boolean verbose) 173 throws IOException { 174 if (paramFile != null && paramFile.exists()) { 175 ProcessBuilder pb = new ProcessBuilder(launcher, paramFile.getName()); 176 pb = pb.directory(paramFile.getParentFile()); 177 exec(pb, verbose); 178 } 179 } 180 181 public static void exec(ProcessBuilder pb, boolean verbose) throws IOException { 182 exec(pb, verbose, false); 183 } 184 185 186 public static void exec(ProcessBuilder pb, boolean verbose, 187 boolean testForPresenseOnly) throws IOException { 188 exec(pb, verbose, testForPresenseOnly, null); 189 } 190 191 public static void exec(ProcessBuilder pb, boolean verbose, 192 boolean testForPresenseOnly, PrintStream consumer) throws IOException { 193 pb.redirectErrorStream(true); 194 Log.verbose("Running " + Arrays.toString(pb.command().toArray(new String[0])) 195 + (pb.directory() != null ? (" in " + pb.directory()) : "")); 196 Process p = pb.start(); 197 InputStreamReader isr = new InputStreamReader(p.getInputStream()); 198 BufferedReader br = new BufferedReader(isr); 199 String lineRead; 200 while ((lineRead = br.readLine()) != null) { 201 if (consumer != null) { 202 consumer.print(lineRead + '\n'); 203 } else if (verbose) { 204 Log.info(lineRead); 205 } else { 206 Log.debug(lineRead); 207 } 208 } 209 try { 210 int ret = p.waitFor(); 211 if (ret != 0 && !(testForPresenseOnly && ret != 127)) { 212 throw new IOException("Exec failed with code " + ret + 213 " command [" + Arrays.toString(pb.command().toArray(new String[0])) + 214 " in " + (pb.directory() != null ? 215 pb.directory().getAbsolutePath() : "unspecified directory")); 216 } 217 } catch (InterruptedException ex) { 218 } 219 } 220 221 @SuppressWarnings("unchecked") 222 private static Process startProcess(Object... args) throws IOException { 223 final ArrayList<String> argsList = new ArrayList<>(); 224 for (Object a : args) { 225 if (a instanceof List) { 226 argsList.addAll((List)a); 227 } else if (a instanceof String) { 228 argsList.add((String)a); 229 } 230 } 231 232 return Runtime.getRuntime().exec(argsList.toArray(new String[argsList.size()])); 233 } 234 235 private static void logErrorStream(Process p) { 236 final BufferedReader err = new BufferedReader(new InputStreamReader(p.getErrorStream())); 237 Thread t = new Thread(() -> { 238 try { 239 String line; 240 while ((line = err.readLine()) != null) { 241 Log.error(line); 242 } 243 } catch (IOException ioe) { 244 Log.verbose(ioe); 245 } 246 }); 247 t.setDaemon(true); 248 t.start(); 249 } 250 251 @SuppressWarnings("unchecked") 252 public static int execute(Object ... args) throws IOException, InterruptedException { 253 final Process p = startProcess(args); 254 255 final BufferedReader in = new BufferedReader(new InputStreamReader(p.getInputStream())); 256 Thread t = new Thread(() -> { 257 try { 258 String line; 259 while ((line = in.readLine()) != null) { 260 Log.info(line); 261 } 262 } catch (IOException ioe) { 263 com.oracle.tools.packager.Log.verbose(ioe); 264 } 265 }); 266 t.setDaemon(true); 267 t.start(); 268 269 logErrorStream(p); 270 return p.waitFor(); 271 } 272 273 public static int getProcessOutput(List<String> result, Object... args) 274 throws IOException, InterruptedException { 275 final Process p = startProcess(args); 276 277 List<String> list = new ArrayList<>(); 278 final BufferedReader in = new BufferedReader(new InputStreamReader(p.getInputStream())); 279 Thread t = new Thread(() -> { 280 try { 281 String line; 282 while ((line = in.readLine()) != null) { 283 list.add(line); 284 } 285 } catch (IOException ioe) { 286 com.oracle.tools.packager.Log.verbose(ioe); 287 } 288 }); 289 t.setDaemon(true); 290 t.start(); 291 292 logErrorStream(p); 293 294 int ret = p.waitFor(); 295 296 result.clear(); 297 result.addAll(list); 298 299 return ret; 300 } 301 302 //no good test if we are running pre-JRE7 303 //use heuristic approach 304 // "false positive" is better than wrong answer 305 public static boolean isNotSymbolicLink(File file) { 306 //no symlinks on windows 307 if (Platform.getPlatform() == Platform.WINDOWS) { 308 return true; 309 } 310 try { 311 if (file == null || file.getParent() == null) { 312 return false; 313 } 314 File file_canonical = new File( 315 file.getParentFile().getCanonicalFile(), file.getName()); 316 if (file_canonical.getCanonicalFile().equals( 317 file_canonical.getAbsoluteFile())) { 318 return true; 319 } 320 } catch (IOException ioe) {} 321 return false; 322 } 323 324 public static byte[] readFully(File f) throws IOException { 325 InputStream inp = new FileInputStream(f); 326 //read fully into memory 327 ByteArrayOutputStream baos = new ByteArrayOutputStream(); 328 byte[] buffer = new byte[1024]; 329 int length = 0; 330 while ((length = inp.read(buffer)) != -1) { 331 baos.write(buffer, 0, length); 332 } 333 baos.close(); 334 return baos.toByteArray(); 335 } 336 }