KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > jdt > internal > ui > browsing > PackagesViewHierarchicalContentProvider


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.browsing;
12
13 import java.util.ArrayList JavaDoc;
14 import java.util.Arrays JavaDoc;
15 import java.util.Iterator JavaDoc;
16 import java.util.List JavaDoc;
17
18 import org.eclipse.core.runtime.CoreException;
19
20 import org.eclipse.core.resources.IFolder;
21 import org.eclipse.core.resources.IResource;
22
23 import org.eclipse.swt.widgets.Control;
24 import org.eclipse.swt.widgets.Display;
25
26 import org.eclipse.jface.viewers.ITreeContentProvider;
27 import org.eclipse.jface.viewers.StructuredViewer;
28 import org.eclipse.jface.viewers.TreeViewer;
29
30 import org.eclipse.jdt.core.ICompilationUnit;
31 import org.eclipse.jdt.core.IJavaElement;
32 import org.eclipse.jdt.core.IJavaElementDelta;
33 import org.eclipse.jdt.core.IJavaProject;
34 import org.eclipse.jdt.core.IPackageFragment;
35 import org.eclipse.jdt.core.IPackageFragmentRoot;
36 import org.eclipse.jdt.core.JavaCore;
37 import org.eclipse.jdt.core.JavaModelException;
38
39 import org.eclipse.jdt.internal.ui.JavaPlugin;
40
41 /**
42  * Tree content provider for the hierarchical layout in the packages view.
43  * <p>
44  * XXX: The standard Java browsing part content provider needs and calls
45  * the browsing part/view. This class currently doesn't need to do so
46  * but might be required to later.
47  * </p>
48  */

