KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > jdt > internal > ui > packageview > PackageFragmentProvider


1 /*******************************************************************************
2  * Copyright (c) 2000, 2006 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.packageview;
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.IFolder;
19 import org.eclipse.core.resources.IResource;
20
21 import org.eclipse.swt.widgets.Control;
22 import org.eclipse.swt.widgets.Display;
23
24 import org.eclipse.jface.util.IPropertyChangeListener;
25 import org.eclipse.jface.util.PropertyChangeEvent;
26 import org.eclipse.jface.viewers.TreeViewer;
27 import org.eclipse.jface.viewers.Viewer;
28
29 import org.eclipse.jdt.core.ElementChangedEvent;
30 import org.eclipse.jdt.core.IJavaElement;
31 import org.eclipse.jdt.core.IJavaElementDelta;
32 import org.eclipse.jdt.core.IJavaProject;
33 import org.eclipse.jdt.core.IPackageFragment;
34 import org.eclipse.jdt.core.IPackageFragmentRoot;
35 import org.eclipse.jdt.core.JavaCore;
36 import org.eclipse.jdt.core.JavaModelException;
37
38 import org.eclipse.jdt.ui.PreferenceConstants;
39
40 import org.eclipse.jdt.internal.ui.JavaPlugin;
41
42 /**
43  * Content provider which provides package fragments for hierarchical
44  * Package Explorer layout.
45  *
46  * @since 2.1
47  */

