/******************************************************************************* * Copyright (c) 2000, 2004 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Common Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/cpl-v10.html * * Contributors: * IBM Corporation - initial API and implementation *******************************************************************************/ package net.sourceforge.phpdt.ui; import java.text.Collator; import net.sourceforge.phpdt.core.Flags; import net.sourceforge.phpdt.core.IField; import net.sourceforge.phpdt.core.IJavaElement; import net.sourceforge.phpdt.core.IMember; import net.sourceforge.phpdt.core.IMethod; import net.sourceforge.phpdt.core.IPackageFragment; import net.sourceforge.phpdt.core.IPackageFragmentRoot; import net.sourceforge.phpdt.core.IType; import net.sourceforge.phpdt.core.JavaModelException; import net.sourceforge.phpdt.core.Signature; import net.sourceforge.phpdt.internal.corext.util.JavaModelUtil; import net.sourceforge.phpdt.internal.corext.util.JdtFlags; import net.sourceforge.phpdt.internal.ui.preferences.MembersOrderPreferenceCache; import net.sourceforge.phpeclipse.PHPeclipsePlugin; import org.eclipse.core.resources.IContainer; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IStorage; import org.eclipse.core.runtime.IAdaptable; import org.eclipse.core.runtime.IPath; import org.eclipse.jface.viewers.ContentViewer; import org.eclipse.jface.viewers.IBaseLabelProvider; import org.eclipse.jface.viewers.ILabelProvider; import org.eclipse.jface.viewers.Viewer; import org.eclipse.jface.viewers.ViewerSorter; import org.eclipse.ui.model.IWorkbenchAdapter; /** * Sorter for Java elements. Ordered by element category, then by element name. * Package fragment roots are sorted as ordered on the classpath. * *

* This class may be instantiated; it is not intended to be subclassed. *

* * @since 2.0 */ public class JavaElementSorter extends ViewerSorter { private static final int PROJECTS = 1; private static final int PACKAGEFRAGMENTROOTS = 2; private static final int PACKAGEFRAGMENT = 3; private static final int COMPILATIONUNITS = 4; private static final int CLASSFILES = 5; private static final int RESOURCEFOLDERS = 7; private static final int RESOURCES = 8; private static final int STORAGE = 9; private static final int PACKAGE_DECL = 10; private static final int IMPORT_CONTAINER = 11; private static final int IMPORT_DECLARATION = 12; // Includes all categories ordered using the OutlineSortOrderPage: // types, initializers, methods & fields private static final int MEMBERSOFFSET = 15; private static final int JAVAELEMENTS = 50; private static final int OTHERS = 51; private MembersOrderPreferenceCache fMemberOrderCache; /** * Constructor. */ public JavaElementSorter() { super(null); // delay initialization of collator fMemberOrderCache = PHPeclipsePlugin.getDefault() .getMemberOrderPreferenceCache(); } /** * @deprecated Bug 22518. Method never used: does not override * ViewerSorter#isSorterProperty(Object, String). Method could * be removed, but kept for API compatibility. */ // public boolean isSorterProperty(Object element, Object property) { // return true; // } /* * @see ViewerSorter#category */ public int category(Object element) { if (element instanceof IJavaElement) { try { IJavaElement je = (IJavaElement) element; switch (je.getElementType()) { case IJavaElement.METHOD: { IMethod method = (IMethod) je; if (method.isConstructor()) { return getMemberCategory(MembersOrderPreferenceCache.CONSTRUCTORS_INDEX); } int flags = method.getFlags(); if (Flags.isStatic(flags)) return getMemberCategory(MembersOrderPreferenceCache.STATIC_METHODS_INDEX); else return getMemberCategory(MembersOrderPreferenceCache.METHOD_INDEX); } case IJavaElement.FIELD: { int flags = ((IField) je).getFlags(); if (Flags.isStatic(flags)) return getMemberCategory(MembersOrderPreferenceCache.STATIC_FIELDS_INDEX); else return getMemberCategory(MembersOrderPreferenceCache.FIELDS_INDEX); } // case IJavaElement.INITIALIZER : // { // int flags= ((IInitializer) je).getFlags(); // if (Flags.isStatic(flags)) // return // getMemberCategory(MembersOrderPreferenceCache.STATIC_INIT_INDEX); // else // return // getMemberCategory(MembersOrderPreferenceCache.INIT_INDEX); // } case IJavaElement.TYPE: return getMemberCategory(MembersOrderPreferenceCache.TYPE_INDEX); case IJavaElement.PACKAGE_DECLARATION: return PACKAGE_DECL; case IJavaElement.IMPORT_CONTAINER: return IMPORT_CONTAINER; case IJavaElement.IMPORT_DECLARATION: return IMPORT_DECLARATION; case IJavaElement.PACKAGE_FRAGMENT: IPackageFragment pack = (IPackageFragment) je; if (pack.getParent().getResource() instanceof IProject) { return PACKAGEFRAGMENTROOTS; } return PACKAGEFRAGMENT; case IJavaElement.PACKAGE_FRAGMENT_ROOT: return PACKAGEFRAGMENTROOTS; case IJavaElement.JAVA_PROJECT: return PROJECTS; case IJavaElement.CLASS_FILE: return CLASSFILES; case IJavaElement.COMPILATION_UNIT: return COMPILATIONUNITS; } } catch (JavaModelException e) { if (!e.isDoesNotExist()) PHPeclipsePlugin.log(e); } return JAVAELEMENTS; } else if (element instanceof IFile) { return RESOURCES; } else if (element instanceof IProject) { return PROJECTS; } else if (element instanceof IContainer) { return RESOURCEFOLDERS; } else if (element instanceof IStorage) { return STORAGE; } // else if (element instanceof ClassPathContainer) { // return PACKAGEFRAGMENTROOTS; // } return OTHERS; } private int getMemberCategory(int kind) { int offset = fMemberOrderCache.getCategoryIndex(kind); return offset + MEMBERSOFFSET; } /* * @see ViewerSorter#compare */ public int compare(Viewer viewer, Object e1, Object e2) { int cat1 = category(e1); int cat2 = category(e2); if (cat1 != cat2) return cat1 - cat2; if (cat1 == PROJECTS) { IWorkbenchAdapter a1 = (IWorkbenchAdapter) ((IAdaptable) e1) .getAdapter(IWorkbenchAdapter.class); IWorkbenchAdapter a2 = (IWorkbenchAdapter) ((IAdaptable) e2) .getAdapter(IWorkbenchAdapter.class); return getCollator().compare(a1.getLabel(e1), a2.getLabel(e2)); } if (cat1 == PACKAGEFRAGMENTROOTS) { IPackageFragmentRoot root1 = getPackageFragmentRoot(e1); IPackageFragmentRoot root2 = getPackageFragmentRoot(e2); if (root1 == null) { if (root2 == null) { return 0; } else { return 1; } } else if (root2 == null) { return -1; } if (!root1.getPath().equals(root2.getPath())) { int p1 = getClassPathIndex(root1); int p2 = getClassPathIndex(root2); if (p1 != p2) { return p1 - p2; } } e1 = root1; // normalize classpath container to root e2 = root2; } // non - java resources are sorted using the label from the viewers // label provider if (cat1 == PROJECTS || cat1 == RESOURCES || cat1 == RESOURCEFOLDERS || cat1 == STORAGE || cat1 == OTHERS) { return compareWithLabelProvider(viewer, e1, e2); } if (e1 instanceof IMember) { if (fMemberOrderCache.isSortByVisibility()) { try { int flags1 = JdtFlags.getVisibilityCode((IMember) e1); int flags2 = JdtFlags.getVisibilityCode((IMember) e2); int vis = fMemberOrderCache.getVisibilityIndex(flags1) - fMemberOrderCache.getVisibilityIndex(flags2); if (vis != 0) { return vis; } } catch (JavaModelException ignore) { } } } String name1 = ((IJavaElement) e1).getElementName(); String name2 = ((IJavaElement) e2).getElementName(); if (e1 instanceof IType) { // handle anonymous types if (name1.length() == 0) { if (name2.length() == 0) { try { return getCollator().compare( ((IType) e1).getSuperclassName(), ((IType) e2).getSuperclassName()); } catch (JavaModelException e) { return 0; } } else { return 1; } } else if (name2.length() == 0) { return -1; } } int cmp = getCollator().compare(name1, name2); if (cmp != 0) { return cmp; } if (e1 instanceof IMethod) { String[] params1 = ((IMethod) e1).getParameterTypes(); String[] params2 = ((IMethod) e2).getParameterTypes(); int len = Math.min(params1.length, params2.length); for (int i = 0; i < len; i++) { cmp = getCollator().compare(Signature.toString(params1[i]), Signature.toString(params2[i])); if (cmp != 0) { return cmp; } } return params1.length - params2.length; } return 0; } private IPackageFragmentRoot getPackageFragmentRoot(Object element) { // if (element instanceof ClassPathContainer) { // // return first package fragment root from the container // ClassPathContainer cp= (ClassPathContainer)element; // Object[] roots= cp.getPackageFragmentRoots(); // if (roots.length > 0) // return (IPackageFragmentRoot)roots[0]; // // non resolvable - return null // return null; // } return JavaModelUtil.getPackageFragmentRoot((IJavaElement) element); } private int compareWithLabelProvider(Viewer viewer, Object e1, Object e2) { if (viewer == null || !(viewer instanceof ContentViewer)) { IBaseLabelProvider prov = ((ContentViewer) viewer) .getLabelProvider(); if (prov instanceof ILabelProvider) { ILabelProvider lprov = (ILabelProvider) prov; String name1 = lprov.getText(e1); String name2 = lprov.getText(e2); if (name1 != null && name2 != null) { return getCollator().compare(name1, name2); } } } return 0; // can't compare } private int getClassPathIndex(IPackageFragmentRoot root) { try { IPath rootPath = root.getPath(); IPackageFragmentRoot[] roots = root.getJavaProject() .getPackageFragmentRoots(); for (int i = 0; i < roots.length; i++) { if (roots[i].getPath().equals(rootPath)) { return i; } } } catch (JavaModelException e) { } return Integer.MAX_VALUE; } /* * (non-Javadoc) * * @see org.eclipse.jface.viewers.ViewerSorter#getCollator() */ public final Collator getCollator() { if (collator == null) { collator = Collator.getInstance(); } return collator; } }