update copyright
[fedora-idea.git] / java / java-impl / src / com / intellij / refactoring / copy / CopyClassesHandler.java
blobcd16d3e214112f7a921fa93a0ae023ecb9edbf46
1 /*
2 * Copyright 2000-2009 JetBrains s.r.o.
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
16 package com.intellij.refactoring.copy;
18 import com.intellij.codeInsight.actions.OptimizeImportsProcessor;
19 import com.intellij.codeInsight.daemon.impl.CollectHighlightsUtil;
20 import com.intellij.featureStatistics.FeatureUsageTracker;
21 import com.intellij.ide.util.EditorHelper;
22 import com.intellij.openapi.application.ApplicationManager;
23 import com.intellij.openapi.command.CommandProcessor;
24 import com.intellij.openapi.project.Project;
25 import com.intellij.openapi.ui.Messages;
26 import com.intellij.openapi.wm.ToolWindowManager;
27 import com.intellij.psi.*;
28 import com.intellij.psi.search.LocalSearchScope;
29 import com.intellij.psi.search.searches.ReferencesSearch;
30 import com.intellij.refactoring.RefactoringBundle;
31 import com.intellij.util.IncorrectOperationException;
32 import org.jetbrains.annotations.Nullable;
34 public class CopyClassesHandler implements CopyHandlerDelegate {
35 public boolean canCopy(PsiElement[] elements) {
36 return canCopyClass(elements);
39 public static boolean canCopyClass(PsiElement... elements) {
40 return convertToTopLevelClass(elements) != null;
43 @Nullable
44 private static PsiClass convertToTopLevelClass(final PsiElement[] elements) {
45 if (elements.length == 1 && !CollectHighlightsUtil.isOutsideSourceRootJavaFile(elements[0].getContainingFile())) {
46 return getTopLevelClass(elements [0]);
48 return null;
51 public void doCopy(PsiElement[] elements, PsiDirectory defaultTargetDirectory) {
52 FeatureUsageTracker.getInstance().triggerFeatureUsed("refactoring.copyClass");
53 PsiClass aClass = convertToTopLevelClass(elements);
54 assert aClass != null;
55 Project project = aClass.getProject();
56 if (defaultTargetDirectory == null) {
57 defaultTargetDirectory = aClass.getContainingFile().getContainingDirectory();
59 CopyClassDialog dialog = new CopyClassDialog(aClass, defaultTargetDirectory, project, false);
60 dialog.setTitle(RefactoringBundle.message("copy.handler.copy.class"));
61 dialog.show();
62 if (dialog.isOK()) {
63 PsiDirectory targetDirectory = dialog.getTargetDirectory();
64 String className = dialog.getClassName();
65 copyClassImpl(className, project, aClass, targetDirectory, RefactoringBundle.message("copy.handler.copy.class"), false);
69 public void doClone(PsiElement element) {
70 FeatureUsageTracker.getInstance().triggerFeatureUsed("refactoring.copyClass");
71 PsiClass aClass = getTopLevelClass(element);
72 Project project = element.getProject();
74 CopyClassDialog dialog = new CopyClassDialog(aClass, null, project, true);
75 dialog.setTitle(RefactoringBundle.message("copy.handler.clone.class"));
76 dialog.show();
77 if (dialog.isOK()) {
78 String className = dialog.getClassName();
79 PsiDirectory targetDirectory = element.getContainingFile().getContainingDirectory();
80 copyClassImpl(className, project, aClass, targetDirectory, RefactoringBundle.message("copy.handler.clone.class"), true);
84 private static void copyClassImpl(final String copyClassName, final Project project, final PsiClass aClass, final PsiDirectory targetDirectory, String commandName, final boolean selectInActivePanel) {
85 if (copyClassName == null || copyClassName.length() == 0) return;
86 final boolean[] result = new boolean[] {false};
87 Runnable command = new Runnable() {
88 public void run() {
89 final Runnable action = new Runnable() {
90 public void run() {
91 try {
92 PsiElement newElement = doCopyClass(aClass, copyClassName, targetDirectory);
93 CopyHandler.updateSelectionInActiveProjectView(newElement, project, selectInActivePanel);
94 EditorHelper.openInEditor(newElement);
96 result[0] = true;
98 catch (final IncorrectOperationException ex) {
99 ApplicationManager.getApplication().invokeLater(new Runnable() {
100 public void run() {
101 Messages.showMessageDialog(project, ex.getMessage(), RefactoringBundle.message("error.title"), Messages.getErrorIcon());
107 ApplicationManager.getApplication().runWriteAction(action);
110 CommandProcessor processor = CommandProcessor.getInstance();
111 processor.executeCommand(project, command, commandName, null);
113 if (result[0]) {
114 ToolWindowManager.getInstance(project).invokeLater(new Runnable() {
115 public void run() {
116 ToolWindowManager.getInstance(project).activateEditorComponent();
122 public static PsiElement doCopyClass(final PsiClass aClass, final String copyClassName, final PsiDirectory targetDirectory)
123 throws IncorrectOperationException {
124 PsiElement elementToCopy = aClass.getNavigationElement();
126 final PsiClass classCopy = (PsiClass)elementToCopy.copy();
127 classCopy.setName(copyClassName);
129 final String fileName = copyClassName + "." + elementToCopy.getContainingFile().getOriginalFile().getViewProvider().getVirtualFile().getExtension();
130 final PsiFile createdFile = targetDirectory.copyFileFrom(fileName, elementToCopy.getContainingFile());
131 PsiElement newElement = createdFile;
132 if (createdFile instanceof PsiClassOwner) {
133 for (final PsiClass psiClass : ((PsiClassOwner)createdFile).getClasses()) {
134 if (!(psiClass instanceof SyntheticElement)) {
135 createdFile.deleteChildRange(psiClass, psiClass);
139 final PsiClass newClass = (PsiClass)createdFile.add(classCopy);
141 for (final PsiReference reference : ReferencesSearch.search(aClass, new LocalSearchScope(newClass)).findAll()) {
142 reference.bindToElement(newClass);
145 new OptimizeImportsProcessor(aClass.getProject(), createdFile).run();
147 newElement = newClass;
149 return newElement;
152 @Nullable
153 private static PsiClass getTopLevelClass(PsiElement element) {
154 while (true) {
155 if (element == null || element instanceof PsiFile) break;
156 if (element instanceof PsiClass && element.getParent() instanceof PsiFile) break;
157 element = element.getParent();
159 if (element instanceof PsiClassOwner) {
160 PsiClass[] classes = ((PsiClassOwner)element).getClasses();
161 if (classes.length > 0) {
162 for (final PsiClass aClass : classes) {
163 if (aClass instanceof SyntheticElement) {
164 return null;
168 element = classes[0];
171 return element instanceof PsiClass ? (PsiClass)element : null;