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.
18 * Created by IntelliJ IDEA.
22 * To change template for new class use
23 * Code Style | Class Templates options (Tools | IDE Options).
25 package com
.intellij
.refactoring
.inheritanceToDelegation
;
27 import com
.intellij
.openapi
.actionSystem
.DataContext
;
28 import com
.intellij
.openapi
.actionSystem
.PlatformDataKeys
;
29 import com
.intellij
.openapi
.diagnostic
.Logger
;
30 import com
.intellij
.openapi
.editor
.Editor
;
31 import com
.intellij
.openapi
.editor
.ScrollType
;
32 import com
.intellij
.openapi
.project
.Project
;
33 import com
.intellij
.psi
.*;
34 import com
.intellij
.psi
.impl
.source
.jsp
.jspJava
.JspClass
;
35 import com
.intellij
.refactoring
.HelpID
;
36 import com
.intellij
.refactoring
.RefactoringActionHandler
;
37 import com
.intellij
.refactoring
.RefactoringBundle
;
38 import com
.intellij
.refactoring
.util
.CommonRefactoringUtil
;
39 import com
.intellij
.refactoring
.util
.RefactoringHierarchyUtil
;
40 import com
.intellij
.refactoring
.util
.RefactoringMessageUtil
;
41 import com
.intellij
.refactoring
.util
.classMembers
.MemberInfo
;
42 import com
.intellij
.refactoring
.util
.classMembers
.MemberInfoStorage
;
43 import com
.intellij
.util
.containers
.HashMap
;
44 import org
.jetbrains
.annotations
.NonNls
;
45 import org
.jetbrains
.annotations
.NotNull
;
47 import java
.util
.ArrayList
;
48 import java
.util
.Collection
;
49 import java
.util
.List
;
51 public class InheritanceToDelegationHandler
implements RefactoringActionHandler
{
52 private static final Logger LOG
= Logger
.getInstance("#com.intellij.refactoring.inheritanceToDelegation.InheritanceToDelegationHandler");
53 public static final String REFACTORING_NAME
= RefactoringBundle
.message("replace.inheritance.with.delegation.title");
55 private static final MemberInfo
.Filter
<PsiMember
> MEMBER_INFO_FILTER
= new MemberInfo
.Filter
<PsiMember
>() {
56 public boolean includeMember(PsiMember element
) {
57 if (element
instanceof PsiMethod
) {
58 final PsiMethod method
= (PsiMethod
)element
;
59 return !method
.hasModifierProperty(PsiModifier
.STATIC
)
60 && !method
.hasModifierProperty(PsiModifier
.PRIVATE
);
62 else if (element
instanceof PsiClass
&& ((PsiClass
)element
).isInterface()) {
70 public void invoke(@NotNull Project project
, Editor editor
, PsiFile file
, DataContext dataContext
) {
71 editor
.getScrollingModel().scrollToCaret(ScrollType
.MAKE_VISIBLE
);
72 int offset
= editor
.getCaretModel().getOffset();
73 PsiElement element
= file
.findElementAt(offset
);
75 if (element
== null || element
instanceof PsiFile
) {
76 String message
= RefactoringBundle
.getCannotRefactorMessage(RefactoringBundle
.message("error.wrong.caret.position.class"));
77 CommonRefactoringUtil
.showErrorHint(project
, editor
, message
, REFACTORING_NAME
, HelpID
.INHERITANCE_TO_DELEGATION
);
81 if (element
instanceof PsiClass
&& !(element
instanceof PsiAnonymousClass
)) {
82 invoke(project
, new PsiElement
[]{element
}, dataContext
);
85 element
= element
.getParent();
89 public void invoke(@NotNull Project project
, @NotNull PsiElement
[] elements
, DataContext dataContext
) {
90 if (elements
.length
!= 1) return;
92 final PsiClass aClass
= (PsiClass
)elements
[0];
94 Editor editor
= PlatformDataKeys
.EDITOR
.getData(dataContext
);
95 if (aClass
.isInterface()) {
96 String message
= RefactoringBundle
.getCannotRefactorMessage(RefactoringBundle
.message("class.is.interface", aClass
.getQualifiedName()));
97 CommonRefactoringUtil
.showErrorHint(project
, editor
, message
, REFACTORING_NAME
, HelpID
.INHERITANCE_TO_DELEGATION
);
101 if (aClass
instanceof JspClass
) {
102 RefactoringMessageUtil
.showNotSupportedForJspClassesError(project
, editor
, REFACTORING_NAME
, HelpID
.INHERITANCE_TO_DELEGATION
);
106 if (!CommonRefactoringUtil
.checkReadOnlyStatus(project
, aClass
)) return;
108 final PsiClass
[] bases
= aClass
.getSupers();
109 @NonNls final String javaLangObject
= "java.lang.Object";
110 if (bases
.length
== 0 || bases
.length
== 1 && javaLangObject
.equals(bases
[0].getQualifiedName())) {
111 String message
= RefactoringBundle
.getCannotRefactorMessage(RefactoringBundle
.message("class.does.not.have.base.classes.or.interfaces", aClass
.getQualifiedName()));
112 CommonRefactoringUtil
.showErrorHint(project
, editor
, message
, REFACTORING_NAME
, HelpID
.INHERITANCE_TO_DELEGATION
);
116 final HashMap
<PsiClass
, Collection
<MemberInfo
>> basesToMemberInfos
= new HashMap
<PsiClass
, Collection
<MemberInfo
>>();
118 for (PsiClass base
: bases
) {
119 basesToMemberInfos
.put(base
, createBaseClassMemberInfos(base
));
123 new InheritanceToDelegationDialog(project
, aClass
,
124 bases
, basesToMemberInfos
).show();
127 private static List
<MemberInfo
> createBaseClassMemberInfos(PsiClass baseClass
) {
128 final PsiClass deepestBase
= RefactoringHierarchyUtil
.getDeepestNonObjectBase(baseClass
);
129 LOG
.assertTrue(deepestBase
!= null);
131 final MemberInfoStorage memberInfoStorage
= new MemberInfoStorage(baseClass
, MEMBER_INFO_FILTER
);
133 ArrayList
<MemberInfo
> memberInfoList
= new ArrayList
<MemberInfo
>(memberInfoStorage
.getClassMemberInfos(deepestBase
));
134 List
<MemberInfo
> memberInfos
= memberInfoStorage
.getMemberInfosList(deepestBase
);
135 for (final MemberInfo memberInfo
: memberInfos
) {
136 memberInfoList
.add(memberInfo
);
139 return memberInfoList
;