| /* |
| * Copyright 2005 Sascha Weinreuter |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| package org.intellij.lang.xpath.xslt.refactoring; |
| |
| import com.intellij.codeInsight.highlighting.HighlightManager; |
| import com.intellij.injected.editor.EditorWindow; |
| import com.intellij.openapi.command.WriteCommandAction; |
| import com.intellij.openapi.editor.Editor; |
| import com.intellij.openapi.editor.SelectionModel; |
| import com.intellij.openapi.editor.colors.EditorColors; |
| import com.intellij.openapi.editor.markup.RangeHighlighter; |
| import com.intellij.openapi.util.TextRange; |
| import com.intellij.psi.PsiElement; |
| import com.intellij.psi.PsiFile; |
| import com.intellij.psi.util.PsiTreeUtil; |
| import com.intellij.psi.xml.XmlAttribute; |
| import com.intellij.psi.xml.XmlTag; |
| |
| import org.intellij.lang.xpath.XPathFile; |
| import org.intellij.lang.xpath.psi.XPathExpression; |
| import org.intellij.lang.xpath.xslt.XsltSupport; |
| import org.intellij.lang.xpath.xslt.util.XsltCodeInsightUtil; |
| |
| import java.util.ArrayList; |
| import java.util.List; |
| import java.util.Set; |
| |
| public abstract class BaseIntroduceAction<Settings extends RefactoringOptions> extends XsltRefactoringActionBase { |
| protected abstract String getCommandName(); |
| |
| protected abstract Settings getSettings(XPathExpression expression, Set<XPathExpression> matchingExpressions); |
| |
| protected abstract boolean extractImpl(XPathExpression expression, Set<XPathExpression> matchingExpressions, List<XmlTag> otherMatches, Settings settings); |
| |
| public String getErrorMessage(Editor editor, PsiFile file, XmlAttribute context) { |
| if (context != null) { |
| if (XsltSupport.isPatternAttribute(context)) { |
| return "Match patterns may not contain variable references."; |
| } |
| if (XsltSupport.isXPathAttribute(context) && editor.getSelectionModel().hasSelection()) { |
| return "Please select a complete XPath expression to extract."; |
| } |
| } |
| return super.getErrorMessage(editor, file, context); |
| } |
| |
| protected boolean actionPerformedImpl(PsiFile file, Editor editor, XmlAttribute context, int offset) { |
| if (!(file instanceof XPathFile)) return false; |
| |
| // pattern attribute may not reference variables |
| if (XsltSupport.isPatternAttribute(context)) return false; |
| |
| final SelectionModel selectionModel = editor.getSelectionModel(); |
| final boolean hasSelection = selectionModel.hasSelection(); |
| final int start = selectionModel.getSelectionStart(); |
| final int end = selectionModel.getSelectionEnd(); |
| |
| if (hasSelection) { |
| final PsiElement xpathElement = file.findElementAt(start); |
| if (xpathElement != null) { |
| XPathExpression expression = PsiTreeUtil.getParentOfType(xpathElement, XPathExpression.class); |
| while (expression != null) { |
| if (expression.getTextRange().getStartOffset() == start) { |
| final int diff = expression.getTextRange().getEndOffset() - end; |
| if (diff == 0) { |
| extractFromExpression(editor, expression); |
| return true; |
| } else if (diff > 0) { |
| break; |
| } |
| } |
| expression = PsiTreeUtil.getParentOfType(expression, XPathExpression.class); |
| } |
| } |
| } else { |
| final XPathExpression expression = PsiTreeUtil.getChildOfType(file, XPathExpression.class); |
| if (expression != null) { |
| final PsiFile containingFile = expression.getContainingFile(); |
| assert containingFile != null; |
| final TextRange range = expression.getTextRange(); |
| editor.getSelectionModel().setSelection(range.getStartOffset(), range.getEndOffset()); |
| extractFromExpression(editor, expression); |
| return true; |
| } |
| } |
| |
| return false; |
| } |
| |
| private void extractFromExpression(Editor e, final XPathExpression expression) { |
| final Editor editor = (e instanceof EditorWindow) ? ((EditorWindow)e).getDelegate() : e; |
| |
| final HighlightManager highlightManager = HighlightManager.getInstance(expression.getProject()); |
| |
| final Set<XPathExpression> matchingExpressions = RefactoringUtil.collectMatchingExpressions(expression); |
| final List<XmlTag> otherMatches = new ArrayList<XmlTag>(matchingExpressions.size()); |
| final ArrayList<RangeHighlighter> highlighters = new ArrayList<RangeHighlighter>(matchingExpressions.size() + 1); |
| if (matchingExpressions.size() > 0) { |
| final SelectionModel selectionModel = editor.getSelectionModel(); |
| highlightManager.addRangeHighlight(editor, selectionModel.getSelectionStart(), selectionModel.getSelectionEnd(), |
| EditorColors.SEARCH_RESULT_ATTRIBUTES.getDefaultAttributes(), false, highlighters); |
| for (XPathExpression expr : matchingExpressions) { |
| final TextRange range = XsltCodeInsightUtil.getRangeInsideHostingFile(expr); |
| highlightManager.addRangeHighlight(editor, range.getStartOffset(), range.getEndOffset(), |
| EditorColors.SEARCH_RESULT_ATTRIBUTES.getDefaultAttributes(), false, highlighters); |
| |
| final XmlTag tag = PsiTreeUtil.getContextOfType(expr, XmlTag.class, true); |
| assert tag != null; |
| otherMatches.add(tag); |
| } |
| } |
| |
| final Settings dlg = getSettings(expression, matchingExpressions); |
| if (dlg == null || dlg.isCanceled()) return; |
| |
| if (getCommandName() != null) { |
| new WriteCommandAction.Simple(e.getProject(), getCommandName()) { |
| protected void run() throws Throwable { |
| if (extractImpl(expression, matchingExpressions, otherMatches, dlg)) { |
| for (RangeHighlighter highlighter : highlighters) { |
| highlighter.dispose(); |
| } |
| } |
| } |
| }.execute(); |
| } else { |
| extractImpl(expression, matchingExpressions, otherMatches, dlg); |
| } |
| } |
| } |