View | Details | Raw Unified | Return to bug 251370 | Differences between
and this patch

Collapse All | Expand All

(-)src/org/eclipse/core/tests/resources/LinkedResourceTest.java (+246 lines)
Lines 10-16 Link Here
10
 *******************************************************************************/
10
 *******************************************************************************/
11
package org.eclipse.core.tests.resources;
11
package org.eclipse.core.tests.resources;
12
12
13
import org.eclipse.core.runtime.jobs.Job;
14
13
import java.io.*;
15
import java.io.*;
16
import java.io.File;
14
import java.net.URI;
17
import java.net.URI;
15
import java.util.HashMap;
18
import java.util.HashMap;
16
import junit.framework.Test;
19
import junit.framework.Test;
Lines 1640-1643 Link Here
1640
		assertTrue("2.0", link.exists());
1643
		assertTrue("2.0", link.exists());
1641
		assertTrue("2.1", linkChild.exists());
1644
		assertTrue("2.1", linkChild.exists());
1642
	}
1645
	}
1646
1647
 	/**
1648
	 * Bug251370
1649
	 * Updating a .project file within a nested Project causes problems when the project is closed
1650
	 * and then reopened (having moved one of the linked resources)
1651
	 *
1652
	 * This test creates a linked resource between the inner project and outer project.
1653
	 * The first linked resource is relative to a path variable "ROOT"
1654
	 * The second is absolute.
1655
	 *
1656
	 * Overwrite the .project file externally (such that the file is out of sync.).
1657
	 * Problem occurs.
1658
	 */
1659
	public void testChangingLinksWithNestedProjects() {
1660
		// /ExistingProject/foo
1661
		final String sOverlappingProject = "foo";
1662
		final IFolder overlappingFolder = existingProject.getFolder(sOverlappingProject);
1663
		ensureExistsInFileSystem(overlappingFolder);
1664
1665
		// /foo -> /ExistingProject/foo
1666
		final IProject overlappingProject = getWorkspace().getRoot().getProject(sOverlappingProject);
1667
		IProjectDescription desc = getWorkspace().newProjectDescription(sOverlappingProject);
1668
		desc.setLocation(overlappingFolder.getLocation());
1669
		try {
1670
			overlappingProject.create(desc, getMonitor());
1671
			overlappingProject.open(getMonitor());
1672
			assertTrue("0.9",overlappingProject.exists());
1673
		} catch (CoreException e) {
1674
			fail("1.0");
1675
		}
1676
1677
		// Create a path variable for the workspace root
1678
		try {
1679
			IPath ROOT = getWorkspace().getRoot().getLocation();
1680
			getWorkspace().getPathVariableManager().setValue("ROOT", ROOT);
1681
		} catch (CoreException e) {
1682
			fail("1.5");
1683
		}
1684
1685
		// Two linked resource paths:
1686
		// 1) Uses path variable
1687
		IPath l1 = new Path("ROOT").append(existingFolderInExistingProject.getFullPath());
1688
		// 2) uses absolute path
1689
		IPath l2 = existingFolderInExistingProject.getLocation();
1690
1691
		// Refresh Workspace
1692
		try {
1693
			getWorkspace().getRoot().refreshLocal(IResource.DEPTH_INFINITE, getMonitor());
1694
		} catch (CoreException e) {
1695
			fail ("2.0");
1696
		}
1697
1698
		// Create a link to the folder in the existing project (using absolute path)
1699
		// /foo/linkedFolder -> /ExistingProject/existingFolderInExistingProject
1700
		IFolder linkedFolder = overlappingProject.getFolder("linkedFolder");
1701
		try {
1702
			linkedFolder.createLink(l1, IResource.REPLACE, getMonitor());
1703
			assertTrue("1.9",linkedFolder.exists());
1704
			// Back-up .project the file to .project1
1705
			overlappingProject.getFile(".project").copy(new Path(".project1"), true, getMonitor());
1706
		} catch (CoreException e) {
1707
			fail("3.0");
1708
		}
1709
1710
		// Change the variable to be relative to the ROOT variable
1711
		try {
1712
			linkedFolder.delete(true, getMonitor());
1713
			linkedFolder.createLink(l2, IResource.REPLACE, getMonitor());
1714
			assertTrue(linkedFolder.exists());
1715
			// Back-up .project the file to .project2
1716
			overlappingProject.getFile(".project").copy(new Path(".project2"), true, getMonitor());
1717
		} catch (CoreException e) {
1718
			fail("5.0");
1719
		}
1720
1721
		// Switch between the two version of the .project file
1722
		try {
1723
			overlappingProject.close(getMonitor());
1724
			copyFile(overlappingFolder.getFile(".project1").getLocation().toFile(),
1725
					overlappingFolder.getFile(".project").getLocation().toFile());
1726
			overlappingProject.open(getMonitor());
1727
			getWorkspace().getRoot().refreshLocal(IResource.DEPTH_INFINITE, getMonitor());
1728
		} catch (CoreException e) {
1729
			fail ("10.0");
1730
		}
1731
1732
		try {
1733
			overlappingProject.close(getMonitor());
1734
			copyFile(overlappingFolder.getFile(".project2").getLocation().toFile(),
1735
					overlappingFolder.getFile(".project").getLocation().toFile());
1736
			overlappingProject.open(getMonitor());
1737
			getWorkspace().getRoot().refreshLocal(IResource.DEPTH_INFINITE, getMonitor());
1738
		} catch (CoreException e) {
1739
			fail ("11.0");
1740
		}
1741
	}
