1 11 package org.eclipse.jdt.internal.corext.codemanipulation; 12 13 import java.util.ArrayList ; 14 import java.util.HashMap ; 15 import java.util.HashSet ; 16 import java.util.List ; 17 import java.util.Set ; 18 19 import org.eclipse.text.edits.DeleteEdit; 20 import org.eclipse.text.edits.InsertEdit; 21 import org.eclipse.text.edits.MalformedTreeException; 22 import org.eclipse.text.edits.MultiTextEdit; 23 import org.eclipse.text.edits.TextEdit; 24 25 import org.eclipse.core.runtime.CoreException; 26 import org.eclipse.core.runtime.IPath; 27 import org.eclipse.core.runtime.IProgressMonitor; 28 import org.eclipse.core.runtime.IStatus; 29 import org.eclipse.core.runtime.NullProgressMonitor; 30 import org.eclipse.core.runtime.SubProgressMonitor; 31 32 import org.eclipse.core.filebuffers.FileBuffers; 33 import org.eclipse.core.filebuffers.ITextFileBufferManager; 34 35 import org.eclipse.core.resources.IFile; 36 37 import org.eclipse.jface.text.BadLocationException; 38 import org.eclipse.jface.text.Document; 39 import org.eclipse.jface.text.DocumentRewriteSession; 40 import org.eclipse.jface.text.DocumentRewriteSessionType; 41 import org.eclipse.jface.text.IDocument; 42 import org.eclipse.jface.text.IDocumentExtension4; 43 import org.eclipse.jface.text.IRegion; 44 import org.eclipse.jface.text.Region; 45 import org.eclipse.jface.text.TextUtilities; 46 47 import org.eclipse.jdt.core.Flags; 48 import org.eclipse.jdt.core.ICompilationUnit; 49 import org.eclipse.jdt.core.IImportContainer; 50 import org.eclipse.jdt.core.IImportDeclaration; 51 import org.eclipse.jdt.core.IJavaElement; 52 import org.eclipse.jdt.core.IPackageDeclaration; 53 import org.eclipse.jdt.core.ISourceRange; 54 import org.eclipse.jdt.core.IType; 55 import org.eclipse.jdt.core.JavaModelException; 56 import org.eclipse.jdt.core.Signature; 57 import org.eclipse.jdt.core.ToolFactory; 58 import org.eclipse.jdt.core.dom.AST; 59 import org.eclipse.jdt.core.dom.IBinding; 60 import org.eclipse.jdt.core.dom.IMethodBinding; 61 import org.eclipse.jdt.core.dom.ITypeBinding; 62 import org.eclipse.jdt.core.dom.IVariableBinding; 63 import org.eclipse.jdt.core.dom.ParameterizedType; 64 import org.eclipse.jdt.core.dom.PrimitiveType; 65 import org.eclipse.jdt.core.dom.Type; 66 import org.eclipse.jdt.core.dom.WildcardType; 67 import org.eclipse.jdt.core.formatter.CodeFormatter; 68 import org.eclipse.jdt.core.search.IJavaSearchConstants; 69 import org.eclipse.jdt.core.search.IJavaSearchScope; 70 import org.eclipse.jdt.core.search.SearchEngine; 71 import org.eclipse.jdt.core.search.TypeNameRequestor; 72 73 import org.eclipse.jdt.internal.corext.ValidateEditException; 74 import org.eclipse.jdt.internal.corext.dom.ASTNodeFactory; 75 import org.eclipse.jdt.internal.corext.dom.Bindings; 76 import org.eclipse.jdt.internal.corext.util.JavaModelUtil; 77 import org.eclipse.jdt.internal.corext.util.Resources; 78 import org.eclipse.jdt.internal.corext.util.Strings; 79 80 import org.eclipse.jdt.internal.ui.JavaPlugin; 81 import org.eclipse.jdt.internal.ui.JavaUIStatus; 82 83 88 public final class ImportsStructure implements IImportsStructure { 89 90 private ICompilationUnit fCompilationUnit; 91 private ArrayList fPackageEntries; 92 93 private int fImportOnDemandThreshold; 94 95 private boolean fFilterImplicitImports; 96 private boolean fFindAmbiguousImports; 97 98 private List fImportsCreated; 99 private List fStaticImportsCreated; 100 private boolean fHasChanges= false; 101 private IRegion fReplaceRange; 102 103 private static final String JAVA_LANG= "java.lang"; 105 115 public ImportsStructure(ICompilationUnit cu, String [] preferenceOrder, int importThreshold, boolean restoreExistingImports) throws CoreException { 116 fCompilationUnit= cu; 117 JavaModelUtil.reconcile(cu); 118 119 IImportContainer container= cu.getImportContainer(); 120 121 fImportOnDemandThreshold= importThreshold; 122 fFilterImplicitImports= true; 123 fFindAmbiguousImports= true; 125 fPackageEntries= new ArrayList (20); 126 fImportsCreated= null; fStaticImportsCreated= null; 128 129 IProgressMonitor monitor= new NullProgressMonitor(); 130 IDocument document= null; 131 try { 132 document= aquireDocument(monitor); 133 fReplaceRange= evaluateReplaceRange(document); 134 if (restoreExistingImports && container.exists()) { 135 addExistingImports(document, cu.getImports(), fReplaceRange); 136 } 137 } catch (BadLocationException e) { 138 throw new CoreException(JavaUIStatus.createError(IStatus.ERROR, e)); 139 } finally { 140 if (document != null) { 141 releaseDocument(document, monitor); 142 } 143 } 144 PackageEntry[] order= new PackageEntry[preferenceOrder.length]; 145 for (int i= 0; i < order.length; i++) { 146 String curr= preferenceOrder[i]; 147 if (curr.length() > 0 && curr.charAt(0) == '#') { 148 curr= curr.substring(1); 149 order[i]= new PackageEntry(curr, curr, true); } else { 151 order[i]= new PackageEntry(curr, curr, false); } 153 } 154 155 addPreferenceOrderHolders(order); 156 157 fHasChanges= false; 158 } 159 160 private void addPreferenceOrderHolders(PackageEntry[] preferenceOrder) { 161 if (fPackageEntries.isEmpty()) { 162 for (int i= 0; i < preferenceOrder.length; i++) { 164 fPackageEntries.add(preferenceOrder[i]); 165 } 166 } else { 167 170 PackageEntry[] lastAssigned= new PackageEntry[preferenceOrder.length]; 171 172 for (int k= 0; k < fPackageEntries.size(); k++) { 174 PackageEntry entry= (PackageEntry) fPackageEntries.get(k); 175 if (!entry.isComment()) { 176 String currName= entry.getName(); 177 int currNameLen= currName.length(); 178 int bestGroupIndex= -1; 179 int bestGroupLen= -1; 180 for (int i= 0; i < preferenceOrder.length; i++) { 181 boolean currPrevStatic= preferenceOrder[i].isStatic(); 182 if (currPrevStatic == entry.isStatic()) { 183 String currPrefEntry= preferenceOrder[i].getName(); 184 int currPrefLen= currPrefEntry.length(); 185 if (currName.startsWith(currPrefEntry) && currPrefLen >= bestGroupLen) { 186 if (currPrefLen == currNameLen || currName.charAt(currPrefLen) == '.') { 187 if (bestGroupIndex == -1 || currPrefLen > bestGroupLen) { 188 bestGroupLen= currPrefLen; 189 bestGroupIndex= i; 190 } 191 } 192 } 193 } 194 } 195 if (bestGroupIndex != -1) { 196 entry.setGroupID(preferenceOrder[bestGroupIndex].getName()); 197 lastAssigned[bestGroupIndex]= entry; } 199 } 200 } 201 int currAppendIndex= 0; 203 for (int i= 0; i < lastAssigned.length; i++) { 204 PackageEntry entry= lastAssigned[i]; 205 if (entry == null) { 206 PackageEntry newEntry= preferenceOrder[i]; 207 if (currAppendIndex == 0 && !newEntry.isStatic()) { 208 currAppendIndex= getIndexAfterStatics(); 209 } 210 fPackageEntries.add(currAppendIndex, newEntry); 211 currAppendIndex++; 212 } else { 213 currAppendIndex= fPackageEntries.indexOf(entry) + 1; 214 } 215 } 216 } 217 } 218 219 220 private void addExistingImports(IDocument document, IImportDeclaration[] decls, IRegion replaceRange) throws JavaModelException, BadLocationException { 221 if (decls.length == 0) { 222 return; 223 } 224 PackageEntry currPackage= null; 225 226 IImportDeclaration curr= decls[0]; 227 ISourceRange sourceRange= curr.getSourceRange(); 228 int currOffset= sourceRange.getOffset(); 229 int currLength= sourceRange.getLength(); 230 int currEndLine= document.getLineOfOffset(currOffset + currLength); 231 232 for (int i= 1; i < decls.length; i++) { 233 String name= curr.getElementName(); 234 boolean isStatic= Flags.isStatic(curr.getFlags()); 235 236 String packName= Signature.getQualifier(name); 237 if (currPackage == null || currPackage.compareTo(packName, isStatic) != 0) { 238 currPackage= new PackageEntry(packName, null, isStatic); 239 fPackageEntries.add(currPackage); 240 } 241 242 IImportDeclaration next= decls[i]; 243 sourceRange= next.getSourceRange(); 244 int nextOffset= sourceRange.getOffset(); 245 int nextLength= sourceRange.getLength(); 246 int nextOffsetLine= document.getLineOfOffset(nextOffset); 247 248 if (currEndLine < nextOffsetLine) { 250 currEndLine++; 251 nextOffset= document.getLineInformation(currEndLine).getOffset(); 252 } 253 currPackage.add(new ImportDeclEntry(name, isStatic, new Region(currOffset, nextOffset - currOffset))); 254 currOffset= nextOffset; 255 curr= next; 256 257 if (currEndLine < nextOffsetLine) { 259 nextOffset= document.getLineInformation(nextOffsetLine).getOffset(); 260 261 currPackage= new PackageEntry(); fPackageEntries.add(currPackage); 263 currPackage.add(new ImportDeclEntry(null, false, new Region(currOffset, nextOffset - currOffset))); 264 265 currOffset= nextOffset; 266 } 267 currEndLine= document.getLineOfOffset(nextOffset + nextLength); 268 } 269 270 String name= curr.getElementName(); 271 boolean isStatic= Flags.isStatic(curr.getFlags()); 272 String packName= Signature.getQualifier(name); 273 if (currPackage == null || currPackage.compareTo(packName, isStatic) != 0) { 274 currPackage= new PackageEntry(packName, null, isStatic); 275 fPackageEntries.add(currPackage); 276 } 277 ISourceRange range= curr.getSourceRange(); 278 int length= replaceRange.getOffset() + replaceRange.getLength() - range.getOffset(); 279 currPackage.add(new ImportDeclEntry(name, isStatic, new Region(range.getOffset(), length))); 280 } 281 282 285 public ICompilationUnit getCompilationUnit() { 286 return fCompilationUnit; 287 } 288 289 297 public void setFilterImplicitImports(boolean filterImplicitImports) { 298 fFilterImplicitImports= filterImplicitImports; 299 } 300 301 306 public void setFindAmbiguousImports(boolean findAmbiguousImports) { 307 fFindAmbiguousImports= findAmbiguousImports; 308 } 309 310 private static class PackageMatcher { 311 private String fNewName; 312 private String fBestName; 313 private int fBestMatchLen; 314 315 public PackageMatcher() { 316 } 317 318 public void initialize(String newName, String bestName) { 319 fNewName= newName; 320 fBestName= bestName; 321 fBestMatchLen= getCommonPrefixLength(bestName, fNewName); 322 } 323 324 public boolean isBetterMatch(String currName, boolean preferCurr) { 325 boolean isBetter; 326 int currMatchLen= getCommonPrefixLength(currName, fNewName); 327 int matchDiff= currMatchLen - fBestMatchLen; 328 if (matchDiff == 0) { 329 if (currMatchLen == fNewName.length() && currMatchLen == currName.length() && currMatchLen == fBestName.length()) { 330 isBetter= preferCurr; 332 } else { 333 isBetter= sameMatchLenTest(currName); 334 } 335 } else { 336 isBetter= (matchDiff > 0); } 338 if (isBetter) { 339 fBestName= currName; 340 fBestMatchLen= currMatchLen; 341 } 342 return isBetter; 343 } 344 345 private boolean sameMatchLenTest(String currName) { 346 int matchLen= fBestMatchLen; 347 350 char newChar= getCharAt(fNewName, matchLen); 352 char currChar= getCharAt(currName, matchLen); 353 char bestChar= getCharAt(fBestName, matchLen); 354 355 if (newChar < currChar) { 356 if (bestChar < newChar) { return (currChar - newChar) < (newChar - bestChar); } else { if (currChar == bestChar) { return false; } else { 362 return currChar < bestChar; } 364 } 365 } else { 366 if (bestChar > newChar) { return (newChar - currChar) < (bestChar - newChar); } else { if (currChar == bestChar) { return true; } else { 372 return currChar > bestChar; } 374 } 375 } 376 } 377 378 } 379 380 private static int getCommonPrefixLength(String s, String t) { 381 int len= Math.min(s.length(), t.length()); 382 for (int i= 0; i < len; i++) { 383 if (s.charAt(i) != t.charAt(i)) { 384 return i; 385 } 386 } 387 return len; 388 } 389 390 private static char getCharAt(String str, int index) { 391 if (str.length() > index) { 392 return str.charAt(index); 393 } 394 return 0; 395 } 396 397 private PackageEntry findBestMatch(String newName, boolean isStatic) { 398 if (fPackageEntries.isEmpty()) { 399 return null; 400 } 401 String groupId= null; 402 int longestPrefix= -1; 403 for (int i= 0; i < fPackageEntries.size(); i++) { 405 PackageEntry curr= (PackageEntry) fPackageEntries.get(i); 406 if (isStatic == curr.isStatic()) { 407 String currGroup= curr.getGroupID(); 408 if (currGroup != null && newName.startsWith(currGroup)) { 409 int prefixLen= currGroup.length(); 410 if (prefixLen == newName.length()) { 411 return curr; } 413 if ((newName.charAt(prefixLen) == '.') && prefixLen > longestPrefix) { 414 longestPrefix= prefixLen; 415 groupId= currGroup; 416 } 417 } 418 } 419 } 420 PackageEntry bestMatch= null; 421 PackageMatcher matcher= new PackageMatcher(); 422 matcher.initialize(newName, ""); for (int i= 0; i < fPackageEntries.size(); i++) { PackageEntry curr= (PackageEntry) fPackageEntries.get(i); 425 if (!curr.isComment() && curr.isStatic() == isStatic) { 426 if (groupId == null || groupId.equals(curr.getGroupID())) { 427 boolean preferrCurr= (bestMatch == null) || (curr.getNumberOfImports() > bestMatch.getNumberOfImports()); 428 if (matcher.isBetterMatch(curr.getName(), preferrCurr)) { 429 bestMatch= curr; 430 } 431 } 432 } 433 } 434 return bestMatch; 435 } 436 437 public static boolean isImplicitImport(String qualifier, ICompilationUnit cu) { 438 if (JAVA_LANG.equals(qualifier)) { return true; 440 } 441 String packageName= cu.getParent().getElementName(); 442 if (qualifier.equals(packageName)) { 443 return true; 444 } 445 String mainTypeName= JavaModelUtil.concatenateName(packageName, Signature.getQualifier(cu.getElementName())); 446 return qualifier.equals(mainTypeName); 447 } 448 449 458 public Type addImport(ITypeBinding binding, AST ast) { 459 if (binding.isPrimitive()) { 460 return ast.newPrimitiveType(PrimitiveType.toCode(binding.getName())); 461 } 462 463 ITypeBinding normalizedBinding= Bindings.normalizeTypeBinding(binding); 464 if (normalizedBinding == null) { 465 return ast.newSimpleType(ast.newSimpleName("invalid")); } 467 468 if (normalizedBinding.isTypeVariable()) { 469 return ast.newSimpleType(ast.newSimpleName(binding.getName())); 471 } 472 if (normalizedBinding.isWildcardType()) { 473 WildcardType wcType= ast.newWildcardType(); 474 ITypeBinding bound= normalizedBinding.getBound(); 475 if (bound != null && !bound.isWildcardType() && !bound.isCapture()) { Type boundType= addImport(bound, ast); 477 wcType.setBound(boundType, normalizedBinding.isUpperbound()); 478 } 479 return wcType; 480 } 481 482 if (normalizedBinding.isArray()) { 483 Type elementType= addImport(normalizedBinding.getElementType(), ast); 484 return ast.newArrayType(elementType, normalizedBinding.getDimensions()); 485 } 486 487 String qualifiedName= Bindings.getRawQualifiedName(normalizedBinding); 488 if (qualifiedName.length() > 0) { 489 String res= internalAddImport(qualifiedName); 490 491 ITypeBinding[] typeArguments= normalizedBinding.getTypeArguments(); 492 if (typeArguments.length > 0) { 493 Type erasureType= ast.newSimpleType(ASTNodeFactory.newName(ast,res)); 494 ParameterizedType paramType= ast.newParameterizedType(erasureType); 495 List arguments= paramType.typeArguments(); 496 for (int i= 0; i < typeArguments.length; i++) { 497 arguments.add(addImport(typeArguments[i], ast)); 498 } 499 return paramType; 500 } 501 return ast.newSimpleType(ASTNodeFactory.newName(ast, res)); 502 } 503 return ast.newSimpleType(ASTNodeFactory.newName(ast, Bindings.getRawName(normalizedBinding))); 504 } 505 506 515 public Type addImportFromSignature(String typeSig, AST ast) { 516 if (typeSig == null || typeSig.length() == 0) { 517 throw new IllegalArgumentException ("Invalid type signature: empty or null"); } 519 int sigKind= Signature.getTypeSignatureKind(typeSig); 520 switch (sigKind) { 521 case Signature.BASE_TYPE_SIGNATURE: 522 return ast.newPrimitiveType(PrimitiveType.toCode(Signature.toString(typeSig))); 523 case Signature.ARRAY_TYPE_SIGNATURE: 524 Type elementType= addImportFromSignature(Signature.getElementType(typeSig), ast); 525 return ast.newArrayType(elementType, Signature.getArrayCount(typeSig)); 526 case Signature.CLASS_TYPE_SIGNATURE: 527 String erasureSig= Signature.getTypeErasure(typeSig); 528 529 String erasureName= Signature.toString(erasureSig); 530 if (erasureSig.charAt(0) == Signature.C_RESOLVED) { 531 erasureName= internalAddImport(erasureName); 532 } 533 Type baseType= ast.newSimpleType(ASTNodeFactory.newName(ast, erasureName)); 534 String [] typeArguments= Signature.getTypeArguments(typeSig); 535 if (typeArguments.length > 0) { 536 ParameterizedType type= ast.newParameterizedType(baseType); 537 List argNodes= type.typeArguments(); 538 for (int i= 0; i < typeArguments.length; i++) { 539 argNodes.add(addImportFromSignature(typeArguments[i], ast)); 540 } 541 return type; 542 } 543 return baseType; 544 case Signature.TYPE_VARIABLE_SIGNATURE: 545 return ast.newSimpleType(ast.newSimpleName(Signature.toString(typeSig))); 546 case Signature.WILDCARD_TYPE_SIGNATURE: 547 WildcardType wildcardType= ast.newWildcardType(); 548 char ch= typeSig.charAt(0); 549 if (ch != Signature.C_STAR) { 550 Type bound= addImportFromSignature(typeSig.substring(1), ast); 551 wildcardType.setBound(bound, ch == Signature.C_EXTENDS); 552 } 553 return wildcardType; 554 case Signature.CAPTURE_TYPE_SIGNATURE: 555 return addImportFromSignature(typeSig.substring(1), ast); 556 default: 557 JavaPlugin.logErrorMessage("Unknown type signature kind: " + typeSig); } 559 return ast.newSimpleType(ast.newSimpleName("invalid")); } 561 562 563 572 public String addImport(ITypeBinding binding) { 573 574 if (binding.isPrimitive() || binding.isTypeVariable()) { 575 return binding.getName(); 576 } 577 578 ITypeBinding normalizedBinding= Bindings.normalizeTypeBinding(binding); 579 if (normalizedBinding == null) { 580 return "invalid"; } 582 if (normalizedBinding.isWildcardType()) { 583 StringBuffer res= new StringBuffer ("?"); ITypeBinding bound= normalizedBinding.getBound(); 585 if (bound != null && !bound.isWildcardType() && !bound.isCapture()) { if (normalizedBinding.isUpperbound()) { 587 res.append(" extends "); } else { 589 res.append(" super "); } 591 res.append(addImport(bound)); 592 } 593 return res.toString(); 594 } 595 596 if (normalizedBinding.isArray()) { 597 StringBuffer res= new StringBuffer (addImport(normalizedBinding.getElementType())); 598 for (int i= normalizedBinding.getDimensions(); i > 0; i--) { 599 res.append("[]"); } 601 return res.toString(); 602 } 603 604 605 606 String qualifiedName= Bindings.getRawQualifiedName(normalizedBinding); 607 if (qualifiedName.length() > 0) { 608 String str= internalAddImport(qualifiedName); 609 610 ITypeBinding[] typeArguments= normalizedBinding.getTypeArguments(); 611 if (typeArguments.length > 0) { 612 StringBuffer res= new StringBuffer (str); 613 res.append('<'); 614 for (int i= 0; i < typeArguments.length; i++) { 615 if (i > 0) { 616 res.append(','); } 618 res.append(addImport(typeArguments[i])); 619 } 620 res.append('>'); 621 return res.toString(); 622 } 623 return str; 624 } 625 return Bindings.getRawName(normalizedBinding); 626 } 627 628 635 public String addImport(String qualifiedTypeName) { 636 int angleBracketOffset= qualifiedTypeName.indexOf('<'); 637 if (angleBracketOffset != -1) { 638 return internalAddImport(qualifiedTypeName.substring(0, angleBracketOffset)) + qualifiedTypeName.substring(angleBracketOffset); 639 } 640 int bracketOffset= qualifiedTypeName.indexOf('['); 641 if (bracketOffset != -1) { 642 return internalAddImport(qualifiedTypeName.substring(0, bracketOffset)) + qualifiedTypeName.substring(bracketOffset); 643 } 644 return internalAddImport(qualifiedTypeName); 645 } 646 647 648 public String addStaticImport(IBinding binding) { 649 if (binding instanceof IVariableBinding) { 650 ITypeBinding declaringType= ((IVariableBinding) binding).getDeclaringClass(); 651 return addStaticImport(Bindings.getRawQualifiedName(declaringType), binding.getName(), true); 652 } else if (binding instanceof IMethodBinding) { 653 ITypeBinding declaringType= ((IMethodBinding) binding).getDeclaringClass(); 654 return addStaticImport(Bindings.getRawQualifiedName(declaringType), binding.getName(), false); 655 } 656 return binding.getName(); 657 } 658 659 666 public String addStaticImport(String declaringTypeName, String simpleName, boolean isField) { 667 String containerName= Signature.getQualifier(declaringTypeName); 668 String fullName= declaringTypeName + '.' + simpleName; 669 670 if (containerName.length() == 0) { 671 return declaringTypeName + '.' + simpleName; 672 } 673 if (!"*".equals(simpleName)) { if (isField) { 675 String existing= findStaticImport(null, simpleName); 676 if (existing != null) { 677 if (existing.equals(fullName)) { 678 return simpleName; 679 } else { 680 return fullName; 681 } 682 } 683 } else { 684 String existing= findStaticImport(declaringTypeName, simpleName); 685 if (existing != null) { 686 return simpleName; 687 } 688 } 689 } 690 ImportDeclEntry decl= new ImportDeclEntry(fullName, true, null); 691 692 sortIn(declaringTypeName, decl, true); 693 return simpleName; 694 } 695 696 private String internalAddImport(String fullTypeName) { 697 int idx= fullTypeName.lastIndexOf('.'); 698 String typeContainerName, typeName; 699 if (idx != -1) { 700 typeContainerName= fullTypeName.substring(0, idx); 701 typeName= fullTypeName.substring(idx + 1); 702 } else { 703 typeContainerName= ""; typeName= fullTypeName; 705 } 706 707 if (typeContainerName.length() == 0 && PrimitiveType.toCode(typeName) != null) { 708 return fullTypeName; 709 } 710 711 if (!"*".equals(typeName)) { String topLevelTypeName= Signature.getQualifier(fCompilationUnit.getElementName()); 713 714 if (typeName.equals(topLevelTypeName)) { 715 if (!typeContainerName.equals(fCompilationUnit.getParent().getElementName())) { 716 return fullTypeName; 717 } else { 718 return typeName; 719 } 720 } 721 String existing= findImport(typeName); 722 if (existing != null) { 723 if (fullTypeName.equals(existing)) { 724 return typeName; 725 } else { 726 return fullTypeName; 727 } 728 } 729 } 730 731 ImportDeclEntry decl= new ImportDeclEntry(fullTypeName, false, null); 732 733 sortIn(typeContainerName, decl, false); 734 return typeName; 735 } 736 737 private int getIndexAfterStatics() { 738 for (int i= 0; i < fPackageEntries.size(); i++) { 739 if (!((PackageEntry) fPackageEntries.get(i)).isStatic()) { 740 return i; 741 } 742 } 743 return fPackageEntries.size(); 744 } 745 746 747 private void sortIn(String typeContainerName, ImportDeclEntry decl, boolean isStatic) { 748 PackageEntry bestMatch= findBestMatch(typeContainerName, isStatic); 749 if (bestMatch == null) { 750 PackageEntry packEntry= new PackageEntry(typeContainerName, null, isStatic); 751 packEntry.add(decl); 752 int insertPos= packEntry.isStatic() ? 0 : getIndexAfterStatics(); 753 fPackageEntries.add(insertPos, packEntry); 754 } else { 755 int cmp= typeContainerName.compareTo(bestMatch.getName()); 756 if (cmp == 0) { 757 bestMatch.sortIn(decl); 758 } else { 759 String group= bestMatch.getGroupID(); 761 if (group != null) { 762 if (!typeContainerName.startsWith(group)) { 763 group= null; 764 } 765 } 766 PackageEntry packEntry= new PackageEntry(typeContainerName, group, isStatic); 767 packEntry.add(decl); 768 int index= fPackageEntries.indexOf(bestMatch); 769 if (cmp < 0) { fPackageEntries.add(index, packEntry); 771 } else { fPackageEntries.add(index + 1, packEntry); 773 } 774 } 775 } 776 fHasChanges= true; 777 } 778 779 784 public boolean removeImport(String qualifiedName) { 785 String typeContainerName= Signature.getQualifier(qualifiedName); 786 int bracketOffset= qualifiedName.indexOf('['); 787 if (bracketOffset != -1) { 788 qualifiedName= qualifiedName.substring(0, bracketOffset); 789 } 790 791 int nPackages= fPackageEntries.size(); 792 for (int i= 0; i < nPackages; i++) { 793 PackageEntry entry= (PackageEntry) fPackageEntries.get(i); 794 if (entry.compareTo(typeContainerName, false) == 0) { 795 if (entry.remove(qualifiedName, false)) { 796 fHasChanges= true; 797 return true; 798 } 799 } 800 } 801 return false; 802 } 803 804 809 public boolean removeStaticImport(String qualifiedName) { 810 String containerName= Signature.getQualifier(qualifiedName); 811 812 int nPackages= fPackageEntries.size(); 813 for (int i= 0; i < nPackages; i++) { 814 PackageEntry entry= (PackageEntry) fPackageEntries.get(i); 815 if (entry.compareTo(containerName, true) == 0) { 816 if (entry.remove(qualifiedName, true)) { 817 fHasChanges= true; 818 return true; 819 } 820 } 821 } 822 return false; 823 } 824 825 826 831 public boolean removeImport(ITypeBinding binding) { 832 binding= Bindings.normalizeTypeBinding(binding); 833 if (binding == null) { 834 return false; 835 } 836 String qualifiedName= Bindings.getRawQualifiedName(binding); 837 if (qualifiedName.length() > 0) { 838 return removeImport(qualifiedName); 839 } 840 return false; 841 } 842 843 848 public String findImport(String simpleName) { 849 int nPackages= fPackageEntries.size(); 850 for (int i= 0; i < nPackages; i++) { 851 PackageEntry entry= (PackageEntry) fPackageEntries.get(i); 852 if (!entry.isStatic()) { 853 ImportDeclEntry found= entry.find(simpleName); 854 if (found != null) { 855 return found.getElementName(); 856 } 857 } 858 } 859 return null; 860 } 861 862 public String findStaticImport(String typeContainerName, String typeSimpleName) { 863 int nPackages= fPackageEntries.size(); 864 for (int i= 0; i < nPackages; i++) { 865 PackageEntry entry= (PackageEntry) fPackageEntries.get(i); 866 if (entry.isStatic()) { 867 if (typeContainerName == null || entry.getName().equals(typeContainerName)) { 868 ImportDeclEntry found= entry.find(typeSimpleName); 869 if (found != null) { 870 return found.getElementName(); 871 } 872 } 873 } 874 } 875 return null; 876 } 877 878 884 public void create(boolean save, IProgressMonitor monitor) throws CoreException { 885 if (monitor == null) { 886 monitor= new NullProgressMonitor(); 887 } 888 monitor.beginTask(CodeGenerationMessages.ImportsStructure_operation_description, 4); 889 890 IDocument document= null; 891 DocumentRewriteSession session= null; 892 try { 893 document= aquireDocument(new SubProgressMonitor(monitor, 1)); 894 if (document instanceof IDocumentExtension4) { 895 session= ((IDocumentExtension4)document).startRewriteSession( 896 DocumentRewriteSessionType.UNRESTRICTED); 897 } 898 MultiTextEdit edit= getResultingEdits(document, new SubProgressMonitor(monitor, 1)); 899 if (edit.hasChildren()) { 900 if (save) { 901 commitDocument(document, edit, new SubProgressMonitor(monitor, 1)); 902 } else { 903 edit.apply(document); 904 } 905 } 906 } catch (BadLocationException e) { 907 throw new CoreException(JavaUIStatus.createError(IStatus.ERROR, e)); 908 } finally { 909 try { 910 if (session != null) { 911 ((IDocumentExtension4)document).stopRewriteSession(session); 912 } 913 } finally { 914 releaseDocument(document, new SubProgressMonitor(monitor, 1)); 915 } 916 monitor.done(); 917 } 918 } 919 920 private IDocument aquireDocument(IProgressMonitor monitor) throws CoreException { 921 if (JavaModelUtil.isPrimary(fCompilationUnit)) { 922 IFile file= (IFile) fCompilationUnit.getResource(); 923 if (file.exists()) { 924 ITextFileBufferManager bufferManager= FileBuffers.getTextFileBufferManager(); 925 IPath path= fCompilationUnit.getPath(); 926 bufferManager.connect(path, monitor); 927 return bufferManager.getTextFileBuffer(path).getDocument(); 928 } 929 } 930 monitor.done(); 931 return new Document(fCompilationUnit.getSource()); 932 } 933 934 private void releaseDocument(IDocument document, IProgressMonitor monitor) throws CoreException { 935 if (JavaModelUtil.isPrimary(fCompilationUnit)) { 936 IFile file= (IFile) fCompilationUnit.getResource(); 937 if (file.exists()) { 938 ITextFileBufferManager bufferManager= FileBuffers.getTextFileBufferManager(); 939 bufferManager.disconnect(file.getFullPath(), monitor); 940 return; 941 } 942 } 943 fCompilationUnit.getBuffer().setContents(document.get()); 944 monitor.done(); 945 } 946 947 private void commitDocument(IDocument document, MultiTextEdit edit, IProgressMonitor monitor) throws CoreException, MalformedTreeException, BadLocationException { 948 if (JavaModelUtil.isPrimary(fCompilationUnit)) { 949 IFile file= (IFile) fCompilationUnit.getResource(); 950 if (file.exists()) { 951 IStatus status= Resources.makeCommittable(file, null); 952 if (!status.isOK()) { 953 throw new ValidateEditException(status); 954 } 955 edit.apply(document); 957 ITextFileBufferManager bufferManager= FileBuffers.getTextFileBufferManager(); 958 bufferManager.getTextFileBuffer(file.getFullPath()).commit(monitor, true); 959 return; 960 } 961 } 962 edit.apply(document); 964 } 965 966 private IRegion evaluateReplaceRange(IDocument document) throws JavaModelException, BadLocationException { 967 JavaModelUtil.reconcile(fCompilationUnit); 968 969 IImportContainer container= fCompilationUnit.getImportContainer(); 970 if (container.exists()) { 971 ISourceRange importSourceRange= container.getSourceRange(); 972 int startPos= importSourceRange.getOffset(); 973 int endPos= startPos + importSourceRange.getLength(); 974 if (!Strings.isLineDelimiterChar(document.getChar(endPos - 1))) { 975 int nextLine= document.getLineOfOffset(endPos) + 1; 978 if (nextLine < document.getNumberOfLines()) { 979 int stopPos= document.getLineInformation(nextLine).getOffset(); 980 while (endPos < stopPos && Character.isWhitespace(document.getChar(endPos))) { 982 endPos++; 983 } 984 } 985 } 986 return new Region(startPos, endPos - startPos); 987 } else { 988 int start= getPackageStatementEndPos(document); 989 return new Region(start, 0); 990 } 991 } 992 993 public MultiTextEdit getResultingEdits(IDocument document, IProgressMonitor monitor) throws JavaModelException, BadLocationException { 994 if (monitor == null) { 995 monitor= new NullProgressMonitor(); 996 } 997 try { 998 fImportsCreated= new ArrayList (); 999 fStaticImportsCreated= new ArrayList (); 1000 1001 int importsStart= fReplaceRange.getOffset(); 1002 int importsLen= fReplaceRange.getLength(); 1003 1004 String lineDelim= TextUtilities.getDefaultLineDelimiter(document); 1005 boolean useSpaceBetween= useSpaceBetweenGroups(); 1006 1007 int currPos= importsStart; 1008 MultiTextEdit resEdit= new MultiTextEdit(); 1009 1010 if (importsLen == 0) { 1011 resEdit.addChild(new InsertEdit(currPos, lineDelim)); } 1014 1015 PackageEntry lastPackage= null; 1016 1017 Set onDemandConflicts= null; 1018 if (fFindAmbiguousImports) { 1019 onDemandConflicts= evaluateStarImportConflicts(monitor); 1020 } 1021 1022 ArrayList stringsToInsert= new ArrayList (); 1023 1024 int nPackageEntries= fPackageEntries.size(); 1025 for (int i= 0; i < nPackageEntries; i++) { 1026 PackageEntry pack= (PackageEntry) fPackageEntries.get(i); 1027 int nImports= pack.getNumberOfImports(); 1028 1029 if (fFilterImplicitImports && !pack.isStatic() && isImplicitImport(pack.getName(), fCompilationUnit)) { 1030 pack.removeAllNew(onDemandConflicts); 1031 nImports= pack.getNumberOfImports(); 1032 } 1033 if (nImports == 0) { 1034 continue; 1035 } 1036 1037 if (useSpaceBetween) { 1038 if (lastPackage != null && !pack.isComment() && !pack.isSameGroup(lastPackage)) { 1040 ImportDeclEntry last= lastPackage.getImportAt(lastPackage.getNumberOfImports() - 1); 1041 ImportDeclEntry first= pack.getImportAt(0); 1042 if (!lastPackage.isComment() && (last.isNew() || first.isNew())) { 1043 stringsToInsert.add(lineDelim); 1044 } 1045 } 1046 } 1047 lastPackage= pack; 1048 1049 boolean isStatic= pack.isStatic(); 1050 1051 boolean doStarImport= pack.hasStarImport(fImportOnDemandThreshold, onDemandConflicts); 1052 if (doStarImport && (pack.find("*") == null)) { String starImportString= pack.getName() + ".*"; String str= getNewImportString(starImportString, isStatic, lineDelim); 1055 stringsToInsert.add(str); 1056 } 1057 1058 for (int k= 0; k < nImports; k++) { 1059 ImportDeclEntry currDecl= pack.getImportAt(k); 1060 IRegion region= currDecl.getSourceRange(); 1061 1062 if (region == null) { if (!doStarImport || currDecl.isOnDemand() || (onDemandConflicts != null && onDemandConflicts.contains(currDecl.getSimpleName()))) { 1064 String str= getNewImportString(currDecl.getElementName(), isStatic, lineDelim); 1065 stringsToInsert.add(str); 1066 } 1067 } else { 1068 if (!doStarImport || currDecl.isOnDemand() || onDemandConflicts == null || onDemandConflicts.contains(currDecl.getSimpleName())) { 1069 int offset= region.getOffset(); 1070 removeAndInsertNew(document, currPos, offset, stringsToInsert, resEdit); 1071 stringsToInsert.clear(); 1072 currPos= offset + region.getLength(); 1073 } 1074 } 1075 } 1076 } 1077 1078 int end= importsStart + importsLen; 1079 removeAndInsertNew(document, currPos, end, stringsToInsert, resEdit); 1080 1081 if (importsLen == 0) { 1082 if (!fImportsCreated.isEmpty() || !fStaticImportsCreated.isEmpty()) { if (fCompilationUnit.getPackageDeclarations().length == 0) { resEdit.removeChild(0); 1085 } 1086 IType[] types= fCompilationUnit.getTypes(); 1088 if (types.length > 0) { 1089 if (types[0].getSourceRange().getOffset() == importsStart) { 1090 resEdit.addChild(new InsertEdit(currPos, lineDelim)); 1091 } 1092 } 1093 } else { 1094 return new MultiTextEdit(); } 1096 } 1097 return resEdit; 1098 } finally { 1099 monitor.done(); 1100 } 1101 } 1102 1103 private void removeAndInsertNew(IDocument doc, int contentOffset, int contentEnd, ArrayList stringsToInsert, MultiTextEdit resEdit) throws BadLocationException { 1104 int pos= contentOffset; 1105 for (int i= 0; i < stringsToInsert.size(); i++) { 1106 String curr= (String ) stringsToInsert.get(i); 1107 int idx= findInDocument(doc, curr, pos, contentEnd); 1108 if (idx != -1) { 1109 if (idx != pos) { 1110 resEdit.addChild(new DeleteEdit(pos, idx - pos)); 1111 } 1112 pos= idx + curr.length(); 1113 } else { 1114 resEdit.addChild(new InsertEdit(pos, curr)); 1115 } 1116 } 1117 if (pos < contentEnd) { 1118 resEdit.addChild(new DeleteEdit(pos, contentEnd - pos)); 1119 } 1120 } 1121 1122 private int findInDocument(IDocument doc, String str, int start, int end) throws BadLocationException { 1123 int pos= start; 1124 int len= str.length(); 1125 if (pos + len > end || str.length() == 0) { 1126 return -1; 1127 } 1128 char first= str.charAt(0); 1129 int step= str.indexOf(first, 1); 1130 if (step == -1) { 1131 step= len; 1132 } 1133 while (pos + len <= end) { 1134 if (doc.getChar(pos) == first) { 1135 int k= 1; 1136 while (k < len && doc.getChar(pos + k) == str.charAt(k)) { 1137 k++; 1138 } 1139 if (k == len) { 1140 return pos; } 1142 if (k < step) { 1143 pos+= k; 1144 } else { 1145 pos+= step; 1146 } 1147 } else { 1148 pos++; 1149 } 1150 } 1151 return -1; 1152 } 1153 1154 1155 1158 private boolean useSpaceBetweenGroups() { 1159 try { 1160 String sample= "import a.A;\n\n import b.B;\nclass C {}"; TextEdit res= ToolFactory.createCodeFormatter(fCompilationUnit.getJavaProject().getOptions(true)).format(CodeFormatter.K_COMPILATION_UNIT, sample, 0, sample.length(), 0, String.valueOf('\n')); 1162 Document doc= new Document(sample); 1163 res.apply(doc); 1164 int idx1= doc.search(0, "import", true, true, false); int line1= doc.getLineOfOffset(idx1); 1166 int idx2= doc.search(idx1 + 1, "import", true, true, false); int line2= doc.getLineOfOffset(idx2); 1168 return line2 - line1 > 1; 1169 } catch (BadLocationException e) { 1170 } 1172 return true; 1173 } 1174 1175 private Set evaluateStarImportConflicts(IProgressMonitor monitor) throws JavaModelException { 1176 1178 final HashSet onDemandConflicts= new HashSet (); 1179 1180 IJavaSearchScope scope= SearchEngine.createJavaSearchScope(new IJavaElement[] { fCompilationUnit.getJavaProject() }); 1181 1182 ArrayList starImportPackages= new ArrayList (); 1183 ArrayList simpleTypeNames= new ArrayList (); 1184 int nPackageEntries= fPackageEntries.size(); 1185 for (int i= 0; i < nPackageEntries; i++) { 1186 PackageEntry pack= (PackageEntry) fPackageEntries.get(i); 1187 if (!pack.isStatic() && pack.hasStarImport(fImportOnDemandThreshold, null)) { 1188 starImportPackages.add(pack.getName().toCharArray()); 1189 for (int k= 0; k < pack.getNumberOfImports(); k++) { 1190 ImportDeclEntry curr= pack.getImportAt(k); 1191 if (!curr.isOnDemand() && !curr.isComment()) { 1192 simpleTypeNames.add(curr.getSimpleName().toCharArray()); 1193 } 1194 } 1195 } 1196 } 1197 if (starImportPackages.isEmpty()) { 1198 return null; 1199 } 1200 1201 starImportPackages.add(fCompilationUnit.getParent().getElementName().toCharArray()); 1202 starImportPackages.add(JAVA_LANG.toCharArray()); 1203 1204 char[][] allPackages= (char[][]) starImportPackages.toArray(new char[starImportPackages.size()][]); 1205 char[][] allTypes= (char[][]) simpleTypeNames.toArray(new char[simpleTypeNames.size()][]); 1206 1207 TypeNameRequestor requestor= new TypeNameRequestor() { 1208 HashMap foundTypes= new HashMap (); 1209 1210 private String getTypeContainerName(char[] packageName, char[][] enclosingTypeNames) { 1211 StringBuffer buf= new StringBuffer (); 1212 buf.append(packageName); 1213 for (int i= 0; i < enclosingTypeNames.length; i++) { 1214 if (buf.length() > 0) 1215 buf.append('.'); 1216 buf.append(enclosingTypeNames[i]); 1217 } 1218 return buf.toString(); 1219 } 1220 1221 public void acceptType(int flags, char[] packageName, char[] simpleTypeName, char[][] enclosingTypeNames, String path) { 1222 String name= new String (simpleTypeName); 1223 String containerName= getTypeContainerName(packageName, enclosingTypeNames); 1224 1225 String oldContainer= (String ) foundTypes.put(name, containerName); 1226 if (oldContainer != null && !oldContainer.equals(containerName)) { 1227 onDemandConflicts.add(name); 1228 } 1229 } 1230 }; 1231 new SearchEngine().searchAllTypeNames(allPackages, allTypes, scope, requestor, IJavaSearchConstants.WAIT_UNTIL_READY_TO_SEARCH, monitor); 1232 return onDemandConflicts; 1233 } 1234 1235 private String getNewImportString(String importName, boolean isStatic, String lineDelim) { 1236 StringBuffer buf= new StringBuffer (); 1237 buf.append("import "); if (isStatic) { 1239 buf.append("static "); } 1241 buf.append(importName); 1242 buf.append(';'); 1243 buf.append(lineDelim); 1244 1246 if (isStatic) { 1247 fStaticImportsCreated.add(importName); 1248 } else { 1249 fImportsCreated.add(importName); 1250 } 1251 return buf.toString(); 1252 } 1253 1254 private int getPackageStatementEndPos(IDocument document) throws JavaModelException, BadLocationException { 1255 IPackageDeclaration[] packDecls= fCompilationUnit.getPackageDeclarations(); 1256 if (packDecls != null && packDecls.length > 0) { 1257 ISourceRange range= packDecls[0].getSourceRange(); 1258 int line= document.getLineOfOffset(range.getOffset() + range.getLength()); 1259 IRegion region= document.getLineInformation(line + 1); 1260 if (region != null) { 1261 IType[] types= fCompilationUnit.getTypes(); 1262 if (types.length > 0) { 1263 return Math.min(types[0].getSourceRange().getOffset(), region.getOffset()); 1264 } 1265 return region.getOffset(); 1266 } 1267 } 1268 return 0; 1269 } 1270 1271 public String toString() { 1272 int nPackages= fPackageEntries.size(); 1273 StringBuffer buf= new StringBuffer ("\n-----------------------\n"); for (int i= 0; i < nPackages; i++) { 1275 PackageEntry entry= (PackageEntry) fPackageEntries.get(i); 1276 if (entry.isStatic()) { 1277 buf.append("static "); } 1279 buf.append(entry.toString()); 1280 } 1281 return buf.toString(); 1282 } 1283 1284 private static final class ImportDeclEntry { 1285 1286 private String fElementName; 1287 private IRegion fSourceRange; 1288 private final boolean fIsStatic; 1289 1290 public ImportDeclEntry(String elementName, boolean isStatic, IRegion sourceRange) { 1291 fElementName= elementName; 1292 fSourceRange= sourceRange; 1293 fIsStatic= isStatic; 1294 } 1295 1296 public String getElementName() { 1297 return fElementName; 1298 } 1299 1300 public int compareTo(String fullName, boolean isStatic) { 1301 int cmp= fElementName.compareTo(fullName); 1302 if (cmp == 0) { 1303 if (fIsStatic == isStatic) { 1304 return 0; 1305 } 1306 return fIsStatic ? -1 : 1; 1307 } 1308 return cmp; 1309 } 1310 1311 public String getSimpleName() { 1312 return Signature.getSimpleName(fElementName); 1313 } 1314 1315 public boolean isOnDemand() { 1316 return fElementName != null && fElementName.endsWith(".*"); } 1318 1319 public boolean isStatic() { 1320 return fIsStatic; 1321 } 1322 1323 public boolean isNew() { 1324 return fSourceRange == null; 1325 } 1326 1327 public boolean isComment() { 1328 return fElementName == null; 1329 } 1330 1331 public IRegion getSourceRange() { 1332 return fSourceRange; 1333 } 1334 1335 } 1336 1337 1341 private final static class PackageEntry { 1342 1343 public static PackageEntry createOnPlaceholderEntry(String preferenceOrder) { 1344 if (preferenceOrder.length() > 0 && preferenceOrder.charAt(0) == '#') { 1345 String curr= preferenceOrder.substring(1); 1346 return new PackageEntry(curr, curr, true); 1347 } 1348 return new PackageEntry(preferenceOrder, preferenceOrder, false); 1349 } 1350 1351 private String fName; 1352 private ArrayList fImportEntries; 1353 private String fGroup; 1354 private boolean fIsStatic; 1355 1356 1359 public PackageEntry() { 1360 this("!", null, false); } 1362 1363 1369 public PackageEntry(String name, String group, boolean isStatic) { 1370 fName= name; 1371 fImportEntries= new ArrayList (5); 1372 fGroup= group; 1373 fIsStatic= isStatic; 1374 } 1375 1376 public boolean isStatic() { 1377 return fIsStatic; 1378 } 1379 1380 public int compareTo(String name, boolean isStatic) { 1381 int cmp= fName.compareTo(name); 1382 if (cmp == 0) { 1383 if (fIsStatic == isStatic) { 1384 return 0; 1385 } 1386 return fIsStatic ? -1 : 1; 1387 } 1388 return cmp; 1389 } 1390 1391 public void sortIn(ImportDeclEntry imp) { 1392 String fullImportName= imp.getElementName(); 1393 int insertPosition= -1; 1394 int nInports= fImportEntries.size(); 1395 for (int i= 0; i < nInports; i++) { 1396 ImportDeclEntry curr= getImportAt(i); 1397 if (!curr.isComment()) { 1398 int cmp= curr.compareTo(fullImportName, imp.isStatic()); 1399 if (cmp == 0) { 1400 return; } else if (cmp > 0 && insertPosition == -1) { 1402 insertPosition= i; 1403 } 1404 } 1405 } 1406 if (insertPosition == -1) { 1407 fImportEntries.add(imp); 1408 } else { 1409 fImportEntries.add(insertPosition, imp); 1410 } 1411 } 1412 1413 1414 public void add(ImportDeclEntry imp) { 1415 fImportEntries.add(imp); 1416 } 1417 1418 public ImportDeclEntry find(String simpleName) { 1419 int nInports= fImportEntries.size(); 1420 for (int i= 0; i < nInports; i++) { 1421 ImportDeclEntry curr= getImportAt(i); 1422 if (!curr.isComment()) { 1423 String name= curr.getElementName(); 1424 if (name.endsWith(simpleName)) { 1425 int dotPos= name.length() - simpleName.length() - 1; 1426 if ((dotPos == -1) || (dotPos > 0 && name.charAt(dotPos) == '.')) { 1427 return curr; 1428 } 1429 } 1430 } 1431 } 1432 return null; 1433 } 1434 1435 public boolean remove(String fullName, boolean isStaticImport) { 1436 int nInports= fImportEntries.size(); 1437 for (int i= 0; i < nInports; i++) { 1438 ImportDeclEntry curr= getImportAt(i); 1439 if (!curr.isComment() && curr.compareTo(fullName, isStaticImport) == 0) { 1440 fImportEntries.remove(i); 1441 return true; 1442 } 1443 } 1444 return false; 1445 } 1446 1447 public void removeAllNew(Set onDemandConflicts) { 1448 int nInports= fImportEntries.size(); 1449 for (int i= nInports - 1; i >= 0; i--) { 1450 ImportDeclEntry curr= getImportAt(i); 1451 if (curr.isNew() ) { 1452 fImportEntries.remove(i); 1453 } 1454 } 1455 } 1456 1457 public ImportDeclEntry getImportAt(int index) { 1458 return (ImportDeclEntry) fImportEntries.get(index); 1459 } 1460 1461 public boolean hasStarImport(int threshold, Set explicitImports) { 1462 if (isComment() || isDefaultPackage()) { return false; 1464 } 1465 int nImports= getNumberOfImports(); 1466 int count= 0; 1467 boolean containsNew= false; 1468 for (int i= 0; i < nImports; i++) { 1469 ImportDeclEntry curr= getImportAt(i); 1470 if (curr.isOnDemand()) { 1471 return true; 1472 } 1473 if (!curr.isComment()) { 1474 count++; 1475 boolean isExplicit= !curr.isStatic() && (explicitImports != null) && explicitImports.contains(curr.getSimpleName()); 1476 containsNew |= curr.isNew() && !isExplicit; 1477 } 1478 } 1479 return (count >= threshold) && containsNew; 1480 } 1481 1482 public int getNumberOfImports() { 1483 return fImportEntries.size(); 1484 } 1485 1486 public String getName() { 1487 return fName; 1488 } 1489 1490 public String getGroupID() { 1491 return fGroup; 1492 } 1493 1494 public void setGroupID(String groupID) { 1495 fGroup= groupID; 1496 } 1497 1498 public boolean isSameGroup(PackageEntry other) { 1499 if (fGroup == null) { 1500 return other.getGroupID() == null; 1501 } else { 1502 return fGroup.equals(other.getGroupID()) && (fIsStatic == other.isStatic()); 1503 } 1504 } 1505 1506 public ImportDeclEntry getLast() { 1507 int nImports= getNumberOfImports(); 1508 if (nImports > 0) { 1509 return getImportAt(nImports - 1); 1510 } 1511 return null; 1512 } 1513 1514 public boolean isComment() { 1515 return "!".equals(fName); } 1517 1518 public boolean isDefaultPackage() { 1519 return fName.length() == 0; 1520 } 1521 1522 public String toString() { 1523 StringBuffer buf= new StringBuffer (); 1524 if (isComment()) { 1525 buf.append("comment\n"); } else { 1527 buf.append(fName); buf.append(", groupId: "); buf.append(fGroup); buf.append("\n"); int nImports= getNumberOfImports(); 1529 for (int i= 0; i < nImports; i++) { 1530 ImportDeclEntry curr= getImportAt(i); 1531 buf.append(" "); if (curr.isStatic()) { 1533 buf.append("static "); } 1535 buf.append(curr.getSimpleName()); 1536 if (curr.isNew()) { 1537 buf.append(" (new)"); } 1539 buf.append("\n"); } 1541 } 1542 return buf.toString(); 1543 } 1544 } 1545 1546 public String [] getCreatedImports() { 1547 if (fImportsCreated == null) { 1548 return new String [0]; 1549 } 1550 return (String []) fImportsCreated.toArray(new String [fImportsCreated.size()]); 1551 } 1552 1553 public String [] getCreatedStaticImports() { 1554 if (fStaticImportsCreated == null) { 1555 return new String [0]; 1556 } 1557 return (String []) fStaticImportsCreated.toArray(new String [fStaticImportsCreated.size()]); 1558 } 1559 1560 1564 public boolean hasChanges() { 1565 return fHasChanges; 1566 } 1567 1568 1569 1570} 1571 | Popular Tags |