49 class PackagesViewHierarchicalContentProvider extends LogicalPackagesProvider implements ITreeContentProvider {
50
51     public PackagesViewHierarchicalContentProvider(StructuredViewer viewer){
52         super(viewer);
53     }
54
55     /*
56      * @see org.eclipse.jface.viewers.ITreeContentProvider#getChildren(Object)
57      */

58     public Object JavaDoc[] getChildren(Object JavaDoc parentElement) {
59         try {
60             if (parentElement instanceof IJavaElement) {
61                 IJavaElement iJavaElement= (IJavaElement) parentElement;
62                 int type= iJavaElement.getElementType();
63
64                 switch (type) {
65                     case IJavaElement.JAVA_PROJECT :
66                         {
67
68                             //create new element mapping
69
fMapToLogicalPackage.clear();
70                             fMapToPackageFragments.clear();
71                             IJavaProject project= (IJavaProject) parentElement;
72
73                             IPackageFragment[] topLevelChildren= getTopLevelChildrenByElementName(project.getPackageFragments());
74                             List JavaDoc list= new ArrayList JavaDoc();
75                             for (int i= 0; i < topLevelChildren.length; i++) {
76                                 IPackageFragment fragment= topLevelChildren[i];
77
78                                 IJavaElement el= fragment.getParent();
79                                 if (el instanceof IPackageFragmentRoot) {
80                                     IPackageFragmentRoot root= (IPackageFragmentRoot) el;
81                                     if (!root.isArchive() || !root.isExternal())
82                                         list.add(fragment);
83                                 }
84                             }
85                             
86                             IPackageFragmentRoot[] packageFragmentRoots= project.getPackageFragmentRoots();
87                             List JavaDoc folders= new ArrayList JavaDoc();
88                             for (int i= 0; i < packageFragmentRoots.length; i++) {
89                                 IPackageFragmentRoot root= packageFragmentRoots[i];
90                                 IResource resource= root.getUnderlyingResource();
91                                 if (resource != null && resource instanceof IFolder) {
92                                     folders.addAll(getFolders(((IFolder)resource).members()));
93                                 }
94                             }
95                             
96                             Object JavaDoc[] logicalPackages= combineSamePackagesIntoLogialPackages((IPackageFragment[]) list.toArray(new IPackageFragment[list.size()]));
97                             if (folders.size() > 0) {
98                                 if (logicalPackages.length > 0)
99                                     folders.addAll(Arrays.asList(logicalPackages));
100                                 return folders.toArray();
101                             } else {
102                                 return logicalPackages;
103                             }
104                         }
105
106                     case IJavaElement.PACKAGE_FRAGMENT_ROOT :
107                         {
108                             IPackageFragmentRoot root= (IPackageFragmentRoot) parentElement;
109
110                             //create new element mapping
111
fMapToLogicalPackage.clear();
112                             fMapToPackageFragments.clear();
113                             IResource resource= root.getUnderlyingResource();
114                             if (root.isArchive()) {
115                                 IPackageFragment[] fragments= new IPackageFragment[0];
116                                 IJavaElement[] els= root.getChildren();
117                                 fragments= getTopLevelChildrenByElementName(els);
118                                 addFragmentsToMap(fragments);
119                                 return fragments;
120
121                             } else if (resource != null && resource instanceof IFolder) {
122                                 List JavaDoc children= getFoldersAndElements(((IFolder)resource).members());
123                                 
124                                 IPackageFragment defaultPackage= root.getPackageFragment(""); //$NON-NLS-1$
125
if(defaultPackage.exists())
126                                     children.add(defaultPackage);
127                                 
128                                 addFragmentsToMap(children);
129                                 return children.toArray();
130                             } else {
131                                 return NO_CHILDREN;
132                             }
133                         }
134
135                     case IJavaElement.PACKAGE_FRAGMENT :
136                         {
137                             IPackageFragment packageFragment= (IPackageFragment) parentElement;
138                             if (packageFragment.isDefaultPackage())
139                                 return NO_CHILDREN;
140                             
141                             IPackageFragmentRoot parent= (IPackageFragmentRoot) packageFragment.getParent();
142                             IPackageFragment[] fragments= findNextLevelChildrenByElementName(parent, packageFragment);
143                             
144                             addFragmentsToMap(fragments);
145                             
146                             Object JavaDoc[] nonJavaResources= packageFragment.getNonJavaResources();
147                             if (nonJavaResources.length == 0) {
148                                 return fragments;
149                             }
150                             ArrayList JavaDoc combined= new ArrayList JavaDoc();
151                             combined.addAll(Arrays.asList(fragments));
152                             for (int i= 0; i < nonJavaResources.length; i++) {
153                                 Object JavaDoc curr= nonJavaResources[i];
154                                 if (curr instanceof IFolder) {
155                                     combined.add(curr);
156                                 }
157                             }
158                             return combined.toArray();
159                         }
160                 }
161
162             //@Improve: rewrite using concatenate
163
} else if (parentElement instanceof LogicalPackage) {
164
165                 List JavaDoc children= new ArrayList JavaDoc();
166                 LogicalPackage logicalPackage= (LogicalPackage) parentElement;
167                 IPackageFragment[] elements= logicalPackage.getFragments();
168                 for (int i= 0; i < elements.length; i++) {
169                     IPackageFragment fragment= elements[i];
170                     IPackageFragment[] objects= findNextLevelChildrenByElementName((IPackageFragmentRoot) fragment.getParent(), fragment);
171                     children.addAll(Arrays.asList(objects));
172                 }
173                 return combineSamePackagesIntoLogialPackages((IPackageFragment[]) children.toArray(new IPackageFragment[children.size()]));
174             } else if (parentElement instanceof IFolder) {
175                 IFolder folder= (IFolder)parentElement;
176                 IResource[] resources= folder.members();
177                 List JavaDoc children = getFoldersAndElements(resources);
178                 addFragmentsToMap(children);
179                 return children.toArray();
180             }
181
182         } catch (JavaModelException e) {
183             return NO_CHILDREN;
184         } catch (CoreException e) {
185             return NO_CHILDREN;
186         }
187         return NO_CHILDREN;
188     }
189
190     private void addFragmentsToMap(List JavaDoc elements) {
191         List JavaDoc packageFragments= new ArrayList JavaDoc();
192         for (Iterator JavaDoc iter= elements.iterator(); iter.hasNext();) {
193             Object JavaDoc elem= iter.next();
194             if (elem instanceof IPackageFragment)
195                 packageFragments.add(elem);
196         }
197         addFragmentsToMap((IPackageFragment[])packageFragments.toArray(new IPackageFragment[packageFragments.size()]));
198     }
199
200     private List JavaDoc getFoldersAndElements(IResource[] resources) throws CoreException {
201         List JavaDoc list= new ArrayList JavaDoc();
202         for (int i= 0; i < resources.length; i++) {
203             IResource resource= resources[i];
204             
205             if (resource instanceof IFolder) {
206                 IFolder folder= (IFolder) resource;
207                 IJavaElement element= JavaCore.create(folder);
208                 
209                 if (element instanceof IPackageFragment) {
210                     list.add(element);
211                 } else {
212                     list.add(folder);
213                 }
214             }
215         }
216         return list;
217     }
218     
219     private List JavaDoc getFolders(IResource[] resources) throws CoreException {
220         List JavaDoc list= new ArrayList JavaDoc();
221         for (int i= 0; i < resources.length; i++) {
222             IResource resource= resources[i];
223             
224             if (resource instanceof IFolder) {
225                 IFolder folder= (IFolder) resource;
226                 IJavaElement element= JavaCore.create(folder);
227                 
228                 if (element == null) {
229                     list.add(folder);
230                 }
231             }
232         }
233         return list;
234     }
235
236     private IPackageFragment[] findNextLevelChildrenByElementName(IPackageFragmentRoot parent, IPackageFragment fragment) {
237         List JavaDoc list= new ArrayList JavaDoc();
238         try {
239
240             IJavaElement[] children= parent.getChildren();
241             String JavaDoc fragmentname= fragment.getElementName();
242             for (int i= 0; i < children.length; i++) {
243                 IJavaElement element= children[i];
244                 if (element instanceof IPackageFragment) {
245                     IPackageFragment frag= (IPackageFragment) element;
246
247                     String JavaDoc name= element.getElementName();
248                     if (name.length() > fragmentname.length() && name.charAt(fragmentname.length()) == '.' && frag.exists() && !IPackageFragment.DEFAULT_PACKAGE_NAME.equals(fragmentname) && name.startsWith(fragmentname) && !name.equals(fragmentname)) {
249                         String JavaDoc tail= name.substring(fragmentname.length() + 1);
250                         if (!IPackageFragment.DEFAULT_PACKAGE_NAME.equals(tail) && tail.indexOf('.') == -1) {
251                             list.add(frag);
252                         }
253                     }
254                 }
255             }
256
257         } catch (JavaModelException e) {
258             JavaPlugin.log(e);
259         }
260         return (IPackageFragment[]) list.toArray(new IPackageFragment[list.size()]);
261     }
262
263     private IPackageFragment[] getTopLevelChildrenByElementName(IJavaElement[] elements){
264         List JavaDoc topLevelElements= new ArrayList JavaDoc();
265         for (int i= 0; i < elements.length; i++) {
266             IJavaElement iJavaElement= elements[i];
267             //if the name of the PackageFragment is the top level package it will contain no "." separators
268
if (iJavaElement instanceof IPackageFragment && iJavaElement.getElementName().indexOf('.')==-1){
269                 topLevelElements.add(iJavaElement);
270             }
271         }
272         return (IPackageFragment[]) topLevelElements.toArray(new IPackageFragment[topLevelElements.size()]);
273     }
274
275     /*
276      * @see org.eclipse.jface.viewers.ITreeContentProvider#getParent(Object)
277      */

278     public Object JavaDoc getParent(Object JavaDoc element) {
279
280         try {
281             if (element instanceof IPackageFragment) {
282                 IPackageFragment fragment= (IPackageFragment) element;
283                 if(!fragment.exists())
284                     return null;
285                 Object JavaDoc parent= getHierarchicalParent(fragment);
286                 if(parent instanceof IPackageFragment) {
287                     IPackageFragment pkgFragment= (IPackageFragment)parent;
288                     LogicalPackage logicalPkg= findLogicalPackage(pkgFragment);
289                     if (logicalPkg != null)
290                         return logicalPkg;
291                     else {
292                         LogicalPackage lp= createLogicalPackage(pkgFragment);
293                         if(lp == null)
294                             return pkgFragment;
295                         else return lp;
296                     }
297                 }
298                 return parent;
299
300             } else if(element instanceof LogicalPackage){
301                 LogicalPackage el= (LogicalPackage) element;
302                 IPackageFragment fragment= el.getFragments()[0];
303                 Object JavaDoc parent= getHierarchicalParent(fragment);
304
305                 if(parent instanceof IPackageFragment){
306                     IPackageFragment pkgFragment= (IPackageFragment) parent;
307                     LogicalPackage logicalPkg= findLogicalPackage(pkgFragment);
308                     if (logicalPkg != null)
309                         return logicalPkg;
310                     else {
311                         LogicalPackage lp= createLogicalPackage(pkgFragment);
312                         if(lp == null)
313                             return pkgFragment;
314                         else return lp;
315                     }
316                 } else
317                     return fragment.getJavaProject();
318             } else if (element instanceof IFolder) {
319                 IFolder folder = (IFolder) element;
320                 IResource res = folder.getParent();
321
322                 IJavaElement el = JavaCore.create(res);
323                 if (el != null) {
324                     return el;
325                 } else {
326                     return res;
327                 }
328             }
329
330         } catch (JavaModelException e) {
331             JavaPlugin.log(e);
332         }
333         return null;
334     }
335
336     /*
337      * Check if the given IPackageFragment should be the member of a
338      * LogicalPackage and if so creates the LogicalPackage and adds it to the
339      * map.
340      */

341     private LogicalPackage createLogicalPackage(IPackageFragment pkgFragment) {
342         if(!fInputIsProject)
343             return null;
344
345         List JavaDoc fragments= new ArrayList JavaDoc();
346         try {
347             IPackageFragmentRoot[] roots= pkgFragment.getJavaProject().getPackageFragmentRoots();
348             for (int i= 0; i < roots.length; i++) {
349                 IPackageFragmentRoot root= roots[i];
350                 IPackageFragment fragment= root.getPackageFragment(pkgFragment.getElementName());
351                 if(fragment.exists() && !fragment.equals(pkgFragment))
352                     fragments.add(fragment);
353             }
354             if(!fragments.isEmpty()) {
355                 LogicalPackage logicalPackage= new LogicalPackage(pkgFragment);
356                 fMapToLogicalPackage.put(getKey(pkgFragment), logicalPackage);
357                 Iterator JavaDoc iter= fragments.iterator();
358                 while(iter.hasNext()){
359                     IPackageFragment f= (IPackageFragment)iter.next();
360                     if(logicalPackage.belongs(f)){
361                         logicalPackage.add(f);
362                         fMapToLogicalPackage.put(getKey(f), logicalPackage);
363                     }
364                 }
365
366                 return logicalPackage;
367             }
368
369         } catch (JavaModelException e) {
370             JavaPlugin.log(e);
371         }
372
373         return null;
374     }
375
376     private Object JavaDoc getHierarchicalParent(IPackageFragment fragment) throws JavaModelException {
377         IJavaElement parent= fragment.getParent();
378
379         if ((parent instanceof IPackageFragmentRoot) && parent.exists()) {
380             IPackageFragmentRoot root= (IPackageFragmentRoot) parent;
381             if (root.isArchive() || !fragment.exists()) {
382                 return findNextLevelParentByElementName(fragment);
383             } else {
384                 IResource resource= fragment.getUnderlyingResource();
385                 if ((resource != null) && (resource instanceof IFolder)) {
386                     IFolder folder= (IFolder) resource;
387                     IResource res= folder.getParent();
388
389                     IJavaElement el= JavaCore.create(res);
390                     if (el != null) {
391                         return el;
392                     } else {
393                         return res;
394                     }
395                 }
396             }
397         }
398         return parent;
399     }
400
401     private Object JavaDoc findNextLevelParentByElementName(IPackageFragment child) {
402         String JavaDoc name= child.getElementName();
403         
404         int index= name.lastIndexOf('.');
405         if (index != -1) {
406             String JavaDoc realParentName= name.substring(0, index);
407             IPackageFragment element= ((IPackageFragmentRoot) child.getParent()).getPackageFragment(realParentName);
408             if (element.exists()) {
409                 return element;
410             }
411         }
412         return child.getParent();
413     }
414
415
416     /*
417      * @see org.eclipse.jface.viewers.ITreeContentProvider#hasChildren(Object)
418      */

419     public boolean hasChildren(Object JavaDoc element) {
420
421         if (element instanceof IPackageFragment) {
422             IPackageFragment fragment= (IPackageFragment) element;
423             if(fragment.isDefaultPackage() || !fragment.exists())
424                 return false;
425         }
426         return getChildren(element).length > 0;
427     }
428
429     /*
430      * @see org.eclipse.jface.viewers.IStructuredContentProvider#getElements(Object)
431      */

432     public Object JavaDoc[] getElements(Object JavaDoc inputElement) {
433         return getChildren(inputElement);
434     }
435
436     protected void processDelta(IJavaElementDelta delta) throws JavaModelException {
437
438         int kind = delta.getKind();
439         final IJavaElement element = delta.getElement();
440
441         if (isClassPathChange(delta)) {
442             Object JavaDoc input= fViewer.getInput();
443             if (input != null) {
444                 if (fInputIsProject && input.equals(element.getJavaProject())) {
445                     postRefresh(input);
446                     return;
447                 } else if (!fInputIsProject && input.equals(element)) {
448                     if (element.exists())
449                         postRefresh(input);
450                     else
451                         postRemove(input);
452                     return;
453                 }
454             }
455         }
456
457         if (kind == IJavaElementDelta.REMOVED) {
458             Object JavaDoc input= fViewer.getInput();
459             if (input != null && input.equals(element)) {
460                     postRemove(input);
461                     return;
462                 }
463         }
464
465         if (element instanceof IPackageFragment) {
466             final IPackageFragment frag = (IPackageFragment) element;
467
468             //if fragment was in LogicalPackage refresh,
469
//otherwise just remove
470
if (kind == IJavaElementDelta.REMOVED) {
471                 removeElement(frag);
472                 return;
473
474             } else if (kind == IJavaElementDelta.ADDED) {
475
476                 Object JavaDoc parent= getParent(frag);
477                 addElement(frag, parent);
478                 return;
479
480             } else if (kind == IJavaElementDelta.CHANGED) {
481                 //just refresh
482
LogicalPackage logicalPkg= findLogicalPackage(frag);
483                 //in case changed object is filtered out
484
if (logicalPkg != null)
485                     postRefresh(findElementToRefresh(logicalPkg));
486                 else
487                     postRefresh(findElementToRefresh(frag));
488                 return;
489             }
490         }
491
492         processAffectedChildren(delta);
493     }
494
495     private Object JavaDoc findElementToRefresh(Object JavaDoc object) {
496         Object JavaDoc toBeRefreshed= object;
497         if (fViewer.testFindItem(object) == null) {
498              Object JavaDoc parent= getParent(object);
499              if(parent instanceof IPackageFragmentRoot && fInputIsProject)
500                 parent= ((IPackageFragmentRoot)parent).getJavaProject();
501
502             if(parent != null)
503                 toBeRefreshed= parent;
504         }
505         return toBeRefreshed;
506     }
507
508     private void processAffectedChildren(IJavaElementDelta delta) throws JavaModelException {
509         IJavaElementDelta[] affectedChildren = delta.getAffectedChildren();
510         for (int i = 0; i < affectedChildren.length; i++) {
511             if (!(affectedChildren[i] instanceof ICompilationUnit)) {
512                 processDelta(affectedChildren[i]);
513             }
514         }
515     }
516
517     private void postAdd(final Object JavaDoc child, final Object JavaDoc parent) {
518         postRunnable(new Runnable JavaDoc() {
519             public void run() {
520                 Control ctrl = fViewer.getControl();
521                 if (ctrl != null && !ctrl.isDisposed()) {
522                     ((TreeViewer)fViewer).add(parent, child);
523                 }
524             }
525         });
526     }
527
528     private void postRemove(final Object JavaDoc object) {
529         postRunnable(new Runnable JavaDoc() {
530             public void run() {
531                 Control ctrl = fViewer.getControl();
532                 if (ctrl != null && !ctrl.isDisposed()) {
533                     ((TreeViewer)fViewer).remove(object);
534                 }
535             }
536         });
537     }
538
539     private void postRefresh(final Object JavaDoc object) {
540         postRunnable(new Runnable JavaDoc() {
541             public void run() {
542                 Control ctrl= fViewer.getControl();
543                 if (ctrl != null && !ctrl.isDisposed()) {
544                     ((TreeViewer) fViewer).refresh(object);
545                 }
546             }
547         });
548     }
549
550     private void postRunnable(final Runnable JavaDoc r) {
551         Control ctrl= fViewer.getControl();
552         if (ctrl != null && !ctrl.isDisposed()) {
553         // fBrowsingPart.setProcessSelectionEvents(false);
554
try {
555                 Display currentDisplay= Display.getCurrent();
556                 if (currentDisplay != null && currentDisplay.equals(ctrl.getDisplay()))
557                     ctrl.getDisplay().syncExec(r);
558                 else
559                     ctrl.getDisplay().asyncExec(r);
560             } finally {
561         // fBrowsingPart.setProcessSelectionEvents(true);
562
}
563         }
564     }
565
566     private void addElement(IPackageFragment frag, Object JavaDoc parent) {
567
568         String JavaDoc key= getKey(frag);
569         LogicalPackage lp= (LogicalPackage)fMapToLogicalPackage.get(key);
570
571         //if fragment must be added to an existing LogicalPackage
572
if (lp != null && lp.belongs(frag)){
573             lp.add(frag);
574             return;
575         }
576
577         //if a new LogicalPackage must be created
578
IPackageFragment iPackageFragment= (IPackageFragment)fMapToPackageFragments.get(key);
579         if (iPackageFragment!= null && !iPackageFragment.equals(frag)){
580             lp= new LogicalPackage(iPackageFragment);
581             lp.add(frag);
582             //add new LogicalPackage to LogicalPackages map
583
fMapToLogicalPackage.put(key, lp);
584
585             //determine who to refresh
586
if (parent instanceof IPackageFragmentRoot){
587                 IPackageFragmentRoot root= (IPackageFragmentRoot) parent;
588                 if (fInputIsProject){
589                     postRefresh(root.getJavaProject());
590                 } else {
591                     postRefresh(root);
592                 }
593             } else {
594                 //@Improve: Should this be replaced by a refresh?
595
postAdd(lp, parent);
596                 postRemove(iPackageFragment);
597             }
598
599         }
600         //if this is a new Package Fragment
601
else {
602             fMapToPackageFragments.put(key, frag);
603
604             //determine who to refresh
605
if (parent instanceof IPackageFragmentRoot) {
606                 IPackageFragmentRoot root= (IPackageFragmentRoot) parent;
607                 if (fInputIsProject) {
608                     postAdd(frag, root.getJavaProject());
609                 } else
610                     postAdd(frag, root);
611             } else {
612                 postAdd(frag, parent);
613             }
614         }
615     }
616
617     private void removeElement(IPackageFragment frag) {
618
619         String JavaDoc key= getKey(frag);
620         LogicalPackage lp= (LogicalPackage)fMapToLogicalPackage.get(key);
621
622         if(lp != null){
623             lp.remove(frag);
624             //if the LogicalPackage needs to revert back to a PackageFragment
625
//remove it from the LogicalPackages map and add the PackageFragment
626
//to the PackageFragment map
627
if (lp.getFragments().length == 1) {
628                 IPackageFragment fragment= lp.getFragments()[0];
629                 fMapToPackageFragments.put(key, fragment);
630                 fMapToLogicalPackage.remove(key);
631
632                 //remove the LogicalPackage from viewer
633
postRemove(lp);
634
635                 Object JavaDoc parent= getParent(fragment);
636                 if (parent instanceof IPackageFragmentRoot) {
637                     parent= ((IPackageFragmentRoot)parent).getJavaProject();
638                 }
639                 postAdd(fragment, parent);
640             }
641
642         } else {
643             //remove the fragment from the fragment map and viewer
644
IPackageFragment fragment= (IPackageFragment) fMapToPackageFragments.get(key);
645             if (fragment!= null && fragment.equals(frag)) {
646                 fMapToPackageFragments.remove(key);
647                 postRemove(frag);
648             }
649         }
650     }
651 }
652
Popular Tags