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