update copyright
[fedora-idea.git] / java / java-impl / src / com / intellij / codeInsight / daemon / impl / quickfix / ExtendsListFix.java
blob29e314911328af3b8b971ed7e16b64771176af03
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.codeInsight.daemon.impl.quickfix;
18 import com.intellij.codeInsight.CodeInsightUtilBase;
19 import com.intellij.codeInsight.daemon.QuickFixBundle;
20 import com.intellij.codeInsight.intention.IntentionAction;
21 import com.intellij.codeInspection.LocalQuickFix;
22 import com.intellij.codeInspection.ProblemDescriptor;
23 import com.intellij.openapi.command.undo.UndoUtil;
24 import com.intellij.openapi.diagnostic.Logger;
25 import com.intellij.openapi.editor.Editor;
26 import com.intellij.openapi.project.Project;
27 import com.intellij.psi.*;
28 import com.intellij.util.IncorrectOperationException;
29 import org.jetbrains.annotations.NonNls;
30 import org.jetbrains.annotations.NotNull;
32 public class ExtendsListFix implements IntentionAction, LocalQuickFix {
33 private static final Logger LOG = Logger.getInstance("#com.intellij.codeInsight.daemon.impl.quickfix.ExtendsListFix");
35 final PsiClass myClass;
36 final PsiClass myClassToExtendFrom;
37 private final boolean myToAdd;
38 private final PsiClassType myTypeToExtendFrom;
40 public ExtendsListFix(PsiClass aClass, PsiClassType typeToExtendFrom, boolean toAdd) {
41 myClass = aClass;
42 myClassToExtendFrom = typeToExtendFrom.resolve();
43 myTypeToExtendFrom = typeToExtendFrom;
44 myToAdd = toAdd;
47 public ExtendsListFix(PsiClass aClass, PsiClass classToExtendFrom, boolean toAdd) {
48 myClass = aClass;
49 myClassToExtendFrom = classToExtendFrom;
50 myTypeToExtendFrom = JavaPsiFacade.getInstance(aClass.getProject()).getElementFactory().createType(classToExtendFrom);
51 myToAdd = toAdd;
54 @NotNull
55 public String getText() {
56 @NonNls final String messageKey;
57 if (myClass.isInterface() == myClassToExtendFrom.isInterface()) {
58 messageKey = myToAdd ? "add.class.to.extends.list" : "remove.class.from.extends.list";
60 else {
61 messageKey = myToAdd ? "add.interface.to.implements.list" : "remove.interface.from.implements.list";
64 return QuickFixBundle.message(messageKey, myClass.getName(), myClassToExtendFrom.getQualifiedName());
67 @NotNull
68 public String getName() {
69 return getText();
72 @NotNull
73 public String getFamilyName() {
74 return QuickFixBundle.message("change.extends.list.family");
77 public void applyFix(@NotNull final Project project, @NotNull final ProblemDescriptor descriptor) {
78 invoke(project, null, descriptor.getPsiElement().getContainingFile());
81 public boolean isAvailable(@NotNull Project project, Editor editor, PsiFile file) {
82 return
83 myClass != null
84 && myClass.isValid()
85 && myClass.getManager().isInProject(myClass)
86 && myClassToExtendFrom != null
87 && myClassToExtendFrom.isValid()
88 && !myClassToExtendFrom.hasModifierProperty(PsiModifier.FINAL)
89 && (myClassToExtendFrom.isInterface()
90 || (!myClass.isInterface()
91 && myClass.getExtendsList() != null
92 && myClass.getExtendsList().getReferencedTypes().length == 0 == myToAdd))
97 protected void invokeImpl () {
98 if (!CodeInsightUtilBase.prepareFileForWrite(myClass.getContainingFile())) return;
99 PsiReferenceList extendsList = !(myClass instanceof PsiTypeParameter) &&
100 myClass.isInterface() != myClassToExtendFrom.isInterface() ?
101 myClass.getImplementsList() : myClass.getExtendsList();
102 PsiReferenceList otherList = extendsList == myClass.getImplementsList() ?
103 myClass.getExtendsList() : myClass.getImplementsList();
104 try {
105 if (extendsList != null) {
106 modifyList(extendsList, myToAdd, -1);
108 if (otherList != null) {
109 modifyList(otherList, false, -1);
112 catch (IncorrectOperationException e) {
113 LOG.error(e);
117 public void invoke(@NotNull Project project, Editor editor, PsiFile file) {
118 invokeImpl();
119 UndoUtil.markPsiFileForUndo(file);
123 * @param position to add new class to or -1 if add to the end
125 PsiReferenceList modifyList(@NotNull PsiReferenceList extendsList, boolean add, int position) throws IncorrectOperationException {
126 PsiJavaCodeReferenceElement[] referenceElements = extendsList.getReferenceElements();
127 boolean alreadyExtends = false;
128 for (PsiJavaCodeReferenceElement referenceElement : referenceElements) {
129 if (referenceElement.resolve() == myClassToExtendFrom) {
130 alreadyExtends = true;
131 if (!add) {
132 referenceElement.delete();
136 PsiReferenceList list = extendsList;
137 if (add && !alreadyExtends) {
138 PsiElement anchor;
139 if (position == -1) {
140 anchor = referenceElements.length ==0 ? null : referenceElements[referenceElements.length-1];
142 else if (position == 0) {
143 anchor = null;
145 else {
146 anchor = referenceElements[position - 1];
148 PsiJavaCodeReferenceElement classReferenceElement =
149 JavaPsiFacade.getInstance(myClass.getProject()).getElementFactory().createReferenceElementByType(myTypeToExtendFrom);
150 PsiElement element;
151 if (anchor == null) {
152 if (referenceElements.length == 0) {
153 element = extendsList.add(classReferenceElement);
155 else {
156 element = extendsList.addBefore(classReferenceElement, referenceElements[0]);
159 else {
160 element = extendsList.addAfter(classReferenceElement, anchor);
162 list = (PsiReferenceList) element.getParent();
164 return list;
167 public boolean startInWriteAction() {
168 return true;