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;
29 import net.sourceforge.phpeclipse.ui.WebUI;
31 import org.eclipse.core.resources.IContainer;
32 import org.eclipse.core.resources.IFile;
33 import org.eclipse.core.resources.IProject;
34 import org.eclipse.core.resources.IStorage;
35 import org.eclipse.core.runtime.IAdaptable;
36 import org.eclipse.core.runtime.IPath;
37 import org.eclipse.jface.viewers.ContentViewer;
38 import org.eclipse.jface.viewers.IBaseLabelProvider;
39 import org.eclipse.jface.viewers.ILabelProvider;
40 import org.eclipse.jface.viewers.Viewer;
41 import org.eclipse.jface.viewers.ViewerSorter;
42 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;
58 private static final int PACKAGEFRAGMENTROOTS = 2;
60 private static final int PACKAGEFRAGMENT = 3;
62 private static final int COMPILATIONUNITS = 4;
64 private static final int CLASSFILES = 5;
66 private static final int RESOURCEFOLDERS = 7;
68 private static final int RESOURCES = 8;
70 private static final int STORAGE = 9;
72 private static final int PACKAGE_DECL = 10;
74 private static final int IMPORT_CONTAINER = 11;
76 private static final int IMPORT_DECLARATION = 12;
78 // Includes all categories ordered using the OutlineSortOrderPage:
79 // types, initializers, methods & fields
80 private static final int MEMBERSOFFSET = 15;
82 private static final int JAVAELEMENTS = 50;
84 private static final int OTHERS = 51;
86 private MembersOrderPreferenceCache fMemberOrderCache;
91 public JavaElementSorter() {
92 super(null); // delay initialization of collator
93 fMemberOrderCache = WebUI.getDefault()
94 .getMemberOrderPreferenceCache();
98 * @deprecated Bug 22518. Method never used: does not override
99 * ViewerSorter#isSorterProperty(Object, String). Method could
100 * be removed, but kept for API compatibility.
102 // public boolean isSorterProperty(Object element, Object property) {
107 * @see ViewerSorter#category
109 public int category(Object element) {
110 if (element instanceof IJavaElement) {
112 IJavaElement je = (IJavaElement) element;
114 switch (je.getElementType()) {
115 case IJavaElement.METHOD: {
116 IMethod method = (IMethod) je;
117 if (method.isConstructor()) {
118 return getMemberCategory(MembersOrderPreferenceCache.CONSTRUCTORS_INDEX);
120 int flags = method.getFlags();
121 if (Flags.isStatic(flags))
122 return getMemberCategory(MembersOrderPreferenceCache.STATIC_METHODS_INDEX);
124 return getMemberCategory(MembersOrderPreferenceCache.METHOD_INDEX);
126 case IJavaElement.FIELD: {
127 int flags = ((IField) je).getFlags();
128 if (Flags.isStatic(flags))
129 return getMemberCategory(MembersOrderPreferenceCache.STATIC_FIELDS_INDEX);
131 return getMemberCategory(MembersOrderPreferenceCache.FIELDS_INDEX);
133 // case IJavaElement.INITIALIZER :
135 // int flags= ((IInitializer) je).getFlags();
136 // if (Flags.isStatic(flags))
138 // getMemberCategory(MembersOrderPreferenceCache.STATIC_INIT_INDEX);
141 // getMemberCategory(MembersOrderPreferenceCache.INIT_INDEX);
143 case IJavaElement.TYPE:
144 return getMemberCategory(MembersOrderPreferenceCache.TYPE_INDEX);
145 case IJavaElement.PACKAGE_DECLARATION:
147 case IJavaElement.IMPORT_CONTAINER:
148 return IMPORT_CONTAINER;
149 case IJavaElement.IMPORT_DECLARATION:
150 return IMPORT_DECLARATION;
151 case IJavaElement.PACKAGE_FRAGMENT:
152 IPackageFragment pack = (IPackageFragment) je;
153 if (pack.getParent().getResource() instanceof IProject) {
154 return PACKAGEFRAGMENTROOTS;
156 return PACKAGEFRAGMENT;
157 case IJavaElement.PACKAGE_FRAGMENT_ROOT:
158 return PACKAGEFRAGMENTROOTS;
159 case IJavaElement.JAVA_PROJECT:
161 case IJavaElement.CLASS_FILE:
163 case IJavaElement.COMPILATION_UNIT:
164 return COMPILATIONUNITS;
167 } catch (JavaModelException e) {
168 if (!e.isDoesNotExist())
169 PHPeclipsePlugin.log(e);
172 } else if (element instanceof IFile) {
174 } else if (element instanceof IProject) {
176 } else if (element instanceof IContainer) {
177 return RESOURCEFOLDERS;
178 } else if (element instanceof IStorage) {
181 // else if (element instanceof ClassPathContainer) {
182 // return PACKAGEFRAGMENTROOTS;
187 private int getMemberCategory(int kind) {
188 int offset = fMemberOrderCache.getCategoryIndex(kind);
189 return offset + MEMBERSOFFSET;
193 * @see ViewerSorter#compare
195 public int compare(Viewer viewer, Object e1, Object e2) {
196 int cat1 = category(e1);
197 int cat2 = category(e2);
202 if (cat1 == PROJECTS) {
203 IWorkbenchAdapter a1 = (IWorkbenchAdapter) ((IAdaptable) e1)
204 .getAdapter(IWorkbenchAdapter.class);
205 IWorkbenchAdapter a2 = (IWorkbenchAdapter) ((IAdaptable) e2)
206 .getAdapter(IWorkbenchAdapter.class);
207 return getCollator().compare(a1.getLabel(e1), a2.getLabel(e2));
210 if (cat1 == PACKAGEFRAGMENTROOTS) {
211 IPackageFragmentRoot root1 = getPackageFragmentRoot(e1);
212 IPackageFragmentRoot root2 = getPackageFragmentRoot(e2);
219 } else if (root2 == null) {
222 if (!root1.getPath().equals(root2.getPath())) {
223 int p1 = getClassPathIndex(root1);
224 int p2 = getClassPathIndex(root2);
229 e1 = root1; // normalize classpath container to root
232 // non - java resources are sorted using the label from the viewers
234 if (cat1 == PROJECTS || cat1 == RESOURCES || cat1 == RESOURCEFOLDERS
235 || cat1 == STORAGE || cat1 == OTHERS) {
236 return compareWithLabelProvider(viewer, e1, e2);
239 if (e1 instanceof IMember) {
240 if (fMemberOrderCache.isSortByVisibility()) {
242 int flags1 = JdtFlags.getVisibilityCode((IMember) e1);
243 int flags2 = JdtFlags.getVisibilityCode((IMember) e2);
244 int vis = fMemberOrderCache.getVisibilityIndex(flags1)
245 - fMemberOrderCache.getVisibilityIndex(flags2);
249 } catch (JavaModelException ignore) {
254 String name1 = ((IJavaElement) e1).getElementName();
255 String name2 = ((IJavaElement) e2).getElementName();
257 if (e1 instanceof IType) { // handle anonymous types
258 if (name1.length() == 0) {
259 if (name2.length() == 0) {
261 return getCollator().compare(
262 ((IType) e1).getSuperclassName(),
263 ((IType) e2).getSuperclassName());
264 } catch (JavaModelException e) {
270 } else if (name2.length() == 0) {
275 int cmp = getCollator().compare(name1, name2);
280 if (e1 instanceof IMethod) {
281 String[] params1 = ((IMethod) e1).getParameterTypes();
282 String[] params2 = ((IMethod) e2).getParameterTypes();
283 int len = Math.min(params1.length, params2.length);
284 for (int i = 0; i < len; i++) {
285 cmp = getCollator().compare(Signature.toString(params1[i]),
286 Signature.toString(params2[i]));
291 return params1.length - params2.length;
296 private IPackageFragmentRoot getPackageFragmentRoot(Object element) {
297 // if (element instanceof ClassPathContainer) {
298 // // return first package fragment root from the container
299 // ClassPathContainer cp= (ClassPathContainer)element;
300 // Object[] roots= cp.getPackageFragmentRoots();
301 // if (roots.length > 0)
302 // return (IPackageFragmentRoot)roots[0];
303 // // non resolvable - return null
306 return JavaModelUtil.getPackageFragmentRoot((IJavaElement) element);
309 private int compareWithLabelProvider(Viewer viewer, Object e1, Object e2) {
310 if (viewer == null || !(viewer instanceof ContentViewer)) {
311 IBaseLabelProvider prov = ((ContentViewer) viewer)
313 if (prov instanceof ILabelProvider) {
314 ILabelProvider lprov = (ILabelProvider) prov;
315 String name1 = lprov.getText(e1);
316 String name2 = lprov.getText(e2);
317 if (name1 != null && name2 != null) {
318 return getCollator().compare(name1, name2);
322 return 0; // can't compare
325 private int getClassPathIndex(IPackageFragmentRoot root) {
327 IPath rootPath = root.getPath();
328 IPackageFragmentRoot[] roots = root.getJavaProject()
329 .getPackageFragmentRoots();
330 for (int i = 0; i < roots.length; i++) {
331 if (roots[i].getPath().equals(rootPath)) {
335 } catch (JavaModelException e) {
338 return Integer.MAX_VALUE;
344 * @see org.eclipse.jface.viewers.ViewerSorter#getCollator()
346 public final Collator getCollator() {
347 if (collator == null) {
348 collator = Collator.getInstance();