blob: 363e8322ffc77b6dcfa4d57a560afdd6faa2c642 [file] [log] [blame]
package org.jetbrains.android.refactoring;
import com.intellij.openapi.project.Project;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.psi.xml.XmlFile;
import com.intellij.psi.xml.XmlTag;
import com.intellij.refactoring.RefactoringBundle;
import com.intellij.util.xml.DomElement;
import com.intellij.util.xml.DomFileDescription;
import com.intellij.util.xml.DomManager;
import org.jetbrains.android.dom.converters.AndroidResourceReferenceBase;
import org.jetbrains.android.dom.layout.LayoutDomFileDescription;
import org.jetbrains.android.dom.resources.ResourcesDomFileDescription;
import org.jetbrains.android.dom.resources.Style;
import org.jetbrains.android.util.AndroidBundle;
import org.jetbrains.android.util.AndroidUtils;
import org.jetbrains.android.util.ProjectBasedErrorReporter;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.TestOnly;
/**
* @author Eugene.Kudelevsky
*/
public class AndroidInlineStyleReferenceAction extends AndroidBaseXmlRefactoringAction {
public static final String ACTION_ID = "AndroidInlineStyleReferenceAction";
private final AndroidInlineTestConfig myTestConfig;
@TestOnly
AndroidInlineStyleReferenceAction(AndroidInlineTestConfig testConfig) {
myTestConfig = testConfig;
}
@SuppressWarnings("UnusedDeclaration")
public AndroidInlineStyleReferenceAction() {
myTestConfig = null;
}
@Override
protected void doRefactorForTags(@NotNull Project project, @NotNull final XmlTag[] tags) {
assert tags.length == 1;
final XmlTag tag = tags[0];
final PsiFile file = tag.getContainingFile();
if (file == null) {
return;
}
final StyleUsageData usageData = AndroidInlineUtil.getStyleUsageData(tag);
if (usageData == null) {
return;
}
final AndroidResourceReferenceBase reference = usageData.getReference();
final String title = AndroidBundle.message("android.inline.style.title");
final PsiElement[] styleElements = reference.computeTargetElements();
if (styleElements.length == 0) {
AndroidUtils.reportError(project, "Cannot find style by reference '" + reference.getValue() + "'", title);
return;
}
if (styleElements.length > 1) {
AndroidUtils.reportError(project, RefactoringBundle.getCannotRefactorMessage("Unambiguous style reference."), title);
return;
}
final PsiElement styleElement = styleElements[0];
final XmlTag styleTag = PsiTreeUtil.getParentOfType(styleElement, XmlTag.class);
final DomElement domElement = styleTag != null ? DomManager.getDomManager(project).getDomElement(styleTag) : null;
if (!(domElement instanceof Style)) {
AndroidUtils.reportError(project, "Cannot find style by reference '" + reference.getValue() + "'", title);
return;
}
final Style style = (Style)domElement;
String styleName = style.getName().getStringValue();
if (styleName == null) {
AndroidUtils.reportError(project, RefactoringBundle.getCannotRefactorMessage("Style name is not specified."), title);
return;
}
AndroidInlineUtil.doInlineStyleDeclaration(project, new AndroidInlineUtil.MyStyleData(styleName, style, styleElement),
usageData,
new ProjectBasedErrorReporter(project), myTestConfig);
}
@Override
protected boolean isEnabledForTags(@NotNull XmlTag[] tags) {
return tags.length == 1 && AndroidInlineUtil.getStyleUsageData(tags[0]) != null;
}
@Override
protected boolean isMyFile(PsiFile file) {
final DomFileDescription<?> description = DomManager.getDomManager(file.getProject()).getDomFileDescription((XmlFile)file);
return description instanceof LayoutDomFileDescription ||
description instanceof ResourcesDomFileDescription;
}
}