/*
* 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);
}
}
}
}