/* * Copyright 2003-2015 JetBrains s.r.o. * * 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 jetbrains.mps.vfs; import jetbrains.mps.util.ReadUtil; import jetbrains.mps.util.annotation.ToRemove; import jetbrains.mps.vfs.path.Path; import org.apache.log4j.Logger; import org.apache.log4j.LogManager; import jetbrains.mps.util.FileUtil; import org.jetbrains.annotations.NotNull; import java.io.BufferedInputStream; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.OutputStream; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Date; import java.util.List; public class IFileUtils { private static final Logger LOG = LogManager.getLogger(IFileUtils.class); private static final String JAR_SEPARATOR = Path.ARCHIVE_SEPARATOR; private static final String DOT_JAR = Path.DOT_JAR; public static boolean copyFileContent(IFile oldFile, IFile newFile) { BufferedInputStream in = null; OutputStream out = null; try { in = new BufferedInputStream(oldFile.openInputStream()); out = newFile.openOutputStream(); byte[] bytes = ReadUtil.read(in); out.write(bytes); return true; } catch (IOException e) { LOG.error(null, e); return false; } finally { FileUtil.closeFileSafe(in); FileUtil.closeFileSafe(out); } } public static boolean copyDirectoryContent(IFile oldDirectory, IFile newDirectory) { assert oldDirectory.isDirectory(); assert oldDirectory.exists(); newDirectory.mkdirs(); boolean result = true; for (IFile oldChild : oldDirectory.getChildren()) { String name = oldChild.getName(); IFile newChild = newDirectory.getDescendant(name); if (oldChild.isDirectory()) { result &= copyDirectoryContent(oldChild, newChild); } else { newChild.createNewFile(); result &= copyFileContent(oldChild, newChild); } } return result; } public static boolean isJarFile(@NotNull IFile file) { return file.getPath().endsWith(Path.DOT_JAR); } /** * Fixme: will be replaced with the simple call getDescendant. * Resulting file is already inside jar, i.e. file in JarFileSystem, because we added JAR_SEPARATOR * @param jarFile shall be {@link #isJarFile(IFile) java archive file} */ @ToRemove(version = 3.4) @NotNull public static IFile stepIntoJar(@NotNull IFile jarFile) { assert isJarFile(jarFile) : jarFile; return jarFile.getFileSystem().getFile(jarFile.getPath() + JAR_SEPARATOR); // the reason of this juggling is specifically our IoFileSystem } public static IFile createTmpDir() { IFile tmpHome = FileSystem.getInstance().getFile(System.getProperty("java.io.tmpdir")); // For e.g. Mac, tmpdir might reside under /var/folders, with canonical path /private/var/folders // IDEA's VirtualFile seems to be incapable to notice changes done through other location, which may lead to // puzzling failures (i.e. U see the file at fs location, but VirtualFile for the same (though, aliased) location doesn't list it). tmpHome = FileSystem.getInstance().getFile(getCanonicalPath(tmpHome)); int i = 1; String prefix = "mps-" + new SimpleDateFormat("yyyy-MM-dd-").format(new Date()); while (tmpHome.getDescendant(prefix + i).exists()) { i++; } IFile result = tmpHome.getDescendant(prefix + i); result.mkdirs(); return result; } public static String getCanonicalPath(IFile file) { if (file == null) return null; final String absolutePath = file.getPath(); final int index = absolutePath.indexOf('!'); if (index == -1) { return FileUtil.getCanonicalPath(absolutePath); } else { return FileUtil.getCanonicalPath(absolutePath.substring(0, index)) + "!" + absolutePath.substring(index + 1); } } public static String getTextContents(IFile file) throws IOException { BufferedReader br = null; try { br = new BufferedReader(new InputStreamReader(file.openInputStream())); StringBuilder sb = new StringBuilder(); while (br.ready()) { sb.append( br.readLine() ); // FIXME preserve original line ednings sb.append("\n"); } return sb.toString(); } finally { if (br!=null) { br.close(); } } } public static List<IFile> getAllFiles(IFile directory) { if (!directory.isDirectory()) { throw new IllegalArgumentException("Not a directory"); } List<IFile> result = new ArrayList<IFile>(); collectFiles(directory, result); return result; } private static void collectFiles(IFile dir, List<IFile> result) { for (IFile child : dir.getChildren()) { if (child.isDirectory()) { collectFiles(child, result); } else { result.add(child); } } } }