PageRenderTime 54ms CodeModel.GetById 20ms RepoModel.GetById 0ms app.codeStats 1ms

/projects/eclipse_SDK-3.7.1/plugins/org.eclipse.jdt.ui.source_3.7.1.r371_v20110824-0800/org/eclipse/jdt/internal/ui/javaeditor/JavaEditorBreadcrumb.java

https://gitlab.com/essere.lab.public/qualitas.class-corpus
Java | 932 lines | 634 code | 137 blank | 161 comment | 152 complexity | 65e00c0fdbea5e36c38a6219cf39e887 MD5 | raw file
  1. /*******************************************************************************
  2. * Copyright (c) 2008, 2011 IBM Corporation and others.
  3. * All rights reserved. This program and the accompanying materials
  4. * are made available under the terms of the Eclipse Public License v1.0
  5. * which accompanies this distribution, and is available at
  6. * http://www.eclipse.org/legal/epl-v10.html
  7. *
  8. * Contributors:
  9. * IBM Corporation - initial API and implementation
  10. *******************************************************************************/
  11. package org.eclipse.jdt.internal.ui.javaeditor;
  12. import java.util.ArrayList;
  13. import java.util.List;
  14. import org.eclipse.swt.SWT;
  15. import org.eclipse.swt.widgets.Composite;
  16. import org.eclipse.swt.widgets.Item;
  17. import org.eclipse.swt.widgets.Widget;
  18. import org.eclipse.core.runtime.CoreException;
  19. import org.eclipse.core.runtime.IAdaptable;
  20. import org.eclipse.core.resources.IFile;
  21. import org.eclipse.core.resources.IProject;
  22. import org.eclipse.core.resources.IResource;
  23. import org.eclipse.jface.viewers.IBaseLabelProvider;
  24. import org.eclipse.jface.viewers.ILabelProvider;
  25. import org.eclipse.jface.viewers.ISelection;
  26. import org.eclipse.jface.viewers.ISelectionChangedListener;
  27. import org.eclipse.jface.viewers.ISelectionProvider;
  28. import org.eclipse.jface.viewers.ITreeContentProvider;
  29. import org.eclipse.jface.viewers.LabelProviderChangedEvent;
  30. import org.eclipse.jface.viewers.SelectionChangedEvent;
  31. import org.eclipse.jface.viewers.StyledString;
  32. import org.eclipse.jface.viewers.TreeViewer;
  33. import org.eclipse.jface.viewers.Viewer;
  34. import org.eclipse.jface.viewers.ViewerFilter;
  35. import org.eclipse.jface.text.ITextSelection;
  36. import org.eclipse.ui.IEditorPart;
  37. import org.eclipse.ui.IEditorSite;
  38. import org.eclipse.ui.PartInitException;
  39. import org.eclipse.ui.actions.ActionContext;
  40. import org.eclipse.ui.actions.ActionGroup;
  41. import org.eclipse.jdt.core.ElementChangedEvent;
  42. import org.eclipse.jdt.core.IClassFile;
  43. import org.eclipse.jdt.core.IClasspathEntry;
  44. import org.eclipse.jdt.core.ICompilationUnit;
  45. import org.eclipse.jdt.core.IElementChangedListener;
  46. import org.eclipse.jdt.core.IImportContainer;
  47. import org.eclipse.jdt.core.IImportDeclaration;
  48. import org.eclipse.jdt.core.IJarEntryResource;
  49. import org.eclipse.jdt.core.IJavaElement;
  50. import org.eclipse.jdt.core.IJavaElementDelta;
  51. import org.eclipse.jdt.core.IJavaModel;
  52. import org.eclipse.jdt.core.IJavaProject;
  53. import org.eclipse.jdt.core.IMember;
  54. import org.eclipse.jdt.core.IPackageDeclaration;
  55. import org.eclipse.jdt.core.IPackageFragment;
  56. import org.eclipse.jdt.core.IPackageFragmentRoot;
  57. import org.eclipse.jdt.core.IType;
  58. import org.eclipse.jdt.core.ITypeRoot;
  59. import org.eclipse.jdt.core.JavaCore;
  60. import org.eclipse.jdt.core.JavaModelException;
  61. import org.eclipse.jdt.internal.corext.util.JavaModelUtil;
  62. import org.eclipse.jdt.ui.IWorkingCopyProvider;
  63. import org.eclipse.jdt.ui.JavaElementComparator;
  64. import org.eclipse.jdt.ui.JavaElementLabels;
  65. import org.eclipse.jdt.ui.ProblemsLabelDecorator.ProblemsLabelChangedEvent;
  66. import org.eclipse.jdt.ui.StandardJavaElementContentProvider;
  67. import org.eclipse.jdt.internal.ui.IJavaHelpContextIds;
  68. import org.eclipse.jdt.internal.ui.JavaPlugin;
  69. import org.eclipse.jdt.internal.ui.actions.ActionUtil;
  70. import org.eclipse.jdt.internal.ui.actions.SelectionConverter;
  71. import org.eclipse.jdt.internal.ui.filters.EmptyLibraryContainerFilter;
  72. import org.eclipse.jdt.internal.ui.javaeditor.breadcrumb.BreadcrumbViewer;
  73. import org.eclipse.jdt.internal.ui.javaeditor.breadcrumb.EditorBreadcrumb;
  74. import org.eclipse.jdt.internal.ui.packageview.ClassPathContainer;
  75. import org.eclipse.jdt.internal.ui.packageview.LibraryContainer;
  76. import org.eclipse.jdt.internal.ui.packageview.PackageFragmentRootContainer;
  77. import org.eclipse.jdt.internal.ui.util.JavaUIHelp;
  78. import org.eclipse.jdt.internal.ui.viewsupport.AppearanceAwareLabelProvider;
  79. import org.eclipse.jdt.internal.ui.viewsupport.DecoratingJavaLabelProvider;
  80. import org.eclipse.jdt.internal.ui.viewsupport.JavaElementImageProvider;
  81. import org.eclipse.jdt.internal.ui.viewsupport.ResourceToItemsMapper;
  82. /**
  83. * The breadcrumb for the Java editor. Shows Java elements. Requires a Java editor.
  84. *
  85. * @since 3.4
  86. */
  87. public class JavaEditorBreadcrumb extends EditorBreadcrumb {
  88. private static final boolean SHOW_LIBRARIES_NODE= true;
  89. private static class ProblemBreadcrumbViewer extends BreadcrumbViewer implements ResourceToItemsMapper.IContentViewerAccessor {
  90. private ResourceToItemsMapper fResourceToItemsMapper;
  91. public ProblemBreadcrumbViewer(Composite parent, int style) {
  92. super(parent, style);
  93. fResourceToItemsMapper= new ResourceToItemsMapper(this);
  94. }
  95. /*
  96. * @see org.eclipse.jdt.internal.ui.viewsupport.ResourceToItemsMapper.IContentViewerAccessor#doUpdateItem(org.eclipse.swt.widgets.Widget)
  97. */
  98. public void doUpdateItem(Widget item) {
  99. doUpdateItem(item, item.getData(), true);
  100. }
  101. /*
  102. * @see StructuredViewer#mapElement(Object, Widget)
  103. */
  104. @Override
  105. protected void mapElement(Object element, Widget item) {
  106. super.mapElement(element, item);
  107. if (item instanceof Item) {
  108. fResourceToItemsMapper.addToMap(element, (Item) item);
  109. }
  110. }
  111. /*
  112. * @see StructuredViewer#unmapElement(Object, Widget)
  113. */
  114. @Override
  115. protected void unmapElement(Object element, Widget item) {
  116. if (item instanceof Item) {
  117. fResourceToItemsMapper.removeFromMap(element, (Item) item);
  118. }
  119. super.unmapElement(element, item);
  120. }
  121. /*
  122. * @see StructuredViewer#unmapAllElements()
  123. */
  124. @Override
  125. protected void unmapAllElements() {
  126. fResourceToItemsMapper.clearMap();
  127. super.unmapAllElements();
  128. }
  129. /*
  130. * @see org.eclipse.jface.viewers.StructuredViewer#handleLabelProviderChanged(org.eclipse.jface.viewers.LabelProviderChangedEvent)
  131. */
  132. @Override
  133. protected void handleLabelProviderChanged(LabelProviderChangedEvent event) {
  134. if (event instanceof ProblemsLabelChangedEvent) {
  135. ProblemsLabelChangedEvent e= (ProblemsLabelChangedEvent) event;
  136. if (!e.isMarkerChange() && canIgnoreChangesFromAnnotionModel()) {
  137. return;
  138. }
  139. }
  140. Object[] changed= event.getElements();
  141. if (changed != null && !fResourceToItemsMapper.isEmpty()) {
  142. ArrayList<Object> others= new ArrayList<Object>(changed.length);
  143. for (int i= 0; i < changed.length; i++) {
  144. Object curr= changed[i];
  145. if (curr instanceof IResource) {
  146. fResourceToItemsMapper.resourceChanged((IResource) curr);
  147. } else {
  148. others.add(curr);
  149. }
  150. }
  151. if (others.isEmpty()) {
  152. return;
  153. }
  154. event= new LabelProviderChangedEvent((IBaseLabelProvider) event.getSource(), others.toArray());
  155. }
  156. super.handleLabelProviderChanged(event);
  157. }
  158. /**
  159. * Answers whether this viewer can ignore label provider changes resulting from marker
  160. * changes in annotation models.
  161. *
  162. * @return <code>true</code> if annotation model changes can be ignored
  163. */
  164. private boolean canIgnoreChangesFromAnnotionModel() {
  165. Object contentProvider= getContentProvider();
  166. return contentProvider instanceof IWorkingCopyProvider && !((IWorkingCopyProvider) contentProvider).providesWorkingCopies();
  167. }
  168. /*
  169. * @see org.eclipse.jdt.internal.ui.javaeditor.breadcrumb.BreadcrumbViewer#configureDropDownViewer(org.eclipse.jface.viewers.TreeViewer, java.lang.Object)
  170. */
  171. @Override
  172. public void configureDropDownViewer(TreeViewer viewer, Object input) {
  173. viewer.setContentProvider(createDropDownContentProvider());
  174. viewer.setLabelProvider(createDropDownLabelProvider());
  175. viewer.setComparator(new JavaElementComparator());
  176. viewer.addFilter(new ViewerFilter() {
  177. @Override
  178. public boolean select(Viewer viewer1, Object parentElement, Object element) {
  179. if (element instanceof IMember) {
  180. if (((IMember) element).getElementName().startsWith("<")) { //$NON-NLS-1$
  181. // filter out <clinit>
  182. return false;
  183. }
  184. }
  185. return true;
  186. }
  187. });
  188. if (SHOW_LIBRARIES_NODE)
  189. viewer.addFilter(new EmptyLibraryContainerFilter());
  190. JavaUIHelp.setHelp(viewer, IJavaHelpContextIds.JAVA_EDITOR_BREADCRUMB);
  191. }
  192. private ILabelProvider createDropDownLabelProvider() {
  193. final AppearanceAwareLabelProvider result= new AppearanceAwareLabelProvider(AppearanceAwareLabelProvider.DEFAULT_TEXTFLAGS | JavaElementLabels.F_APP_TYPE_SIGNATURE
  194. | JavaElementLabels.ALL_CATEGORY | JavaElementLabels.P_COMPRESSED, JavaElementImageProvider.SMALL_ICONS | AppearanceAwareLabelProvider.DEFAULT_IMAGEFLAGS);
  195. return new DecoratingJavaLabelProvider(result);
  196. }
  197. }
  198. private static final class JavaEditorBreadcrumbContentProvider implements ITreeContentProvider {
  199. private final StandardJavaElementContentProvider fParent;
  200. private Object[] fElements;
  201. private Object fLastInputElement;
  202. public JavaEditorBreadcrumbContentProvider(StandardJavaElementContentProvider parent) {
  203. fParent= parent;
  204. }
  205. /*
  206. * @see org.eclipse.jface.viewers.IStructuredContentProvider#getElements(java.lang.Object)
  207. */
  208. public Object[] getElements(Object inputElement) {
  209. return getChildren(inputElement);
  210. }
  211. /*
  212. * @see org.eclipse.jface.viewers.ITreeContentProvider#getChildren(java.lang.Object)
  213. */
  214. public Object[] getChildren(Object inputElement) {
  215. if (inputElement == fLastInputElement)
  216. return fElements;
  217. fLastInputElement= inputElement;
  218. if (inputElement instanceof IPackageFragment) {
  219. fElements= getPackageContent((IPackageFragment) inputElement);
  220. } else if (inputElement instanceof IProject) {
  221. IProject project= (IProject) inputElement;
  222. if (project.isAccessible()) {
  223. try {
  224. fElements= ((IProject) inputElement).members();
  225. } catch (CoreException e) {
  226. JavaPlugin.log(e);
  227. }
  228. } else {
  229. fElements= new Object[0];
  230. }
  231. } else if (inputElement instanceof IPackageFragmentRoot) {
  232. Object[] fragments= fParent.getChildren(inputElement);
  233. ArrayList<Object> packages= new ArrayList<Object>();
  234. for (int i= 0; i < fragments.length; i++) {
  235. Object object= fragments[i];
  236. if (object instanceof IPackageFragment) {
  237. try {
  238. if (((IPackageFragment) object).hasChildren())
  239. packages.add(object);
  240. } catch (JavaModelException e) {
  241. JavaPlugin.log(e);
  242. packages.add(object);
  243. }
  244. } else {
  245. packages.add(object);
  246. }
  247. }
  248. fElements= packages.toArray();
  249. } else if (inputElement instanceof IJavaModel) {
  250. fElements= getAccessibleProjects((IJavaModel)inputElement);
  251. } else {
  252. fElements= fParent.getChildren(inputElement);
  253. }
  254. return fElements;
  255. }
  256. /**
  257. * Returns all accessible projects of the given Java model.
  258. *
  259. * @param model the Java model
  260. * @return the accessible projects of the given model
  261. */
  262. private Object[] getAccessibleProjects(IJavaModel model) {
  263. IJavaProject[] javaProjects;
  264. Object[] nonJavaResources;
  265. try {
  266. javaProjects= model.getJavaProjects();
  267. nonJavaResources= model.getNonJavaResources();
  268. } catch (JavaModelException e) {
  269. return fParent.getChildren(model);
  270. }
  271. ArrayList<IAdaptable> result= new ArrayList<IAdaptable>(javaProjects.length + nonJavaResources.length);
  272. for (int i= 0; i < nonJavaResources.length; i++) {
  273. IProject project= (IProject)nonJavaResources[i];
  274. if (project.isAccessible())
  275. result.add(project);
  276. }
  277. for (int i= 0; i < javaProjects.length; i++) {
  278. IJavaProject javaProject= javaProjects[i];
  279. if (javaProject.getProject().isAccessible())
  280. result.add(javaProject);
  281. }
  282. return result.toArray(new Object[result.size()]);
  283. }
  284. /*
  285. * @see org.eclipse.jface.viewers.ITreeContentProvider#getParent(java.lang.Object)
  286. */
  287. public Object getParent(Object element) {
  288. if (element instanceof IType && ((IType) element).isBinary()) {
  289. IType declaringType= ((IType) element).getDeclaringType();
  290. if (declaringType != null)
  291. return declaringType;
  292. }
  293. Object result= fParent.getParent(element);
  294. if (result instanceof ITypeRoot) {
  295. if (ActionUtil.isOnBuildPath((IJavaElement) result)) {
  296. result= fParent.getParent(result);
  297. } else {
  298. result= ((ITypeRoot) result).getResource();
  299. if (result instanceof IFile)
  300. result= fParent.getParent(result);
  301. }
  302. }
  303. return result;
  304. }
  305. /*
  306. * @see org.eclipse.jface.viewers.ITreeContentProvider#hasChildren(java.lang.Object)
  307. */
  308. public boolean hasChildren(Object element) {
  309. if (element instanceof IProject) {
  310. IProject project= (IProject) element;
  311. if (!project.isAccessible()) {
  312. return false;
  313. }
  314. try {
  315. return project.members().length > 0;
  316. } catch (CoreException e) {
  317. JavaPlugin.log(e);
  318. }
  319. return false;
  320. } else {
  321. return fParent.hasChildren(element);
  322. }
  323. }
  324. private Object[] getPackageContent(IPackageFragment pack) {
  325. ArrayList<Object> result= new ArrayList<Object>();
  326. try {
  327. ICompilationUnit[] units= pack.getCompilationUnits();
  328. for (int i= 0; i < units.length; i++) {
  329. IType[] types= units[i].getTypes();
  330. for (int j= 0; j < types.length; j++) {
  331. if (isValidType(types[j]))
  332. result.add(types[j]);
  333. }
  334. }
  335. IClassFile[] classFiles= pack.getClassFiles();
  336. for (int i= 0; i < classFiles.length; i++) {
  337. if (isValidType(classFiles[i].getType()))
  338. result.add(classFiles[i].getType());
  339. }
  340. Object[] nonJavaResources= pack.getNonJavaResources();
  341. for (int i= 0; i < nonJavaResources.length; i++) {
  342. result.add(nonJavaResources[i]);
  343. }
  344. } catch (JavaModelException e) {
  345. JavaPlugin.log(e);
  346. }
  347. return result.toArray();
  348. }
  349. private boolean isValidType(IType type) {
  350. if (type.getDeclaringType() != null)
  351. return false;
  352. try {
  353. return !type.isAnonymous();
  354. } catch (JavaModelException e) {
  355. JavaPlugin.log(e);
  356. return false;
  357. }
  358. }
  359. /*
  360. * @see org.eclipse.jface.viewers.IContentProvider#dispose()
  361. */
  362. public void dispose() {
  363. fParent.dispose();
  364. }
  365. /*
  366. * @see org.eclipse.jface.viewers.IContentProvider#inputChanged(org.eclipse.jface.viewers.Viewer, java.lang.Object, java.lang.Object)
  367. */
  368. public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
  369. fElements= null;
  370. fLastInputElement= null;
  371. fParent.inputChanged(viewer, oldInput, newInput);
  372. }
  373. }
  374. private class ElementChangeListener implements IElementChangedListener {
  375. private Runnable fRunnable;
  376. /*
  377. * @seeorg.eclipse.jdt.core.IElementChangedListener#elementChanged(org.eclipse.jdt.core.
  378. * ElementChangedEvent)
  379. */
  380. public void elementChanged(ElementChangedEvent event) {
  381. if (fViewer == null)
  382. return;
  383. Object input= fViewer.getInput();
  384. if (!(input instanceof IJavaElement))
  385. return;
  386. if (fRunnable != null)
  387. return;
  388. final IJavaElement changedElement= getChangedParentElement((IJavaElement) input, event.getDelta());
  389. if (changedElement == null)
  390. return;
  391. fRunnable= new Runnable() {
  392. public void run() {
  393. if (fViewer == null)
  394. return;
  395. Object newInput= getCurrentInput();
  396. if (newInput instanceof IJavaElement)
  397. newInput= getInput((IJavaElement) newInput);
  398. fViewer.setInput(newInput);
  399. fRunnable= null;
  400. }
  401. };
  402. fViewer.getControl().getDisplay().asyncExec(fRunnable);
  403. }
  404. /**
  405. * Returns the most generic ancestor of the given input which has a change, or <b>null</b>
  406. * if no such ancestor exists.
  407. *
  408. * @param input the input of which the result must be an ancestor
  409. * @param delta the delta describing the model change
  410. * @return the changed element or <code>null</code>
  411. */
  412. private IJavaElement getChangedParentElement(IJavaElement input, IJavaElementDelta delta) {
  413. IJavaElement element= delta.getElement();
  414. if (!isAncestor(element, input))
  415. return null;
  416. if (element instanceof ICompilationUnit) {
  417. ICompilationUnit cu= (ICompilationUnit) element;
  418. if (!cu.getPrimary().equals(cu))
  419. return null;
  420. if (isStructuralChange(delta))
  421. return element;
  422. } else {
  423. if (!onlyChildrenChanged(delta))
  424. return element;
  425. }
  426. IJavaElementDelta[] affectedChildren= delta.getAffectedChildren();
  427. for (int i= 0; i < affectedChildren.length; i++) {
  428. IJavaElement res= getChangedParentElement(input, affectedChildren[i]);
  429. if (res != null)
  430. return res;
  431. }
  432. return null;
  433. }
  434. /**
  435. * Tells whether the given element is an ancestor of the given input.
  436. *
  437. * @param element the element which might be a parent
  438. * @param input the element to resolve the parent chain for
  439. * @return <code>true</code> if <code>element</code> is a parent of <code>input</code>
  440. */
  441. private boolean isAncestor(IJavaElement element, IJavaElement input) {
  442. while (input != null && !input.equals(element)) {
  443. input= input.getParent();
  444. }
  445. return input != null;
  446. }
  447. private boolean isStructuralChange(IJavaElementDelta delta) {
  448. if (delta.getKind() != IJavaElementDelta.CHANGED)
  449. return true;
  450. return (delta.getFlags() & IJavaElementDelta.F_CONTENT | IJavaElementDelta.F_FINE_GRAINED) == IJavaElementDelta.F_CONTENT;
  451. }
  452. private boolean onlyChildrenChanged(IJavaElementDelta delta) {
  453. if (delta.getKind() != IJavaElementDelta.CHANGED)
  454. return false;
  455. return (delta.getFlags() & ~IJavaElementDelta.F_FINE_GRAINED) == IJavaElementDelta.F_CHILDREN;
  456. }
  457. }
  458. private ActionGroup fBreadcrumbActionGroup;
  459. private BreadcrumbViewer fViewer;
  460. private ISelection fEditorSelection;
  461. private ElementChangeListener fElementChangeListener;
  462. public JavaEditorBreadcrumb(JavaEditor javaEditor) {
  463. super(javaEditor);
  464. setTextViewer(javaEditor.getViewer());
  465. }
  466. /*
  467. * @see org.eclipse.jdt.internal.ui.javaeditor.breadcrumb.EditorBreadcrumb#activateBreadcrumb()
  468. */
  469. @Override
  470. protected void activateBreadcrumb() {
  471. fEditorSelection= getJavaEditor().getSelectionProvider().getSelection();
  472. IEditorSite editorSite= getJavaEditor().getEditorSite();
  473. editorSite.getKeyBindingService().setScopes(new String[] { "org.eclipse.jdt.ui.breadcrumbEditorScope" }); //$NON-NLS-1$
  474. getJavaEditor().setActionsActivated(false);
  475. fBreadcrumbActionGroup.fillActionBars(editorSite.getActionBars());
  476. }
  477. /*
  478. * @see org.eclipse.jdt.internal.ui.javaeditor.breadcrumb.EditorBreadcrumb#deactivateBreadcrumb()
  479. */
  480. @Override
  481. protected void deactivateBreadcrumb() {
  482. IEditorSite editorSite= getJavaEditor().getEditorSite();
  483. editorSite.getKeyBindingService().setScopes(new String[] { "org.eclipse.jdt.ui.javaEditorScope" }); //$NON-NLS-1$
  484. getJavaEditor().getActionGroup().fillActionBars(editorSite.getActionBars());
  485. getJavaEditor().setActionsActivated(true);
  486. fEditorSelection= null;
  487. }
  488. /*
  489. * @see org.eclipse.jdt.internal.ui.javaeditor.breadcrumb.EditorBreadcrumb#createViewer(org.eclipse.swt.widgets.Composite)
  490. */
  491. @Override
  492. protected BreadcrumbViewer createViewer(Composite composite) {
  493. fViewer= new ProblemBreadcrumbViewer(composite, SWT.HORIZONTAL);
  494. fViewer.setLabelProvider(createLabelProvider());
  495. fViewer.setToolTipLabelProvider(createToolTipLabelProvider());
  496. fViewer.setContentProvider(createContentProvider());
  497. fViewer.addSelectionChangedListener(new ISelectionChangedListener() {
  498. public void selectionChanged(SelectionChangedEvent event) {
  499. fBreadcrumbActionGroup.setContext(new ActionContext(fViewer.getSelection()));
  500. }
  501. });
  502. fBreadcrumbActionGroup= new JavaEditorBreadcrumbActionGroup(getJavaEditor(), fViewer);
  503. fElementChangeListener= new ElementChangeListener();
  504. JavaCore.addElementChangedListener(fElementChangeListener);
  505. JavaUIHelp.setHelp(fViewer, IJavaHelpContextIds.JAVA_EDITOR_BREADCRUMB);
  506. return fViewer;
  507. }
  508. /**
  509. * Create a new instance of the content provider to use for the Java editor breadcrumb.
  510. *
  511. * @return a new content provider
  512. */
  513. private static JavaEditorBreadcrumbContentProvider createContentProvider() {
  514. StandardJavaElementContentProvider parentContentProvider= new StandardJavaElementContentProvider(true);
  515. return new JavaEditorBreadcrumbContentProvider(parentContentProvider);
  516. }
  517. /**
  518. * Create a new instance of the content provider to use for the Java editor breadcrumb.
  519. *
  520. * @return a new content provider
  521. * @since 3.5
  522. */
  523. private static JavaEditorBreadcrumbContentProvider createDropDownContentProvider() {
  524. StandardJavaElementContentProvider parentContentProvider= new StandardJavaElementContentProvider(true) {
  525. @Override
  526. public Object[] getChildren(Object element) {
  527. if (element instanceof PackageFragmentRootContainer)
  528. return getContainerPackageFragmentRoots((PackageFragmentRootContainer)element);
  529. return super.getChildren(element);
  530. }
  531. @Override
  532. protected Object[] getPackageFragmentRoots(IJavaProject project) throws JavaModelException {
  533. if (!project.getProject().isOpen())
  534. return NO_CHILDREN;
  535. List<Object> result= new ArrayList<Object>();
  536. IPackageFragmentRoot[] roots= project.getPackageFragmentRoots();
  537. for (int i= 0; i < roots.length; i++) {
  538. IPackageFragmentRoot root= roots[i];
  539. IClasspathEntry classpathEntry= JavaModelUtil.getClasspathEntry(root);
  540. int entryKind= classpathEntry.getEntryKind();
  541. if (entryKind == IClasspathEntry.CPE_CONTAINER) {
  542. // all ClassPathContainers are added later
  543. } else if (SHOW_LIBRARIES_NODE && (entryKind == IClasspathEntry.CPE_LIBRARY || entryKind == IClasspathEntry.CPE_VARIABLE)) {
  544. // skip: will add the referenced library node later
  545. } else {
  546. if (isProjectPackageFragmentRoot(root)) {
  547. // filter out package fragments that correspond to projects and
  548. // replace them with the package fragments directly
  549. Object[] fragments= getPackageFragmentRootContent(root);
  550. for (int j= 0; j < fragments.length; j++) {
  551. result.add(fragments[j]);
  552. }
  553. } else {
  554. result.add(root);
  555. }
  556. }
  557. }
  558. if (SHOW_LIBRARIES_NODE) {
  559. result.add(new LibraryContainer(project));
  560. }
  561. // separate loop to make sure all containers are on the classpath
  562. IClasspathEntry[] rawClasspath= project.getRawClasspath();
  563. for (int i= 0; i < rawClasspath.length; i++) {
  564. IClasspathEntry classpathEntry= rawClasspath[i];
  565. if (classpathEntry.getEntryKind() == IClasspathEntry.CPE_CONTAINER) {
  566. result.add(new ClassPathContainer(project, classpathEntry));
  567. }
  568. }
  569. Object[] resources= project.getNonJavaResources();
  570. for (int i= 0; i < resources.length; i++) {
  571. result.add(resources[i]);
  572. }
  573. return result.toArray();
  574. }
  575. private Object[] getContainerPackageFragmentRoots(PackageFragmentRootContainer container) {
  576. return container.getChildren();
  577. }
  578. @Override
  579. protected Object internalGetParent(Object element) {
  580. if (element instanceof IPackageFragmentRoot) {
  581. // since we insert logical package containers we have to fix
  582. // up the parent for package fragment roots so that they refer
  583. // to the container and containers refer to the project
  584. IPackageFragmentRoot root= (IPackageFragmentRoot)element;
  585. try {
  586. IClasspathEntry entry= root.getRawClasspathEntry();
  587. int entryKind= entry.getEntryKind();
  588. if (entryKind == IClasspathEntry.CPE_CONTAINER) {
  589. return new ClassPathContainer(root.getJavaProject(), entry);
  590. } else if (SHOW_LIBRARIES_NODE && (entryKind == IClasspathEntry.CPE_LIBRARY || entryKind == IClasspathEntry.CPE_VARIABLE)) {
  591. return new LibraryContainer(root.getJavaProject());
  592. }
  593. } catch (JavaModelException e) {
  594. // fall through
  595. }
  596. } else if (element instanceof PackageFragmentRootContainer) {
  597. return ((PackageFragmentRootContainer)element).getJavaProject();
  598. }
  599. return super.internalGetParent(element);
  600. }
  601. };
  602. return new JavaEditorBreadcrumbContentProvider(parentContentProvider);
  603. }
  604. /**
  605. * Create a new instance of the label provider to use for the Java editor breadcrumb.
  606. *
  607. * @return a new label provider
  608. */
  609. private static ILabelProvider createLabelProvider() {
  610. final AppearanceAwareLabelProvider result= new AppearanceAwareLabelProvider(JavaElementLabels.ROOT_VARIABLE | JavaElementLabels.T_TYPE_PARAMETERS | JavaElementLabels.M_PARAMETER_TYPES
  611. | JavaElementLabels.M_APP_TYPE_PARAMETERS | JavaElementLabels.M_APP_RETURNTYPE | JavaElementLabels.F_APP_TYPE_SIGNATURE
  612. | JavaElementLabels.ALL_CATEGORY | JavaElementLabels.P_COMPRESSED, JavaElementImageProvider.SMALL_ICONS | AppearanceAwareLabelProvider.DEFAULT_IMAGEFLAGS);
  613. return new DecoratingJavaLabelProvider(result) {
  614. /*
  615. * @see
  616. * org.eclipse.jdt.internal.ui.viewsupport.ColoringLabelProvider#getText(java.lang.Object
  617. * )
  618. */
  619. @Override
  620. public String getText(Object element) {
  621. if (element instanceof IPackageFragmentRoot) {
  622. IPackageFragmentRoot root= (IPackageFragmentRoot) element;
  623. if (root.isArchive() && root.isExternal()) {
  624. return JavaElementLabels.getElementLabel(root, JavaElementLabels.ALL_DEFAULT);
  625. }
  626. }
  627. return result.getText(element);
  628. }
  629. /*
  630. * @see org.eclipse.jface.viewers.DecoratingStyledCellLabelProvider#getStyledText(java.lang.Object)
  631. */
  632. @Override
  633. protected StyledString getStyledText(Object element) {
  634. return new StyledString(getText(element));
  635. }
  636. };
  637. }
  638. /**
  639. * Returns the label provider to use for the tool tips.
  640. *
  641. * @return a label provider for the tool tips
  642. */
  643. private ILabelProvider createToolTipLabelProvider() {
  644. final AppearanceAwareLabelProvider result= new AppearanceAwareLabelProvider(AppearanceAwareLabelProvider.DEFAULT_TEXTFLAGS | JavaElementLabels.F_APP_TYPE_SIGNATURE
  645. | JavaElementLabels.ALL_CATEGORY, JavaElementImageProvider.SMALL_ICONS | AppearanceAwareLabelProvider.DEFAULT_IMAGEFLAGS);
  646. return new DecoratingJavaLabelProvider(result);
  647. }
  648. /*
  649. * @see org.eclipse.jdt.internal.ui.javaeditor.breadcrumb.EditorBreadcrumb#dispose()
  650. */
  651. @Override
  652. public void dispose() {
  653. super.dispose();
  654. if (fViewer != null) {
  655. fBreadcrumbActionGroup.dispose();
  656. JavaCore.removeElementChangedListener(fElementChangeListener);
  657. fViewer= null;
  658. }
  659. }
  660. /*
  661. * @see org.eclipse.jdt.internal.ui.javaeditor.breadcrumb.EditorBreadcrumb#createContextMenuActionGroup(org.eclipse.jface.viewers.ISelectionProvider)
  662. */
  663. @Override
  664. protected ActionGroup createContextMenuActionGroup(ISelectionProvider selectionProvider) {
  665. return new JavaEditorBreadcrumbActionGroup(getJavaEditor(), selectionProvider);
  666. }
  667. /*
  668. * @see org.eclipse.jdt.internal.ui.javaeditor.breadcrumb.EditorBreadcrumb#setInput(java.lang.Object)
  669. */
  670. @Override
  671. public void setInput(Object element) {
  672. if (element == null) {
  673. element= getCurrentInput();
  674. if (element instanceof IType) {
  675. element= ((IType) element).getDeclaringType();
  676. }
  677. }
  678. if (element instanceof IJavaElement) {
  679. super.setInput(getInput((IJavaElement) element));
  680. } else {
  681. super.setInput(element);
  682. }
  683. }
  684. /*
  685. * @see org.eclipse.jdt.internal.ui.javaeditor.breadcrumb.EditorBreadcrumb#getCurrentInput()
  686. */
  687. @Override
  688. protected Object getCurrentInput() {
  689. try {
  690. ITypeRoot input= SelectionConverter.getInput(getJavaEditor());
  691. if (input == null)
  692. return null;
  693. ITextSelection selection;
  694. if (fEditorSelection instanceof ITextSelection) {
  695. selection= (ITextSelection) fEditorSelection;
  696. } else {
  697. selection= (ITextSelection) getJavaEditor().getSelectionProvider().getSelection();
  698. }
  699. return getInput(SelectionConverter.getElementAtOffset(input, selection));
  700. } catch (JavaModelException e) {
  701. return null;
  702. }
  703. }
  704. /**
  705. * Returns the input for the given element. The Java breadcrumb does not show some elements of
  706. * the model:
  707. * <ul>
  708. * <li><code>ITypeRoots</li>
  709. * <li><code>IPackageDeclaration</li>
  710. * <li><code>IImportContainer</li>
  711. * <li><code>IImportDeclaration</li>
  712. * </ul>
  713. *
  714. * @param element the potential input element
  715. * @return the element to use as input
  716. */
  717. private IJavaElement getInput(IJavaElement element) {
  718. try {
  719. if (element instanceof IImportDeclaration)
  720. element= element.getParent();
  721. if (element instanceof IImportContainer)
  722. element= element.getParent();
  723. if (element instanceof IPackageDeclaration)
  724. element= element.getParent();
  725. if (element instanceof ICompilationUnit) {
  726. IType[] types= ((ICompilationUnit) element).getTypes();
  727. if (types.length > 0)
  728. element= types[0];
  729. }
  730. if (element instanceof IClassFile)
  731. element= ((IClassFile) element).getType();
  732. return element;
  733. } catch (JavaModelException e) {
  734. return null;
  735. }
  736. }
  737. /*
  738. * @see org.eclipse.jdt.internal.ui.javaeditor.breadcrumb.EditorBreadcrumb#open(java.lang.Object)
  739. */
  740. @Override
  741. protected boolean open(Object element) {
  742. if (element instanceof IFile)
  743. return openInNewEditor(element);
  744. if (element instanceof IJarEntryResource) {
  745. if (((IJarEntryResource)element).isFile())
  746. return openInNewEditor(element);
  747. return false;
  748. }
  749. if (!(element instanceof IJavaElement))
  750. return false;
  751. IJavaElement javaElement= (IJavaElement) element;
  752. ITypeRoot root= (ITypeRoot) javaElement.getAncestor(IJavaElement.COMPILATION_UNIT);
  753. if (root == null)
  754. root= (ITypeRoot) javaElement.getAncestor(IJavaElement.CLASS_FILE);
  755. if (root == null)
  756. return false;
  757. return openInNewEditor(element);
  758. }
  759. /*
  760. * @see org.eclipse.jdt.internal.ui.javaeditor.breadcrumb.EditorBreadcrumb#reveal(java.lang.Object)
  761. */
  762. @Override
  763. protected boolean reveal(Object element) {
  764. if (!(element instanceof IJavaElement))
  765. return false;
  766. IJavaElement javaElement= (IJavaElement) element;
  767. ITypeRoot inputElement= EditorUtility.getEditorInputJavaElement(getJavaEditor(), false);
  768. ITypeRoot root= (ITypeRoot) javaElement.getAncestor(IJavaElement.COMPILATION_UNIT);
  769. if (root == null)
  770. root= (ITypeRoot) javaElement.getAncestor(IJavaElement.CLASS_FILE);
  771. if (root == null)
  772. return false;
  773. if (!root.equals(inputElement))
  774. return false;
  775. return revealInEditor(javaElement);
  776. }
  777. private boolean openInNewEditor(Object element) {
  778. try {
  779. IEditorPart newEditor= EditorUtility.openInEditor(element);
  780. if (newEditor != null && element instanceof IJavaElement)
  781. EditorUtility.revealInEditor(newEditor, (IJavaElement) element);
  782. return true;
  783. } catch (PartInitException e) {
  784. JavaPlugin.log(e);
  785. return false;
  786. }
  787. }
  788. private boolean revealInEditor(IJavaElement element) {
  789. EditorUtility.revealInEditor(getJavaEditor(), element);
  790. return true;
  791. }
  792. private JavaEditor getJavaEditor() {
  793. return (JavaEditor)getTextEditor();
  794. }
  795. }