KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > jdt > ui > StandardJavaElementContentProvider


1 /*******************************************************************************
2  * Copyright (c) 2000, 2007 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
13 import java.util.ArrayList JavaDoc;
14 import java.util.List JavaDoc;
15
16 import org.eclipse.core.runtime.CoreException;
17
18 import org.eclipse.core.resources.IFile;
19 import org.eclipse.core.resources.IFolder;
20 import org.eclipse.core.resources.IResource;
21
22 import org.eclipse.jface.viewers.ITreeContentProvider;
23 import org.eclipse.jface.viewers.Viewer;
24
25 import org.eclipse.jdt.core.IClassFile;
26 import org.eclipse.jdt.core.ICompilationUnit;
27 import org.eclipse.jdt.core.IJarEntryResource;
28 import org.eclipse.jdt.core.IJavaElement;
29 import org.eclipse.jdt.core.IJavaElementDelta;
30 import org.eclipse.jdt.core.IJavaModel;
31 import org.eclipse.jdt.core.IJavaProject;
32 import org.eclipse.jdt.core.IPackageFragment;
33 import org.eclipse.jdt.core.IPackageFragmentRoot;
34 import org.eclipse.jdt.core.IParent;
35 import org.eclipse.jdt.core.ISourceReference;
36 import org.eclipse.jdt.core.JavaCore;
37 import org.eclipse.jdt.core.JavaModelException;
38  
39 /**
40  * A base content provider for Java elements. It provides access to the
41  * Java element hierarchy without listening to changes in the Java model.
42  * If updating the presentation on Java model change is required than
43  * clients have to subclass, listen to Java model changes and have to update
44  * the UI using corresponding methods provided by the JFace viewers or their
45  * own UI presentation.
46  * <p>
47  * The following Java element hierarchy is surfaced by this content provider:
48  * <p>
49  * <pre>
50 Java model (<code>IJavaModel</code>)
51    Java project (<code>IJavaProject</code>)
52       package fragment root (<code>IPackageFragmentRoot</code>)
53          package fragment (<code>IPackageFragment</code>)
54             compilation unit (<code>ICompilationUnit</code>)
55             binary class file (<code>IClassFile</code>)
56  * </pre>
57  * </p>
58  * <p>
59  * Note that when the entire Java project is declared to be package fragment root,
60  * the corresponding package fragment root element that normally appears between the
61  * Java project and the package fragments is automatically filtered out.
62  * </p>
63  *
64  * @since 2.0
65  */

