KickJava   Java API By Example, From Geeks To Geeks.

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


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 org.eclipse.core.runtime.IAdaptable;
14 import org.eclipse.core.runtime.IPath;
15
16 import org.eclipse.core.resources.IContainer;
17 import org.eclipse.core.resources.IFile;
18 import org.eclipse.core.resources.IProject;
19 import org.eclipse.core.resources.IResource;
20 import org.eclipse.core.resources.IStorage;
21
22 import org.eclipse.jface.viewers.ContentViewer;
23 import org.eclipse.jface.viewers.IBaseLabelProvider;
24 import org.eclipse.jface.viewers.ILabelProvider;
25 import org.eclipse.jface.viewers.Viewer;
26 import org.eclipse.jface.viewers.ViewerComparator;
27
28 import org.eclipse.ui.model.IWorkbenchAdapter;
29
30 import org.eclipse.jdt.core.Flags;
31 import org.eclipse.jdt.core.IField;
32 import org.eclipse.jdt.core.IInitializer;
33 import org.eclipse.jdt.core.IJarEntryResource;
34 import org.eclipse.jdt.core.IJavaElement;
35 import org.eclipse.jdt.core.IJavaProject;
36 import org.eclipse.jdt.core.IMember;
37 import org.eclipse.jdt.core.IMethod;
38 import org.eclipse.jdt.core.IPackageFragment;
39 import org.eclipse.jdt.core.IPackageFragmentRoot;
40 import org.eclipse.jdt.core.IType;
41 import org.eclipse.jdt.core.JavaModelException;
42 import org.eclipse.jdt.core.Signature;
43
44 import org.eclipse.jdt.internal.corext.util.JavaModelUtil;
45 import org.eclipse.jdt.internal.corext.util.JdtFlags;
46
47 import org.eclipse.jdt.internal.ui.JavaPlugin;
48 import org.eclipse.jdt.internal.ui.packageview.PackageFragmentRootContainer;
49 import org.eclipse.jdt.internal.ui.preferences.MembersOrderPreferenceCache;
50
51
52 /**
53  * Viewer comparator for Java elements. Ordered by element category, then by element name.
54  * Package fragment roots are sorted as ordered on the classpath.
55  *
56  * <p>
57  * This class may be instantiated; it is not intended to be subclassed.
58  * </p>
59  *
60  * @since 3.3
61  */

