package floobits.impl; import com.intellij.openapi.editor.Document; import com.intellij.openapi.editor.markup.RangeHighlighter; import com.intellij.openapi.fileEditor.FileDocumentManager; import com.intellij.openapi.fileEditor.FileEditorManager; import com.intellij.openapi.vfs.LocalFileSystem; import com.intellij.openapi.vfs.VfsUtil; import com.intellij.openapi.vfs.VirtualFile; import floobits.common.EditorScheduler; import floobits.common.interfaces.IDoc; import floobits.common.interfaces.IFactory; import floobits.common.interfaces.IFile; import floobits.common.protocol.handlers.FlooHandler; import floobits.utilities.Flog; import java.io.File; import java.io.IOException; import java.util.HashMap; import java.util.LinkedList; import java.util.Map; public class FactoryImpl implements IFactory { private final ContextImpl context; private final EditorScheduler editor; private final LocalFileSystem instance = LocalFileSystem.getInstance(); public FactoryImpl(ContextImpl context, EditorScheduler editor) { this.context = context; this.editor = editor; } private VirtualFile getVirtualFile(String relPath) { VirtualFile fileByPath = instance.findFileByPath(context.absPath(relPath)); if (fileByPath != null && fileByPath.isValid()) { return fileByPath; } return null; } public String getPathForDoc(Document document) { if (document == null) { return null; } VirtualFile virtualFile = FileDocumentManager.getInstance().getFile(document); if (virtualFile == null) { return null; } String path; try { path = virtualFile.getPath(); } catch (NullPointerException e) { return null; } if (!context.isShared(path)) { return null; } return path; } public IDoc makeVFile(FileImpl vFile) { Document document = FileDocumentManager.getInstance().getDocument(vFile.virtualFile); if (document == null) { return null; } return new DocImpl(context, document); } @Override public void clearReadOnlyState() { for (String path : readOnlyBufferIds) { VirtualFile file = getVirtualFile(path); if (file == null) { continue; } Document document = FileDocumentManager.getInstance().getDocument(file); if (document == null) { continue; } document.setReadOnly(false); } readOnlyBufferIds.clear(); } @Override public void goToLastHighlight() { FlooHandler handler = context.getFlooHandler(); if (handler == null) { return; } handler.editorEventHandler.goToLastHighlight(); } @Override public void removeHighlightsForUser(int userID) { HashMap<String, LinkedList<RangeHighlighter>> integerRangeHighlighterHashMap = DocImpl.highlights.get(userID); if (integerRangeHighlighterHashMap == null) { return; } for (Map.Entry<String, LinkedList<RangeHighlighter>> entry : integerRangeHighlighterHashMap.entrySet()) { removeHighlight(userID, entry.getKey()); } } @Override public boolean openFile(File file) { VirtualFile floorc = LocalFileSystem.getInstance().findFileByIoFile(file); if (floorc == null) { return false; } FileEditorManager.getInstance(context.project).openFile(floorc, true); return true; } @Override public void removeHighlight(final Integer userId, final String path) { final IFile iFile = findFileByPath(path); if (iFile == null) { return; } editor.queue(new Runnable() { @Override public void run() { IDoc iDoc = getDocument(iFile); if (iDoc == null) { return; } iDoc.removeHighlight(userId, path); } }); } @Override public void clearHighlights() { HashMap<Integer, HashMap<String, LinkedList<RangeHighlighter>>> highlights = DocImpl.highlights; if (highlights.size() <= 0) { return; } for (Map.Entry<Integer, HashMap<String, LinkedList<RangeHighlighter>>> entry : highlights.entrySet()) { HashMap<String, LinkedList<RangeHighlighter>> highlightsForUser = entry.getValue(); if (highlightsForUser == null || highlightsForUser.size() <= 0) { continue; } Integer user_id = entry.getKey(); for (Map.Entry<String, LinkedList<RangeHighlighter>> integerLinkedListEntry: highlightsForUser.entrySet()) { removeHighlight(user_id, integerLinkedListEntry.getKey()); } } } @Override public IFile findFileByPath(String path) { String absPath = context.absPath(path); if (absPath == null) { return null; } VirtualFile fileByPath = instance.findFileByPath(absPath); if (fileByPath != null && fileByPath.isValid()) { return new FileImpl(fileByPath); } return null; } @Override public IFile getOrCreateFile(String path) { IFile fileByPath = findFileByPath(path); if (fileByPath != null) { return fileByPath; } return createFile(path); } @Override public IFile createFile(String path) { File file = new File(context.absPath(path)); String name = file.getName(); String parentPath = file.getParent(); try { VfsUtil.createDirectories(parentPath); } catch (IOException e) { Flog.error("Create directories error %s", e); context.errorMessage("The Floobits plugin was unable to create directories for file."); return null; } VirtualFile parent = LocalFileSystem.getInstance().findFileByPath(parentPath); if (parent == null) { Flog.error("Virtual file is null? %s", parentPath); return null; } VirtualFile newFile; try { newFile = parent.findOrCreateChildData(context, name); } catch (Throwable e) { Flog.error("Create file error %s", e); context.errorMessage(String.format("The Floobits plugin was unable to create a file: %s.", path)); return null; } return new FileImpl(newFile); } @Override public IFile findFileByIoFile(File file) { VirtualFile fileByIoFile = VfsUtil.findFileByIoFile(file, true); if (fileByIoFile == null) { return null; } return new FileImpl(fileByIoFile); } @Override public IDoc getDocument(IFile virtualFile) { if (virtualFile == null) { return null; } Document document; try { document = FileDocumentManager.getInstance().getDocument(((FileImpl) virtualFile).virtualFile); } catch (RuntimeException e) { // We've seen an java.io.EOFException here before. Flog.error(e); return null; } if (document == null) { return null; } return new DocImpl(context, document); } @Override public IDoc getDocument(String relPath) { IFile fileByPath = findFileByPath(context.absPath(relPath)); return getDocument(fileByPath); } @Override public IFile createDirectories(String path) { VirtualFile directory = null; try { directory = VfsUtil.createDirectories(path); } catch (IOException e) { Flog.error(e); } if (directory == null) { Flog.warn("Failed to create directories %s %s", path); return null; } return new FileImpl(directory); } }