1 /*******************************************************************************
2 * Copyright (c) 2000, 2004 IBM Corporation and others.
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the Common Public License v1.0
5 * which accompanies this distribution, and is available at
6 * http://www.eclipse.org/legal/cpl-v10.html
9 * IBM Corporation - initial API and implementation
10 *******************************************************************************/
11 package net.sourceforge.phpdt.ui;
13 import java.text.Collator;
15 import net.sourceforge.phpdt.core.Flags;
16 import net.sourceforge.phpdt.core.IField;
17 import net.sourceforge.phpdt.core.IJavaElement;
18 import net.sourceforge.phpdt.core.IMember;
19 import net.sourceforge.phpdt.core.IMethod;
20 import net.sourceforge.phpdt.core.IPackageFragment;
21 import net.sourceforge.phpdt.core.IPackageFragmentRoot;
22 import net.sourceforge.phpdt.core.IType;
23 import net.sourceforge.phpdt.core.JavaModelException;
24 import net.sourceforge.phpdt.core.Signature;
25 import net.sourceforge.phpdt.internal.corext.util.JavaModelUtil;
26 import net.sourceforge.phpdt.internal.corext.util.JdtFlags;
27 import net.sourceforge.phpdt.internal.ui.preferences.MembersOrderPreferenceCache;
28 import net.sourceforge.phpeclipse.PHPeclipsePlugin;
30 import org.eclipse.core.resources.IContainer;
31 import org.eclipse.core.resources.IFile;
32 import org.eclipse.core.resources.IProject;
33 import org.eclipse.core.resources.IStorage;
34 import org.eclipse.core.runtime.IAdaptable;
35 import org.eclipse.core.runtime.IPath;
36 import org.eclipse.jface.viewers.ContentViewer;
37 import org.eclipse.jface.viewers.IBaseLabelProvider;
38 import org.eclipse.jface.viewers.ILabelProvider;
39 import org.eclipse.jface.viewers.Viewer;
40 import org.eclipse.jface.viewers.ViewerSorter;
41 import org.eclipse.ui.model.IWorkbenchAdapter;
45 * Sorter for Java elements. Ordered by element category, then by element name.
46 * Package fragment roots are sorted as ordered on the classpath.
49 * This class may be instantiated; it is not intended to be subclassed.
54 public class JavaElementSorter extends ViewerSorter {
56 private static final int PROJECTS= 1;
57 private static final int PACKAGEFRAGMENTROOTS= 2;
58 private static final int PACKAGEFRAGMENT= 3;
60 private static final int COMPILATIONUNITS= 4;
61 private static final int CLASSFILES= 5;
63 private static final int RESOURCEFOLDERS= 7;
64 private static final int RESOURCES= 8;
65 private static final int STORAGE= 9;
67 private static final int PACKAGE_DECL= 10;
68 private static final int IMPORT_CONTAINER= 11;
69 private static final int IMPORT_DECLARATION= 12;
71 // Includes all categories ordered using the OutlineSortOrderPage:
72 // types, initializers, methods & fields
73 private static final int MEMBERSOFFSET= 15;
75 private static final int JAVAELEMENTS= 50;
76 private static final int OTHERS= 51;
78 private MembersOrderPreferenceCache fMemberOrderCache;
83 public JavaElementSorter() {
84 super(null); // delay initialization of collator
85 fMemberOrderCache= PHPeclipsePlugin.getDefault().getMemberOrderPreferenceCache();
89 * @deprecated Bug 22518. Method never used: does not override ViewerSorter#isSorterProperty(Object, String).
90 * Method could be removed, but kept for API compatibility.
92 public boolean isSorterProperty(Object element, Object property) {
97 * @see ViewerSorter#category
99 public int category(Object element) {
100 if (element instanceof IJavaElement) {
102 IJavaElement je= (IJavaElement) element;
104 switch (je.getElementType()) {
105 case IJavaElement.METHOD:
107 IMethod method= (IMethod) je;
108 if (method.isConstructor()) {
109 return getMemberCategory(MembersOrderPreferenceCache.CONSTRUCTORS_INDEX);
111 int flags= method.getFlags();
112 if (Flags.isStatic(flags))
113 return getMemberCategory(MembersOrderPreferenceCache.STATIC_METHODS_INDEX);
115 return getMemberCategory(MembersOrderPreferenceCache.METHOD_INDEX);
117 case IJavaElement.FIELD :
119 int flags= ((IField) je).getFlags();
120 if (Flags.isStatic(flags))
121 return getMemberCategory(MembersOrderPreferenceCache.STATIC_FIELDS_INDEX);
123 return getMemberCategory(MembersOrderPreferenceCache.FIELDS_INDEX);
125 // case IJavaElement.INITIALIZER :
127 // int flags= ((IInitializer) je).getFlags();
128 // if (Flags.isStatic(flags))
129 // return getMemberCategory(MembersOrderPreferenceCache.STATIC_INIT_INDEX);
131 // return getMemberCategory(MembersOrderPreferenceCache.INIT_INDEX);
133 case IJavaElement.TYPE :
134 return getMemberCategory(MembersOrderPreferenceCache.TYPE_INDEX);
135 case IJavaElement.PACKAGE_DECLARATION :
137 case IJavaElement.IMPORT_CONTAINER :
138 return IMPORT_CONTAINER;
139 case IJavaElement.IMPORT_DECLARATION :
140 return IMPORT_DECLARATION;
141 case IJavaElement.PACKAGE_FRAGMENT :
142 IPackageFragment pack= (IPackageFragment) je;
143 if (pack.getParent().getResource() instanceof IProject) {
144 return PACKAGEFRAGMENTROOTS;
146 return PACKAGEFRAGMENT;
147 case IJavaElement.PACKAGE_FRAGMENT_ROOT :
148 return PACKAGEFRAGMENTROOTS;
149 case IJavaElement.JAVA_PROJECT :
151 case IJavaElement.CLASS_FILE :
153 case IJavaElement.COMPILATION_UNIT :
154 return COMPILATIONUNITS;
157 } catch (JavaModelException e) {
158 if (!e.isDoesNotExist())
159 PHPeclipsePlugin.log(e);
162 } else if (element instanceof IFile) {
164 } else if (element instanceof IProject) {
166 } else if (element instanceof IContainer) {
167 return RESOURCEFOLDERS;
168 } else if (element instanceof IStorage) {
171 // else if (element instanceof ClassPathContainer) {
172 // return PACKAGEFRAGMENTROOTS;
177 private int getMemberCategory(int kind) {
178 int offset= fMemberOrderCache.getCategoryIndex(kind);
179 return offset + MEMBERSOFFSET;
183 * @see ViewerSorter#compare
185 public int compare(Viewer viewer, Object e1, Object e2) {
186 int cat1= category(e1);
187 int cat2= category(e2);
192 if (cat1 == PROJECTS) {
193 IWorkbenchAdapter a1= (IWorkbenchAdapter)((IAdaptable)e1).getAdapter(IWorkbenchAdapter.class);
194 IWorkbenchAdapter a2= (IWorkbenchAdapter)((IAdaptable)e2).getAdapter(IWorkbenchAdapter.class);
195 return getCollator().compare(a1.getLabel(e1), a2.getLabel(e2));
198 if (cat1 == PACKAGEFRAGMENTROOTS) {
199 IPackageFragmentRoot root1= getPackageFragmentRoot(e1);
200 IPackageFragmentRoot root2= getPackageFragmentRoot(e2);
207 } else if (root2 == null) {
210 if (!root1.getPath().equals(root2.getPath())) {
211 int p1= getClassPathIndex(root1);
212 int p2= getClassPathIndex(root2);
217 e1= root1; // normalize classpath container to root
220 // non - java resources are sorted using the label from the viewers label provider
221 if (cat1 == PROJECTS || cat1 == RESOURCES || cat1 == RESOURCEFOLDERS || cat1 == STORAGE || cat1 == OTHERS) {
222 return compareWithLabelProvider(viewer, e1, e2);
225 if (e1 instanceof IMember) {
226 if (fMemberOrderCache.isSortByVisibility()) {
228 int flags1= JdtFlags.getVisibilityCode((IMember) e1);
229 int flags2= JdtFlags.getVisibilityCode((IMember) e2);
230 int vis= fMemberOrderCache.getVisibilityIndex(flags1) - fMemberOrderCache.getVisibilityIndex(flags2);
234 } catch (JavaModelException ignore) {
239 String name1= ((IJavaElement) e1).getElementName();
240 String name2= ((IJavaElement) e2).getElementName();
242 if (e1 instanceof IType) { // handle anonymous types
243 if (name1.length() == 0) {
244 if (name2.length() == 0) {
246 return getCollator().compare(((IType) e1).getSuperclassName(), ((IType) e2).getSuperclassName());
247 } catch (JavaModelException e) {
253 } else if (name2.length() == 0) {
258 int cmp= getCollator().compare(name1, name2);
263 if (e1 instanceof IMethod) {
264 String[] params1= ((IMethod) e1).getParameterTypes();
265 String[] params2= ((IMethod) e2).getParameterTypes();
266 int len= Math.min(params1.length, params2.length);
267 for (int i = 0; i < len; i++) {
268 cmp= getCollator().compare(Signature.toString(params1[i]), Signature.toString(params2[i]));
273 return params1.length - params2.length;
279 private IPackageFragmentRoot getPackageFragmentRoot(Object element) {
280 // if (element instanceof ClassPathContainer) {
281 // // return first package fragment root from the container
282 // ClassPathContainer cp= (ClassPathContainer)element;
283 // Object[] roots= cp.getPackageFragmentRoots();
284 // if (roots.length > 0)
285 // return (IPackageFragmentRoot)roots[0];
286 // // non resolvable - return null
289 return JavaModelUtil.getPackageFragmentRoot((IJavaElement)element);
292 private int compareWithLabelProvider(Viewer viewer, Object e1, Object e2) {
293 if (viewer == null || !(viewer instanceof ContentViewer)) {
294 IBaseLabelProvider prov = ((ContentViewer) viewer).getLabelProvider();
295 if (prov instanceof ILabelProvider) {
296 ILabelProvider lprov= (ILabelProvider) prov;
297 String name1 = lprov.getText(e1);
298 String name2 = lprov.getText(e2);
299 if (name1 != null && name2 != null) {
300 return getCollator().compare(name1, name2);
304 return 0; // can't compare
307 private int getClassPathIndex(IPackageFragmentRoot root) {
309 IPath rootPath= root.getPath();
310 IPackageFragmentRoot[] roots= root.getJavaProject().getPackageFragmentRoots();
311 for (int i= 0; i < roots.length; i++) {
312 if (roots[i].getPath().equals(rootPath)) {
316 } catch (JavaModelException e) {
319 return Integer.MAX_VALUE;
323 * @see org.eclipse.jface.viewers.ViewerSorter#getCollator()
325 public final Collator getCollator() {
326 if (collator == null) {
327 collator= Collator.getInstance();