1 11 package org.eclipse.jdt.internal.corext.refactoring.reorg; 12 13 import java.util.ArrayList ; 14 import java.util.Arrays ; 15 import java.util.Collections ; 16 import java.util.Comparator ; 17 import java.util.HashMap ; 18 import java.util.HashSet ; 19 import java.util.Iterator ; 20 import java.util.List ; 21 import java.util.Map ; 22 import java.util.Set ; 23 24 import org.eclipse.core.runtime.Assert; 25 import org.eclipse.core.runtime.CoreException; 26 import org.eclipse.core.runtime.IProgressMonitor; 27 import org.eclipse.core.runtime.OperationCanceledException; 28 29 import org.eclipse.core.filebuffers.FileBuffers; 30 import org.eclipse.core.filebuffers.ITextFileBuffer; 31 import org.eclipse.core.filebuffers.LocationKind; 32 33 import org.eclipse.core.resources.IContainer; 34 import org.eclipse.core.resources.IFile; 35 import org.eclipse.core.resources.IFolder; 36 import org.eclipse.core.resources.IProject; 37 import org.eclipse.core.resources.IResource; 38 import org.eclipse.core.resources.IResourceVisitor; 39 import org.eclipse.core.resources.mapping.IResourceChangeDescriptionFactory; 40 41 import org.eclipse.ltk.core.refactoring.Change; 42 import org.eclipse.ltk.core.refactoring.RefactoringDescriptor; 43 import org.eclipse.ltk.core.refactoring.RefactoringStatus; 44 import org.eclipse.ltk.core.refactoring.participants.CheckConditionsContext; 45 import org.eclipse.ltk.core.refactoring.participants.DeleteProcessor; 46 import org.eclipse.ltk.core.refactoring.participants.RefactoringArguments; 47 import org.eclipse.ltk.core.refactoring.participants.RefactoringParticipant; 48 import org.eclipse.ltk.core.refactoring.participants.ResourceChangeChecker; 49 import org.eclipse.ltk.core.refactoring.participants.SharableParticipants; 50 51 import org.eclipse.jdt.core.ICompilationUnit; 52 import org.eclipse.jdt.core.IField; 53 import org.eclipse.jdt.core.IJavaElement; 54 import org.eclipse.jdt.core.IJavaProject; 55 import org.eclipse.jdt.core.IMethod; 56 import org.eclipse.jdt.core.IPackageFragment; 57 import org.eclipse.jdt.core.IPackageFragmentRoot; 58 import org.eclipse.jdt.core.IType; 59 import org.eclipse.jdt.core.JavaCore; 60 import org.eclipse.jdt.core.JavaModelException; 61 import org.eclipse.jdt.core.refactoring.IJavaRefactorings; 62 import org.eclipse.jdt.core.refactoring.descriptors.JavaRefactoringDescriptor; 63 64 import org.eclipse.jdt.internal.corext.codemanipulation.GetterSetterUtil; 65 import org.eclipse.jdt.internal.corext.refactoring.JDTRefactoringDescriptor; 66 import org.eclipse.jdt.internal.corext.refactoring.JDTRefactoringDescriptorComment; 67 import org.eclipse.jdt.internal.corext.refactoring.JavaRefactoringArguments; 68 import org.eclipse.jdt.internal.corext.refactoring.RefactoringAvailabilityTester; 69 import org.eclipse.jdt.internal.corext.refactoring.RefactoringCoreMessages; 70 import org.eclipse.jdt.internal.corext.refactoring.changes.DynamicValidationRefactoringChange; 71 import org.eclipse.jdt.internal.corext.refactoring.code.ScriptableRefactoring; 72 import org.eclipse.jdt.internal.corext.refactoring.participants.JavaProcessors; 73 import org.eclipse.jdt.internal.corext.refactoring.participants.ResourceProcessors; 74 import org.eclipse.jdt.internal.corext.refactoring.tagging.ICommentProvider; 75 import org.eclipse.jdt.internal.corext.refactoring.tagging.IScriptableRefactoring; 76 import org.eclipse.jdt.internal.corext.refactoring.util.JavaElementUtil; 77 import org.eclipse.jdt.internal.corext.refactoring.util.ResourceUtil; 78 import org.eclipse.jdt.internal.corext.refactoring.util.TextChangeManager; 79 import org.eclipse.jdt.internal.corext.util.Messages; 80 import org.eclipse.jdt.internal.corext.util.Resources; 81 82 import org.eclipse.jdt.internal.ui.JavaPlugin; 83 84 public final class JavaDeleteProcessor extends DeleteProcessor implements IScriptableRefactoring, ICommentProvider { 85 86 private static final String ATTRIBUTE_RESOURCES= "resources"; private static final String ATTRIBUTE_ELEMENTS= "elements"; private static final String ATTRIBUTE_SUGGEST_ACCESSORS= "accessors"; private static final String ATTRIBUTE_DELETE_SUBPACKAGES= "subPackages"; 91 private boolean fAccessorsDeleted; 92 private boolean fWasCanceled; 93 private boolean fSuggestGetterSetterDeletion; 94 private Object [] fElements; 95 private IResource[] fResources; 96 private IJavaElement[] fJavaElements; 97 private IReorgQueries fDeleteQueries; 98 private DeleteModifications fDeleteModifications; 99 private String fComment; 100 101 private Change fDeleteChange; 102 private boolean fDeleteSubPackages; 103 104 public static final String IDENTIFIER= "org.eclipse.jdt.ui.DeleteProcessor"; 106 public JavaDeleteProcessor(Object [] elements) { 107 fElements= elements; 108 if (fElements != null) { 109 fResources= RefactoringAvailabilityTester.getResources(elements); 110 fJavaElements= RefactoringAvailabilityTester.getJavaElements(elements); 111 } 112 fSuggestGetterSetterDeletion= true; 113 fDeleteSubPackages= false; 114 fWasCanceled= false; 115 } 116 117 public String getIdentifier() { 118 return IDENTIFIER; 119 } 120 121 public boolean isApplicable() throws CoreException { 122 if (fElements.length == 0) 123 return false; 124 if (fElements.length != fResources.length + fJavaElements.length) 125 return false; 126 for (int i= 0; i < fResources.length; i++) { 127 if (!RefactoringAvailabilityTester.isDeleteAvailable(fResources[i])) 128 return false; 129 } 130 for (int i= 0; i < fJavaElements.length; i++) { 131 if (!RefactoringAvailabilityTester.isDeleteAvailable(fJavaElements[i])) 132 return false; 133 } 134 return true; 135 } 136 137 public boolean needsProgressMonitor() { 138 if (fResources != null && fResources.length > 0) 139 return true; 140 if (fJavaElements != null) { 141 for (int i= 0; i < fJavaElements.length; i++) { 142 int type= fJavaElements[i].getElementType(); 143 if (type <= IJavaElement.CLASS_FILE) 144 return true; 145 } 146 } 147 return false; 148 149 } 150 151 public String getProcessorName() { 152 return RefactoringCoreMessages.DeleteRefactoring_7; 153 } 154 155 public Object [] getElements() { 156 return fElements; 157 } 158 159 public RefactoringParticipant[] loadParticipants(RefactoringStatus status, SharableParticipants shared) throws CoreException { 160 return fDeleteModifications.loadParticipants(status, this, getAffectedProjectNatures(), shared); 161 } 162 163 private String [] getAffectedProjectNatures() throws CoreException { 164 String [] jNatures= JavaProcessors.computeAffectedNaturs(fJavaElements); 165 String [] rNatures= ResourceProcessors.computeAffectedNatures(fResources); 166 Set result= new HashSet (); 167 result.addAll(Arrays.asList(jNatures)); 168 result.addAll(Arrays.asList(rNatures)); 169 return (String [])result.toArray(new String [result.size()]); 170 } 171 172 176 public void setSuggestGetterSetterDeletion(boolean suggest){ 177 fSuggestGetterSetterDeletion= suggest; 178 } 179 180 public void setDeleteSubPackages(boolean selection) { 181 fDeleteSubPackages= selection; 182 } 183 184 public boolean getDeleteSubPackages() { 185 return fDeleteSubPackages; 186 } 187 188 public boolean hasSubPackagesToDelete() { 189 try { 190 for (int i= 0; i < fJavaElements.length; i++) { 191 if (fJavaElements[i] instanceof IPackageFragment) { 192 IPackageFragment packageFragment= (IPackageFragment) fJavaElements[i]; 193 if (packageFragment.isDefaultPackage()) 194 continue; if (packageFragment.hasSubpackages()) 196 return true; 197 } 198 } 199 } catch (JavaModelException e) { 200 JavaPlugin.log(e); 201 } 202 return false; 203 } 204 205 public void setQueries(IReorgQueries queries){ 206 Assert.isNotNull(queries); 207 fDeleteQueries= queries; 208 } 209 210 public IJavaElement[] getJavaElementsToDelete(){ 211 return fJavaElements; 212 } 213 214 public boolean wasCanceled() { 215 return fWasCanceled; 216 } 217 218 public IResource[] getResourcesToDelete(){ 219 return fResources; 220 } 221 222 225 public RefactoringStatus checkInitialConditions(IProgressMonitor pm) throws CoreException { 226 Assert.isNotNull(fDeleteQueries); RefactoringStatus result= new RefactoringStatus(); 228 result.merge(RefactoringStatus.create(Resources.checkInSync(ReorgUtils.getNotLinked(fResources)))); 229 IResource[] javaResources= ReorgUtils.getResources(fJavaElements); 230 result.merge(RefactoringStatus.create(Resources.checkInSync(ReorgUtils.getNotNulls(javaResources)))); 231 for (int i= 0; i < fJavaElements.length; i++) { 232 IJavaElement element= fJavaElements[i]; 233 if (element instanceof IType && ((IType)element).isAnonymous()) { 234 } 237 } 238 return result; 239 } 240 241 244 public RefactoringStatus checkFinalConditions(IProgressMonitor pm, CheckConditionsContext context) throws CoreException { 245 pm.beginTask(RefactoringCoreMessages.DeleteRefactoring_1, 1); 246 try{ 247 fWasCanceled= false; 248 RefactoringStatus result= new RefactoringStatus(); 249 250 recalculateElementsToDelete(); 251 252 checkDirtyCompilationUnits(result); 253 checkDirtyResources(result); 254 fDeleteModifications= new DeleteModifications(); 255 fDeleteModifications.delete(fResources); 256 fDeleteModifications.delete(fJavaElements); 257 List packageDeletes= fDeleteModifications.postProcess(); 258 259 TextChangeManager manager= new TextChangeManager(); 260 fDeleteChange= DeleteChangeCreator.createDeleteChange(manager, fResources, fJavaElements, getProcessorName(), packageDeletes); 261 262 ResourceChangeChecker checker= (ResourceChangeChecker) context.getChecker(ResourceChangeChecker.class); 263 IResourceChangeDescriptionFactory deltaFactory= checker.getDeltaFactory(); 264 fDeleteModifications.buildDelta(deltaFactory); 265 IFile[] files= ResourceUtil.getFiles(manager.getAllCompilationUnits()); 266 for (int i= 0; i < files.length; i++) { 267 deltaFactory.change(files[i]); 268 } 269 return result; 270 } catch (OperationCanceledException e) { 271 fWasCanceled= true; 272 throw e; 273 } catch (JavaModelException e){ 274 throw e; 275 } catch (CoreException e) { 276 throw new JavaModelException(e); 277 } finally{ 278 pm.done(); 279 } 280 } 281 282 private void checkDirtyCompilationUnits(RefactoringStatus result) throws CoreException { 283 if (fJavaElements == null || fJavaElements.length == 0) 284 return; 285 for (int je= 0; je < fJavaElements.length; je++) { 286 IJavaElement element= fJavaElements[je]; 287 if (element instanceof ICompilationUnit) { 288 checkDirtyCompilationUnit(result, (ICompilationUnit)element); 289 } else if (element instanceof IPackageFragment) { 290 ICompilationUnit[] units= ((IPackageFragment)element).getCompilationUnits(); 291 for (int u = 0; u < units.length; u++) { 292 checkDirtyCompilationUnit(result, units[u]); 293 } 294 } 295 } 296 } 297 298 private void checkDirtyCompilationUnit(RefactoringStatus result, ICompilationUnit cunit) { 299 IResource resource= cunit.getResource(); 300 if (resource == null || resource.getType() != IResource.FILE) 301 return; 302 checkDirtyFile(result, (IFile)resource); 303 } 304 305 private void checkDirtyResources(final RefactoringStatus result) throws CoreException { 306 for (int i= 0; i < fResources.length; i++) { 307 IResource resource= fResources[i]; 308 resource.accept(new IResourceVisitor() { 309 public boolean visit(IResource visitedResource) throws CoreException { 310 if (visitedResource instanceof IFile) { 311 checkDirtyFile(result, (IFile)visitedResource); 312 } 313 return true; 314 } 315 }, IResource.DEPTH_INFINITE, false); 316 } 317 } 318 319 private void checkDirtyFile(RefactoringStatus result, IFile file) { 320 if (file == null || !file.exists()) 321 return; 322 ITextFileBuffer buffer= FileBuffers.getTextFileBufferManager().getTextFileBuffer(file.getFullPath(), LocationKind.IFILE); 323 if (buffer != null && buffer.isDirty()) { 324 if (buffer.isStateValidated() && buffer.isSynchronized()) { 325 result.addWarning(Messages.format( 326 RefactoringCoreMessages.JavaDeleteProcessor_unsaved_changes, 327 file.getFullPath().toString())); 328 } else { 329 result.addFatalError(Messages.format( 330 RefactoringCoreMessages.JavaDeleteProcessor_unsaved_changes, 331 file.getFullPath().toString())); 332 } 333 } 334 } 335 336 342 private void recalculateElementsToDelete() throws CoreException { 343 fAccessorsDeleted= false; 345 if (fDeleteSubPackages) 346 addSubPackages(); 347 348 removeElementsWithParentsInSelection(); 350 removeUnconfirmedFoldersThatContainSourceFolders(); 352 removeUnconfirmedReferencedArchives(); 353 addEmptyCusToDelete(); 354 removeJavaElementsChildrenOfJavaElements(); 356 confirmDeletingReadOnly(); 357 358 if (fSuggestGetterSetterDeletion) 359 addGettersSetters(); 360 361 addDeletableParentPackagesOnPackageDeletion(); 362 } 363 364 370 private void addSubPackages() throws JavaModelException { 371 372 final Set javaElements= new HashSet (); 373 for (int i= 0; i < fJavaElements.length; i++) { 374 if (fJavaElements[i] instanceof IPackageFragment) { 375 javaElements.addAll(Arrays.asList(JavaElementUtil.getPackageAndSubpackages((IPackageFragment) fJavaElements[i]))); 376 } else { 377 javaElements.add(fJavaElements[i]); 378 } 379 } 380 381 fJavaElements= (IJavaElement[]) javaElements.toArray(new IJavaElement[javaElements.size()]); 382 } 383 384 389 private void addDeletableParentPackagesOnPackageDeletion() throws CoreException { 390 391 final List initialPackagesToDelete= ReorgUtils.getElementsOfType(fJavaElements, IJavaElement.PACKAGE_FRAGMENT); 392 393 if (initialPackagesToDelete.size() == 0) 394 return; 395 396 Collections.sort(initialPackagesToDelete, new Comparator () { 398 public int compare(Object arg0, Object arg1) { 399 IPackageFragment one= (IPackageFragment) arg0; 400 IPackageFragment two= (IPackageFragment) arg1; 401 return two.getElementName().compareTo(one.getElementName()); 402 } 403 }); 404 405 final Set deletedChildren= new HashSet (); 407 deletedChildren.addAll(Arrays.asList(fResources)); 408 for (int i= 0; i < fJavaElements.length; i++) { 409 if (!ReorgUtils.isInsideCompilationUnit(fJavaElements[i])) 410 deletedChildren.add(fJavaElements[i].getResource()); 411 } 412 413 final List allFragmentsToDelete= new ArrayList (); 415 416 for (Iterator outerIter= initialPackagesToDelete.iterator(); outerIter.hasNext();) { 417 final IPackageFragment currentPackageFragment= (IPackageFragment) outerIter.next(); 418 419 allFragmentsToDelete.add(currentPackageFragment); 421 422 if (canRemoveCompletely(currentPackageFragment, initialPackagesToDelete)) { 423 424 final IPackageFragment parent= JavaElementUtil.getParentSubpackage(currentPackageFragment); 425 if (parent != null && !initialPackagesToDelete.contains(parent)) { 426 427 final List emptyParents= new ArrayList (); 428 addDeletableParentPackages(parent, initialPackagesToDelete, deletedChildren, emptyParents); 429 430 allFragmentsToDelete.addAll(emptyParents); 432 } 433 } 434 } 435 436 final List javaElements= new ArrayList (); 438 for (int i= 0; i < fJavaElements.length; i++) { 439 if (!(fJavaElements[i] instanceof IPackageFragment)) { 440 final IPackageFragment frag= (IPackageFragment) fJavaElements[i].getAncestor(IJavaElement.PACKAGE_FRAGMENT); 442 if (!allFragmentsToDelete.contains(frag)) 443 javaElements.add(fJavaElements[i]); 444 } 445 } 446 javaElements.addAll(allFragmentsToDelete); 448 449 final List resources= new ArrayList (); 451 for (int i= 0; i < fResources.length; i++) { 452 IResource parent= fResources[i]; 453 if (parent.getType() == IResource.FILE) 454 parent= parent.getParent(); 455 if (!deletedChildren.contains(parent)) 456 resources.add(fResources[i]); 457 } 458 459 fJavaElements= (IJavaElement[]) javaElements.toArray(new IJavaElement[javaElements.size()]); 460 fResources= (IResource[]) resources.toArray(new IResource[resources.size()]); 461 } 462 463 468 private boolean canRemoveCompletely(IPackageFragment pack, List packagesToDelete) throws JavaModelException { 469 final IPackageFragment[] subPackages= JavaElementUtil.getPackageAndSubpackages(pack); 470 for (int i= 0; i < subPackages.length; i++) { 471 if (!(subPackages[i].equals(pack)) && !(packagesToDelete.contains(subPackages[i]))) 472 return false; 473 } 474 return true; 475 } 476 477 483 private void addDeletableParentPackages(IPackageFragment frag, List initialPackagesToDelete, Set resourcesToDelete, List deletableParentPackages) 484 throws CoreException { 485 486 if (frag.getResource().isLinked()) { 487 final IConfirmQuery query= fDeleteQueries.createYesNoQuery(RefactoringCoreMessages.JavaDeleteProcessor_confirm_linked_folder_delete, false, IReorgQueries.CONFIRM_DELETE_LINKED_PARENT); 488 if (!query.confirm(Messages.format(RefactoringCoreMessages.JavaDeleteProcessor_delete_linked_folder_question, new String [] { frag.getResource().getName() }))) 489 return; 490 } 491 492 final IResource[] children= (((IContainer) frag.getResource())).members(); 493 for (int i= 0; i < children.length; i++) { 494 if (!resourcesToDelete.contains(children[i])) 497 return; 498 } 499 resourcesToDelete.add(frag.getResource()); 500 deletableParentPackages.add(frag); 501 502 final IPackageFragment parent= JavaElementUtil.getParentSubpackage(frag); 503 if (parent != null && !initialPackagesToDelete.contains(parent)) 504 addDeletableParentPackages(parent, initialPackagesToDelete, resourcesToDelete, deletableParentPackages); 505 } 506 507 private void removeUnconfirmedReferencedArchives() throws JavaModelException { 510 String queryTitle= RefactoringCoreMessages.DeleteRefactoring_2; 511 IConfirmQuery query= fDeleteQueries.createYesYesToAllNoNoToAllQuery(queryTitle, true, IReorgQueries.CONFIRM_DELETE_REFERENCED_ARCHIVES); 512 removeUnconfirmedReferencedPackageFragmentRoots(query); 513 removeUnconfirmedReferencedArchiveFiles(query); 514 } 515 516 private void removeUnconfirmedReferencedArchiveFiles(IConfirmQuery query) throws JavaModelException, OperationCanceledException { 517 List filesToSkip= new ArrayList (0); 518 for (int i= 0; i < fResources.length; i++) { 519 IResource resource= fResources[i]; 520 if (! (resource instanceof IFile)) 521 continue; 522 523 IJavaProject project= JavaCore.create(resource.getProject()); 524 if (project == null || ! project.exists()) 525 continue; 526 IPackageFragmentRoot root= project.findPackageFragmentRoot(resource.getFullPath()); 527 if (root == null) 528 continue; 529 List referencingProjects= Arrays.asList(JavaElementUtil.getReferencingProjects(root)); 530 if (skipDeletingReferencedRoot(query, root, referencingProjects)) 531 filesToSkip.add(resource); 532 } 533 removeFromSetToDelete((IFile[]) filesToSkip.toArray(new IFile[filesToSkip.size()])); 534 } 535 536 private void removeUnconfirmedReferencedPackageFragmentRoots(IConfirmQuery query) throws JavaModelException, OperationCanceledException { 537 List rootsToSkip= new ArrayList (0); 538 for (int i= 0; i < fJavaElements.length; i++) { 539 IJavaElement element= fJavaElements[i]; 540 if (! (element instanceof IPackageFragmentRoot)) 541 continue; 542 IPackageFragmentRoot root= (IPackageFragmentRoot)element; 543 ArrayList referencingProjects= new ArrayList (Arrays.asList(JavaElementUtil.getReferencingProjects(root))); 544 referencingProjects.remove(root.getJavaProject()); 545 if (skipDeletingReferencedRoot(query, root, referencingProjects)) 546 rootsToSkip.add(root); 547 } 548 removeFromSetToDelete((IJavaElement[]) rootsToSkip.toArray(new IJavaElement[rootsToSkip.size()])); 549 } 550 551 private static boolean skipDeletingReferencedRoot(IConfirmQuery query, IPackageFragmentRoot root, List referencingProjects) throws OperationCanceledException { 552 if (referencingProjects.isEmpty() || root == null || ! root.exists() ||! root.isArchive()) 553 return false; 554 String question= Messages.format(RefactoringCoreMessages.DeleteRefactoring_3, root.getElementName()); 555 return ! query.confirm(question, referencingProjects.toArray()); 556 } 557 558 private void removeUnconfirmedFoldersThatContainSourceFolders() throws CoreException { 559 String queryTitle= RefactoringCoreMessages.DeleteRefactoring_4; 560 IConfirmQuery query= fDeleteQueries.createYesYesToAllNoNoToAllQuery(queryTitle, true, IReorgQueries.CONFIRM_DELETE_FOLDERS_CONTAINING_SOURCE_FOLDERS); 561 List foldersToSkip= new ArrayList (0); 562 for (int i= 0; i < fResources.length; i++) { 563 IResource resource= fResources[i]; 564 if (resource instanceof IFolder){ 565 IFolder folder= (IFolder)resource; 566 if (containsSourceFolder(folder)){ 567 String question= Messages.format(RefactoringCoreMessages.DeleteRefactoring_5, folder.getName()); 568 if (! query.confirm(question)) 569 foldersToSkip.add(folder); 570 } 571 } 572 } 573 removeFromSetToDelete((IResource[]) foldersToSkip.toArray(new IResource[foldersToSkip.size()])); 574 } 575 576 private static boolean containsSourceFolder(IFolder folder) throws CoreException { 577 IResource[] subFolders= folder.members(); 578 for (int i = 0; i < subFolders.length; i++) { 579 if (! (subFolders[i] instanceof IFolder)) 580 continue; 581 IJavaElement element= JavaCore.create(folder); 582 if (element instanceof IPackageFragmentRoot) 583 return true; 584 if (element instanceof IPackageFragment) 585 continue; 586 if (containsSourceFolder((IFolder)subFolders[i])) 587 return true; 588 } 589 return false; 590 } 591 592 private void removeElementsWithParentsInSelection() { 593 ParentChecker parentUtil= new ParentChecker(fResources, fJavaElements); 594 parentUtil.removeElementsWithAncestorsOnList(false); 595 fJavaElements= parentUtil.getJavaElements(); 596 fResources= parentUtil.getResources(); 597 } 598 599 private void removeJavaElementsChildrenOfJavaElements(){ 600 ParentChecker parentUtil= new ParentChecker(fResources, fJavaElements); 601 parentUtil.removeElementsWithAncestorsOnList(true); 602 fJavaElements= parentUtil.getJavaElements(); 603 } 604 605 public Change createChange(IProgressMonitor monitor) throws CoreException { 606 try { 607 monitor.beginTask(RefactoringCoreMessages.JavaDeleteProcessor_creating_change, 1); 608 final Map arguments= new HashMap (); 609 final String description= fElements.length == 1 ? RefactoringCoreMessages.JavaDeleteProcessor_description_singular : RefactoringCoreMessages.JavaDeleteProcessor_description_plural; 610 final IProject resource= getSingleProject(); 611 final String project= resource != null ? resource.getName() : null; 612 final String source= project != null ? Messages.format(RefactoringCoreMessages.JavaDeleteProcessor_project_pattern, project) : RefactoringCoreMessages.JavaDeleteProcessor_workspace; 613 final String header= Messages.format(RefactoringCoreMessages.JavaDeleteProcessor_header, new String [] { String.valueOf(fElements.length), source}); 614 int flags= JavaRefactoringDescriptor.JAR_MIGRATION | JavaRefactoringDescriptor.JAR_REFACTORING | RefactoringDescriptor.STRUCTURAL_CHANGE | RefactoringDescriptor.MULTI_CHANGE; 615 final JDTRefactoringDescriptorComment comment= new JDTRefactoringDescriptorComment(project, this, header); 616 if (fDeleteSubPackages) 617 comment.addSetting(RefactoringCoreMessages.JavaDeleteProcessor_delete_subpackages); 618 if (fAccessorsDeleted) 619 comment.addSetting(RefactoringCoreMessages.JavaDeleteProcessor_delete_accessors); 620 final JDTRefactoringDescriptor descriptor= new JDTRefactoringDescriptor(IJavaRefactorings.DELETE, project, description, comment.asString(), arguments, flags); 621 arguments.put(ATTRIBUTE_DELETE_SUBPACKAGES, Boolean.valueOf(fDeleteSubPackages).toString()); 622 arguments.put(ATTRIBUTE_SUGGEST_ACCESSORS, Boolean.valueOf(fSuggestGetterSetterDeletion).toString()); 623 arguments.put(ATTRIBUTE_RESOURCES, new Integer (fResources.length).toString()); 624 for (int offset= 0; offset < fResources.length; offset++) 625 arguments.put(JDTRefactoringDescriptor.ATTRIBUTE_ELEMENT + (offset + 1), descriptor.resourceToHandle(fResources[offset])); 626 arguments.put(ATTRIBUTE_ELEMENTS, new Integer (fJavaElements.length).toString()); 627 for (int offset= 0; offset < fJavaElements.length; offset++) 628 arguments.put(JDTRefactoringDescriptor.ATTRIBUTE_ELEMENT + (offset + fResources.length + 1), descriptor.elementToHandle(fJavaElements[offset])); 629 return new DynamicValidationRefactoringChange(descriptor, RefactoringCoreMessages.DeleteRefactoring_7, new Change[] { fDeleteChange}); 630 } finally { 631 monitor.done(); 632 } 633 } 634 635 private IProject getSingleProject() { 636 IProject first= null; 637 for (int index= 0; index < fElements.length; index++) { 638 IProject project= null; 639 if (fElements[index] instanceof IJavaElement) 640 project= ((IJavaElement) fElements[index]).getJavaProject().getProject(); 641 else if (fElements[index] instanceof IResource) 642 project= ((IResource) fElements[index]).getProject(); 643 if (project != null) { 644 if (first == null) 645 first= project; 646 else if (!project.equals(first)) 647 return null; 648 } 649 } 650 return first; 651 } 652 653 private void addToSetToDelete(IJavaElement[] newElements){ 654 fJavaElements= ReorgUtils.union(fJavaElements, newElements); 655 } 656 657 private void removeFromSetToDelete(IResource[] resourcesToNotDelete) { 658 fResources= ReorgUtils.setMinus(fResources, resourcesToNotDelete); 659 } 660 661 private void removeFromSetToDelete(IJavaElement[] elementsToNotDelete) { 662 fJavaElements= ReorgUtils.setMinus(fJavaElements, elementsToNotDelete); 663 } 664 665 private void addGettersSetters() throws JavaModelException { 666 IField[] fields= getFields(fJavaElements); 667 if (fields.length == 0) 668 return; 669 Map getterSetterMapping= createGetterSetterMapping(fields); 671 if (getterSetterMapping.isEmpty()) 672 return; 673 removeAlreadySelectedMethods(getterSetterMapping); 674 if (getterSetterMapping.isEmpty()) 675 return; 676 fAccessorsDeleted= true; 677 List gettersSettersToAdd= getGettersSettersToDelete(getterSetterMapping); 678 addToSetToDelete((IMethod[]) gettersSettersToAdd.toArray(new IMethod[gettersSettersToAdd.size()])); 679 } 680 681 private List getGettersSettersToDelete(Map getterSetterMapping) { 682 List gettersSettersToAdd= new ArrayList (getterSetterMapping.size()); 683 String queryTitle= RefactoringCoreMessages.DeleteRefactoring_8; 684 IConfirmQuery getterSetterQuery= fDeleteQueries.createYesYesToAllNoNoToAllQuery(queryTitle, true, IReorgQueries.CONFIRM_DELETE_GETTER_SETTER); 685 for (Iterator iter= getterSetterMapping.keySet().iterator(); iter.hasNext();) { 686 IField field= (IField) iter.next(); 687 Assert.isTrue(hasGetter(getterSetterMapping, field) || hasSetter(getterSetterMapping, field)); 688 String deleteGetterSetter= Messages.format(RefactoringCoreMessages.DeleteRefactoring_9, JavaElementUtil.createFieldSignature(field)); 689 if (getterSetterQuery.confirm(deleteGetterSetter)){ 690 if (hasGetter(getterSetterMapping, field)) 691 gettersSettersToAdd.add(getGetter(getterSetterMapping, field)); 692 if (hasSetter(getterSetterMapping, field)) 693 gettersSettersToAdd.add(getSetter(getterSetterMapping, field)); 694 } 695 } 696 return gettersSettersToAdd; 697 } 698 699 private void removeAlreadySelectedMethods(Map getterSetterMapping) { 701 List elementsToDelete= Arrays.asList(fJavaElements); 702 for (Iterator iter= getterSetterMapping.keySet().iterator(); iter.hasNext();) { 703 IField field= (IField) iter.next(); 704 IMethod getter= getGetter(getterSetterMapping, field); 706 if (getter != null && elementsToDelete.contains(getter)) 707 removeGetterFromMapping(getterSetterMapping, field); 708 709 IMethod setter= getSetter(getterSetterMapping, field); 711 if (setter != null && elementsToDelete.contains(setter)) 712 removeSetterFromMapping(getterSetterMapping, field); 713 714 if (! hasGetter(getterSetterMapping, field) && ! hasSetter(getterSetterMapping, field)) 716 iter.remove(); 717 } 718 } 719 720 723 private static Map createGetterSetterMapping(IField[] fields) throws JavaModelException { 724 Map result= new HashMap (); 725 for (int i= 0; i < fields.length; i++) { 726 IField field= fields[i]; 727 IMethod[] getterSetter= getGetterSetter(field); 728 if (getterSetter != null) 729 result.put(field, getterSetter); 730 } 731 return result; 732 } 733 private static boolean hasSetter(Map getterSetterMapping, IField field){ 734 return getterSetterMapping.containsKey(field) && 735 getSetter(getterSetterMapping, field) != null; 736 } 737 private static boolean hasGetter(Map getterSetterMapping, IField field){ 738 return getterSetterMapping.containsKey(field) && 739 getGetter(getterSetterMapping, field) != null; 740 } 741 private static void removeGetterFromMapping(Map getterSetterMapping, IField field){ 742 ((IMethod[])getterSetterMapping.get(field))[0]= null; 743 } 744 private static void removeSetterFromMapping(Map getterSetterMapping, IField field){ 745 ((IMethod[])getterSetterMapping.get(field))[1]= null; 746 } 747 private static IMethod getGetter(Map getterSetterMapping, IField field){ 748 return ((IMethod[])getterSetterMapping.get(field))[0]; 749 } 750 private static IMethod getSetter(Map getterSetterMapping, IField field){ 751 return ((IMethod[])getterSetterMapping.get(field))[1]; 752 } 753 private static IField[] getFields(IJavaElement[] elements){ 754 List fields= new ArrayList (3); 755 for (int i= 0; i < elements.length; i++) { 756 if (elements[i] instanceof IField) 757 fields.add(elements[i]); 758 } 759 return (IField[]) fields.toArray(new IField[fields.size()]); 760 } 761 762 765 private static IMethod[] getGetterSetter(IField field) throws JavaModelException { 766 IMethod getter= GetterSetterUtil.getGetter(field); 767 IMethod setter= GetterSetterUtil.getSetter(field); 768 if ((getter != null && getter.exists()) || (setter != null && setter.exists())) 769 return new IMethod[]{getter, setter}; 770 else 771 return null; 772 } 773 774 private void confirmDeletingReadOnly() throws CoreException { 776 if (! ReadOnlyResourceFinder.confirmDeleteOfReadOnlyElements(fJavaElements, fResources, fDeleteQueries)) 777 throw new OperationCanceledException(); } 779 780 private void addEmptyCusToDelete() throws JavaModelException { 782 Set cusToEmpty= getCusToEmpty(); 783 addToSetToDelete((ICompilationUnit[]) cusToEmpty.toArray(new ICompilationUnit[cusToEmpty.size()])); 784 } 785 786 private Set getCusToEmpty() throws JavaModelException { 787 Set result= new HashSet (); 788 for (int i= 0; i < fJavaElements.length; i++) { 789 IJavaElement element= fJavaElements[i]; 790 ICompilationUnit cu= ReorgUtils.getCompilationUnit(element); 791 if (cu != null && ! result.contains(cu) && willHaveAllTopLevelTypesDeleted(cu)) 792 result.add(cu); 793 } 794 return result; 795 } 796 797 private boolean willHaveAllTopLevelTypesDeleted(ICompilationUnit cu) throws JavaModelException { 798 Set elementSet= new HashSet (Arrays.asList(fJavaElements)); 799 IType[] topLevelTypes= cu.getTypes(); 800 for (int i= 0; i < topLevelTypes.length; i++) { 801 if (! elementSet.contains(topLevelTypes[i])) 802 return false; 803 } 804 return true; 805 } 806 807 public boolean canEnableComment() { 808 return true; 809 } 810 811 public String getComment() { 812 return fComment; 813 } 814 815 public void setComment(String comment) { 816 fComment= comment; 817 } 818 819 public RefactoringStatus initialize(RefactoringArguments arguments) { 820 setQueries(new NullReorgQueries()); 821 final RefactoringStatus status= new RefactoringStatus(); 822 if (arguments instanceof JavaRefactoringArguments) { 823 final JavaRefactoringArguments extended= (JavaRefactoringArguments) arguments; 824 final String subPackages= extended.getAttribute(ATTRIBUTE_DELETE_SUBPACKAGES); 825 if (subPackages != null) { 826 fDeleteSubPackages= Boolean.valueOf(subPackages).booleanValue(); 827 } else 828 return RefactoringStatus.createFatalErrorStatus(Messages.format(RefactoringCoreMessages.InitializableRefactoring_argument_not_exist, ATTRIBUTE_DELETE_SUBPACKAGES)); 829 final String suggest= extended.getAttribute(ATTRIBUTE_SUGGEST_ACCESSORS); 830 if (suggest != null) { 831 fSuggestGetterSetterDeletion= Boolean.valueOf(suggest).booleanValue(); 832 } else 833 return RefactoringStatus.createFatalErrorStatus(Messages.format(RefactoringCoreMessages.InitializableRefactoring_argument_not_exist, ATTRIBUTE_SUGGEST_ACCESSORS)); 834 int resourceCount= 0; 835 int elementCount= 0; 836 String value= extended.getAttribute(ATTRIBUTE_RESOURCES); 837 if (value != null && !"".equals(value)) { try { 839 resourceCount= Integer.parseInt(value); 840 } catch (NumberFormatException exception) { 841 return RefactoringStatus.createFatalErrorStatus(Messages.format(RefactoringCoreMessages.InitializableRefactoring_argument_not_exist, ATTRIBUTE_RESOURCES)); 842 } 843 } else 844 return RefactoringStatus.createFatalErrorStatus(Messages.format(RefactoringCoreMessages.InitializableRefactoring_argument_not_exist, ATTRIBUTE_RESOURCES)); 845 value= extended.getAttribute(ATTRIBUTE_ELEMENTS); 846 if (value != null && !"".equals(value)) { try { 848 elementCount= Integer.parseInt(value); 849 } catch (NumberFormatException exception) { 850 return RefactoringStatus.createFatalErrorStatus(Messages.format(RefactoringCoreMessages.InitializableRefactoring_argument_not_exist, ATTRIBUTE_ELEMENTS)); 851 } 852 } else 853 return RefactoringStatus.createFatalErrorStatus(Messages.format(RefactoringCoreMessages.InitializableRefactoring_argument_not_exist, ATTRIBUTE_ELEMENTS)); 854 String handle= null; 855 List elements= new ArrayList (); 856 for (int index= 0; index < resourceCount; index++) { 857 final String attribute= JDTRefactoringDescriptor.ATTRIBUTE_ELEMENT + (index + 1); 858 handle= extended.getAttribute(attribute); 859 if (handle != null && !"".equals(handle)) { final IResource resource= JDTRefactoringDescriptor.handleToResource(extended.getProject(), handle); 861 if (resource == null || !resource.exists()) 862 status.merge(ScriptableRefactoring.createInputWarningStatus(resource, getRefactoring().getName(), IJavaRefactorings.DELETE)); 863 else 864 elements.add(resource); 865 } else 866 return RefactoringStatus.createFatalErrorStatus(Messages.format(RefactoringCoreMessages.InitializableRefactoring_argument_not_exist, attribute)); 867 } 868 fResources= (IResource[]) elements.toArray(new IResource[elements.size()]); 869 elements= new ArrayList (); 870 for (int index= 0; index < elementCount; index++) { 871 final String attribute= JDTRefactoringDescriptor.ATTRIBUTE_ELEMENT + (resourceCount + index + 1); 872 handle= extended.getAttribute(attribute); 873 if (handle != null && !"".equals(handle)) { final IJavaElement element= JDTRefactoringDescriptor.handleToElement(extended.getProject(), handle, false); 875 if (element == null || !element.exists()) 876 status.merge(ScriptableRefactoring.createInputWarningStatus(element, getRefactoring().getName(), IJavaRefactorings.DELETE)); 877 else 878 elements.add(element); 879 } else 880 return RefactoringStatus.createFatalErrorStatus(Messages.format(RefactoringCoreMessages.InitializableRefactoring_argument_not_exist, attribute)); 881 } 882 fJavaElements= (IJavaElement[]) elements.toArray(new IJavaElement[elements.size()]); 883 fElements= new Object [fResources.length + fJavaElements.length]; 884 System.arraycopy(fResources, 0, fElements, 0, fResources.length); 885 System.arraycopy(fJavaElements, 0, fElements, fResources.length, fJavaElements.length); 886 } else 887 return RefactoringStatus.createFatalErrorStatus(RefactoringCoreMessages.InitializableRefactoring_inacceptable_arguments); 888 return status; 889 } 890 } 891 | Popular Tags |