1 11 package org.eclipse.jdt.internal.core.hierarchy; 12 13 import java.util.*; 14 import java.util.ArrayList ; 15 import java.util.HashMap ; 16 import java.util.Iterator ; 17 18 import org.eclipse.jdt.core.*; 19 import org.eclipse.jdt.core.IJavaElementDelta; 20 import org.eclipse.jdt.core.IType; 21 import org.eclipse.jdt.core.JavaModelException; 22 import org.eclipse.jdt.internal.core.JavaElement; 23 import org.eclipse.jdt.internal.core.SimpleDelta; 24 25 28 public class ChangeCollector { 29 30 33 HashMap changes = new HashMap (); 34 35 TypeHierarchy hierarchy; 36 37 public ChangeCollector(TypeHierarchy hierarchy) { 38 this.hierarchy = hierarchy; 39 } 40 41 44 private void addAffectedChildren(IJavaElementDelta delta) throws JavaModelException { 45 IJavaElementDelta[] children = delta.getAffectedChildren(); 46 for (int i = 0, length = children.length; i < length; i++) { 47 IJavaElementDelta child = children[i]; 48 IJavaElement childElement = child.getElement(); 49 switch (childElement.getElementType()) { 50 case IJavaElement.IMPORT_CONTAINER: 51 addChange((IImportContainer)childElement, child); 52 break; 53 case IJavaElement.IMPORT_DECLARATION: 54 addChange((IImportDeclaration)childElement, child); 55 break; 56 case IJavaElement.TYPE: 57 addChange((IType)childElement, child); 58 break; 59 case IJavaElement.INITIALIZER: 60 case IJavaElement.FIELD: 61 case IJavaElement.METHOD: 62 addChange((IMember)childElement, child); 63 break; 64 } 65 } 66 } 67 68 71 public void addChange(ICompilationUnit cu, IJavaElementDelta newDelta) throws JavaModelException { 72 int newKind = newDelta.getKind(); 73 switch (newKind) { 74 case IJavaElementDelta.ADDED: 75 ArrayList allTypes = new ArrayList (); 76 getAllTypesFromElement(cu, allTypes); 77 for (int i = 0, length = allTypes.size(); i < length; i++) { 78 IType type = (IType)allTypes.get(i); 79 addTypeAddition(type, (SimpleDelta)this.changes.get(type)); 80 } 81 break; 82 case IJavaElementDelta.REMOVED: 83 allTypes = new ArrayList (); 84 getAllTypesFromHierarchy((JavaElement)cu, allTypes); 85 for (int i = 0, length = allTypes.size(); i < length; i++) { 86 IType type = (IType)allTypes.get(i); 87 addTypeRemoval(type, (SimpleDelta)this.changes.get(type)); 88 } 89 break; 90 case IJavaElementDelta.CHANGED: 91 addAffectedChildren(newDelta); 92 break; 93 } 94 } 95 96 private void addChange(IImportContainer importContainer, IJavaElementDelta newDelta) throws JavaModelException { 97 int newKind = newDelta.getKind(); 98 if (newKind == IJavaElementDelta.CHANGED) { 99 addAffectedChildren(newDelta); 100 return; 101 } 102 SimpleDelta existingDelta = (SimpleDelta)this.changes.get(importContainer); 103 if (existingDelta != null) { 104 switch (newKind) { 105 case IJavaElementDelta.ADDED: 106 if (existingDelta.getKind() == IJavaElementDelta.REMOVED) { 107 this.changes.remove(importContainer); 109 } 110 break; 111 case IJavaElementDelta.REMOVED: 112 if (existingDelta.getKind() == IJavaElementDelta.ADDED) { 113 this.changes.remove(importContainer); 115 } 116 break; 117 } 119 } else { 120 SimpleDelta delta = new SimpleDelta(); 121 switch (newKind) { 122 case IJavaElementDelta.ADDED: 123 delta.added(); 124 break; 125 case IJavaElementDelta.REMOVED: 126 delta.removed(); 127 break; 128 } 129 this.changes.put(importContainer, delta); 130 } 131 } 132 133 private void addChange(IImportDeclaration importDecl, IJavaElementDelta newDelta) { 134 SimpleDelta existingDelta = (SimpleDelta)this.changes.get(importDecl); 135 int newKind = newDelta.getKind(); 136 if (existingDelta != null) { 137 switch (newKind) { 138 case IJavaElementDelta.ADDED: 139 if (existingDelta.getKind() == IJavaElementDelta.REMOVED) { 140 this.changes.remove(importDecl); 142 } 143 break; 144 case IJavaElementDelta.REMOVED: 145 if (existingDelta.getKind() == IJavaElementDelta.ADDED) { 146 this.changes.remove(importDecl); 148 } 149 break; 150 } 152 } else { 153 SimpleDelta delta = new SimpleDelta(); 154 switch (newKind) { 155 case IJavaElementDelta.ADDED: 156 delta.added(); 157 break; 158 case IJavaElementDelta.REMOVED: 159 delta.removed(); 160 break; 161 } 162 this.changes.put(importDecl, delta); 163 } 164 } 165 166 169 private void addChange(IMember member, IJavaElementDelta newDelta) throws JavaModelException { 170 int newKind = newDelta.getKind(); 171 switch (newKind) { 172 case IJavaElementDelta.ADDED: 173 ArrayList allTypes = new ArrayList (); 174 getAllTypesFromElement(member, allTypes); 175 for (int i = 0, length = allTypes.size(); i < length; i++) { 176 IType innerType = (IType)allTypes.get(i); 177 addTypeAddition(innerType, (SimpleDelta)this.changes.get(innerType)); 178 } 179 break; 180 case IJavaElementDelta.REMOVED: 181 allTypes = new ArrayList (); 182 getAllTypesFromHierarchy((JavaElement)member, allTypes); 183 for (int i = 0, length = allTypes.size(); i < length; i++) { 184 IType type = (IType)allTypes.get(i); 185 addTypeRemoval(type, (SimpleDelta)this.changes.get(type)); 186 } 187 break; 188 case IJavaElementDelta.CHANGED: 189 addAffectedChildren(newDelta); 190 break; 191 } 192 } 193 194 197 private void addChange(IType type, IJavaElementDelta newDelta) throws JavaModelException { 198 int newKind = newDelta.getKind(); 199 SimpleDelta existingDelta = (SimpleDelta)this.changes.get(type); 200 switch (newKind) { 201 case IJavaElementDelta.ADDED: 202 addTypeAddition(type, existingDelta); 203 ArrayList allTypes = new ArrayList (); 204 getAllTypesFromElement(type, allTypes); 205 for (int i = 0, length = allTypes.size(); i < length; i++) { 206 IType innerType = (IType)allTypes.get(i); 207 addTypeAddition(innerType, (SimpleDelta)this.changes.get(innerType)); 208 } 209 break; 210 case IJavaElementDelta.REMOVED: 211 addTypeRemoval(type, existingDelta); 212 allTypes = new ArrayList (); 213 getAllTypesFromHierarchy((JavaElement)type, allTypes); 214 for (int i = 0, length = allTypes.size(); i < length; i++) { 215 IType innerType = (IType)allTypes.get(i); 216 addTypeRemoval(innerType, (SimpleDelta)this.changes.get(innerType)); 217 } 218 break; 219 case IJavaElementDelta.CHANGED: 220 addTypeChange(type, newDelta.getFlags(), existingDelta); 221 addAffectedChildren(newDelta); 222 break; 223 } 224 } 225 226 private void addTypeAddition(IType type, SimpleDelta existingDelta) throws JavaModelException { 227 if (existingDelta != null) { 228 switch (existingDelta.getKind()) { 229 case IJavaElementDelta.REMOVED: 230 boolean hasChange = false; 232 if (hasSuperTypeChange(type)) { 233 existingDelta.superTypes(); 234 hasChange = true; 235 } 236 if (hasVisibilityChange(type)) { 237 existingDelta.modifiers(); 238 hasChange = true; 239 } 240 if (!hasChange) { 241 this.changes.remove(type); 242 } 243 break; 244 } 247 } else { 248 String typeName = type.getElementName(); 250 if (this.hierarchy.hasSupertype(typeName) 251 || this.hierarchy.subtypesIncludeSupertypeOf(type) 252 || this.hierarchy.missingTypes.contains(typeName)) { 253 SimpleDelta delta = new SimpleDelta(); 254 delta.added(); 255 this.changes.put(type, delta); 256 } 257 } 258 } 259 260 private void addTypeChange(IType type, int newFlags, SimpleDelta existingDelta) throws JavaModelException { 261 if (existingDelta != null) { 262 switch (existingDelta.getKind()) { 263 case IJavaElementDelta.CHANGED: 264 int existingFlags = existingDelta.getFlags(); 266 boolean hasChange = false; 267 if ((existingFlags & IJavaElementDelta.F_SUPER_TYPES) != 0 268 && hasSuperTypeChange(type)) { 269 existingDelta.superTypes(); 270 hasChange = true; 271 } 272 if ((existingFlags & IJavaElementDelta.F_MODIFIERS) != 0 273 && hasVisibilityChange(type)) { 274 existingDelta.modifiers(); 275 hasChange = true; 276 } 277 if (!hasChange) { 278 this.changes.remove(type); 280 } 281 break; 282 } 285 } else { 286 SimpleDelta typeDelta = null; 288 if ((newFlags & IJavaElementDelta.F_SUPER_TYPES) != 0 289 && this.hierarchy.includesTypeOrSupertype(type)) { 290 typeDelta = new SimpleDelta(); 291 typeDelta.superTypes(); 292 } 293 if ((newFlags & IJavaElementDelta.F_MODIFIERS) != 0 294 && (this.hierarchy.hasSupertype(type.getElementName()) 295 || type.equals(this.hierarchy.focusType))) { 296 if (typeDelta == null) { 297 typeDelta = new SimpleDelta(); 298 } 299 typeDelta.modifiers(); 300 } 301 if (typeDelta != null) { 302 this.changes.put(type, typeDelta); 303 } 304 } 305 } 306 307 private void addTypeRemoval(IType type, SimpleDelta existingDelta) { 308 if (existingDelta != null) { 309 switch (existingDelta.getKind()) { 310 case IJavaElementDelta.ADDED: 311 this.changes.remove(type); 313 break; 314 case IJavaElementDelta.CHANGED: 315 existingDelta.removed(); 317 break; 318 } 320 } else { 321 if (this.hierarchy.contains(type)) { 323 SimpleDelta typeDelta = new SimpleDelta(); 324 typeDelta.removed(); 325 this.changes.put(type, typeDelta); 326 } 327 } 328 } 329 330 333 private void getAllTypesFromElement(IJavaElement element, ArrayList allTypes) throws JavaModelException { 334 switch (element.getElementType()) { 335 case IJavaElement.COMPILATION_UNIT: 336 IType[] types = ((ICompilationUnit)element).getTypes(); 337 for (int i = 0, length = types.length; i < length; i++) { 338 IType type = types[i]; 339 allTypes.add(type); 340 getAllTypesFromElement(type, allTypes); 341 } 342 break; 343 case IJavaElement.TYPE: 344 types = ((IType)element).getTypes(); 345 for (int i = 0, length = types.length; i < length; i++) { 346 IType type = types[i]; 347 allTypes.add(type); 348 getAllTypesFromElement(type, allTypes); 349 } 350 break; 351 case IJavaElement.INITIALIZER: 352 case IJavaElement.FIELD: 353 case IJavaElement.METHOD: 354 IJavaElement[] children = ((IMember)element).getChildren(); 355 for (int i = 0, length = children.length; i < length; i++) { 356 IType type = (IType)children[i]; 357 allTypes.add(type); 358 getAllTypesFromElement(type, allTypes); 359 } 360 break; 361 } 362 } 363 364 367 private void getAllTypesFromHierarchy(JavaElement element, ArrayList allTypes) { 368 switch (element.getElementType()) { 369 case IJavaElement.COMPILATION_UNIT: 370 ArrayList types = (ArrayList )this.hierarchy.files.get(element); 371 if (types != null) { 372 allTypes.addAll(types); 373 } 374 break; 375 case IJavaElement.TYPE: 376 case IJavaElement.INITIALIZER: 377 case IJavaElement.FIELD: 378 case IJavaElement.METHOD: 379 types = (ArrayList )this.hierarchy.files.get(((IMember)element).getCompilationUnit()); 380 if (types != null) { 381 for (int i = 0, length = types.size(); i < length; i++) { 382 IType type = (IType)types.get(i); 383 if (element.isAncestorOf(type)) { 384 allTypes.add(type); 385 } 386 } 387 } 388 break; 389 } 390 } 391 392 private boolean hasSuperTypeChange(IType type) throws JavaModelException { 393 IType superclass = this.hierarchy.getSuperclass(type); 395 String existingSuperclassName = superclass == null ? null : superclass.getElementName(); 396 String newSuperclassName = type.getSuperclassName(); 397 if (existingSuperclassName != null && !existingSuperclassName.equals(newSuperclassName)) { 398 return true; 399 } 400 401 IType[] existingSuperInterfaces = this.hierarchy.getSuperInterfaces(type); 403 String [] newSuperInterfaces = type.getSuperInterfaceNames(); 404 if (existingSuperInterfaces.length != newSuperInterfaces.length) { 405 return true; 406 } 407 for (int i = 0, length = newSuperInterfaces.length; i < length; i++) { 408 String superInterfaceName = newSuperInterfaces[i]; 409 if (!superInterfaceName.equals(newSuperInterfaces[i])) { 410 return true; 411 } 412 } 413 414 return false; 415 } 416 417 private boolean hasVisibilityChange(IType type) throws JavaModelException { 418 int existingFlags = this.hierarchy.getCachedFlags(type); 419 int newFlags = type.getFlags(); 420 return existingFlags != newFlags; 421 } 422 423 426 public boolean needsRefresh() { 427 return changes.size() != 0; 428 } 429 430 public String toString() { 431 StringBuffer buffer = new StringBuffer (); 432 Iterator iterator = this.changes.entrySet().iterator(); 433 while (iterator.hasNext()) { 434 Map.Entry entry = (Map.Entry )iterator.next(); 435 buffer.append(((JavaElement)entry.getKey()).toDebugString()); 436 buffer.append(entry.getValue()); 437 if (iterator.hasNext()) { 438 buffer.append('\n'); 439 } 440 } 441 return buffer.toString(); 442 } 443 } 444 | Popular Tags |