/******************************************************************************* * Copyright (c) 2000, 2017 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * IBM Corporation - Initial API and implementation * tammo.freese@offis.de - tests for swapping files and folders ******************************************************************************/ package org.eclipse.core.tests.resources; import java.io.ByteArrayInputStream; import java.io.IOException; import junit.framework.Test; import junit.framework.TestSuite; import org.eclipse.core.internal.resources.Workspace; import org.eclipse.core.resources.*; import org.eclipse.core.runtime.*; import org.eclipse.core.runtime.jobs.Job; /** * Tests behavior of IResourceChangeListener, including validation * that correct deltas are received for all types of workspace changes. */ public class IResourceChangeListenerTest extends ResourceTest { class SimpleListener implements IResourceChangeListener { Object source; int trigger; @Override public void resourceChanged(IResourceChangeEvent event) { source = event.getSource(); trigger = event.getBuildKind(); } } protected static final String VERIFIER_NAME = "TestListener"; IFile file1; //below folder1 IFile file2; //below folder1 IFile file3; //below folder2 IFolder folder1; //below project2 IFolder folder2; //below folder1 IFolder folder3; //same as file1 /* some random resource handles */ IProject project1; IFile project1MetaData; IProject project2; IFile project2MetaData; ResourceDeltaVerifier verifier; public static Test suite() { // TestSuite suite = new TestSuite(); // suite.addTest(new IResourceChangeListenerTest("testMoveProject1")); // return suite; return new TestSuite(IResourceChangeListenerTest.class); } public IResourceChangeListenerTest() { super(); } public IResourceChangeListenerTest(String name) { super(name); } public void _testBenchMark_1GBYQEZ() { // start with a clean workspace getWorkspace().removeResourceChangeListener(verifier); try { getWorkspace().getRoot().delete(false, getMonitor()); } catch (CoreException e) { fail("0.0", e); } // create the listener IResourceChangeListener listener = new IResourceChangeListener() { public int fCounter; @Override public void resourceChanged(IResourceChangeEvent event) { try { System.out.println("Start"); for (int i = 0; i < 10; i++) { fCounter = 0; long start = System.currentTimeMillis(); IResourceDelta delta = event.getDelta(); delta.accept(delta2 -> { fCounter++; return true; }); long end = System.currentTimeMillis(); System.out.println(" Number of deltas: " + fCounter + ". Time needed: " + (end - start)); } System.out.println("End"); } catch (CoreException e) { fail("1.0", e); } } }; // add the listener getWorkspace().addResourceChangeListener(listener); // setup the test data IWorkspaceRunnable body = monitor -> { IProject project = getWorkspace().getRoot().getProject("Test"); IProjectDescription description = getWorkspace().newProjectDescription(project.getName()); IPath root = getWorkspace().getRoot().getLocation(); IPath contents = root.append("temp/testing"); description.setLocation(contents); project.create(description, getMonitor()); project.open(getMonitor()); project.refreshLocal(IResource.DEPTH_INFINITE, getMonitor()); }; try { getWorkspace().run(body, getMonitor()); } catch (CoreException e) { fail("2.0", e); } // touch all resources (so that they appear in the delta) body = monitor -> { IResourceVisitor visitor = resource -> { resource.touch(getMonitor()); return true; }; getWorkspace().getRoot().accept(visitor); }; try { getWorkspace().run(body, getMonitor()); } catch (CoreException e) { fail("3.0", e); } // un-register our listener getWorkspace().removeResourceChangeListener(listener); } /** * Tests that the builder is receiving an appropriate delta * * @see SortBuilderPlugin * @see SortBuilder */ public void assertDelta() { assertTrue(verifier.getMessage(), verifier.isDeltaValid()); } /** * Asserts that a manual traversal of the delta does not find the given * resources. */ void assertNotDeltaIncludes(String message, IResourceDelta delta, IResource[] resources) { try { IResource deltaResource = delta.getResource(); for (int i = 0; i < resources.length; i++) { assertTrue(message, !deltaResource.equals(resources[i])); } IResourceDelta[] children = delta.getAffectedChildren(); for (IResourceDelta element : children) { assertNotDeltaIncludes(message, element, resources); } } catch (RuntimeException e) { fail(message, e); } } /** * Asserts that a visitor traversal of the delta does not find the given * resources. */ void assertNotDeltaVisits(final String message, IResourceDelta delta, final IResource[] resources) { try { delta.accept(delta2 -> { IResource deltaResource = delta2.getResource(); for (int i = 0; i < resources.length; i++) { assertTrue(message, !deltaResource.equals(resources[i])); } return true; }); } catch (CoreException e) { fail(message, e); } catch (RuntimeException e) { fail(message, e); } } /** * Runs code to handle a core exception */ protected void handleCoreException(CoreException e) { fail("IResourceChangeListenerTest", e); } /** * Sets the workspace autobuilding to the desired value. */ protected void setAutoBuilding(boolean value) { IWorkspace workspace = getWorkspace(); if (workspace.isAutoBuilding() == value) { return; } IWorkspaceDescription desc = workspace.getDescription(); desc.setAutoBuilding(value); try { workspace.setDescription(desc); } catch (CoreException e) { fail("failed to set workspace description", e); } } /** * Sets up the fixture, for example, open a network connection. This method * is called before a test is executed. */ @Override protected void setUp() throws Exception { super.setUp(); // Create some resource handles project1 = getWorkspace().getRoot().getProject("Project" + 1); project2 = getWorkspace().getRoot().getProject("Project" + 2); folder1 = project1.getFolder("Folder" + 1); folder2 = folder1.getFolder("Folder" + 2); folder3 = folder1.getFolder("File" + 1); file1 = folder1.getFile("File" + 1); file2 = folder1.getFile("File" + 2); file3 = folder2.getFile("File" + 1); project1MetaData = project1.getFile(IProjectDescription.DESCRIPTION_FILE_NAME); project2MetaData = project2.getFile(IProjectDescription.DESCRIPTION_FILE_NAME); // Create and open a project, folder and file IWorkspaceRunnable body = monitor -> { project1.create(getMonitor()); project1.open(getMonitor()); folder1.create(true, true, getMonitor()); file1.create(getRandomContents(), true, getMonitor()); }; verifier = new ResourceDeltaVerifier(); getWorkspace().addResourceChangeListener(verifier, IResourceChangeEvent.POST_CHANGE); try { getWorkspace().run(body, getMonitor()); } catch (CoreException e) { fail("1.0", e); } //ensure all background jobs are done before we reset the delta verifier waitForBuild(); waitForRefresh(); verifier.reset(); } /** * Tears down the fixture, for example, close a network connection. This * method is called after a test is executed. */ @Override protected void tearDown() throws Exception { super.tearDown(); ensureDoesNotExistInWorkspace(getWorkspace().getRoot()); getWorkspace().removeResourceChangeListener(verifier); } /* * Create a resource change listener and register it for POST_BUILD * events. Ensure that you are able to modify the workspace tree. */ public void test_1GDK9OG() { // create the resource change listener IResourceChangeListener listener = event -> { try { IWorkspaceRunnable body = monitor -> { // modify the tree. IResourceDeltaVisitor visitor = delta -> { IResource resource = delta.getResource(); try { resource.touch(getMonitor()); } catch (RuntimeException e) { throw e; } resource.createMarker(IMarker.PROBLEM); return true; }; event.getDelta().accept(visitor); }; getWorkspace().run(body, getMonitor()); } catch (CoreException e) { fail("1.0", e); } }; // register the listener with the workspace. getWorkspace().addResourceChangeListener(listener, IResourceChangeEvent.POST_BUILD); try { IWorkspaceRunnable body = new IWorkspaceRunnable() { // cause a delta by touching all resources final IResourceVisitor visitor = resource -> { resource.touch(getMonitor()); return true; }; @Override public void run(IProgressMonitor monitor) throws CoreException { getWorkspace().getRoot().accept(visitor); } }; getWorkspace().run(body, getMonitor()); //wait for autobuild so POST_BUILD will fire try { Job.getJobManager().join(ResourcesPlugin.FAMILY_AUTO_BUILD, null); } catch (OperationCanceledException e) { //ignore } catch (InterruptedException e) { //ignore } } catch (CoreException e) { fail("2.0", e); } finally { // cleanup: ensure that the listener is removed getWorkspace().removeResourceChangeListener(listener); } } public void testAddAndRemoveFile() { try { verifier.reset(); getWorkspace().run((IWorkspaceRunnable) m -> { m.beginTask("Creating and deleting", 100); try { file2.create(getRandomContents(), true, SubMonitor.convert(m, 50)); file2.delete(true, SubMonitor.convert(m, 50)); } finally { m.done(); } }, getMonitor()); //should not have been verified since there was no change assertTrue("Unexpected notification on no change", !verifier.hasBeenNotified()); } catch (CoreException e) { handleCoreException(e); } } public void testAddAndRemoveFolder() { try { verifier.reset(); getWorkspace().run((IWorkspaceRunnable) m -> { m.beginTask("Creating and deleting", 100); try { folder2.create(true, true, SubMonitor.convert(m, 50)); folder2.delete(true, SubMonitor.convert(m, 50)); } finally { m.done(); } }, getMonitor()); //should not have been verified since there was no change assertTrue("Unexpected notification on no change", !verifier.hasBeenNotified()); } catch (CoreException e) { handleCoreException(e); } } public void testAddFile() { try { verifier.addExpectedChange(file2, IResourceDelta.ADDED, 0); file2.create(getRandomContents(), true, getMonitor()); assertDelta(); } catch (CoreException e) { handleCoreException(e); } } public void testAddFileAndFolder() { try { verifier.addExpectedChange(folder2, IResourceDelta.ADDED, 0); verifier.addExpectedChange(file3, IResourceDelta.ADDED, 0); getWorkspace().run((IWorkspaceRunnable) m -> { m.beginTask("Creating folder and file", 100); try { folder2.create(true, true, SubMonitor.convert(m, 50)); file3.create(getRandomContents(), true, SubMonitor.convert(m, 50)); } finally { m.done(); } }, getMonitor()); assertDelta(); } catch (CoreException e) { handleCoreException(e); } } public void testAddFolder() { try { verifier.addExpectedChange(folder2, IResourceDelta.ADDED, 0); folder2.create(true, true, getMonitor()); assertDelta(); } catch (CoreException e) { handleCoreException(e); } } public void testAddProject() { try { verifier.addExpectedChange(project2, IResourceDelta.ADDED, 0); verifier.addExpectedChange(project2MetaData, IResourceDelta.ADDED, 0); project2.create(getMonitor()); assertDelta(); } catch (CoreException e) { handleCoreException(e); } } /* * Create a resource change listener and register it for POST_CHANGE events. * Ensure that you are NOT able to modify the workspace tree. */ public void testBug45996() { // create the resource change listener IResourceChangeListener listener = event -> { boolean failed = false; try { IWorkspaceRunnable body = monitor -> { // modify the tree. IResourceDeltaVisitor visitor = delta -> { IResource resource = delta.getResource(); try { resource.touch(getMonitor()); } catch (RuntimeException e) { throw e; } resource.createMarker(IMarker.PROBLEM); return true; }; event.getDelta().accept(visitor); }; getWorkspace().run(body, getMonitor()); } catch (CoreException e) { //should fail failed = true; } assertTrue("1.0", failed); }; // register the listener with the workspace. getWorkspace().addResourceChangeListener(listener, IResourceChangeEvent.POST_CHANGE); try { IWorkspaceRunnable body = new IWorkspaceRunnable() { // cause a delta by touching all resources final IResourceVisitor visitor = resource -> { resource.touch(getMonitor()); return true; }; @Override public void run(IProgressMonitor monitor) throws CoreException { getWorkspace().getRoot().accept(visitor); } }; getWorkspace().run(body, getMonitor()); } catch (CoreException e) { fail("2.0", e); } finally { // cleanup: ensure that the listener is removed getWorkspace().removeResourceChangeListener(listener); } } public void testBuildKind() { SimpleListener preBuild = new SimpleListener(); SimpleListener postBuild = new SimpleListener(); SimpleListener postChange = new SimpleListener(); final IWorkspace workspace = getWorkspace(); try { setAutoBuilding(false); workspace.addResourceChangeListener(preBuild, IResourceChangeEvent.PRE_BUILD); workspace.addResourceChangeListener(postBuild, IResourceChangeEvent.POST_BUILD); workspace.addResourceChangeListener(postChange, IResourceChangeEvent.POST_CHANGE); final int[] triggers = new int[] {IncrementalProjectBuilder.INCREMENTAL_BUILD, IncrementalProjectBuilder.FULL_BUILD, IncrementalProjectBuilder.CLEAN_BUILD,}; for (int i = 0; i < triggers.length; i++) { final int trigger = triggers[i]; workspace.run((IWorkspaceRunnable) monitor -> { file1.touch(null); workspace.build(trigger, monitor); }, getMonitor()); assertEquals("1.0." + i, workspace, preBuild.source); assertEquals("1.1." + i, workspace, postBuild.source); assertEquals("1.2." + i, workspace, postChange.source); assertEquals("1.3." + i, trigger, preBuild.trigger); assertEquals("1.4." + i, trigger, postBuild.trigger); assertEquals("1.5." + i, 0, postChange.trigger); workspace.run((IWorkspaceRunnable) monitor -> { file1.touch(null); project1.build(trigger, getMonitor()); }, getMonitor()); assertEquals("2.0." + i, project1, preBuild.source); assertEquals("2.2." + i, project1, postBuild.source); assertEquals("2.2." + i, workspace, postChange.source); assertEquals("2.3." + i, trigger, preBuild.trigger); assertEquals("2.4." + i, trigger, postBuild.trigger); assertEquals("2.5." + i, 0, postChange.trigger); } //test autobuild trigger setAutoBuilding(true); file1.touch(null); waitForBuild(); int trigger = IncrementalProjectBuilder.AUTO_BUILD; assertEquals("1.0", workspace, preBuild.source); assertEquals("1.1", workspace, postBuild.source); assertEquals("1.2", workspace, postChange.source); assertEquals("1.3", trigger, preBuild.trigger); assertEquals("1.4", trigger, postBuild.trigger); assertEquals("1.5", 0, postChange.trigger); } catch (CoreException e) { fail("4.99", e); } finally { workspace.removeResourceChangeListener(preBuild); workspace.removeResourceChangeListener(postBuild); workspace.removeResourceChangeListener(postChange); setAutoBuilding(true); } } public void testChangeFile() { try { /* change file1's contents */ verifier.addExpectedChange(file1, IResourceDelta.CHANGED, IResourceDelta.CONTENT); file1.setContents(getRandomContents(), true, false, getMonitor()); assertDelta(); } catch (CoreException e) { handleCoreException(e); } } public void testChangeFileToFolder() { try { /* change file1 into a folder */ verifier.addExpectedChange(file1, IResourceDelta.CHANGED, IResourceDelta.CONTENT | IResourceDelta.TYPE | IResourceDelta.REPLACED); getWorkspace().run((IWorkspaceRunnable) m -> { m.beginTask("Deleting and Creating", 100); try { file1.delete(true, SubMonitor.convert(m, 50)); folder3.create(true, true, SubMonitor.convert(m, 50)); } finally { m.done(); } }, getMonitor()); assertDelta(); } catch (CoreException e) { handleCoreException(e); } } public void testChangeFolderToFile() { try { /* change to a folder */ verifier.reset(); getWorkspace().run((IWorkspaceRunnable) m -> { file1.delete(true, getMonitor()); folder3.create(true, true, getMonitor()); }, null); /* now change back to a file and verify */ verifier.addExpectedChange(file1, IResourceDelta.CHANGED, IResourceDelta.CONTENT | IResourceDelta.TYPE | IResourceDelta.REPLACED); getWorkspace().run((IWorkspaceRunnable) m -> { m.beginTask("Deleting and Creating", 100); try { folder3.delete(true, SubMonitor.convert(m, 50)); file1.create(getRandomContents(), true, SubMonitor.convert(m, 50)); } finally { m.done(); } }, getMonitor()); assertDelta(); } catch (CoreException e) { handleCoreException(e); } } public void testChangeProject() { try { verifier.reset(); getWorkspace().run((IWorkspaceRunnable) m -> { project2.create(getMonitor()); project2.open(getMonitor()); }, null); IProjectDescription desc = project2.getDescription(); desc.setReferencedProjects(new IProject[] {project1}); verifier.addExpectedChange(project2, IResourceDelta.CHANGED, IResourceDelta.DESCRIPTION); verifier.addExpectedChange(project2MetaData, IResourceDelta.CHANGED, IResourceDelta.CONTENT); project2.setDescription(desc, IResource.FORCE, getMonitor()); assertDelta(); } catch (CoreException e) { handleCoreException(e); } } public void testCopyChangeFile() { try { verifier.addExpectedChange(folder2, IResourceDelta.ADDED, 0); verifier.addExpectedChange(file3, IResourceDelta.ADDED, 0, null, null); getWorkspace().run((IWorkspaceRunnable) m -> { m.beginTask("Creating and moving", 150); try { folder2.create(true, true, SubMonitor.convert(m, 50)); file1.copy(file3.getFullPath(), true, SubMonitor.convert(m, 50)); file3.setContents(getRandomContents(), IResource.NONE, SubMonitor.convert(m, 50)); } finally { m.done(); } }, getMonitor()); assertDelta(); } catch (CoreException e) { handleCoreException(e); } } public void testCopyFile() { try { verifier.addExpectedChange(folder2, IResourceDelta.ADDED, 0); verifier.addExpectedChange(file3, IResourceDelta.ADDED, 0, null, null); getWorkspace().run((IWorkspaceRunnable) m -> { m.beginTask("Creating and moving", 100); try { folder2.create(true, true, SubMonitor.convert(m, 50)); file1.copy(file3.getFullPath(), true, SubMonitor.convert(m, 50)); } finally { m.done(); } }, getMonitor()); assertDelta(); } catch (CoreException e) { handleCoreException(e); } } public void testCloseOpenReplaceFile() { try { // FIXME: how to do this? //workspace.save(getMonitor()); //workspace.close(getMonitor()); //workspace.open(getMonitor()); verifier.reset(); getWorkspace().addResourceChangeListener(verifier); /* change file1's contents */ verifier.addExpectedChange(file1, IResourceDelta.CHANGED, IResourceDelta.REPLACED | IResourceDelta.CONTENT); getWorkspace().run((IWorkspaceRunnable) m -> { m.beginTask("Deleting and Creating", 100); try { file1.delete(true, SubMonitor.convert(m, 50)); file1.create(getRandomContents(), true, SubMonitor.convert(m, 50)); } finally { m.done(); } }, getMonitor()); assertDelta(); } catch (CoreException e) { handleCoreException(e); } } public void testDeleteInPostBuildListener() { // create the resource change listener IResourceChangeListener listener = event -> { try { event.getDelta().accept(delta -> { IResource resource = delta.getResource(); if (resource.getType() == IResource.FILE) { try { ((IFile) resource).delete(true, true, null); } catch (RuntimeException e) { throw e; } } return true; }); } catch (CoreException e) { fail("1.0", e); } }; // register the listener with the workspace. getWorkspace().addResourceChangeListener(listener, IResourceChangeEvent.POST_BUILD); try { getWorkspace().run((IWorkspaceRunnable) monitor -> getWorkspace().getRoot().accept(resource -> { resource.touch(getMonitor()); return true; }), getMonitor()); } catch (CoreException e) { fail("2.0", e); } finally { // cleanup: ensure that the listener is removed getWorkspace().removeResourceChangeListener(listener); } } /** * Tests deleting a file, then moving another file to that deleted location. * See bug 27527. */ public void testDeleteMoveFile() { try { verifier.reset(); file2.create(getRandomContents(), IResource.NONE, getMonitor()); verifier.reset(); int flags = IResourceDelta.REPLACED | IResourceDelta.MOVED_FROM | IResourceDelta.CONTENT; verifier.addExpectedChange(file1, IResourceDelta.CHANGED, flags, file2.getFullPath(), null); verifier.addExpectedChange(file2, IResourceDelta.REMOVED, IResourceDelta.MOVED_TO, null, file1.getFullPath()); getWorkspace().run((IWorkspaceRunnable) m -> { m.beginTask("deleting and moving", 100); try { file1.delete(IResource.NONE, SubMonitor.convert(m, 50)); file2.move(file1.getFullPath(), IResource.NONE, SubMonitor.convert(m, 50)); } finally { m.done(); } }, getMonitor()); assertDelta(); } catch (CoreException e) { handleCoreException(e); } } public void testDeleteProject() throws CoreException { //test that marker deltas are fired when projects are deleted verifier.reset(); final IMarker marker = project1.createMarker(IMarker.TASK); class Listener1 implements IResourceChangeListener { public boolean done = false; @Override public void resourceChanged(IResourceChangeEvent event) { done = true; IMarkerDelta[] deltas = event.findMarkerDeltas(IMarker.TASK, false); assertEquals("1.0", 1, deltas.length); assertEquals("1.1", marker.getId(), deltas[0].getId()); assertEquals("1.2", IResourceDelta.REMOVED, deltas[0].getKind()); synchronized (this) { notifyAll(); } } } Listener1 listener = new Listener1(); try { getWorkspace().addResourceChangeListener(listener, IResourceChangeEvent.POST_CHANGE); project1.delete(true, false, getMonitor()); synchronized (listener) { int i = 0; while (!listener.done) { try { listener.wait(1000); } catch (InterruptedException e) { } assertTrue("2.0", ++i < 60); } } } finally { getWorkspace().removeResourceChangeListener(listener); } } public void testDeleteFolderDuringRefresh() throws CoreException { project1 = getWorkspace().getRoot().getProject(getUniqueString()); project1.create(getMonitor()); project1.open(getMonitor()); project2 = getWorkspace().getRoot().getProject(getUniqueString()); project2.create(getMonitor()); project2.open(getMonitor()); assertTrue("1.0", project1.isOpen()); assertTrue("2.0", project2.isOpen()); final IFolder f = project1.getFolder(getUniqueString()); f.create(true, true, getMonitor()); // the listener checks if an attempt to modify the tree succeeds if made in a job // that belongs to FAMILY_MANUAL_REFRESH class Listener1 implements IResourceChangeListener { public boolean wasPerformed = false; @Override public void resourceChanged(IResourceChangeEvent event) { new Job("deleteFolder") { @Override public boolean belongsTo(Object family) { return family == ResourcesPlugin.FAMILY_MANUAL_REFRESH; } @Override protected IStatus run(IProgressMonitor monitor) { try { f.delete(true, getMonitor()); wasPerformed = true; } catch (Exception e) { fail("3.0", e); } return Status.OK_STATUS; } }.schedule(); } } Listener1 listener1 = new Listener1(); // perform a refresh to test the added listeners try { getWorkspace().addResourceChangeListener(listener1, IResourceChangeEvent.PRE_REFRESH); project2.refreshLocal(IResource.DEPTH_INFINITE, getMonitor()); Job.getJobManager().join(ResourcesPlugin.FAMILY_MANUAL_REFRESH, null); assertTrue("4.0", listener1.wasPerformed); assertDoesNotExistInWorkspace("5.0", f); } catch (InterruptedException e) { fail("6.0", e); } catch (CoreException e) { fail("7.0", e); } finally { getWorkspace().removeResourceChangeListener(listener1); } } public void testRefreshOtherProjectDuringRefresh() throws Exception { final IProject p = getWorkspace().getRoot().getProject(getUniqueString()); p.create(null); p.open(null); project1 = getWorkspace().getRoot().getProject(getUniqueString()); project1.create(null); project1.open(null); assertTrue("1.0", p.isOpen()); assertTrue("2.0", project1.isOpen()); // the listener checks if an attempt to modify the tree succeeds if made in a job // that belongs to FAMILY_MANUAL_REFRESH class Listener1 implements IResourceChangeListener { public boolean wasPerformed = false; @Override public void resourceChanged(final IResourceChangeEvent event) { new Job("refreshProject") { @Override public boolean belongsTo(Object family) { return family == ResourcesPlugin.FAMILY_MANUAL_REFRESH; } @Override protected IStatus run(IProgressMonitor monitor) { try { if (event.getResource() != p) { p.refreshLocal(IResource.DEPTH_INFINITE, null); } wasPerformed = true; } catch (Exception e) { fail("3.0", e); } return Status.OK_STATUS; } }.schedule(); } } Listener1 listener1 = new Listener1(); // the listener checks if an attempt to modify the tree in the refresh thread fails class Listener2 implements IResourceChangeListener { @Override public void resourceChanged(IResourceChangeEvent event) { try { if (event.getResource() != p) { p.refreshLocal(IResource.DEPTH_INFINITE, null); } fail("4.0"); } catch (Exception e) { // should fail } } } Listener2 listener2 = new Listener2(); // perform a refresh to test the added listeners try { getWorkspace().addResourceChangeListener(listener1, IResourceChangeEvent.PRE_REFRESH); getWorkspace().addResourceChangeListener(listener2, IResourceChangeEvent.PRE_REFRESH); project1.refreshLocal(IResource.DEPTH_INFINITE, getMonitor()); Job.getJobManager().join(ResourcesPlugin.FAMILY_MANUAL_REFRESH, null); assertTrue("5.0", listener1.wasPerformed); } catch (InterruptedException e) { fail("6.0", e); } catch (CoreException e) { fail("7.0", e); } finally { getWorkspace().removeResourceChangeListener(listener1); getWorkspace().removeResourceChangeListener(listener2); } } public void testPreRefreshNotification() throws Exception { final IWorkspaceRoot root = getWorkspace().getRoot(); project1 = root.getProject(getUniqueString()); project1.create(null); project1.open(null); assertTrue("1.0", project1.isOpen()); class Listener1 implements IResourceChangeListener { public boolean wasPerformed = false; public Object eventSource; public Object eventResource; @Override public void resourceChanged(final IResourceChangeEvent event) { wasPerformed = true; eventSource = event.getSource(); eventResource = event.getResource(); } } Listener1 listener1 = new Listener1(); // perform a refresh to test the added listeners try { getWorkspace().addResourceChangeListener(listener1, IResourceChangeEvent.PRE_REFRESH); root.refreshLocal(IResource.DEPTH_INFINITE, getMonitor()); Job.getJobManager().join(ResourcesPlugin.FAMILY_MANUAL_REFRESH, null); assertTrue("2.0", listener1.wasPerformed); assertEquals("3.0", getWorkspace(), listener1.eventSource); assertEquals("4.0", null, listener1.eventResource); project1.refreshLocal(IResource.DEPTH_INFINITE, getMonitor()); Job.getJobManager().join(ResourcesPlugin.FAMILY_MANUAL_REFRESH, null); assertTrue("5.0", listener1.wasPerformed); assertEquals("6.0", project1, listener1.eventSource); assertEquals("7.0", project1, listener1.eventResource); } catch (InterruptedException e) { fail("8.0", e); } catch (CoreException e) { fail("9.0", e); } finally { getWorkspace().removeResourceChangeListener(listener1); } } /** * Tests that phantom members don't show up in resource deltas when standard * traversal and visitor are used. */ public void testHiddenPhantomChanges() { final IWorkspace workspace = getWorkspace(); final IFolder phantomFolder = project1.getFolder("PhantomFolder"); final IFile phantomFile = folder1.getFile("PhantomFile"); final IResource[] phantomResources = new IResource[] {phantomFolder, phantomFile}; final QualifiedName partner = new QualifiedName("Test", "Infected"); IResourceChangeListener listener = event -> { //make sure the delta doesn't include the phantom members assertNotDeltaIncludes("1.0", event.getDelta(), phantomResources); //make sure a visitor does not find phantom members assertNotDeltaVisits("1.1", event.getDelta(), phantomResources); }; workspace.addResourceChangeListener(listener); workspace.getSynchronizer().add(partner); ensureDoesNotExistInWorkspace(phantomResources); try { //create a phantom folder workspace.run((IWorkspaceRunnable) monitor -> workspace.getSynchronizer().setSyncInfo(partner, phantomFolder, new byte[] {1}), getMonitor()); //create children in phantom folder IFile fileInFolder = phantomFolder.getFile("FileInPrivateFolder"); workspace.getSynchronizer().setSyncInfo(partner, fileInFolder, new byte[] {1}); //modify children in phantom folder workspace.getSynchronizer().setSyncInfo(partner, fileInFolder, new byte[] {2}); //delete children in phantom folder workspace.getSynchronizer().flushSyncInfo(partner, fileInFolder, IResource.DEPTH_INFINITE); //delete phantom folder and change some other file workspace.run((IWorkspaceRunnable) monitor -> { phantomFolder.delete(IResource.NONE, getMonitor()); file1.setContents(getRandomContents(), IResource.NONE, getMonitor()); }, getMonitor()); //create phantom file workspace.run((IWorkspaceRunnable) monitor -> workspace.getSynchronizer().setSyncInfo(partner, phantomFile, new byte[] {2}), getMonitor()); //modify phantom file workspace.getSynchronizer().setSyncInfo(partner, phantomFile, new byte[] {3}); //delete phantom file workspace.getSynchronizer().flushSyncInfo(partner, phantomFile, IResource.DEPTH_INFINITE); } catch (CoreException e) { handleCoreException(e); } finally { workspace.removeResourceChangeListener(listener); } } /** * Tests that team private members don't show up in resource deltas when * standard traversal and visitor are used. */ public void testHiddenTeamPrivateChanges() { IWorkspace workspace = getWorkspace(); final IFolder teamPrivateFolder = project1.getFolder("TeamPrivateFolder"); final IFile teamPrivateFile = folder1.getFile("TeamPrivateFile"); final IResource[] privateResources = new IResource[] {teamPrivateFolder, teamPrivateFile}; IResourceChangeListener listener = event -> { //make sure the delta doesn't include the team private members assertNotDeltaIncludes("1.0", event.getDelta(), privateResources); //make sure a visitor does not find team private members assertNotDeltaVisits("1.1", event.getDelta(), privateResources); }; workspace.addResourceChangeListener(listener); try { //create a team private folder workspace.run((IWorkspaceRunnable) monitor -> { teamPrivateFolder.create(true, true, getMonitor()); teamPrivateFolder.setTeamPrivateMember(true); }, getMonitor()); //create children in team private folder IFile fileInFolder = teamPrivateFolder.getFile("FileInPrivateFolder"); fileInFolder.create(getRandomContents(), true, getMonitor()); //modify children in team private folder fileInFolder.setContents(getRandomContents(), IResource.NONE, getMonitor()); //delete children in team private folder fileInFolder.delete(IResource.NONE, getMonitor()); //delete team private folder and change some other file workspace.run((IWorkspaceRunnable) monitor -> { teamPrivateFolder.delete(IResource.NONE, getMonitor()); file1.setContents(getRandomContents(), IResource.NONE, getMonitor()); }, getMonitor()); //create team private file workspace.run((IWorkspaceRunnable) monitor -> { teamPrivateFile.create(getRandomContents(), true, getMonitor()); teamPrivateFile.setTeamPrivateMember(true); }, getMonitor()); //modify team private file teamPrivateFile.setContents(getRandomContents(), IResource.NONE, getMonitor()); //delete team private file teamPrivateFile.delete(IResource.NONE, getMonitor()); } catch (CoreException e) { handleCoreException(e); } finally { workspace.removeResourceChangeListener(listener); } } public void testModifyMoveFile() { try { verifier.addExpectedChange(folder2, IResourceDelta.ADDED, 0); verifier.addExpectedChange(file1, IResourceDelta.REMOVED, IResourceDelta.MOVED_TO, null, file3.getFullPath()); verifier.addExpectedChange(file3, IResourceDelta.ADDED, IResourceDelta.MOVED_FROM | IResourceDelta.CONTENT, file1.getFullPath(), null); getWorkspace().run((IWorkspaceRunnable) m -> { m.beginTask("Creating and moving", 100); try { folder2.create(true, true, SubMonitor.convert(m, 50)); file1.setContents(getRandomContents(), IResource.NONE, getMonitor()); file1.move(file3.getFullPath(), true, SubMonitor.convert(m, 50)); } finally { m.done(); } }, getMonitor()); assertDelta(); } catch (CoreException e) { handleCoreException(e); } } public void testMoveFile() { try { verifier.addExpectedChange(folder2, IResourceDelta.ADDED, 0); verifier.addExpectedChange(file1, IResourceDelta.REMOVED, IResourceDelta.MOVED_TO, null, file3.getFullPath()); verifier.addExpectedChange(file3, IResourceDelta.ADDED, IResourceDelta.MOVED_FROM, file1.getFullPath(), null); getWorkspace().run((IWorkspaceRunnable) m -> { m.beginTask("Creating and moving", 100); try { folder2.create(true, true, SubMonitor.convert(m, 50)); file1.move(file3.getFullPath(), true, SubMonitor.convert(m, 50)); } finally { m.done(); } }, getMonitor()); assertDelta(); } catch (CoreException e) { handleCoreException(e); } } public void testMoveFileAddMarker() { try { verifier.addExpectedChange(folder2, IResourceDelta.ADDED, 0); verifier.addExpectedChange(file1, IResourceDelta.REMOVED, IResourceDelta.MOVED_TO, null, file3.getFullPath()); verifier.addExpectedChange(file3, IResourceDelta.ADDED, IResourceDelta.MOVED_FROM | IResourceDelta.MARKERS, file1.getFullPath(), null); getWorkspace().run((IWorkspaceRunnable) m -> { m.beginTask("Creating and moving", 100); try { folder2.create(true, true, SubMonitor.convert(m, 50)); file1.move(file3.getFullPath(), true, SubMonitor.convert(m, 50)); file3.createMarker(IMarker.TASK); } finally { m.done(); } }, getMonitor()); assertDelta(); } catch (CoreException e) { handleCoreException(e); } } /** * Regression test for bug 42514 */ public void testMoveFileDeleteFolder() { try { //file2 moved to file1, and colliding folder3 is deleted file1.delete(IResource.NONE, null); file2.create(getRandomContents(), IResource.NONE, null); folder3.create(IResource.NONE, true, null); verifier.reset(); verifier.addExpectedChange(file2, IResourceDelta.REMOVED, IResourceDelta.MOVED_TO, null, file1.getFullPath()); int flags = IResourceDelta.MOVED_FROM | IResourceDelta.REPLACED | IResourceDelta.TYPE | IResourceDelta.CONTENT; verifier.addExpectedChange(file1, IResourceDelta.CHANGED, flags, file2.getFullPath(), null); getWorkspace().run((IWorkspaceRunnable) m -> { m.beginTask("Deleting and moving", 100); try { folder3.delete(IResource.FORCE, SubMonitor.convert(m, 50)); file2.move(file1.getFullPath(), true, SubMonitor.convert(m, 50)); } finally { m.done(); } }, getMonitor()); assertDelta(); } catch (CoreException e) { handleCoreException(e); } } public void testMoveFileDeleteSourceParent() { try { file1.delete(IResource.NONE, null); create(file3, true); verifier.reset(); verifier.addExpectedChange(folder2, IResourceDelta.REMOVED, 0, null, null); verifier.addExpectedChange(file1, IResourceDelta.ADDED, IResourceDelta.MOVED_FROM, file3.getFullPath(), null); verifier.addExpectedChange(file3, IResourceDelta.REMOVED, IResourceDelta.MOVED_TO, null, file1.getFullPath()); getWorkspace().run((IWorkspaceRunnable) m -> { m.beginTask("Creating and moving", 100); try { file3.move(file1.getFullPath(), true, SubMonitor.convert(m, 50)); folder2.delete(IResource.NONE, SubMonitor.convert(m, 50)); } finally { m.done(); } }, getMonitor()); assertDelta(); } catch (CoreException e) { handleCoreException(e); } } public void testMoveModifyFile() { try { verifier.addExpectedChange(folder2, IResourceDelta.ADDED, 0); verifier.addExpectedChange(file1, IResourceDelta.REMOVED, IResourceDelta.MOVED_TO, null, file3.getFullPath()); verifier.addExpectedChange(file3, IResourceDelta.ADDED, IResourceDelta.MOVED_FROM | IResourceDelta.CONTENT, file1.getFullPath(), null); getWorkspace().run((IWorkspaceRunnable) m -> { m.beginTask("Creating and moving", 100); try { folder2.create(true, true, SubMonitor.convert(m, 50)); file1.move(file3.getFullPath(), true, SubMonitor.convert(m, 50)); file3.setContents(getRandomContents(), IResource.NONE, getMonitor()); } finally { m.done(); } }, getMonitor()); assertDelta(); } catch (CoreException e) { handleCoreException(e); } } public void testMoveMoveFile() { file2 = project1.getFile("File2"); file3 = project1.getFile("File3"); try { verifier.addExpectedChange(file1, IResourceDelta.REMOVED, IResourceDelta.MOVED_TO, null, file3.getFullPath()); verifier.addExpectedChange(file3, IResourceDelta.ADDED, IResourceDelta.MOVED_FROM, file1.getFullPath(), null); getWorkspace().run((IWorkspaceRunnable) m -> { m.beginTask("moving and moving file", 100); try { file1.move(file2.getFullPath(), false, null); file2.move(file3.getFullPath(), false, null); } finally { m.done(); } }, getMonitor()); assertDelta(); } catch (CoreException e) { handleCoreException(e); } } public void testMoveMoveFolder() { folder2 = project1.getFolder("Folder2"); folder3 = project1.getFolder("Folder3"); file3 = folder3.getFile(file1.getName()); try { verifier.addExpectedChange(folder1, IResourceDelta.REMOVED, IResourceDelta.MOVED_TO, null, folder3.getFullPath()); verifier.addExpectedChange(folder3, IResourceDelta.ADDED, IResourceDelta.MOVED_FROM, folder1.getFullPath(), null); verifier.addExpectedChange(file1, IResourceDelta.REMOVED, IResourceDelta.MOVED_TO, null, file3.getFullPath()); verifier.addExpectedChange(file3, IResourceDelta.ADDED, IResourceDelta.MOVED_FROM, file1.getFullPath(), null); getWorkspace().run((IWorkspaceRunnable) m -> { m.beginTask("moving and moving folder", 100); try { folder1.move(folder2.getFullPath(), false, null); folder2.move(folder3.getFullPath(), false, null); } finally { m.done(); } }, getMonitor()); assertDelta(); } catch (CoreException e) { handleCoreException(e); } } /** * Move a project via rename. Note that the DESCRIPTION flag should be set * in the delta for the destination only. */ public void testMoveProject1() { try { verifier.reset(); verifier.addExpectedChange(project1, IResourceDelta.REMOVED, IResourceDelta.MOVED_TO, null, project2.getFullPath()); verifier.addExpectedChange(project1.getFile(".project"), IResourceDelta.REMOVED, IResourceDelta.MOVED_TO, null, project2.getFile(".project").getFullPath()); verifier.addExpectedChange(folder1, IResourceDelta.REMOVED, IResourceDelta.MOVED_TO, null, project2.getFolder(folder1.getProjectRelativePath()).getFullPath()); verifier.addExpectedChange(file1, IResourceDelta.REMOVED, IResourceDelta.MOVED_TO, null, project2.getFile(file1.getProjectRelativePath()).getFullPath()); verifier.addExpectedChange(project2, IResourceDelta.ADDED, IResourceDelta.OPEN | IResourceDelta.DESCRIPTION | IResourceDelta.MOVED_FROM, project1.getFullPath(), null); verifier.addExpectedChange(project2.getFile(".project"), IResourceDelta.ADDED, IResourceDelta.CONTENT | IResourceDelta.MOVED_FROM, project1.getFile(".project").getFullPath(), null); verifier.addExpectedChange(project2.getFolder(folder1.getProjectRelativePath()), IResourceDelta.ADDED, IResourceDelta.MOVED_FROM, folder1.getFullPath(), null); verifier.addExpectedChange(project2.getFile(file1.getProjectRelativePath()), IResourceDelta.ADDED, IResourceDelta.MOVED_FROM, file1.getFullPath(), null); getWorkspace().run((IWorkspaceRunnable) m -> { m.beginTask("Creating and moving", 100); try { project1.move(project2.getFullPath(), IResource.NONE, SubMonitor.convert(m, 50)); } finally { m.done(); } }, getMonitor()); assertDelta(); } catch (CoreException e) { handleCoreException(e); } } /** * Move a project via a location change only. Note that the DESCRIPTION flag * should be set in the delta. */ public void testMoveProject2() { final IPath path = getRandomLocation(); try { verifier.addExpectedChange(project1, IResourceDelta.CHANGED, IResourceDelta.DESCRIPTION); getWorkspace().run((IWorkspaceRunnable) m -> { m.beginTask("Creating and moving", 100); try { IProjectDescription desc = project1.getDescription(); desc.setLocation(path); project1.move(desc, IResource.NONE, SubMonitor.convert(m, 50)); } finally { m.done(); } }, getMonitor()); assertDelta(); } catch (CoreException e) { handleCoreException(e); } finally { Workspace.clear(path.toFile()); } } public void testMulti() { class Listener1 implements IResourceChangeListener { public boolean done = false; @Override public void resourceChanged(IResourceChangeEvent event) { assertEquals("1.0", IResourceChangeEvent.POST_CHANGE, event.getType()); done = true; } } class Listener2 extends Listener1 implements IResourceChangeListener { @Override public void resourceChanged(IResourceChangeEvent event) { assertEquals("2.0", IResourceChangeEvent.POST_BUILD, event.getType()); done = true; } } Listener1 listener1 = new Listener1(); Listener2 listener2 = new Listener2(); getWorkspace().addResourceChangeListener(listener1, IResourceChangeEvent.POST_CHANGE); getWorkspace().addResourceChangeListener(listener2, IResourceChangeEvent.POST_BUILD); try { try { project1.touch(getMonitor()); } catch (CoreException e) { handleCoreException(e); } int i = 0; while (!(listener1.done && listener2.done)) { //timeout if the listeners are never called assertTrue("3.0", ++i < 600); try { Thread.sleep(100); } catch (InterruptedException e1) { } } } finally { getWorkspace().removeResourceChangeListener(listener1); getWorkspace().removeResourceChangeListener(listener2); } } public void testProjectDescriptionComment() { try { /* change file1's contents */ verifier.addExpectedChange(project1, IResourceDelta.CHANGED, IResourceDelta.DESCRIPTION); verifier.addExpectedChange(project1MetaData, IResourceDelta.CHANGED, IResourceDelta.CONTENT); IProjectDescription description = project1.getDescription(); description.setComment("new comment"); project1.setDescription(description, IResource.NONE, getMonitor()); assertDelta(); } catch (CoreException e) { handleCoreException(e); } } public void testProjectDescriptionDynamicRefs() { try { /* change file1's contents */ verifier.addExpectedChange(project1, IResourceDelta.CHANGED, IResourceDelta.DESCRIPTION); IProjectDescription description = project1.getDescription(); description.setDynamicReferences(new IProject[] {project2}); project1.setDescription(description, IResource.NONE, getMonitor()); assertDelta(); } catch (CoreException e) { handleCoreException(e); } } public void testProjectDescriptionNatures() { try { /* change file1's contents */ verifier.addExpectedChange(project1, IResourceDelta.CHANGED, IResourceDelta.DESCRIPTION); verifier.addExpectedChange(project1MetaData, IResourceDelta.CHANGED, IResourceDelta.CONTENT); IProjectDescription description = project1.getDescription(); description.setNatureIds(new String[] {NATURE_SIMPLE}); project1.setDescription(description, IResource.NONE, getMonitor()); assertDelta(); } catch (CoreException e) { handleCoreException(e); } } public void testProjectDescriptionStaticRefs() { try { /* change file1's contents */ verifier.addExpectedChange(project1, IResourceDelta.CHANGED, IResourceDelta.DESCRIPTION); verifier.addExpectedChange(project1MetaData, IResourceDelta.CHANGED, IResourceDelta.CONTENT); IProjectDescription description = project1.getDescription(); description.setReferencedProjects(new IProject[] {project2}); project1.setDescription(description, IResource.NONE, getMonitor()); assertDelta(); } catch (CoreException e) { handleCoreException(e); } } public void testRemoveFile() { try { verifier.addExpectedChange(file1, IResourceDelta.REMOVED, 0); file1.delete(true, getMonitor()); assertDelta(); } catch (CoreException e) { handleCoreException(e); } } public void testRemoveFileAndFolder() { try { verifier.addExpectedChange(folder1, IResourceDelta.REMOVED, 0); verifier.addExpectedChange(file1, IResourceDelta.REMOVED, 0); folder1.delete(true, getMonitor()); assertDelta(); } catch (CoreException e) { handleCoreException(e); } } public void testReplaceFile() { try { /* change file1's contents */ verifier.addExpectedChange(file1, IResourceDelta.CHANGED, IResourceDelta.REPLACED | IResourceDelta.CONTENT); getWorkspace().run((IWorkspaceRunnable) m -> { m.beginTask("Deleting and Creating", 100); try { file1.delete(true, SubMonitor.convert(m, 50)); file1.create(getRandomContents(), true, SubMonitor.convert(m, 50)); } finally { m.done(); } }, getMonitor()); assertDelta(); } catch (CoreException e) { handleCoreException(e); } } public void testReplaceFolderWithFolder() { try { folder2 = project1.getFolder("Folder2"); folder3 = project1.getFolder("Folder3"); verifier.reset(); getWorkspace().run((IWorkspaceRunnable) m -> { file1.delete(false, null); folder2.create(false, true, null); }, null); verifier.reset(); verifier.addExpectedChange(folder1, IResourceDelta.REMOVED, IResourceDelta.MOVED_TO, null, folder2.getFullPath()); int flags = IResourceDelta.MOVED_FROM | IResourceDelta.MOVED_TO | IResourceDelta.REPLACED | IResourceDelta.CONTENT; verifier.addExpectedChange(folder2, IResourceDelta.CHANGED, flags, folder1.getFullPath(), folder3.getFullPath()); verifier.addExpectedChange(folder3, IResourceDelta.ADDED, IResourceDelta.MOVED_FROM, folder2.getFullPath(), null); getWorkspace().run((IWorkspaceRunnable) m -> { m.beginTask("replace folder with folder", 100); try { folder2.move(folder3.getFullPath(), false, null); folder1.move(folder2.getFullPath(), false, null); } finally { m.done(); } }, getMonitor()); assertDelta(); } catch (CoreException e) { handleCoreException(e); } } public void testSetLocal() { try { verifier.reset(); //set local on a file that is already local -- should be no change file1.setLocal(true, IResource.DEPTH_INFINITE, getMonitor()); assertTrue("Unexpected notification on no change", !verifier.hasBeenNotified()); //set non-local, still shouldn't appear in delta verifier.reset(); file1.setLocal(false, IResource.DEPTH_INFINITE, getMonitor()); assertTrue("Unexpected notification on no change", !verifier.hasBeenNotified()); } catch (CoreException e) { handleCoreException(e); } } public void testSwapFiles() { try { file1 = project1.getFile("File1"); file2 = project1.getFile("File2"); file3 = project1.getFile("File3"); verifier.reset(); getWorkspace().run((IWorkspaceRunnable) m -> { file1.create(new ByteArrayInputStream(new byte[] {65}), false, null); file2.create(new ByteArrayInputStream(new byte[] {67}), false, null); }, null); verifier.reset(); final int flags = IResourceDelta.MOVED_FROM | IResourceDelta.MOVED_TO | IResourceDelta.REPLACED | IResourceDelta.CONTENT; verifier.addExpectedChange(file1, IResourceDelta.CHANGED, flags, file2.getFullPath(), file2.getFullPath()); verifier.addExpectedChange(file2, IResourceDelta.CHANGED, flags, file1.getFullPath(), file1.getFullPath()); getWorkspace().run((IWorkspaceRunnable) m -> { m.beginTask("swap files", 100); try { file1.move(file3.getFullPath(), false, null); file2.move(file1.getFullPath(), false, null); file3.move(file2.getFullPath(), false, null); } finally { m.done(); } }, getMonitor()); assertDelta(); } catch (CoreException e) { handleCoreException(e); } } public void testSwapFolders() { try { verifier.reset(); getWorkspace().run((IWorkspaceRunnable) m -> { folder2 = project1.getFolder("Folder2"); folder3 = project1.getFolder("Folder3"); file1.delete(false, null); folder2.create(false, true, null); }, null); verifier.reset(); final int flags = IResourceDelta.MOVED_FROM | IResourceDelta.MOVED_TO | IResourceDelta.REPLACED | IResourceDelta.CONTENT; verifier.addExpectedChange(folder1, IResourceDelta.CHANGED, flags, folder2.getFullPath(), folder2.getFullPath()); verifier.addExpectedChange(folder2, IResourceDelta.CHANGED, flags, folder1.getFullPath(), folder1.getFullPath()); getWorkspace().run((IWorkspaceRunnable) m -> { m.beginTask("swap folders", 100); try { folder1.move(folder3.getFullPath(), false, null); folder2.move(folder1.getFullPath(), false, null); folder3.move(folder2.getFullPath(), false, null); } finally { m.done(); } }, getMonitor()); assertDelta(); } catch (CoreException e) { handleCoreException(e); } } /** * Asserts that the delta is correct for changes to team private members. */ public void testTeamPrivateChanges() { IWorkspace workspace = getWorkspace(); final IFolder teamPrivateFolder = project1.getFolder("TeamPrivateFolder"); final IFile teamPrivateFile = folder1.getFile("TeamPrivateFile"); try { //create a team private folder verifier.reset(); verifier.addExpectedChange(teamPrivateFolder, IResourceDelta.ADDED, 0); workspace.run((IWorkspaceRunnable) monitor -> { teamPrivateFolder.create(true, true, getMonitor()); teamPrivateFolder.setTeamPrivateMember(true); }, getMonitor()); assertDelta(); verifier.reset(); //create children in team private folder IFile fileInFolder = teamPrivateFolder.getFile("FileInPrivateFolder"); verifier.addExpectedChange(fileInFolder, IResourceDelta.ADDED, 0); fileInFolder.create(getRandomContents(), true, getMonitor()); assertDelta(); verifier.reset(); //modify children in team private folder verifier.addExpectedChange(fileInFolder, IResourceDelta.CHANGED, IResourceDelta.CONTENT); fileInFolder.setContents(getRandomContents(), IResource.NONE, getMonitor()); assertDelta(); verifier.reset(); //delete children in team private folder verifier.addExpectedChange(fileInFolder, IResourceDelta.REMOVED, 0); fileInFolder.delete(IResource.NONE, getMonitor()); assertDelta(); verifier.reset(); //delete team private folder and change some other file verifier.addExpectedChange(teamPrivateFolder, IResourceDelta.REMOVED, 0); verifier.addExpectedChange(file1, IResourceDelta.CHANGED, IResourceDelta.CONTENT); workspace.run((IWorkspaceRunnable) monitor -> { teamPrivateFolder.delete(IResource.NONE, getMonitor()); file1.setContents(getRandomContents(), IResource.NONE, getMonitor()); }, getMonitor()); assertDelta(); verifier.reset(); //create team private file verifier.addExpectedChange(teamPrivateFile, IResourceDelta.ADDED, 0); workspace.run((IWorkspaceRunnable) monitor -> { teamPrivateFile.create(getRandomContents(), true, getMonitor()); teamPrivateFile.setTeamPrivateMember(true); }, getMonitor()); assertDelta(); verifier.reset(); //modify team private file verifier.addExpectedChange(teamPrivateFile, IResourceDelta.CHANGED, IResourceDelta.CONTENT); teamPrivateFile.setContents(getRandomContents(), IResource.NONE, getMonitor()); assertDelta(); verifier.reset(); //delete team private file verifier.addExpectedChange(teamPrivateFile, IResourceDelta.REMOVED, 0); teamPrivateFile.delete(IResource.NONE, getMonitor()); assertDelta(); verifier.reset(); } catch (CoreException e) { handleCoreException(e); } } public void testTwoFileChanges() { try { verifier.addExpectedChange(file1, IResourceDelta.CHANGED, IResourceDelta.CONTENT); verifier.addExpectedChange(file2, IResourceDelta.ADDED, 0); getWorkspace().run((IWorkspaceRunnable) m -> { m.beginTask("setting contents and creating", 100); try { file1.setContents(getRandomContents(), true, false, SubMonitor.convert(m, 50)); file2.create(getRandomContents(), true, SubMonitor.convert(m, 50)); } finally { m.done(); } }, getMonitor()); assertDelta(); } catch (CoreException e) { handleCoreException(e); } } public void testRemoveAndCreateUnderlyingFileForLinkedResource() { IPath path = getTempDir().addTrailingSeparator().append(getUniqueString()); try { try { path.toFile().createNewFile(); } catch (IOException e) { fail("1.0", e); } IFile linkedFile = project1.getFile(getUniqueString()); linkedFile.createLink(path, IResource.NONE, getMonitor()); // check the delta when underlying file is removed verifier.addExpectedChange(linkedFile, IResourceDelta.CHANGED, IResourceDelta.LOCAL_CHANGED); path.toFile().delete(); project1.refreshLocal(IResource.DEPTH_INFINITE, getMonitor()); assertDelta(); // check the delta when underlying file is recreated verifier.addExpectedChange(linkedFile, IResourceDelta.CHANGED, IResourceDelta.LOCAL_CHANGED | IResourceDelta.CONTENT); try { path.toFile().createNewFile(); } catch (IOException e) { fail("2.0", e); } project1.refreshLocal(IResource.DEPTH_INFINITE, getMonitor()); assertDelta(); } catch (CoreException e) { handleCoreException(e); } finally { if (path.toFile().exists()) { path.toFile().delete(); } } } public void testRemoveAndCreateUnderlyingFolderForLinkedResource() { IPath path = getTempDir().addTrailingSeparator().append(getUniqueString()); try { path.toFile().mkdir(); IFolder linkedFolder = project1.getFolder(getUniqueString()); linkedFolder.createLink(path, IResource.NONE, getMonitor()); // check the delta when underlying folder is removed verifier.addExpectedChange(linkedFolder, IResourceDelta.CHANGED, IResourceDelta.LOCAL_CHANGED); path.toFile().delete(); project1.refreshLocal(IResource.DEPTH_INFINITE, getMonitor()); assertDelta(); // check the delta when underlying folder is recreated verifier.addExpectedChange(linkedFolder, IResourceDelta.CHANGED, IResourceDelta.LOCAL_CHANGED); path.toFile().mkdir(); project1.refreshLocal(IResource.DEPTH_INFINITE, getMonitor()); assertDelta(); } catch (CoreException e) { handleCoreException(e); } finally { if (path.toFile().exists()) { path.toFile().delete(); } } } public void testBug228354() { IPath path = getTempDir().addTrailingSeparator().append(getUniqueString()); try { path.toFile().mkdir(); IFolder linkedFolder = project1.getFolder(getUniqueString()); linkedFolder.createLink(path, IResource.NONE, getMonitor()); IFolder regularFolder = project1.getFolder(getUniqueString()); regularFolder.create(true, true, getMonitor()); // check the delta when underlying folder is removed verifier.addExpectedChange(regularFolder, IResourceDelta.REMOVED, 0); regularFolder.delete(true, getMonitor()); assertDelta(); } catch (CoreException e) { handleCoreException(e); } finally { if (path.toFile().exists()) { path.toFile().delete(); } } } }