exctract language-independent part from MoveDirectoryWithClassesProcessor
authorKirill.Safonov <kirill.safonov@jetbrains.com>
Thu, 23 Jun 2011 15:06:42 +0000 (19:06 +0400)
committerKirill.Safonov <kirill.safonov@jetbrains.com>
Thu, 23 Jun 2011 15:08:25 +0000 (19:08 +0400)
java/java-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/JavaMoveDirectoryWithClassesHelper.java [new file with mode: 0644]
java/java-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/MoveClassToInnerProcessor.java
java/java-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/MoveClassesOrPackagesProcessor.java
platform/lang-impl/src/com/intellij/refactoring/move/MoveMultipleElementsViewDescriptor.java [moved from java/java-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/MoveClassesOrPackagesViewDescriptor.java with 58% similarity]
platform/lang-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/CommonMoveUtil.java [new file with mode: 0644]
platform/lang-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/MoveDirectoryWithClassesHelper.java [new file with mode: 0644]
platform/lang-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/MoveDirectoryWithClassesProcessor.java [moved from java/java-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/MoveDirectoryWithClassesProcessor.java with 73% similarity]
platform/platform-resources/src/META-INF/LangExtensionPoints.xml
platform/platform-resources/src/META-INF/LangExtensions.xml
plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/move/MoveGroovyScriptProcessor.java
resources/src/META-INF/IdeaPlugin.xml

diff --git a/java/java-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/JavaMoveDirectoryWithClassesHelper.java b/java/java-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/JavaMoveDirectoryWithClassesHelper.java
new file mode 100644 (file)
index 0000000..18d5ab7
--- /dev/null
@@ -0,0 +1,112 @@
+package com.intellij.refactoring.move.moveClassesOrPackages;
+
+import com.intellij.codeInsight.ChangeContextUtil;
+import com.intellij.openapi.project.Project;
+import com.intellij.psi.*;
+import com.intellij.psi.search.searches.ReferencesSearch;
+import com.intellij.psi.util.PsiTreeUtil;
+import com.intellij.refactoring.listeners.RefactoringElementListener;
+import com.intellij.usageView.UsageInfo;
+
+import java.util.*;
+
+public class JavaMoveDirectoryWithClassesHelper extends MoveDirectoryWithClassesHelper {
+
+  @Override
+  public void findUsages(Collection<PsiFile> filesToMove,
+                         PsiDirectory[] directoriesToMove,
+                         Collection<UsageInfo> usages,
+                         boolean searchInComments,
+                         boolean searchInNonJavaFiles,
+                         Project project) {
+    final Set<String> packageNames = new HashSet<String>();
+    for (PsiFile psiFile : filesToMove) {
+      if (psiFile instanceof PsiClassOwner) {
+        final PsiClass[] classes = ((PsiClassOwner)psiFile).getClasses();
+        for (PsiClass aClass : classes) {
+          Collections
+            .addAll(usages, MoveClassesOrPackagesUtil.findUsages(aClass, searchInComments, searchInNonJavaFiles, aClass.getName()));
+        }
+        packageNames.add(((PsiClassOwner)psiFile).getPackageName());
+      }
+    }
+
+    final JavaPsiFacade psiFacade = JavaPsiFacade.getInstance(project);
+    for (String packageName : packageNames) {
+      final PsiPackage aPackage = psiFacade.findPackage(packageName);
+      if (aPackage != null) {
+        boolean remainsNothing = true;
+        for (PsiDirectory packageDirectory : aPackage.getDirectories()) {
+          if (!isUnderRefactoring(packageDirectory, directoriesToMove)) {
+            remainsNothing = false;
+            break;
+          }
+        }
+        if (remainsNothing) {
+          for (PsiReference reference : ReferencesSearch.search(aPackage)) {
+            final PsiElement element = reference.getElement();
+            final PsiImportStatementBase statementBase = PsiTreeUtil.getParentOfType(element, PsiImportStatementBase.class);
+            if (statementBase != null && statementBase.isOnDemand()) {
+              usages.add(new RemoveOnDemandImportStatementsUsageInfo(statementBase));
+            }
+          }
+        }
+      }
+    }
+  }
+
+  private static boolean isUnderRefactoring(PsiDirectory packageDirectory, PsiDirectory[] directoriesToMove) {
+    for (PsiDirectory directory : directoriesToMove) {
+      if (PsiTreeUtil.isAncestor(directory, packageDirectory, true)) {
+        return true;
+      }
+    }
+    return false;
+  }
+
+  @Override
+  public boolean move(PsiFile file,
+                      PsiDirectory moveDestination,
+                      Map<PsiElement, PsiElement> oldToNewElementsMapping,
+                      List<PsiFile> movedFiles,
+                      RefactoringElementListener listener) {
+    if (!(file instanceof PsiClassOwner)) {
+      return false;
+    }
+
+    for (PsiClass psiClass : ((PsiClassOwner)file).getClasses()) {
+      final PsiClass newClass = MoveClassesOrPackagesUtil.doMoveClass(psiClass, moveDestination);
+      oldToNewElementsMapping.put(psiClass, newClass);
+      listener.elementMoved(newClass);
+    }
+    return true;
+  }
+
+  @Override
+  public void postProcessUsages(UsageInfo[] usages) {
+    for (UsageInfo usage : usages) {
+      if (usage instanceof RemoveOnDemandImportStatementsUsageInfo) {
+        final PsiElement element = usage.getElement();
+        if (element != null) {
+          element.delete();
+        }
+      }
+    }
+  }
+
+  @Override
+  public void beforeMove(PsiFile psiFile) {
+    ChangeContextUtil.encodeContextInfo(psiFile, true);
+  }
+
+  @Override
+  public void afterMove(PsiElement newElement) {
+    ChangeContextUtil.decodeContextInfo(newElement, null, null);
+  }
+
+  private static class RemoveOnDemandImportStatementsUsageInfo extends UsageInfo {
+    public RemoveOnDemandImportStatementsUsageInfo(PsiImportStatementBase statementBase) {
+      super(statementBase);
+    }
+  }
+}
index 8097599a0eba20e3ff3b6f25fc9878e6a49bcc79..3a25fb25c19548deef35698dcb024aa77aae0505 100644 (file)
@@ -36,6 +36,7 @@ import com.intellij.refactoring.PackageWrapper;
 import com.intellij.refactoring.RefactoringBundle;
 import com.intellij.refactoring.move.MoveCallback;
 import com.intellij.refactoring.move.MoveClassesOrPackagesCallback;
