]>
Commit | Line | Data |
---|---|---|
1b2798f6 EK |
1 | /******************************************************************************* |
2 | * Copyright (c) 2000, 2011 IBM Corporation and others. | |
3 | * All rights reserved. This program and the accompanying materials | |
4 | * are made available under the terms of the Eclipse Public License v1.0 | |
5 | * which accompanies this distribution, and is available at | |
6 | * http://www.eclipse.org/legal/epl-v10.html | |
7 | * | |
8 | * Contributors: | |
9 | * IBM Corporation - initial API and implementation | |
10 | *******************************************************************************/ | |
11 | package org.eclipse.jdt.internal.ui.typehierarchy; | |
12 | ||
13 | import org.eclipse.jface.viewers.Viewer; | |
14 | import org.eclipse.jface.viewers.ViewerComparator; | |
15 | ||
16 | import org.eclipse.jdt.core.Flags; | |
17 | import org.eclipse.jdt.core.IMethod; | |
18 | import org.eclipse.jdt.core.IType; | |
19 | import org.eclipse.jdt.core.ITypeHierarchy; | |
20 | import org.eclipse.jdt.core.JavaModelException; | |
21 | ||
22 | import org.eclipse.jdt.internal.corext.util.JavaModelUtil; | |
23 | import org.eclipse.jdt.internal.corext.util.MethodOverrideTester; | |
24 | ||
25 | import org.eclipse.jdt.ui.JavaElementComparator; | |
26 | ||
27 | import org.eclipse.jdt.internal.ui.viewsupport.SourcePositionComparator; | |
28 | ||
29 | /** | |
30 | */ | |
31 | public abstract class AbstractHierarchyViewerSorter extends ViewerComparator { | |
32 | ||
33 | private static final int OTHER= 1; | |
34 | private static final int CLASS= 2; | |
35 | private static final int INTERFACE= 3; | |
36 | private static final int ANONYM= 4; | |
37 | ||
38 | private JavaElementComparator fNormalSorter; | |
39 | private SourcePositionComparator fSourcePositonSorter; | |
40 | ||
41 | public AbstractHierarchyViewerSorter() { | |
42 | fNormalSorter= new JavaElementComparator(); | |
43 | fSourcePositonSorter= new SourcePositionComparator(); | |
44 | } | |
45 | ||
46 | protected abstract ITypeHierarchy getHierarchy(IType type); | |
47 | public abstract boolean isSortByDefiningType(); | |
48 | public abstract boolean isSortAlphabetically(); | |
49 | ||
50 | ||
51 | protected int getTypeFlags(IType type) throws JavaModelException { | |
52 | return type.getFlags(); | |
53 | } | |
54 | ||
55 | /* (non-Javadoc) | |
56 | * @see org.eclipse.jface.viewers.ViewerSorter#category(java.lang.Object) | |
57 | */ | |
58 | @Override | |
59 | public int category(Object element) { | |
60 | if (element instanceof IType) { | |
61 | IType type= (IType) element; | |
62 | if (type.getElementName().length() == 0) { | |
63 | return ANONYM; | |
64 | } | |
65 | try { | |
66 | int flags= getTypeFlags(type); | |
67 | if (Flags.isInterface(flags)) { | |
68 | return INTERFACE; | |
69 | } else { | |
70 | return CLASS; | |
71 | } | |
72 | } catch (JavaModelException e) { | |
73 | // ignore | |
74 | } | |
75 | } | |
76 | return OTHER; | |
77 | } | |
78 | ||
79 | /* (non-Javadoc) | |
80 | * @see org.eclipse.jface.viewers.ViewerSorter#compare(null, null, null) | |
81 | */ | |
82 | @Override | |
83 | public int compare(Viewer viewer, Object e1, Object e2) { | |
84 | if (!isSortAlphabetically() && !isSortByDefiningType()) { | |
85 | return fSourcePositonSorter.compare(viewer, e1, e2); | |
86 | } | |
87 | ||
88 | int cat1= category(e1); | |
89 | int cat2= category(e2); | |
90 | ||
91 | if (cat1 != cat2) | |
92 | return cat1 - cat2; | |
93 | ||
94 | if (cat1 == OTHER) { // method or field | |
95 | if (isSortByDefiningType()) { | |
96 | try { | |
97 | IType def1= (e1 instanceof IMethod) ? getDefiningType((IMethod) e1) : null; | |
98 | IType def2= (e2 instanceof IMethod) ? getDefiningType((IMethod) e2) : null; | |
99 | if (def1 != null) { | |
100 | if (def2 != null) { | |
101 | if (!def2.equals(def1)) { | |
102 | return compareInHierarchy(def1, def2); | |
103 | } | |
104 | } else { | |
105 | return -1; | |
106 | } | |
107 | } else { | |
108 | if (def2 != null) { | |
109 | return 1; | |
110 | } | |
111 | } | |
112 | } catch (JavaModelException e) { | |
113 | // ignore, default to normal comparison | |
114 | } | |
115 | } | |
116 | if (isSortAlphabetically()) { | |
117 | return fNormalSorter.compare(viewer, e1, e2); // use appearance pref page settings | |
118 | } | |
119 | return 0; | |
120 | } else if (cat1 == ANONYM) { | |
121 | return 0; | |
122 | } else if (isSortAlphabetically()) { | |
123 | String name1= ((IType) e1).getElementName(); | |
124 | String name2= ((IType) e2).getElementName(); | |
125 | return getComparator().compare(name1, name2); | |
126 | } | |
127 | return 0; | |
128 | } | |
129 | ||
130 | private IType getDefiningType(IMethod method) throws JavaModelException { | |
131 | int flags= method.getFlags(); | |
132 | if (Flags.isPrivate(flags) || Flags.isStatic(flags) || method.isConstructor()) { | |
133 | return null; | |
134 | } | |
135 | ||
136 | IType declaringType= method.getDeclaringType(); | |
137 | ITypeHierarchy hierarchy= getHierarchy(declaringType); | |
138 | if (hierarchy != null) { | |
139 | MethodOverrideTester tester= new MethodOverrideTester(declaringType, hierarchy); | |
140 | IMethod res= tester.findDeclaringMethod(method, true); | |
141 | if (res != null) { | |
142 | return res.getDeclaringType(); | |
143 | } | |
144 | } | |
145 | return null; | |
146 | } | |
147 | ||
148 | ||
149 | private int compareInHierarchy(IType def1, IType def2) { | |
150 | if (JavaModelUtil.isSuperType(getHierarchy(def1), def2, def1)) { | |
151 | return 1; | |
152 | } else if (JavaModelUtil.isSuperType(getHierarchy(def2), def1, def2)) { | |
153 | return -1; | |
154 | } | |
155 | // interfaces after classes | |
156 | try { | |
157 | int flags1= getTypeFlags(def1); | |
158 | int flags2= getTypeFlags(def2); | |
159 | if (Flags.isInterface(flags1)) { | |
160 | if (!Flags.isInterface(flags2)) { | |
161 | return 1; | |
162 | } | |
163 | } else if (Flags.isInterface(flags2)) { | |
164 | return -1; | |
165 | } | |
166 | } catch (JavaModelException e) { | |
167 | // ignore | |
168 | } | |
169 | String name1= def1.getElementName(); | |
170 | String name2= def2.getElementName(); | |
171 | ||
172 | return getComparator().compare(name1, name2); | |
173 | } | |
174 | ||
175 | } |