62 public class JavaElementComparator extends ViewerComparator {
63     
64     private static final int PROJECTS= 1;
65     private static final int PACKAGEFRAGMENTROOTS= 2;
66     private static final int PACKAGEFRAGMENT= 3;
67
68     private static final int COMPILATIONUNITS= 4;
69     private static final int CLASSFILES= 5;
70     
71     private static final int RESOURCEFOLDERS= 7;
72     private static final int RESOURCES= 8;
73     
74     private static final int PACKAGE_DECL= 10;
75     private static final int IMPORT_CONTAINER= 11;
76     private static final int IMPORT_DECLARATION= 12;
77     
78     // Includes all categories ordered using the OutlineSortOrderPage:
79
// types, initializers, methods & fields
80
private static final int MEMBERSOFFSET= 15;
81     
82     private static final int JAVAELEMENTS= 50;
83     private static final int OTHERS= 51;
84     
85     private MembersOrderPreferenceCache fMemberOrderCache;
86     
87     /**
88      * Constructor.
89      */

90     public JavaElementComparator() {
91         super(null); // delay initialization of collator
92
fMemberOrderCache= JavaPlugin.getDefault().getMemberOrderPreferenceCache();
93     }
94         
95     /* (non-Javadoc)
96      * @see org.eclipse.jface.viewers.ViewerComparator#category(java.lang.Object)
97      */

98     public int category(Object JavaDoc element) {
99         if (element instanceof IJavaElement) {
100             try {
101                 IJavaElement je= (IJavaElement) element;
102
103                 switch (je.getElementType()) {
104                     case IJavaElement.METHOD:
105                         {
106                             IMethod method= (IMethod) je;
107                             if (method.isConstructor()) {
108                                 return getMemberCategory(MembersOrderPreferenceCache.CONSTRUCTORS_INDEX);
109                             }
110                             int flags= method.getFlags();
111                             if (Flags.isStatic(flags))
112                                 return getMemberCategory(MembersOrderPreferenceCache.STATIC_METHODS_INDEX);
113                             else
114                                 return getMemberCategory(MembersOrderPreferenceCache.METHOD_INDEX);
115                         }
116                     case IJavaElement.FIELD :
117                         {
118                             int flags= ((IField) je).getFlags();
119                             if (Flags.isEnum(flags)) {
120                                 return getMemberCategory(MembersOrderPreferenceCache.ENUM_CONSTANTS_INDEX);
121                             }
122                             if (Flags.isStatic(flags))
123                                 return getMemberCategory(MembersOrderPreferenceCache.STATIC_FIELDS_INDEX);
124                             else
125                                 return getMemberCategory(MembersOrderPreferenceCache.FIELDS_INDEX);
126                         }
127                     case IJavaElement.INITIALIZER :
128                         {
129                             int flags= ((IInitializer) je).getFlags();
130                             if (Flags.isStatic(flags))
131                                 return getMemberCategory(MembersOrderPreferenceCache.STATIC_INIT_INDEX);
132                             else
133                                 return getMemberCategory(MembersOrderPreferenceCache.INIT_INDEX);
134                         }
135                     case IJavaElement.TYPE :
136                         return getMemberCategory(MembersOrderPreferenceCache.TYPE_INDEX);
137                     case IJavaElement.PACKAGE_DECLARATION :
138                         return PACKAGE_DECL;
139                     case IJavaElement.IMPORT_CONTAINER :
140                         return IMPORT_CONTAINER;
141                     case IJavaElement.IMPORT_DECLARATION :
142                         return IMPORT_DECLARATION;
143                     case IJavaElement.PACKAGE_FRAGMENT :
144                         return PACKAGEFRAGMENT;
145                     case IJavaElement.PACKAGE_FRAGMENT_ROOT :
146                         return PACKAGEFRAGMENTROOTS;
147                     case IJavaElement.JAVA_PROJECT :
148                         return PROJECTS;
149                     case IJavaElement.CLASS_FILE :
150                         return CLASSFILES;
151                     case IJavaElement.COMPILATION_UNIT :
152                         return COMPILATIONUNITS;
153                 }
154
155             } catch (JavaModelException e) {
156                 if (!e.isDoesNotExist())
157                     JavaPlugin.log(e);
158             }
159             return JAVAELEMENTS;
160         } else if (element instanceof IFile) {
161             return RESOURCES;
162         } else if (element instanceof IProject) {
163             return PROJECTS;
164         } else if (element instanceof IContainer) {
165             return RESOURCEFOLDERS;
166         } else if (element instanceof IJarEntryResource) {
167             if (((IJarEntryResource) element).isFile()) {
168                 return RESOURCES;
169             }
170             return RESOURCEFOLDERS;
171         } else if (element instanceof PackageFragmentRootContainer) {
172             return PACKAGEFRAGMENTROOTS;
173         }
174         return OTHERS;
175     }
176     
177     private int getMemberCategory(int kind) {
178         int offset= fMemberOrderCache.getCategoryIndex(kind);
179         return offset + MEMBERSOFFSET;
180     }
181     
182     /* (non-Javadoc)
183      * @see org.eclipse.jface.viewers.ViewerComparator#compare(org.eclipse.jface.viewers.Viewer, java.lang.Object, java.lang.Object)
184      */

185     public int compare(Viewer viewer, Object JavaDoc e1, Object JavaDoc e2) {
186         int cat1= category(e1);
187         int cat2= category(e2);
188
189         if (needsClasspathComparision(e1, cat1, e2, cat2)) {
190             IPackageFragmentRoot root1= getPackageFragmentRoot(e1);
191             IPackageFragmentRoot root2= getPackageFragmentRoot(e2);
192             if (root1 == null) {
193                 if (root2 == null) {
194                     return 0;
195                 } else {
196                     return 1;
197                 }
198             } else if (root2 == null) {
199                 return -1;
200             }
201             // check if not same to avoid expensive class path access
202
if (!root1.getPath().equals(root2.getPath())) {
203                 int p1= getClassPathIndex(root1);
204                 int p2= getClassPathIndex(root2);
205                 if (p1 != p2) {
206                     return p1 - p2;
207                 }
208             }
209         }
210         
211         if (cat1 != cat2)
212             return cat1 - cat2;
213
214         if (cat1 == PROJECTS || cat1 == RESOURCES || cat1 == RESOURCEFOLDERS || cat1 == OTHERS) {
215             String JavaDoc name1= getNonJavaElementLabel(viewer, e1);
216             String JavaDoc name2= getNonJavaElementLabel(viewer, e2);
217             if (name1 != null && name2 != null) {
218                 return getComparator().compare(name1, name2);
219             }
220             return 0; // can't compare
221
}
222         // only java elements from this point
223

224         if (e1 instanceof IMember) {
225             if (fMemberOrderCache.isSortByVisibility()) {
226                 try {
227                     int flags1= JdtFlags.getVisibilityCode((IMember) e1);
228                     int flags2= JdtFlags.getVisibilityCode((IMember) e2);
229                     int vis= fMemberOrderCache.getVisibilityIndex(flags1) - fMemberOrderCache.getVisibilityIndex(flags2);
230                     if (vis != 0) {
231                         return vis;
232                     }
233                 } catch (JavaModelException ignore) {
234                 }
235             }
236         }
237         
238         String JavaDoc name1= getElementName(e1);
239         String JavaDoc name2= getElementName(e2);
240         
241         if (e1 instanceof IType) { // handle anonymous types
242
if (name1.length() == 0) {
243                 if (name2.length() == 0) {
244                     try {
245                         return getComparator().compare(((IType) e1).getSuperclassName(), ((IType) e2).getSuperclassName());
246                     } catch (JavaModelException e) {
247                         return 0;
248                     }
249                 } else {
250                     return 1;
251                 }
252             } else if (name2.length() == 0) {
253                 return -1;
254             }
255         }
256                 
257         int cmp= getComparator().compare(name1, name2);
258         if (cmp != 0) {
259             return cmp;
260         }
261         
262         if (e1 instanceof IMethod) {
263             String JavaDoc[] params1= ((IMethod) e1).getParameterTypes();
264             String JavaDoc[] params2= ((IMethod) e2).getParameterTypes();
265             int len= Math.min(params1.length, params2.length);
266             for (int i = 0; i < len; i++) {
267                 cmp= getComparator().compare(Signature.toString(params1[i]), Signature.toString(params2[i]));
268                 if (cmp != 0) {
269                     return cmp;
270                 }
271             }
272             return params1.length - params2.length;
273         }
274         return 0;
275     }
276     
277     private IPackageFragmentRoot getPackageFragmentRoot(Object JavaDoc element) {
278         if (element instanceof PackageFragmentRootContainer) {
279             // return first package fragment root from the container
280
PackageFragmentRootContainer cp= (PackageFragmentRootContainer)element;
281             Object JavaDoc[] roots= cp.getPackageFragmentRoots();
282             if (roots.length > 0)
283                 return (IPackageFragmentRoot)roots[0];
284             // non resolvable - return null
285
return null;
286         }
287         return JavaModelUtil.getPackageFragmentRoot((IJavaElement)element);
288     }
289     
290     private String JavaDoc getNonJavaElementLabel(Viewer viewer, Object JavaDoc element) {
291         // try to use the workbench adapter for non - java resources or if not available, use the viewers label provider
292
if (element instanceof IResource) {
293             return ((IResource) element).getName();
294         }
295         if (element instanceof IStorage) {
296             return ((IStorage) element).getName();
297         }
298         if (element instanceof IAdaptable) {
299             IWorkbenchAdapter adapter= (IWorkbenchAdapter) ((IAdaptable) element).getAdapter(IWorkbenchAdapter.class);
300             if (adapter != null) {
301                 return adapter.getLabel(element);
302             }
303         }
304         if (viewer instanceof ContentViewer) {
305             IBaseLabelProvider prov = ((ContentViewer) viewer).getLabelProvider();
306             if (prov instanceof ILabelProvider) {
307                 return ((ILabelProvider) prov).getText(element);
308             }
309         }
310         return null;
311     }
312             
313     private int getClassPathIndex(IPackageFragmentRoot root) {
314         try {
315             IPath rootPath= root.getPath();
316             IPackageFragmentRoot[] roots= root.getJavaProject().getPackageFragmentRoots();
317             for (int i= 0; i < roots.length; i++) {
318                 if (roots[i].getPath().equals(rootPath)) {
319                     return i;
320                 }
321             }
322         } catch (JavaModelException e) {
323         }
324
325         return Integer.MAX_VALUE;
326     }
327         
328     private boolean needsClasspathComparision(Object JavaDoc e1, int cat1, Object JavaDoc e2, int cat2) {
329         if ((cat1 == PACKAGEFRAGMENTROOTS && cat2 == PACKAGEFRAGMENTROOTS) ||
330             (cat1 == PACKAGEFRAGMENT &&
331                 ((IPackageFragment)e1).getParent().getResource() instanceof IProject &&
332                 cat2 == PACKAGEFRAGMENTROOTS) ||
333             (cat1 == PACKAGEFRAGMENTROOTS &&
334                 cat2 == PACKAGEFRAGMENT &&
335                 ((IPackageFragment)e2).getParent().getResource() instanceof IProject)) {
336             IJavaProject p1= getJavaProject(e1);
337             return p1 != null && p1.equals(getJavaProject(e2));
338         }
339         return false;
340     }
341     
342     private IJavaProject getJavaProject(Object JavaDoc element) {
343         if (element instanceof IJavaElement) {
344             return ((IJavaElement)element).getJavaProject();
345         } else if (element instanceof PackageFragmentRootContainer) {
346             return ((PackageFragmentRootContainer)element).getJavaProject();
347         }
348         return null;
349     }
350     
351     private String JavaDoc getElementName(Object JavaDoc element) {
352         if (element instanceof IJavaElement) {
353             return ((IJavaElement)element).getElementName();
354         } else if (element instanceof PackageFragmentRootContainer) {
355             return ((PackageFragmentRootContainer)element).getLabel();
356         } else {
357             return element.toString();
358         }
359     }
360 }
361
Popular Tags