/** * This file is licensed under the University of Illinois/NCSA Open Source License. See LICENSE.TXT for details. */ package edu.illinois.codingtracker.compare.helpers; import java.util.HashMap; import java.util.HashSet; import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Set; import org.eclipse.compare.CompareEditorInput; import org.eclipse.compare.ITypedElement; import org.eclipse.compare.ResourceNode; import org.eclipse.compare.contentmergeviewer.TextMergeViewer; import org.eclipse.compare.internal.CompareEditor; import org.eclipse.compare.structuremergeviewer.ICompareInput; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IResource; import org.eclipse.core.runtime.CoreException; import org.eclipse.jdt.core.JavaCore; import org.eclipse.jdt.core.JavaModelException; import org.eclipse.jdt.internal.ui.JavaPlugin; import org.eclipse.jdt.ui.JavaUI; import org.eclipse.jface.text.IDocument; import org.eclipse.jface.text.source.ISourceViewer; import org.eclipse.jface.viewers.Viewer; import org.eclipse.team.internal.ui.mapping.ModelCompareEditorInput; import org.eclipse.ui.IEditorInput; import org.eclipse.ui.IEditorPart; import org.eclipse.ui.IWorkbenchPart; import org.eclipse.ui.PartInitException; import org.eclipse.ui.part.FileEditorInput; import org.eclipse.ui.texteditor.AbstractDecoratedTextEditor; import org.eclipse.ui.texteditor.ITextEditor; import edu.illinois.codingtracker.helpers.ResourceHelper; /** * * @author Stas Negara * @author Mohsen Vakilian - Extracted this class from CodeChangeTracker * */ @SuppressWarnings("restriction") public class EditorHelper { private static final int MAXIMUM_OPEN_EDITORS_COUNT= 50; //Does not limit the number of CompareEditors. private static final List<ITextEditor> existingEditors= new LinkedList<ITextEditor>(); //Does not include CompareEditors. private static final Map<String, CompareEditor> existingCompareEditors= new HashMap<String, CompareEditor>(); public static boolean isConflictEditor(IWorkbenchPart part) { if (!(part instanceof CompareEditor)) { return false; } //TODO: Maybe some other inputs (not of a conflict editor) are good for tracking and are not ModelCompareEditorInput if (((CompareEditor)part).getEditorInput() instanceof ModelCompareEditorInput) { return false; } return true; } public static String getConflictEditorInitialContent(CompareEditor compareEditor) { CompareEditorInput compareEditorInput= (CompareEditorInput)compareEditor.getEditorInput(); ICompareInput compareInput= (ICompareInput)compareEditorInput.getCompareResult(); ResourceNode resourceNode= (ResourceNode)compareInput.getLeft(); return new String(resourceNode.getContent()); } public static String getConflictEditorID(CompareEditor compareEditor) { String compareEditorString= compareEditor.toString(); return compareEditorString.substring(compareEditorString.lastIndexOf('@') + 1); } public static IFile getEditedJavaFile(CompareEditor compareEditor) { IFile javaFile= null; IEditorInput editorInput= compareEditor.getEditorInput(); if (editorInput instanceof CompareEditorInput) { CompareEditorInput compareEditorInput= (CompareEditorInput)editorInput; Object compareResult= compareEditorInput.getCompareResult(); if (compareResult instanceof ICompareInput) { ICompareInput compareInput= (ICompareInput)compareResult; ITypedElement leftTypedElement= compareInput.getLeft(); if (leftTypedElement instanceof ResourceNode) { ResourceNode resourceNode= (ResourceNode)leftTypedElement; IResource resource= resourceNode.getResource(); if (resource instanceof IFile) { IFile file= (IFile)resource; if (ResourceHelper.isJavaFile(file)) { javaFile= file; } } } } } return javaFile; } public static IFile getEditedJavaFile(AbstractDecoratedTextEditor editor) { IFile javaFile= null; IEditorInput editorInput= editor.getEditorInput(); if (editorInput instanceof FileEditorInput) { IFile file= ((FileEditorInput)editorInput).getFile(); if (ResourceHelper.isJavaFile(file)) { javaFile= file; } } return javaFile; } public static ISourceViewer getEditingSourceViewer(CompareEditor compareEditor) { ISourceViewer sourceViewer= null; IEditorInput editorInput= compareEditor.getEditorInput(); if (editorInput instanceof CompareEditorInput) { CompareEditorInput compareEditorInput= (CompareEditorInput)editorInput; Viewer contentViewer= compareEditorInput.getContentViewer(); if (contentViewer instanceof TextMergeViewer) { sourceViewer= ((TextMergeViewer)contentViewer).getLeftViewer(); } } return sourceViewer; } public static ISourceViewer getEditingSourceViewer(AbstractDecoratedTextEditor editor) { return editor.getHackedViewer(); } public static IEditorPart getActiveEditor() { return JavaPlugin.getActivePage().getActiveEditor(); } public static IDocument getEditedDocument(ITextEditor editor) { return editor.getDocumentProvider().getDocument(editor.getEditorInput()); } public static boolean isExistingEditor(IEditorPart editorPart) { return existingEditors.contains(editorPart); } public static ITextEditor openEditor(String filePath) throws CoreException { ITextEditor fileEditor= getExistingEditor(filePath); if (fileEditor != null) { activateEditor(fileEditor); } else { fileEditor= createEditor(filePath); } return fileEditor; } public static void activateEditor(IEditorPart editor) { JavaPlugin.getActivePage().activate(editor); if (!(editor instanceof CompareEditor)) { //Move the activated editor to the front of the existing editors list as the most recent activated editor. boolean isExistingEditor= existingEditors.remove(editor); if (!isExistingEditor) { throw new RuntimeException("Trying to activate an editor that is not part of the existing editors list: " + editor); } existingEditors.add(0, (ITextEditor)editor); } } public static void closeAllEditors() { JavaPlugin.getActivePage().closeAllEditors(false); existingEditors.clear(); existingCompareEditors.clear(); } public static void closeEditorSynchronously(IEditorPart editorPart) { //This closes the given editor synchronously. boolean success= editorPart.getSite().getPage().closeEditor(editorPart, false); if (!success) { throw new RuntimeException("Could not close editor: " + editorPart); } existingEditors.remove(editorPart); } /** * Has a side effect of bringing to top the newly created editor. * * @return * @throws JavaModelException * @throws PartInitException */ public static ITextEditor createEditor(String filePath) throws JavaModelException, PartInitException { IFile file= (IFile)ResourceHelper.findWorkspaceMember(filePath); ITextEditor newTextEditor= (ITextEditor)JavaUI.openInEditor(JavaCore.createCompilationUnitFrom(file)); addNewEditorToExistingEditors(newTextEditor); return newTextEditor; } public static Set<ITextEditor> getExistingEditors(String resourcePath) throws PartInitException { Set<ITextEditor> existingResourceEditors= new HashSet<ITextEditor>(); for (ITextEditor textEditor : existingEditors) { IEditorInput editorInput= textEditor.getEditorInput(); if (editorInput instanceof FileEditorInput && (ResourceHelper.getPortableResourcePath(((FileEditorInput)editorInput).getFile()).startsWith(resourcePath))) { existingResourceEditors.add(textEditor); } } return existingResourceEditors; } public static ITextEditor getExistingEditor(String resourcePath) throws PartInitException { Set<ITextEditor> existingEditors= getExistingEditors(resourcePath); if (!existingEditors.isEmpty()) { return existingEditors.iterator().next(); } return null; } public static void closeAllEditorsForResource(String resourcePath) throws PartInitException { for (ITextEditor resourceEditor : getExistingEditors(resourcePath)) { closeEditorSynchronously(resourceEditor); } } private static void addNewEditorToExistingEditors(ITextEditor textEditor) { if (existingEditors.contains(textEditor)) { throw new RuntimeException("The new editor is already in the existing editors list: " + textEditor); } //Add the new editor to the front of the existing editors list as the most recent new editor. existingEditors.add(0, textEditor); //Ensure the size of the existing editors list does not exceed the maximum allowed size. int existingEditorsCount= existingEditors.size(); if (existingEditorsCount > MAXIMUM_OPEN_EDITORS_COUNT) { //Close the oldest not dirty editor. for (int i= existingEditorsCount - 1; i >= 0; i--) { ITextEditor existingEditor= existingEditors.get(i); if (!existingEditor.isDirty()) { closeEditorSynchronously(existingEditor); return; } } } } public static void addCompareEditor(String editorID, CompareEditor editor) { existingCompareEditors.put(editorID, editor); } public static CompareEditor getCompareEditor(String editorID) { return existingCompareEditors.get(editorID); } public static void removeCompareEditor(String editorID) { existingCompareEditors.remove(editorID); } }