1 11 package org.eclipse.jdt.internal.ui.typehierarchy; 12 13 import java.util.ArrayList ; 14 import java.util.List ; 15 16 import org.eclipse.core.runtime.Assert; 17 18 import org.eclipse.jface.viewers.ITreeContentProvider; 19 import org.eclipse.jface.viewers.TreeViewer; 20 import org.eclipse.jface.viewers.Viewer; 21 import org.eclipse.jface.viewers.ViewerFilter; 22 23 import org.eclipse.jdt.core.IJavaElement; 24 import org.eclipse.jdt.core.IMember; 25 import org.eclipse.jdt.core.IMethod; 26 import org.eclipse.jdt.core.IType; 27 import org.eclipse.jdt.core.ITypeHierarchy; 28 import org.eclipse.jdt.core.JavaModelException; 29 30 import org.eclipse.jdt.internal.corext.util.JavaModelUtil; 31 import org.eclipse.jdt.internal.corext.util.MethodOverrideTester; 32 33 import org.eclipse.jdt.ui.IWorkingCopyProvider; 34 35 40 public abstract class TypeHierarchyContentProvider implements ITreeContentProvider, IWorkingCopyProvider { 41 protected static final Object [] NO_ELEMENTS= new Object [0]; 42 43 protected TypeHierarchyLifeCycle fTypeHierarchy; 44 protected IMember[] fMemberFilter; 45 46 protected TreeViewer fViewer; 47 48 private ViewerFilter fWorkingSetFilter; 49 private MethodOverrideTester fMethodOverrideTester; 50 private ITypeHierarchyLifeCycleListener fTypeHierarchyLifeCycleListener; 51 52 53 public TypeHierarchyContentProvider(TypeHierarchyLifeCycle lifecycle) { 54 fTypeHierarchy= lifecycle; 55 fMemberFilter= null; 56 fWorkingSetFilter= null; 57 fMethodOverrideTester= null; 58 fTypeHierarchyLifeCycleListener= new ITypeHierarchyLifeCycleListener() { 59 public void typeHierarchyChanged(TypeHierarchyLifeCycle typeHierarchyProvider, IType[] changedTypes) { 60 if (changedTypes == null) { 61 fMethodOverrideTester= null; 62 } 63 } 64 }; 65 lifecycle.addChangedListener(fTypeHierarchyLifeCycleListener); 66 } 67 68 74 public final void setMemberFilter(IMember[] memberFilter) { 75 fMemberFilter= memberFilter; 76 } 77 78 private boolean initializeMethodOverrideTester(IMethod filterMethod, IType typeToFindIn) { 79 IType filterType= filterMethod.getDeclaringType(); 80 ITypeHierarchy hierarchy= fTypeHierarchy.getHierarchy(); 81 82 boolean filterOverrides= JavaModelUtil.isSuperType(hierarchy, typeToFindIn, filterType); 83 IType focusType= filterOverrides ? filterType : typeToFindIn; 84 85 if (fMethodOverrideTester == null || !fMethodOverrideTester.getFocusType().equals(focusType)) { 86 fMethodOverrideTester= new MethodOverrideTester(focusType, hierarchy); 87 } 88 return filterOverrides; 89 } 90 91 private void addCompatibleMethods(IMethod filterMethod, IType typeToFindIn, List children) throws JavaModelException { 92 boolean filterMethodOverrides= initializeMethodOverrideTester(filterMethod, typeToFindIn); 93 IMethod[] methods= typeToFindIn.getMethods(); 94 for (int i= 0; i < methods.length; i++) { 95 IMethod curr= methods[i]; 96 if (isCompatibleMethod(filterMethod, curr, filterMethodOverrides) && !children.contains(curr)) { 97 children.add(curr); 98 } 99 } 100 } 101 102 private boolean hasCompatibleMethod(IMethod filterMethod, IType typeToFindIn) throws JavaModelException { 103 boolean filterMethodOverrides= initializeMethodOverrideTester(filterMethod, typeToFindIn); 104 IMethod[] methods= typeToFindIn.getMethods(); 105 for (int i= 0; i < methods.length; i++) { 106 if (isCompatibleMethod(filterMethod, methods[i], filterMethodOverrides)) { 107 return true; 108 } 109 } 110 return false; 111 } 112 113 private boolean isCompatibleMethod(IMethod filterMethod, IMethod method, boolean filterOverrides) throws JavaModelException { 114 if (filterOverrides) { 115 return fMethodOverrideTester.isSubsignature(filterMethod, method); 116 } else { 117 return fMethodOverrideTester.isSubsignature(method, filterMethod); 118 } 119 } 120 121 124 public IMember[] getMemberFilter() { 125 return fMemberFilter; 126 } 127 128 131 public void setWorkingSetFilter(ViewerFilter filter) { 132 fWorkingSetFilter= filter; 133 } 134 135 136 protected final ITypeHierarchy getHierarchy() { 137 return fTypeHierarchy.getHierarchy(); 138 } 139 140 141 144 public boolean providesWorkingCopies() { 145 return true; 146 } 147 148 149 153 public Object [] getElements(Object parent) { 154 ArrayList types= new ArrayList (); 155 getRootTypes(types); 156 for (int i= types.size() - 1; i >= 0; i--) { 157 IType curr= (IType) types.get(i); 158 try { 159 if (!isInTree(curr)) { 160 types.remove(i); 161 } 162 } catch (JavaModelException e) { 163 } 165 } 166 return types.toArray(); 167 } 168 169 protected void getRootTypes(List res) { 170 ITypeHierarchy hierarchy= getHierarchy(); 171 if (hierarchy != null) { 172 IType input= hierarchy.getType(); 173 if (input != null) { 174 res.add(input); 175 } 176 } 178 } 179 180 183 protected abstract void getTypesInHierarchy(IType type, List res); 184 185 188 protected abstract IType getParentType(IType type); 189 190 191 private boolean isInScope(IType type) { 192 if (fWorkingSetFilter != null && !fWorkingSetFilter.select(null, null, type)) { 193 return false; 194 } 195 196 IJavaElement input= fTypeHierarchy.getInputElement(); 197 int inputType= input.getElementType(); 198 if (inputType == IJavaElement.TYPE) { 199 return true; 200 } 201 202 IJavaElement parent= type.getAncestor(input.getElementType()); 203 if (inputType == IJavaElement.PACKAGE_FRAGMENT) { 204 if (parent == null || parent.getElementName().equals(input.getElementName())) { 205 return true; 206 } 207 } else if (input.equals(parent)) { 208 return true; 209 } 210 return false; 211 } 212 213 217 public Object [] getChildren(Object element) { 218 if (element instanceof IType) { 219 try { 220 IType type= (IType)element; 221 222 List children= new ArrayList (); 223 if (fMemberFilter != null) { 224 addFilteredMemberChildren(type, children); 225 } 226 227 addTypeChildren(type, children); 228 229 return children.toArray(); 230 } catch (JavaModelException e) { 231 } 233 } 234 return NO_ELEMENTS; 235 } 236 237 240 public boolean hasChildren(Object element) { 241 if (element instanceof IType) { 242 try { 243 IType type= (IType) element; 244 return hasTypeChildren(type) || (fMemberFilter != null && hasMemberFilterChildren(type)); 245 } catch (JavaModelException e) { 246 return false; 247 } 248 } 249 return false; 250 } 251 252 private void addFilteredMemberChildren(IType parent, List children) throws JavaModelException { 253 for (int i= 0; i < fMemberFilter.length; i++) { 254 IMember member= fMemberFilter[i]; 255 if (parent.equals(member.getDeclaringType())) { 256 if (!children.contains(member)) { 257 children.add(member); 258 } 259 } else if (member instanceof IMethod) { 260 addCompatibleMethods((IMethod) member, parent, children); 261 } 262 } 263 } 264 265 private void addTypeChildren(IType type, List children) throws JavaModelException { 266 ArrayList types= new ArrayList (); 267 getTypesInHierarchy(type, types); 268 int len= types.size(); 269 for (int i= 0; i < len; i++) { 270 IType curr= (IType) types.get(i); 271 if (isInTree(curr)) { 272 children.add(curr); 273 } 274 } 275 } 276 277 protected final boolean isInTree(IType type) throws JavaModelException { 278 if (isInScope(type)) { 279 if (fMemberFilter != null) { 280 return hasMemberFilterChildren(type) || hasTypeChildren(type); 281 } else { 282 return true; 283 } 284 } 285 return hasTypeChildren(type); 286 } 287 288 private boolean hasMemberFilterChildren(IType type) throws JavaModelException { 289 for (int i= 0; i < fMemberFilter.length; i++) { 290 IMember member= fMemberFilter[i]; 291 if (type.equals(member.getDeclaringType())) { 292 return true; 293 } else if (member instanceof IMethod) { 294 if (hasCompatibleMethod((IMethod) member, type)) { 295 return true; 296 } 297 } 298 } 299 return false; 300 } 301 302 private boolean hasTypeChildren(IType type) throws JavaModelException { 303 ArrayList types= new ArrayList (); 304 getTypesInHierarchy(type, types); 305 int len= types.size(); 306 for (int i= 0; i < len; i++) { 307 IType curr= (IType) types.get(i); 308 if (isInTree(curr)) { 309 return true; 310 } 311 } 312 return false; 313 } 314 315 318 public void inputChanged(Viewer part, Object oldInput, Object newInput) { 319 Assert.isTrue(part instanceof TreeViewer); 320 fViewer= (TreeViewer)part; 321 } 322 323 326 public void dispose() { 327 fTypeHierarchy.removeChangedListener(fTypeHierarchyLifeCycleListener); 328 329 } 330 331 334 public Object getParent(Object element) { 335 if (element instanceof IMember) { 336 IMember member= (IMember) element; 337 if (member.getElementType() == IJavaElement.TYPE) { 338 return getParentType((IType)member); 339 } 340 return member.getDeclaringType(); 341 } 342 return null; 343 } 344 345 protected final boolean isAnonymous(IType type) { 346 return type.getElementName().length() == 0; 347 } 348 349 protected final boolean isAnonymousFromInterface(IType type) { 350 return isAnonymous(type) && fTypeHierarchy.getHierarchy().getSuperInterfaces(type).length != 0; 351 } 352 353 protected final boolean isObject(IType type) { 354 return "Object".equals(type.getElementName()) && type.getDeclaringType() == null && "java.lang".equals(type.getPackageFragment().getElementName()); } 356 357 358 359 360 361 } 362 | Popular Tags |