66 public class StandardJavaElementContentProvider implements ITreeContentProvider, IWorkingCopyProvider {
67
68     protected static final Object JavaDoc[] NO_CHILDREN= new Object JavaDoc[0];
69     protected boolean fProvideMembers;
70     protected boolean fProvideWorkingCopy;
71     
72     /**
73      * Creates a new content provider. The content provider does not
74      * provide members of compilation units or class files.
75      */

76     public StandardJavaElementContentProvider() {
77         this(false);
78     }
79     
80     /**
81      *@deprecated Use {@link #StandardJavaElementContentProvider(boolean)} instead.
82      * Since 3.0 compilation unit children are always provided as working copies. The Java Model
83      * does not support the 'original' mode anymore.
84      */

85     public StandardJavaElementContentProvider(boolean provideMembers, boolean provideWorkingCopy) {
86         this(provideMembers);
87     }
88     
89     
90     /**
91      * Creates a new <code>StandardJavaElementContentProvider</code>.
92      *
93      * @param provideMembers if <code>true</code> members below compilation units
94      * and class files are provided.
95      */

96     public StandardJavaElementContentProvider(boolean provideMembers) {
97         fProvideMembers= provideMembers;
98         fProvideWorkingCopy= provideMembers;
99     }
100     
101     /**
102      * Returns whether members are provided when asking
103      * for a compilation units or class file for its children.
104      *
105      * @return <code>true</code> if the content provider provides members;
106      * otherwise <code>false</code> is returned
107      */

108     public boolean getProvideMembers() {
109         return fProvideMembers;
110     }
111
112     /**
113      * Sets whether the content provider is supposed to return members
114      * when asking a compilation unit or class file for its children.
115      *
116      * @param b if <code>true</code> then members are provided.
117      * If <code>false</code> compilation units and class files are the
118      * leaves provided by this content provider.
119      */

120     public void setProvideMembers(boolean b) {
121         //hello
122
fProvideMembers= b;
123     }
124     
125     /**
126      * @deprecated Since 3.0 compilation unit children are always provided as working copies. The Java model
127      * does not support the 'original' mode anymore.
128      */

129     public boolean getProvideWorkingCopy() {
130         return fProvideWorkingCopy;
131     }
132
133     /**
134      * @deprecated Since 3.0 compilation unit children are always provided from the working copy. The Java model
135      * offers a unified world and does not support the 'original' mode anymore.
136      */

137     public void setProvideWorkingCopy(boolean b) {
138         fProvideWorkingCopy= b;
139     }
140
141     /* (non-Javadoc)
142      * @see IWorkingCopyProvider#providesWorkingCopies()
143      */

144     public boolean providesWorkingCopies() {
145         return getProvideWorkingCopy();
146     }
147
148     /* (non-Javadoc)
149      * Method declared on IStructuredContentProvider.
150      */

151     public Object JavaDoc[] getElements(Object JavaDoc parent) {
152         return getChildren(parent);
153     }
154     
155     /* (non-Javadoc)
156      * Method declared on IContentProvider.
157      */

158     public void inputChanged(Viewer viewer, Object JavaDoc oldInput, Object JavaDoc newInput) {
159     }
160
161     /* (non-Javadoc)
162      * Method declared on IContentProvider.
163      */

164     public void dispose() {
165     }
166
167     /* (non-Javadoc)
168      * Method declared on ITreeContentProvider.
169      */

170     public Object JavaDoc[] getChildren(Object JavaDoc element) {
171         if (!exists(element))
172             return NO_CHILDREN;
173             
174         try {
175             if (element instanceof IJavaModel)
176                 return getJavaProjects((IJavaModel)element);
177             
178             if (element instanceof IJavaProject)
179                 return getPackageFragmentRoots((IJavaProject)element);
180             
181             if (element instanceof IPackageFragmentRoot)
182                 return getPackageFragmentRootContent((IPackageFragmentRoot)element);
183             
184             if (element instanceof IPackageFragment)
185                 return getPackageContent((IPackageFragment)element);
186                 
187             if (element instanceof IFolder)
188                 return getFolderContent((IFolder)element);
189             
190             if (element instanceof IJarEntryResource) {
191                 return ((IJarEntryResource) element).getChildren();
192             }
193             
194             if (getProvideMembers() && element instanceof ISourceReference && element instanceof IParent) {
195                 return ((IParent)element).getChildren();
196             }
197         } catch (CoreException e) {
198             return NO_CHILDREN;
199         }
200         return NO_CHILDREN;
201     }
202
203     /* (non-Javadoc)
204      * @see ITreeContentProvider
205      */

206     public boolean hasChildren(Object JavaDoc element) {
207         if (getProvideMembers()) {
208             // assume CUs and class files are never empty
209
if (element instanceof ICompilationUnit ||
210                 element instanceof IClassFile) {
211                 return true;
212             }
213         } else {
214             // don't allow to drill down into a compilation unit or class file
215
if (element instanceof ICompilationUnit ||
216                 element instanceof IClassFile ||
217                 element instanceof IFile)
218             return false;
219         }
220             
221         if (element instanceof IJavaProject) {
222             IJavaProject jp= (IJavaProject)element;
223             if (!jp.getProject().isOpen()) {
224                 return false;
225             }
226         }
227         
228         if (element instanceof IParent) {
229             try {
230                 // when we have Java children return true, else we fetch all the children
231
if (((IParent)element).hasChildren())
232                     return true;
233             } catch(JavaModelException e) {
234                 return true;
235             }
236         }
237         Object JavaDoc[] children= getChildren(element);
238         return (children != null) && children.length > 0;
239     }
240      
241     /* (non-Javadoc)
242      * Method declared on ITreeContentProvider.
243      */

244     public Object JavaDoc getParent(Object JavaDoc element) {
245         if (!exists(element))
246             return null;
247         return internalGetParent(element);
248     }
249     
250     /**
251      * Evaluates all children of a given {@link IPackageFragmentRoot}. Clients can override this method.
252      * @param root The root to evaluate the children for.
253      * @return The children of the root
254      * @exception JavaModelException if the package fragment root does not exist or if an
255      * exception occurs while accessing its corresponding resource
256      *
257      * @since 3.3
258      */

259     protected Object JavaDoc[] getPackageFragmentRootContent(IPackageFragmentRoot root) throws JavaModelException {
260         IJavaElement[] fragments= root.getChildren();
261         if (isProjectPackageFragmentRoot(root)) {
262             return fragments;
263         }
264         Object JavaDoc[] nonJavaResources= root.getNonJavaResources();
265         if (nonJavaResources == null)
266             return fragments;
267         return concatenate(fragments, nonJavaResources);
268     }
269     
270     /**
271      * Evaluates all children of a given {@link IJavaProject}. Clients can override this method.
272      * @param project The Java project to evaluate the children for.
273      * @return The children of the project. Typically these are package fragment roots but can also be other elements.
274      * @exception JavaModelException if the Java project does not exist or if an
275      * exception occurs while accessing its corresponding resource
276      */

277     protected Object JavaDoc[] getPackageFragmentRoots(IJavaProject project) throws JavaModelException {
278         if (!project.getProject().isOpen())
279             return NO_CHILDREN;
280             
281         IPackageFragmentRoot[] roots= project.getPackageFragmentRoots();
282         List JavaDoc list= new ArrayList JavaDoc(roots.length);
283         // filter out package fragments that correspond to projects and
284
// replace them with the package fragments directly
285
for (int i= 0; i < roots.length; i++) {
286             IPackageFragmentRoot root= roots[i];
287             if (isProjectPackageFragmentRoot(root)) {
288                 Object JavaDoc[] fragments= getPackageFragmentRootContent(root);
289                 for (int j= 0; j < fragments.length; j++) {
290                     list.add(fragments[j]);
291                 }
292             } else {
293                 list.add(root);
294             }
295         }
296         Object JavaDoc[] resources= project.getNonJavaResources();
297         for (int i= 0; i < resources.length; i++) {
298             list.add(resources[i]);
299         }
300         return list.toArray();
301     }
302
303     /**
304      * Note: This method is for internal use only. Clients should not call this method.
305      */

306     protected Object JavaDoc[] getJavaProjects(IJavaModel jm) throws JavaModelException {
307         return jm.getJavaProjects();
308     }
309     
310     /**
311      * Evaluates all children of a given {@link IPackageFragment}. Clients can override this method.
312      * @param fragment The fragment to evaluate the children for.
313      * @return The children of the given package fragment.
314      * @exception JavaModelException if the package fragment does not exist or if an
315      * exception occurs while accessing its corresponding resource
316      *
317      * @since 3.3
318      */

319     protected Object JavaDoc[] getPackageContent(IPackageFragment fragment) throws JavaModelException {
320         if (fragment.getKind() == IPackageFragmentRoot.K_SOURCE) {
321             return concatenate(fragment.getCompilationUnits(), fragment.getNonJavaResources());
322         }
323         return concatenate(fragment.getClassFiles(), fragment.getNonJavaResources());
324     }
325     
326     /**
327      * Evaluates all children of a given {@link IFolder}. Clients can override this method.
328      * @param folder The folder to evaluate the children for.
329      * @return The children of the given package fragment.
330      * @exception CoreException if the folder does not exist.
331      *
332      * @since 3.3
333      */

334     protected Object JavaDoc[] getFolderContent(IFolder folder) throws CoreException {
335         IResource[] members= folder.members();
336         IJavaProject javaProject= JavaCore.create(folder.getProject());
337         if (javaProject == null || !javaProject.exists())
338             return members;
339         boolean isFolderOnClasspath = javaProject.isOnClasspath(folder);
340         List JavaDoc nonJavaResources= new ArrayList JavaDoc();
341         // Can be on classpath but as a member of non-java resource folder
342
for (int i= 0; i < members.length; i++) {
343             IResource member= members[i];
344             // A resource can also be a java element
345
// in the case of exclusion and inclusion filters.
346
// We therefore exclude Java elements from the list
347
// of non-Java resources.
348
if (isFolderOnClasspath) {
349                 if (javaProject.findPackageFragmentRoot(member.getFullPath()) == null) {
350                     nonJavaResources.add(member);
351                 }
352             } else if (!javaProject.isOnClasspath(member)) {
353                 nonJavaResources.add(member);
354             }
355         }
356         return nonJavaResources.toArray();
357     }
358     
359     /**
360      * Note: This method is for internal use only. Clients should not call this method.
361      */

362     protected boolean isClassPathChange(IJavaElementDelta delta) {
363         
364         // need to test the flags only for package fragment roots
365
if (delta.getElement().getElementType() != IJavaElement.PACKAGE_FRAGMENT_ROOT)
366             return false;
367         
368         int flags= delta.getFlags();
369         return (delta.getKind() == IJavaElementDelta.CHANGED &&
370             ((flags & IJavaElementDelta.F_ADDED_TO_CLASSPATH) != 0) ||
371              ((flags & IJavaElementDelta.F_REMOVED_FROM_CLASSPATH) != 0) ||
372              ((flags & IJavaElementDelta.F_REORDER) != 0));
373     }
374     
375     /**
376      * Note: This method is for internal use only. Clients should not call this method.
377      */

378     protected Object JavaDoc skipProjectPackageFragmentRoot(IPackageFragmentRoot root) {
379         if (isProjectPackageFragmentRoot(root))
380             return root.getParent();
381         return root;
382     }
383     
384     /**
385      * Note: This method is for internal use only. Clients should not call this method.
386      */

387     protected boolean isPackageFragmentEmpty(IJavaElement element) throws JavaModelException {
388         if (element instanceof IPackageFragment) {
389             IPackageFragment fragment= (IPackageFragment)element;
390             if (fragment.exists() && !(fragment.hasChildren() || fragment.getNonJavaResources().length > 0) && fragment.hasSubpackages())
391                 return true;
392         }
393         return false;
394     }
395
396     /**
397      * Note: This method is for internal use only. Clients should not call this method.
398      */

399     protected boolean isProjectPackageFragmentRoot(IPackageFragmentRoot root) {
400         IJavaProject javaProject= root.getJavaProject();
401         return javaProject != null && javaProject.getPath().equals(root.getPath());
402     }
403     
404     /**
405      * Note: This method is for internal use only. Clients should not call this method.
406      */

407     protected boolean exists(Object JavaDoc element) {
408         if (element == null) {
409             return false;
410         }
411         if (element instanceof IResource) {
412             return ((IResource)element).exists();
413         }
414         if (element instanceof IJavaElement) {
415             return ((IJavaElement)element).exists();
416         }
417         return true;
418     }
419     
420     /**
421      * Note: This method is for internal use only. Clients should not call this method.
422      */

423     protected Object JavaDoc internalGetParent(Object JavaDoc element) {
424
425         // try to map resources to the containing package fragment
426
if (element instanceof IResource) {
427             IResource parent= ((IResource)element).getParent();
428             IJavaElement jParent= JavaCore.create(parent);
429             // http://bugs.eclipse.org/bugs/show_bug.cgi?id=31374
430
if (jParent != null && jParent.exists())
431                 return jParent;
432             return parent;
433         } else if (element instanceof IJavaElement) {
434             IJavaElement parent= ((IJavaElement) element).getParent();
435             // for package fragments that are contained in a project package fragment
436
// we have to skip the package fragment root as the parent.
437
if (element instanceof IPackageFragment) {
438                 return skipProjectPackageFragmentRoot((IPackageFragmentRoot) parent);
439             }
440             return parent;
441         } else if (element instanceof IJarEntryResource) {
442             return ((IJarEntryResource) element).getParent();
443         }
444         return null;
445     }
446         
447     /**
448      * Note: This method is for internal use only. Clients should not call this method.
449      */

450     protected static Object JavaDoc[] concatenate(Object JavaDoc[] a1, Object JavaDoc[] a2) {
451         int a1Len= a1.length;
452         int a2Len= a2.length;
453         if (a1Len == 0) return a2;
454         if (a2Len == 0) return a1;
455         Object JavaDoc[] res= new Object JavaDoc[a1Len + a2Len];
456         System.arraycopy(a1, 0, res, 0, a1Len);
457         System.arraycopy(a2, 0, res, a1Len, a2Len);
458         return res;
459     }
460
461
462 }
463
Popular Tags