package org.mule.tooling.esb.config.refactoring.rename; import com.intellij.codeInsight.completion.TagNameReferenceCompletionProvider; import com.intellij.codeInsight.lookup.LookupElement; import com.intellij.codeInsight.lookup.LookupManager; import com.intellij.lang.findUsages.DescriptiveNameUtil; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.command.CommandProcessor; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.fileTypes.FileTypes; import com.intellij.openapi.help.HelpManager; import com.intellij.openapi.util.text.StringUtil; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiReference; import com.intellij.psi.impl.source.xml.TagNameReference; import com.intellij.psi.xml.XmlTag; import com.intellij.refactoring.RefactoringBundle; import com.intellij.refactoring.ui.NameSuggestionsField; import com.intellij.refactoring.ui.RefactoringDialog; import com.intellij.usageView.UsageViewUtil; import com.intellij.util.IncorrectOperationException; import com.intellij.xml.XmlBundle; import com.intellij.xml.refactoring.XmlTagRenameDialog; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.mule.tooling.esb.config.MuleConfigConstants; import org.mule.tooling.esb.util.MuleConfigUtils; import javax.swing.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.util.List; /** * Created by eberman on 3/7/17. */ public class FlowRenameDialog extends RefactoringDialog { private static final Logger LOG = Logger.getInstance("#com.intellij.xml.refactoring.XmlTagRenameDialog"); private static final String REFACTORING_NAME = RefactoringBundle.message("rename.title"); private final PsiElement myElement; private final Editor myEditor; private JLabel myTitleLabel; private NameSuggestionsField myNameSuggestionsField; private String myHelpID; private final XmlTag myTag; private NameSuggestionsField.DataChanged myNameChangedListener; public FlowRenameDialog(@Nullable Editor editor, @NotNull PsiElement element, @NotNull XmlTag tag) { super(element.getProject(), true); this.myEditor = editor; this.myElement = element; this.myTag = tag; this.setTitle(REFACTORING_NAME); this.createNewNameComponent(); this.init(); this.myTitleLabel.setText("Rename Mule flow '" + tag.getAttributeValue("name") + "' and its usages to:"); this.validateButtons(); } protected void dispose() { this.myNameSuggestionsField.removeDataChangedListener(this.myNameChangedListener); super.dispose(); } protected boolean hasHelpAction() { return false; } private static String getFullName(@NotNull XmlTag tag) { String name = DescriptiveNameUtil.getDescriptiveName(tag.getAttribute("name")); return (UsageViewUtil.getType(tag) + " " + name).trim(); } public static void renameFlowTag(Editor editor, @NotNull PsiElement element, @NotNull XmlTag tag) { FlowRenameDialog dialog = new FlowRenameDialog(editor, element, tag); dialog.show(); } private void createNewNameComponent() { String flowName = this.myTag.getAttribute("name").getValue(); this.myNameSuggestionsField = new NameSuggestionsField(new String[]{ flowName }, this.myProject, FileTypes.PLAIN_TEXT, this.myEditor); this.myNameChangedListener = new NameSuggestionsField.DataChanged() { public void dataChanged() { FlowRenameDialog.this.validateButtons(); } }; this.myNameSuggestionsField.addDataChangedListener(this.myNameChangedListener); this.myNameSuggestionsField.getComponent().registerKeyboardAction(new ActionListener() { public void actionPerformed(ActionEvent e) { FlowRenameDialog.this.completeVariable(FlowRenameDialog.this.myNameSuggestionsField.getEditor()); } }, KeyStroke.getKeyStroke(32, 2), 2); } private void completeVariable(Editor editor) { String prefix = this.myNameSuggestionsField.getEnteredName(); PsiReference reference = this.myTag.getReference(); if(reference instanceof TagNameReference) { LookupElement[] lookupItems = TagNameReferenceCompletionProvider.getTagNameVariants(this.myTag, this.myTag.getNamespacePrefix()); editor.getCaretModel().moveToOffset(prefix.length()); editor.getSelectionModel().removeSelection(); LookupManager.getInstance(this.getProject()).showLookup(editor, lookupItems, prefix); } } protected void doAction() { LOG.assertTrue(this.myElement.isValid()); CommandProcessor.getInstance().executeCommand(this.myProject, () -> { ApplicationManager.getApplication().runWriteAction(() -> { try { final List<XmlTag> refs = MuleConfigUtils.findFlowRefsForFlow(this.myTag); this.myTag.getAttribute(MuleConfigConstants.NAME_ATTRIBUTE).setValue(this.getNewName()); for (XmlTag ref : refs) { ref.getAttribute(MuleConfigConstants.NAME_ATTRIBUTE).setValue(this.getNewName()); } } catch (IncorrectOperationException var2) { LOG.error(var2); } }); }, RefactoringBundle.message("rename.title"), (Object)null); this.close(0); } @Nullable protected JComponent createCenterPanel() { return null; } public JComponent getPreferredFocusedComponent() { return this.myNameSuggestionsField.getFocusableComponent(); } protected JComponent createNorthPanel() { JPanel panel = new JPanel(); panel.setLayout(new BoxLayout(panel, 1)); panel.setBorder(BorderFactory.createEmptyBorder(4, 8, 4, 8)); this.myTitleLabel = new JLabel(); panel.add(this.myTitleLabel); panel.add(Box.createVerticalStrut(8)); panel.add(this.myNameSuggestionsField.getComponent()); return panel; } protected void doHelpAction() { HelpManager.getInstance().invokeHelp(this.myHelpID); } public String getNewName() { return this.myNameSuggestionsField.getEnteredName().trim(); } protected void validateButtons() { super.validateButtons(); this.getPreviewAction().setEnabled(false); } protected boolean areButtonsValid() { String newName = this.getNewName(); return !StringUtil.containsAnyChar(newName, "\t ;*'\"\\/,()^&<>={}"); } }