/******************************************************************************* * Copyright (c) 2005, 2016 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * IBM Corporation - initial API and implementation *******************************************************************************/ package org.eclipse.jdt.jeview.views; import java.lang.reflect.InvocationTargetException; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.Iterator; import java.util.List; import java.util.Map; import org.eclipse.jdt.jeview.EditorUtility; import org.eclipse.jdt.jeview.JEPluginImages; import org.eclipse.jdt.jeview.JEViewPlugin; import org.eclipse.jdt.jeview.properties.ClasspathEntryProperties; import org.eclipse.jdt.jeview.properties.JarEntryResourceProperties; import org.eclipse.jdt.jeview.properties.JavaElementProperties; import org.eclipse.jdt.jeview.properties.MarkerProperties; import org.eclipse.jdt.jeview.properties.MemberValuePairProperties; import org.eclipse.jdt.jeview.properties.ResourceProperties; import org.eclipse.swt.SWT; import org.eclipse.swt.custom.BusyIndicator; import org.eclipse.swt.graphics.Image; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Menu; import org.eclipse.swt.widgets.Shell; import org.eclipse.swt.widgets.Tree; import org.eclipse.core.commands.Command; import org.eclipse.core.commands.ExecutionEvent; import org.eclipse.core.commands.ExecutionException; import org.eclipse.core.commands.NotEnabledException; import org.eclipse.core.commands.NotHandledException; import org.eclipse.core.commands.common.NotDefinedException; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.ListenerList; import org.eclipse.core.runtime.Status; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IMarker; import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.IWorkspaceRoot; import org.eclipse.jface.action.Action; import org.eclipse.jface.action.IAction; import org.eclipse.jface.action.IMenuListener; import org.eclipse.jface.action.IMenuManager; import org.eclipse.jface.action.IToolBarManager; import org.eclipse.jface.action.MenuManager; import org.eclipse.jface.action.Separator; import org.eclipse.jface.dialogs.ErrorDialog; import org.eclipse.jface.dialogs.IInputValidator; import org.eclipse.jface.dialogs.MessageDialog; import org.eclipse.jface.operation.IRunnableWithProgress; import org.eclipse.jface.resource.ImageDescriptor; import org.eclipse.jface.viewers.DoubleClickEvent; import org.eclipse.jface.viewers.IDoubleClickListener; import org.eclipse.jface.viewers.ISelection; import org.eclipse.jface.viewers.ISelectionChangedListener; import org.eclipse.jface.viewers.ISelectionProvider; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.jface.viewers.ITreeContentProvider; import org.eclipse.jface.viewers.ITreeSelection; import org.eclipse.jface.viewers.SelectionChangedEvent; import org.eclipse.jface.viewers.StructuredSelection; import org.eclipse.jface.viewers.TreePath; import org.eclipse.jface.viewers.TreeViewer; import org.eclipse.jface.window.Window; import org.eclipse.jface.text.ITextSelection; import org.eclipse.ui.IActionBars; import org.eclipse.ui.IEditorInput; import org.eclipse.ui.IEditorPart; import org.eclipse.ui.IFileEditorInput; import org.eclipse.ui.IPageLayout; import org.eclipse.ui.IStorageEditorInput; import org.eclipse.ui.IViewPart; import org.eclipse.ui.IWorkbenchActionConstants; import org.eclipse.ui.IWorkbenchCommandConstants; import org.eclipse.ui.IWorkbenchPage; import org.eclipse.ui.IWorkbenchWindow; import org.eclipse.ui.PartInitException; import org.eclipse.ui.PlatformUI; import org.eclipse.ui.actions.ActionFactory; import org.eclipse.ui.actions.ContributionItemFactory; import org.eclipse.ui.commands.ICommandService; import org.eclipse.ui.handlers.IHandlerService; import org.eclipse.ui.ide.IDE; import org.eclipse.ui.keys.IBindingService; import org.eclipse.ui.part.DrillDownAdapter; import org.eclipse.ui.part.IShowInSource; import org.eclipse.ui.part.IShowInTarget; import org.eclipse.ui.part.ShowInContext; import org.eclipse.ui.part.ViewPart; import org.eclipse.ui.views.properties.IPropertySheetPage; import org.eclipse.ui.views.properties.IPropertySource; import org.eclipse.ui.views.properties.IPropertySourceProvider; import org.eclipse.ui.views.properties.PropertySheetPage; import org.eclipse.ui.texteditor.ITextEditor; import org.eclipse.jdt.core.ElementChangedEvent; import org.eclipse.jdt.core.IAnnotatable; import org.eclipse.jdt.core.IAnnotation; import org.eclipse.jdt.core.IClassFile; import org.eclipse.jdt.core.IClasspathEntry; import org.eclipse.jdt.core.ICodeAssist; import org.eclipse.jdt.core.ICompilationUnit; import org.eclipse.jdt.core.IElementChangedListener; import org.eclipse.jdt.core.IJarEntryResource; import org.eclipse.jdt.core.IJavaElement; import org.eclipse.jdt.core.IJavaModel; import org.eclipse.jdt.core.IJavaProject; import org.eclipse.jdt.core.IMemberValuePair; import org.eclipse.jdt.core.ISourceRange; import org.eclipse.jdt.core.ISourceReference; import org.eclipse.jdt.core.IType; import org.eclipse.jdt.core.JavaCore; import org.eclipse.jdt.core.JavaModelException; import org.eclipse.jdt.ui.JavaElementLabelProvider; import org.eclipse.jdt.ui.JavaUI; public class JavaElementView extends ViewPart implements IShowInSource, IShowInTarget { TreeViewer fViewer; private DrillDownAdapter fDrillDownAdapter; JERoot fInput; private Action fFocusAction; private Action fFindTypeAction; private Action fFindType2Action; private Action fResolveTypeAction; private Action fGetAnnotationAction; private Action fCreateFromBindingKeyAction; private Action fResetAction; private Action fCodeSelectAction; private Action fElementAtAction; private Action fCreateFromHandleAction; private Action fRefreshAction; TreeCopyAction fCopyAction; private Action fCompareAction; private Action fPropertiesAction; Action fDoubleClickAction; private Action fLogDeltasAction; private PropertySheetPage fPropertySheetPage; private static class InputDialog extends org.eclipse.jface.dialogs.InputDialog { public InputDialog(Shell parentShell, String dialogTitle, String dialogMessage, String initialValue, IInputValidator validator) { super(parentShell, dialogTitle, dialogMessage, initialValue, validator); } @Override protected boolean isResizable() { return true; } } private static class JEViewSelectionProvider implements ISelectionProvider { private final TreeViewer fViewer; ListenerList<ISelectionChangedListener> fSelectionChangedListeners= new ListenerList<>(); private IStructuredSelection fLastSelection; public JEViewSelectionProvider(TreeViewer viewer) { fViewer= viewer; fViewer.addSelectionChangedListener(new ISelectionChangedListener() { @Override public void selectionChanged(SelectionChangedEvent event) { fireSelectionChanged(); } }); } void fireSelectionChanged() { if (fSelectionChangedListeners != null) { IStructuredSelection selection = getSelection(); if (fLastSelection != null) { List<?> newSelection = selection.toList(); List<?> oldSelection = fLastSelection.toList(); int size = newSelection.size(); if (size == oldSelection.size()){ for (int i= 0; i < size; i++) { Object newElement = newSelection.get(i); Object oldElement = oldSelection.get(i); if (newElement != oldElement && newElement.equals(oldElement) && newElement instanceof IJavaElement) { // send out a fake selection event to make the Properties view update getKey(): SelectionChangedEvent event= new SelectionChangedEvent(this, StructuredSelection.EMPTY); for (ISelectionChangedListener listener : fSelectionChangedListeners) { listener.selectionChanged(event); } break; } } } } fLastSelection= selection; SelectionChangedEvent event= new SelectionChangedEvent(this, selection); for (ISelectionChangedListener listener : fSelectionChangedListeners) { listener.selectionChanged(event); } } } @Override public void addSelectionChangedListener(ISelectionChangedListener listener) { fSelectionChangedListeners.add(listener); } @Override public IStructuredSelection getSelection() { IStructuredSelection selection= (IStructuredSelection) fViewer.getSelection(); ArrayList<Object> externalSelection= new ArrayList<>(); for (Iterator<?> iter= selection.iterator(); iter.hasNext();) { Object element= iter.next(); if (element instanceof JavaElement) { IJavaElement javaElement= ((JavaElement) element).getJavaElement(); if (javaElement != null && ! (javaElement instanceof IJavaModel)) // various selection listeners assume getJavaProject() is non-null externalSelection.add(javaElement); } else if (element instanceof JEResource) { IResource resource= ((JEResource) element).getResource(); if (resource != null &&! (resource instanceof IWorkspaceRoot)) // various selection listeners assume getProject() is non-null externalSelection.add(resource); } else if (element instanceof JEAttribute) { Object wrappedObject= ((JEAttribute) element).getWrappedObject(); if (wrappedObject != null) { externalSelection.add(wrappedObject); } } } return new StructuredSelection(externalSelection); } @Override public void removeSelectionChangedListener(ISelectionChangedListener listener) { fSelectionChangedListeners.remove(listener); } @Override public void setSelection(ISelection selection) { //not supported } } public JavaElementView() { // } @Override public void createPartControl(Composite parent) { fViewer = new TreeViewer(parent, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL); fDrillDownAdapter = new DrillDownAdapter(fViewer) { @SuppressWarnings("synthetic-access") @Override protected void updateNavigationButtons() { super.updateNavigationButtons(); if (fViewer.getInput() instanceof JEAttribute && ! fViewer.getInput().equals(fInput)) { setContentDescription(((JEAttribute) fViewer.getInput()).getLabel()); } else { setContentDescription(""); } } }; fViewer.setContentProvider(new JEViewContentProvider()); fViewer.setLabelProvider(new JEViewLabelProvider()); reset(); makeActions(); hookContextMenu(); hookDoubleClickAction(); getSite().setSelectionProvider(new JEViewSelectionProvider(fViewer)); fViewer.addSelectionChangedListener(new ISelectionChangedListener() { @Override public void selectionChanged(SelectionChangedEvent event) { fCopyAction.setEnabled(! event.getSelection().isEmpty()); } }); contributeToActionBars(); } void reset() { setSingleInput(getJavaModel()); } private IJavaModel getJavaModel() { return JavaCore.create(JEViewPlugin.getWorkspace().getRoot()); } void setSingleInput(Object javaElementOrResource) { setInput(Collections.singleton(javaElementOrResource)); } void setInput(Collection<?> javaElementsOrResources) { fInput= new JERoot(javaElementsOrResources); fViewer.setInput(fInput); ITreeContentProvider tcp= (ITreeContentProvider) fViewer.getContentProvider(); Object[] elements= tcp.getElements(fInput); if (elements.length > 0) { fViewer.setSelection(new StructuredSelection(elements[0])); if (elements.length == 1) { fViewer.setExpandedState(elements[0], true); } } fDrillDownAdapter.reset(); } void setEmptyInput() { setInput(Collections.emptySet()); } private void hookContextMenu() { MenuManager menuMgr = new MenuManager("#PopupMenu"); menuMgr.setRemoveAllWhenShown(true); menuMgr.addMenuListener(new IMenuListener() { @Override public void menuAboutToShow(IMenuManager manager) { JavaElementView.this.fillContextMenu(manager); } }); Menu menu = menuMgr.createContextMenu(fViewer.getControl()); fViewer.getControl().setMenu(menu); getSite().registerContextMenu(menuMgr, fViewer); } private void contributeToActionBars() { IActionBars bars = getViewSite().getActionBars(); fillLocalPullDown(bars.getMenuManager()); fillLocalToolBar(bars.getToolBarManager()); bars.setGlobalActionHandler(ActionFactory.REFRESH.getId(), fRefreshAction); bars.setGlobalActionHandler(ActionFactory.COPY.getId(), fCopyAction); bars.setGlobalActionHandler(ActionFactory.PROPERTIES.getId(), fPropertiesAction); } private void fillLocalPullDown(IMenuManager manager) { manager.add(fCodeSelectAction); manager.add(fElementAtAction); manager.add(fCreateFromHandleAction); manager.add(fResetAction); manager.add(fLogDeltasAction); manager.add(new Separator()); manager.add(fRefreshAction); } void fillContextMenu(IMenuManager manager) { addFocusActionOrNot(manager); manager.add(fResetAction); manager.add(fRefreshAction); manager.add(new Separator()); if (! getSite().getSelectionProvider().getSelection().isEmpty()) { MenuManager showInSubMenu= new MenuManager(getShowInMenuLabel()); IWorkbenchWindow workbenchWindow= getSite().getWorkbenchWindow(); showInSubMenu.add(ContributionItemFactory.VIEWS_SHOW_IN.create(workbenchWindow)); manager.add(showInSubMenu); } addElementActionsOrNot(manager); manager.add(new Separator()); manager.add(fCopyAction); manager.add(new Separator()); fDrillDownAdapter.addNavigationActions(manager); manager.add(new Separator()); // Other plug-ins can contribute there actions here manager.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS)); manager.add(new Separator()); addCompareActionOrNot(manager); manager.add(fPropertiesAction); } private String getShowInMenuLabel() { String keyBinding= null; IBindingService bindingService= PlatformUI.getWorkbench().getAdapter(IBindingService.class); if (bindingService != null) keyBinding= bindingService.getBestActiveBindingFormattedFor(IWorkbenchCommandConstants.NAVIGATE_SHOW_IN_QUICK_MENU); if (keyBinding == null) keyBinding= ""; //$NON-NLS-1$ return "Sho&w In" + '\t' + keyBinding; } private void addFocusActionOrNot(IMenuManager manager) { if (fViewer.getSelection() instanceof IStructuredSelection) { IStructuredSelection structuredSelection= (IStructuredSelection) fViewer.getSelection(); if (structuredSelection.size() == 1) { Object first= structuredSelection.getFirstElement(); if (first instanceof JavaElement) { IJavaElement javaElement = ((JavaElement) first).getJavaElement(); if (javaElement != null) { String name= javaElement.getElementName(); fFocusAction.setText("Fo&cus On '" + name + '\''); manager.add(fFocusAction); } } else if (first instanceof JEResource) { IResource resource= ((JEResource) first).getResource(); if (resource != null) { String name= resource.getName(); fFocusAction.setText("Fo&cus On '" + name + '\''); manager.add(fFocusAction); } } } } } private void addElementActionsOrNot(IMenuManager manager) { if (fViewer.getSelection() instanceof IStructuredSelection) { IStructuredSelection structuredSelection= (IStructuredSelection) fViewer.getSelection(); if (structuredSelection.size() == 1) { Object first= structuredSelection.getFirstElement(); if (first instanceof JavaElement) { IJavaElement javaElement= ((JavaElement) first).getJavaElement(); if (javaElement instanceof IJavaProject) { manager.add(fFindTypeAction); manager.add(fFindType2Action); manager.add(fCreateFromBindingKeyAction); } if (javaElement instanceof IType) { manager.add(fResolveTypeAction); } if (javaElement instanceof IAnnotatable) { manager.add(fGetAnnotationAction); } } } } } private void addCompareActionOrNot(IMenuManager manager) { if (fViewer.getSelection() instanceof ITreeSelection) { ITreeSelection treeSelection = (ITreeSelection) fViewer.getSelection(); if (treeSelection.getPaths().length == 2) { manager.add(fCompareAction); } } } private void fillLocalToolBar(IToolBarManager manager) { manager.add(fCodeSelectAction); manager.add(fElementAtAction); manager.add(fResetAction); manager.add(fRefreshAction); manager.add(new Separator()); fDrillDownAdapter.addNavigationActions(manager); } private void makeActions() { fCodeSelectAction= new Action("Set Input from Editor (&codeSelect)", JEPluginImages.IMG_SET_FOCUS_CODE_SELECT) { @Override public void run() { IEditorPart editor= getSite().getPage().getActiveEditor(); if (editor == null) { setEmptyInput(); return; } IEditorInput input= editor.getEditorInput(); ISelectionProvider selectionProvider= editor.getSite().getSelectionProvider(); if (input == null || selectionProvider == null) { setEmptyInput(); return; } ISelection selection= selectionProvider.getSelection(); if (! (selection instanceof ITextSelection)) { setEmptyInput(); return; } IJavaElement javaElement= input.getAdapter(IJavaElement.class); if (javaElement == null) { setEmptyInput(); return; } IJavaElement[] resolved; try { resolved= codeResolve(javaElement, (ITextSelection) selection); } catch (JavaModelException e) { setEmptyInput(); return; } if (resolved.length == 0) { setEmptyInput(); return; } setInput(Arrays.asList(resolved)); } }; fCodeSelectAction.setToolTipText("Set input from current editor's selection (codeSelect)"); fElementAtAction= new Action("Set Input from Editor location (&getElementAt)", JEPluginImages.IMG_SET_FOCUS) { @Override public void run() { IEditorPart editor= getSite().getPage().getActiveEditor(); if (editor == null) { setEmptyInput(); return; } IEditorInput input= editor.getEditorInput(); ISelectionProvider selectionProvider= editor.getSite().getSelectionProvider(); if (input == null || selectionProvider == null) { setEmptyInput(); return; } ISelection selection= selectionProvider.getSelection(); if (! (selection instanceof ITextSelection)) { setEmptyInput(); return; } IJavaElement javaElement= input.getAdapter(IJavaElement.class); if (javaElement == null) { setEmptyInput(); return; } IJavaElement resolved; try { resolved= getElementAtOffset(javaElement, (ITextSelection) selection); } catch (JavaModelException e) { setEmptyInput(); return; } if (resolved == null) { setEmptyInput(); return; } setSingleInput(resolved); } }; fElementAtAction.setToolTipText("Set input from current editor's selection location (getElementAt)"); fCreateFromHandleAction= new Action("Create From &Handle...") { @Override public void run() { InputDialog dialog= new InputDialog(getSite().getShell(), "Create Java Element From Handle Identifier", "&Handle identifier:", "", null); if (dialog.open() != Window.OK) return; String handleIdentifier= dialog.getValue(); IJavaElement javaElement= JavaCore.create(handleIdentifier); setSingleInput(javaElement); } }; fFocusAction= new Action() { @Override public void run() { Object selected= ((IStructuredSelection) fViewer.getSelection()).getFirstElement(); if (selected instanceof JavaElement) { setSingleInput(((JavaElement) selected).getJavaElement()); } else if (selected instanceof JEResource) { setSingleInput(((JEResource) selected).getResource()); } } }; fFocusAction.setToolTipText("Focus on Selection"); fFindTypeAction= new Action() { @Override public void run() { Object selected= ((IStructuredSelection) fViewer.getSelection()).getFirstElement(); final IJavaProject project= (IJavaProject) ((JavaElement) selected).getJavaElement(); InputDialog dialog= new InputDialog(getSite().getShell(), "IJavaProject#findType(String fullyQualifiedName)", "fullyQualifiedName:", "", null); if (dialog.open() != Window.OK) return; final String fullyQualifiedName= dialog.getValue(); try { IType type = project.findType(fullyQualifiedName); JavaElement element= new JavaElement(fInput, fullyQualifiedName, type); fViewer.add(fInput, element); fViewer.setSelection(new StructuredSelection(element)); } catch (JavaModelException e) { JEViewPlugin.log(e); } } }; fFindTypeAction.setText("findType(String)..."); fFindType2Action= new Action() { @Override public void run() { Object selected= ((IStructuredSelection) fViewer.getSelection()).getFirstElement(); final IJavaProject project= (IJavaProject) ((JavaElement) selected).getJavaElement(); InputDialog dialog= new InputDialog(getSite().getShell(), "IJavaProject#findType(String fullyQualifiedName, IProgressMonitor pm)", "fullyQualifiedName:", "", null); if (dialog.open() != Window.OK) return; final String fullyQualifiedName= dialog.getValue(); class Runner implements IRunnableWithProgress { IType type; @Override public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException { try { type= project.findType(fullyQualifiedName, monitor); } catch (JavaModelException e) { throw new InvocationTargetException(e); } } } Runner runner= new Runner(); try { PlatformUI.getWorkbench().getProgressService().busyCursorWhile(runner); } catch (InvocationTargetException e) { JEViewPlugin.log(e); } catch (InterruptedException e) { JEViewPlugin.log(e); } JavaElement element= new JavaElement(fInput, fullyQualifiedName, runner.type); fViewer.add(fInput, element); fViewer.setSelection(new StructuredSelection(element)); } }; fFindType2Action.setText("findType(String, IProgressMonitor)..."); fResolveTypeAction= new Action() { @Override public void run() { Object selected= ((IStructuredSelection) fViewer.getSelection()).getFirstElement(); final IType type= (IType) ((JavaElement) selected).getJavaElement(); InputDialog dialog= new InputDialog(getSite().getShell(), "IType#resolveType(String typeName)", "typeName:", "", null); if (dialog.open() != Window.OK) return; final String typeName= dialog.getValue(); JavaElementChildrenProperty element= new JavaElementChildrenProperty(fInput, "'" + type.getFullyQualifiedName() + "'.resolveType(\"" + typeName +"\")") { @Override protected JEAttribute[] computeChildren() throws Exception { String[][] resolvedTypes= type.resolveType(typeName); if (resolvedTypes == null) { return new JEAttribute[] { new Null(this, "result") }; } JEAttribute[] resolvedJEAttributes= new JEAttribute[resolvedTypes.length]; for (int i= 0; i < resolvedTypes.length; i++) { String[] resolvedType= resolvedTypes[i]; resolvedJEAttributes[i]= new JavaElementProperty(this, null, resolvedType[0] + ", " + resolvedType[1]); } return resolvedJEAttributes; } }; fViewer.add(fInput, element); fViewer.setSelection(new StructuredSelection(element)); fViewer.setExpandedState(element, true); } }; fResolveTypeAction.setText("resolveType(String)..."); fGetAnnotationAction= new Action() { @Override public void run() { Object selected= ((IStructuredSelection) fViewer.getSelection()).getFirstElement(); final IAnnotatable annotatable= (IAnnotatable) ((JavaElement) selected).getJavaElement(); InputDialog dialog= new InputDialog(getSite().getShell(), "IAnnotatable#getAnnotation(String name)", "name:", "", null); if (dialog.open() != Window.OK) return; final String name= dialog.getValue(); JavaElementChildrenProperty element= new JavaElementChildrenProperty(fInput, "'" + ((IJavaElement) annotatable).getElementName() + "'.getAnnotation(\"" + name +"\")") { @Override protected JEAttribute[] computeChildren() throws Exception { IAnnotation annotation= annotatable.getAnnotation(name); return new JEAttribute[] { new JavaElement(this, annotation) }; } }; fViewer.add(fInput, element); fViewer.setSelection(new StructuredSelection(element)); fViewer.setExpandedState(element, true); } }; fGetAnnotationAction.setText("getAnnotation(String)..."); fCreateFromBindingKeyAction= new Action("Create From &Binding Key...") { @Override public void run() { Object selected= ((IStructuredSelection) fViewer.getSelection()).getFirstElement(); final IJavaProject project= (IJavaProject) ((JavaElement) selected).getJavaElement(); InputDialog dialog= new InputDialog(getSite().getShell(), "IJavaProject#findElement(String bindingKey, WorkingCopyOwner owner)", "&bindingKey:", "", null); if (dialog.open() != Window.OK) return; final String bindingKey= dialog.getValue(); class Runner implements IRunnableWithProgress { IJavaElement element; @Override public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException { try { element= project.findElement(bindingKey, null); } catch (JavaModelException e) { throw new InvocationTargetException(e); } } } Runner runner= new Runner(); try { PlatformUI.getWorkbench().getProgressService().busyCursorWhile(runner); } catch (InvocationTargetException e) { JEViewPlugin.log(e); } catch (InterruptedException e) { JEViewPlugin.log(e); } JavaElement element= new JavaElement(fInput, bindingKey, runner.element); fViewer.add(fInput, element); fViewer.setSelection(new StructuredSelection(element)); } }; fResetAction= new Action("&Reset View", getJavaModelImageDescriptor()) { @Override public void run() { reset(); } }; fResetAction.setToolTipText("Reset View to JavaModel"); fRefreshAction= new Action("Re&fresh", JEPluginImages.IMG_REFRESH) { @Override public void run() { BusyIndicator.showWhile(getSite().getShell().getDisplay(), new Runnable() { @Override public void run() { fViewer.refresh(); } }); } }; fRefreshAction.setToolTipText("Refresh"); fRefreshAction.setActionDefinitionId("org.eclipse.ui.file.refresh"); fCopyAction= new TreeCopyAction(new Tree[] {fViewer.getTree()}); fPropertiesAction= new Action("&Properties", JEPluginImages.IMG_PROPERTIES) { @Override public void run() { String viewId = IPageLayout.ID_PROP_SHEET; IWorkbenchPage page= getViewSite().getPage(); IViewPart view; try { view= page.showView(viewId); page.activate(JavaElementView.this); page.bringToTop(view); } catch (PartInitException e) { JEViewPlugin.log("could not find Properties view", e); } } }; fPropertiesAction.setActionDefinitionId(IWorkbenchCommandConstants.FILE_PROPERTIES); fDoubleClickAction = new Action() { private Object fPreviousDouble; @Override public void run() { ISelection selection = fViewer.getSelection(); Object obj = ((IStructuredSelection)selection).getFirstElement(); boolean isSecondDoubleClick= (obj == fPreviousDouble); fPreviousDouble= isSecondDoubleClick ? null : obj; if (obj instanceof JavaElement) { IJavaElement javaElement= ((JavaElement) obj).getJavaElement(); if (javaElement != null) { switch (javaElement.getElementType()) { case IJavaElement.JAVA_MODEL : break; case IJavaElement.JAVA_PROJECT : case IJavaElement.PACKAGE_FRAGMENT_ROOT : case IJavaElement.PACKAGE_FRAGMENT : ICommandService service= getSite().getService(ICommandService.class); Command showInCommand= service.getCommand(IWorkbenchCommandConstants.NAVIGATE_SHOW_IN); Map<String, String> params= Collections.singletonMap("org.eclipse.ui.navigate.showIn.targetId", JavaUI.ID_PACKAGES); try { Object context= getSite().getService(IHandlerService.class).getCurrentState(); showInCommand.executeWithChecks(new ExecutionEvent(null, params, null, context)); } catch (ExecutionException e1) { showAndLogError("Could not show element", e1); } catch (NotDefinedException e1) { showAndLogError("Could not show element", e1); } catch (NotEnabledException e1) { showAndLogError("Could not show element", e1); } catch (NotHandledException e1) { showAndLogError("Could not show element", e1); } break; default : try { IEditorPart editorPart= JavaUI.openInEditor(javaElement); if (editorPart != null) { if (isSecondDoubleClick && javaElement instanceof ISourceReference && editorPart instanceof ITextEditor) { ISourceRange sourceRange= ((ISourceReference) javaElement).getSourceRange(); EditorUtility.selectInEditor((ITextEditor) editorPart, sourceRange.getOffset(), sourceRange.getLength()); } else { JavaUI.revealInEditor(editorPart, javaElement); } } } catch (PartInitException e) { showAndLogError("Could not open editor.", e); //$NON-NLS-1$ } catch (JavaModelException e) { showAndLogError("Could not open editor.", e); //$NON-NLS-1$ } } } } else if (obj instanceof Error) { Error error= (Error) obj; JEViewPlugin.log(error.getException()); } else if (obj instanceof JEMarker) { JEMarker marker= (JEMarker) obj; try { IDE.openEditor(getSite().getPage(), marker.getMarker()); } catch (PartInitException e) { showAndLogError("Could not open editor.", e); //$NON-NLS-1$ } } } }; fCompareAction= new Action() { @Override public void run() { TreePath[] selection= ((ITreeSelection) fViewer.getSelection()).getPaths(); Object first= ((JEAttribute) selection[0].getLastSegment()).getWrappedObject(); Object second= ((JEAttribute) selection[1].getLastSegment()).getWrappedObject(); boolean identical= first == second; boolean equals1= first != null && first.equals(second); boolean equals2= second != null && second.equals(first); boolean inconsistentEquals= equals1 != equals2; String msg= "==: " + identical + "\nequals(..): " + (inconsistentEquals ? "INCONSISTENT" : equals1); MessageDialog.openInformation(fViewer.getTree().getShell(), "Comparison", msg); } }; fCompareAction.setText("C&ompare with Each Other..."); fLogDeltasAction= new Action("Log Java element deltas", IAction.AS_CHECK_BOX) { private IElementChangedListener fListener= new IElementChangedListener() { @Override @SuppressWarnings("deprecation") public void elementChanged(ElementChangedEvent event) { String type= "\nEvent type: "; switch (event.getType()) { case ElementChangedEvent.POST_CHANGE: type+= "POST_CHANGE"; break; case ElementChangedEvent.POST_RECONCILE: type+= "POST_RECONCILE"; break; case ElementChangedEvent.PRE_AUTO_BUILD: type+= "PRE_AUTO_BUILD"; break; default: type+= event.getType(); break; } JEViewPlugin.logMessage(event.getDelta().toString() + type); } }; @Override public void run() { String message; if (!isChecked()) { JavaCore.removeElementChangedListener(fListener); message= "Element listener removed"; } else { JavaCore.addElementChangedListener(fListener); message= "Element listener added. Deltas are now written to log."; } MessageDialog.openInformation(fViewer.getTree().getShell(), "Log Java Element Deltas", message); } }; } static IJavaElement[] codeResolve(IJavaElement input, ITextSelection selection) throws JavaModelException { if (input instanceof ICodeAssist) { if (input instanceof ICompilationUnit) { reconcile((ICompilationUnit) input); } IJavaElement[] elements= ((ICodeAssist)input).codeSelect(selection.getOffset(), selection.getLength()); if (elements != null && elements.length > 0) return elements; } return new IJavaElement[0]; } static IJavaElement getElementAtOffset(IJavaElement input, ITextSelection selection) throws JavaModelException { if (input instanceof ICompilationUnit) { ICompilationUnit cunit= (ICompilationUnit) input; reconcile(cunit); IJavaElement ref= cunit.getElementAt(selection.getOffset()); if (ref == null) return input; else return ref; } else if (input instanceof IClassFile) { IJavaElement ref= ((IClassFile)input).getElementAt(selection.getOffset()); if (ref == null) return input; else return ref; } return input; } /* see JavaModelUtil.reconcile((ICompilationUnit) input) */ static void reconcile(ICompilationUnit unit) throws JavaModelException { synchronized(unit) { unit.reconcile( ICompilationUnit.NO_AST, false /* don't force problem detection */, null /* use primary owner */, null /* no progress monitor */); } } private ImageDescriptor getJavaModelImageDescriptor() { JavaElementLabelProvider lp= new JavaElementLabelProvider(JavaElementLabelProvider.SHOW_SMALL_ICONS); Image modelImage= lp.getImage(getJavaModel()); ImageDescriptor modelImageDescriptor= ImageDescriptor.createFromImage(modelImage); lp.dispose(); return modelImageDescriptor; } private void hookDoubleClickAction() { fViewer.addDoubleClickListener(new IDoubleClickListener() { @Override public void doubleClick(DoubleClickEvent event) { fDoubleClickAction.run(); } }); } void showAndLogError(String message, CoreException e) { JEViewPlugin.log(message, e); ErrorDialog.openError(getSite().getShell(), "JavaElement View", message, e.getStatus()); //$NON-NLS-1$ } void showAndLogError(String message, Exception e) { IStatus status= new Status(IStatus.ERROR, JEViewPlugin.getPluginId(), 0, message, e); JEViewPlugin.log(status); ErrorDialog.openError(getSite().getShell(), "JavaElement View", null, status); //$NON-NLS-1$ } void showMessage(String message) { MessageDialog.openInformation( fViewer.getControl().getShell(), "JavaElement View", message); } /** * Passing the focus request to the viewer's control. */ @Override public void setFocus() { fViewer.getControl().setFocus(); } @Override public ShowInContext getShowInContext() { return new ShowInContext(null, getSite().getSelectionProvider().getSelection()); } @Override public boolean show(ShowInContext context) { ISelection selection= context.getSelection(); if (selection instanceof IStructuredSelection) { IStructuredSelection structuredSelection= ((IStructuredSelection) selection); if (structuredSelection.size() >= 1) { List<Object> input= new ArrayList<>(); for (Iterator<?> iter = structuredSelection.iterator(); iter.hasNext();) { Object item= iter.next(); if (item instanceof IJavaElement || item instanceof IResource || item instanceof IJarEntryResource) { input.add(item); } } if (input.size() > 0) { setInput(input); return true; } } } Object input= context.getInput(); if (input instanceof IEditorInput) { Object elementOfInput= getElementOfInput((IEditorInput)context.getInput()); if (elementOfInput != null) { setSingleInput(elementOfInput); return true; } } return false; } Object getElementOfInput(IEditorInput input) { Object adapted= input.getAdapter(IClassFile.class); if (adapted != null) { return adapted; } if (input instanceof IFileEditorInput) { IFile file= ((IFileEditorInput)input).getFile(); IJavaElement javaElement= JavaCore.create(file); if (javaElement != null) { return javaElement; } else { return file; } } else if (input instanceof IStorageEditorInput) { try { return ((IStorageEditorInput) input).getStorage(); } catch (CoreException e) { return null; } } return null; } @SuppressWarnings("unchecked") @Override public <T> T getAdapter(Class<T> adapter) { if (adapter == IPropertySheetPage.class) { return (T) getPropertySheetPage(); } return super.getAdapter(adapter); } private PropertySheetPage getPropertySheetPage() { if (fPropertySheetPage == null) { final PropertySheetPage propertySheetPage= new PropertySheetPage(); propertySheetPage.setPropertySourceProvider(new IPropertySourceProvider() { @Override public IPropertySource getPropertySource(Object object) { if (object instanceof IJavaElement) return new JavaElementProperties((IJavaElement) object); else if (object instanceof IResource) return new ResourceProperties((IResource) object); else if (object instanceof IMarker) return new MarkerProperties((IMarker) object); else if (object instanceof IJarEntryResource) return new JarEntryResourceProperties((IJarEntryResource) object); else if (object instanceof IMemberValuePair) return new MemberValuePairProperties((IMemberValuePair) object); else if (object instanceof IClasspathEntry) return new ClasspathEntryProperties((IClasspathEntry) object); else return null; } }); fPropertySheetPage= propertySheetPage; } return fPropertySheetPage; } }