1 /* 2 * Copyright (C) 2012 The Android Open Source Project 3 * 4 * Licensed under the Eclipse Public License, Version 1.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 7 * 8 * http://www.eclipse.org/org/documents/epl-v10.php 9 * 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. 15 */ 16 package com.android.ide.eclipse.adt.internal.refactorings.core; 17 18 import com.android.annotations.NonNull; 19 import com.android.ide.common.resources.ResourceUrl; 20 import com.android.ide.eclipse.adt.internal.project.BaseProjectHelper; 21 import com.android.resources.ResourceType; 22 23 import org.eclipse.core.resources.IFile; 24 import org.eclipse.core.resources.IProject; 25 import org.eclipse.core.resources.IResource; 26 import org.eclipse.jdt.core.IField; 27 import org.eclipse.jdt.core.IJavaProject; 28 import org.eclipse.jdt.core.IType; 29 import org.eclipse.jdt.internal.corext.refactoring.rename.RenameFieldProcessor; 30 import org.eclipse.ltk.core.refactoring.participants.RenameProcessor; 31 import org.eclipse.ltk.core.refactoring.participants.RenameRefactoring; 32 33 @SuppressWarnings({"javadoc", "restriction"}) 34 public class RenameResourceParticipantTest extends RefactoringTestBase { 35 public void testRefactor1() throws Exception { 36 renameResource( 37 TEST_PROJECT, 38 "@string/app_name", 39 true /*updateReferences*/, 40 "myname", 41 42 "CHANGES:\n" + 43 "-------\n" + 44 "[x] strings.xml - /testRefactor1/res/values/strings.xml\n" + 45 " @@ -4 +4\n" + 46 " - <string name=\"app_name\">RefactoringTest</string>\n" + 47 " + <string name=\"myname\">RefactoringTest</string>\n" + 48 "\n" + 49 "\n" + 50 "[ ] R.java - /testRefactor1/gen/com/example/refactoringtest/R.java\n" + 51 " @@ -29 +29\n" + 52 " - public static final int app_name=0x7f040000;\n" + 53 " + public static final int myname=0x7f040000;\n" + 54 "\n" + 55 "\n" + 56 "[x] AndroidManifest.xml - /testRefactor1/AndroidManifest.xml\n" + 57 " @@ -13 +13\n" + 58 " - android:label=\"@string/app_name\"\n" + 59 " + android:label=\"@string/myname\"\n" + 60 " @@ -17 +17\n" + 61 " - android:label=\"@string/app_name\" >\n" + 62 " + android:label=\"@string/myname\" >"); 63 } 64 65 public void testRefactor2() throws Exception { 66 renameResource( 67 TEST_PROJECT, 68 "@+id/menu_settings", 69 true /*updateReferences*/, 70 "new_id_for_the_action_bar", 71 72 "CHANGES:\n" + 73 "-------\n" + 74 "[x] activity_main.xml - /testRefactor2/res/menu/activity_main.xml\n" + 75 " @@ -4 +4\n" + 76 " - android:id=\"@+id/menu_settings\"\n" + 77 " + android:id=\"@+id/new_id_for_the_action_bar\"\n" + 78 "\n" + 79 "\n" + 80 "[ ] R.java - /testRefactor2/gen/com/example/refactoringtest/R.java\n" + 81 " @@ -19 +19\n" + 82 " - public static final int menu_settings=0x7f070003;\n" + 83 " + public static final int new_id_for_the_action_bar=0x7f070003;"); 84 } 85 86 public void testRefactor3() throws Exception { 87 renameResource( 88 TEST_PROJECT, 89 "@+id/textView1", 90 true /*updateReferences*/, 91 "output", 92 93 "CHANGES:\n" + 94 "-------\n" + 95 "[x] activity_main.xml - /testRefactor3/res/layout/activity_main.xml\n" + 96 " @@ -8 +8\n" + 97 " - android:id=\"@+id/textView1\"\n" + 98 " + android:id=\"@+id/output\"\n" + 99 " @@ -19 +19\n" + 100 " - android:layout_alignLeft=\"@+id/textView1\"\n" + 101 " - android:layout_below=\"@+id/textView1\"\n" + 102 " + android:layout_alignLeft=\"@+id/output\"\n" + 103 " + android:layout_below=\"@+id/output\"\n" + 104 "\n" + 105 "\n" + 106 "[x] MainActivity.java - /testRefactor3/src/com/example/refactoringtest/MainActivity.java\n" + 107 " @@ -14 +14\n" + 108 " - View view1 = findViewById(R.id.textView1);\n" + 109 " + View view1 = findViewById(R.id.output);\n" + 110 "\n" + 111 "\n" + 112 "[ ] R.java - /testRefactor3/gen/com/example/refactoringtest/R.java\n" + 113 " @@ -20 +20\n" + 114 " - public static final int textView1=0x7f070000;\n" + 115 " + public static final int output=0x7f070000;"); 116 } 117 118 public void testRefactor4() throws Exception { 119 renameResource( 120 TEST_PROJECT, 121 // same as testRefactor3, but use @id rather than @+id even though @+id is in file 122 "@id/textView1", 123 true /*updateReferences*/, 124 "output", 125 126 "CHANGES:\n" + 127 "-------\n" + 128 "[x] activity_main.xml - /testRefactor4/res/layout/activity_main.xml\n" + 129 " @@ -8 +8\n" + 130 " - android:id=\"@+id/textView1\"\n" + 131 " + android:id=\"@+id/output\"\n" + 132 " @@ -19 +19\n" + 133 " - android:layout_alignLeft=\"@+id/textView1\"\n" + 134 " - android:layout_below=\"@+id/textView1\"\n" + 135 " + android:layout_alignLeft=\"@+id/output\"\n" + 136 " + android:layout_below=\"@+id/output\"\n" + 137 "\n" + 138 "\n" + 139 "[x] MainActivity.java - /testRefactor4/src/com/example/refactoringtest/MainActivity.java\n" + 140 " @@ -14 +14\n" + 141 " - View view1 = findViewById(R.id.textView1);\n" + 142 " + View view1 = findViewById(R.id.output);\n" + 143 "\n" + 144 "\n" + 145 "[ ] R.java - /testRefactor4/gen/com/example/refactoringtest/R.java\n" + 146 " @@ -20 +20\n" + 147 " - public static final int textView1=0x7f070000;\n" + 148 " + public static final int output=0x7f070000;"); 149 } 150 151 public void testRefactor5() throws Exception { 152 renameResource( 153 TEST_PROJECT, 154 "@layout/activity_main", 155 true /*updateReferences*/, 156 "newlayout", 157 158 "CHANGES:\n" + 159 "-------\n" + 160 "[x] MainActivity.java - /testRefactor5/src/com/example/refactoringtest/MainActivity.java\n" + 161 " @@ -13 +13\n" + 162 " - setContentView(R.layout.activity_main);\n" + 163 " + setContentView(R.layout.newlayout);\n" + 164 "\n" + 165 "\n" + 166 "[ ] R.java - /testRefactor5/gen/com/example/refactoringtest/R.java\n" + 167 " @@ -23 +23\n" + 168 " - public static final int activity_main=0x7f030000;\n" + 169 " + public static final int newlayout=0x7f030000;\n" + 170 "\n" + 171 "\n" + 172 "[x] Rename 'testRefactor5/res/layout/activity_main.xml' to 'newlayout.xml'\n" + 173 "\n" + 174 "[x] Rename 'testRefactor5/res/layout-land/activity_main.xml' to 'newlayout.xml'"); 175 } 176 177 public void testRefactor6() throws Exception { 178 renameResource( 179 TEST_PROJECT, 180 "@drawable/ic_launcher", 181 true /*updateReferences*/, 182 "newlauncher", 183 184 "CHANGES:\n" + 185 "-------\n" + 186 "[ ] R.java - /testRefactor6/gen/com/example/refactoringtest/R.java\n" + 187 " @@ -14 +14\n" + 188 " - public static final int ic_launcher=0x7f020000;\n" + 189 " + public static final int newlauncher=0x7f020000;\n" + 190 "\n" + 191 "\n" + 192 "[x] Rename 'testRefactor6/res/drawable-xhdpi/ic_launcher.png' to 'newlauncher.png'\n" + 193 "\n" + 194 "[x] Rename 'testRefactor6/res/drawable-mdpi/ic_launcher.png' to 'newlauncher.png'\n" + 195 "\n" + 196 "[x] Rename 'testRefactor6/res/drawable-ldpi/ic_launcher.png' to 'newlauncher.png'\n" + 197 "\n" + 198 "[x] Rename 'testRefactor6/res/drawable-hdpi/ic_launcher.png' to 'newlauncher.png'\n" + 199 "\n" + 200 "[x] AndroidManifest.xml - /testRefactor6/AndroidManifest.xml\n" + 201 " @@ -12 +12\n" + 202 " - android:icon=\"@drawable/ic_launcher\"\n" + 203 " + android:icon=\"@drawable/newlauncher\""); 204 } 205 206 public void testRefactor7() throws Exception { 207 // Test refactoring initiated on a file rename 208 IProject project = createProject(TEST_PROJECT); 209 IFile file = project.getFile("res/layout/activity_main.xml"); 210 renameResource( 211 project, 212 file, 213 true /*updateReferences*/, 214 "newlayout", 215 216 "CHANGES:\n" + 217 "-------\n" + 218 "[x] MainActivity.java - /testRefactor7/src/com/example/refactoringtest/MainActivity.java\n" + 219 " @@ -13 +13\n" + 220 " - setContentView(R.layout.activity_main);\n" + 221 " + setContentView(R.layout.newlayout);\n" + 222 "\n" + 223 "\n" + 224 "[ ] R.java - /testRefactor7/gen/com/example/refactoringtest/R.java\n" + 225 " @@ -23 +23\n" + 226 " - public static final int activity_main=0x7f030000;\n" + 227 " + public static final int newlayout=0x7f030000;\n" + 228 "\n" + 229 "\n" + 230 "[x] Rename 'testRefactor7/res/layout-land/activity_main.xml' to 'newlayout.xml'\n" + 231 "\n" + 232 "[x] Rename 'testRefactor7/res/layout/activity_main.xml' to 'newlayout.xml'", 233 null); 234 } 235 236 public void testRefactor8() throws Exception { 237 // Test refactoring initiated on a Java field rename 238 IProject project = createProject(TEST_PROJECT); 239 IJavaProject javaProject = BaseProjectHelper.getJavaProject(project); 240 assertNotNull(javaProject); 241 IType type = javaProject.findType("com.example.refactoringtest.R.layout"); 242 if (type == null || !type.exists()) { 243 type = javaProject.findType("com.example.refactoringtest.R$layout"); 244 System.out.println("Had to switch to $ notation"); 245 } 246 assertNotNull(type); 247 assertTrue(type.exists()); 248 IField field = type.getField("activity_main"); 249 assertNotNull(field); 250 assertTrue(field.exists()); 251 252 renameResource( 253 project, 254 field, 255 true /*updateReferences*/, 256 "newlauncher", 257 258 "CHANGES:\n" + 259 "-------\n" + 260 "[x] Rename 'testRefactor8/res/layout/activity_main.xml' to 'newlauncher.xml'\n" + 261 "\n" + 262 "[x] Rename 'testRefactor8/res/layout-land/activity_main.xml' to 'newlauncher.xml'\n" + 263 "\n" + 264 "[x] MainActivity.java - /testRefactor8/src/com/example/refactoringtest/MainActivity.java\n" + 265 " @@ -13 +13\n" + 266 " - setContentView(R.layout.activity_main);\n" + 267 " + setContentView(R.layout.newlauncher);\n" + 268 "\n" + 269 "\n" + 270 "[ ] R.java - /testRefactor8/gen/com/example/refactoringtest/R.java\n" + 271 " @@ -23 +23\n" + 272 " - public static final int activity_main=0x7f030000;\n" + 273 " + public static final int newlauncher=0x7f030000;", 274 null); 275 } 276 277 public void testInvalidName() throws Exception { 278 renameResource( 279 TEST_PROJECT, 280 "@drawable/ic_launcher", 281 true /*updateReferences*/, 282 "Newlauncher", 283 284 "", 285 "<ERROR\n" + 286 "\t\n" + 287 "ERROR: File-based resource names must start with a lowercase letter.\n" + 288 "Context: <Unspecified context>\n" + 289 "code: none\n" + 290 "Data: null\n" + 291 ">"); 292 } 293 294 public void testRefactor9() throws Exception { 295 // same as testRefactor4, but not updating references 296 renameResource( 297 TEST_PROJECT, 298 "@id/textView1", 299 false /*updateReferences*/, 300 "output", 301 302 "CHANGES:\n" + 303 "-------\n" + 304 "[x] activity_main.xml - /testRefactor9/res/layout/activity_main.xml\n" + 305 " @@ -8 +8\n" + 306 " - android:id=\"@+id/textView1\"\n" + 307 " + android:id=\"@+id/output\"\n" + 308 "\n" + 309 "\n" + 310 "[ ] R.java - /testRefactor9/gen/com/example/refactoringtest/R.java\n" + 311 " @@ -20 +20\n" + 312 " - public static final int textView1=0x7f070000;\n" + 313 " + public static final int output=0x7f070000;"); 314 } 315 316 public void testRefactor10() throws Exception { 317 // Check updating tools: attributes 318 renameResource( 319 TEST_PROJECT, 320 "@layout/preview", 321 true /*updateReferences*/, 322 "newlayout", 323 324 "CHANGES:\n" + 325 "-------\n" + 326 "[x] activity_main.xml - /testRefactor10/res/layout-land/activity_main.xml\n" + 327 " @@ -10 +10\n" + 328 " - tools:listitem=\"@layout/preview\" >\n" + 329 " + tools:listitem=\"@layout/newlayout\" >\n" + 330 " @@ -17 +17\n" + 331 " - tools:layout=\"@layout/preview\" />\n" + 332 " + tools:layout=\"@layout/newlayout\" />"); 333 } 334 335 // ---- Test infrastructure ---- 336 337 protected void renameResource( 338 @NonNull Object[] testData, 339 @NonNull Object resource, 340 boolean updateReferences, 341 @NonNull String newName, 342 @NonNull String expected) throws Exception { 343 renameResource(testData, resource, updateReferences, newName, expected, null); 344 } 345 346 protected void renameResource( 347 @NonNull Object[] testData, 348 @NonNull Object resource, 349 boolean updateReferences, 350 @NonNull String newName, 351 @NonNull String expected, 352 @NonNull String expectedWarnings) throws Exception { 353 IProject project = createProject(testData); 354 renameResource(project, resource, updateReferences, newName, expected, expectedWarnings); 355 } 356 357 protected void renameResource( 358 @NonNull IProject project, 359 @NonNull Object resource, 360 boolean updateReferences, 361 @NonNull String newName, 362 @NonNull String expected, 363 @NonNull String expectedWarnings) throws Exception { 364 RenameProcessor processor = null; 365 if (resource instanceof String) { 366 String url = (String) resource; 367 assert url.startsWith("@") : resource; 368 369 ResourceUrl parsedUrl = ResourceUrl.parse(url); 370 assertNotNull(url, parsedUrl); 371 assert parsedUrl != null; // null analysis doesn't recognize assertNotNull 372 ResourceType type = parsedUrl.type; 373 String currentName = parsedUrl.name; 374 RenameResourceProcessor p; 375 p = new RenameResourceProcessor(project, type, currentName, newName); 376 p.setUpdateReferences(updateReferences); 377 processor = p; 378 } else if (resource instanceof IResource) { 379 IResource r = (IResource) resource; 380 org.eclipse.ltk.internal.core.refactoring.resource.RenameResourceProcessor p; 381 p = new org.eclipse.ltk.internal.core.refactoring.resource.RenameResourceProcessor(r); 382 String fileName = r.getName(); 383 int dot = fileName.indexOf('.'); 384 String extension = (dot != -1) ? fileName.substring(dot) : ""; 385 p.setNewResourceName(newName + extension); 386 p.setUpdateReferences(updateReferences); 387 processor = p; 388 } else if (resource instanceof IField) { 389 RenameFieldProcessor p = new RenameFieldProcessor((IField) resource); 390 p.setNewElementName(newName); 391 p.setUpdateReferences(updateReferences); 392 processor = p; 393 } else { 394 fail("Unsupported resource element in tests: " + resource); 395 } 396 397 assertNotNull(processor); 398 399 RenameRefactoring refactoring = new RenameRefactoring(processor); 400 checkRefactoring(refactoring, expected, expectedWarnings); 401 } 402 }