Merge commit 'origin/master'
[idea/community.git] / plugins / groovy / src / org / jetbrains / plugins / groovy / refactoring / move / MoveGroovyScriptProcessor.java
1 /*
2  * Copyright 2000-2009 JetBrains s.r.o.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 package org.jetbrains.plugins.groovy.refactoring.move;
18
19 import com.intellij.openapi.project.Project;
20 import com.intellij.openapi.util.Ref;
21 import com.intellij.psi.PsiClass;
22 import com.intellij.psi.PsiElement;
23 import com.intellij.psi.PsiManager;
24 import com.intellij.refactoring.MoveDestination;
25 import com.intellij.refactoring.listeners.RefactoringElementListener;
26 import com.intellij.refactoring.move.MoveCallback;
27 import com.intellij.refactoring.move.moveClassesOrPackages.MoveClassesOrPackagesProcessor;
28 import com.intellij.refactoring.move.moveClassesOrPackages.MoveClassesOrPackagesUtil;
29 import com.intellij.refactoring.util.NonCodeUsageInfo;
30 import com.intellij.refactoring.util.RefactoringUIUtil;
31 import com.intellij.usageView.UsageInfo;
32 import com.intellij.usageView.UsageViewUtil;
33 import com.intellij.util.IncorrectOperationException;
34 import com.intellij.util.containers.HashMap;
35 import com.intellij.util.containers.MultiMap;
36 import org.jetbrains.annotations.NotNull;
37 import org.jetbrains.plugins.groovy.lang.psi.GroovyFile;
38 import org.jetbrains.plugins.groovy.refactoring.GroovyChangeContextUtil;
39
40 import java.util.ArrayList;
41 import java.util.Arrays;
42 import java.util.List;
43 import java.util.Map;
44
45 /**
46  * @author Maxim.Medvedev
47  */
48 public class MoveGroovyScriptProcessor extends MoveClassesOrPackagesProcessor {
49   public MoveGroovyScriptProcessor(Project project,
50                                    PsiElement[] elements,
51                                    MoveDestination moveDestination,
52                                    boolean searchInComments,
53                                    boolean searchInNonJavaFiles,
54                                    MoveCallback moveCallback) {
55     super(project, elements, moveDestination, searchInComments, searchInNonJavaFiles, moveCallback);
56   }
57
58   @NotNull
59   @Override
60   protected UsageInfo[] findUsages() {
61     List<UsageInfo> allUsages = new ArrayList<UsageInfo>();
62     MultiMap<PsiElement, String> conflicts = new MultiMap<PsiElement, String>();
63     final List<PsiElement> elements = getElements();
64     for (PsiElement element : elements) {
65       final GroovyFile groovyFile = (GroovyFile)element;
66
67       final PsiClass[] classes = groovyFile.getClasses();
68       for (PsiClass aClass : classes) {
69         String newName = getTargetPackage().getQualifiedName() + aClass.getName();
70
71         final UsageInfo[] usages = MoveClassesOrPackagesUtil.findUsages(aClass, isSearchInComments(), isSearchInNonJavaFiles(), newName);
72         allUsages.addAll(new ArrayList<UsageInfo>(Arrays.asList(usages)));
73       }
74     }
75     myMoveDestination
76       .analyzeModuleConflicts(elements, conflicts, allUsages.toArray(new UsageInfo[allUsages.size()]));
77     if (!conflicts.isEmpty()) {
78       for (PsiElement element : conflicts.keySet()) {
79         allUsages.add(new ConflictsUsageInfo(element, conflicts.get(element)));
80       }
81     }
82
83     return UsageViewUtil.removeDuplicatedUsages(allUsages.toArray(new UsageInfo[allUsages.size()]));
84   }
85
86   @Override
87   protected boolean preprocessUsages(Ref<UsageInfo[]> refUsages) {
88     return showConflicts(new MultiMap<PsiElement, String>(), refUsages.get());
89   }
90
91   @Override
92   protected void performRefactoring(UsageInfo[] usages) {
93     try {
94       Map<PsiElement, PsiElement> oldToNewElementsMapping = new HashMap<PsiElement, PsiElement>();
95       final List<PsiElement> elements = getElements();
96       for (PsiElement element : elements) {
97         GroovyFile file = (GroovyFile)element;
98         final RefactoringElementListener elementListener = getTransaction().getElementListener(file);
99
100         final PsiClass[] oldClasses = file.getClasses();
101         GroovyChangeContextUtil.encodeContextInfo(file);
102         PsiManager.getInstance(myProject).moveFile(file, myMoveDestination.getTargetDirectory(file));
103         file.setPackageName(getTargetPackage().getQualifiedName());
104
105         PsiClass[] newClasses = file.getClasses();
106         for (int i = 0; i < oldClasses.length; i++) {
107           oldToNewElementsMapping.put(oldClasses[i], newClasses[i]);
108         }
109
110         elementListener.elementMoved(file);
111       }
112
113       for (PsiElement element : elements) {
114         GroovyChangeContextUtil.decodeContextInfo(element, null, null);
115       }
116
117       myNonCodeUsages = retargetUsages(usages, oldToNewElementsMapping);
118     }
119     catch (IncorrectOperationException e) {
120       myNonCodeUsages = new NonCodeUsageInfo[0];
121       RefactoringUIUtil.processIncorrectOperation(myProject, e);
122     }
123   }
124 }