blob: d2b208097d6318f50ec2b89921dac137625b5d5a [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2000, 2006 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.jdt.internal.ui.typehierarchy;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.viewers.ViewerSorter;
import org.eclipse.jdt.core.Flags;
import org.eclipse.jdt.core.IMethod;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.ITypeHierarchy;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.ui.JavaElementSorter;
import org.eclipse.jdt.internal.ui.viewsupport.SourcePositionSorter;
import org.eclipse.jdt.internal.corext.util.JavaModelUtil;
import org.eclipse.jdt.internal.corext.util.MethodOverrideTester;
/**
*/
public abstract class AbstractHierarchyViewerSorter extends ViewerSorter {
private static final int OTHER= 1;
private static final int CLASS= 2;
private static final int INTERFACE= 3;
private static final int ANONYM= 4;
private JavaElementSorter fNormalSorter;
private SourcePositionSorter fSourcePositonSorter;
public AbstractHierarchyViewerSorter() {
fNormalSorter= new JavaElementSorter();
fSourcePositonSorter= new SourcePositionSorter();
}
protected abstract ITypeHierarchy getHierarchy(IType type);
public abstract boolean isSortByDefiningType();
public abstract boolean isSortAlphabetically();
protected int getTypeFlags(IType type) throws JavaModelException {
return type.getFlags();
}
/* (non-Javadoc)
* @see org.eclipse.jface.viewers.ViewerSorter#category(java.lang.Object)
*/
public int category(Object element) {
if (element instanceof IType) {
IType type= (IType) element;
if (type.getElementName().length() == 0) {
return ANONYM;
}
try {
int flags= getTypeFlags(type);
if (Flags.isInterface(flags)) {
return INTERFACE;
} else {
return CLASS;
}
} catch (JavaModelException e) {
// ignore
}
}
return OTHER;
}
/* (non-Javadoc)
* @see org.eclipse.jface.viewers.ViewerSorter#compare(null, null, null)
*/
public int compare(Viewer viewer, Object e1, Object e2) {
if (!isSortAlphabetically() && !isSortByDefiningType()) {
return fSourcePositonSorter.compare(viewer, e1, e2);
}
int cat1= category(e1);
int cat2= category(e2);
if (cat1 != cat2)
return cat1 - cat2;
if (cat1 == OTHER) { // method or field
if (isSortByDefiningType()) {
try {
IType def1= (e1 instanceof IMethod) ? getDefiningType((IMethod) e1) : null;
IType def2= (e2 instanceof IMethod) ? getDefiningType((IMethod) e2) : null;
if (def1 != null) {
if (def2 != null) {
if (!def2.equals(def1)) {
return compareInHierarchy(def1, def2);
}
} else {
return -1;
}
} else {
if (def2 != null) {
return 1;
}
}
} catch (JavaModelException e) {
// ignore, default to normal comparison
}
}
if (isSortAlphabetically()) {
return fNormalSorter.compare(viewer, e1, e2); // use appearance pref page settings
}
return 0;
} else if (cat1 == ANONYM) {
return 0;
} else if (isSortAlphabetically()) {
String name1= ((IType) e1).getElementName();
String name2= ((IType) e2).getElementName();
return getCollator().compare(name1, name2);
}
return 0;
}
private IType getDefiningType(IMethod method) throws JavaModelException {
int flags= method.getFlags();
if (Flags.isPrivate(flags) || Flags.isStatic(flags) || method.isConstructor()) {
return null;
}
IType declaringType= method.getDeclaringType();
MethodOverrideTester tester= new MethodOverrideTester(declaringType, getHierarchy(declaringType));
IMethod res= tester.findDeclaringMethod(method, true);
if (res == null) {
return null;
}
return res.getDeclaringType();
}
private int compareInHierarchy(IType def1, IType def2) {
if (JavaModelUtil.isSuperType(getHierarchy(def1), def2, def1)) {
return 1;
} else if (JavaModelUtil.isSuperType(getHierarchy(def2), def1, def2)) {
return -1;
}
// interfaces after classes
try {
int flags1= getTypeFlags(def1);
int flags2= getTypeFlags(def2);
if (Flags.isInterface(flags1)) {
if (!Flags.isInterface(flags2)) {
return 1;
}
} else if (Flags.isInterface(flags2)) {
return -1;
}
} catch (JavaModelException e) {
// ignore
}
String name1= def1.getElementName();
String name2= def2.getElementName();
return getCollator().compare(name1, name2);
}
}