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;
44 * Sorter for Java elements. Ordered by element category, then by element name.
45 * Package fragment roots are sorted as ordered on the classpath.
48 * This class may be instantiated; it is not intended to be subclassed.
53 public class JavaElementSorter extends ViewerSorter {
55 private static final int PROJECTS = 1;
57 private static final int PACKAGEFRAGMENTROOTS = 2;
59 private static final int PACKAGEFRAGMENT = 3;
61 private static final int COMPILATIONUNITS = 4;
63 private static final int CLASSFILES = 5;
65 private static final int RESOURCEFOLDERS = 7;
67 private static final int RESOURCES = 8;
69 private static final int STORAGE = 9;
71 private static final int PACKAGE_DECL = 10;
73 private static final int IMPORT_CONTAINER = 11;
75 private static final int IMPORT_DECLARATION = 12;
77 // Includes all categories ordered using the OutlineSortOrderPage:
78 // types, initializers, methods & fields
79 private static final int MEMBERSOFFSET = 15;
81 private static final int JAVAELEMENTS = 50;
83 private static final int OTHERS = 51;
85 private MembersOrderPreferenceCache fMemberOrderCache;
90 public JavaElementSorter() {
91 super(null); // delay initialization of collator
92 fMemberOrderCache = PHPeclipsePlugin.getDefault()
93 .getMemberOrderPreferenceCache();
97 * @deprecated Bug 22518. Method never used: does not override
98 * ViewerSorter#isSorterProperty(Object, String). Method could
99 * be removed, but kept for API compatibility.
101 public boolean isSorterProperty(Object element, Object property) {
106 * @see ViewerSorter#category
108 public int category(Object element) {
109 if (element instanceof IJavaElement) {
111 IJavaElement je = (IJavaElement) element;
113 switch (je.getElementType()) {
114 case IJavaElement.METHOD: {
115 IMethod method = (IMethod) je;
116 if (method.isConstructor()) {
117 return getMemberCategory(MembersOrderPreferenceCache.CONSTRUCTORS_INDEX);
119 int flags = method.getFlags();
120 if (Flags.isStatic(flags))
121 return getMemberCategory(MembersOrderPreferenceCache.STATIC_METHODS_INDEX);
123 return getMemberCategory(MembersOrderPreferenceCache.METHOD_INDEX);
125 case IJavaElement.FIELD: {
126 int flags = ((IField) je).getFlags();
127 if (Flags.isStatic(flags))
128 return getMemberCategory(MembersOrderPreferenceCache.STATIC_FIELDS_INDEX);
130 return getMemberCategory(MembersOrderPreferenceCache.FIELDS_INDEX);
132 // case IJavaElement.INITIALIZER :
134 // int flags= ((IInitializer) je).getFlags();
135 // if (Flags.isStatic(flags))
137 // getMemberCategory(MembersOrderPreferenceCache.STATIC_INIT_INDEX);
140 // getMemberCategory(MembersOrderPreferenceCache.INIT_INDEX);
142 case IJavaElement.TYPE:
143 return getMemberCategory(MembersOrderPreferenceCache.TYPE_INDEX);
144 case IJavaElement.PACKAGE_DECLARATION:
146 case IJavaElement.IMPORT_CONTAINER:
147 return IMPORT_CONTAINER;
148 case IJavaElement.IMPORT_DECLARATION:
149 return IMPORT_DECLARATION;
150 case IJavaElement.PACKAGE_FRAGMENT:
151 IPackageFragment pack = (IPackageFragment) je;
152 if (pack.getParent().getResource() instanceof IProject) {
153 return PACKAGEFRAGMENTROOTS;
155 return PACKAGEFRAGMENT;
156 case IJavaElement.PACKAGE_FRAGMENT_ROOT:
157 return PACKAGEFRAGMENTROOTS;
158 case IJavaElement.JAVA_PROJECT:
160 case IJavaElement.CLASS_FILE:
162 case IJavaElement.COMPILATION_UNIT:
163 return COMPILATIONUNITS;
166 } catch (JavaModelException e) {
167 if (!e.isDoesNotExist())
168 PHPeclipsePlugin.log(e);
171 } else if (element instanceof IFile) {
173 } else if (element instanceof IProject) {
175 } else if (element instanceof IContainer) {
176 return RESOURCEFOLDERS;
177 } else if (element instanceof IStorage) {
180 // else if (element instanceof ClassPathContainer) {
181 // return PACKAGEFRAGMENTROOTS;
186 private int getMemberCategory(int kind) {
187 int offset = fMemberOrderCache.getCategoryIndex(kind);
188 return offset + MEMBERSOFFSET;
192 * @see ViewerSorter#compare
194 public int compare(Viewer viewer, Object e1, Object e2) {
195 int cat1 = category(e1);
196 int cat2 = category(e2);
201 if (cat1 == PROJECTS) {
202 IWorkbenchAdapter a1 = (IWorkbenchAdapter) ((IAdaptable) e1)
203 .getAdapter(IWorkbenchAdapter.class);
204 IWorkbenchAdapter a2 = (IWorkbenchAdapter) ((IAdaptable) e2)
205 .getAdapter(IWorkbenchAdapter.class);
206 return getCollator().compare(a1.getLabel(e1), a2.getLabel(e2));
209 if (cat1 == PACKAGEFRAGMENTROOTS) {
210 IPackageFragmentRoot root1 = getPackageFragmentRoot(e1);
211 IPackageFragmentRoot root2 = getPackageFragmentRoot(e2);
218 } else if (root2 == null) {
221 if (!root1.getPath().equals(root2.getPath())) {
222 int p1 = getClassPathIndex(root1);
223 int p2 = getClassPathIndex(root2);
228 e1 = root1; // normalize classpath container to root
231 // non - java resources are sorted using the label from the viewers
233 if (cat1 == PROJECTS || cat1 == RESOURCES || cat1 == RESOURCEFOLDERS
234 || cat1 == STORAGE || cat1 == OTHERS) {
235 return compareWithLabelProvider(viewer, e1, e2);
238 if (e1 instanceof IMember) {
239 if (fMemberOrderCache.isSortByVisibility()) {
241 int flags1 = JdtFlags.getVisibilityCode((IMember) e1);
242 int flags2 = JdtFlags.getVisibilityCode((IMember) e2);
243 int vis = fMemberOrderCache.getVisibilityIndex(flags1)
244 - fMemberOrderCache.getVisibilityIndex(flags2);
248 } catch (JavaModelException ignore) {
253 String name1 = ((IJavaElement) e1).getElementName();
254 String name2 = ((IJavaElement) e2).getElementName();
256 if (e1 instanceof IType) { // handle anonymous types
257 if (name1.length() == 0) {
258 if (name2.length() == 0) {
260 return getCollator().compare(
261 ((IType) e1).getSuperclassName(),
262 ((IType) e2).getSuperclassName());
263 } catch (JavaModelException e) {
269 } else if (name2.length() == 0) {
274 int cmp = getCollator().compare(name1, name2);
279 if (e1 instanceof IMethod) {
280 String[] params1 = ((IMethod) e1).getParameterTypes();
281 String[] params2 = ((IMethod) e2).getParameterTypes();
282 int len = Math.min(params1.length, params2.length);
283 for (int i = 0; i < len; i++) {
284 cmp = getCollator().compare(Signature.toString(params1[i]),
285 Signature.toString(params2[i]));
290 return params1.length - params2.length;
295 private IPackageFragmentRoot getPackageFragmentRoot(Object element) {
296 // if (element instanceof ClassPathContainer) {
297 // // return first package fragment root from the container
298 // ClassPathContainer cp= (ClassPathContainer)element;
299 // Object[] roots= cp.getPackageFragmentRoots();
300 // if (roots.length > 0)
301 // return (IPackageFragmentRoot)roots[0];
302 // // non resolvable - return null
305 return JavaModelUtil.getPackageFragmentRoot((IJavaElement) element);
308 private int compareWithLabelProvider(Viewer viewer, Object e1, Object e2) {
309 if (viewer == null || !(viewer instanceof ContentViewer)) {
310 IBaseLabelProvider prov = ((ContentViewer) viewer)
312 if (prov instanceof ILabelProvider) {
313 ILabelProvider lprov = (ILabelProvider) prov;
314 String name1 = lprov.getText(e1);
315 String name2 = lprov.getText(e2);
316 if (name1 != null && name2 != null) {
317 return getCollator().compare(name1, name2);
321 return 0; // can't compare
324 private int getClassPathIndex(IPackageFragmentRoot root) {
326 IPath rootPath = root.getPath();
327 IPackageFragmentRoot[] roots = root.getJavaProject()
328 .getPackageFragmentRoots();
329 for (int i = 0; i < roots.length; i++) {
330 if (roots[i].getPath().equals(rootPath)) {
334 } catch (JavaModelException e) {
337 return Integer.MAX_VALUE;
343 * @see org.eclipse.jface.viewers.ViewerSorter#getCollator()
345 public final Collator getCollator() {
346 if (collator == null) {
347 collator = Collator.getInstance();