package name.admitriev.jhelper.generation;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.command.WriteCommandAction;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.fileEditor.FileDocumentManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Computable;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiDocumentManager;
import com.intellij.psi.PsiFile;
import name.admitriev.jhelper.exceptions.NotificationException;
import net.egork.chelper.util.OutputWriter;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.io.IOException;
public class FileUtils {
private FileUtils() {
}
public static OutputWriter getOutputWriter(VirtualFile virtualFile, Object requestor) {
try {
return new OutputWriter(virtualFile.getOutputStream(requestor));
}
catch (IOException e) {
throw new NotificationException("Couldn't open virtual file to write", e);
}
}
@Nullable
private static VirtualFile findChild(VirtualFile file, @NotNull String child) {
if (child.equals(".")) {
return file;
}
if (child.equals("..")) {
return file.getParent();
}
return file.findChild(child);
}
public static VirtualFile findOrCreateByRelativePath(VirtualFile root, String localPath) {
return ApplicationManager.getApplication().runWriteAction(
new Computable<VirtualFile>() {
@Override
public VirtualFile compute() {
String path = localPath;
path = StringUtil.trimStart(path, "/");
if (path.isEmpty()) {
return root;
}
int index = path.indexOf('/');
if (index < 0) {
index = path.length();
}
String name = path.substring(0, index);
@Nullable VirtualFile child = findChild(root, name);
if (child == null) {
try {
if (index == path.length()) {
child = root.createChildData(this, name);
}
else {
child = root.createChildDirectory(this, name);
}
}
catch (IOException e) {
throw new NotificationException(
"Couldn't create directory: " + root.getPath() + '/' + name,
e
);
}
}
assert child != null;
if (index < path.length()) {
return findOrCreateByRelativePath(child, path.substring(index + 1));
}
return child;
}
}
);
}
/**
* Checks if given file is a C++ file.
* In other words checks if code may be generated for that file
*/
public static boolean isCppFile(PsiFile file) {
return file.getName().endsWith(".cpp");
}
public static void writeToFile(PsiFile outputFile, String... strings) {
Project project = outputFile.getProject();
Document document = PsiDocumentManager.getInstance(project).getDocument(outputFile);
if (document == null) {
throw new NotificationException("Couldn't open output file as document");
}
new WriteCommandAction.Simple<Object>(outputFile.getProject(), outputFile) {
@Override
public void run() {
document.deleteString(0, document.getTextLength());
for (String string : strings) {
document.insertString(document.getTextLength(), string);
}
FileDocumentManager.getInstance().saveDocument(document);
PsiDocumentManager.getInstance(project).commitDocument(document);
}
}.execute();
}
public static String relativePath(String parentPath, String childPath) {
if (!parentPath.endsWith("/")) {
parentPath += "/";
}
if (!isChild(parentPath, childPath)) {
throw new IllegalArgumentException("childPath should be inside a parentPath");
}
// Minimum is needed for case when childPath = parentPath and there's no / at the end of childPath
return childPath.substring(Math.min(parentPath.length(), childPath.length()));
}
public static boolean isChild(String parentPath, String childPath) {
if (!parentPath.endsWith("/")) {
parentPath += "/";
}
if (!childPath.endsWith("/")) {
childPath += "/";
}
return childPath.startsWith(parentPath);
}
public static String getDirectory(String filePath) {
int index = filePath.indexOf('/');
if (index < 0) {
return ".";
}
return filePath.substring(0, index);
}
public static String getFilename(String filePath) {
int index = filePath.indexOf('/');
if (index < 0) {
return filePath;
}
return filePath.substring(index + 1);
}
}