android: "extract string" intention should work in manifest and only in attributes allowing string references

This commit is contained in:
Eugene Kudelevsky
2012-01-26 16:32:12 +04:00
parent 5fc914f545
commit c9def85bf0
8 changed files with 142 additions and 33 deletions
@@ -165,7 +165,12 @@ public class ResourceReferenceConverter extends ResolvingConverter<ResourceValue
}
private Set<String> getResourceTypes(ConvertContext context) {
ResourceType resourceType = context.getInvocationElement().getAnnotation(ResourceType.class);
return getResourceTypes(context.getInvocationElement());
}
@NotNull
public Set<String> getResourceTypes(@NotNull DomElement element) {
ResourceType resourceType = element.getAnnotation(ResourceType.class);
Set<String> types = new HashSet<String>(myResourceTypes);
if (resourceType != null) {
String s = resourceType.value();
@@ -45,8 +45,12 @@ import com.intellij.psi.xml.XmlAttributeValue;
import com.intellij.psi.xml.XmlFile;
import com.intellij.refactoring.util.RefactoringUtil;
import com.intellij.util.IncorrectOperationException;
import com.intellij.util.xml.Converter;
import com.intellij.util.xml.DomManager;
import com.intellij.util.xml.GenericAttributeValue;
import org.jetbrains.android.AndroidFileTemplateProvider;
import org.jetbrains.android.actions.CreateXmlResourceDialog;
import org.jetbrains.android.dom.converters.ResourceReferenceConverter;
import org.jetbrains.android.dom.manifest.Manifest;
import org.jetbrains.android.dom.resources.ResourceElement;
import org.jetbrains.android.dom.resources.ResourceValue;
@@ -107,7 +111,29 @@ public class AndroidAddStringResourceAction extends AbstractIntentionAction {
}
}
else if (file instanceof XmlFile && element instanceof XmlAttributeValue) {
return ((XmlAttributeValue)element).getValue();
final XmlAttribute attribute = PsiTreeUtil.getParentOfType(element, XmlAttribute.class);
if (attribute != null) {
final GenericAttributeValue domAttribute = DomManager.getDomManager(element.getProject()).getDomElement(attribute);
if (domAttribute != null) {
final Converter converter = domAttribute.getConverter();
if (converter instanceof ResourceReferenceConverter) {
final ResourceValue value = (ResourceValue)domAttribute.getValue();
if (value != null && !value.isReference()) {
final Set<String> types = ((ResourceReferenceConverter)converter).getResourceTypes(domAttribute);
for (String type : types) {
if (ResourceType.STRING.getName().equals(type)) {
return ((XmlAttributeValue)element).getValue();
}
}
}
}
}
}
}
return null;
}
@@ -141,25 +167,25 @@ public class AndroidAddStringResourceAction extends AbstractIntentionAction {
static void doInvoke(Project project, Editor editor, PsiFile file, @Nullable String resName) {
final AndroidFacet facet = AndroidFacet.getInstance(file);
assert facet != null;
final PsiElement element = getPsiElement(file, editor);
assert element != null;
String value = getStringLiteralValue(element, file);
assert value != null;
value = value.replace("'", "\\'").replace("\"", "\\\"");
final String aPackage = getPackage(facet);
if (aPackage == null) {
Messages.showErrorDialog(project, AndroidBundle.message("package.not.found.error"), CommonBundle.getErrorTitle());
return;
}
if (resName == null) {
final CreateXmlResourceDialog dialog = new CreateXmlResourceDialog(facet.getModule(), ResourceType.STRING);
dialog.setTitle("Extract String Resource");
dialog.show();
if (!dialog.isOK()) {
return;
}
@@ -180,7 +206,7 @@ public class AndroidAddStringResourceAction extends AbstractIntentionAction {
assert ApplicationManager.getApplication().isUnitTestMode();
doCreate(facet.getModule(), resName, ResourceType.STRING, "strings.xml", "values", value);
}
if (resName == null) {
return;
}
@@ -194,7 +220,7 @@ public class AndroidAddStringResourceAction extends AbstractIntentionAction {
attribute.setValue(ResourceValue.referenceTo('@', null, ResourceType.STRING.getName(), resName).toString());
}
}
PsiDocumentManager.getInstance(project).commitAllDocuments();
UndoUtil.markPsiFileForUndo(file);
@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<TextView
android:layout_width="fill_parent"
android:layout_height="wra<caret>p_content"
android:text="hello"
/>
</LinearLayout>
@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example"
android:versionCode="1"
android:versionName="1.0">
<application android:label="@string/a1<caret>0" >
</application>
</manifest>
@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example"
android:versionCode="1"
android:versionName="1.0">
<application android:label="hell<caret>o" >
</application>
</manifest>
@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example"
android:versionCode="1"
android:versionName="1.0">
<application android:label="@string/hello" >
</application>
</manifest>
@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example"
android:versionCode="1"
android:versionName="1.0">
<application>
<activity android:name="MyAc<caret>tivity">
</activity>
</application>
</manifest>
@@ -11,12 +11,18 @@ import com.intellij.util.IncorrectOperationException;
import org.jetbrains.android.AndroidTestCase;
import org.jetbrains.annotations.Nullable;
import java.io.IOException;
/**
* @author Eugene.Kudelevsky
*/
public class AndroidAddStringResourceActionTest extends AndroidTestCase {
private static final String BASE_PATH = "addStringRes/";
public AndroidAddStringResourceActionTest() {
super(false);
}
@Override
public void setUp() throws Exception {
super.setUp();
@@ -29,31 +35,31 @@ public class AndroidAddStringResourceActionTest extends AndroidTestCase {
super.tearDown();
}
public void test1() {
public void test1() throws IOException {
doTest();
}
public void test2() {
public void test2() throws IOException {
doTest();
}
public void test3() {
public void test3() throws IOException {
doTest();
}
public void test4() {
public void test4() throws IOException {
doTest();
}
public void test5() {
public void test5() throws IOException {
doTest();
}
public void test6() {
public void test6() throws IOException {
doTest();
}
public void test7() {
public void test7() throws IOException {
doTest(new Runnable() {
@Override
public void run() {
@@ -63,19 +69,19 @@ public class AndroidAddStringResourceActionTest extends AndroidTestCase {
});
}
public void test8() {
public void test8() throws IOException {
doTest();
}
public void test9() {
public void test9() throws IOException {
doTest();
}
public void test10() {
public void test10() throws IOException {
doTest();
}
public void test11() {
public void test11() throws IOException {
doTest(new Runnable() {
@Override
public void run() {
@@ -85,11 +91,11 @@ public class AndroidAddStringResourceActionTest extends AndroidTestCase {
});
}
public void test12() {
public void test12() throws IOException {
doTest();
}
public void test13() {
public void test13() throws IOException {
doTest();
}
@@ -100,15 +106,15 @@ public class AndroidAddStringResourceActionTest extends AndroidTestCase {
assertFalse(new AndroidAddStringResourceAction().isAvailable(myFixture.getProject(), myFixture.getEditor(), javaPsiFile));
}
public void testEscape() {
public void testEscape() throws IOException {
doTest(getTestName(false), "strings.xml", null, true, "strings_escape_after.xml");
}
public void testNewFile() {
public void testNewFile() throws IOException {
doTest("1", null, null, true);
}
public void testInvalidStringsXml() {
public void testInvalidStringsXml() throws IOException {
try {
doTest("1", "strings_invalid.xml", null, true);
fail();
@@ -121,21 +127,47 @@ public class AndroidAddStringResourceActionTest extends AndroidTestCase {
myFixture.checkResultByFile("res/values/strings.xml", BASE_PATH + "strings_invalid.xml", false);
}
public void testFromLayout() {
final VirtualFile javaFile = myFixture.copyFileToProject(BASE_PATH + getTestName(false) + ".xml", "res/layout/layout.xml");
doExtractAndCheckStringsXml("strings.xml", null, true, "strings_after.xml", javaFile);
myFixture.checkResultByFile(BASE_PATH + getTestName(false) + "_after.xml");
public void testFromLayout() throws IOException {
createManifest();
final VirtualFile file = myFixture.copyFileToProject(BASE_PATH + getTestName(true) + ".xml", "res/layout/layout.xml");
doExtractAndCheckStringsXml("strings.xml", null, true, "strings_after.xml", file);
myFixture.checkResultByFile(BASE_PATH + getTestName(true) + "_after.xml");
}
private void doTest() {
public void testFromLayout1() throws IOException {
createManifest();
final VirtualFile file = myFixture.copyFileToProject(BASE_PATH + getTestName(true) + ".xml", "res/layout/layout.xml");
myFixture.configureFromExistingVirtualFile(file);
assertFalse(new AndroidAddStringResourceAction().isAvailable(myFixture.getProject(), myFixture.getEditor(), myFixture.getFile()));
}
public void testFromManifest() {
final VirtualFile file = myFixture.copyFileToProject(BASE_PATH + getTestName(true) + ".xml", "AndroidManifest.xml");
myFixture.configureFromExistingVirtualFile(file);
assertFalse(new AndroidAddStringResourceAction().isAvailable(myFixture.getProject(), myFixture.getEditor(), myFixture.getFile()));
}
public void testFromManifest1() {
final VirtualFile file = myFixture.copyFileToProject(BASE_PATH + getTestName(true) + ".xml", "AndroidManifest.xml");
doExtractAndCheckStringsXml("strings.xml", null, true, "strings_after.xml", file);
myFixture.checkResultByFile(BASE_PATH + getTestName(true) + "_after.xml");
}
public void testFromManifest2() {
final VirtualFile file = myFixture.copyFileToProject(BASE_PATH + getTestName(true) + ".xml", "AndroidManifest.xml");
myFixture.configureFromExistingVirtualFile(file);
assertFalse(new AndroidAddStringResourceAction().isAvailable(myFixture.getProject(), myFixture.getEditor(), myFixture.getFile()));
}
private void doTest() throws IOException {
doTest(getTestName(false), "strings.xml", null, true);
}
private void doTest(Runnable invokeAfterTemplate) {
private void doTest(Runnable invokeAfterTemplate) throws IOException {
doTest(getTestName(false), "strings.xml", invokeAfterTemplate, false);
}
private void doTest(String testName, String stringsXml, final Runnable invokeAfterTemplate, final boolean closePopup) {
private void doTest(String testName, String stringsXml, final Runnable invokeAfterTemplate, final boolean closePopup) throws IOException {
doTest(testName, stringsXml, invokeAfterTemplate, closePopup, "strings_after.xml");
}
@@ -143,7 +175,8 @@ public class AndroidAddStringResourceActionTest extends AndroidTestCase {
String stringsXml,
@Nullable final Runnable invokeAfterTemplate,
final boolean closePopup,
String stringsAfter) {
String stringsAfter) throws IOException {
createManifest();
VirtualFile javaFile = myFixture.copyFileToProject(BASE_PATH + "Class" + testName + ".java", "src/p1/p2/Class.java");
doExtractAndCheckStringsXml(stringsXml, invokeAfterTemplate, closePopup, stringsAfter, javaFile);
myFixture.checkResultByFile(BASE_PATH + "Class" + testName + "_after.java");