class members refactoring refactoring
[fedora-idea.git] / refactoring / impl / com / intellij / refactoring / inheritanceToDelegation / InheritanceToDelegationHandler.java
blob302666cd44940ce2ee43aa33a426ac2aaf8d65ab
1 /*
2 * Created by IntelliJ IDEA.
3 * User: dsl
4 * Date: 06.08.2002
5 * Time: 17:17:27
6 * To change template for new class use
7 * Code Style | Class Templates options (Tools | IDE Options).
8 */
9 package com.intellij.refactoring.inheritanceToDelegation;
11 import com.intellij.openapi.actionSystem.DataContext;
12 import com.intellij.openapi.actionSystem.PlatformDataKeys;
13 import com.intellij.openapi.diagnostic.Logger;
14 import com.intellij.openapi.editor.Editor;
15 import com.intellij.openapi.editor.ScrollType;
16 import com.intellij.openapi.project.Project;
17 import com.intellij.psi.*;
18 import com.intellij.psi.impl.source.jsp.jspJava.JspClass;
19 import com.intellij.refactoring.HelpID;
20 import com.intellij.refactoring.RefactoringActionHandler;
21 import com.intellij.refactoring.RefactoringBundle;
22 import com.intellij.refactoring.util.CommonRefactoringUtil;
23 import com.intellij.refactoring.util.RefactoringHierarchyUtil;
24 import com.intellij.refactoring.util.RefactoringMessageUtil;
25 import com.intellij.refactoring.util.classMembers.MemberInfo;
26 import com.intellij.refactoring.util.classMembers.MemberInfoStorage;
27 import com.intellij.util.containers.HashMap;
28 import org.jetbrains.annotations.NonNls;
29 import org.jetbrains.annotations.NotNull;
31 import java.util.ArrayList;
32 import java.util.Collection;
33 import java.util.List;
35 public class InheritanceToDelegationHandler implements RefactoringActionHandler {
36 private static final Logger LOG = Logger.getInstance("#com.intellij.refactoring.inheritanceToDelegation.InheritanceToDelegationHandler");
37 public static final String REFACTORING_NAME = RefactoringBundle.message("replace.inheritance.with.delegation.title");
39 private static final MemberInfo.Filter<PsiMember> MEMBER_INFO_FILTER = new MemberInfo.Filter<PsiMember>() {
40 public boolean includeMember(PsiMember element) {
41 if (element instanceof PsiMethod) {
42 final PsiMethod method = (PsiMethod)element;
43 return !method.hasModifierProperty(PsiModifier.STATIC)
44 && !method.hasModifierProperty(PsiModifier.PRIVATE);
46 else if (element instanceof PsiClass && ((PsiClass)element).isInterface()) {
47 return true;
49 return false;
54 public void invoke(@NotNull Project project, Editor editor, PsiFile file, DataContext dataContext) {
55 editor.getScrollingModel().scrollToCaret(ScrollType.MAKE_VISIBLE);
56 int offset = editor.getCaretModel().getOffset();
57 PsiElement element = file.findElementAt(offset);
58 while (true) {
59 if (element == null || element instanceof PsiFile) {
60 String message = RefactoringBundle.getCannotRefactorMessage(RefactoringBundle.message("error.wrong.caret.position.class"));
61 CommonRefactoringUtil.showErrorHint(project, editor, message, REFACTORING_NAME, HelpID.INHERITANCE_TO_DELEGATION);
62 return;
65 if (element instanceof PsiClass && !(element instanceof PsiAnonymousClass)) {
66 invoke(project, new PsiElement[]{element}, dataContext);
67 return;
69 element = element.getParent();
73 public void invoke(@NotNull Project project, @NotNull PsiElement[] elements, DataContext dataContext) {
74 if (elements.length != 1) return;
76 final PsiClass aClass = (PsiClass)elements[0];
78 Editor editor = PlatformDataKeys.EDITOR.getData(dataContext);
79 if (aClass.isInterface()) {
80 String message = RefactoringBundle.getCannotRefactorMessage(RefactoringBundle.message("class.is.interface", aClass.getQualifiedName()));
81 CommonRefactoringUtil.showErrorHint(project, editor, message, REFACTORING_NAME, HelpID.INHERITANCE_TO_DELEGATION);
82 return;
85 if (aClass instanceof JspClass) {
86 RefactoringMessageUtil.showNotSupportedForJspClassesError(project, editor, REFACTORING_NAME, HelpID.INHERITANCE_TO_DELEGATION);
87 return;
90 if (!CommonRefactoringUtil.checkReadOnlyStatus(project, aClass)) return;
92 final PsiClass[] bases = aClass.getSupers();
93 @NonNls final String javaLangObject = "java.lang.Object";
94 if (bases.length == 0 || bases.length == 1 && javaLangObject.equals(bases[0].getQualifiedName())) {
95 String message = RefactoringBundle.getCannotRefactorMessage(RefactoringBundle.message("class.does.not.have.base.classes.or.interfaces", aClass.getQualifiedName()));
96 CommonRefactoringUtil.showErrorHint(project, editor, message, REFACTORING_NAME, HelpID.INHERITANCE_TO_DELEGATION);
97 return;
100 final HashMap<PsiClass, Collection<MemberInfo>> basesToMemberInfos = new HashMap<PsiClass, Collection<MemberInfo>>();
102 for (PsiClass base : bases) {
103 basesToMemberInfos.put(base, createBaseClassMemberInfos(base));
107 new InheritanceToDelegationDialog(project, aClass,
108 bases, basesToMemberInfos).show();
111 private static List<MemberInfo> createBaseClassMemberInfos(PsiClass baseClass) {
112 final PsiClass deepestBase = RefactoringHierarchyUtil.getDeepestNonObjectBase(baseClass);
113 LOG.assertTrue(deepestBase != null);
115 final MemberInfoStorage memberInfoStorage = new MemberInfoStorage(baseClass, MEMBER_INFO_FILTER);
117 ArrayList<MemberInfo> memberInfoList = new ArrayList<MemberInfo>(memberInfoStorage.getClassMemberInfos(deepestBase));
118 List<MemberInfo> memberInfos = memberInfoStorage.getMemberInfosList(deepestBase);
119 for (final MemberInfo memberInfo : memberInfos) {
120 memberInfoList.add(memberInfo);
123 return memberInfoList;