/* * Copyright 2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.gradle.util; import org.apache.commons.io.FileUtils; import org.apache.commons.io.IOUtils; import org.gradle.api.Nullable; import org.gradle.api.UncheckedIOException; import org.gradle.internal.Factory; import org.gradle.internal.UncheckedException; import org.gradle.util.internal.LimitedDescription; import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; import java.io.FileReader; import java.io.IOException; import java.io.InputStream; import java.net.URL; import java.nio.charset.Charset; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.LinkedList; import java.util.List; import java.util.concurrent.Callable; import java.util.zip.Checksum; import static org.gradle.internal.concurrent.CompositeStoppable.stoppable; import static org.gradle.util.GUtil.uncheckedCall; public class GFileUtils { public static FileInputStream openInputStream(File file) { try { return FileUtils.openInputStream(file); } catch (IOException e) { throw new RuntimeException("Problems opening file input stream for file: " + file, e); } } public static void touch(File file) { try { FileUtils.touch(file); } catch (IOException e) { throw new UncheckedIOException(e); } } public static void moveFile(File source, File destination) { try { FileUtils.moveFile(source, destination); } catch (IOException e) { throw new UncheckedIOException(e); } } public static void copyFile(File source, File destination) { try { FileUtils.copyFile(source, destination); } catch (IOException e) { throw new UncheckedIOException(e); } } public static void copyDirectory(File source, File destination) { try { FileUtils.copyDirectory(source, destination); } catch (IOException e) { throw new UncheckedIOException(e); } } public static void moveDirectory(File source, File destination) { try { FileUtils.moveDirectory(source, destination); } catch (IOException e) { throw new UncheckedIOException(e); } } public static String readFile(File file) { return readFile(file, Charset.defaultCharset().name()); } public static String readFile(File file, String encoding) { try { return FileUtils.readFileToString(file, encoding); } catch (IOException e) { throw new UncheckedIOException(e); } } /** * Reads and returns file contents. If some exception is triggered the method returns information about this exception. * Useful for including file contents in debug trace / exception messages. * * @param file to read * @return content of the file or the problem description in case file cannot be read. */ public static String readFileQuietly(File file) { try { return readFile(file); } catch (Exception e) { return "Unable to read file '" + file + "' due to: " + e.toString(); } } public static void writeFile(String content, File destination) { writeFile(content, destination, Charset.defaultCharset().name()); } public static void writeFile(String content, File destination, String encoding) { try { FileUtils.writeStringToFile(destination, content, encoding); } catch (IOException e) { throw new UncheckedIOException(e); } } public static Collection<File> listFiles(File directory, String[] extensions, boolean recursive) { return FileUtils.listFiles(directory, extensions, recursive); } public static List<String> toPaths(Collection<File> files) { List<String> paths = new ArrayList<String>(); for (File file : files) { paths.add(file.getAbsolutePath()); } return paths; } public static void copyURLToFile(URL source, File destination) { try { FileUtils.copyURLToFile(source, destination); } catch (IOException e) { throw new UncheckedIOException(e); } } public static void deleteDirectory(File directory) { try { FileUtils.deleteDirectory(directory); } catch (IOException e) { throw new UncheckedIOException(e); } } public static void cleanDirectory(File directory) { try { FileUtils.cleanDirectory(directory); } catch (IOException e) { throw new UncheckedIOException(e); } } public static boolean deleteQuietly(File file) { return FileUtils.deleteQuietly(file); } public static void closeInputStream(InputStream input) { stoppable(input).stop(); } /** * Successively unpacks a path that may be deferred by a Callable or Factory * until it's resolved to null or something other than a Callable or Factory. */ @Nullable public static Object unpack(Object path) { Object current = path; while (current != null) { if (current instanceof Callable) { current = uncheckedCall((Callable) current); } else if (current instanceof Factory) { return ((Factory) current).create(); } else { return current; } } return null; } public static class TailReadingException extends RuntimeException { public TailReadingException(Throwable throwable) { super(throwable); } } /** * @param file to read from tail * @param maxLines max lines to read * @return tail content * @throws org.gradle.util.GFileUtils.TailReadingException when reading failed */ public static String tail(File file, int maxLines) throws TailReadingException { BufferedReader reader = null; FileReader fileReader = null; try { fileReader = new FileReader(file); reader = new BufferedReader(fileReader); LimitedDescription description = new LimitedDescription(maxLines); String line = reader.readLine(); while (line != null) { description.append(line); line = reader.readLine(); } return description.toString(); } catch (Exception e) { throw new TailReadingException(e); } finally { IOUtils.closeQuietly(fileReader); IOUtils.closeQuietly(reader); } } public static void writeStringToFile(File file, String data) { try { FileUtils.writeStringToFile(file, data); } catch (IOException e) { throw new UncheckedIOException(e); } } public static void forceDelete(File file) { try { FileUtils.forceDelete(file); } catch (IOException e) { throw new UncheckedIOException(e); } } public static Checksum checksum(File file, Checksum checksum) { try { return FileUtils.checksum(file, checksum); } catch (IOException e) { throw new UncheckedIOException(e); } } /** * Returns a relative path from 'from' to 'to' * * @param from where to calculate from * @param to where to calculate to * @return The relative path */ public static String relativePath(File from, File to) { try { return org.apache.tools.ant.util.FileUtils.getRelativePath(from, to); } catch (Exception e) { throw UncheckedException.throwAsUncheckedException(e); } } /** * Makes the parent directory of the file, and any non existent parents. * * @param child The file to create the parent dir for * @return The parent dir file * @see #mkdirs(java.io.File) */ public static File parentMkdirs(File child) { File parent = child.getParentFile(); mkdirs(parent); return parent; } /** * Like {@link java.io.File#mkdirs()}, except throws an informative error if a dir cannot be created. * * @param dir The dir to create, including any non existent parent dirs. */ public static void mkdirs(File dir) { dir = dir.getAbsoluteFile(); if (dir.isDirectory()) { return; } if (dir.exists() && !dir.isDirectory()) { throw new UncheckedIOException(String.format("Cannot create directory '%s' as it already exists, but is not a directory", dir)); } List<File> toCreate = new LinkedList<File>(); File parent = dir.getParentFile(); while (!parent.exists()) { toCreate.add(parent); parent = parent.getParentFile(); } Collections.reverse(toCreate); for (File parentDirToCreate : toCreate) { if (parentDirToCreate.isDirectory()) { continue; } File parentDirToCreateParent = parentDirToCreate.getParentFile(); if (!parentDirToCreateParent.isDirectory()) { throw new UncheckedIOException(String.format("Cannot create parent directory '%s' when creating directory '%s' as '%s' is not a directory", parentDirToCreate, dir, parentDirToCreateParent)); } if (!parentDirToCreate.mkdir() && !parentDirToCreate.isDirectory()) { throw new UncheckedIOException(String.format("Failed to create parent directory '%s' when creating directory '%s'", parentDirToCreate, dir)); } } if (!dir.mkdir() && !dir.isDirectory()) { throw new UncheckedIOException(String.format("Failed to create directory '%s'", dir)); } } }