update copyright
[fedora-idea.git] / xml / impl / src / com / intellij / xml / refactoring / XmlTagRenameHandler.java
blobf7a1b7b91504339125b21d70149b6ba4726a3d41
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.
18 * Created by IntelliJ IDEA.
19 * User: spleaner
20 * Date: Aug 7, 2007
21 * Time: 2:44:37 PM
23 package com.intellij.xml.refactoring;
25 import com.intellij.featureStatistics.FeatureUsageTracker;
26 import com.intellij.lang.Language;
27 import com.intellij.openapi.actionSystem.DataContext;
28 import com.intellij.openapi.actionSystem.LangDataKeys;
29 import com.intellij.openapi.actionSystem.PlatformDataKeys;
30 import com.intellij.openapi.diagnostic.Logger;
31 import com.intellij.openapi.editor.Editor;
32 import com.intellij.openapi.project.Project;
33 import com.intellij.patterns.PlatformPatterns;
34 import com.intellij.psi.PsiElement;
35 import com.intellij.psi.PsiFile;
36 import com.intellij.psi.PsiManager;
37 import com.intellij.psi.util.PsiUtilBase;
38 import com.intellij.psi.xml.XmlFile;
39 import com.intellij.psi.xml.XmlTag;
40 import com.intellij.refactoring.actions.BaseRefactoringAction;
41 import com.intellij.refactoring.rename.RenameHandler;
42 import com.intellij.refactoring.rename.PsiElementRenameHandler;
43 import com.intellij.xml.XmlElementDescriptor;
44 import com.intellij.xml.impl.schema.AnyXmlElementDescriptor;
45 import org.jetbrains.annotations.NotNull;
46 import org.jetbrains.annotations.Nullable;
48 public class XmlTagRenameHandler implements RenameHandler {
49 private static final Logger LOG = Logger.getInstance("#com.intellij.xml.refactoring.XmlTagRenameHandler");
52 public boolean isAvailableOnDataContext(final DataContext dataContext) {
53 final PsiElement element = getElement(dataContext);
54 if (PsiElementRenameHandler.isVetoed(element)) return false;
55 //noinspection ConstantConditions
56 return PlatformPatterns.psiElement().withParent(XmlTag.class).accepts(element) &&
57 isDeclarationOutOfProjectOrAbsent(element.getProject(), dataContext);
60 public boolean isRenaming(final DataContext dataContext) {
61 return isAvailableOnDataContext(dataContext);
64 private static boolean isInplaceRenameAvailable(final Editor editor) {
65 return editor.getSettings().isVariableInplaceRenameEnabled();
68 private static boolean isDeclarationOutOfProjectOrAbsent(@NotNull final Project project, final DataContext context) {
69 final PsiElement[] elements = BaseRefactoringAction.getPsiElementArray(context);
70 return elements.length == 0 || elements.length == 1 && shouldBeRenamedInplace(project, elements);
73 private static boolean shouldBeRenamedInplace(Project project, PsiElement[] elements) {
74 boolean inProject = PsiManager.getInstance(project).isInProject(elements[0]);
75 if (inProject && elements[0] instanceof XmlTag) {
76 XmlElementDescriptor descriptor = ((XmlTag)elements[0]).getDescriptor();
77 return descriptor instanceof AnyXmlElementDescriptor;
79 return !inProject;
82 @Nullable
83 private static Editor getEditor(@Nullable DataContext context) {
84 return PlatformDataKeys.EDITOR.getData(context);
87 @Nullable
88 private static PsiElement getElement(@Nullable final DataContext context) {
89 if (context != null) {
90 final Editor editor = getEditor(context);
91 if (editor != null) {
92 final int offset = editor.getCaretModel().getOffset();
93 final PsiFile file = LangDataKeys.PSI_FILE.getData(context);
94 if (file instanceof XmlFile) {
95 return file.getViewProvider().findElementAt(offset);
97 if (file != null) {
98 final Language language = PsiUtilBase.getLanguageAtOffset(file, offset);
99 if (language != file.getLanguage()) {
100 final PsiFile psiAtOffset = file.getViewProvider().getPsi(language);
101 if (psiAtOffset instanceof XmlFile) {
102 return psiAtOffset.findElementAt(offset);
109 return null;
112 private void invoke(@Nullable final Editor editor, @NotNull final PsiElement element, @Nullable final DataContext context) {
113 if (!isRenaming(context)) {
114 return;
117 FeatureUsageTracker.getInstance().triggerFeatureUsed("refactoring.rename");
119 if (isInplaceRenameAvailable(editor)) {
120 XmlTagInplaceRenamer.rename(editor, (XmlTag)element.getParent());
122 else {
123 XmlTagRenameDialog.renameXmlTag(editor, element, (XmlTag)element.getParent());
127 public void invoke(@NotNull final Project project, final Editor editor, final PsiFile file, @Nullable final DataContext dataContext) {
128 if (!isRenaming(dataContext)) {
129 return;
132 final PsiElement element = getElement(dataContext);
133 assert element != null;
135 invoke(editor, element, dataContext);
138 public void invoke(@NotNull final Project project, @NotNull final PsiElement[] elements, @Nullable final DataContext dataContext) {
139 PsiElement element = elements.length == 1 ? elements[0] : null;
140 if (element == null) {
141 element = getElement(dataContext);
144 LOG.assertTrue(element != null);
145 invoke(getEditor(dataContext), element, dataContext);