+import com.intellij.refactoring.move.MoveMultipleElementsViewDescriptor;
 import com.intellij.refactoring.rename.RenameUtil;
 import com.intellij.refactoring.util.*;
 import com.intellij.usageView.UsageInfo;
@@ -93,9 +94,7 @@ public class MoveClassToInnerProcessor extends BaseRefactoringProcessor {
   }
 
   protected UsageViewDescriptor createUsageViewDescriptor(UsageInfo[] usages) {
-    return new MoveClassesOrPackagesViewDescriptor(myClassesToMove,
-                                                   mySearchInComments, mySearchInNonJavaFiles,
-                                                   myTargetClass.getQualifiedName());
+    return new MoveMultipleElementsViewDescriptor(myClassesToMove, myTargetClass.getQualifiedName());
   }
 
   @NotNull
@@ -155,7 +154,7 @@ public class MoveClassToInnerProcessor extends BaseRefactoringProcessor {
         oldToNewElementsMapping.put(classToMove, newClass);
       }
 
-      myNonCodeUsages = MoveClassesOrPackagesProcessor.retargetUsages(usages, oldToNewElementsMapping);
+      myNonCodeUsages = CommonMoveUtil.retargetUsages(usages, oldToNewElementsMapping);
       retargetNonCodeUsages(oldToNewElementsMapping);
 
       retargetClassRefsInMoved(oldToNewElementsMapping);
index a1f370567f5d641737989c53a96b33f3217ec872..cf04a5e6132915e11a0c93d5d76ce2805c7a292a 100644 (file)
@@ -38,6 +38,7 @@ import com.intellij.refactoring.RefactoringBundle;
 import com.intellij.refactoring.listeners.RefactoringElementListener;
 import com.intellij.refactoring.move.MoveCallback;
 import com.intellij.refactoring.move.MoveClassesOrPackagesCallback;
+import com.intellij.refactoring.move.MoveMultipleElementsViewDescriptor;
 import com.intellij.refactoring.rename.RenameUtil;
 import com.intellij.refactoring.util.*;
 import com.intellij.refactoring.util.classRefs.ClassInstanceScanner;