1742
1743
	/**
1744
	 * Helper method to copy file from source to dest, ensuring that the modification
1745
	 * time has incremented
1746
	 * @param src
1747
	 * @param dst
1748
	 */
1749
	private void copyFile(File src, File dst) {
1750
		long initModificationTime = dst.lastModified();
1751
		FileInputStream in = null;
1752
		FileOutputStream out = null;
1753
		try {
1754
			in = new FileInputStream(src);
1755
			out = new FileOutputStream(dst);
1756
			byte[] buffer = new byte[8192];
1757
			int bytesRead;
1758
			while ((bytesRead = in.read(buffer)) != -1)
1759
				out.write(buffer, 0, bytesRead);
1760
		} catch (Exception e) {
1761
			fail("Exception copyingFile: " + src.getAbsolutePath() + " -> " + dst.getAbsolutePath());
1762
		} finally {
1763
			if (in != null)
1764
				try {in.close();} catch (Exception e) {/*Don't care*/}
1765
			if (out != null)
1766
				try {out.close();} catch (Exception e) {/*Don't care*/}
1767
		}
1768
1769
		while (dst.lastModified() - initModificationTime == 0) {
1770
			// Unix stat doesn't return granularity < 1000ms :(
1771
			// If we don't sleep here, and the unit test goes too quickly, we're scuppered.
1772
			try {
1773
				Thread.sleep(200);
1774
			} catch (InterruptedException e) {
1775
				// Don't care
1776
			}
1777
			dst.setLastModified(System.currentTimeMillis());
1778
		}
1779
	}
1780
1781
 	/**
1782
	 * Bug251408
1783
	 * Updating the .project file of an inner-nested Project causes problems when the the scheduling
1784
	 * rule for the outer project is held but it doesn't contain the scheduling rule for the inner project.
1785
	 *
1786
	 * This test creates a linked resource between the inner project and outer project.
1787
	 * The first linked resource is relative to a path variable "ROOT"
1788
	 * The second is absolute.
1789
	 *
1790
	 * Overwrite the .project file externally (such that the file is out of sync.).
1791
	 * Problem occurs.
1792
	 */
