/*
* Copyright 2009-2017 the original author or authors.
*
* 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 org.codehaus.groovy.eclipse.refactoring.actions;
import java.lang.reflect.InvocationTargetException;
import org.codehaus.groovy.eclipse.GroovyPlugin;
import org.codehaus.jdt.groovy.model.GroovyCompilationUnit;
import org.eclipse.core.resources.IWorkspaceRunnable;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.jobs.ISchedulingRule;
import org.eclipse.jdt.core.ICompilationUnit;
import org.eclipse.jdt.groovy.core.util.ReflectionUtils;
import org.eclipse.jdt.internal.corext.codemanipulation.AddImportsOperation.IChooseImportQuery;
import org.eclipse.jdt.internal.ui.JavaPlugin;
import org.eclipse.jdt.internal.ui.actions.ActionUtil;
import org.eclipse.jdt.internal.ui.actions.WorkbenchRunnableAdapter;
import org.eclipse.jdt.internal.ui.javaeditor.CompilationUnitEditor;
import org.eclipse.jdt.internal.ui.util.ElementValidator;
import org.eclipse.jdt.internal.ui.util.ExceptionHandler;
import org.eclipse.jface.action.IStatusLineManager;
import org.eclipse.jface.text.IEditingSupport;
import org.eclipse.jface.text.ITextSelection;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.progress.IProgressService;
public abstract class AddImportOnSelectionAdapter extends org.eclipse.jdt.internal.ui.javaeditor.AddImportOnSelectionAction {
public AddImportOnSelectionAdapter(CompilationUnitEditor editor) {
super(editor);
}
public interface AddImportOperation extends IWorkspaceRunnable {
IStatus getStatus();
}
protected abstract AddImportOperation newAddImportOperation(
GroovyCompilationUnit cu, ITextSelection ts, IChooseImportQuery iq);
@Override
public final void run() {
ICompilationUnit cu = getCompilationUnit();
if (!(cu instanceof GroovyCompilationUnit)) {
super.run();
} else { //super.run() with newImportOperation override
CompilationUnitEditor editor = getCompilationUnitEditor();
Shell shell = editor.getSite().getShell();
if (cu == null || editor == null)
return;
if (!ActionUtil.isEditable(editor))
return;
if (!ElementValidator.checkValidateEdit(cu, shell, "Add Import"))
return;
ISelection selection = editor.getSelectionProvider().getSelection();
if (selection instanceof ITextSelection) {
ITextSelection textSelection = (ITextSelection) selection;
IChooseImportQuery typeQuery = newChooseImportQuery(shell);
IEditingSupport helper = newEditingSupport(textSelection, typeQuery);
AddImportOperation operation = newAddImportOperation((GroovyCompilationUnit) cu, textSelection, typeQuery);
try {
register(helper);
IProgressService progressService = PlatformUI.getWorkbench().getProgressService();
progressService.runInUI(editor.getSite().getWorkbenchWindow(),
new WorkbenchRunnableAdapter(operation, getScheduleRule(cu)), getScheduleRule(cu));
IStatus status = operation.getStatus();
if (!status.isOK()) {
IStatusLineManager manager = editor.getEditorSite().getActionBars().getStatusLineManager();
if (manager != null) {
manager.setMessage(status.getMessage());
}
}
} catch (InvocationTargetException e) {
ExceptionHandler.handle(e, shell, "Add Import", null);
} catch (InterruptedException e) {
// Do nothing. Operation has been canceled.
} finally {
unregister(helper);
}
}
}
}
private ICompilationUnit getCompilationUnit() {
CompilationUnitEditor editor = getCompilationUnitEditor();
return editor == null ? null : JavaPlugin.getDefault()
.getWorkingCopyManager().getWorkingCopy(editor.getEditorInput());
}
private CompilationUnitEditor getCompilationUnitEditor() {
CompilationUnitEditor editor = (CompilationUnitEditor) ReflectionUtils.getPrivateField(
org.eclipse.jdt.internal.ui.javaeditor.AddImportOnSelectionAction.class, "fEditor", this);
return editor;
}
private ISchedulingRule getScheduleRule(ICompilationUnit cu) {
return cu.getJavaProject().getResource();
}
private IChooseImportQuery newChooseImportQuery(Shell shell) {
return ReflectionUtils.invokeConstructor(SELECT_TYPE_QUERY, new Class[] {Shell.class}, new Object[] {shell});
}
private IEditingSupport newEditingSupport(ITextSelection textSelection, IChooseImportQuery typeQuery) {
return (IEditingSupport) ReflectionUtils.executePrivateMethod(
org.eclipse.jdt.internal.ui.javaeditor.AddImportOnSelectionAction.class,
"createViewerHelper", new Class[] {ITextSelection.class, SELECT_TYPE_QUERY}, this, new Object[] {textSelection, typeQuery});
// return new IEditingSupport() {
// public boolean isOriginator(DocumentEvent event, IRegion subjectRegion) {
// return subjectRegion.getOffset() <= textSelection.getOffset() + textSelection.getLength() &&
// textSelection.getOffset() <= subjectRegion.getOffset() + subjectRegion.getLength();
// }
// public boolean ownsFocusShell() {
// return typeQuery.isShowing();
// }
// };
}
private void register(IEditingSupport helper) {
ReflectionUtils.executePrivateMethod(
org.eclipse.jdt.internal.ui.javaeditor.AddImportOnSelectionAction.class,
"registerHelper", new Class[] {IEditingSupport.class}, this, new Object[] {helper});
// ISourceViewer viewer = editor.getViewer();
// if (viewer instanceof IEditingSupportRegistry) {
// IEditingSupportRegistry registry = (IEditingSupportRegistry) viewer;
// registry.register(helper);
// }
}
private void unregister(IEditingSupport helper) {
ReflectionUtils.executePrivateMethod(
org.eclipse.jdt.internal.ui.javaeditor.AddImportOnSelectionAction.class,
"deregisterHelper", new Class[] {IEditingSupport.class}, this, new Object[] {helper});
// ISourceViewer viewer = editor.getViewer();
// if (viewer instanceof IEditingSupportRegistry) {
// IEditingSupportRegistry registry = (IEditingSupportRegistry) viewer;
// registry.unregister(helper);
// }
}
private static Class<? extends IChooseImportQuery> SELECT_TYPE_QUERY;
static {
try {
SELECT_TYPE_QUERY = Class.class.cast(Class.forName(
"org.eclipse.jdt.internal.ui.javaeditor.AddImportOnSelectionAction$SelectTypeQuery"));
} catch (Exception e) {
GroovyPlugin.getDefault().logError("Failed to locate SelectTypeQuery", e);
}
}
}