@@ -114,8 +115,7 @@ public class MoveClassesOrPackagesProcessor extends BaseRefactoringProcessor {
   protected UsageViewDescriptor createUsageViewDescriptor(UsageInfo[] usages) {
     PsiElement[] elements = new PsiElement[myElementsToMove.length];
     System.arraycopy(myElementsToMove, 0, elements, 0, myElementsToMove.length);
-    return new MoveClassesOrPackagesViewDescriptor(elements, mySearchInComments, mySearchInNonJavaFiles,
-                                                   MoveClassesOrPackagesUtil.getPackageName(myTargetPackage));
+    return new MoveMultipleElementsViewDescriptor(elements, MoveClassesOrPackagesUtil.getPackageName(myTargetPackage));
   }
 
   public boolean verifyValidPackageName() {
@@ -486,7 +486,7 @@ public class MoveClassesOrPackagesProcessor extends BaseRefactoringProcessor {
         }
       }
 
-      myNonCodeUsages = retargetUsages(usages, oldToNewElementsMapping);
+      myNonCodeUsages = CommonMoveUtil.retargetUsages(usages, oldToNewElementsMapping);
     }
     catch (IncorrectOperationException e) {
       myNonCodeUsages = new NonCodeUsageInfo[0];
@@ -494,30 +494,6 @@ public class MoveClassesOrPackagesProcessor extends BaseRefactoringProcessor {
     }
   }
 
