1 12 package org.eclipse.jdt.internal.corext.callhierarchy; 13 14 import java.util.HashMap ; 15 import java.util.Iterator ; 16 import java.util.Map ; 17 18 import org.eclipse.core.runtime.Assert; 19 import org.eclipse.core.runtime.IProgressMonitor; 20 import org.eclipse.core.runtime.OperationCanceledException; 21 import org.eclipse.core.runtime.PlatformObject; 22 23 import org.eclipse.ui.model.IWorkbenchAdapter; 24 25 import org.eclipse.jdt.core.IJavaElement; 26 import org.eclipse.jdt.core.IMember; 27 28 29 import org.eclipse.jdt.internal.ui.callhierarchy.MethodWrapperWorkbenchAdapter; 30 31 36 public abstract class MethodWrapper extends PlatformObject { 37 private Map fElements = null; 38 39 44 private Map fMethodCache; 45 private MethodCall fMethodCall; 46 private MethodWrapper fParent; 47 private int fLevel; 48 49 52 public MethodWrapper(MethodWrapper parent, MethodCall methodCall) { 53 Assert.isNotNull(methodCall); 54 55 if (parent == null) { 56 setMethodCache(new HashMap ()); 57 fLevel = 1; 58 } else { 59 setMethodCache(parent.getMethodCache()); 60 fLevel = parent.getLevel() + 1; 61 } 62 63 this.fMethodCall = methodCall; 64 this.fParent = parent; 65 } 66 67 public Object getAdapter(Class adapter) { 68 if (adapter == IJavaElement.class) { 69 return getMember(); 70 } else if (adapter == IWorkbenchAdapter.class){ 71 return new MethodWrapperWorkbenchAdapter(this); 72 } else { 73 return null; 74 } 75 } 76 77 80 public MethodWrapper[] getCalls(IProgressMonitor progressMonitor) { 81 if (fElements == null) { 82 doFindChildren(progressMonitor); 83 } 84 85 MethodWrapper[] result = new MethodWrapper[fElements.size()]; 86 int i = 0; 87 88 for (Iterator iter = fElements.keySet().iterator(); iter.hasNext();) { 89 MethodCall methodCall = getMethodCallFromMap(fElements, iter.next()); 90 result[i++] = createMethodWrapper(methodCall); 91 } 92 93 return result; 94 } 95 96 public int getLevel() { 97 return fLevel; 98 } 99 100 public IMember getMember() { 101 return getMethodCall().getMember(); 102 } 103 104 public MethodCall getMethodCall() { 105 return fMethodCall; 106 } 107 108 public String getName() { 109 if (getMethodCall() != null) { 110 return getMethodCall().getMember().getElementName(); 111 } else { 112 return ""; } 114 } 115 116 public MethodWrapper getParent() { 117 return fParent; 118 } 119 120 public boolean equals(Object oth) { 121 if (this == oth) { 122 return true; 123 } 124 125 if (oth == null) { 126 return false; 127 } 128 129 if (oth instanceof MethodWrapperWorkbenchAdapter) { 130 oth= ((MethodWrapperWorkbenchAdapter) oth).getMethodWrapper(); 132 } 133 134 if (oth.getClass() != getClass()) { 135 return false; 136 } 137 138 MethodWrapper other = (MethodWrapper) oth; 139 140 if (this.fParent == null) { 141 if (other.fParent != null) { 142 return false; 143 } 144 } else { 145 if (!this.fParent.equals(other.fParent)) { 146 return false; 147 } 148 } 149 150 if (this.getMethodCall() == null) { 151 if (other.getMethodCall() != null) { 152 return false; 153 } 154 } else { 155 if (!this.getMethodCall().equals(other.getMethodCall())) { 156 return false; 157 } 158 } 159 160 return true; 161 } 162 163 public int hashCode() { 164 final int PRIME = 1000003; 165 int result = 0; 166 167 if (fParent != null) { 168 result = (PRIME * result) + fParent.hashCode(); 169 } 170 171 if (getMethodCall() != null) { 172 result = (PRIME * result) + getMethodCall().getMember().hashCode(); 173 } 174 175 return result; 176 } 177 178 private void setMethodCache(Map methodCache) { 179 fMethodCache = methodCache; 180 } 181 182 protected abstract String getTaskName(); 183 184 private void addCallToCache(MethodCall methodCall) { 185 Map cachedCalls = lookupMethod(this.getMethodCall()); 186 cachedCalls.put(methodCall.getKey(), methodCall); 187 } 188 189 protected abstract MethodWrapper createMethodWrapper(MethodCall methodCall); 190 191 private void doFindChildren(IProgressMonitor progressMonitor) { 192 Map existingResults = lookupMethod(getMethodCall()); 193 194 if (existingResults != null) { 195 fElements = new HashMap (); 196 fElements.putAll(existingResults); 197 } else { 198 initCalls(); 199 200 if (progressMonitor != null) { 201 progressMonitor.beginTask(getTaskName(), 100); 202 } 203 204 try { 205 performSearch(progressMonitor); 206 } finally { 207 if (progressMonitor != null) { 208 progressMonitor.done(); 209 } 210 } 211 212 } 215 } 216 217 223 public boolean isRecursive() { 224 MethodWrapper current = getParent(); 225 226 while (current != null) { 227 if (getMember().getHandleIdentifier().equals(current.getMember() 228 .getHandleIdentifier())) { 229 return true; 230 } 231 232 current = current.getParent(); 233 } 234 235 return false; 236 } 237 238 243 protected abstract Map findChildren(IProgressMonitor progressMonitor); 244 245 private Map getMethodCache() { 246 return fMethodCache; 247 } 248 249 private void initCalls() { 250 this.fElements = new HashMap (); 251 252 initCacheForMethod(); 253 } 254 255 259 private Map lookupMethod(MethodCall methodCall) { 260 return (Map ) getMethodCache().get(methodCall.getKey()); 261 } 262 263 private void performSearch(IProgressMonitor progressMonitor) { 264 fElements = findChildren(progressMonitor); 265 266 for (Iterator iter = fElements.keySet().iterator(); iter.hasNext();) { 267 checkCanceled(progressMonitor); 268 269 MethodCall methodCall = getMethodCallFromMap(fElements, iter.next()); 270 addCallToCache(methodCall); 271 } 272 } 273 274 private MethodCall getMethodCallFromMap(Map elements, Object key) { 275 return (MethodCall) elements.get(key); 276 } 277 278 private void initCacheForMethod() { 279 Map cachedCalls = new HashMap (); 280 getMethodCache().put(this.getMethodCall().getKey(), cachedCalls); 281 } 282 283 291 protected void checkCanceled(IProgressMonitor progressMonitor) { 292 if (progressMonitor != null && progressMonitor.isCanceled()) { 293 throw new OperationCanceledException(); 294 } 295 } 296 297 303 public void accept(CallHierarchyVisitor visitor, IProgressMonitor progressMonitor) { 304 if (getParent() != null && getParent().isRecursive()) { 305 return; 306 } 307 checkCanceled(progressMonitor); 308 309 visitor.preVisit(this); 310 if (visitor.visit(this)) { 311 MethodWrapper[] methodWrappers= getCalls(progressMonitor); 312 for (int i= 0; i < methodWrappers.length; i++) { 313 methodWrappers[i].accept(visitor, progressMonitor); 314 } 315 } 316 visitor.postVisit(this); 317 318 if (progressMonitor != null) { 319 progressMonitor.worked(1); 320 } 321 } 322 } 323 | Popular Tags |