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