-  public static NonCodeUsageInfo[] retargetUsages(final UsageInfo[] usages, final Map<PsiElement, PsiElement> oldToNewElementsMapping)
-    throws IncorrectOperationException {
-    List<NonCodeUsageInfo> nonCodeUsages = new ArrayList<NonCodeUsageInfo>();
-    for (UsageInfo usage : usages) {
-      if (usage instanceof NonCodeUsageInfo) {
-        nonCodeUsages.add((NonCodeUsageInfo)usage);
-      }
-      else if (usage instanceof MoveRenameUsageInfo) {
-        final MoveRenameUsageInfo moveRenameUsage = (MoveRenameUsageInfo)usage;
-        final PsiElement oldElement = moveRenameUsage.getReferencedElement();
-        final PsiElement newElement = oldToNewElementsMapping.get(oldElement);
-        LOG.assertTrue(newElement != null);
-        final PsiReference reference = moveRenameUsage.getReference();
-        if (reference != null) {
-          try {
-            reference.bindToElement(newElement);
-          } catch (IncorrectOperationException e) {//
-          }
-        }
-      }
-    }
-    return nonCodeUsages.toArray(new NonCodeUsageInfo[nonCodeUsages.size()]);
-  }
-
   protected void performPsiSpoilingRefactoring() {
     RenameUtil.renameNonCodeUsages(myProject, myNonCodeUsages);
     if (myMoveCallback != null) {
similarity index 58%
rename from java/java-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/MoveClassesOrPackagesViewDescriptor.java
rename to platform/lang-impl/src/com/intellij/refactoring/move/MoveMultipleElementsViewDescriptor.java
index cee788604434c8441fba01b87b313ea2ad0ac744..441624c51020d467f177614e7302a5642fe4204d 100644 (file)
  * created at Sep 17, 2001
  * @author Jeka
  */
-package com.intellij.refactoring.move.moveClassesOrPackages;
+package com.intellij.refactoring.move;
 
 import com.intellij.openapi.util.text.StringUtil;
-import com.intellij.psi.PsiClass;
-import com.intellij.psi.PsiDirectory;
 import com.intellij.psi.PsiElement;
 import com.intellij.refactoring.RefactoringBundle;
 import com.intellij.usageView.UsageViewBundle;
@@ -30,36 +28,25 @@ import com.intellij.usageView.UsageViewDescriptor;
 import com.intellij.usageView.UsageViewUtil;
 import org.jetbrains.annotations.NotNull;
 
-class MoveClassesOrPackagesViewDescriptor implements UsageViewDescriptor {
+public class MoveMultipleElementsViewDescriptor implements UsageViewDescriptor {
   private final PsiElement[] myPsiElements;
-  private final boolean mySearchInComments;
-  private final boolean mySearchInNonJavaFiles;
-  private final String myNewParentPackageName;
   private String myProcessedElementsHeader;
   private final String myCodeReferencesText;
 
-  public MoveClassesOrPackagesViewDescriptor(PsiElement[] psiElements,
-                                             boolean isSearchInComments,
-                                             boolean searchInNonJavaFiles,
-                                             String targetName) {
+  public MoveMultipleElementsViewDescriptor(PsiElement[] psiElements,
+                                            String targetName) {
     myPsiElements = psiElements;
-    mySearchInComments = isSearchInComments;
-    mySearchInNonJavaFiles = searchInNonJavaFiles;
-    myNewParentPackageName = targetName;
     if (psiElements.length == 1) {
       myProcessedElementsHeader = StringUtil.capitalize(
-        RefactoringBundle.message("move.single.element.elements.header", UsageViewUtil.getType(psiElements[0]), myNewParentPackageName));
-      myCodeReferencesText = RefactoringBundle.message("references.in.code.to.0.1", UsageViewUtil.getType(psiElements[0]), UsageViewUtil.getLongName(psiElements[0]));
+        RefactoringBundle.message("move.single.element.elements.header", UsageViewUtil.getType(psiElements[0]), targetName));
+      myCodeReferencesText = RefactoringBundle
+        .message("references.in.code.to.0.1", UsageViewUtil.getType(psiElements[0]), UsageViewUtil.getLongName(psiElements[0]));
     }
     else {
       if (psiElements.length > 0) {
-        if (psiElements[0] instanceof PsiClass) {
-          myProcessedElementsHeader = StringUtil.capitalize(RefactoringBundle.message("move.classes.elements.header", myNewParentPackageName));
-        }
-        else if (psiElements[0] instanceof PsiDirectory){
-          myProcessedElementsHeader =
-            StringUtil.capitalize(RefactoringBundle.message("move.packages.elements.header", myNewParentPackageName));
-        }
+        myProcessedElementsHeader = StringUtil.capitalize(
+          RefactoringBundle
+            .message("move.single.element.elements.header", StringUtil.pluralize(UsageViewUtil.getType(psiElements[0])), targetName));
       }
       myCodeReferencesText = RefactoringBundle.message("references.found.in.code");
     }
diff --git a/platform/lang-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/CommonMoveUtil.java b/platform/lang-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/CommonMoveUtil.java
new file mode 100644 (file)
index 0000000..475c16c
--- /dev/null
@@ -0,0 +1,46 @@
+package com.intellij.refactoring.move.moveClassesOrPackages;
+
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.PsiReference;
+import com.intellij.refactoring.util.MoveRenameUsageInfo;
+import com.intellij.refactoring.util.NonCodeUsageInfo;
+import com.intellij.usageView.UsageInfo;
+import com.intellij.util.IncorrectOperationException;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+public class CommonMoveUtil {
+
+  private CommonMoveUtil() {
+  }
+
+  private static final Logger LOG = Logger.getInstance("#com.intellij.refactoring.move.moveClassesOrPackages.CommonMoveUtil");
+
+  public static NonCodeUsageInfo[] retargetUsages(final UsageInfo[] usages, final Map<PsiElement, PsiElement> oldToNewElementsMapping)
+    throws IncorrectOperationException {
+    List<NonCodeUsageInfo> nonCodeUsages = new ArrayList<NonCodeUsageInfo>();
+    for (UsageInfo usage : usages) {
+      if (usage instanceof NonCodeUsageInfo) {
+        nonCodeUsages.add((NonCodeUsageInfo)usage);
+      }
+      else if (usage instanceof MoveRenameUsageInfo) {
+        final MoveRenameUsageInfo moveRenameUsage = (MoveRenameUsageInfo)usage;
+        final PsiElement oldElement = moveRenameUsage.getReferencedElement();
+        final PsiElement newElement = oldToNewElementsMapping.get(oldElement);
+        LOG.assertTrue(newElement != null);
+        final PsiReference reference = moveRenameUsage.getReference();
+        if (reference != null) {
+          try {
+            reference.bindToElement(newElement);
+          }
+          catch (IncorrectOperationException e) {//
+          }
+        }
+      }
+    }
+    return nonCodeUsages.toArray(new NonCodeUsageInfo[nonCodeUsages.size()]);
+  }
+}
diff --git a/platform/lang-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/MoveDirectoryWithClassesHelper.java b/platform/lang-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/MoveDirectoryWithClassesHelper.java
new file mode 100644 (file)
index 0000000..5e488d8
--- /dev/null
@@ -0,0 +1,86 @@
+package com.intellij.refactoring.move.moveClassesOrPackages;
+
+import com.intellij.openapi.extensions.ExtensionPointName;
+import com.intellij.openapi.extensions.Extensions;
+import com.intellij.openapi.project.Project;
+import com.intellij.psi.PsiDirectory;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.PsiFile;
+import com.intellij.refactoring.listeners.RefactoringElementListener;
+import com.intellij.refactoring.move.moveFilesOrDirectories.MoveFileHandler;
+import com.intellij.refactoring.move.moveFilesOrDirectories.MoveFilesOrDirectoriesUtil;
+import com.intellij.usageView.UsageInfo;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @author ksafonov
+ */
+public abstract class MoveDirectoryWithClassesHelper {
+  private static final ExtensionPointName<MoveDirectoryWithClassesHelper> EP_NAME =
+    ExtensionPointName.create("com.intellij.refactoring.moveDirectoryWithClassesHelper");
+
+  public abstract void findUsages(Collection<PsiFile> filesToMove, PsiDirectory[] directoriesToMove, Collection<UsageInfo> result,
+                                  boolean searchInComments, boolean searchInNonJavaFiles, Project project);
+
+  public abstract boolean move(PsiFile file,
+                                  PsiDirectory moveDestination,
+                                  Map<PsiElement, PsiElement> oldToNewElementsMapping,
+                                  List<PsiFile> movedFiles,
+                                  RefactoringElementListener listener);
+
+  public abstract void postProcessUsages(UsageInfo[] usages);
+
+  public abstract void beforeMove(PsiFile psiFile);
+
+  public abstract void afterMove(PsiElement newElement);
+
+  public static MoveDirectoryWithClassesHelper[] findAll() {
+    return Extensions.getExtensions(EP_NAME);
+  }
+
+
+  public static class Default extends MoveDirectoryWithClassesHelper {
+
+    @Override
+    public void findUsages(Collection<PsiFile> filesToMove, PsiDirectory[] directoriesToMove, Collection<UsageInfo> result,
+                           boolean searchInComments, boolean searchInNonJavaFiles, Project project) {
+    }
+
+    @Override
+    public boolean move(PsiFile psiFile,
+                           PsiDirectory moveDestination,
+                           Map<PsiElement, PsiElement> oldToNewElementsMapping,
+                           List<PsiFile> movedFiles,
+                           RefactoringElementListener listener) {
+      if (moveDestination.equals(psiFile.getContainingDirectory())) {
+        return false;
+      }
+
+      MoveFileHandler.forElement(psiFile).prepareMovedFile(psiFile, moveDestination, oldToNewElementsMapping);
+
+      PsiFile moving = moveDestination.findFile(psiFile.getName());
+      if (moving == null) {
+        MoveFilesOrDirectoriesUtil.doMoveFile(psiFile, moveDestination);
+      }
+      moving = moveDestination.findFile(psiFile.getName());
+      movedFiles.add(moving);
+      listener.elementMoved(psiFile);
+      return true;
+    }
+
+    @Override
+    public void postProcessUsages(UsageInfo[] usages) {
+    }
+
+    @Override
+    public void beforeMove(PsiFile psiFile) {
+    }
+
+    @Override
+    public void afterMove(PsiElement newElement) {
+    }
+  }
+}
similarity index 73%
rename from java/java-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/MoveDirectoryWithClassesProcessor.java
rename to platform/lang-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/MoveDirectoryWithClassesProcessor.java
index 36f119eec048b6551b69cada01cf5af8001917e7..a2196e37234bfff2ea330bf99b0b7dd20cb9c3b7 100644 (file)
 package com.intellij.refactoring.move.moveClassesOrPackages;
 
 import com.intellij.CommonBundle;
-import com.intellij.codeInsight.ChangeContextUtil;
 import com.intellij.openapi.project.Project;
 import com.intellij.openapi.ui.Messages;
 import com.intellij.openapi.util.Ref;
 import com.intellij.openapi.vfs.VfsUtil;
-import com.intellij.psi.*;
-import com.intellij.psi.search.searches.ReferencesSearch;
-import com.intellij.psi.util.PsiTreeUtil;
+import com.intellij.psi.PsiDirectory;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.PsiFile;
 import com.intellij.psi.util.PsiUtilBase;
 import com.intellij.refactoring.BaseRefactoringProcessor;
 import com.intellij.refactoring.RefactoringBundle;
 import com.intellij.refactoring.listeners.RefactoringElementListener;
 import com.intellij.refactoring.move.FileReferenceContextUtil;
 import com.intellij.refactoring.move.MoveCallback;
+import com.intellij.refactoring.move.MoveMultipleElementsViewDescriptor;
 import com.intellij.refactoring.move.moveFilesOrDirectories.MoveFileHandler;
-import com.intellij.refactoring.move.moveFilesOrDirectories.MoveFilesOrDirectoriesUtil;
 import com.intellij.refactoring.rename.RenameUtil;
 import com.intellij.refactoring.util.NonCodeUsageInfo;
 import com.intellij.refactoring.util.RefactoringUIUtil;
@@ -69,7 +68,7 @@ public class MoveDirectoryWithClassesProcessor extends BaseRefactoringProcessor
     super(project);
     if (targetDirectory != null) {
       final List<PsiDirectory> dirs = new ArrayList<PsiDirectory>(Arrays.asList(directories));
-      for (Iterator<PsiDirectory> iterator = dirs.iterator(); iterator.hasNext();) {
+      for (Iterator<PsiDirectory> iterator = dirs.iterator(); iterator.hasNext(); ) {
         final PsiDirectory directory = iterator.next();
         if (targetDirectory.equals(directory.getParentDirectory()) || targetDirectory.equals(directory)) {
           iterator.remove();
@@ -88,12 +87,13 @@ public class MoveDirectoryWithClassesProcessor extends BaseRefactoringProcessor
     }
   }
 
+  @NotNull
   @Override
   protected UsageViewDescriptor createUsageViewDescriptor(UsageInfo[] usages) {
     PsiElement[] elements = new PsiElement[myFilesToMove.size()];
     final PsiFile[] classes = PsiUtilBase.toPsiFileArray(myFilesToMove.keySet());
     System.arraycopy(classes, 0, elements, 0, classes.length);
-    return new MoveClassesOrPackagesViewDescriptor(elements, false, false, getTargetName());
+    return new MoveMultipleElementsViewDescriptor(elements, getTargetName());
   }
 
   protected String getTargetName() {
@@ -104,51 +104,12 @@ public class MoveDirectoryWithClassesProcessor extends BaseRefactoringProcessor
   @Override
   public UsageInfo[] findUsages() {
     final List<UsageInfo> usages = new ArrayList<UsageInfo>();
-    final Set<String> packageNames = new HashSet<String>();
-    for (PsiFile psiFile : myFilesToMove.keySet()) {
-      if (psiFile instanceof PsiClassOwner) {
-        final PsiClass[] classes = ((PsiClassOwner)psiFile).getClasses();
-        for (PsiClass aClass : classes) {
-          Collections.addAll(usages, MoveClassesOrPackagesUtil.findUsages(aClass, mySearchInComments, mySearchInNonJavaFiles, aClass.getName()));
-        }
-        packageNames.add(((PsiClassOwner)psiFile).getPackageName());
-      }
-    }
-    final JavaPsiFacade psiFacade = JavaPsiFacade.getInstance(myProject);
-    for (String packageName : packageNames) {
-      final PsiPackage aPackage = psiFacade.findPackage(packageName);
-      if (aPackage != null) {
-        boolean remainsNothing = true;
-        for (PsiDirectory packageDirectory : aPackage.getDirectories()) {
-          if (!isUnderRefactoring(packageDirectory)) {
-            remainsNothing = false;
-            break;
-          }
-        }
-        if (remainsNothing) {
-          for (PsiReference reference : ReferencesSearch.search(aPackage)) {
-            final PsiElement element = reference.getElement();
-            final PsiImportStatementBase statementBase = PsiTreeUtil.getParentOfType(element, PsiImportStatementBase.class);
-            if (statementBase != null && statementBase.isOnDemand()) {
-              usages.add(new RemoveOnDemandImportStatementsUsageInfo(statementBase));
-            }
-          }
-        }
-      }
+    for (MoveDirectoryWithClassesHelper helper : MoveDirectoryWithClassesHelper.findAll()) {
+      helper.findUsages(myFilesToMove.keySet(), myDirectories, usages, mySearchInComments, mySearchInNonJavaFiles, myProject);
     }
     return UsageViewUtil.removeDuplicatedUsages(usages.toArray(new UsageInfo[usages.size()]));
   }
 
-  private boolean isUnderRefactoring(PsiDirectory packageDirectory) {
-    for (PsiDirectory directory : myDirectories) {
-      if (PsiTreeUtil.isAncestor(directory, packageDirectory, true)) {
-        return true;
-      }
-    }
-    return false;
-  }
-
-
   @Override
   protected boolean preprocessUsages(Ref<UsageInfo[]> refUsages) {
     final MultiMap<PsiElement, String> conflicts = new MultiMap<PsiElement, String>();
@@ -189,31 +150,23 @@ public class MoveDirectoryWithClassesProcessor extends BaseRefactoringProcessor
     final List<PsiFile> movedFiles = new ArrayList<PsiFile>();
     final Map<PsiElement, PsiElement> oldToNewElementsMapping = new HashMap<PsiElement, PsiElement>();
     for (PsiFile psiFile : myFilesToMove.keySet()) {
-      ChangeContextUtil.encodeContextInfo(psiFile, true);
+      for (MoveDirectoryWithClassesHelper helper : MoveDirectoryWithClassesHelper.findAll()) {
+        helper.beforeMove(psiFile);
+      }
       final RefactoringElementListener listener = getTransaction().getElementListener(psiFile);
       final PsiDirectory moveDestination = myFilesToMove.get(psiFile).getTargetDirectory();
-      if (psiFile instanceof PsiClassOwner) {
-        for (PsiClass psiClass : ((PsiClassOwner)psiFile).getClasses()) {
-          final PsiClass newClass = MoveClassesOrPackagesUtil.doMoveClass(psiClass, moveDestination);
-          oldToNewElementsMapping.put(psiClass, newClass);
-          listener.elementMoved(newClass);
-        }
-      } else {
-        if (!moveDestination.equals(psiFile.getContainingDirectory())) {
-          MoveFileHandler.forElement(psiFile).prepareMovedFile(psiFile, moveDestination, oldToNewElementsMapping);
 
-          PsiFile moving = moveDestination.findFile(psiFile.getName());
-          if (moving == null) {
-            MoveFilesOrDirectoriesUtil.doMoveFile(psiFile, moveDestination);
-          }
-          moving = moveDestination.findFile(psiFile.getName());
-          movedFiles.add(moving);
-          listener.elementMoved(psiFile);
+      for (MoveDirectoryWithClassesHelper helper : MoveDirectoryWithClassesHelper.findAll()) {
+        boolean processed = helper.move(psiFile, moveDestination, oldToNewElementsMapping, movedFiles, listener);
+        if (processed) {
+          break;
         }
       }
     }
     for (PsiElement newElement : oldToNewElementsMapping.values()) {
-      ChangeContextUtil.decodeContextInfo(newElement, null, null);
+      for (MoveDirectoryWithClassesHelper helper : MoveDirectoryWithClassesHelper.findAll()) {
+        helper.afterMove(newElement);
+      }
     }
 
     // fix references in moved files to outer files
@@ -222,14 +175,9 @@ public class MoveDirectoryWithClassesProcessor extends BaseRefactoringProcessor
       FileReferenceContextUtil.decodeFileReferences(movedFile);
     }
 
-    myNonCodeUsages = MoveClassesOrPackagesProcessor.retargetUsages(usages, oldToNewElementsMapping);
-    for (UsageInfo usage : usages) {
-      if (usage instanceof RemoveOnDemandImportStatementsUsageInfo) {
-        final PsiElement element = usage.getElement();
-        if (element != null) {
-          element.delete();
-        }
-      }
+    myNonCodeUsages = CommonMoveUtil.retargetUsages(usages, oldToNewElementsMapping);
+    for (MoveDirectoryWithClassesHelper helper : MoveDirectoryWithClassesHelper.findAll()) {
+      helper.postProcessUsages(usages);
     }
     for (PsiDirectory directory : myDirectories) {
       directory.delete();
@@ -273,12 +221,6 @@ public class MoveDirectoryWithClassesProcessor extends BaseRefactoringProcessor
     return new TargetDirectoryWrapper(myTargetDirectory);
   }
 
-  private static class RemoveOnDemandImportStatementsUsageInfo extends UsageInfo {
-    public RemoveOnDemandImportStatementsUsageInfo(PsiImportStatementBase statementBase) {
-      super(statementBase);
-    }
-  }
-  
   public static class TargetDirectoryWrapper {
     private TargetDirectoryWrapper myParentDirectory;
     private PsiDirectory myTargetDirectory;
index 649ba91e14dbea7f345298fa5cee91624f9506d1..a5e6af8bae96516e8fefba8add819224e9efd990 100644 (file)
 
   <extensionPoint name="refactoring.copyHandler" interface="com.intellij.refactoring.copy.CopyHandlerDelegate"/>
   <extensionPoint name="refactoring.moveHandler" interface="com.intellij.refactoring.move.MoveHandlerDelegate"/>
+  <extensionPoint name="refactoring.moveDirectoryWithClassesHelper" interface="com.intellij.refactoring.move.moveClassesOrPackages.MoveDirectoryWithClassesHelper"/>
   <extensionPoint name="refactoring.moveClassHandler" interface="com.intellij.refactoring.move.moveClassesOrPackages.MoveClassHandler"/>
   <extensionPoint name="refactoring.moveMemberHandler" beanClass="com.intellij.lang.LanguageExtensionPoint"/>
   <extensionPoint name="refactoring.moveInnerHandler" beanClass="com.intellij.lang.LanguageExtensionPoint"/>
index 483650698b32e0f19742da06a8fc318bbb952381..20ae55754f8adf0d461e68bf1dcf3f6741be4cd5 100644 (file)
   <inspectionsReportConverter implementation="com.intellij.codeInspection.ex.PlainTextFormatter" />
 
   <documentationProvider implementation="com.intellij.openapi.paths.WebReferenceDocumentationProvider"/>
+
+  <refactoring.moveDirectoryWithClassesHelper implementation="com.intellij.refactoring.move.moveClassesOrPackages.MoveDirectoryWithClassesHelper$Default" order="last"/>
 </extensions>
index 219789fc37540864cb10f28f7b691fcec8d8e8ef..5d6318a759bebc570579ecd2c3cb416e4af3e7f3 100644 (file)
@@ -27,6 +27,7 @@ import com.intellij.refactoring.listeners.RefactoringElementListener;
 import com.intellij.refactoring.move.MoveCallback;
 import com.intellij.refactoring.move.moveClassesOrPackages.MoveClassesOrPackagesProcessor;
 import com.intellij.refactoring.move.moveClassesOrPackages.MoveClassesOrPackagesUtil;
+import com.intellij.refactoring.move.moveClassesOrPackages.CommonMoveUtil;
 import com.intellij.refactoring.util.NonCodeUsageInfo;
 import com.intellij.refactoring.util.RefactoringUIUtil;
 import com.intellij.usageView.UsageInfo;
@@ -128,7 +129,7 @@ public class MoveGroovyScriptProcessor extends MoveClassesOrPackagesProcessor {
         GroovyChangeContextUtil.decodeContextInfo(element, null, null);
       }
 
-      myNonCodeUsages = retargetUsages(usages, oldToNewElementsMapping);
+      myNonCodeUsages = CommonMoveUtil.retargetUsages(usages, oldToNewElementsMapping);
     }
     catch (IncorrectOperationException e) {
       myNonCodeUsages = new NonCodeUsageInfo[0];
index 3e1eca7def3caa2fb1a1340706721ba90ffffbdc..72bd8c784440033bb333fa761fa17013aa499b4e 100644 (file)
     <refactoring.moveHandler implementation="com.intellij.refactoring.move.moveInner.MoveInnerToUpperOrMembersHandler"/>
     <refactoring.moveHandler implementation="com.intellij.refactoring.anonymousToInner.MoveAnonymousToInnerHandler"/>
 
+    <refactoring.moveDirectoryWithClassesHelper implementation="com.intellij.refactoring.move.moveClassesOrPackages.JavaMoveDirectoryWithClassesHelper"/>
+
     <moveFileHandler implementation="com.intellij.refactoring.move.moveClassesOrPackages.MoveJavaFileHandler" id="java"/>
 
     <refactoring.moveClassHandler implementation="com.intellij.refactoring.move.moveClassesOrPackages.MoveJavaClassHandler" id="java"/>