1793
	public void testChangingLinksWithNestedProjects2() {
1794
		// /ExistingProject/foo
1795
		final String sOverlappingProject = "foo";
1796
		final IFolder overlappingFolder = existingProject.getFolder(sOverlappingProject);
1797
		ensureExistsInFileSystem(overlappingFolder);
1798
1799
		// /foo -> /ExistingProject/foo
1800
		final IProject overlappingProject = getWorkspace().getRoot().getProject(sOverlappingProject);
1801
		IProjectDescription desc = getWorkspace().newProjectDescription(sOverlappingProject);
1802
		desc.setLocation(overlappingFolder.getLocation());
1803
		try {
1804
			overlappingProject.create(desc, getMonitor());
1805
			overlappingProject.open(getMonitor());
1806
			assertTrue("0.9",overlappingProject.exists());
1807
		} catch (CoreException e) {
1808
			fail("1.0");
1809
		}
1810
1811
		// Create a path variable for the workspace root
1812
		try {
1813
			IPath ROOT = getWorkspace().getRoot().getLocation();
1814
			getWorkspace().getPathVariableManager().setValue("ROOT", ROOT);
1815
		} catch (CoreException e) {
1816
			fail("1.5");
1817
		}
1818
1819
		// Two linked resource paths:
1820
		// 1) Uses path variable
1821
		IPath l1 = new Path("ROOT").append(existingFolderInExistingProject.getFullPath());
1822
		// 2) uses absolute path
1823
		IPath l2 = existingFolderInExistingProject.getLocation();
1824
1825
		// Refresh Workspace
1826
		try {
1827
			getWorkspace().getRoot().refreshLocal(IResource.DEPTH_INFINITE, getMonitor());
1828
		} catch (CoreException e) {
1829
			fail ("2.0");
1830
		}
1831
1832
		// Create a link to the folder in the existing project (using absolute path)
1833
		// /foo/linkedFolder -> /ExistingProject/existingFolderInExistingProject
1834
		IFolder linkedFolder = overlappingProject.getFolder("linkedFolder");
1835
		try {
1836
			linkedFolder.createLink(l1, IResource.REPLACE, getMonitor());
1837
			assertTrue("1.9",linkedFolder.exists());
1838
			// Back-up .project the file to .project1
1839
			overlappingProject.getFile(".project").copy(new Path(".project1"), true, getMonitor());
1840
		} catch (CoreException e) {
1841
			fail("3.0");
1842
		}
1843
1844
		// Change the variable to be relative to the ROOT variable
1845
		try {
1846
			linkedFolder.delete(true, getMonitor());
1847
			linkedFolder.createLink(l2, IResource.REPLACE, getMonitor());
1848
			assertTrue(linkedFolder.exists());
1849
			// Back-up .project the file to .project2
1850
			overlappingProject.getFile(".project").copy(new Path(".project2"), true, getMonitor());
1851
		} catch (CoreException e) {
1852
			fail("5.0");
1853
		}
1854
1855
		// Refresh Workspace
1856
		try {
1857
			getWorkspace().getRoot().refreshLocal(IResource.DEPTH_INFINITE, getMonitor());
1858
		} catch (CoreException e) {
1859
			fail ("2.0");
1860
		}
1861
1862
		// FIXME if we don't sleep here then there's no issue...
1863
		try {
1864
			Thread.sleep(1000);
1865
		}catch (Exception e){}
1866
1867
		try {
1868
			// Now lock the outer project, and overwrite the inner project's 
1869
			// .project file (as might be done by a team provider)
1870
			Job.getJobManager().beginRule(existingProject, getMonitor());
1871
	
1872
			// Switch between the two version of the .project file
1873
			try {
1874
				overlappingFolder.getFile(".project").setContents(overlappingFolder.getFile(".project1").getContents(), true, false, getMonitor());
1875
			} catch (CoreException e) {
1876
				fail ("10.0");
1877
			}
1878
	
1879
			try {
1880
				overlappingFolder.getFile(".project").setContents(overlappingFolder.getFile(".project2").getContents(), true, false, getMonitor());
1881
			} catch (CoreException e) {
1882
				fail ("11.0");
1883
			}
1884
		} finally {
1885
			Job.getJobManager().endRule(existingProject);
1886
		}
1887
	}
1888
1643
}
1889
}

Return to bug 251370