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
.extractclass
;
18 import com
.intellij
.openapi
.actionSystem
.DataContext
;
19 import com
.intellij
.openapi
.editor
.CaretModel
;
20 import com
.intellij
.openapi
.editor
.Editor
;
21 import com
.intellij
.openapi
.editor
.ScrollType
;
22 import com
.intellij
.openapi
.editor
.ScrollingModel
;
23 import com
.intellij
.openapi
.project
.Project
;
24 import com
.intellij
.psi
.*;
25 import com
.intellij
.psi
.util
.PsiTreeUtil
;
26 import com
.intellij
.refactoring
.HelpID
;
27 import com
.intellij
.refactoring
.RefactorJBundle
;
28 import com
.intellij
.refactoring
.RefactoringActionHandler
;
29 import com
.intellij
.refactoring
.util
.CommonRefactoringUtil
;
30 import org
.jetbrains
.annotations
.NotNull
;
32 public class ExtractClassHandler
implements RefactoringActionHandler
{
34 protected static String
getRefactoringName() {
35 return RefactorJBundle
.message("extract.class");
38 protected static String
getHelpID() {
39 return HelpID
.ExtractClass
;
42 public void invoke(@NotNull Project project
, Editor editor
, PsiFile file
, DataContext dataContext
) {
43 final ScrollingModel scrollingModel
= editor
.getScrollingModel();
44 scrollingModel
.scrollToCaret(ScrollType
.MAKE_VISIBLE
);
45 final CaretModel caretModel
= editor
.getCaretModel();
46 final int position
= caretModel
.getOffset();
47 final PsiElement element
= file
.findElementAt(position
);
49 final PsiMember selectedMember
= PsiTreeUtil
.getParentOfType(element
, PsiMember
.class, true);
50 if (selectedMember
== null) {
55 PsiClass containingClass
= selectedMember
.getContainingClass();
57 if (containingClass
== null && selectedMember
instanceof PsiClass
) {
58 containingClass
= (PsiClass
)selectedMember
;
61 if (containingClass
== null) {
62 CommonRefactoringUtil
.showErrorHint(project
, editor
, RefactorJBundle
.message("cannot.perform.the.refactoring") + RefactorJBundle
.message("the.caret.should.be.positioned.within.a.class.to.be.refactored"),
66 if (containingClass
.isInterface()) {
67 CommonRefactoringUtil
.showErrorHint(project
, editor
, RefactorJBundle
.message("cannot.perform.the.refactoring") + RefactorJBundle
.message("the.selected.class.is.an.interface"), null,
71 if (containingClass
.isEnum()) {
72 CommonRefactoringUtil
.showErrorHint(project
, editor
, RefactorJBundle
.message("cannot.perform.the.refactoring") + RefactorJBundle
.message("the.selected.class.is.an.enumeration"), null,
76 if (containingClass
.isAnnotationType()) {
77 CommonRefactoringUtil
.showErrorHint(project
, editor
, RefactorJBundle
.message("cannot.perform.the.refactoring") + RefactorJBundle
.message("the.selected.class.is.an.annotation.type"), null,
81 if (classIsInner(containingClass
) && !containingClass
.hasModifierProperty(PsiModifier
.STATIC
)) {
82 CommonRefactoringUtil
.showErrorHint(project
, editor
, RefactorJBundle
.message("cannot.perform.the.refactoring") + RefactorJBundle
.message("the.refactoring.is.not.supported.on.non.static.inner.classes"),
86 if (classIsTrivial(containingClass
)) {
87 CommonRefactoringUtil
.showErrorHint(project
, editor
, RefactorJBundle
.message("cannot.perform.the.refactoring") + RefactorJBundle
.message("the.selected.class.has.no.members.to.extract"), null,
91 new ExtractClassDialog(containingClass
, selectedMember
).show();
94 private static boolean classIsInner(PsiClass aClass
) {
95 return PsiTreeUtil
.getParentOfType(aClass
, PsiClass
.class, true) != null;
98 public void invoke(@NotNull Project project
, @NotNull PsiElement
[] elements
, DataContext dataContext
) {
99 if (elements
.length
!= 1) {
102 final PsiClass containingClass
= PsiTreeUtil
.getParentOfType(elements
[0], PsiClass
.class, false);
104 final PsiMember selectedMember
= PsiTreeUtil
.getParentOfType(elements
[0], PsiMember
.class, false);
105 if (containingClass
== null) {
108 if (classIsTrivial(containingClass
)) {
111 new ExtractClassDialog(containingClass
, selectedMember
).show();
114 private static boolean classIsTrivial(PsiClass containingClass
) {
115 if (containingClass
.getFields().length
== 0) {
116 final PsiMethod
[] methods
= containingClass
.getMethods();
117 if (methods
.length
== 0) return true;
118 for (PsiMethod method
: methods
) {
119 if (method
.getBody() != null) return false;