1 /******************************************************************************* 2 * Copyright (c) 2000, 2017 IBM Corporation and others. 3 * 4 * This program and the accompanying materials 5 * are made available under the terms of the Eclipse Public License 2.0 6 * which accompanies this distribution, and is available at 7 * https://www.eclipse.org/legal/epl-2.0/ 8 * 9 * SPDX-License-Identifier: EPL-2.0 10 * 11 * Contributors: 12 * IBM Corporation - Initial API and implementation 13 * tammo.freese@offis.de - tests for swapping files and folders 14 ******************************************************************************/ 15 package org.eclipse.core.tests.resources; 16 17 import java.io.ByteArrayInputStream; 18 import java.io.IOException; 19 import org.eclipse.core.internal.resources.Workspace; 20 import org.eclipse.core.resources.*; 21 import org.eclipse.core.runtime.*; 22 import org.eclipse.core.runtime.jobs.Job; 23 24 /** 25 * Tests behavior of IResourceChangeListener, including validation 26 * that correct deltas are received for all types of workspace changes. 27 */ 28 public class IResourceChangeListenerTest extends ResourceTest { 29 class SimpleListener implements IResourceChangeListener { 30 Object source; 31 int trigger; 32 33 @Override resourceChanged(IResourceChangeEvent event)34 public void resourceChanged(IResourceChangeEvent event) { 35 source = event.getSource(); 36 trigger = event.getBuildKind(); 37 } 38 } 39 40 protected static final String VERIFIER_NAME = "TestListener"; 41 IFile file1; //below folder1 42 IFile file2; //below folder1 43 IFile file3; //below folder2 44 IFolder folder1; //below project2 45 IFolder folder2; //below folder1 46 IFolder folder3; //same as file1 47 /* some random resource handles */ 48 IProject project1; 49 IFile project1MetaData; 50 IProject project2; 51 IFile project2MetaData; 52 ResourceDeltaVerifier verifier; 53 _testBenchMark_1GBYQEZ()54 public void _testBenchMark_1GBYQEZ() { 55 // start with a clean workspace 56 getWorkspace().removeResourceChangeListener(verifier); 57 try { 58 getWorkspace().getRoot().delete(false, getMonitor()); 59 } catch (CoreException e) { 60 fail("0.0", e); 61 } 62 // create the listener 63 IResourceChangeListener listener = new IResourceChangeListener() { 64 public int fCounter; 65 66 @Override 67 public void resourceChanged(IResourceChangeEvent event) { 68 try { 69 System.out.println("Start"); 70 for (int i = 0; i < 10; i++) { 71 fCounter = 0; 72 long start = System.currentTimeMillis(); 73 IResourceDelta delta = event.getDelta(); 74 delta.accept(delta2 -> { 75 fCounter++; 76 return true; 77 }); 78 long end = System.currentTimeMillis(); 79 System.out.println(" Number of deltas: " + fCounter + ". Time needed: " + (end - start)); 80 } 81 System.out.println("End"); 82 } catch (CoreException e) { 83 fail("1.0", e); 84 } 85 } 86 }; 87 // add the listener 88 getWorkspace().addResourceChangeListener(listener); 89 // setup the test data 90 IWorkspaceRunnable body = monitor -> { 91 IProject project = getWorkspace().getRoot().getProject("Test"); 92 IProjectDescription description = getWorkspace().newProjectDescription(project.getName()); 93 IPath root = getWorkspace().getRoot().getLocation(); 94 IPath contents = root.append("temp/testing"); 95 description.setLocation(contents); 96 project.create(description, getMonitor()); 97 project.open(getMonitor()); 98 project.refreshLocal(IResource.DEPTH_INFINITE, getMonitor()); 99 }; 100 try { 101 getWorkspace().run(body, getMonitor()); 102 } catch (CoreException e) { 103 fail("2.0", e); 104 } 105 // touch all resources (so that they appear in the delta) 106 body = monitor -> { 107 IResourceVisitor visitor = resource -> { 108 resource.touch(getMonitor()); 109 return true; 110 }; 111 getWorkspace().getRoot().accept(visitor); 112 }; 113 try { 114 getWorkspace().run(body, getMonitor()); 115 } catch (CoreException e) { 116 fail("3.0", e); 117 } 118 // un-register our listener 119 getWorkspace().removeResourceChangeListener(listener); 120 } 121 122 /** 123 * Tests that the builder is receiving an appropriate delta 124 * 125 * @see SortBuilderPlugin 126 * @see SortBuilder 127 */ assertDelta()128 public void assertDelta() { 129 assertTrue(verifier.getMessage(), verifier.isDeltaValid()); 130 } 131 132 /** 133 * Asserts that a manual traversal of the delta does not find the given 134 * resources. 135 */ assertNotDeltaIncludes(String message, IResourceDelta delta, IResource[] resources)136 void assertNotDeltaIncludes(String message, IResourceDelta delta, IResource[] resources) { 137 try { 138 IResource deltaResource = delta.getResource(); 139 for (IResource resource : resources) { 140 assertTrue(message, !deltaResource.equals(resource)); 141 } 142 IResourceDelta[] children = delta.getAffectedChildren(); 143 for (IResourceDelta element : children) { 144 assertNotDeltaIncludes(message, element, resources); 145 } 146 } catch (RuntimeException e) { 147 fail(message, e); 148 } 149 } 150 151 /** 152 * Asserts that a visitor traversal of the delta does not find the given 153 * resources. 154 */ assertNotDeltaVisits(final String message, IResourceDelta delta, final IResource[] resources)155 void assertNotDeltaVisits(final String message, IResourceDelta delta, final IResource[] resources) { 156 try { 157 delta.accept(delta2 -> { 158 IResource deltaResource = delta2.getResource(); 159 for (IResource resource : resources) { 160 assertTrue(message, !deltaResource.equals(resource)); 161 } 162 return true; 163 }); 164 } catch (CoreException | RuntimeException e) { 165 fail(message, e); 166 } 167 } 168 169 /** 170 * Runs code to handle a core exception 171 */ handleCoreException(CoreException e)172 protected void handleCoreException(CoreException e) { 173 fail("IResourceChangeListenerTest", e); 174 } 175 176 /** 177 * Sets the workspace autobuilding to the desired value. 178 */ setAutoBuilding(boolean value)179 protected void setAutoBuilding(boolean value) { 180 IWorkspace workspace = getWorkspace(); 181 if (workspace.isAutoBuilding() == value) { 182 return; 183 } 184 IWorkspaceDescription desc = workspace.getDescription(); 185 desc.setAutoBuilding(value); 186 try { 187 workspace.setDescription(desc); 188 } catch (CoreException e) { 189 fail("failed to set workspace description", e); 190 } 191 } 192 193 /** 194 * Sets up the fixture, for example, open a network connection. This method 195 * is called before a test is executed. 196 */ 197 @Override setUp()198 protected void setUp() throws Exception { 199 super.setUp(); 200 // Create some resource handles 201 project1 = getWorkspace().getRoot().getProject("Project" + 1); 202 project2 = getWorkspace().getRoot().getProject("Project" + 2); 203 folder1 = project1.getFolder("Folder" + 1); 204 folder2 = folder1.getFolder("Folder" + 2); 205 folder3 = folder1.getFolder("File" + 1); 206 file1 = folder1.getFile("File" + 1); 207 file2 = folder1.getFile("File" + 2); 208 file3 = folder2.getFile("File" + 1); 209 project1MetaData = project1.getFile(IProjectDescription.DESCRIPTION_FILE_NAME); 210 project2MetaData = project2.getFile(IProjectDescription.DESCRIPTION_FILE_NAME); 211 // Create and open a project, folder and file 212 IWorkspaceRunnable body = monitor -> { 213 project1.create(getMonitor()); 214 project1.open(getMonitor()); 215 folder1.create(true, true, getMonitor()); 216 file1.create(getRandomContents(), true, getMonitor()); 217 }; 218 verifier = new ResourceDeltaVerifier(); 219 getWorkspace().addResourceChangeListener(verifier, IResourceChangeEvent.POST_CHANGE); 220 try { 221 getWorkspace().run(body, getMonitor()); 222 } catch (CoreException e) { 223 fail("1.0", e); 224 } 225 //ensure all background jobs are done before we reset the delta verifier 226 waitForBuild(); 227 waitForRefresh(); 228 verifier.reset(); 229 } 230 231 /** 232 * Tears down the fixture, for example, close a network connection. This 233 * method is called after a test is executed. 234 */ 235 @Override tearDown()236 protected void tearDown() throws Exception { 237 getWorkspace().removeResourceChangeListener(verifier); 238 super.tearDown(); 239 ensureDoesNotExistInWorkspace(getWorkspace().getRoot()); 240 } 241 242 /* 243 * Create a resource change listener and register it for POST_BUILD 244 * events. Ensure that you are able to modify the workspace tree. 245 */ test_1GDK9OG()246 public void test_1GDK9OG() { 247 // create the resource change listener 248 IResourceChangeListener listener = event -> { 249 try { 250 IWorkspaceRunnable body = monitor -> { 251 // modify the tree. 252 IResourceDeltaVisitor visitor = delta -> { 253 IResource resource = delta.getResource(); 254 try { 255 resource.touch(getMonitor()); 256 } catch (RuntimeException e) { 257 throw e; 258 } 259 resource.createMarker(IMarker.PROBLEM); 260 return true; 261 }; 262 event.getDelta().accept(visitor); 263 }; 264 getWorkspace().run(body, getMonitor()); 265 } catch (CoreException e) { 266 fail("1.0", e); 267 } 268 }; 269 // register the listener with the workspace. 270 getWorkspace().addResourceChangeListener(listener, IResourceChangeEvent.POST_BUILD); 271 try { 272 IWorkspaceRunnable body = new IWorkspaceRunnable() { 273 // cause a delta by touching all resources 274 final IResourceVisitor visitor = resource -> { 275 resource.touch(getMonitor()); 276 return true; 277 }; 278 279 @Override 280 public void run(IProgressMonitor monitor) throws CoreException { 281 getWorkspace().getRoot().accept(visitor); 282 } 283 }; 284 getWorkspace().run(body, getMonitor()); 285 //wait for autobuild so POST_BUILD will fire 286 try { 287 Job.getJobManager().join(ResourcesPlugin.FAMILY_AUTO_BUILD, null); 288 } catch (OperationCanceledException | InterruptedException e) { 289 //ignore 290 } 291 } catch (CoreException e) { 292 fail("2.0", e); 293 } finally { 294 // cleanup: ensure that the listener is removed 295 getWorkspace().removeResourceChangeListener(listener); 296 } 297 } 298 testAddAndRemoveFile()299 public void testAddAndRemoveFile() { 300 try { 301 verifier.reset(); 302 getWorkspace().run((IWorkspaceRunnable) m -> { 303 m.beginTask("Creating and deleting", 100); 304 try { 305 file2.create(getRandomContents(), true, SubMonitor.convert(m, 50)); 306 file2.delete(true, SubMonitor.convert(m, 50)); 307 } finally { 308 m.done(); 309 } 310 }, getMonitor()); 311 //should not have been verified since there was no change 312 assertTrue("Unexpected notification on no change", !verifier.hasBeenNotified()); 313 } catch (CoreException e) { 314 handleCoreException(e); 315 } 316 } 317 testAddAndRemoveFolder()318 public void testAddAndRemoveFolder() { 319 try { 320 verifier.reset(); 321 getWorkspace().run((IWorkspaceRunnable) m -> { 322 m.beginTask("Creating and deleting", 100); 323 try { 324 folder2.create(true, true, SubMonitor.convert(m, 50)); 325 folder2.delete(true, SubMonitor.convert(m, 50)); 326 } finally { 327 m.done(); 328 } 329 }, getMonitor()); 330 //should not have been verified since there was no change 331 assertTrue("Unexpected notification on no change", !verifier.hasBeenNotified()); 332 } catch (CoreException e) { 333 handleCoreException(e); 334 } 335 } 336 testAddFile()337 public void testAddFile() { 338 try { 339 verifier.addExpectedChange(file2, IResourceDelta.ADDED, 0); 340 file2.create(getRandomContents(), true, getMonitor()); 341 assertDelta(); 342 } catch (CoreException e) { 343 handleCoreException(e); 344 } 345 } 346 testAddFileAndFolder()347 public void testAddFileAndFolder() { 348 try { 349 verifier.addExpectedChange(folder2, IResourceDelta.ADDED, 0); 350 verifier.addExpectedChange(file3, IResourceDelta.ADDED, 0); 351 getWorkspace().run((IWorkspaceRunnable) m -> { 352 m.beginTask("Creating folder and file", 100); 353 try { 354 folder2.create(true, true, SubMonitor.convert(m, 50)); 355 file3.create(getRandomContents(), true, SubMonitor.convert(m, 50)); 356 } finally { 357 m.done(); 358 } 359 }, getMonitor()); 360 assertDelta(); 361 } catch (CoreException e) { 362 handleCoreException(e); 363 } 364 } 365 testAddFolder()366 public void testAddFolder() { 367 try { 368 verifier.addExpectedChange(folder2, IResourceDelta.ADDED, 0); 369 folder2.create(true, true, getMonitor()); 370 assertDelta(); 371 } catch (CoreException e) { 372 handleCoreException(e); 373 } 374 } 375 testAddProject()376 public void testAddProject() { 377 try { 378 verifier.addExpectedChange(project2, IResourceDelta.ADDED, 0); 379 verifier.addExpectedChange(project2MetaData, IResourceDelta.ADDED, 0); 380 project2.create(getMonitor()); 381 assertDelta(); 382 } catch (CoreException e) { 383 handleCoreException(e); 384 } 385 } 386 387 /* 388 * Create a resource change listener and register it for POST_CHANGE events. 389 * Ensure that you are NOT able to modify the workspace tree. 390 */ testBug45996()391 public void testBug45996() { 392 // create the resource change listener 393 IResourceChangeListener listener = event -> { 394 boolean failed = false; 395 try { 396 IWorkspaceRunnable body = monitor -> { 397 // modify the tree. 398 IResourceDeltaVisitor visitor = delta -> { 399 IResource resource = delta.getResource(); 400 try { 401 resource.touch(getMonitor()); 402 } catch (RuntimeException e) { 403 throw e; 404 } 405 resource.createMarker(IMarker.PROBLEM); 406 return true; 407 }; 408 event.getDelta().accept(visitor); 409 }; 410 getWorkspace().run(body, getMonitor()); 411 } catch (CoreException e) { 412 //should fail 413 failed = true; 414 } 415 assertTrue("1.0", failed); 416 }; 417 // register the listener with the workspace. 418 getWorkspace().addResourceChangeListener(listener, IResourceChangeEvent.POST_CHANGE); 419 try { 420 IWorkspaceRunnable body = new IWorkspaceRunnable() { 421 // cause a delta by touching all resources 422 final IResourceVisitor visitor = resource -> { 423 resource.touch(getMonitor()); 424 return true; 425 }; 426 427 @Override 428 public void run(IProgressMonitor monitor) throws CoreException { 429 getWorkspace().getRoot().accept(visitor); 430 } 431 }; 432 getWorkspace().run(body, getMonitor()); 433 } catch (CoreException e) { 434 fail("2.0", e); 435 } finally { 436 // cleanup: ensure that the listener is removed 437 getWorkspace().removeResourceChangeListener(listener); 438 } 439 } 440 testBuildKind()441 public void testBuildKind() { 442 SimpleListener preBuild = new SimpleListener(); 443 SimpleListener postBuild = new SimpleListener(); 444 SimpleListener postChange = new SimpleListener(); 445 final IWorkspace workspace = getWorkspace(); 446 try { 447 setAutoBuilding(false); 448 workspace.addResourceChangeListener(preBuild, IResourceChangeEvent.PRE_BUILD); 449 workspace.addResourceChangeListener(postBuild, IResourceChangeEvent.POST_BUILD); 450 workspace.addResourceChangeListener(postChange, IResourceChangeEvent.POST_CHANGE); 451 452 final int[] triggers = new int[] {IncrementalProjectBuilder.INCREMENTAL_BUILD, IncrementalProjectBuilder.FULL_BUILD, IncrementalProjectBuilder.CLEAN_BUILD,}; 453 for (int i = 0; i < triggers.length; i++) { 454 final int trigger = triggers[i]; 455 workspace.run((IWorkspaceRunnable) monitor -> { 456 file1.touch(null); 457 workspace.build(trigger, monitor); 458 }, getMonitor()); 459 assertEquals("1.0." + i, workspace, preBuild.source); 460 assertEquals("1.1." + i, workspace, postBuild.source); 461 assertEquals("1.2." + i, workspace, postChange.source); 462 assertEquals("1.3." + i, trigger, preBuild.trigger); 463 assertEquals("1.4." + i, trigger, postBuild.trigger); 464 assertEquals("1.5." + i, 0, postChange.trigger); 465 466 workspace.run((IWorkspaceRunnable) monitor -> { 467 file1.touch(null); 468 project1.build(trigger, getMonitor()); 469 }, getMonitor()); 470 assertEquals("2.0." + i, project1, preBuild.source); 471 assertEquals("2.2." + i, project1, postBuild.source); 472 assertEquals("2.2." + i, workspace, postChange.source); 473 assertEquals("2.3." + i, trigger, preBuild.trigger); 474 assertEquals("2.4." + i, trigger, postBuild.trigger); 475 assertEquals("2.5." + i, 0, postChange.trigger); 476 477 } 478 479 //test autobuild trigger 480 setAutoBuilding(true); 481 file1.touch(null); 482 waitForBuild(); 483 int trigger = IncrementalProjectBuilder.AUTO_BUILD; 484 assertEquals("1.0", workspace, preBuild.source); 485 assertEquals("1.1", workspace, postBuild.source); 486 assertEquals("1.2", workspace, postChange.source); 487 assertEquals("1.3", trigger, preBuild.trigger); 488 assertEquals("1.4", trigger, postBuild.trigger); 489 assertEquals("1.5", 0, postChange.trigger); 490 491 } catch (CoreException e) { 492 fail("4.99", e); 493 } finally { 494 workspace.removeResourceChangeListener(preBuild); 495 workspace.removeResourceChangeListener(postBuild); 496 workspace.removeResourceChangeListener(postChange); 497 setAutoBuilding(true); 498 } 499 } 500 testChangeFile()501 public void testChangeFile() { 502 try { 503 /* change file1's contents */ 504 verifier.addExpectedChange(file1, IResourceDelta.CHANGED, IResourceDelta.CONTENT); 505 file1.setContents(getRandomContents(), true, false, getMonitor()); 506 assertDelta(); 507 } catch (CoreException e) { 508 handleCoreException(e); 509 } 510 } 511 testChangeFileToFolder()512 public void testChangeFileToFolder() { 513 try { 514 /* change file1 into a folder */ 515 verifier.addExpectedChange(file1, IResourceDelta.CHANGED, IResourceDelta.CONTENT | IResourceDelta.TYPE | IResourceDelta.REPLACED); 516 getWorkspace().run((IWorkspaceRunnable) m -> { 517 m.beginTask("Deleting and Creating", 100); 518 try { 519 file1.delete(true, SubMonitor.convert(m, 50)); 520 folder3.create(true, true, SubMonitor.convert(m, 50)); 521 } finally { 522 m.done(); 523 } 524 }, getMonitor()); 525 assertDelta(); 526 } catch (CoreException e) { 527 handleCoreException(e); 528 } 529 } 530 testChangeFolderToFile()531 public void testChangeFolderToFile() { 532 try { 533 /* change to a folder */ 534 verifier.reset(); 535 getWorkspace().run((IWorkspaceRunnable) m -> { 536 file1.delete(true, getMonitor()); 537 folder3.create(true, true, getMonitor()); 538 }, null); 539 /* now change back to a file and verify */ 540 verifier.addExpectedChange(file1, IResourceDelta.CHANGED, IResourceDelta.CONTENT | IResourceDelta.TYPE | IResourceDelta.REPLACED); 541 getWorkspace().run((IWorkspaceRunnable) m -> { 542 m.beginTask("Deleting and Creating", 100); 543 try { 544 folder3.delete(true, SubMonitor.convert(m, 50)); 545 file1.create(getRandomContents(), true, SubMonitor.convert(m, 50)); 546 } finally { 547 m.done(); 548 } 549 }, getMonitor()); 550 assertDelta(); 551 } catch (CoreException e) { 552 handleCoreException(e); 553 } 554 } 555 testChangeProject()556 public void testChangeProject() { 557 try { 558 verifier.reset(); 559 getWorkspace().run((IWorkspaceRunnable) m -> { 560 project2.create(getMonitor()); 561 project2.open(getMonitor()); 562 }, null); 563 IProjectDescription desc = project2.getDescription(); 564 desc.setReferencedProjects(new IProject[] {project1}); 565 verifier.addExpectedChange(project2, IResourceDelta.CHANGED, IResourceDelta.DESCRIPTION); 566 verifier.addExpectedChange(project2MetaData, IResourceDelta.CHANGED, IResourceDelta.CONTENT); 567 project2.setDescription(desc, IResource.FORCE, getMonitor()); 568 assertDelta(); 569 } catch (CoreException e) { 570 handleCoreException(e); 571 } 572 } 573 testCopyChangeFile()574 public void testCopyChangeFile() { 575 try { 576 verifier.addExpectedChange(folder2, IResourceDelta.ADDED, 0); 577 verifier.addExpectedChange(file3, IResourceDelta.ADDED, 0, null, null); 578 getWorkspace().run((IWorkspaceRunnable) m -> { 579 m.beginTask("Creating and moving", 150); 580 try { 581 folder2.create(true, true, SubMonitor.convert(m, 50)); 582 file1.copy(file3.getFullPath(), true, SubMonitor.convert(m, 50)); 583 file3.setContents(getRandomContents(), IResource.NONE, SubMonitor.convert(m, 50)); 584 } finally { 585 m.done(); 586 } 587 }, getMonitor()); 588 assertDelta(); 589 } catch (CoreException e) { 590 handleCoreException(e); 591 } 592 } 593 testCopyFile()594 public void testCopyFile() { 595 try { 596 verifier.addExpectedChange(folder2, IResourceDelta.ADDED, 0); 597 verifier.addExpectedChange(file3, IResourceDelta.ADDED, 0, null, null); 598 getWorkspace().run((IWorkspaceRunnable) m -> { 599 m.beginTask("Creating and moving", 100); 600 try { 601 folder2.create(true, true, SubMonitor.convert(m, 50)); 602 file1.copy(file3.getFullPath(), true, SubMonitor.convert(m, 50)); 603 } finally { 604 m.done(); 605 } 606 }, getMonitor()); 607 assertDelta(); 608 } catch (CoreException e) { 609 handleCoreException(e); 610 } 611 } 612 testCloseOpenReplaceFile()613 public void testCloseOpenReplaceFile() { 614 try { 615 // FIXME: how to do this? 616 //workspace.save(getMonitor()); 617 //workspace.close(getMonitor()); 618 //workspace.open(getMonitor()); 619 verifier.reset(); 620 getWorkspace().addResourceChangeListener(verifier); 621 /* change file1's contents */ 622 verifier.addExpectedChange(file1, IResourceDelta.CHANGED, IResourceDelta.REPLACED | IResourceDelta.CONTENT); 623 getWorkspace().run((IWorkspaceRunnable) m -> { 624 m.beginTask("Deleting and Creating", 100); 625 try { 626 file1.delete(true, SubMonitor.convert(m, 50)); 627 file1.create(getRandomContents(), true, SubMonitor.convert(m, 50)); 628 } finally { 629 m.done(); 630 } 631 }, getMonitor()); 632 assertDelta(); 633 } catch (CoreException e) { 634 handleCoreException(e); 635 } 636 } 637 testDeleteInPostBuildListener()638 public void testDeleteInPostBuildListener() { 639 // create the resource change listener 640 IResourceChangeListener listener = event -> { 641 try { 642 event.getDelta().accept(delta -> { 643 IResource resource = delta.getResource(); 644 if (resource.getType() == IResource.FILE) { 645 try { 646 ((IFile) resource).delete(true, true, null); 647 } catch (RuntimeException e) { 648 throw e; 649 } 650 } 651 return true; 652 }); 653 } catch (CoreException e) { 654 fail("1.0", e); 655 } 656 }; 657 // register the listener with the workspace. 658 getWorkspace().addResourceChangeListener(listener, IResourceChangeEvent.POST_BUILD); 659 try { 660 getWorkspace().run((IWorkspaceRunnable) monitor -> getWorkspace().getRoot().accept(resource -> { 661 resource.touch(getMonitor()); 662 return true; 663 }), getMonitor()); 664 } catch (CoreException e) { 665 fail("2.0", e); 666 } finally { 667 // cleanup: ensure that the listener is removed 668 getWorkspace().removeResourceChangeListener(listener); 669 } 670 } 671 672 /** 673 * Tests deleting a file, then moving another file to that deleted location. 674 * See bug 27527. 675 */ testDeleteMoveFile()676 public void testDeleteMoveFile() { 677 try { 678 verifier.reset(); 679 file2.create(getRandomContents(), IResource.NONE, getMonitor()); 680 verifier.reset(); 681 int flags = IResourceDelta.REPLACED | IResourceDelta.MOVED_FROM | IResourceDelta.CONTENT; 682 verifier.addExpectedChange(file1, IResourceDelta.CHANGED, flags, file2.getFullPath(), null); 683 verifier.addExpectedChange(file2, IResourceDelta.REMOVED, IResourceDelta.MOVED_TO, null, file1.getFullPath()); 684 getWorkspace().run((IWorkspaceRunnable) m -> { 685 m.beginTask("deleting and moving", 100); 686 try { 687 file1.delete(IResource.NONE, SubMonitor.convert(m, 50)); 688 file2.move(file1.getFullPath(), IResource.NONE, SubMonitor.convert(m, 50)); 689 } finally { 690 m.done(); 691 } 692 }, getMonitor()); 693 assertDelta(); 694 } catch (CoreException e) { 695 handleCoreException(e); 696 } 697 } 698 testDeleteProject()699 public void testDeleteProject() throws CoreException { 700 //test that marker deltas are fired when projects are deleted 701 verifier.reset(); 702 final IMarker marker = project1.createMarker(IMarker.TASK); 703 class Listener1 implements IResourceChangeListener { 704 public boolean done = false; 705 706 @Override 707 public void resourceChanged(IResourceChangeEvent event) { 708 done = true; 709 IMarkerDelta[] deltas = event.findMarkerDeltas(IMarker.TASK, false); 710 assertEquals("1.0", 1, deltas.length); 711 assertEquals("1.1", marker.getId(), deltas[0].getId()); 712 assertEquals("1.2", IResourceDelta.REMOVED, deltas[0].getKind()); 713 synchronized (this) { 714 notifyAll(); 715 } 716 } 717 } 718 Listener1 listener = new Listener1(); 719 try { 720 getWorkspace().addResourceChangeListener(listener, IResourceChangeEvent.POST_CHANGE); 721 project1.delete(true, false, getMonitor()); 722 synchronized (listener) { 723 int i = 0; 724 while (!listener.done) { 725 try { 726 listener.wait(1000); 727 } catch (InterruptedException e) { 728 } 729 assertTrue("2.0", ++i < 60); 730 } 731 } 732 } finally { 733 getWorkspace().removeResourceChangeListener(listener); 734 } 735 } 736 testDeleteFolderDuringRefresh()737 public void testDeleteFolderDuringRefresh() throws CoreException { 738 project1 = getWorkspace().getRoot().getProject(getUniqueString()); 739 project1.create(getMonitor()); 740 project1.open(getMonitor()); 741 742 project2 = getWorkspace().getRoot().getProject(getUniqueString()); 743 project2.create(getMonitor()); 744 project2.open(getMonitor()); 745 746 assertTrue("1.0", project1.isOpen()); 747 assertTrue("2.0", project2.isOpen()); 748 749 final IFolder f = project1.getFolder(getUniqueString()); 750 f.create(true, true, getMonitor()); 751 752 // the listener checks if an attempt to modify the tree succeeds if made in a job 753 // that belongs to FAMILY_MANUAL_REFRESH 754 class Listener1 implements IResourceChangeListener { 755 public boolean wasPerformed = false; 756 757 @Override 758 public void resourceChanged(IResourceChangeEvent event) { 759 new Job("deleteFolder") { 760 @Override 761 public boolean belongsTo(Object family) { 762 return family == ResourcesPlugin.FAMILY_MANUAL_REFRESH; 763 } 764 765 @Override 766 protected IStatus run(IProgressMonitor monitor) { 767 try { 768 f.delete(true, getMonitor()); 769 wasPerformed = true; 770 } catch (Exception e) { 771 fail("3.0", e); 772 } 773 return Status.OK_STATUS; 774 } 775 }.schedule(); 776 } 777 } 778 779 Listener1 listener1 = new Listener1(); 780 781 // perform a refresh to test the added listeners 782 try { 783 getWorkspace().addResourceChangeListener(listener1, IResourceChangeEvent.PRE_REFRESH); 784 785 project2.refreshLocal(IResource.DEPTH_INFINITE, getMonitor()); 786 Job.getJobManager().join(ResourcesPlugin.FAMILY_MANUAL_REFRESH, null); 787 788 assertTrue("4.0", listener1.wasPerformed); 789 assertDoesNotExistInWorkspace("5.0", f); 790 } catch (InterruptedException e) { 791 fail("6.0", e); 792 } catch (CoreException e) { 793 fail("7.0", e); 794 } finally { 795 getWorkspace().removeResourceChangeListener(listener1); 796 } 797 } 798 testRefreshOtherProjectDuringRefresh()799 public void testRefreshOtherProjectDuringRefresh() throws Exception { 800 final IProject p = getWorkspace().getRoot().getProject(getUniqueString()); 801 p.create(null); 802 p.open(null); 803 804 project1 = getWorkspace().getRoot().getProject(getUniqueString()); 805 project1.create(null); 806 project1.open(null); 807 808 assertTrue("1.0", p.isOpen()); 809 assertTrue("2.0", project1.isOpen()); 810 811 // the listener checks if an attempt to modify the tree succeeds if made in a job 812 // that belongs to FAMILY_MANUAL_REFRESH 813 class Listener1 implements IResourceChangeListener { 814 public boolean wasPerformed = false; 815 816 @Override 817 public void resourceChanged(final IResourceChangeEvent event) { 818 new Job("refreshProject") { 819 @Override 820 public boolean belongsTo(Object family) { 821 return family == ResourcesPlugin.FAMILY_MANUAL_REFRESH; 822 } 823 824 @Override 825 protected IStatus run(IProgressMonitor monitor) { 826 try { 827 if (event.getResource() != p) { 828 p.refreshLocal(IResource.DEPTH_INFINITE, null); 829 } 830 wasPerformed = true; 831 } catch (Exception e) { 832 fail("3.0", e); 833 } 834 return Status.OK_STATUS; 835 } 836 }.schedule(); 837 } 838 } 839 840 Listener1 listener1 = new Listener1(); 841 842 // the listener checks if an attempt to modify the tree in the refresh thread fails 843 class Listener2 implements IResourceChangeListener { 844 @Override 845 public void resourceChanged(IResourceChangeEvent event) { 846 try { 847 if (event.getResource() != p) { 848 p.refreshLocal(IResource.DEPTH_INFINITE, null); 849 } 850 fail("4.0"); 851 } catch (Exception e) { 852 // should fail 853 } 854 } 855 } 856 857 Listener2 listener2 = new Listener2(); 858 859 // perform a refresh to test the added listeners 860 try { 861 getWorkspace().addResourceChangeListener(listener1, IResourceChangeEvent.PRE_REFRESH); 862 getWorkspace().addResourceChangeListener(listener2, IResourceChangeEvent.PRE_REFRESH); 863 864 project1.refreshLocal(IResource.DEPTH_INFINITE, getMonitor()); 865 Job.getJobManager().join(ResourcesPlugin.FAMILY_MANUAL_REFRESH, null); 866 867 assertTrue("5.0", listener1.wasPerformed); 868 } catch (InterruptedException e) { 869 fail("6.0", e); 870 } catch (CoreException e) { 871 fail("7.0", e); 872 } finally { 873 getWorkspace().removeResourceChangeListener(listener1); 874 getWorkspace().removeResourceChangeListener(listener2); 875 } 876 } 877 testPreRefreshNotification()878 public void testPreRefreshNotification() throws Exception { 879 final IWorkspaceRoot root = getWorkspace().getRoot(); 880 881 project1 = root.getProject(getUniqueString()); 882 project1.create(null); 883 project1.open(null); 884 885 assertTrue("1.0", project1.isOpen()); 886 887 class Listener1 implements IResourceChangeListener { 888 public boolean wasPerformed = false; 889 public Object eventSource; 890 public Object eventResource; 891 892 @Override 893 public void resourceChanged(final IResourceChangeEvent event) { 894 wasPerformed = true; 895 eventSource = event.getSource(); 896 eventResource = event.getResource(); 897 } 898 } 899 900 Listener1 listener1 = new Listener1(); 901 902 // perform a refresh to test the added listeners 903 try { 904 getWorkspace().addResourceChangeListener(listener1, IResourceChangeEvent.PRE_REFRESH); 905 906 root.refreshLocal(IResource.DEPTH_INFINITE, getMonitor()); 907 Job.getJobManager().join(ResourcesPlugin.FAMILY_MANUAL_REFRESH, null); 908 909 assertTrue("2.0", listener1.wasPerformed); 910 assertEquals("3.0", getWorkspace(), listener1.eventSource); 911 assertEquals("4.0", null, listener1.eventResource); 912 913 project1.refreshLocal(IResource.DEPTH_INFINITE, getMonitor()); 914 Job.getJobManager().join(ResourcesPlugin.FAMILY_MANUAL_REFRESH, null); 915 916 assertTrue("5.0", listener1.wasPerformed); 917 assertEquals("6.0", project1, listener1.eventSource); 918 assertEquals("7.0", project1, listener1.eventResource); 919 } catch (InterruptedException e) { 920 fail("8.0", e); 921 } catch (CoreException e) { 922 fail("9.0", e); 923 } finally { 924 getWorkspace().removeResourceChangeListener(listener1); 925 } 926 } 927 928 /** 929 * Tests that phantom members don't show up in resource deltas when standard 930 * traversal and visitor are used. 931 */ testHiddenPhantomChanges()932 public void testHiddenPhantomChanges() { 933 final IWorkspace workspace = getWorkspace(); 934 final IFolder phantomFolder = project1.getFolder("PhantomFolder"); 935 final IFile phantomFile = folder1.getFile("PhantomFile"); 936 final IResource[] phantomResources = new IResource[] {phantomFolder, phantomFile}; 937 final QualifiedName partner = new QualifiedName("Test", "Infected"); 938 IResourceChangeListener listener = event -> { 939 //make sure the delta doesn't include the phantom members 940 assertNotDeltaIncludes("1.0", event.getDelta(), phantomResources); 941 //make sure a visitor does not find phantom members 942 assertNotDeltaVisits("1.1", event.getDelta(), phantomResources); 943 }; 944 workspace.addResourceChangeListener(listener); 945 workspace.getSynchronizer().add(partner); 946 ensureDoesNotExistInWorkspace(phantomResources); 947 try { 948 //create a phantom folder 949 workspace.run((IWorkspaceRunnable) monitor -> workspace.getSynchronizer().setSyncInfo(partner, phantomFolder, new byte[] {1}), getMonitor()); 950 //create children in phantom folder 951 IFile fileInFolder = phantomFolder.getFile("FileInPrivateFolder"); 952 workspace.getSynchronizer().setSyncInfo(partner, fileInFolder, new byte[] {1}); 953 //modify children in phantom folder 954 workspace.getSynchronizer().setSyncInfo(partner, fileInFolder, new byte[] {2}); 955 //delete children in phantom folder 956 workspace.getSynchronizer().flushSyncInfo(partner, fileInFolder, IResource.DEPTH_INFINITE); 957 //delete phantom folder and change some other file 958 workspace.run((IWorkspaceRunnable) monitor -> { 959 phantomFolder.delete(IResource.NONE, getMonitor()); 960 file1.setContents(getRandomContents(), IResource.NONE, getMonitor()); 961 }, getMonitor()); 962 //create phantom file 963 workspace.run((IWorkspaceRunnable) monitor -> workspace.getSynchronizer().setSyncInfo(partner, phantomFile, new byte[] {2}), getMonitor()); 964 //modify phantom file 965 workspace.getSynchronizer().setSyncInfo(partner, phantomFile, new byte[] {3}); 966 //delete phantom file 967 workspace.getSynchronizer().flushSyncInfo(partner, phantomFile, IResource.DEPTH_INFINITE); 968 } catch (CoreException e) { 969 handleCoreException(e); 970 } finally { 971 workspace.removeResourceChangeListener(listener); 972 } 973 } 974 975 /** 976 * Tests that team private members don't show up in resource deltas when 977 * standard traversal and visitor are used. 978 */ testHiddenTeamPrivateChanges()979 public void testHiddenTeamPrivateChanges() { 980 IWorkspace workspace = getWorkspace(); 981 final IFolder teamPrivateFolder = project1.getFolder("TeamPrivateFolder"); 982 final IFile teamPrivateFile = folder1.getFile("TeamPrivateFile"); 983 final IResource[] privateResources = new IResource[] {teamPrivateFolder, teamPrivateFile}; 984 IResourceChangeListener listener = event -> { 985 //make sure the delta doesn't include the team private members 986 assertNotDeltaIncludes("1.0", event.getDelta(), privateResources); 987 //make sure a visitor does not find team private members 988 assertNotDeltaVisits("1.1", event.getDelta(), privateResources); 989 }; 990 workspace.addResourceChangeListener(listener); 991 try { 992 //create a team private folder 993 workspace.run((IWorkspaceRunnable) monitor -> { 994 teamPrivateFolder.create(true, true, getMonitor()); 995 teamPrivateFolder.setTeamPrivateMember(true); 996 }, getMonitor()); 997 //create children in team private folder 998 IFile fileInFolder = teamPrivateFolder.getFile("FileInPrivateFolder"); 999 fileInFolder.create(getRandomContents(), true, getMonitor()); 1000 //modify children in team private folder 1001 fileInFolder.setContents(getRandomContents(), IResource.NONE, getMonitor()); 1002 //delete children in team private folder 1003 fileInFolder.delete(IResource.NONE, getMonitor()); 1004 //delete team private folder and change some other file 1005 workspace.run((IWorkspaceRunnable) monitor -> { 1006 teamPrivateFolder.delete(IResource.NONE, getMonitor()); 1007 file1.setContents(getRandomContents(), IResource.NONE, getMonitor()); 1008 }, getMonitor()); 1009 //create team private file 1010 workspace.run((IWorkspaceRunnable) monitor -> { 1011 teamPrivateFile.create(getRandomContents(), true, getMonitor()); 1012 teamPrivateFile.setTeamPrivateMember(true); 1013 }, getMonitor()); 1014 //modify team private file 1015 teamPrivateFile.setContents(getRandomContents(), IResource.NONE, getMonitor()); 1016 //delete team private file 1017 teamPrivateFile.delete(IResource.NONE, getMonitor()); 1018 } catch (CoreException e) { 1019 handleCoreException(e); 1020 } finally { 1021 workspace.removeResourceChangeListener(listener); 1022 } 1023 } 1024 testModifyMoveFile()1025 public void testModifyMoveFile() { 1026 try { 1027 verifier.addExpectedChange(folder2, IResourceDelta.ADDED, 0); 1028 verifier.addExpectedChange(file1, IResourceDelta.REMOVED, IResourceDelta.MOVED_TO, null, file3.getFullPath()); 1029 verifier.addExpectedChange(file3, IResourceDelta.ADDED, IResourceDelta.MOVED_FROM | IResourceDelta.CONTENT, file1.getFullPath(), null); 1030 getWorkspace().run((IWorkspaceRunnable) m -> { 1031 m.beginTask("Creating and moving", 100); 1032 try { 1033 folder2.create(true, true, SubMonitor.convert(m, 50)); 1034 file1.setContents(getRandomContents(), IResource.NONE, getMonitor()); 1035 file1.move(file3.getFullPath(), true, SubMonitor.convert(m, 50)); 1036 } finally { 1037 m.done(); 1038 } 1039 }, getMonitor()); 1040 assertDelta(); 1041 } catch (CoreException e) { 1042 handleCoreException(e); 1043 } 1044 } 1045 testMoveFile()1046 public void testMoveFile() { 1047 try { 1048 verifier.addExpectedChange(folder2, IResourceDelta.ADDED, 0); 1049 verifier.addExpectedChange(file1, IResourceDelta.REMOVED, IResourceDelta.MOVED_TO, null, file3.getFullPath()); 1050 verifier.addExpectedChange(file3, IResourceDelta.ADDED, IResourceDelta.MOVED_FROM, file1.getFullPath(), null); 1051 getWorkspace().run((IWorkspaceRunnable) m -> { 1052 m.beginTask("Creating and moving", 100); 1053 try { 1054 folder2.create(true, true, SubMonitor.convert(m, 50)); 1055 file1.move(file3.getFullPath(), true, SubMonitor.convert(m, 50)); 1056 } finally { 1057 m.done(); 1058 } 1059 }, getMonitor()); 1060 assertDelta(); 1061 } catch (CoreException e) { 1062 handleCoreException(e); 1063 } 1064 } 1065 testMoveFileAddMarker()1066 public void testMoveFileAddMarker() { 1067 try { 1068 verifier.addExpectedChange(folder2, IResourceDelta.ADDED, 0); 1069 verifier.addExpectedChange(file1, IResourceDelta.REMOVED, IResourceDelta.MOVED_TO, null, file3.getFullPath()); 1070 verifier.addExpectedChange(file3, IResourceDelta.ADDED, IResourceDelta.MOVED_FROM | IResourceDelta.MARKERS, file1.getFullPath(), null); 1071 getWorkspace().run((IWorkspaceRunnable) m -> { 1072 m.beginTask("Creating and moving", 100); 1073 try { 1074 folder2.create(true, true, SubMonitor.convert(m, 50)); 1075 file1.move(file3.getFullPath(), true, SubMonitor.convert(m, 50)); 1076 file3.createMarker(IMarker.TASK); 1077 } finally { 1078 m.done(); 1079 } 1080 }, getMonitor()); 1081 assertDelta(); 1082 } catch (CoreException e) { 1083 handleCoreException(e); 1084 } 1085 } 1086 1087 /** 1088 * Regression test for bug 42514 1089 */ testMoveFileDeleteFolder()1090 public void testMoveFileDeleteFolder() { 1091 try { 1092 //file2 moved to file1, and colliding folder3 is deleted 1093 file1.delete(IResource.NONE, null); 1094 file2.create(getRandomContents(), IResource.NONE, null); 1095 folder3.create(IResource.NONE, true, null); 1096 verifier.reset(); 1097 verifier.addExpectedChange(file2, IResourceDelta.REMOVED, IResourceDelta.MOVED_TO, null, file1.getFullPath()); 1098 int flags = IResourceDelta.MOVED_FROM | IResourceDelta.REPLACED | IResourceDelta.TYPE | IResourceDelta.CONTENT; 1099 verifier.addExpectedChange(file1, IResourceDelta.CHANGED, flags, file2.getFullPath(), null); 1100 getWorkspace().run((IWorkspaceRunnable) m -> { 1101 m.beginTask("Deleting and moving", 100); 1102 try { 1103 folder3.delete(IResource.FORCE, SubMonitor.convert(m, 50)); 1104 file2.move(file1.getFullPath(), true, SubMonitor.convert(m, 50)); 1105 } finally { 1106 m.done(); 1107 } 1108 }, getMonitor()); 1109 assertDelta(); 1110 } catch (CoreException e) { 1111 handleCoreException(e); 1112 } 1113 } 1114 testMoveFileDeleteSourceParent()1115 public void testMoveFileDeleteSourceParent() { 1116 try { 1117 file1.delete(IResource.NONE, null); 1118 create(file3, true); 1119 verifier.reset(); 1120 verifier.addExpectedChange(folder2, IResourceDelta.REMOVED, 0, null, null); 1121 verifier.addExpectedChange(file1, IResourceDelta.ADDED, IResourceDelta.MOVED_FROM, file3.getFullPath(), null); 1122 verifier.addExpectedChange(file3, IResourceDelta.REMOVED, IResourceDelta.MOVED_TO, null, file1.getFullPath()); 1123 getWorkspace().run((IWorkspaceRunnable) m -> { 1124 m.beginTask("Creating and moving", 100); 1125 try { 1126 file3.move(file1.getFullPath(), true, SubMonitor.convert(m, 50)); 1127 folder2.delete(IResource.NONE, SubMonitor.convert(m, 50)); 1128 } finally { 1129 m.done(); 1130 } 1131 }, getMonitor()); 1132 assertDelta(); 1133 } catch (CoreException e) { 1134 handleCoreException(e); 1135 } 1136 } 1137 testMoveModifyFile()1138 public void testMoveModifyFile() { 1139 try { 1140 verifier.addExpectedChange(folder2, IResourceDelta.ADDED, 0); 1141 verifier.addExpectedChange(file1, IResourceDelta.REMOVED, IResourceDelta.MOVED_TO, null, file3.getFullPath()); 1142 verifier.addExpectedChange(file3, IResourceDelta.ADDED, IResourceDelta.MOVED_FROM | IResourceDelta.CONTENT, file1.getFullPath(), null); 1143 getWorkspace().run((IWorkspaceRunnable) m -> { 1144 m.beginTask("Creating and moving", 100); 1145 try { 1146 folder2.create(true, true, SubMonitor.convert(m, 50)); 1147 file1.move(file3.getFullPath(), true, SubMonitor.convert(m, 50)); 1148 file3.setContents(getRandomContents(), IResource.NONE, getMonitor()); 1149 } finally { 1150 m.done(); 1151 } 1152 }, getMonitor()); 1153 assertDelta(); 1154 } catch (CoreException e) { 1155 handleCoreException(e); 1156 } 1157 } 1158 testMoveMoveFile()1159 public void testMoveMoveFile() { 1160 file2 = project1.getFile("File2"); 1161 file3 = project1.getFile("File3"); 1162 try { 1163 verifier.addExpectedChange(file1, IResourceDelta.REMOVED, IResourceDelta.MOVED_TO, null, file3.getFullPath()); 1164 verifier.addExpectedChange(file3, IResourceDelta.ADDED, IResourceDelta.MOVED_FROM, file1.getFullPath(), null); 1165 getWorkspace().run((IWorkspaceRunnable) m -> { 1166 m.beginTask("moving and moving file", 100); 1167 try { 1168 file1.move(file2.getFullPath(), false, null); 1169 file2.move(file3.getFullPath(), false, null); 1170 } finally { 1171 m.done(); 1172 } 1173 }, getMonitor()); 1174 assertDelta(); 1175 } catch (CoreException e) { 1176 handleCoreException(e); 1177 } 1178 } 1179 testMoveMoveFolder()1180 public void testMoveMoveFolder() { 1181 folder2 = project1.getFolder("Folder2"); 1182 folder3 = project1.getFolder("Folder3"); 1183 file3 = folder3.getFile(file1.getName()); 1184 try { 1185 verifier.addExpectedChange(folder1, IResourceDelta.REMOVED, IResourceDelta.MOVED_TO, null, folder3.getFullPath()); 1186 verifier.addExpectedChange(folder3, IResourceDelta.ADDED, IResourceDelta.MOVED_FROM, folder1.getFullPath(), null); 1187 verifier.addExpectedChange(file1, IResourceDelta.REMOVED, IResourceDelta.MOVED_TO, null, file3.getFullPath()); 1188 verifier.addExpectedChange(file3, IResourceDelta.ADDED, IResourceDelta.MOVED_FROM, file1.getFullPath(), null); 1189 getWorkspace().run((IWorkspaceRunnable) m -> { 1190 m.beginTask("moving and moving folder", 100); 1191 try { 1192 folder1.move(folder2.getFullPath(), false, null); 1193 folder2.move(folder3.getFullPath(), false, null); 1194 } finally { 1195 m.done(); 1196 } 1197 }, getMonitor()); 1198 assertDelta(); 1199 } catch (CoreException e) { 1200 handleCoreException(e); 1201 } 1202 } 1203 1204 /** 1205 * Move a project via rename. Note that the DESCRIPTION flag should be set 1206 * in the delta for the destination only. 1207 */ testMoveProject1()1208 public void testMoveProject1() { 1209 try { 1210 verifier.reset(); 1211 verifier.addExpectedChange(project1, IResourceDelta.REMOVED, IResourceDelta.MOVED_TO, null, project2.getFullPath()); 1212 verifier.addExpectedChange(project1.getFile(".project"), IResourceDelta.REMOVED, IResourceDelta.MOVED_TO, null, project2.getFile(".project").getFullPath()); 1213 verifier.addExpectedChange(folder1, IResourceDelta.REMOVED, IResourceDelta.MOVED_TO, null, project2.getFolder(folder1.getProjectRelativePath()).getFullPath()); 1214 verifier.addExpectedChange(file1, IResourceDelta.REMOVED, IResourceDelta.MOVED_TO, null, project2.getFile(file1.getProjectRelativePath()).getFullPath()); 1215 verifier.addExpectedChange(project2, IResourceDelta.ADDED, IResourceDelta.OPEN | IResourceDelta.DESCRIPTION | IResourceDelta.MOVED_FROM, project1.getFullPath(), null); 1216 verifier.addExpectedChange(project2.getFile(".project"), IResourceDelta.ADDED, IResourceDelta.CONTENT | IResourceDelta.MOVED_FROM, project1.getFile(".project").getFullPath(), null); 1217 verifier.addExpectedChange(project2.getFolder(folder1.getProjectRelativePath()), IResourceDelta.ADDED, IResourceDelta.MOVED_FROM, folder1.getFullPath(), null); 1218 verifier.addExpectedChange(project2.getFile(file1.getProjectRelativePath()), IResourceDelta.ADDED, IResourceDelta.MOVED_FROM, file1.getFullPath(), null); 1219 getWorkspace().run((IWorkspaceRunnable) m -> { 1220 m.beginTask("Creating and moving", 100); 1221 try { 1222 project1.move(project2.getFullPath(), IResource.NONE, SubMonitor.convert(m, 50)); 1223 } finally { 1224 m.done(); 1225 } 1226 }, getMonitor()); 1227 assertDelta(); 1228 } catch (CoreException e) { 1229 handleCoreException(e); 1230 } 1231 } 1232 1233 /** 1234 * Move a project via a location change only. Note that the DESCRIPTION flag 1235 * should be set in the delta. 1236 */ testMoveProject2()1237 public void testMoveProject2() { 1238 final IPath path = getRandomLocation(); 1239 try { 1240 verifier.addExpectedChange(project1, IResourceDelta.CHANGED, IResourceDelta.DESCRIPTION); 1241 getWorkspace().run((IWorkspaceRunnable) m -> { 1242 m.beginTask("Creating and moving", 100); 1243 try { 1244 IProjectDescription desc = project1.getDescription(); 1245 desc.setLocation(path); 1246 project1.move(desc, IResource.NONE, SubMonitor.convert(m, 50)); 1247 } finally { 1248 m.done(); 1249 } 1250 }, getMonitor()); 1251 assertDelta(); 1252 } catch (CoreException e) { 1253 handleCoreException(e); 1254 } finally { 1255 Workspace.clear(path.toFile()); 1256 } 1257 } 1258 testMulti()1259 public void testMulti() { 1260 class Listener1 implements IResourceChangeListener { 1261 public boolean done = false; 1262 1263 @Override 1264 public void resourceChanged(IResourceChangeEvent event) { 1265 assertEquals("1.0", IResourceChangeEvent.POST_CHANGE, event.getType()); 1266 done = true; 1267 } 1268 } 1269 class Listener2 extends Listener1 implements IResourceChangeListener { 1270 @Override 1271 public void resourceChanged(IResourceChangeEvent event) { 1272 assertEquals("2.0", IResourceChangeEvent.POST_BUILD, event.getType()); 1273 done = true; 1274 } 1275 } 1276 Listener1 listener1 = new Listener1(); 1277 Listener2 listener2 = new Listener2(); 1278 getWorkspace().addResourceChangeListener(listener1, IResourceChangeEvent.POST_CHANGE); 1279 getWorkspace().addResourceChangeListener(listener2, IResourceChangeEvent.POST_BUILD); 1280 try { 1281 try { 1282 project1.touch(getMonitor()); 1283 } catch (CoreException e) { 1284 handleCoreException(e); 1285 } 1286 int i = 0; 1287 while (!(listener1.done && listener2.done)) { 1288 //timeout if the listeners are never called 1289 assertTrue("3.0", ++i < 600); 1290 try { 1291 Thread.sleep(100); 1292 } catch (InterruptedException e1) { 1293 } 1294 } 1295 } finally { 1296 getWorkspace().removeResourceChangeListener(listener1); 1297 getWorkspace().removeResourceChangeListener(listener2); 1298 } 1299 } 1300 testProjectDescriptionComment()1301 public void testProjectDescriptionComment() { 1302 try { 1303 /* change file1's contents */ 1304 verifier.addExpectedChange(project1, IResourceDelta.CHANGED, IResourceDelta.DESCRIPTION); 1305 verifier.addExpectedChange(project1MetaData, IResourceDelta.CHANGED, IResourceDelta.CONTENT); 1306 IProjectDescription description = project1.getDescription(); 1307 description.setComment("new comment"); 1308 project1.setDescription(description, IResource.NONE, getMonitor()); 1309 assertDelta(); 1310 } catch (CoreException e) { 1311 handleCoreException(e); 1312 } 1313 } 1314 testProjectDescriptionDynamicRefs()1315 public void testProjectDescriptionDynamicRefs() { 1316 try { 1317 /* change file1's contents */ 1318 verifier.addExpectedChange(project1, IResourceDelta.CHANGED, IResourceDelta.DESCRIPTION); 1319 IProjectDescription description = project1.getDescription(); 1320 description.setDynamicReferences(new IProject[] {project2}); 1321 project1.setDescription(description, IResource.NONE, getMonitor()); 1322 assertDelta(); 1323 } catch (CoreException e) { 1324 handleCoreException(e); 1325 } 1326 } 1327 testProjectDescriptionNatures()1328 public void testProjectDescriptionNatures() { 1329 try { 1330 /* change file1's contents */ 1331 verifier.addExpectedChange(project1, IResourceDelta.CHANGED, IResourceDelta.DESCRIPTION); 1332 verifier.addExpectedChange(project1MetaData, IResourceDelta.CHANGED, IResourceDelta.CONTENT); 1333 IProjectDescription description = project1.getDescription(); 1334 description.setNatureIds(new String[] {NATURE_SIMPLE}); 1335 project1.setDescription(description, IResource.NONE, getMonitor()); 1336 assertDelta(); 1337 } catch (CoreException e) { 1338 handleCoreException(e); 1339 } 1340 } 1341 testProjectDescriptionStaticRefs()1342 public void testProjectDescriptionStaticRefs() { 1343 try { 1344 /* change file1's contents */ 1345 verifier.addExpectedChange(project1, IResourceDelta.CHANGED, IResourceDelta.DESCRIPTION); 1346 verifier.addExpectedChange(project1MetaData, IResourceDelta.CHANGED, IResourceDelta.CONTENT); 1347 IProjectDescription description = project1.getDescription(); 1348 description.setReferencedProjects(new IProject[] {project2}); 1349 project1.setDescription(description, IResource.NONE, getMonitor()); 1350 assertDelta(); 1351 } catch (CoreException e) { 1352 handleCoreException(e); 1353 } 1354 } 1355 testRemoveFile()1356 public void testRemoveFile() { 1357 try { 1358 verifier.addExpectedChange(file1, IResourceDelta.REMOVED, 0); 1359 file1.delete(true, getMonitor()); 1360 assertDelta(); 1361 } catch (CoreException e) { 1362 handleCoreException(e); 1363 } 1364 } 1365 testRemoveFileAndFolder()1366 public void testRemoveFileAndFolder() { 1367 try { 1368 verifier.addExpectedChange(folder1, IResourceDelta.REMOVED, 0); 1369 verifier.addExpectedChange(file1, IResourceDelta.REMOVED, 0); 1370 folder1.delete(true, getMonitor()); 1371 assertDelta(); 1372 } catch (CoreException e) { 1373 handleCoreException(e); 1374 } 1375 } 1376 testReplaceFile()1377 public void testReplaceFile() { 1378 try { 1379 /* change file1's contents */ 1380 verifier.addExpectedChange(file1, IResourceDelta.CHANGED, IResourceDelta.REPLACED | IResourceDelta.CONTENT); 1381 getWorkspace().run((IWorkspaceRunnable) m -> { 1382 m.beginTask("Deleting and Creating", 100); 1383 try { 1384 file1.delete(true, SubMonitor.convert(m, 50)); 1385 file1.create(getRandomContents(), true, SubMonitor.convert(m, 50)); 1386 } finally { 1387 m.done(); 1388 } 1389 }, getMonitor()); 1390 assertDelta(); 1391 } catch (CoreException e) { 1392 handleCoreException(e); 1393 } 1394 } 1395 testReplaceFolderWithFolder()1396 public void testReplaceFolderWithFolder() { 1397 try { 1398 folder2 = project1.getFolder("Folder2"); 1399 folder3 = project1.getFolder("Folder3"); 1400 verifier.reset(); 1401 getWorkspace().run((IWorkspaceRunnable) m -> { 1402 file1.delete(false, null); 1403 folder2.create(false, true, null); 1404 }, null); 1405 verifier.reset(); 1406 verifier.addExpectedChange(folder1, IResourceDelta.REMOVED, IResourceDelta.MOVED_TO, null, folder2.getFullPath()); 1407 int flags = IResourceDelta.MOVED_FROM | IResourceDelta.MOVED_TO | IResourceDelta.REPLACED | IResourceDelta.CONTENT; 1408 verifier.addExpectedChange(folder2, IResourceDelta.CHANGED, flags, folder1.getFullPath(), folder3.getFullPath()); 1409 verifier.addExpectedChange(folder3, IResourceDelta.ADDED, IResourceDelta.MOVED_FROM, folder2.getFullPath(), null); 1410 getWorkspace().run((IWorkspaceRunnable) m -> { 1411 m.beginTask("replace folder with folder", 100); 1412 try { 1413 folder2.move(folder3.getFullPath(), false, null); 1414 folder1.move(folder2.getFullPath(), false, null); 1415 } finally { 1416 m.done(); 1417 } 1418 }, getMonitor()); 1419 assertDelta(); 1420 } catch (CoreException e) { 1421 handleCoreException(e); 1422 } 1423 } 1424 testSetLocal()1425 public void testSetLocal() { 1426 try { 1427 verifier.reset(); 1428 //set local on a file that is already local -- should be no change 1429 file1.setLocal(true, IResource.DEPTH_INFINITE, getMonitor()); 1430 assertTrue("Unexpected notification on no change", !verifier.hasBeenNotified()); 1431 //set non-local, still shouldn't appear in delta 1432 verifier.reset(); 1433 file1.setLocal(false, IResource.DEPTH_INFINITE, getMonitor()); 1434 assertTrue("Unexpected notification on no change", !verifier.hasBeenNotified()); 1435 } catch (CoreException e) { 1436 handleCoreException(e); 1437 } 1438 } 1439 testSwapFiles()1440 public void testSwapFiles() { 1441 try { 1442 file1 = project1.getFile("File1"); 1443 file2 = project1.getFile("File2"); 1444 file3 = project1.getFile("File3"); 1445 verifier.reset(); 1446 getWorkspace().run((IWorkspaceRunnable) m -> { 1447 file1.create(new ByteArrayInputStream(new byte[] {65}), false, null); 1448 file2.create(new ByteArrayInputStream(new byte[] {67}), false, null); 1449 }, null); 1450 verifier.reset(); 1451 final int flags = IResourceDelta.MOVED_FROM | IResourceDelta.MOVED_TO | IResourceDelta.REPLACED | IResourceDelta.CONTENT; 1452 verifier.addExpectedChange(file1, IResourceDelta.CHANGED, flags, file2.getFullPath(), file2.getFullPath()); 1453 verifier.addExpectedChange(file2, IResourceDelta.CHANGED, flags, file1.getFullPath(), file1.getFullPath()); 1454 getWorkspace().run((IWorkspaceRunnable) m -> { 1455 m.beginTask("swap files", 100); 1456 try { 1457 file1.move(file3.getFullPath(), false, null); 1458 file2.move(file1.getFullPath(), false, null); 1459 file3.move(file2.getFullPath(), false, null); 1460 } finally { 1461 m.done(); 1462 } 1463 }, getMonitor()); 1464 assertDelta(); 1465 } catch (CoreException e) { 1466 handleCoreException(e); 1467 } 1468 } 1469 testSwapFolders()1470 public void testSwapFolders() { 1471 try { 1472 verifier.reset(); 1473 getWorkspace().run((IWorkspaceRunnable) m -> { 1474 folder2 = project1.getFolder("Folder2"); 1475 folder3 = project1.getFolder("Folder3"); 1476 file1.delete(false, null); 1477 folder2.create(false, true, null); 1478 }, null); 1479 verifier.reset(); 1480 final int flags = IResourceDelta.MOVED_FROM | IResourceDelta.MOVED_TO | IResourceDelta.REPLACED | IResourceDelta.CONTENT; 1481 verifier.addExpectedChange(folder1, IResourceDelta.CHANGED, flags, folder2.getFullPath(), folder2.getFullPath()); 1482 verifier.addExpectedChange(folder2, IResourceDelta.CHANGED, flags, folder1.getFullPath(), folder1.getFullPath()); 1483 getWorkspace().run((IWorkspaceRunnable) m -> { 1484 m.beginTask("swap folders", 100); 1485 try { 1486 folder1.move(folder3.getFullPath(), false, null); 1487 folder2.move(folder1.getFullPath(), false, null); 1488 folder3.move(folder2.getFullPath(), false, null); 1489 } finally { 1490 m.done(); 1491 } 1492 }, getMonitor()); 1493 assertDelta(); 1494 } catch (CoreException e) { 1495 handleCoreException(e); 1496 } 1497 } 1498 1499 /** 1500 * Asserts that the delta is correct for changes to team private members. 1501 */ testTeamPrivateChanges()1502 public void testTeamPrivateChanges() { 1503 IWorkspace workspace = getWorkspace(); 1504 final IFolder teamPrivateFolder = project1.getFolder("TeamPrivateFolder"); 1505 final IFile teamPrivateFile = folder1.getFile("TeamPrivateFile"); 1506 try { 1507 //create a team private folder 1508 verifier.reset(); 1509 verifier.addExpectedChange(teamPrivateFolder, IResourceDelta.ADDED, 0); 1510 workspace.run((IWorkspaceRunnable) monitor -> { 1511 teamPrivateFolder.create(true, true, getMonitor()); 1512 teamPrivateFolder.setTeamPrivateMember(true); 1513 }, getMonitor()); 1514 assertDelta(); 1515 verifier.reset(); 1516 //create children in team private folder 1517 IFile fileInFolder = teamPrivateFolder.getFile("FileInPrivateFolder"); 1518 verifier.addExpectedChange(fileInFolder, IResourceDelta.ADDED, 0); 1519 fileInFolder.create(getRandomContents(), true, getMonitor()); 1520 assertDelta(); 1521 verifier.reset(); 1522 //modify children in team private folder 1523 verifier.addExpectedChange(fileInFolder, IResourceDelta.CHANGED, IResourceDelta.CONTENT); 1524 fileInFolder.setContents(getRandomContents(), IResource.NONE, getMonitor()); 1525 assertDelta(); 1526 verifier.reset(); 1527 //delete children in team private folder 1528 verifier.addExpectedChange(fileInFolder, IResourceDelta.REMOVED, 0); 1529 fileInFolder.delete(IResource.NONE, getMonitor()); 1530 assertDelta(); 1531 verifier.reset(); 1532 //delete team private folder and change some other file 1533 verifier.addExpectedChange(teamPrivateFolder, IResourceDelta.REMOVED, 0); 1534 verifier.addExpectedChange(file1, IResourceDelta.CHANGED, IResourceDelta.CONTENT); 1535 workspace.run((IWorkspaceRunnable) monitor -> { 1536 teamPrivateFolder.delete(IResource.NONE, getMonitor()); 1537 file1.setContents(getRandomContents(), IResource.NONE, getMonitor()); 1538 }, getMonitor()); 1539 assertDelta(); 1540 verifier.reset(); 1541 //create team private file 1542 verifier.addExpectedChange(teamPrivateFile, IResourceDelta.ADDED, 0); 1543 workspace.run((IWorkspaceRunnable) monitor -> { 1544 teamPrivateFile.create(getRandomContents(), true, getMonitor()); 1545 teamPrivateFile.setTeamPrivateMember(true); 1546 }, getMonitor()); 1547 assertDelta(); 1548 verifier.reset(); 1549 //modify team private file 1550 verifier.addExpectedChange(teamPrivateFile, IResourceDelta.CHANGED, IResourceDelta.CONTENT); 1551 teamPrivateFile.setContents(getRandomContents(), IResource.NONE, getMonitor()); 1552 assertDelta(); 1553 verifier.reset(); 1554 //delete team private file 1555 verifier.addExpectedChange(teamPrivateFile, IResourceDelta.REMOVED, 0); 1556 teamPrivateFile.delete(IResource.NONE, getMonitor()); 1557 assertDelta(); 1558 verifier.reset(); 1559 } catch (CoreException e) { 1560 handleCoreException(e); 1561 } 1562 } 1563 testTwoFileChanges()1564 public void testTwoFileChanges() { 1565 try { 1566 verifier.addExpectedChange(file1, IResourceDelta.CHANGED, IResourceDelta.CONTENT); 1567 verifier.addExpectedChange(file2, IResourceDelta.ADDED, 0); 1568 getWorkspace().run((IWorkspaceRunnable) m -> { 1569 m.beginTask("setting contents and creating", 100); 1570 try { 1571 file1.setContents(getRandomContents(), true, false, SubMonitor.convert(m, 50)); 1572 file2.create(getRandomContents(), true, SubMonitor.convert(m, 50)); 1573 } finally { 1574 m.done(); 1575 } 1576 }, getMonitor()); 1577 assertDelta(); 1578 } catch (CoreException e) { 1579 handleCoreException(e); 1580 } 1581 } 1582 testRemoveAndCreateUnderlyingFileForLinkedResource()1583 public void testRemoveAndCreateUnderlyingFileForLinkedResource() { 1584 IPath path = getTempDir().addTrailingSeparator().append(getUniqueString()); 1585 try { 1586 try { 1587 path.toFile().createNewFile(); 1588 } catch (IOException e) { 1589 fail("1.0", e); 1590 } 1591 IFile linkedFile = project1.getFile(getUniqueString()); 1592 linkedFile.createLink(path, IResource.NONE, getMonitor()); 1593 1594 // check the delta when underlying file is removed 1595 verifier.addExpectedChange(linkedFile, IResourceDelta.CHANGED, IResourceDelta.LOCAL_CHANGED); 1596 path.toFile().delete(); 1597 project1.refreshLocal(IResource.DEPTH_INFINITE, getMonitor()); 1598 assertDelta(); 1599 1600 // check the delta when underlying file is recreated 1601 verifier.addExpectedChange(linkedFile, IResourceDelta.CHANGED, IResourceDelta.LOCAL_CHANGED | IResourceDelta.CONTENT); 1602 try { 1603 path.toFile().createNewFile(); 1604 } catch (IOException e) { 1605 fail("2.0", e); 1606 } 1607 project1.refreshLocal(IResource.DEPTH_INFINITE, getMonitor()); 1608 assertDelta(); 1609 } catch (CoreException e) { 1610 handleCoreException(e); 1611 } finally { 1612 if (path.toFile().exists()) { 1613 path.toFile().delete(); 1614 } 1615 } 1616 } 1617 testRemoveAndCreateUnderlyingFolderForLinkedResource()1618 public void testRemoveAndCreateUnderlyingFolderForLinkedResource() { 1619 IPath path = getTempDir().addTrailingSeparator().append(getUniqueString()); 1620 try { 1621 path.toFile().mkdir(); 1622 IFolder linkedFolder = project1.getFolder(getUniqueString()); 1623 linkedFolder.createLink(path, IResource.NONE, getMonitor()); 1624 1625 // check the delta when underlying folder is removed 1626 verifier.addExpectedChange(linkedFolder, IResourceDelta.CHANGED, IResourceDelta.LOCAL_CHANGED); 1627 path.toFile().delete(); 1628 project1.refreshLocal(IResource.DEPTH_INFINITE, getMonitor()); 1629 assertDelta(); 1630 1631 // check the delta when underlying folder is recreated 1632 verifier.addExpectedChange(linkedFolder, IResourceDelta.CHANGED, IResourceDelta.LOCAL_CHANGED); 1633 path.toFile().mkdir(); 1634 project1.refreshLocal(IResource.DEPTH_INFINITE, getMonitor()); 1635 assertDelta(); 1636 } catch (CoreException e) { 1637 handleCoreException(e); 1638 } finally { 1639 if (path.toFile().exists()) { 1640 path.toFile().delete(); 1641 } 1642 } 1643 } 1644 testBug228354()1645 public void testBug228354() { 1646 IPath path = getTempDir().addTrailingSeparator().append(getUniqueString()); 1647 try { 1648 path.toFile().mkdir(); 1649 IFolder linkedFolder = project1.getFolder(getUniqueString()); 1650 linkedFolder.createLink(path, IResource.NONE, getMonitor()); 1651 1652 IFolder regularFolder = project1.getFolder(getUniqueString()); 1653 regularFolder.create(true, true, getMonitor()); 1654 1655 // check the delta when underlying folder is removed 1656 verifier.addExpectedChange(regularFolder, IResourceDelta.REMOVED, 0); 1657 regularFolder.delete(true, getMonitor()); 1658 assertDelta(); 1659 } catch (CoreException e) { 1660 handleCoreException(e); 1661 } finally { 1662 if (path.toFile().exists()) { 1663 path.toFile().delete(); 1664 } 1665 } 1666 } 1667 }