blob: 0fb00876978bdac1241323188fdcb5c5e1474745 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2000, 2005 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.jdt.internal.corext.refactoring.reorg;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.OperationCanceledException;
import org.eclipse.core.filebuffers.FileBuffers;
import org.eclipse.core.filebuffers.ITextFileBuffer;
import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IResourceVisitor;
import org.eclipse.ltk.core.refactoring.Change;
import org.eclipse.ltk.core.refactoring.RefactoringStatus;
import org.eclipse.ltk.core.refactoring.participants.CheckConditionsContext;
import org.eclipse.ltk.core.refactoring.participants.DeleteArguments;
import org.eclipse.ltk.core.refactoring.participants.DeleteProcessor;
import org.eclipse.ltk.core.refactoring.participants.ParticipantManager;
import org.eclipse.ltk.core.refactoring.participants.RefactoringParticipant;
import org.eclipse.ltk.core.refactoring.participants.SharableParticipants;
import org.eclipse.ltk.core.refactoring.participants.ValidateEditChecker;
import org.eclipse.jdt.core.ICompilationUnit;
import org.eclipse.jdt.core.IField;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.IMethod;
import org.eclipse.jdt.core.IPackageFragment;
import org.eclipse.jdt.core.IPackageFragmentRoot;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.internal.corext.Assert;
import org.eclipse.jdt.internal.corext.codemanipulation.GetterSetterUtil;
import org.eclipse.jdt.internal.corext.refactoring.RefactoringAvailabilityTester;
import org.eclipse.jdt.internal.corext.refactoring.RefactoringCoreMessages;
import org.eclipse.jdt.internal.corext.refactoring.participants.JavaProcessors;
import org.eclipse.jdt.internal.corext.refactoring.participants.ResourceModifications;
import org.eclipse.jdt.internal.corext.refactoring.participants.ResourceProcessors;
import org.eclipse.jdt.internal.corext.refactoring.util.JavaElementUtil;
import org.eclipse.jdt.internal.corext.refactoring.util.ResourceUtil;
import org.eclipse.jdt.internal.corext.refactoring.util.TextChangeManager;
import org.eclipse.jdt.internal.corext.util.Messages;
import org.eclipse.jdt.internal.corext.util.Resources;
public final class JavaDeleteProcessor extends DeleteProcessor {
private boolean fWasCanceled;
private boolean fSuggestGetterSetterDeletion;
private Object[] fElements;
private IResource[] fResources;
private IJavaElement[] fJavaElements;
private IReorgQueries fDeleteQueries;
private Change fDeleteChange;
public static final String IDENTIFIER= "org.eclipse.jdt.ui.DeleteProcessor"; //$NON-NLS-1$
public JavaDeleteProcessor(Object[] elements) {
fElements= elements;
fResources= RefactoringAvailabilityTester.getResources(elements);
fJavaElements= RefactoringAvailabilityTester.getJavaElements(elements);
fSuggestGetterSetterDeletion= true;
fWasCanceled= false;
}
//---- IRefactoringProcessor ---------------------------------------------------
public String getIdentifier() {
return IDENTIFIER;
}
public boolean isApplicable() throws CoreException {
if (fElements.length == 0)
return false;
if (fElements.length != fResources.length + fJavaElements.length)
return false;
for (int i= 0; i < fResources.length; i++) {
if (!RefactoringAvailabilityTester.isDeleteAvailable(fResources[i]))
return false;
}
for (int i= 0; i < fJavaElements.length; i++) {
if (!RefactoringAvailabilityTester.isDeleteAvailable(fJavaElements[i]))
return false;
}
return true;
}
public boolean needsProgressMonitor() {
if (fResources != null && fResources.length > 0)
return true;
if (fJavaElements != null) {
for (int i= 0; i < fJavaElements.length; i++) {
int type= fJavaElements[i].getElementType();
if (type <= IJavaElement.CLASS_FILE)
return true;
}
}
return false;
}
public String getProcessorName() {
return RefactoringCoreMessages.DeleteRefactoring_7;
}
public Object[] getElements() {
return fElements;
}
public RefactoringParticipant[] loadParticipants(RefactoringStatus status, SharableParticipants shared) throws CoreException {
String[] natures= getAffectedProjectNatures();
ResourceModifications mod= new ResourceModifications();
List collected= new ArrayList();
for (int i= 0; i < fJavaElements.length; i++) {
handleJavaElementDelete(collected, fJavaElements[i], natures, mod, shared);
}
for (int i= 0; i < fResources.length; i++) {
handleResourceDelete(collected, fResources[i], natures, shared);
}
List result= new ArrayList();
for (Iterator iter= collected.iterator(); iter.hasNext();) {
result.addAll(Arrays.asList(ParticipantManager.loadDeleteParticipants(status,
this, iter.next(),
new DeleteArguments(), natures, shared)));
}
result.addAll(Arrays.asList(mod.getParticipants(status, this, natures, shared)));
return (RefactoringParticipant[]) result.toArray(new RefactoringParticipant[result.size()]);
}
private void handleJavaElementDelete(List collected, IJavaElement element, String[] natures, ResourceModifications mod, SharableParticipants shared) throws CoreException {
switch(element.getElementType()) {
case IJavaElement.JAVA_MODEL:
return;
case IJavaElement.JAVA_PROJECT:
collected.add(element);
if (element.getResource() != null)
mod.addDelete(element.getResource());
return;
case IJavaElement.PACKAGE_FRAGMENT_ROOT:
collected.add(element);
IPackageFragmentRoot root= (IPackageFragmentRoot)element;
if (!root.isArchive() && element.getResource() != null)
mod.addDelete(element.getResource());
return;
case IJavaElement.PACKAGE_FRAGMENT:
handlePackageFragmentDelete(collected, (IPackageFragment)element, natures, mod, shared);
return;
case IJavaElement.COMPILATION_UNIT:
collected.add(element);
IType[] types= ((ICompilationUnit)element).getTypes();
collected.addAll(Arrays.asList(types));
if (element.getResource() != null)
mod.addDelete(element.getResource());
return;
case IJavaElement.TYPE:
collected.add(element);
IType type= (IType)element;
ICompilationUnit unit= type.getCompilationUnit();
if (type.getDeclaringType() == null && unit.getElementName().endsWith(type.getElementName())) {
if (unit.getTypes().length == 1) {
collected.add(unit);
if (unit.getResource() != null)
mod.addDelete(unit.getResource());
}
}
return;
default:
collected.add(element);
}
}
private void handlePackageFragmentDelete(List collected, IPackageFragment pack, String[] natures, ResourceModifications mod, SharableParticipants shared) throws CoreException {
collected.add(pack);
IContainer container= (IContainer)pack.getResource();
if (container == null)
return;
IResource[] members= container.members();
int files= 0;
for (int m= 0; m < members.length; m++) {
IResource member= members[m];
if (member instanceof IFile) {
files++;
IFile file= (IFile)member;
if ("class".equals(file.getFileExtension()) && file.isDerived()) //$NON-NLS-1$
continue;
mod.addDelete(member);
}
}
if (files == members.length) {
mod.addDelete(container);
}
}
private void handleResourceDelete(List collected, IResource element, String[] natures, SharableParticipants shared) {
collected.add(element);
}
private String[] getAffectedProjectNatures() throws CoreException {
String[] jNatures= JavaProcessors.computeAffectedNaturs(fJavaElements);
String[] rNatures= ResourceProcessors.computeAffectedNatures(fResources);
Set result= new HashSet();
result.addAll(Arrays.asList(jNatures));
result.addAll(Arrays.asList(rNatures));
return (String[])result.toArray(new String[result.size()]);
}
/*
* This has to be customizable because when drag and drop is performed on a field,
* you don't want to suggest deleting getter/setter if only the field was moved.
*/
public void setSuggestGetterSetterDeletion(boolean suggest){
fSuggestGetterSetterDeletion= suggest;
}
public void setQueries(IReorgQueries queries){
Assert.isNotNull(queries);
fDeleteQueries= queries;
}
public IJavaElement[] getJavaElementsToDelete(){
return fJavaElements;
}
public boolean wasCanceled() {
return fWasCanceled;
}
public IResource[] getResourcesToDelete(){
return fResources;
}
/* (non-Javadoc)
* @see org.eclipse.jdt.internal.corext.refactoring.base.Refactoring#checkActivation(org.eclipse.core.runtime.IProgressMonitor)
*/
public RefactoringStatus checkInitialConditions(IProgressMonitor pm) throws CoreException {
Assert.isNotNull(fDeleteQueries);//must be set before checking activation
RefactoringStatus result= new RefactoringStatus();
result.merge(RefactoringStatus.create(Resources.checkInSync(ReorgUtils.getNotLinked(fResources))));
IResource[] javaResources= ReorgUtils.getResources(fJavaElements);
result.merge(RefactoringStatus.create(Resources.checkInSync(ReorgUtils.getNotNulls(javaResources))));
for (int i= 0; i < fJavaElements.length; i++) {
IJavaElement element= fJavaElements[i];
if (element instanceof IType && ((IType)element).isAnonymous()) {
// work around for bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=44450
// result.addFatalError("Currently, there isn't any support to delete an anonymous type.");
}
}
return result;
}
/* (non-Javadoc)
* @see org.eclipse.jdt.internal.corext.refactoring.base.Refactoring#checkInput(org.eclipse.core.runtime.IProgressMonitor)
*/
public RefactoringStatus checkFinalConditions(IProgressMonitor pm, CheckConditionsContext context) throws CoreException {
pm.beginTask(RefactoringCoreMessages.DeleteRefactoring_1, 1);
try{
fWasCanceled= false;
RefactoringStatus result= new RefactoringStatus();
recalculateElementsToDelete();
TextChangeManager manager= new TextChangeManager();
fDeleteChange= DeleteChangeCreator.createDeleteChange(manager, fResources, fJavaElements, getProcessorName());
checkDirtyCompilationUnits(result);
checkDirtyResources(result);
ValidateEditChecker checker= (ValidateEditChecker)context.getChecker(ValidateEditChecker.class);
IFile[] classPathFiles= getClassPathFiles();
checker.addFiles(ResourceUtil.getFiles(manager.getAllCompilationUnits()));
checker.addFiles(classPathFiles);
return result;
} catch (OperationCanceledException e) {
fWasCanceled= true;
throw e;
} catch (JavaModelException e){
throw e;
} catch (CoreException e) {
throw new JavaModelException(e);
} finally{
pm.done();
}
}
private void checkDirtyCompilationUnits(RefactoringStatus result) throws CoreException {
if (fJavaElements == null || fJavaElements.length == 0)
return;
for (int je= 0; je < fJavaElements.length; je++) {
IJavaElement element= fJavaElements[je];
if (element instanceof ICompilationUnit) {
checkDirtyCompilationUnit(result, (ICompilationUnit)element);
} else if (element instanceof IPackageFragment) {
ICompilationUnit[] units= ((IPackageFragment)element).getCompilationUnits();
for (int u = 0; u < units.length; u++) {
checkDirtyCompilationUnit(result, units[u]);
}
}
}
}
private void checkDirtyCompilationUnit(RefactoringStatus result, ICompilationUnit cunit) {
IResource resource= cunit.getResource();
if (resource == null || resource.getType() != IResource.FILE)
return;
checkDirtyFile(result, (IFile)resource);
}
private void checkDirtyResources(final RefactoringStatus result) throws CoreException {
for (int i= 0; i < fResources.length; i++) {
IResource resource= fResources[i];
resource.accept(new IResourceVisitor() {
public boolean visit(IResource visitedResource) throws CoreException {
if (visitedResource instanceof IFile) {
checkDirtyFile(result, (IFile)visitedResource);
}
return true;
}
}, IResource.DEPTH_INFINITE, false);
}
}
private void checkDirtyFile(RefactoringStatus result, IFile file) {
if (file == null || !file.exists())
return;
ITextFileBuffer buffer= FileBuffers.getTextFileBufferManager().getTextFileBuffer(file.getFullPath());
if (buffer != null && buffer.isDirty()) {
if (buffer.isStateValidated() && buffer.isSynchronized()) {
result.addWarning(Messages.format(
RefactoringCoreMessages.JavaDeleteProcessor_unsaved_changes, //$NON-NLS-1$
file.getFullPath().toString()));
} else {
result.addFatalError(Messages.format(
RefactoringCoreMessages.JavaDeleteProcessor_unsaved_changes, //$NON-NLS-1$
file.getFullPath().toString()));
}
}
}
/*
* The set of elements that will eventually be deleted may be very different from the set
* originally selected - there may be fewer, more or different elements.
* This method is used to calculate the set of elements that will be deleted - if necessary,
* it asks the user.
*/
private void recalculateElementsToDelete() throws CoreException {
//the sequence is critical here
removeElementsWithParentsInSelection(); /*ask before adding empty cus - you don't want to ask if you, for example delete
*the package, in which the cus live*/
removeUnconfirmedFoldersThatContainSourceFolders(); /* a selected folder may be a parent of a source folder
* we must inform the user about it and ask if ok to delete the folder*/
removeUnconfirmedReferencedArchives();
addEmptyCusToDelete();
removeJavaElementsChildrenOfJavaElements();/*because adding cus may create elements (types in cus)
*whose parents are in selection*/
confirmDeletingReadOnly(); /*after empty cus - you want to ask for all cus that are to be deleted*/
if (fSuggestGetterSetterDeletion)
addGettersSetters();/*at the end - this cannot invalidate anything*/
}
//ask for confirmation of deletion of all package fragment roots that are on classpaths of other projects
private void removeUnconfirmedReferencedArchives() throws JavaModelException {
String queryTitle= RefactoringCoreMessages.DeleteRefactoring_2;
IConfirmQuery query= fDeleteQueries.createYesYesToAllNoNoToAllQuery(queryTitle, true, IReorgQueries.CONFIRM_DELETE_REFERENCED_ARCHIVES);
removeUnconfirmedReferencedPackageFragmentRoots(query);
removeUnconfirmedReferencedArchiveFiles(query);
}
private void removeUnconfirmedReferencedArchiveFiles(IConfirmQuery query) throws JavaModelException, OperationCanceledException {
List filesToSkip= new ArrayList(0);
for (int i= 0; i < fResources.length; i++) {
IResource resource= fResources[i];
if (! (resource instanceof IFile))
continue;
IJavaProject project= JavaCore.create(resource.getProject());
if (project == null || ! project.exists())
continue;
IPackageFragmentRoot root= project.findPackageFragmentRoot(resource.getFullPath());
if (root == null)
continue;
List referencingProjects= new ArrayList(1);
referencingProjects.add(root.getJavaProject());
referencingProjects.addAll(Arrays.asList(JavaElementUtil.getReferencingProjects(root)));
if (skipDeletingReferencedRoot(query, root, referencingProjects))
filesToSkip.add(resource);
}
removeFromSetToDelete((IFile[]) filesToSkip.toArray(new IFile[filesToSkip.size()]));
}
private void removeUnconfirmedReferencedPackageFragmentRoots(IConfirmQuery query) throws JavaModelException, OperationCanceledException {
List rootsToSkip= new ArrayList(0);
for (int i= 0; i < fJavaElements.length; i++) {
IJavaElement element= fJavaElements[i];
if (! (element instanceof IPackageFragmentRoot))
continue;
IPackageFragmentRoot root= (IPackageFragmentRoot)element;
List referencingProjects= Arrays.asList(JavaElementUtil.getReferencingProjects(root));
if (skipDeletingReferencedRoot(query, root, referencingProjects))
rootsToSkip.add(root);
}
removeFromSetToDelete((IJavaElement[]) rootsToSkip.toArray(new IJavaElement[rootsToSkip.size()]));
}
private static boolean skipDeletingReferencedRoot(IConfirmQuery query, IPackageFragmentRoot root, List referencingProjects) throws OperationCanceledException {
if (referencingProjects.isEmpty() || root == null || ! root.exists() ||! root.isArchive())
return false;
String question= Messages.format(RefactoringCoreMessages.DeleteRefactoring_3, root.getElementName());
return ! query.confirm(question, referencingProjects.toArray());
}
private void removeUnconfirmedFoldersThatContainSourceFolders() throws CoreException {
String queryTitle= RefactoringCoreMessages.DeleteRefactoring_4;
IConfirmQuery query= fDeleteQueries.createYesYesToAllNoNoToAllQuery(queryTitle, true, IReorgQueries.CONFIRM_DELETE_FOLDERS_CONTAINING_SOURCE_FOLDERS);
List foldersToSkip= new ArrayList(0);
for (int i= 0; i < fResources.length; i++) {
IResource resource= fResources[i];
if (resource instanceof IFolder){
IFolder folder= (IFolder)resource;
if (containsSourceFolder(folder)){
String question= Messages.format(RefactoringCoreMessages.DeleteRefactoring_5, folder.getName());
if (! query.confirm(question))
foldersToSkip.add(folder);
}
}
}
removeFromSetToDelete((IResource[]) foldersToSkip.toArray(new IResource[foldersToSkip.size()]));
}
private static boolean containsSourceFolder(IFolder folder) throws CoreException {
IResource[] subFolders= folder.members();
for (int i = 0; i < subFolders.length; i++) {
if (! (subFolders[i] instanceof IFolder))
continue;
IJavaElement element= JavaCore.create(folder);
if (element instanceof IPackageFragmentRoot)
return true;
if (element instanceof IPackageFragment)
continue;
if (containsSourceFolder((IFolder)subFolders[i]))
return true;
}
return false;
}
private void removeElementsWithParentsInSelection() {
ParentChecker parentUtil= new ParentChecker(fResources, fJavaElements);
parentUtil.removeElementsWithAncestorsOnList(false);
fJavaElements= parentUtil.getJavaElements();
fResources= parentUtil.getResources();
}
private void removeJavaElementsChildrenOfJavaElements(){
ParentChecker parentUtil= new ParentChecker(fResources, fJavaElements);
parentUtil.removeElementsWithAncestorsOnList(true);
fJavaElements= parentUtil.getJavaElements();
}
private IFile[] getClassPathFiles() {
List result= new ArrayList();
for (int i= 0; i < fJavaElements.length; i++) {
IJavaElement element= fJavaElements[i];
if (element instanceof IPackageFragmentRoot) {
IProject project= element.getJavaProject().getProject();
IFile classPathFile= project.getFile(".classpath"); //$NON-NLS-1$
if (classPathFile.exists())
result.add(classPathFile);
}
}
return (IFile[])result.toArray(new IFile[result.size()]);
}
public Change createChange(IProgressMonitor pm) throws CoreException {
pm.beginTask("", 1); //$NON-NLS-1$
pm.done();
return fDeleteChange;
}
private void addToSetToDelete(IJavaElement[] newElements){
fJavaElements= ReorgUtils.union(fJavaElements, newElements);
}
private void removeFromSetToDelete(IResource[] resourcesToNotDelete) {
fResources= ReorgUtils.setMinus(fResources, resourcesToNotDelete);
}
private void removeFromSetToDelete(IJavaElement[] elementsToNotDelete) {
fJavaElements= ReorgUtils.setMinus(fJavaElements, elementsToNotDelete);
}
//--- getter setter related methods
private void addGettersSetters() throws JavaModelException {
IField[] fields= getFields(fJavaElements);
if (fields.length == 0)
return;
//IField -> IMethod[]
Map getterSetterMapping= createGetterSetterMapping(fields);
if (getterSetterMapping.isEmpty())
return;
removeAlreadySelectedMethods(getterSetterMapping);
if (getterSetterMapping.isEmpty())
return;
List gettersSettersToAdd= getGettersSettersToDelete(getterSetterMapping);
addToSetToDelete((IMethod[]) gettersSettersToAdd.toArray(new IMethod[gettersSettersToAdd.size()]));
}
private List getGettersSettersToDelete(Map getterSetterMapping) {
List gettersSettersToAdd= new ArrayList(getterSetterMapping.size());
String queryTitle= RefactoringCoreMessages.DeleteRefactoring_8;
IConfirmQuery getterSetterQuery= fDeleteQueries.createYesYesToAllNoNoToAllQuery(queryTitle, true, IReorgQueries.CONFIRM_DELETE_GETTER_SETTER);
for (Iterator iter= getterSetterMapping.keySet().iterator(); iter.hasNext();) {
IField field= (IField) iter.next();
Assert.isTrue(hasGetter(getterSetterMapping, field) || hasSetter(getterSetterMapping, field));
String deleteGetterSetter= Messages.format(RefactoringCoreMessages.DeleteRefactoring_9, JavaElementUtil.createFieldSignature(field));
if (getterSetterQuery.confirm(deleteGetterSetter)){
if (hasGetter(getterSetterMapping, field))
gettersSettersToAdd.add(getGetter(getterSetterMapping, field));
if (hasSetter(getterSetterMapping, field))
gettersSettersToAdd.add(getSetter(getterSetterMapping, field));
}
}
return gettersSettersToAdd;
}
//note: modifies the mapping
private void removeAlreadySelectedMethods(Map getterSetterMapping) {
List elementsToDelete= Arrays.asList(fJavaElements);
for (Iterator iter= getterSetterMapping.keySet().iterator(); iter.hasNext();) {
IField field= (IField) iter.next();
//remove getter
IMethod getter= getGetter(getterSetterMapping, field);
if (getter != null && elementsToDelete.contains(getter))
removeGetterFromMapping(getterSetterMapping, field);
//remove setter
IMethod setter= getSetter(getterSetterMapping, field);
if (setter != null && elementsToDelete.contains(setter))
removeSetterFromMapping(getterSetterMapping, field);
//both getter and setter already included
if (! hasGetter(getterSetterMapping, field) && ! hasSetter(getterSetterMapping, field))
iter.remove();
}
}
/*
* IField -> IMethod[] (array of 2 - [getter, setter], one of which can be null)
*/
private static Map createGetterSetterMapping(IField[] fields) throws JavaModelException {
Map result= new HashMap();
for (int i= 0; i < fields.length; i++) {
IField field= fields[i];
IMethod[] getterSetter= getGetterSetter(field);
if (getterSetter != null)
result.put(field, getterSetter);
}
return result;
}
private static boolean hasSetter(Map getterSetterMapping, IField field){
return getterSetterMapping.containsKey(field) &&
getSetter(getterSetterMapping, field) != null;
}
private static boolean hasGetter(Map getterSetterMapping, IField field){
return getterSetterMapping.containsKey(field) &&
getGetter(getterSetterMapping, field) != null;
}
private static void removeGetterFromMapping(Map getterSetterMapping, IField field){
((IMethod[])getterSetterMapping.get(field))[0]= null;
}
private static void removeSetterFromMapping(Map getterSetterMapping, IField field){
((IMethod[])getterSetterMapping.get(field))[1]= null;
}
private static IMethod getGetter(Map getterSetterMapping, IField field){
return ((IMethod[])getterSetterMapping.get(field))[0];
}
private static IMethod getSetter(Map getterSetterMapping, IField field){
return ((IMethod[])getterSetterMapping.get(field))[1];
}
private static IField[] getFields(IJavaElement[] elements){
List fields= new ArrayList(3);
for (int i= 0; i < elements.length; i++) {
if (elements[i] instanceof IField)
fields.add(elements[i]);
}
return (IField[]) fields.toArray(new IField[fields.size()]);
}
/*
* returns an array of 2 [getter, setter] or null if no getter or setter exists
*/
private static IMethod[] getGetterSetter(IField field) throws JavaModelException {
IMethod getter= GetterSetterUtil.getGetter(field);
IMethod setter= GetterSetterUtil.getSetter(field);
if ((getter != null && getter.exists()) || (setter != null && setter.exists()))
return new IMethod[]{getter, setter};
else
return null;
}
//----------- read-only confirmation business ------
private void confirmDeletingReadOnly() throws CoreException {
if (! ReadOnlyResourceFinder.confirmDeleteOfReadOnlyElements(fJavaElements, fResources, fDeleteQueries))
throw new OperationCanceledException(); //saying 'no' to this one is like cancelling the whole operation
}
//----------- empty CUs related method
private void addEmptyCusToDelete() throws JavaModelException {
Set cusToEmpty= getCusToEmpty();
addToSetToDelete((ICompilationUnit[]) cusToEmpty.toArray(new ICompilationUnit[cusToEmpty.size()]));
}
private Set getCusToEmpty() throws JavaModelException {
Set result= new HashSet();
for (int i= 0; i < fJavaElements.length; i++) {
IJavaElement element= fJavaElements[i];
ICompilationUnit cu= ReorgUtils.getCompilationUnit(element);
if (cu != null && ! result.contains(cu) && willHaveAllTopLevelTypesDeleted(cu))
result.add(cu);
}
return result;
}
private boolean willHaveAllTopLevelTypesDeleted(ICompilationUnit cu) throws JavaModelException {
Set elementSet= new HashSet(Arrays.asList(fJavaElements));
IType[] topLevelTypes= cu.getTypes();
for (int i= 0; i < topLevelTypes.length; i++) {
if (! elementSet.contains(topLevelTypes[i]))
return false;
}
return true;
}
}