48 public class PackageFragmentProvider implements IPropertyChangeListener {
49
50     private TreeViewer fViewer;
51     private boolean fFoldPackages;
52     
53     public PackageFragmentProvider() {
54         fFoldPackages= arePackagesFoldedInHierarchicalLayout();
55         JavaPlugin.getDefault().getPreferenceStore().addPropertyChangeListener(this);
56     }
57     
58     /*
59      * @see org.eclipse.jface.viewers.ITreeContentProvider#getChildren(Object)
60      */

61     public Object JavaDoc[] getChildren(Object JavaDoc parentElement) {
62         try {
63             if (parentElement instanceof IFolder) {
64                 IResource[] resources= ((IFolder) parentElement).members();
65                 return filter(getFolders(resources)).toArray();
66             } else if (parentElement instanceof IJavaElement) {
67                 IJavaElement iJavaElement= (IJavaElement) parentElement;
68                 int type= iJavaElement.getElementType();
69     
70                 switch (type) {
71                     case IJavaElement.JAVA_PROJECT: {
72                         IJavaProject project= (IJavaProject) iJavaElement;
73                         
74                         IPackageFragmentRoot root= project.findPackageFragmentRoot(project.getPath());
75                         if (root != null) {
76                             List JavaDoc children= getTopLevelChildren(root);
77                             return filter(children).toArray();
78                         }
79                         break;
80                     }
81                     case IJavaElement.PACKAGE_FRAGMENT_ROOT: {
82                         IPackageFragmentRoot root= (IPackageFragmentRoot) parentElement;
83                         if (root.exists()) {
84                             return filter(getTopLevelChildren(root)).toArray();
85                         }
86                         break;
87                     }
88                     case IJavaElement.PACKAGE_FRAGMENT: {
89                         IPackageFragment packageFragment = (IPackageFragment) parentElement;
90                         if (!packageFragment.isDefaultPackage()) {
91                             IPackageFragmentRoot root= (IPackageFragmentRoot) packageFragment.getParent();
92                             List JavaDoc children = getPackageChildren(root, packageFragment);
93                             return filter(children).toArray();
94                         }
95                         break;
96                     }
97                     default :
98                         // do nothing
99
}
100             }
101         } catch (CoreException e) {
102             JavaPlugin.log(e);
103         }
104         return new Object JavaDoc[0];
105     }
106     
107     private List JavaDoc filter(List JavaDoc children) throws JavaModelException {
108         if (fFoldPackages) {
109             int size= children.size();
110             for (int i = 0; i < size; i++) {
111                 Object JavaDoc curr= children.get(i);
112                 if (curr instanceof IPackageFragment) {
113                     IPackageFragment fragment = (IPackageFragment) curr;
114                     if (!fragment.isDefaultPackage() && isEmpty(fragment)) {
115                         IPackageFragment collapsed= getCollapsed(fragment);
116                         if (collapsed != null) {
117                             children.set(i, collapsed); // replace with collapsed
118
}
119                     }
120                 }
121             }
122         }
123         return children;
124     }
125     
126     private IPackageFragment getCollapsed(IPackageFragment pack) throws JavaModelException {
127         IJavaElement[] children= ((IPackageFragmentRoot) pack.getParent()).getChildren();
128         IPackageFragment child= getSinglePackageChild(pack, children);
129         while (child != null && isEmpty(child)) {
130             IPackageFragment collapsed= getSinglePackageChild(child, children);
131             if (collapsed == null) {
132                 return child;
133             }
134             child= collapsed;
135         }
136         return child;
137     }
138         
139     private boolean isEmpty(IPackageFragment fragment) throws JavaModelException {
140         return !fragment.containsJavaResources() && fragment.getNonJavaResources().length == 0;
141     }
142     
143     private static IPackageFragment getSinglePackageChild(IPackageFragment fragment, IJavaElement[] children) {
144         String JavaDoc prefix= fragment.getElementName() + '.';
145         int prefixLen= prefix.length();
146         IPackageFragment found= null;
147         for (int i= 0; i < children.length; i++) {
148             IJavaElement element= children[i];
149             String JavaDoc name= element.getElementName();
150             if (name.startsWith(prefix) && name.length() > prefixLen && name.indexOf('.', prefixLen) == -1) {
151                 if (found == null) {
152                     found= (IPackageFragment) element;
153                 } else {
154                     return null;
155                 }
156             }
157         }
158         return found;
159     }
160     
161     
162     private static List JavaDoc getPackageChildren(IPackageFragmentRoot parent, IPackageFragment fragment) throws JavaModelException {
163         IJavaElement[] children= parent.getChildren();
164         ArrayList JavaDoc list= new ArrayList JavaDoc(children.length);
165         String JavaDoc prefix= fragment.getElementName() + '.';
166         int prefixLen= prefix.length();
167         for (int i= 0; i < children.length; i++) {
168             IJavaElement element= children[i];
169             if (element instanceof IPackageFragment) { // see bug 134256
170
String JavaDoc name= element.getElementName();
171                 if (name.startsWith(prefix) && name.length() > prefixLen && name.indexOf('.', prefixLen) == -1) {
172                     list.add(element);
173                 }
174             }
175         }
176         return list;
177     }
178     
179     private static List JavaDoc getTopLevelChildren(IPackageFragmentRoot root) throws JavaModelException {
180         IJavaElement[] elements= root.getChildren();
181         ArrayList JavaDoc topLevelElements= new ArrayList JavaDoc(elements.length);
182         for (int i= 0; i < elements.length; i++) {
183             IJavaElement iJavaElement= elements[i];
184             //if the name of the PackageFragment is the top level package it will contain no "." separators
185
if (iJavaElement instanceof IPackageFragment && iJavaElement.getElementName().indexOf('.')==-1) {
186                 topLevelElements.add(iJavaElement);
187             }
188         }
189         return topLevelElements;
190     }
191
192     private List JavaDoc getFolders(IResource[] resources) throws JavaModelException {
193         List JavaDoc list= new ArrayList JavaDoc(resources.length);
194         for (int i= 0; i < resources.length; i++) {
195             IResource resource= resources[i];
196             if (resource instanceof IFolder) {
197                 IFolder folder= (IFolder) resource;
198                 IJavaElement element= JavaCore.create(folder);
199                 if (element instanceof IPackageFragment) {
200                     list.add(element);
201                 }
202             }
203         }
204         return list;
205     }
206
207
208     /*
209      * @see org.eclipse.jface.viewers.ITreeContentProvider#getParent(Object)
210      */

211     public Object JavaDoc getParent(Object JavaDoc element) {
212
213         if (element instanceof IPackageFragment) {
214             IPackageFragment frag = (IPackageFragment) element;
215             //@Changed: a fix, before: if(frag.exists() && isEmpty(frag))
216

217             return filterParent(getActualParent(frag));
218         }
219         return null;
220     }
221
222     private Object JavaDoc getActualParent(IPackageFragment fragment) {
223         try {
224
225             if (fragment.exists()) {
226                 IJavaElement parent = fragment.getParent();
227
228                 if ((parent instanceof IPackageFragmentRoot) && parent.exists()) {
229                     IPackageFragmentRoot root = (IPackageFragmentRoot) parent;
230                     if (root.isArchive()) {
231                         return findNextLevelParentByElementName(fragment);
232                     } else {
233
234                         IResource resource = fragment.getUnderlyingResource();
235                         if ((resource != null) && (resource instanceof IFolder)) {
236                             IFolder folder = (IFolder) resource;
237                             IResource res = folder.getParent();
238
239                             IJavaElement el = JavaCore.create(res);
240                             if (el != null) {
241                                 return el;
242                             } else {
243                                 return res;
244                             }
245                         }
246                     }
247                     return parent;
248                 }
249             }
250
251         } catch (JavaModelException e) {
252             JavaPlugin.log(e);
253         }
254         return null;
255     }
256     
257     private Object JavaDoc filterParent(Object JavaDoc parent) {
258         if (fFoldPackages && (parent!=null)) {
259             try {
260                 if (parent instanceof IPackageFragment) {
261                     IPackageFragment fragment = (IPackageFragment) parent;
262                     if (isEmpty(fragment) && hasSingleChild(fragment)) {
263                         return filterParent(getActualParent(fragment));
264                     }
265                 }
266             } catch (JavaModelException e) {
267                 JavaPlugin.log(e);
268             }
269         }
270         return parent;
271     }
272
273     private boolean hasSingleChild(IPackageFragment fragment) {
274         return getChildren(fragment).length==1;
275     }
276
277
278     private Object JavaDoc findNextLevelParentByElementName(IPackageFragment child) {
279         String JavaDoc name= child.getElementName();
280         
281         int index= name.lastIndexOf('.');
282         if (index != -1) {
283             String JavaDoc realParentName= name.substring(0, index);
284             IPackageFragment element= ((IPackageFragmentRoot) child.getParent()).getPackageFragment(realParentName);
285             if (element.exists()) {
286                 return element;
287             }
288         }
289         return child.getParent();
290     }
291
292
293     /*
294      * @see org.eclipse.jface.viewers.ITreeContentProvider#hasChildren(Object)
295      */

296     public boolean hasChildren(Object JavaDoc element) {
297         
298         if (element instanceof IPackageFragment) {
299             IPackageFragment fragment= (IPackageFragment) element;
300             if(fragment.isDefaultPackage())
301                 return false;
302         }
303         return getChildren(element).length > 0;
304     }
305
306     /*
307      * @see org.eclipse.jface.viewers.IStructuredContentProvider#getElements(Object)
308      */

309     public Object JavaDoc[] getElements(Object JavaDoc inputElement) {
310         return getChildren(inputElement);
311     }
312
313     /*
314      * @see org.eclipse.jface.viewers.IContentProvider#dispose()
315      */

316     public void dispose() {
317         JavaPlugin.getDefault().getPreferenceStore().removePropertyChangeListener(this);
318     }
319
320     /**
321      * Called when the view is closed and opened.
322      *
323      * @see org.eclipse.jface.viewers.IContentProvider#inputChanged(Viewer, Object, Object)
324      */

325     public void inputChanged(Viewer viewer, Object JavaDoc oldInput, Object JavaDoc newInput) {
326         fViewer= (TreeViewer)viewer;
327     }
328     
329     /*
330      * @see org.eclipse.jdt.core.IElementChangedListener#elementChanged(org.eclipse.jdt.core.ElementChangedEvent)
331      */

332     public void elementChanged(ElementChangedEvent event) {
333         processDelta(event.getDelta());
334     }
335     
336     public void processDelta(IJavaElementDelta delta) {
337
338         int kind = delta.getKind();
339         final IJavaElement element = delta.getElement();
340
341         if (element instanceof IPackageFragment) {
342
343             if (kind == IJavaElementDelta.REMOVED) {
344
345                 postRunnable(new Runnable JavaDoc() {
346                     public void run() {
347                         Control ctrl = fViewer.getControl();
348                         if (ctrl != null && !ctrl.isDisposed()) {
349                             if (!fFoldPackages)
350                                  fViewer.remove(element);
351                             else
352                                 refreshGrandParent(element);
353                         }
354                     }
355                 });
356                 return;
357
358             } else if (kind == IJavaElementDelta.ADDED) {
359
360                 final Object JavaDoc parent = getParent(element);
361                 if (parent != null) {
362                     postRunnable(new Runnable JavaDoc() {
363                         public void run() {
364                             Control ctrl = fViewer.getControl();
365                             if (ctrl != null && !ctrl.isDisposed()) {
366                                 if (!fFoldPackages)
367                                      fViewer.add(parent, element);
368                                 else
369                                     refreshGrandParent(element);
370                             }
371                         }
372                     });
373                 }
374                 return;
375             }
376         }
377     }
378
379     // XXX: needs to be revisited - might be a performance issue
380
private void refreshGrandParent(final IJavaElement element) {
381         if (element instanceof IPackageFragment) {
382             Object JavaDoc gp= getGrandParent((IPackageFragment)element);
383             if (gp instanceof IJavaElement) {
384                 IJavaElement el = (IJavaElement) gp;
385                 if(el.exists())
386                     fViewer.refresh(gp);
387             } else if (gp instanceof IFolder) {
388                 IFolder folder= (IFolder)gp;
389                 if (folder.exists())
390                     fViewer.refresh(folder);
391             }
392         }
393     }
394
395     private Object JavaDoc getGrandParent(IPackageFragment element) {
396
397         Object JavaDoc parent= findNextLevelParentByElementName(element);
398         if (parent instanceof IPackageFragmentRoot) {
399             IPackageFragmentRoot root= (IPackageFragmentRoot) parent;
400             if(isRootProject(root))
401                 return root.getJavaProject();
402             else return root;
403         }
404
405         Object JavaDoc grandParent= getParent(parent);
406         if(grandParent==null){
407             return parent;
408         }
409         return grandParent;
410     }
411
412     private boolean isRootProject(IPackageFragmentRoot root) {
413         if (IPackageFragmentRoot.DEFAULT_PACKAGEROOT_PATH.equals(root.getElementName()))
414             return true;
415         return false;
416     }
417     
418     private void postRunnable(final Runnable JavaDoc r) {
419         Control ctrl= fViewer.getControl();
420         if (ctrl != null && !ctrl.isDisposed()) {
421
422             Display currentDisplay= Display.getCurrent();
423             if (currentDisplay != null && currentDisplay.equals(ctrl.getDisplay()))
424                 ctrl.getDisplay().syncExec(r);
425             else
426                 ctrl.getDisplay().asyncExec(r);
427         }
428     }
429
430     /*
431      * @see org.eclipse.jface.util.IPropertyChangeListener#propertyChange(org.eclipse.jface.util.PropertyChangeEvent)
432      */

433     public void propertyChange(PropertyChangeEvent event) {
434         if (arePackagesFoldedInHierarchicalLayout() != fFoldPackages){
435             fFoldPackages= arePackagesFoldedInHierarchicalLayout();
436             if (fViewer != null && !fViewer.getControl().isDisposed()) {
437                 fViewer.getControl().setRedraw(false);
438                 Object JavaDoc[] expandedObjects= fViewer.getExpandedElements();
439                 fViewer.refresh();
440                 fViewer.setExpandedElements(expandedObjects);
441                 fViewer.getControl().setRedraw(true);
442             }
443         }
444     }
445
446     private boolean arePackagesFoldedInHierarchicalLayout(){
447         return PreferenceConstants.getPreferenceStore().getBoolean(PreferenceConstants.APPEARANCE_FOLD_PACKAGES_IN_PACKAGE_EXPLORER);
448     }
449 }
450
Popular Tags