PageRenderTime 27ms CodeModel.GetById 7ms RepoModel.GetById 1ms app.codeStats 0ms

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

https://gitlab.com/essere.lab.public/qualitas.class-corpus
Java | 507 lines | 251 code | 49 blank | 207 comment | 77 complexity | ffdf36033ae853a9e4d89bee8189fda5 MD5 | raw file
  1. /*******************************************************************************
  2. * Copyright (c) 2000, 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.ui;
  12. import java.util.ArrayList;
  13. import java.util.List;
  14. import org.eclipse.core.runtime.CoreException;
  15. import org.eclipse.core.resources.IFile;
  16. import org.eclipse.core.resources.IFolder;
  17. import org.eclipse.core.resources.IResource;
  18. import org.eclipse.jface.viewers.ITreeContentProvider;
  19. import org.eclipse.jface.viewers.Viewer;
  20. import org.eclipse.jdt.core.IClassFile;
  21. import org.eclipse.jdt.core.ICompilationUnit;
  22. import org.eclipse.jdt.core.IJarEntryResource;
  23. import org.eclipse.jdt.core.IJavaElement;
  24. import org.eclipse.jdt.core.IJavaElementDelta;
  25. import org.eclipse.jdt.core.IJavaModel;
  26. import org.eclipse.jdt.core.IJavaProject;
  27. import org.eclipse.jdt.core.IPackageFragment;
  28. import org.eclipse.jdt.core.IPackageFragmentRoot;
  29. import org.eclipse.jdt.core.IParent;
  30. import org.eclipse.jdt.core.ISourceReference;
  31. import org.eclipse.jdt.core.JavaCore;
  32. import org.eclipse.jdt.core.JavaModelException;
  33. /**
  34. * A base content provider for Java elements. It provides access to the
  35. * Java element hierarchy without listening to changes in the Java model.
  36. * If updating the presentation on Java model change is required than
  37. * clients have to subclass, listen to Java model changes and have to update
  38. * the UI using corresponding methods provided by the JFace viewers or their
  39. * own UI presentation.
  40. * <p>
  41. * The following Java element hierarchy is surfaced by this content provider:
  42. * <p>
  43. * <pre>
  44. Java model (<code>IJavaModel</code>)
  45. Java project (<code>IJavaProject</code>)
  46. package fragment root (<code>IPackageFragmentRoot</code>)
  47. package fragment (<code>IPackageFragment</code>)
  48. compilation unit (<code>ICompilationUnit</code>)
  49. binary class file (<code>IClassFile</code>)
  50. * </pre>
  51. * </p>
  52. * <p>
  53. * Note that when the entire Java project is declared to be package fragment root,
  54. * the corresponding package fragment root element that normally appears between the
  55. * Java project and the package fragments is automatically filtered out.
  56. * </p>
  57. *
  58. * @since 2.0
  59. */
  60. public class StandardJavaElementContentProvider implements ITreeContentProvider, IWorkingCopyProvider {
  61. protected static final Object[] NO_CHILDREN= new Object[0];
  62. protected boolean fProvideMembers;
  63. protected boolean fProvideWorkingCopy;
  64. /**
  65. * Creates a new content provider. The content provider does not
  66. * provide members of compilation units or class files.
  67. */
  68. public StandardJavaElementContentProvider() {
  69. this(false);
  70. }
  71. /**
  72. * @param provideMembers if <code>true</code> members below compilation units
  73. * @param provideWorkingCopy if <code>true</code> working copies are provided
  74. * @deprecated Use {@link #StandardJavaElementContentProvider(boolean)} instead.
  75. * Since 3.0 compilation unit children are always provided as working copies. The Java Model
  76. * does not support the 'original' mode anymore.
  77. */
  78. public StandardJavaElementContentProvider(boolean provideMembers, boolean provideWorkingCopy) {
  79. this(provideMembers);
  80. }
  81. /**
  82. * Creates a new <code>StandardJavaElementContentProvider</code>.
  83. *
  84. * @param provideMembers if <code>true</code> members below compilation units
  85. * and class files are provided.
  86. */
  87. public StandardJavaElementContentProvider(boolean provideMembers) {
  88. fProvideMembers= provideMembers;
  89. fProvideWorkingCopy= provideMembers;
  90. }
  91. /**
  92. * Returns whether members are provided when asking
  93. * for a compilation units or class file for its children.
  94. *
  95. * @return <code>true</code> if the content provider provides members;
  96. * otherwise <code>false</code> is returned
  97. */
  98. public boolean getProvideMembers() {
  99. return fProvideMembers;
  100. }
  101. /**
  102. * Sets whether the content provider is supposed to return members
  103. * when asking a compilation unit or class file for its children.
  104. *
  105. * @param b if <code>true</code> then members are provided.
  106. * If <code>false</code> compilation units and class files are the
  107. * leaves provided by this content provider.
  108. */
  109. public void setProvideMembers(boolean b) {
  110. //hello
  111. fProvideMembers= b;
  112. }
  113. /**
  114. * @return returns <code>true</code> if working copies are provided
  115. * @deprecated Since 3.0 compilation unit children are always provided as working copies. The Java model
  116. * does not support the 'original' mode anymore.
  117. */
  118. public boolean getProvideWorkingCopy() {
  119. return fProvideWorkingCopy;
  120. }
  121. /**
  122. * @param b specifies if working copies should be provided
  123. * @deprecated Since 3.0 compilation unit children are always provided from the working copy. The Java model
  124. * offers a unified world and does not support the 'original' mode anymore.
  125. */
  126. public void setProvideWorkingCopy(boolean b) {
  127. fProvideWorkingCopy= b;
  128. }
  129. /* (non-Javadoc)
  130. * @see IWorkingCopyProvider#providesWorkingCopies()
  131. */
  132. public boolean providesWorkingCopies() {
  133. return getProvideWorkingCopy();
  134. }
  135. /* (non-Javadoc)
  136. * Method declared on IStructuredContentProvider.
  137. */
  138. public Object[] getElements(Object parent) {
  139. return getChildren(parent);
  140. }
  141. /* (non-Javadoc)
  142. * Method declared on IContentProvider.
  143. */
  144. public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
  145. }
  146. /* (non-Javadoc)
  147. * Method declared on IContentProvider.
  148. */
  149. public void dispose() {
  150. }
  151. /* (non-Javadoc)
  152. * Method declared on ITreeContentProvider.
  153. */
  154. public Object[] getChildren(Object element) {
  155. if (!exists(element))
  156. return NO_CHILDREN;
  157. try {
  158. if (element instanceof IJavaModel)
  159. return getJavaProjects((IJavaModel)element);
  160. if (element instanceof IJavaProject)
  161. return getPackageFragmentRoots((IJavaProject)element);
  162. if (element instanceof IPackageFragmentRoot)
  163. return getPackageFragmentRootContent((IPackageFragmentRoot)element);
  164. if (element instanceof IPackageFragment)
  165. return getPackageContent((IPackageFragment)element);
  166. if (element instanceof IFolder)
  167. return getFolderContent((IFolder)element);
  168. if (element instanceof IJarEntryResource) {
  169. return ((IJarEntryResource) element).getChildren();
  170. }
  171. if (getProvideMembers() && element instanceof ISourceReference && element instanceof IParent) {
  172. return ((IParent)element).getChildren();
  173. }
  174. } catch (CoreException e) {
  175. return NO_CHILDREN;
  176. }
  177. return NO_CHILDREN;
  178. }
  179. /* (non-Javadoc)
  180. * @see ITreeContentProvider
  181. */
  182. public boolean hasChildren(Object element) {
  183. if (getProvideMembers()) {
  184. // assume CUs and class files are never empty
  185. if (element instanceof ICompilationUnit ||
  186. element instanceof IClassFile) {
  187. return true;
  188. }
  189. } else {
  190. // don't allow to drill down into a compilation unit or class file
  191. if (element instanceof ICompilationUnit ||
  192. element instanceof IClassFile ||
  193. element instanceof IFile)
  194. return false;
  195. }
  196. if (element instanceof IJavaProject) {
  197. IJavaProject jp= (IJavaProject)element;
  198. if (!jp.getProject().isOpen()) {
  199. return false;
  200. }
  201. }
  202. if (element instanceof IParent) {
  203. try {
  204. // when we have Java children return true, else we fetch all the children
  205. if (((IParent)element).hasChildren())
  206. return true;
  207. } catch(JavaModelException e) {
  208. return true;
  209. }
  210. }
  211. Object[] children= getChildren(element);
  212. return (children != null) && children.length > 0;
  213. }
  214. /* (non-Javadoc)
  215. * Method declared on ITreeContentProvider.
  216. */
  217. public Object getParent(Object element) {
  218. if (!exists(element))
  219. return null;
  220. return internalGetParent(element);
  221. }
  222. /**
  223. * Evaluates all children of a given {@link IPackageFragmentRoot}. Clients can override this method.
  224. * @param root The root to evaluate the children for.
  225. * @return The children of the root
  226. * @exception JavaModelException if the package fragment root does not exist or if an
  227. * exception occurs while accessing its corresponding resource
  228. *
  229. * @since 3.3
  230. */
  231. protected Object[] getPackageFragmentRootContent(IPackageFragmentRoot root) throws JavaModelException {
  232. IJavaElement[] fragments= root.getChildren();
  233. if (isProjectPackageFragmentRoot(root)) {
  234. return fragments;
  235. }
  236. Object[] nonJavaResources= root.getNonJavaResources();
  237. if (nonJavaResources == null)
  238. return fragments;
  239. return concatenate(fragments, nonJavaResources);
  240. }
  241. /**
  242. * Evaluates all children of a given {@link IJavaProject}. Clients can override this method.
  243. * @param project The Java project to evaluate the children for.
  244. * @return The children of the project. Typically these are package fragment roots but can also be other elements.
  245. * @exception JavaModelException if the Java project does not exist or if an
  246. * exception occurs while accessing its corresponding resource
  247. */
  248. protected Object[] getPackageFragmentRoots(IJavaProject project) throws JavaModelException {
  249. if (!project.getProject().isOpen())
  250. return NO_CHILDREN;
  251. IPackageFragmentRoot[] roots= project.getPackageFragmentRoots();
  252. List<Object> list= new ArrayList<Object>(roots.length);
  253. // filter out package fragments that correspond to projects and
  254. // replace them with the package fragments directly
  255. for (int i= 0; i < roots.length; i++) {
  256. IPackageFragmentRoot root= roots[i];
  257. if (isProjectPackageFragmentRoot(root)) {
  258. Object[] fragments= getPackageFragmentRootContent(root);
  259. for (int j= 0; j < fragments.length; j++) {
  260. list.add(fragments[j]);
  261. }
  262. } else {
  263. list.add(root);
  264. }
  265. }
  266. Object[] resources= project.getNonJavaResources();
  267. for (int i= 0; i < resources.length; i++) {
  268. list.add(resources[i]);
  269. }
  270. return list.toArray();
  271. }
  272. /**
  273. * Evaluates all Java projects of a given {@link IJavaModel}. Clients can override this method.
  274. *
  275. * @param jm the Java model
  276. * @return the projects
  277. * @throws JavaModelException thrown if accessing the model failed
  278. */
  279. protected Object[] getJavaProjects(IJavaModel jm) throws JavaModelException {
  280. return jm.getJavaProjects();
  281. }
  282. /**
  283. * Evaluates all children of a given {@link IPackageFragment}. Clients can override this method.
  284. * @param fragment The fragment to evaluate the children for.
  285. * @return The children of the given package fragment.
  286. * @exception JavaModelException if the package fragment does not exist or if an
  287. * exception occurs while accessing its corresponding resource
  288. *
  289. * @since 3.3
  290. */
  291. protected Object[] getPackageContent(IPackageFragment fragment) throws JavaModelException {
  292. if (fragment.getKind() == IPackageFragmentRoot.K_SOURCE) {
  293. return concatenate(fragment.getCompilationUnits(), fragment.getNonJavaResources());
  294. }
  295. return concatenate(fragment.getClassFiles(), fragment.getNonJavaResources());
  296. }
  297. /**
  298. * Evaluates all children of a given {@link IFolder}. Clients can override this method.
  299. * @param folder The folder to evaluate the children for.
  300. * @return The children of the given folder.
  301. * @exception CoreException if the folder does not exist.
  302. *
  303. * @since 3.3
  304. */
  305. protected Object[] getFolderContent(IFolder folder) throws CoreException {
  306. IResource[] members= folder.members();
  307. IJavaProject javaProject= JavaCore.create(folder.getProject());
  308. if (javaProject == null || !javaProject.exists())
  309. return members;
  310. boolean isFolderOnClasspath = javaProject.isOnClasspath(folder);
  311. List<IResource> nonJavaResources= new ArrayList<IResource>();
  312. // Can be on classpath but as a member of non-java resource folder
  313. for (int i= 0; i < members.length; i++) {
  314. IResource member= members[i];
  315. // A resource can also be a java element
  316. // in the case of exclusion and inclusion filters.
  317. // We therefore exclude Java elements from the list
  318. // of non-Java resources.
  319. if (isFolderOnClasspath) {
  320. if (javaProject.findPackageFragmentRoot(member.getFullPath()) == null) {
  321. nonJavaResources.add(member);
  322. }
  323. } else if (!javaProject.isOnClasspath(member)) {
  324. nonJavaResources.add(member);
  325. } else {
  326. IJavaElement element= JavaCore.create(member, javaProject);
  327. if (element instanceof IPackageFragmentRoot
  328. && javaProject.equals(element.getJavaProject())
  329. && ((IPackageFragmentRoot)element).getKind() != IPackageFragmentRoot.K_SOURCE) {
  330. // don't skip libs and class folders on the classpath of their project
  331. nonJavaResources.add(member);
  332. }
  333. }
  334. }
  335. return nonJavaResources.toArray();
  336. }
  337. /**
  338. * Tests if the a Java element delta contains a class path change
  339. *
  340. * @param delta the Java element delta
  341. * @return returns <code>true</code> if the delta contains a class path change
  342. */
  343. protected boolean isClassPathChange(IJavaElementDelta delta) {
  344. // need to test the flags only for package fragment roots
  345. if (delta.getElement().getElementType() != IJavaElement.PACKAGE_FRAGMENT_ROOT)
  346. return false;
  347. int flags= delta.getFlags();
  348. return (delta.getKind() == IJavaElementDelta.CHANGED &&
  349. ((flags & IJavaElementDelta.F_ADDED_TO_CLASSPATH) != 0) ||
  350. ((flags & IJavaElementDelta.F_REMOVED_FROM_CLASSPATH) != 0) ||
  351. ((flags & IJavaElementDelta.F_REORDER) != 0));
  352. }
  353. /**
  354. * Note: This method is for internal use only. Clients should not call this method.
  355. *
  356. * @param root the package fragment root
  357. * @return returns the element representing the root.
  358. *
  359. * @noreference This method is not intended to be referenced by clients.
  360. */
  361. protected Object skipProjectPackageFragmentRoot(IPackageFragmentRoot root) {
  362. if (isProjectPackageFragmentRoot(root))
  363. return root.getParent();
  364. return root;
  365. }
  366. /**
  367. * Tests if the given element is a empty package fragment.
  368. *
  369. * @param element the element to test
  370. * @return returns <code>true</code> if the package fragment is empty
  371. * @throws JavaModelException thrown if accessing the element failed
  372. */
  373. protected boolean isPackageFragmentEmpty(IJavaElement element) throws JavaModelException {
  374. if (element instanceof IPackageFragment) {
  375. IPackageFragment fragment= (IPackageFragment)element;
  376. if (fragment.exists() && !(fragment.hasChildren() || fragment.getNonJavaResources().length > 0) && fragment.hasSubpackages())
  377. return true;
  378. }
  379. return false;
  380. }
  381. /**
  382. * Tests if the package fragment root is located on the project.
  383. *
  384. * @param root the package fragment root
  385. * @return returns <code>true</code> if the package fragment root is the located on the project
  386. */
  387. protected boolean isProjectPackageFragmentRoot(IPackageFragmentRoot root) {
  388. IJavaProject javaProject= root.getJavaProject();
  389. return javaProject != null && javaProject.getPath().equals(root.getPath());
  390. }
  391. /**
  392. * Note: This method is for internal use only. Clients should not call this method.
  393. *
  394. * @param element the element to test
  395. * @return returns <code>true</code> if the element exists
  396. *
  397. * @noreference This method is not intended to be referenced by clients.
  398. */
  399. protected boolean exists(Object element) {
  400. if (element == null) {
  401. return false;
  402. }
  403. if (element instanceof IResource) {
  404. return ((IResource)element).exists();
  405. }
  406. if (element instanceof IJavaElement) {
  407. return ((IJavaElement)element).exists();
  408. }
  409. return true;
  410. }
  411. /**
  412. * Note: This method is for internal use only. Clients should not call this method.
  413. *
  414. * @param element the element
  415. * @return the parent of the element
  416. *
  417. * @noreference This method is not intended to be referenced by clients.
  418. */
  419. protected Object internalGetParent(Object element) {
  420. // try to map resources to the containing package fragment
  421. if (element instanceof IResource) {
  422. IResource parent= ((IResource)element).getParent();
  423. IJavaElement jParent= JavaCore.create(parent);
  424. // http://bugs.eclipse.org/bugs/show_bug.cgi?id=31374
  425. if (jParent != null && jParent.exists())
  426. return jParent;
  427. return parent;
  428. } else if (element instanceof IJavaElement) {
  429. IJavaElement parent= ((IJavaElement) element).getParent();
  430. // for package fragments that are contained in a project package fragment
  431. // we have to skip the package fragment root as the parent.
  432. if (element instanceof IPackageFragment) {
  433. return skipProjectPackageFragmentRoot((IPackageFragmentRoot) parent);
  434. }
  435. return parent;
  436. } else if (element instanceof IJarEntryResource) {
  437. return ((IJarEntryResource) element).getParent();
  438. }
  439. return null;
  440. }
  441. /**
  442. * Utility method to concatenate two arrays.
  443. *
  444. * @param a1 the first array
  445. * @param a2 the second array
  446. * @return the concatenated array
  447. */
  448. protected static Object[] concatenate(Object[] a1, Object[] a2) {
  449. int a1Len= a1.length;
  450. int a2Len= a2.length;
  451. if (a1Len == 0) return a2;
  452. if (a2Len == 0) return a1;
  453. Object[] res= new Object[a1Len + a2Len];
  454. System.arraycopy(a1, 0, res, 0, a1Len);
  455. System.arraycopy(a2, 0, res, a1Len, a2Len);
  456. return res;
  457. }
  458. }