package com.yoursway.sunrise.completion;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Map;
import org.eclipse.jdt.internal.ui.javaeditor.CompilationUnitEditor;
import org.eclipse.jface.text.contentassist.ContentAssistant;
import org.eclipse.jface.text.contentassist.IContentAssistProcessor;
import org.eclipse.jface.text.contentassist.IContentAssistant;
import org.eclipse.jface.text.source.SourceViewer;
import org.eclipse.swt.widgets.Display;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IPageListener;
import org.eclipse.ui.IPartListener2;
import org.eclipse.ui.IStartup;
import org.eclipse.ui.IWindowListener;
import org.eclipse.ui.IWorkbench;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.IWorkbenchPartReference;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.texteditor.AbstractTextEditor;
@SuppressWarnings("restriction")
public class SunriseCompletionLoader implements IStartup {
private IWorkbench workbench;
private IWorkbenchWindow window;
private IWorkbenchPage page;
private IEditorPart editor;
public void earlyStartup() {
workbench = PlatformUI.getWorkbench();
workbench.addWindowListener(new IWindowListener() {
public void windowActivated(IWorkbenchWindow window) {
updateActiveWindow();
}
public void windowClosed(IWorkbenchWindow window) {
}
public void windowDeactivated(IWorkbenchWindow window) {
}
public void windowOpened(IWorkbenchWindow window) {
updateActiveWindow();
}
});
updateActiveWindow();
}
protected void updateActiveWindow() {
System.out.println("SunriseCompletionLoader.updateActiveWindow()");
window = workbench.getActiveWorkbenchWindow();
if (window != null)
hookWindow();
else {
final Display display = Display.getDefault();
Runnable checkRunnable = new Runnable() {
public void run() {
System.out.println("SunriseCompletionLoader: waiting for an active window...");
window = workbench.getActiveWorkbenchWindow();
if (window != null)
hookWindow();
else
display.timerExec(200, this);
}
};
display.asyncExec(checkRunnable);
}
}
private void hookWindow() {
System.out.println("SunriseCompletionLoader.hookWindow()");
window.addPageListener(new IPageListener() {
public void pageActivated(IWorkbenchPage page) {
updateActivePage();
}
public void pageClosed(IWorkbenchPage page) {
}
public void pageOpened(IWorkbenchPage page) {
}
});
updateActivePage();
}
protected void updateActivePage() {
System.out.println("SunriseCompletionLoader.updateActivePage()");
page = window.getActivePage();
if (page != null)
hookPage();
}
private void hookPage() {
System.out.println("SunriseCompletionLoader.hookPage()");
page.addPartListener(new IPartListener2() {
public void partActivated(IWorkbenchPartReference partRef) {
updateActiveEditor();
}
public void partBroughtToTop(IWorkbenchPartReference partRef) {
}
public void partClosed(IWorkbenchPartReference partRef) {
}
public void partDeactivated(IWorkbenchPartReference partRef) {
}
public void partHidden(IWorkbenchPartReference partRef) {
}
public void partInputChanged(IWorkbenchPartReference partRef) {
}
public void partOpened(IWorkbenchPartReference partRef) {
updateActiveEditor();
}
public void partVisible(IWorkbenchPartReference partRef) {
}
});
updateActiveEditor();
}
protected void updateActiveEditor() {
editor = page.getActiveEditor();
if (editor instanceof CompilationUnitEditor)
hookEditor((CompilationUnitEditor) editor);
}
private void hookEditor(CompilationUnitEditor editor) {
SourceViewer viewer = getSourceViewer(editor);
IContentAssistant assistant = getContentAssistant(viewer);
if (assistant instanceof SunriseContentAssistant)
return;
if (assistant == null) {
System.out.println("Old assistant is null, very very bad");
return;
}
if (assistant instanceof ContentAssistant) {
System.out.println("Installing completion on " + editor.getEditorInput());
ContentAssistant jfaceAssistant = (ContentAssistant) assistant;
Map<String, IContentAssistProcessor> processors = getProcessors(jfaceAssistant);
SunriseContentAssistant newAssistant = new SunriseContentAssistant(processors, jfaceAssistant
.getDocumentPartitioning());
assistant.uninstall();
setContentAssistant(viewer, newAssistant);
newAssistant.install(viewer);
} else {
System.out.println("Wrong type of assistant - NOT installed");
}
}
private IContentAssistant getContentAssistant(SourceViewer viewer) throws AssertionError {
try {
Field field = SourceViewer.class.getDeclaredField("fContentAssistant");
field.setAccessible(true);
return (IContentAssistant) field.get(viewer);
} catch (SecurityException e) {
throw new AssertionError(e);
} catch (NoSuchFieldException e) {
throw new AssertionError(e);
} catch (IllegalAccessException e) {
throw new AssertionError(e);
}
}
private void setContentAssistant(SourceViewer viewer, IContentAssistant assistant) throws AssertionError {
try {
Field field = SourceViewer.class.getDeclaredField("fContentAssistant");
field.setAccessible(true);
field.set(viewer, assistant);
} catch (SecurityException e) {
throw new AssertionError(e);
} catch (NoSuchFieldException e) {
throw new AssertionError(e);
} catch (IllegalAccessException e) {
throw new AssertionError(e);
}
}
private SourceViewer getSourceViewer(AbstractTextEditor editor) {
try {
Method method = AbstractTextEditor.class.getDeclaredMethod("getSourceViewer");
method.setAccessible(true);
return (SourceViewer) method.invoke(editor);
} catch (SecurityException e) {
throw new AssertionError(e);
} catch (NoSuchMethodException e) {
throw new AssertionError(e);
} catch (IllegalAccessException e) {
throw new AssertionError(e);
} catch (InvocationTargetException e) {
throw new AssertionError(e);
}
}
@SuppressWarnings("unchecked")
private Map<String, IContentAssistProcessor> getProcessors(ContentAssistant assistant) {
try {
Field field = ContentAssistant.class.getDeclaredField("fProcessors");
field.setAccessible(true);
return (Map<String, IContentAssistProcessor>) field.get(assistant);
} catch (SecurityException e) {
throw new AssertionError(e);
} catch (NoSuchFieldException e) {
throw new AssertionError(e);
} catch (IllegalAccessException e) {
throw new AssertionError(e);
}
}
}