| /******************************************************************************* |
| * Copyright (c) 2000, 2017 IBM Corporation and others. |
| * |
| * This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License 2.0 |
| * which accompanies this distribution, and is available at |
| * https://www.eclipse.org/legal/epl-2.0/ |
| * |
| * SPDX-License-Identifier: EPL-2.0 |
| * |
| * Contributors: |
| * IBM Corporation - initial API and implementation |
| * Sergey Prigogin (Google) - [338010] Resource.createLink() does not preserve symbolic links |
| *******************************************************************************/ |
| package org.eclipse.core.tests.resources; |
| |
| import java.io.*; |
| import java.io.File; |
| import java.net.URI; |
| import java.util.HashMap; |
| import junit.framework.Test; |
| import junit.framework.TestSuite; |
| import org.eclipse.core.filesystem.EFS; |
| import org.eclipse.core.filesystem.IFileStore; |
| import org.eclipse.core.filesystem.URIUtil; |
| import org.eclipse.core.internal.resources.*; |
| import org.eclipse.core.internal.utils.FileUtil; |
| import org.eclipse.core.resources.*; |
| import org.eclipse.core.runtime.*; |
| import org.eclipse.core.tests.harness.CancelingProgressMonitor; |
| import org.eclipse.core.tests.harness.FussyProgressMonitor; |
| |
| /** |
| * Tests the following API methods: |
| * IFile#createLink |
| * IFolder#createLink |
| * |
| * This test supports both variable-based and non-variable-based locations. |
| * Although the method used for creating random locations |
| * <code>ResourceTest#getRandomLocation()</code> never returns variable- |
| * based paths, this method is overwritten in the derived class |
| * <code>LinkedResourceWithPathVariable</code> to always return variable-based |
| * paths. |
| * |
| * To support variable-based paths wherever a file system location is used, it |
| * is mandatory first to resolve it and only then using it, except in calls to |
| * <code>IFile#createLink</code> and <code>IFolder#createLink</code> and when |
| * the location is obtained using <code>IResource#getLocation()</code>. |
| */ |
| public class LinkedResourceTest extends ResourceTest { |
| protected String childName = "File.txt"; |
| protected IProject closedProject; |
| protected IFile existingFileInExistingProject; |
| protected IFolder existingFolderInExistingFolder; |
| protected IFolder existingFolderInExistingProject; |
| protected IProject existingProject; |
| protected IProject existingProjectInSubDirectory; |
| protected IPath localFile; |
| protected IPath localFolder; |
| protected IFile nonExistingFileInExistingFolder; |
| protected IFile nonExistingFileInExistingProject; |
| protected IFile nonExistingFileInOtherExistingProject; |
| protected IFolder nonExistingFolderInExistingFolder; |
| protected IFolder nonExistingFolderInExistingProject; |
| protected IFolder nonExistingFolderInNonExistingFolder; |
| protected IFolder nonExistingFolderInNonExistingProject; |
| protected IFolder nonExistingFolderInOtherExistingProject; |
| protected IPath nonExistingLocation; |
| protected IProject nonExistingProject; |
| protected IProject otherExistingProject; |
| |
| public static Test suite() { |
| return new TestSuite(LinkedResourceTest.class); |
| // TestSuite suite = new TestSuite(); |
| // suite.addTest(new LinkedResourceTest("testFindFilesForLocationCaseVariant")); |
| // return suite; |
| } |
| |
| public LinkedResourceTest() { |
| super(); |
| } |
| |
| public LinkedResourceTest(String name) { |
| super(name); |
| } |
| |
| protected void doCleanup() throws Exception { |
| ensureExistsInWorkspace(new IResource[] {existingProject, otherExistingProject, closedProject, existingFolderInExistingProject, existingFolderInExistingFolder, existingFileInExistingProject}, true); |
| closedProject.close(getMonitor()); |
| ensureDoesNotExistInWorkspace(new IResource[] {nonExistingProject, nonExistingFolderInExistingProject, nonExistingFolderInExistingFolder, nonExistingFolderInOtherExistingProject, nonExistingFolderInNonExistingProject, nonExistingFolderInNonExistingFolder, nonExistingFileInExistingProject, nonExistingFileInOtherExistingProject, nonExistingFileInExistingFolder}); |
| ensureDoesNotExistInFileSystem(resolve(nonExistingLocation).toFile()); |
| resolve(localFolder).toFile().mkdirs(); |
| createFileInFileSystem(resolve(localFile), getRandomContents()); |
| } |
| |
| private byte[] getFileContents(IFile file) throws CoreException { |
| ByteArrayOutputStream bout = new ByteArrayOutputStream(); |
| transferData(new BufferedInputStream(file.getContents()), bout); |
| return bout.toByteArray(); |
| } |
| |
| /** |
| * Maybe overridden in subclasses that use path variables. |
| */ |
| protected IPath resolve(IPath path) { |
| return path; |
| } |
| |
| /** |
| * Maybe overridden in subclasses that use path variables. |
| */ |
| protected URI resolve(URI uri) { |
| return uri; |
| } |
| |
| @Override |
| protected void setUp() throws Exception { |
| super.setUp(); |
| existingProject = getWorkspace().getRoot().getProject("ExistingProject"); |
| existingProjectInSubDirectory = getWorkspace().getRoot().getProject("ExistingProjectInSubDirectory"); |
| otherExistingProject = getWorkspace().getRoot().getProject("OtherExistingProject"); |
| closedProject = getWorkspace().getRoot().getProject("ClosedProject"); |
| existingFolderInExistingProject = existingProject.getFolder("existingFolderInExistingProject"); |
| existingFolderInExistingFolder = existingFolderInExistingProject.getFolder("existingFolderInExistingFolder"); |
| nonExistingFolderInExistingProject = existingProject.getFolder("nonExistingFolderInExistingProject"); |
| nonExistingFolderInOtherExistingProject = otherExistingProject.getFolder("nonExistingFolderInOtherExistingProject"); |
| nonExistingFolderInNonExistingFolder = nonExistingFolderInExistingProject.getFolder("nonExistingFolderInNonExistingFolder"); |
| nonExistingFolderInExistingFolder = existingFolderInExistingProject.getFolder("nonExistingFolderInExistingFolder"); |
| |
| nonExistingProject = getWorkspace().getRoot().getProject("NonProject"); |
| nonExistingFolderInNonExistingProject = nonExistingProject.getFolder("nonExistingFolderInNonExistingProject"); |
| |
| existingFileInExistingProject = existingProject.getFile("existingFileInExistingProject"); |
| nonExistingFileInExistingProject = existingProject.getFile("nonExistingFileInExistingProject"); |
| nonExistingFileInOtherExistingProject = otherExistingProject.getFile("nonExistingFileInOtherExistingProject"); |
| nonExistingFileInExistingFolder = existingFolderInExistingProject.getFile("nonExistingFileInExistingFolder"); |
| localFolder = getRandomLocation(); |
| nonExistingLocation = getRandomLocation(); |
| localFile = localFolder.append(childName); |
| doCleanup(); |
| |
| if (!existingProjectInSubDirectory.exists()) { |
| IProjectDescription desc = getWorkspace().newProjectDescription(existingProjectInSubDirectory.getName()); |
| File dir = existingProject.getLocation().toFile(); |
| dir = dir.getParentFile(); |
| dir = new File(dir + File.separator + "sub" + File.separator + "dir" + File.separator + "more" + File.separator + "proj"); |
| dir.mkdirs(); |
| desc.setLocation(Path.fromOSString(dir.getAbsolutePath())); |
| existingProjectInSubDirectory.create(desc, getMonitor()); |
| } |
| if (!existingProjectInSubDirectory.isOpen()) { |
| existingProjectInSubDirectory.open(getMonitor()); |
| } |
| } |
| |
| @Override |
| protected void tearDown() throws Exception { |
| super.tearDown(); |
| Workspace.clear(resolve(localFolder).toFile()); |
| Workspace.clear(resolve(nonExistingLocation).toFile()); |
| } |
| |
| /** |
| * Tests creation of a linked resource whose corresponding file system |
| * path does not exist. This should succeed but no operations will be |
| * available on the resulting resource. |
| */ |
| public void testAllowMissingLocal() { |
| //get a non-existing location |
| IPath location = getRandomLocation(); |
| IFolder folder = nonExistingFolderInExistingProject; |
| |
| //try to create without the flag (should fail) |
| try { |
| folder.createLink(location, IResource.NONE, getMonitor()); |
| fail("1.0"); |
| } catch (CoreException e) { |
| //should fail |
| } |
| |
| //now try to create with the flag (should succeed) |
| try { |
| folder.createLink(location, IResource.ALLOW_MISSING_LOCAL, getMonitor()); |
| } catch (CoreException e) { |
| fail("1.1", e); |
| } |
| assertEquals("1.2", resolve(location), folder.getLocation()); |
| assertTrue("1.3", !resolve(location).toFile().exists()); |
| //getting children should succeed (and be empty) |
| try { |
| assertEquals("1.4", 0, folder.members().length); |
| } catch (CoreException e) { |
| fail("1.5", e); |
| } |
| //delete should succeed |
| try { |
| folder.delete(IResource.NONE, getMonitor()); |
| } catch (CoreException e) { |
| fail("1.6", e); |
| } |
| |
| //try to create with local path that can never exist |
| if (isWindows()) { |
| location = new Path("b:\\does\\not\\exist"); |
| } else { |
| location = new Path("/dev/null/does/not/exist"); |
| } |
| location = FileUtil.canonicalPath(location); |
| try { |
| folder.createLink(location, IResource.NONE, getMonitor()); |
| fail("2.1"); |
| } catch (CoreException e) { |
| //should fail |
| } |
| try { |
| folder.createLink(location, IResource.ALLOW_MISSING_LOCAL, getMonitor()); |
| } catch (CoreException e) { |
| fail("2.2", e); |
| } |
| assertEquals("2.3", location, folder.getLocation()); |
| assertTrue("2.4", !location.toFile().exists()); |
| // creating child should fail |
| try { |
| folder.getFile("abc.txt").create(getRandomContents(), IResource.NONE, getMonitor()); |
| fail("2.5"); |
| } catch (CoreException e) { |
| //should fail |
| } |
| } |
| |
| /** |
| * Tests case where a resource in the file system cannot be added to the workspace |
| * because it is blocked by a linked resource of the same name. |
| */ |
| public void testBlockedFolder() { |
| //create local folder that will be blocked |
| ensureExistsInFileSystem(nonExistingFolderInExistingProject); |
| IFile blockedFile = nonExistingFolderInExistingProject.getFile("BlockedFile"); |
| createFileInFileSystem(blockedFile.getLocation(), getRandomContents()); |
| try { |
| //link the folder elsewhere |
| nonExistingFolderInExistingProject.createLink(localFolder, IResource.NONE, getMonitor()); |
| //refresh the project |
| existingProject.refreshLocal(IResource.DEPTH_INFINITE, getMonitor()); |
| } catch (CoreException e) { |
| fail("1.1", e); |
| } |
| |
| //the blocked file should not exist in the workspace |
| assertTrue("1.2", !blockedFile.exists()); |
| assertTrue("1.3", nonExistingFolderInExistingProject.exists()); |
| assertTrue("1.4", nonExistingFolderInExistingProject.getFile(childName).exists()); |
| assertEquals("1.5", nonExistingFolderInExistingProject.getLocation(), resolve(localFolder)); |
| |
| //now delete the link |
| try { |
| nonExistingFolderInExistingProject.delete(IResource.NONE, getMonitor()); |
| } catch (CoreException e) { |
| fail("1.99", e); |
| } |
| //the blocked file and the linked folder should not exist in the workspace |
| assertTrue("2.0", !blockedFile.exists()); |
| assertTrue("2.1", !nonExistingFolderInExistingProject.exists()); |
| assertTrue("2.2", !nonExistingFolderInExistingProject.getFile(childName).exists()); |
| assertEquals("2.3", nonExistingFolderInExistingProject.getLocation(), existingProject.getLocation().append(nonExistingFolderInExistingProject.getName())); |
| |
| //now refresh again to discover the blocked resource |
| try { |
| existingProject.refreshLocal(IResource.DEPTH_INFINITE, getMonitor()); |
| } catch (CoreException e) { |
| fail("2.99", e); |
| } |
| |
| //the blocked file should now exist |
| assertTrue("3.0", blockedFile.exists()); |
| assertTrue("3.1", nonExistingFolderInExistingProject.exists()); |
| assertTrue("3.2", !nonExistingFolderInExistingProject.getFile(childName).exists()); |
| assertEquals("3.3", nonExistingFolderInExistingProject.getLocation(), existingProject.getLocation().append(nonExistingFolderInExistingProject.getName())); |
| |
| //attempting to link again will fail because the folder exists in the workspace |
| try { |
| nonExistingFolderInExistingProject.createLink(localFolder, IResource.NONE, getMonitor()); |
| fail("3.4"); |
| } catch (CoreException e) { |
| //expected |
| } |
| } |
| |
| /** |
| * This test creates a linked folder resource, then changes the directory in |
| * the file system to be a file. On refresh, the linked resource should |
| * still exist, should have the correct gender, and still be a linked |
| * resource. |
| */ |
| public void testChangeLinkGender() { |
| IFolder folder = nonExistingFolderInExistingProject; |
| IFile file = folder.getProject().getFile(folder.getProjectRelativePath()); |
| IPath resolvedLocation = resolve(localFolder); |
| try { |
| folder.createLink(localFolder, IResource.NONE, getMonitor()); |
| } catch (CoreException e) { |
| fail("0.99", e); |
| } |
| ensureDoesNotExistInFileSystem(resolvedLocation.toFile()); |
| createFileInFileSystem(resolvedLocation, getRandomContents()); |
| try { |
| folder.refreshLocal(IResource.DEPTH_INFINITE, getMonitor()); |
| } catch (CoreException e) { |
| fail("2.99", e); |
| } |
| |
| assertTrue("3.0", !folder.exists()); |
| assertTrue("3.1", file.exists()); |
| assertTrue("3.2", file.isLinked()); |
| assertEquals("3.3", resolvedLocation, file.getLocation()); |
| |
| //change back to folder |
| ensureDoesNotExistInFileSystem(resolvedLocation.toFile()); |
| resolvedLocation.toFile().mkdirs(); |
| |
| try { |
| folder.refreshLocal(IResource.DEPTH_INFINITE, getMonitor()); |
| } catch (CoreException e) { |
| fail("3.99", e); |
| } |
| assertTrue("4.0", folder.exists()); |
| assertTrue("4.1", !file.exists()); |
| assertTrue("4.2", folder.isLinked()); |
| assertEquals("4.3", resolvedLocation, folder.getLocation()); |
| } |
| |
| public void testCopyFile() { |
| IResource[] sources = new IResource[] {nonExistingFileInExistingProject, nonExistingFileInExistingFolder}; |
| IResource[] destinationResources = new IResource[] {existingProject, closedProject, nonExistingFileInOtherExistingProject, nonExistingFileInExistingFolder}; |
| Boolean[] deepCopy = new Boolean[] {Boolean.TRUE, Boolean.FALSE}; |
| IProgressMonitor[] monitors = new IProgressMonitor[] {new FussyProgressMonitor(), new CancelingProgressMonitor(), null}; |
| Object[][] inputs = new Object[][] {sources, destinationResources, deepCopy, monitors}; |
| new TestPerformer("LinkedResourceTest.testCopyFile") { |
| protected static final String CANCELED = "canceled"; |
| |
| @Override |
| public void cleanUp(Object[] args, int count) { |
| super.cleanUp(args, count); |
| try { |
| doCleanup(); |
| } catch (Exception e) { |
| fail("invocation " + count + " failed to cleanup", e); |
| } |
| } |
| |
| @Override |
| public Object invokeMethod(Object[] args, int count) throws Exception { |
| IFile source = (IFile) args[0]; |
| IResource destination = (IResource) args[1]; |
| boolean isDeep = ((Boolean) args[2]).booleanValue(); |
| IProgressMonitor monitor = (IProgressMonitor) args[3]; |
| if (monitor instanceof FussyProgressMonitor) { |
| ((FussyProgressMonitor) monitor).prepare(); |
| } |
| try { |
| source.createLink(localFile, IResource.NONE, null); |
| source.copy(destination.getFullPath(), isDeep ? IResource.NONE : IResource.SHALLOW, monitor); |
| } catch (OperationCanceledException e) { |
| return CANCELED; |
| } |
| if (monitor instanceof FussyProgressMonitor) { |
| ((FussyProgressMonitor) monitor).sanityCheck(); |
| } |
| return null; |
| } |
| |
| @Override |
| public boolean shouldFail(Object[] args, int count) { |
| IFile source = (IFile) args[0]; |
| IResource destination = (IResource) args[1]; |
| boolean isDeep = ((Boolean) args[2]).booleanValue(); |
| IProgressMonitor monitor = (IProgressMonitor) args[3]; |
| if (monitor instanceof CancelingProgressMonitor) { |
| return false; |
| } |
| if (source.equals(destination)) { |
| return true; |
| } |
| IResource parent = destination.getParent(); |
| if (!isDeep && parent == null) { |
| return true; |
| } |
| if (!parent.isAccessible()) { |
| return true; |
| } |
| if (destination.exists()) { |
| return true; |
| } |
| //passed all failure cases so it should succeed |
| return false; |
| } |
| |
| @Override |
| public boolean wasSuccess(Object[] args, Object result, Object[] oldState) throws Exception { |
| IFile source = (IFile) args[0]; |
| IResource destination = (IResource) args[1]; |
| boolean isDeep = ((Boolean) args[2]).booleanValue(); |
| IProgressMonitor monitor = (IProgressMonitor) args[3]; |
| if (result == CANCELED) { |
| return monitor instanceof CancelingProgressMonitor; |
| } |
| if (!destination.exists()) { |
| return false; |
| } |
| //destination should only be linked for a shallow copy |
| if (isDeep) { |
| if (destination.isLinked()) { |
| return false; |
| } |
| if (source.getLocation().equals(destination.getLocation())) { |
| return false; |
| } |
| if (!destination.getProject().getLocation().isPrefixOf(destination.getLocation())) { |
| return false; |
| } |
| } else { |
| if (!destination.isLinked()) { |
| return false; |
| } |
| if (!source.getLocation().equals(destination.getLocation())) { |
| return false; |
| } |
| if (!source.getRawLocation().equals(destination.getRawLocation())) { |
| return false; |
| } |
| if (!source.getLocationURI().equals(destination.getLocationURI())) { |
| return false; |
| } |
| } |
| return true; |
| } |
| }.performTest(inputs); |
| } |
| |
| public void testCopyFolder() { |
| IFolder[] sources = new IFolder[] {nonExistingFolderInExistingProject, nonExistingFolderInExistingFolder}; |
| IResource[] destinations = new IResource[] {existingProject, closedProject, nonExistingProject, existingFolderInExistingProject, nonExistingFolderInOtherExistingProject, nonExistingFolderInExistingFolder}; |
| Boolean[] deepCopy = new Boolean[] {Boolean.TRUE, Boolean.FALSE}; |
| IProgressMonitor[] monitors = new IProgressMonitor[] {new FussyProgressMonitor(), new CancelingProgressMonitor(), null}; |
| Object[][] inputs = new Object[][] {sources, destinations, deepCopy, monitors}; |
| new TestPerformer("LinkedResourceTest.testCopyFolder") { |
| protected static final String CANCELED = "canceled"; |
| |
| @Override |
| public void cleanUp(Object[] args, int count) { |
| super.cleanUp(args, count); |
| try { |
| doCleanup(); |
| } catch (Exception e) { |
| fail("invocation " + count + " failed to cleanup", e); |
| } |
| } |
| |
| @Override |
| public Object invokeMethod(Object[] args, int count) throws Exception { |
| IFolder source = (IFolder) args[0]; |
| IResource destination = (IResource) args[1]; |
| boolean isDeep = ((Boolean) args[2]).booleanValue(); |
| IProgressMonitor monitor = (IProgressMonitor) args[3]; |
| if (monitor instanceof FussyProgressMonitor) { |
| ((FussyProgressMonitor) monitor).prepare(); |
| } |
| try { |
| source.createLink(localFolder, IResource.NONE, null); |
| source.copy(destination.getFullPath(), isDeep ? IResource.NONE : IResource.SHALLOW, monitor); |
| } catch (OperationCanceledException e) { |
| return CANCELED; |
| } |
| if (monitor instanceof FussyProgressMonitor) { |
| ((FussyProgressMonitor) monitor).sanityCheck(); |
| } |
| return null; |
| } |
| |
| @Override |
| public boolean shouldFail(Object[] args, int count) { |
| IFolder source = (IFolder) args[0]; |
| IResource destination = (IResource) args[1]; |
| boolean isDeep = ((Boolean) args[2]).booleanValue(); |
| IProgressMonitor monitor = (IProgressMonitor) args[3]; |
| if (monitor instanceof CancelingProgressMonitor) { |
| return false; |
| } |
| IResource parent = destination.getParent(); |
| if (destination.getType() == IResource.PROJECT) { |
| return true; |
| } |
| if (source.equals(destination)) { |
| return true; |
| } |
| if (!isDeep && parent == null) { |
| return true; |
| } |
| if (!parent.isAccessible()) { |
| return true; |
| } |
| if (destination.exists()) { |
| return true; |
| } |
| //passed all failure case so it should succeed |
| return false; |
| } |
| |
| @Override |
| public boolean wasSuccess(Object[] args, Object result, Object[] oldState) throws Exception { |
| IFolder source = (IFolder) args[0]; |
| IResource destination = (IResource) args[1]; |
| boolean isDeep = ((Boolean) args[2]).booleanValue(); |
| IProgressMonitor monitor = (IProgressMonitor) args[3]; |
| if (result == CANCELED) { |
| return monitor instanceof CancelingProgressMonitor; |
| } |
| if (!destination.exists()) { |
| return false; |
| } |
| //destination should only be linked for a shallow copy |
| if (isDeep) { |
| if (destination.isLinked()) { |
| return false; |
| } |
| if (source.getLocation().equals(destination.getLocation())) { |
| return false; |
| } |
| if (!destination.getProject().getLocation().isPrefixOf(destination.getLocation())) { |
| return false; |
| } |
| } else { |
| if (!destination.isLinked()) { |
| return false; |
| } |
| if (!source.getLocation().equals(destination.getLocation())) { |
| return false; |
| } |
| if (!source.getLocationURI().equals(destination.getLocationURI())) { |
| return false; |
| } |
| if (!source.getRawLocation().equals(destination.getRawLocation())) { |
| return false; |
| } |
| } |
| return true; |
| } |
| }.performTest(inputs); |
| } |
| |
| /** |
| * Tests copying a linked file resource that doesn't exist in the file system |
| */ |
| public void testCopyMissingFile() { |
| IPath location = getRandomLocation(); |
| IFile linkedFile = nonExistingFileInExistingProject; |
| try { |
| linkedFile.createLink(location, IResource.ALLOW_MISSING_LOCAL, getMonitor()); |
| } catch (CoreException e) { |
| fail("1.99", e); |
| } |
| |
| IFile dest = existingProject.getFile("FailedCopyDest"); |
| try { |
| linkedFile.copy(dest.getFullPath(), IResource.NONE, getMonitor()); |
| fail("2.0"); |
| } catch (CoreException e1) { |
| //should fail |
| } |
| assertTrue("2.1", !dest.exists()); |
| try { |
| linkedFile.copy(dest.getFullPath(), IResource.FORCE, getMonitor()); |
| fail("2.2"); |
| } catch (CoreException e1) { |
| //should fail |
| } |
| assertTrue("2.3", !dest.exists()); |
| } |
| |
| /** |
| * Tests copying a linked folder that doesn't exist in the file system |
| */ |
| public void testCopyMissingFolder() { |
| IPath location = getRandomLocation(); |
| IFolder linkedFolder = nonExistingFolderInExistingProject; |
| try { |
| linkedFolder.createLink(location, IResource.ALLOW_MISSING_LOCAL, getMonitor()); |
| } catch (CoreException e) { |
| fail("1.99", e); |
| } |
| |
| IFolder dest = existingProject.getFolder("FailedCopyDest"); |
| try { |
| linkedFolder.copy(dest.getFullPath(), IResource.NONE, getMonitor()); |
| fail("2.0"); |
| } catch (CoreException e1) { |
| //should fail |
| } |
| assertTrue("2.1", !dest.exists()); |
| try { |
| linkedFolder.copy(dest.getFullPath(), IResource.FORCE, getMonitor()); |
| fail("2.2"); |
| } catch (CoreException e1) { |
| //should fail |
| } |
| assertTrue("2.3", !dest.exists()); |
| } |
| |
| public void testCopyProjectWithLinks() { |
| IPath fileLocation = getRandomLocation(); |
| IFile linkedFile = nonExistingFileInExistingProject; |
| IFolder linkedFolder = nonExistingFolderInExistingProject; |
| try { |
| try { |
| createFileInFileSystem(resolve(fileLocation), getRandomContents()); |
| linkedFolder.createLink(localFolder, IResource.NONE, getMonitor()); |
| linkedFile.createLink(fileLocation, IResource.NONE, getMonitor()); |
| } catch (CoreException e) { |
| fail("1.0", e); |
| } |
| |
| //copy the project |
| IProject destination = getWorkspace().getRoot().getProject("CopyTargetProject"); |
| try { |
| existingProject.copy(destination.getFullPath(), IResource.SHALLOW, getMonitor()); |
| } catch (CoreException e) { |
| fail("2.0", e); |
| } |
| |
| IFile newFile = destination.getFile(linkedFile.getProjectRelativePath()); |
| assertTrue("3.0", newFile.isLinked()); |
| assertEquals("3.1", linkedFile.getLocation(), newFile.getLocation()); |
| |
| IFolder newFolder = destination.getFolder(linkedFolder.getProjectRelativePath()); |
| assertTrue("4.0", newFolder.isLinked()); |
| assertEquals("4.1", linkedFolder.getLocation(), newFolder.getLocation()); |
| |
| //test project deep copy |
| try { |
| destination.delete(IResource.NONE, getMonitor()); |
| existingProject.copy(destination.getFullPath(), IResource.NONE, getMonitor()); |
| } catch (CoreException e) { |
| fail("5.0", e); |
| } |
| assertTrue("5.1", !newFile.isLinked()); |
| assertEquals("5.2", destination.getLocation().append(newFile.getProjectRelativePath()), newFile.getLocation()); |
| assertTrue("5.3", !newFolder.isLinked()); |
| assertEquals("5.4", destination.getLocation().append(newFolder.getProjectRelativePath()), newFolder.getLocation()); |
| |
| //test copy project when linked resources don't exist with force=false |
| try { |
| destination.delete(IResource.NONE, getMonitor()); |
| } catch (CoreException e) { |
| fail("5.99", e); |
| } |
| assertTrue("6.0", resolve(fileLocation).toFile().delete()); |
| |
| try { |
| existingProject.copy(destination.getFullPath(), IResource.NONE, getMonitor()); |
| fail("6.1"); |
| } catch (CoreException e) { |
| //should fail |
| } |
| //all members except the missing link should have been copied |
| assertTrue("6.2", destination.exists()); |
| assertTrue("6.2.1", !destination.getFile(linkedFile.getName()).exists()); |
| try { |
| IResource[] srcChildren = existingProject.members(); |
| for (int i = 0; i < srcChildren.length; i++) { |
| if (!srcChildren[i].equals(linkedFile)) { |
| assertNotNull("6.3." + i, destination.findMember(srcChildren[i].getProjectRelativePath())); |
| } |
| } |
| } catch (CoreException e) { |
| fail("6.4", e); |
| } |
| //test copy project when linked resources don't exist with force=true |
| //this should mostly succeed, but still throw an exception indicating |
| //a resource could not be copied because its location was missing |
| try { |
| destination.delete(IResource.NONE, getMonitor()); |
| } catch (CoreException e) { |
| fail("6.5", e); |
| } |
| try { |
| existingProject.copy(destination.getFullPath(), IResource.FORCE, getMonitor()); |
| fail("6.6"); |
| } catch (CoreException e) { |
| //should fail |
| } |
| assertTrue("6.7", destination.exists()); |
| assertTrue("6.7.1", !destination.getFile(linkedFile.getName()).exists()); |
| //all members except the missing link should have been copied |
| try { |
| IResource[] srcChildren = existingProject.members(); |
| for (int i = 0; i < srcChildren.length; i++) { |
| if (!srcChildren[i].equals(linkedFile)) { |
| assertNotNull("6.8." + i, destination.findMember(srcChildren[i].getProjectRelativePath())); |
| } |
| } |
| } catch (CoreException e) { |
| fail("6.99", e); |
| } |
| } finally { |
| Workspace.clear(resolve(fileLocation).toFile()); |
| } |
| } |
| |
| /** |
| * Tests creating a linked folder and performing refresh in the background |
| */ |
| public void testCreateFolderInBackground() throws CoreException { |
| final IFileStore rootStore = getTempStore(); |
| rootStore.mkdir(IResource.NONE, getMonitor()); |
| IFileStore childStore = rootStore.getChild("file.txt"); |
| createFileInFileSystem(childStore); |
| |
| IFolder link = nonExistingFolderInExistingProject; |
| link.createLink(rootStore.toURI(), IResource.BACKGROUND_REFRESH, getMonitor()); |
| waitForRefresh(); |
| IFile linkChild = link.getFile(childStore.getName()); |
| assertTrue("1.0", link.exists()); |
| assertTrue("1.1", link.isSynchronized(IResource.DEPTH_INFINITE)); |
| assertTrue("1.2", linkChild.exists()); |
| assertTrue("1.3", linkChild.isSynchronized(IResource.DEPTH_INFINITE)); |
| } |
| |
| /** |
| * Tests creating a linked resource with the same name but different |
| * case as an existing resource. On case insensitive platforms this should fail. |
| */ |
| public void testCreateLinkCaseVariant() { |
| IFolder link = nonExistingFolderInExistingProject; |
| IFolder variant = link.getParent().getFolder(new Path(link.getName().toUpperCase())); |
| ensureExistsInWorkspace(variant, true); |
| |
| try { |
| link.createLink(localFolder, IResource.NONE, getMonitor()); |
| //should fail on case insensitive platforms |
| if (!isCaseSensitive(variant)) { |
| fail("1.0"); |
| } |
| } catch (CoreException e) { |
| //should not fail on case sensitive platforms |
| if (isCaseSensitive(variant)) { |
| fail("1.1", e); |
| } |
| } |
| |
| } |
| |
| /** |
| * Tests creating a linked resource by modifying the .project file directly. |
| * This is a regression test for bug 63331. |
| */ |
| public void testCreateLinkInDotProject() { |
| final IFile dotProject = existingProject.getFile(IProjectDescription.DESCRIPTION_FILE_NAME); |
| IFile link = nonExistingFileInExistingProject; |
| byte[] oldContents = null; |
| try { |
| //create a linked file |
| link.createLink(localFile, IResource.NONE, getMonitor()); |
| //copy the .project file contents |
| oldContents = getFileContents(dotProject); |
| //delete linked file |
| link.delete(IResource.NONE, getMonitor()); |
| } catch (CoreException e) { |
| fail("1.99", e); |
| } |
| final byte[] finalContents = oldContents; |
| try { |
| //recreate the link in a workspace runnable with create scheduling rule |
| getWorkspace().run((IWorkspaceRunnable) monitor -> dotProject.setContents(new ByteArrayInputStream(finalContents), IResource.NONE, getMonitor()), getWorkspace().getRuleFactory().modifyRule(dotProject), IResource.NONE, getMonitor()); |
| } catch (CoreException e1) { |
| fail("2.99", e1); |
| } |
| } |
| |
| /** |
| * Tests creating a project whose .project file already defines links at |
| * depth greater than one. See bug 121322. |
| */ |
| public void testCreateProjectWithDeepLinks() { |
| IProject project = existingProject; |
| IFolder parent = existingFolderInExistingProject; |
| IFolder folder = nonExistingFolderInExistingFolder; |
| try { |
| folder.createLink(localFolder, IResource.NONE, getMonitor()); |
| //delete and recreate the project |
| project.delete(IResource.NEVER_DELETE_PROJECT_CONTENT, getMonitor()); |
| project.create(getMonitor()); |
| project.open(IResource.BACKGROUND_REFRESH, getMonitor()); |
| assertTrue("1.0", folder.exists()); |
| assertTrue("1.1", parent.exists()); |
| assertTrue("1.2", parent.isLocal(IResource.DEPTH_INFINITE)); |
| } catch (CoreException e) { |
| fail("1.99", e); |
| } |
| } |
| |
| /** |
| * Tests whether {@link IFile#createLink} and {@link IFolder#createLink} |
| * handle {@link IResource#HIDDEN} flag properly. |
| */ |
| public void testCreateHiddenLinkedResources() { |
| IFolder folder = existingProject.getFolder("folder"); |
| IFile file = existingProject.getFile("file.txt"); |
| |
| try { |
| folder.createLink(localFolder, IResource.HIDDEN, getMonitor()); |
| } catch (CoreException e) { |
| fail("1.0", e); |
| } |
| |
| try { |
| file.createLink(localFile, IResource.HIDDEN, getMonitor()); |
| } catch (CoreException e) { |
| fail("2.0", e); |
| } |
| |
| assertTrue("3.0", folder.isHidden()); |
| assertTrue("4.0", file.isHidden()); |
| } |
| |
| public void testDeepMoveProjectWithLinks() { |
| IPath fileLocation = getRandomLocation(); |
| IFile file = nonExistingFileInExistingProject; |
| IFolder folder = nonExistingFolderInExistingProject; |
| IFile childFile = folder.getFile(childName); |
| IResource[] oldResources = new IResource[] {file, folder, existingProject, childFile}; |
| try { |
| try { |
| createFileInFileSystem(resolve(fileLocation)); |
| folder.createLink(localFolder, IResource.NONE, getMonitor()); |
| file.createLink(fileLocation, IResource.NONE, getMonitor()); |
| } catch (CoreException e) { |
| fail("1.0", e); |
| } |
| |
| //move the project |
| IProject destination = getWorkspace().getRoot().getProject("MoveTargetProject"); |
| IFile newFile = destination.getFile(file.getProjectRelativePath()); |
| IFolder newFolder = destination.getFolder(folder.getProjectRelativePath()); |
| IFile newChildFile = newFolder.getFile(childName); |
| IResource[] newResources = new IResource[] {destination, newFile, newFolder, newChildFile}; |
| |
| assertDoesNotExistInWorkspace("2.0", destination); |
| |
| try { |
| existingProject.move(destination.getFullPath(), IResource.NONE, getMonitor()); |
| } catch (CoreException e) { |
| fail("2.1", e); |
| } |
| assertExistsInWorkspace("3.0", newResources); |
| assertDoesNotExistInWorkspace("3.1", oldResources); |
| assertTrue("3.2", existingProject.isSynchronized(IResource.DEPTH_INFINITE)); |
| assertTrue("3.3", destination.isSynchronized(IResource.DEPTH_INFINITE)); |
| |
| assertTrue("3.4", !newFile.isLinked()); |
| assertEquals("3.5", destination.getLocation().append(newFile.getProjectRelativePath()), newFile.getLocation()); |
| |
| assertTrue("3.6", !newFolder.isLinked()); |
| assertEquals("3.7", destination.getLocation().append(newFolder.getProjectRelativePath()), newFolder.getLocation()); |
| |
| assertTrue("3.8", destination.isSynchronized(IResource.DEPTH_INFINITE)); |
| } finally { |
| Workspace.clear(resolve(fileLocation).toFile()); |
| } |
| } |
| |
| /** |
| * Tests deleting the parent of a linked resource. |
| */ |
| public void testDeleteLinkParent() { |
| IFolder link = nonExistingFolderInExistingFolder; |
| IFolder linkParent = existingFolderInExistingProject; |
| IFile linkChild = link.getFile("child.txt"); |
| IFileStore childStore = null; |
| try { |
| link.createLink(localFolder, IResource.NONE, getMonitor()); |
| ensureExistsInWorkspace(linkChild, true); |
| childStore = EFS.getStore(linkChild.getLocationURI()); |
| } catch (CoreException e) { |
| fail("0.99", e); |
| } |
| |
| //everything should exist at this point |
| assertTrue("1.0", linkParent.exists()); |
| assertTrue("1.1", link.exists()); |
| assertTrue("1.2", linkChild.exists()); |
| |
| //delete the parent of the link |
| try { |
| linkParent.delete(IResource.KEEP_HISTORY, getMonitor()); |
| } catch (CoreException e) { |
| fail("1.99", e); |
| } |
| |
| //resources should not exist, but link content should exist on disk |
| assertTrue("2.0", !linkParent.exists()); |
| assertTrue("2.1", !link.exists()); |
| assertTrue("2.2", !linkChild.exists()); |
| assertTrue("2.3", childStore.fetchInfo().exists()); |
| } |
| |
| /** |
| * Tests deleting and then recreating a project |
| */ |
| public void testDeleteProjectWithLinks() { |
| IFolder link = nonExistingFolderInExistingProject; |
| try { |
| link.createLink(localFolder, IResource.NONE, getMonitor()); |
| existingProject.delete(IResource.NEVER_DELETE_PROJECT_CONTENT, getMonitor()); |
| existingProject.create(getMonitor()); |
| } catch (CoreException e) { |
| fail("0.99", e); |
| } |
| |
| //link should not exist until the project is open |
| assertTrue("1.0", !link.exists()); |
| |
| try { |
| existingProject.open(getMonitor()); |
| } catch (CoreException e) { |
| fail("1.99", e); |
| } |
| |
| //link should now exist |
| assertTrue("2.0", link.exists()); |
| assertTrue("2.1", link.isLinked()); |
| assertEquals("2.2", resolve(localFolder), link.getLocation()); |
| } |
| |
| /** |
| * Tests deleting a linked resource when .project is read-only |
| */ |
| public void testDeleteLink_Bug351823() throws CoreException { |
| IProject project = existingProject; |
| |
| IFile link = project.getFile(getUniqueString()); |
| link.createLink(localFile, IResource.NONE, getMonitor()); |
| |
| // set .project read-only |
| IFile descriptionFile = project.getFile(IProjectDescription.DESCRIPTION_FILE_NAME); |
| ResourceAttributes attrs = descriptionFile.getResourceAttributes(); |
| attrs.setReadOnly(true); |
| descriptionFile.setResourceAttributes(attrs); |
| |
| try { |
| try { |
| link.delete(false, getMonitor()); |
| fail("1.0"); |
| } catch (CoreException e1) { |
| // should fail |
| } |
| |
| assertTrue("2.0", link.exists()); |
| assertTrue("3.0", link.isLinked()); |
| |
| HashMap<IPath, LinkDescription> links = ((Project) project).internalGetDescription().getLinks(); |
| assertNotNull("4.0", links); |
| assertEquals("5.0", 1, links.size()); |
| |
| LinkDescription linkDesc = links.values().iterator().next(); |
| assertEquals("6.0", link.getProjectRelativePath(), linkDesc.getProjectRelativePath()); |
| |
| // try to delete again |
| // if the project description in memory is ok, it should fail |
| try { |
| link.delete(false, getMonitor()); |
| fail("7.0"); |
| } catch (CoreException e1) { |
| // should fail |
| } |
| } finally { |
| // set .project writable |
| attrs = descriptionFile.getResourceAttributes(); |
| attrs.setReadOnly(false); |
| descriptionFile.setResourceAttributes(attrs); |
| } |
| } |
| |
| /** |
| * Tests bug 209175. |
| */ |
| public void testDeleteFolderWithLinks() { |
| IProject project = existingProject; |
| IFolder folder = existingFolderInExistingProject; |
| IFile file1 = folder.getFile(getUniqueString()); |
| IFile file2 = project.getFile(getUniqueString()); |
| try { |
| file1.createLink(localFile, IResource.NONE, getMonitor()); |
| file2.createLink(localFile, IResource.NONE, getMonitor()); |
| |
| HashMap<IPath, LinkDescription> links = ((Project) project).internalGetDescription().getLinks(); |
| LinkDescription linkDescription1 = links.get(file1.getProjectRelativePath()); |
| assertNotNull("1.0", linkDescription1); |
| assertEquals("1.1", URIUtil.toURI(localFile), linkDescription1.getLocationURI()); |
| LinkDescription linkDescription2 = links.get(file2.getProjectRelativePath()); |
| assertNotNull("2.0", linkDescription2); |
| assertEquals("2.1", URIUtil.toURI(localFile), linkDescription2.getLocationURI()); |
| |
| folder.delete(true, getMonitor()); |
| |
| links = ((Project) project).internalGetDescription().getLinks(); |
| linkDescription1 = links.get(file1.getProjectRelativePath()); |
| assertNull("3.0", linkDescription1); |
| linkDescription2 = links.get(file2.getProjectRelativePath()); |
| assertNotNull("4.0", linkDescription2); |
| assertEquals("4.1", URIUtil.toURI(localFile), linkDescription2.getLocationURI()); |
| } catch (CoreException e) { |
| fail("5.0", e); |
| } |
| } |
| |
| /** |
| * Tests that IWorkspaceRoot.findFilesForLocation works correctly |
| * in presence of a linked resource that does not match the case in the file system |
| */ |
| public void testFindFilesForLocationCaseVariant() { |
| //this test only applies to file systems with a device in the path |
| if (!isWindows()) { |
| return; |
| } |
| IFolder link = nonExistingFolderInExistingProject; |
| IPath localLocation = resolve(localFolder); |
| IPath upperCase = localLocation.setDevice(localLocation.getDevice().toUpperCase()); |
| IPath lowerCase = localLocation.setDevice(localLocation.getDevice().toLowerCase()); |
| |
| try { |
| link.createLink(upperCase, IResource.NONE, getMonitor()); |
| } catch (CoreException e) { |
| fail("1.99", e); |
| } |
| IPath lowerCaseFilePath = lowerCase.append("file.txt"); |
| IFile[] files = getWorkspace().getRoot().findFilesForLocation(lowerCaseFilePath); |
| assertEquals("1.0", 1, files.length); |
| } |
| |
| /** |
| * Tests the {@link org.eclipse.core.resources.IResource#isLinked(int)} method. |
| */ |
| public void testIsLinked() { |
| //initially nothing is linked |
| IResource[] toTest = new IResource[] {closedProject, existingFileInExistingProject, existingFolderInExistingFolder, existingFolderInExistingProject, existingProject, nonExistingFileInExistingFolder, nonExistingFileInExistingProject, nonExistingFileInOtherExistingProject, nonExistingFolderInExistingFolder, nonExistingFolderInExistingProject, nonExistingFolderInNonExistingFolder, nonExistingFolderInNonExistingProject, nonExistingFolderInOtherExistingProject, nonExistingProject, otherExistingProject}; |
| for (int i = 0; i < toTest.length; i++) { |
| assertTrue("1.0 " + toTest[i], !toTest[i].isLinked()); |
| assertTrue("1.1 " + toTest[i], !toTest[i].isLinked(IResource.NONE)); |
| assertTrue("1.2 " + toTest[i], !toTest[i].isLinked(IResource.CHECK_ANCESTORS)); |
| } |
| // create a link |
| IFolder link = nonExistingFolderInExistingProject; |
| try { |
| link.createLink(localFolder, IResource.NONE, getMonitor()); |
| } catch (CoreException e) { |
| fail("1.99", e); |
| } |
| IFile child = link.getFile(childName); |
| assertTrue("2.0", child.exists()); |
| assertTrue("2.1", link.isLinked()); |
| assertTrue("2.2", link.isLinked(IResource.NONE)); |
| assertTrue("2.3", link.isLinked(IResource.CHECK_ANCESTORS)); |
| assertTrue("2.1", !child.isLinked()); |
| assertTrue("2.2", !child.isLinked(IResource.NONE)); |
| assertTrue("2.3", child.isLinked(IResource.CHECK_ANCESTORS)); |
| |
| } |
| |
| /** |
| * Tests the |
| * {@link org.eclipse.core.resources.IResource#setLinkLocation(URI , int , IProgressMonitor )} |
| * method. |
| */ |
| public void testsetLinkLocation() { |
| // initially nothing is linked |
| IResource[] toTest = new IResource[] {closedProject, existingFileInExistingProject, existingFolderInExistingFolder, existingFolderInExistingProject, existingProject, nonExistingFileInExistingFolder, nonExistingFileInExistingProject, nonExistingFileInOtherExistingProject, nonExistingFolderInExistingFolder, nonExistingFolderInExistingProject, nonExistingFolderInNonExistingFolder, nonExistingFolderInNonExistingProject, nonExistingFolderInOtherExistingProject, nonExistingProject, otherExistingProject}; |
| for (int i = 0; i < toTest.length; i++) { |
| assertTrue("1.0 " + toTest[i], !toTest[i].isLinked()); |
| assertTrue("1.1 " + toTest[i], !toTest[i].isLinked(IResource.NONE)); |
| assertTrue("1.2 " + toTest[i], !toTest[i].isLinked(IResource.CHECK_ANCESTORS)); |
| } |
| // create a link |
| IFolder link = nonExistingFolderInExistingProject; |
| try { |
| link.createLink(localFolder, IResource.NONE, getMonitor()); |
| } catch (CoreException e) { |
| fail("1.99", e); |
| } |
| IFile child = link.getFile(childName); |
| assertTrue("2.0", child.exists()); |
| assertTrue("2.1", link.isLinked()); |
| assertTrue("2.2", link.isLinked(IResource.NONE)); |
| assertTrue("2.3", link.isLinked(IResource.CHECK_ANCESTORS)); |
| assertTrue("2.1", !child.isLinked()); |
| assertTrue("2.2", !child.isLinked(IResource.NONE)); |
| assertTrue("2.3", child.isLinked(IResource.CHECK_ANCESTORS)); |
| |
| try { |
| link.createLink(existingFileInExistingProject.getLocationURI(), IResource.REPLACE, getMonitor()); |
| } catch (CoreException e) { |
| fail("2.99", e); |
| } |
| assertTrue("3.1", link.isLinked()); |
| assertTrue("3.2", link.isLinked(IResource.NONE)); |
| assertTrue("3.3", link.isLinked(IResource.CHECK_ANCESTORS)); |
| assertTrue("3.4", link.getLocation().equals(existingFileInExistingProject.getLocation())); |
| } |
| |
| /** |
| * Tests swapping the link location. |
| * This is a regression test for bug 268507 |
| */ |
| public void testSetLinkLocationSwapLinkedResource() { |
| final IPath parentLoc = existingFolderInExistingProject.getLocation(); |
| final IPath childLoc = existingFolderInExistingFolder.getLocation(); |
| |
| try { |
| nonExistingFolderInExistingProject.createLink(parentLoc, IResource.NONE, getMonitor()); |
| nonExistingFolderInOtherExistingProject.createLink(childLoc, IResource.NONE, getMonitor()); |
| create(nonExistingFolderInOtherExistingProject.getFile("foo"), true); |
| |
| assertTrue("2.0", existingFolderInExistingFolder.members().length == 1); |
| assertTrue("3.0", existingFolderInExistingFolder.members()[0].getName().equals("foo")); |
| assertTrue("2.0", nonExistingFolderInOtherExistingProject.members().length == 1); |
| assertTrue("3.0", nonExistingFolderInOtherExistingProject.members()[0].getName().equals("foo")); |
| |
| assertTrue("4.0", nonExistingFolderInExistingProject.members().length == 1); |
| assertTrue("5.0", nonExistingFolderInExistingProject.members()[0].getName().equals(existingFolderInExistingFolder.getName())); |
| } catch (CoreException e) { |
| fail("1.0", e); |
| } |
| |
| // Swap links around |
| try { |
| nonExistingFolderInExistingProject.createLink(childLoc, IResource.REPLACE, getMonitor()); |
| nonExistingFolderInOtherExistingProject.createLink(parentLoc, IResource.REPLACE, getMonitor()); |
| |
| assertTrue("2.0", existingFolderInExistingFolder.members().length == 1); |
| assertTrue("3.0", existingFolderInExistingFolder.members()[0].getName().equals("foo")); |
| assertTrue(nonExistingFolderInExistingProject.getLocation().equals(childLoc)); |
| assertTrue("2.0", nonExistingFolderInExistingProject.members().length == 1); |
| assertTrue("3.0", nonExistingFolderInExistingProject.members()[0].getName().equals("foo")); |
| |
| assertTrue("4.0", nonExistingFolderInOtherExistingProject.members().length == 1); |
| assertTrue("5.0", nonExistingFolderInOtherExistingProject.members()[0].getName().equals(existingFolderInExistingFolder.getName())); |
| } catch (CoreException e) { |
| fail("1.0", e); |
| } |
| } |
| |
| /** |
| * Tests the |
| * {@link org.eclipse.core.resources.IResource#setLinkLocation(IPath, int , IProgressMonitor )} |
| * method. |
| */ |
| public void testsetLinkLocationPath() { |
| //initially nothing is linked |
| IResource[] toTest = new IResource[] {closedProject, existingFileInExistingProject, existingFolderInExistingFolder, existingFolderInExistingProject, existingProject, nonExistingFileInExistingFolder, nonExistingFileInExistingProject, nonExistingFileInOtherExistingProject, nonExistingFolderInExistingFolder, nonExistingFolderInExistingProject, nonExistingFolderInNonExistingFolder, nonExistingFolderInNonExistingProject, nonExistingFolderInOtherExistingProject, nonExistingProject, otherExistingProject}; |
| for (int i = 0; i < toTest.length; i++) { |
| assertTrue("1.0 " + toTest[i], !toTest[i].isLinked()); |
| assertTrue("1.1 " + toTest[i], !toTest[i].isLinked(IResource.NONE)); |
| assertTrue("1.2 " + toTest[i], !toTest[i].isLinked(IResource.CHECK_ANCESTORS)); |
| } |
| //create a link |
| IFolder link = nonExistingFolderInExistingProject; |
| try { |
| link.createLink(localFolder, IResource.NONE, getMonitor()); |
| } catch (CoreException e) { |
| fail("1.99", e); |
| } |
| IFile child = link.getFile(childName); |
| assertTrue("2.0", child.exists()); |
| assertTrue("2.1", link.isLinked()); |
| assertTrue("2.2", link.isLinked(IResource.NONE)); |
| assertTrue("2.3", link.isLinked(IResource.CHECK_ANCESTORS)); |
| assertTrue("2.1", !child.isLinked()); |
| assertTrue("2.2", !child.isLinked(IResource.NONE)); |
| assertTrue("2.3", child.isLinked(IResource.CHECK_ANCESTORS)); |
| |
| try { |
| link.createLink(existingFileInExistingProject.getLocation(), IResource.REPLACE, getMonitor()); |
| } catch (CoreException e) { |
| fail("2.99", e); |
| } |
| assertTrue("3.1", link.isLinked()); |
| assertTrue("3.2", link.isLinked(IResource.NONE)); |
| assertTrue("3.3", link.isLinked(IResource.CHECK_ANCESTORS)); |
| assertTrue("3.4", link.getLocation().equals(existingFileInExistingProject.getLocation())); |
| } |
| |
| /** |
| * Specific testing of links within links. |
| */ |
| public void testLinkedFileInLinkedFolder() { |
| //setup handles |
| IProject project = existingProject; |
| IFolder top = project.getFolder("topFolder"); |
| IFolder linkedFolder = top.getFolder("linkedFolder"); |
| IFolder subFolder = linkedFolder.getFolder("subFolder"); |
| IFile linkedFile = subFolder.getFile("Link.txt"); |
| IFileStore folderStore = getTempStore(); |
| IFileStore subFolderStore = folderStore.getChild(subFolder.getName()); |
| IFileStore fileStore = getTempStore(); |
| IPath folderLocation = URIUtil.toPath(folderStore.toURI()); |
| IPath fileLocation = URIUtil.toPath(fileStore.toURI()); |
| |
| try { |
| //create the structure on disk |
| subFolderStore.mkdir(EFS.NONE, getMonitor()); |
| fileStore.openOutputStream(EFS.NONE, getMonitor()).close(); |
| |
| //create the structure in the workspace |
| ensureExistsInWorkspace(top, true); |
| linkedFolder.createLink(folderStore.toURI(), IResource.NONE, getMonitor()); |
| linkedFile.createLink(fileStore.toURI(), IResource.NONE, getMonitor()); |
| } catch (CoreException e) { |
| fail("4.99", e); |
| } catch (IOException e) { |
| fail("4.99", e); |
| } |
| |
| //assert locations |
| assertEquals("1.0", folderLocation, linkedFolder.getLocation()); |
| assertEquals("1.1", folderLocation.append(subFolder.getName()), subFolder.getLocation()); |
| assertEquals("1.2", fileLocation, linkedFile.getLocation()); |
| //assert URIs |
| assertEquals("1.0", folderStore.toURI(), linkedFolder.getLocationURI()); |
| assertEquals("1.1", subFolderStore.toURI(), subFolder.getLocationURI()); |
| assertEquals("1.2", fileStore.toURI(), linkedFile.getLocationURI()); |
| |
| } |
| |
| /** |
| * Automated test of IFile#createLink |
| */ |
| public void testLinkFile() { |
| IResource[] interestingResources = new IResource[] {existingFileInExistingProject, nonExistingFileInExistingProject, nonExistingFileInExistingFolder}; |
| IPath[] interestingLocations = new IPath[] {localFile, localFolder, nonExistingLocation}; |
| IProgressMonitor[] monitors = new IProgressMonitor[] {new FussyProgressMonitor(), new CancelingProgressMonitor(), null}; |
| Object[][] inputs = new Object[][] {interestingResources, interestingLocations, monitors}; |
| new TestPerformer("LinkedResourceTest.testLinkFile") { |
| protected static final String CANCELED = "canceled"; |
| |
| @Override |
| public void cleanUp(Object[] args, int count) { |
| super.cleanUp(args, count); |
| try { |
| doCleanup(); |
| } catch (Exception e) { |
| fail("invocation " + count + " failed to cleanup", e); |
| } |
| } |
| |
| @Override |
| public Object invokeMethod(Object[] args, int count) throws Exception { |
| IFile file = (IFile) args[0]; |
| IPath location = (IPath) args[1]; |
| IProgressMonitor monitor = (IProgressMonitor) args[2]; |
| if (monitor instanceof FussyProgressMonitor) { |
| ((FussyProgressMonitor) monitor).prepare(); |
| } |
| try { |
| file.createLink(location, IResource.NONE, monitor); |
| } catch (OperationCanceledException e) { |
| return CANCELED; |
| } |
| if (monitor instanceof FussyProgressMonitor) { |
| ((FussyProgressMonitor) monitor).sanityCheck(); |
| } |
| return null; |
| } |
| |
| @Override |
| public boolean shouldFail(Object[] args, int count) { |
| IResource resource = (IResource) args[0]; |
| IPath location = (IPath) args[1]; |
| IProgressMonitor monitor = (IProgressMonitor) args[2]; |
| if (monitor instanceof CancelingProgressMonitor) { |
| return false; |
| } |
| //This resource already exists in the workspace |
| if (resource.exists()) { |
| return true; |
| } |
| IPath resolvedLocation = resolve(location); |
| //The corresponding location in the local file system does not exist. |
| if (!resolvedLocation.toFile().exists()) { |
| return true; |
| } |
| //The workspace contains a resource of a different type at the same path as this resource |
| if (getWorkspace().getRoot().findMember(resource.getFullPath()) != null) { |
| return true; |
| } |
| //The parent of this resource does not exist. |
| if (!resource.getParent().isAccessible()) { |
| return true; |
| } |
| //The name of this resource is not valid (according to IWorkspace.validateName) |
| if (!getWorkspace().validateName(resource.getName(), IResource.FOLDER).isOK()) { |
| return true; |
| } |
| //The corresponding location in the local file system is occupied by a directory (as opposed to a file) |
| if (resolvedLocation.toFile().isDirectory()) { |
| return true; |
| } |
| //passed all failure case so it should succeed |
| return false; |
| } |
| |
| @Override |
| public boolean wasSuccess(Object[] args, Object result, Object[] oldState) throws Exception { |
| IFile resource = (IFile) args[0]; |
| IPath location = (IPath) args[1]; |
| IProgressMonitor monitor = (IProgressMonitor) args[2]; |
| if (result == CANCELED) { |
| return monitor instanceof CancelingProgressMonitor; |
| } |
| IPath resolvedLocation = resolve(location); |
| if (!resource.exists() || !resolvedLocation.toFile().exists()) { |
| return false; |
| } |
| if (!resource.getLocation().equals(resolvedLocation)) { |
| return false; |
| } |
| if (!resource.isSynchronized(IResource.DEPTH_INFINITE)) { |
| return false; |
| } |
| return true; |
| } |
| }.performTest(inputs); |
| } |
| |
| /** |
| * Automated test of IFolder#createLink |
| */ |
| public void testLinkFolder() { |
| IResource[] interestingResources = new IResource[] {existingFolderInExistingProject, existingFolderInExistingFolder, nonExistingFolderInExistingProject, nonExistingFolderInNonExistingProject, nonExistingFolderInNonExistingFolder, nonExistingFolderInExistingFolder}; |
| IPath[] interestingLocations = new IPath[] {localFile, localFolder, nonExistingLocation}; |
| IProgressMonitor[] monitors = new IProgressMonitor[] {new FussyProgressMonitor(), new CancelingProgressMonitor(), null}; |
| Object[][] inputs = new Object[][] {interestingResources, interestingLocations, monitors}; |
| new TestPerformer("LinkedResourceTest.testLinkFolder") { |
| protected static final String CANCELED = "canceled"; |
| |
| @Override |
| public void cleanUp(Object[] args, int count) { |
| super.cleanUp(args, count); |
| try { |
| doCleanup(); |
| } catch (Exception e) { |
| fail("invocation " + count + " failed to cleanup", e); |
| } |
| } |
| |
| @Override |
| public Object invokeMethod(Object[] args, int count) throws Exception { |
| IFolder folder = (IFolder) args[0]; |
| IPath location = (IPath) args[1]; |
| IProgressMonitor monitor = (IProgressMonitor) args[2]; |
| if (monitor instanceof FussyProgressMonitor) { |
| ((FussyProgressMonitor) monitor).prepare(); |
| } |
| try { |
| folder.createLink(location, IResource.NONE, monitor); |
| } catch (OperationCanceledException e) { |
| return CANCELED; |
| } |
| if (monitor instanceof FussyProgressMonitor) { |
| ((FussyProgressMonitor) monitor).sanityCheck(); |
| } |
| return null; |
| } |
| |
| @Override |
| public boolean shouldFail(Object[] args, int count) { |
| IResource resource = (IResource) args[0]; |
| IPath location = (IPath) args[1]; |
| IProgressMonitor monitor = (IProgressMonitor) args[2]; |
| if (monitor instanceof CancelingProgressMonitor) { |
| return false; |
| } |
| //This resource already exists in the workspace |
| if (resource.exists()) { |
| return true; |
| } |
| //The corresponding location in the local file system does not exist. |
| if (!resolve(location).toFile().exists()) { |
| return true; |
| } |
| //The workspace contains a resource of a different type at the same path as this resource |
| if (getWorkspace().getRoot().findMember(resource.getFullPath()) != null) { |
| return true; |
| } |
| //The parent of this resource does not exist. |
| if (!resource.getParent().isAccessible()) { |
| return true; |
| } |
| //The name of this resource is not valid (according to IWorkspace.validateName) |
| if (!getWorkspace().validateName(resource.getName(), IResource.FOLDER).isOK()) { |
| return true; |
| } |
| //The corresponding location in the local file system is occupied by a file (as opposed to a directory) |
| if (resolve(location).toFile().isFile()) { |
| return true; |
| } |
| //passed all failure case so it should succeed |
| return false; |
| } |
| |
| @Override |
| public boolean wasSuccess(Object[] args, Object result, Object[] oldState) throws Exception { |
| IFolder resource = (IFolder) args[0]; |
| IPath location = (IPath) args[1]; |
| IProgressMonitor monitor = (IProgressMonitor) args[2]; |
| if (result == CANCELED) { |
| return monitor instanceof CancelingProgressMonitor; |
| } |
| IPath resolvedLocation = resolve(location); |
| if (!resource.exists() || !resolvedLocation.toFile().exists()) { |
| return false; |
| } |
| if (!resource.getLocation().equals(resolvedLocation)) { |
| return false; |
| } |
| //ensure child exists |
| if (!resource.getFile(childName).exists()) { |
| return false; |
| } |
| return true; |
| } |
| }.performTest(inputs); |
| |
| } |
| |
| /** |
| * Automated test of IWorkspace#validateLinkLocation and IWorkspace#validateLinkLocationURI with empty location |
| * This is a regression test for bug 266662 |
| */ |
| public void testValidateEmptyLinkLocation() { |
| IFolder folder = nonExistingFolderInExistingProject; |
| IPath newLocation = new Path(""); |
| URI newLocationURI = URIUtil.toURI(newLocation); |
| try { |
| IStatus linkedResourceStatus = getWorkspace().validateLinkLocation(folder, newLocation); |
| assertEquals("1.0", IStatus.ERROR, linkedResourceStatus.getSeverity()); |
| linkedResourceStatus = getWorkspace().validateLinkLocationURI(folder, newLocationURI); |
| assertEquals("1.1", IStatus.ERROR, linkedResourceStatus.getSeverity()); |
| } catch (Exception e) { |
| fail("1.99", e); |
| } |
| } |
| |
| /** |
| * Tests creating a linked resource whose location contains a colon character. |
| */ |
| public void testLocationWithColon() { |
| //windows does not allow a location with colon in the name |
| if (isWindows()) { |
| return; |
| } |
| IFolder folder = nonExistingFolderInExistingProject; |
| try { |
| //Note that on *nix, "c:/temp" is a relative path with two segments |
| //so this is treated as relative to an undefined path variable called "c:". |
| IPath location = new Path("c:/temp"); |
| folder.createLink(location, IResource.ALLOW_MISSING_LOCAL, getMonitor()); |
| assertEquals("1.0", location, folder.getRawLocation()); |
| } catch (CoreException e) { |
| fail("1.99", e); |
| } |
| } |
| |
| /** |
| * Tests the timestamp of a linked file when the local file is created or |
| * deleted. See bug 34150 for more details. |
| */ |
| public void testModificationStamp() { |
| IPath location = getRandomLocation(); |
| IFile linkedFile = nonExistingFileInExistingProject; |
| try { |
| try { |
| linkedFile.createLink(location, IResource.ALLOW_MISSING_LOCAL, getMonitor()); |
| } catch (CoreException e) { |
| fail("1.99", e); |
| } |
| assertEquals("1.0", IResource.NULL_STAMP, linkedFile.getModificationStamp()); |
| //create local file |
| try { |
| resolve(location).toFile().createNewFile(); |
| linkedFile.refreshLocal(IResource.DEPTH_INFINITE, getMonitor()); |
| } catch (CoreException e) { |
| fail("2.91", e); |
| } catch (IOException e) { |
| fail("2.92", e); |
| } |
| assertTrue("2.0", linkedFile.getModificationStamp() >= 0); |
| |
| //delete local file |
| ensureDoesNotExistInFileSystem(resolve(location).toFile()); |
| try { |
| linkedFile.refreshLocal(IResource.DEPTH_INFINITE, getMonitor()); |
| } catch (CoreException e) { |
| fail("3.99", e); |
| } |
| assertEquals("4.0", IResource.NULL_STAMP, linkedFile.getModificationStamp()); |
| } finally { |
| Workspace.clear(resolve(location).toFile()); |
| } |
| } |
| |
| public void testMoveFile() { |
| IResource[] sources = new IResource[] {nonExistingFileInExistingProject, nonExistingFileInExistingFolder}; |
| IResource[] destinations = new IResource[] {existingProject, closedProject, nonExistingFileInOtherExistingProject, nonExistingFileInExistingFolder}; |
| Boolean[] deepCopy = new Boolean[] {Boolean.TRUE, Boolean.FALSE}; |
| IProgressMonitor[] monitors = new IProgressMonitor[] {new FussyProgressMonitor(), new CancelingProgressMonitor(), null}; |
| Object[][] inputs = new Object[][] {sources, destinations, deepCopy, monitors}; |
| new TestPerformer("LinkedResourceTest.testMoveFile") { |
| protected static final String CANCELED = "canceled"; |
| |
| @Override |
| public void cleanUp(Object[] args, int count) { |
| super.cleanUp(args, count); |
| try { |
| doCleanup(); |
| } catch (Exception e) { |
| fail("invocation " + count + " failed to cleanup", e); |
| } |
| } |
| |
| @Override |
| public Object invokeMethod(Object[] args, int count) throws Exception { |
| IFile source = (IFile) args[0]; |
| IResource destination = (IResource) args[1]; |
| boolean isDeep = ((Boolean) args[2]).booleanValue(); |
| IProgressMonitor monitor = (IProgressMonitor) args[3]; |
| if (monitor instanceof FussyProgressMonitor) { |
| ((FussyProgressMonitor) monitor).prepare(); |
| } |
| try { |
| source.createLink(localFile, IResource.NONE, null); |
| source.move(destination.getFullPath(), isDeep ? IResource.NONE : IResource.SHALLOW, monitor); |
| } catch (OperationCanceledException e) { |
| return CANCELED; |
| } |
| if (monitor instanceof FussyProgressMonitor) { |
| ((FussyProgressMonitor) monitor).sanityCheck(); |
| } |
| return null; |
| } |
| |
| @Override |
| public boolean shouldFail(Object[] args, int count) { |
| IFile source = (IFile) args[0]; |
| IResource destination = (IResource) args[1]; |
| boolean isDeep = ((Boolean) args[2]).booleanValue(); |
| IProgressMonitor monitor = (IProgressMonitor) args[3]; |
| if (monitor instanceof CancelingProgressMonitor) { |
| return false; |
| } |
| IResource parent = destination.getParent(); |
| if (!isDeep && parent == null) { |
| return true; |
| } |
| if (!parent.isAccessible()) { |
| return true; |
| } |
| if (source.equals(destination)) { |
| return true; |
| } |
| if (source.getType() != destination.getType()) { |
| return true; |
| } |
| if (destination.exists()) { |
| return true; |
| } |
| //passed all failure case so it should succeed |
| return false; |
| } |
| |
| @Override |
| public boolean wasSuccess(Object[] args, Object result, Object[] oldState) throws Exception { |
| IResource destination = (IResource) args[1]; |
| boolean isDeep = ((Boolean) args[2]).booleanValue(); |
| IProgressMonitor monitor = (IProgressMonitor) args[3]; |
| IPath sourceLocation = resolve(localFile); |
| URI sourceLocationURI = URIUtil.toURI(sourceLocation); |
| if (result == CANCELED) { |
| return monitor instanceof CancelingProgressMonitor; |
| } |
| if (!destination.exists()) { |
| return false; |
| } |
| //destination should only be linked for a shallow move |
| if (isDeep) { |
| if (destination.isLinked()) { |
| return false; |
| } |
| if (resolve(localFile).equals(destination.getLocation())) { |
| return false; |
| } |
| if (!destination.getProject().getLocation().isPrefixOf(destination.getLocation())) { |
| return false; |
| } |
| } else { |
| if (!destination.isLinked()) { |
| return false; |
| } |
| if (!sourceLocation.equals(destination.getLocation())) { |
| return false; |
| } |
| if (!sourceLocationURI.equals(destination.getLocationURI())) { |
| return false; |
| } |
| } |
| return true; |
| } |
| }.performTest(inputs); |
| } |
| |
| public void testMoveFolder() { |
| IResource[] sourceResources = new IResource[] {nonExistingFolderInExistingProject, nonExistingFolderInExistingFolder}; |
| IResource[] destinationResources = new IResource[] {existingProject, closedProject, nonExistingProject, existingFolderInExistingProject, nonExistingFolderInOtherExistingProject, nonExistingFolderInExistingFolder}; |
| IProgressMonitor[] monitors = new IProgressMonitor[] {new FussyProgressMonitor(), new CancelingProgressMonitor(), null}; |
| Object[][] inputs = new Object[][] {sourceResources, destinationResources, monitors}; |
| new TestPerformer("LinkedResourceTest.testMoveFolder") { |
| protected static final String CANCELED = "canceled"; |
| |
| @Override |
| public void cleanUp(Object[] args, int count) { |
| super.cleanUp(args, count); |
| try { |
| doCleanup(); |
| } catch (Exception e) { |
| fail("invocation " + count + " failed to cleanup", e); |
| } |
| } |
| |
| @Override |
| public Object invokeMethod(Object[] args, int count) throws Exception { |
| IFolder source = (IFolder) args[0]; |
| IResource destination = (IResource) args[1]; |
| IProgressMonitor monitor = (IProgressMonitor) args[2]; |
| if (monitor instanceof FussyProgressMonitor) { |
| ((FussyProgressMonitor) monitor).prepare(); |
| } |
| try { |
| source.createLink(localFolder, IResource.NONE, null); |
| source.move(destination.getFullPath(), IResource.SHALLOW, monitor); |
| } catch (OperationCanceledException e) { |
| return CANCELED; |
| } |
| if (monitor instanceof FussyProgressMonitor) { |
| ((FussyProgressMonitor) monitor).sanityCheck(); |
| } |
| return null; |
| } |
| |
| @Override |
| public boolean shouldFail(Object[] args, int count) { |
| IFolder source = (IFolder) args[0]; |
| IResource destination = (IResource) args[1]; |
| IProgressMonitor monitor = (IProgressMonitor) args[2]; |
| if (monitor instanceof CancelingProgressMonitor) { |
| return false; |
| } |
| IResource parent = destination.getParent(); |
| if (parent == null) { |
| return true; |
| } |
| if (source.equals(destination)) { |
| return true; |
| } |
| if (source.getType() != destination.getType()) { |
| return true; |
| } |
| if (!parent.isAccessible()) { |
| return true; |
| } |
| if (destination.exists()) { |
| return true; |
| } |
| //passed all failure case so it should succeed |
| return false; |
| } |
| |
| @Override |
| public boolean wasSuccess(Object[] args, Object result, Object[] oldState) throws Exception { |
| IResource destination = (IResource) args[1]; |
| IProgressMonitor monitor = (IProgressMonitor) args[2]; |
| if (result == CANCELED) { |
| return monitor instanceof CancelingProgressMonitor; |
| } |
| if (!destination.exists()) { |
| return false; |
| } |
| if (!destination.isLinked()) { |
| return false; |
| } |
| if (!resolve(localFolder).equals(destination.getLocation())) { |
| return false; |
| } |
| return true; |
| } |
| }.performTest(inputs); |
| } |
| |
| /** |
| * Tests moving a linked file resource that doesn't exist in the file system |
| */ |
| public void testMoveMissingFile() { |
| IPath location = getRandomLocation(); |
| IFile linkedFile = nonExistingFileInExistingProject; |
| try { |
| linkedFile.createLink(location, IResource.ALLOW_MISSING_LOCAL, getMonitor()); |
| } catch (CoreException e) { |
| fail("1.99", e); |
| } |
| |
| IFile dest = existingProject.getFile("FailedMoveDest"); |
| try { |
| linkedFile.move(dest.getFullPath(), IResource.NONE, getMonitor()); |
| fail("2.0"); |
| } catch (CoreException e1) { |
| //should fail |
| } |
| assertTrue("2.1", !dest.exists()); |
| try { |
| linkedFile.move(dest.getFullPath(), IResource.FORCE, getMonitor()); |
| fail("2.2"); |
| } catch (CoreException e1) { |
| //should fail |
| } |
| assertTrue("2.3", !dest.exists()); |
| } |
| |
| /** |
| * Tests moving a linked folder that doesn't exist in the file system |
| */ |
| public void testMoveMissingFolder() { |
| IPath location = getRandomLocation(); |
| IFolder linkedFolder = nonExistingFolderInExistingProject; |
| try { |
| linkedFolder.createLink(location, IResource.ALLOW_MISSING_LOCAL, getMonitor()); |
| } catch (CoreException e) { |
| fail("1.99", e); |
| } |
| |
| IFolder dest = existingProject.getFolder("FailedMoveDest"); |
| try { |
| linkedFolder.move(dest.getFullPath(), IResource.NONE, getMonitor()); |
| fail("2.0"); |
| } catch (CoreException e1) { |
| //should fail |
| } |
| assertTrue("2.1", !dest.exists()); |
| try { |
| linkedFolder.move(dest.getFullPath(), IResource.FORCE, getMonitor()); |
| fail("2.2"); |
| } catch (CoreException e1) { |
| //should fail |
| } |
| assertTrue("2.3", !dest.exists()); |
| } |
| |
| public void testMoveProjectWithLinks() { |
| IPath fileLocation = getRandomLocation(); |
| IFile file = nonExistingFileInExistingProject; |
| IFolder folder = nonExistingFolderInExistingProject; |
| IFile childFile = folder.getFile(childName); |
| IResource[] oldResources = new IResource[] {file, folder, existingProject, childFile}; |
| try { |
| try { |
| createFileInFileSystem(resolve(fileLocation)); |
| folder.createLink(localFolder, IResource.NONE, getMonitor()); |
| file.createLink(fileLocation, IResource.NONE, getMonitor()); |
| } catch (CoreException e) { |
| fail("1.0", e); |
| } |
| |
| //move the project |
| IProject destination = getWorkspace().getRoot().getProject("MoveTargetProject"); |
| IFile newFile = destination.getFile(file.getProjectRelativePath()); |
| IFolder newFolder = destination.getFolder(folder.getProjectRelativePath()); |
| IFile newChildFile = newFolder.getFile(childName); |
| IResource[] newResources = new IResource[] {destination, newFile, newFolder, newChildFile}; |
| |
| assertDoesNotExistInWorkspace("2.0", destination); |
| |
| try { |
| existingProject.move(destination.getFullPath(), IResource.SHALLOW, getMonitor()); |
| } catch (CoreException e) { |
| fail("2.1", e); |
| } |
| assertExistsInWorkspace("3.0", newResources); |
| assertDoesNotExistInWorkspace("3.1", oldResources); |
| |
| assertTrue("3.2", newFile.isLinked()); |
| assertEquals("3.3", resolve(fileLocation), newFile.getLocation()); |
| |
| assertTrue("3.4", newFolder.isLinked()); |
| assertEquals("3.5", resolve(localFolder), newFolder.getLocation()); |
| |
| assertTrue("3.6", destination.isSynchronized(IResource.DEPTH_INFINITE)); |
| |
| //now do a deep move back to the original project |
| try { |
| destination.move(existingProject.getFullPath(), IResource.NONE, getMonitor()); |
| } catch (CoreException e) { |
| fail("5.0", e); |
| } |
| assertExistsInWorkspace("5.1", oldResources); |
| assertDoesNotExistInWorkspace("5.2", newResources); |
| assertTrue("5.3", !file.isLinked()); |
| assertTrue("5.4", !folder.isLinked()); |
| assertEquals("5.5", existingProject.getLocation().append(file.getProjectRelativePath()), file.getLocation()); |
| assertEquals("5.6", existingProject.getLocation().append(folder.getProjectRelativePath()), folder.getLocation()); |
| assertTrue("5.7", existingProject.isSynchronized(IResource.DEPTH_INFINITE)); |
| assertTrue("5.8", destination.isSynchronized(IResource.DEPTH_INFINITE)); |
| } finally { |
| Workspace.clear(resolve(fileLocation).toFile()); |
| } |
| } |
| |
| /** |
| * Tests bug 117402. |
| */ |
| public void testMoveProjectWithLinks2() { |
| IPath fileLocation = getRandomLocation(); |
| IFile linkedFile = existingProject.getFile("(test)"); |
| try { |
| try { |
| createFileInFileSystem(resolve(fileLocation), getRandomContents()); |
| linkedFile.createLink(fileLocation, IResource.NONE, getMonitor()); |
| } catch (CoreException e) { |
| fail("1.0", e); |
| } |
| |
| //move the project |
| IProject destination = getWorkspace().getRoot().getProject("CopyTargetProject"); |
| try { |
| existingProject.move(destination.getFullPath(), IResource.SHALLOW, getMonitor()); |
| } catch (CoreException e) { |
| fail("2.0", e); |
| } |
| |
| IFile newFile = destination.getFile(linkedFile.getProjectRelativePath()); |
| assertTrue("3.0", newFile.isLinked()); |
| assertEquals("3.1", resolve(fileLocation), newFile.getLocation()); |
| } finally { |
| Workspace.clear(resolve(fileLocation).toFile()); |
| } |
| } |
| |
| /** |
| * Tests bug 298849. |
| */ |
| public void testMoveFolderWithLinks() { |
| // create a folder |
| IFolder folderWithLinks = existingProject.getFolder(getUniqueString()); |
| try { |
| folderWithLinks.create(true, true, getMonitor()); |
| } catch (CoreException e) { |
| fail("1.0", e); |
| } |
| |
| IPath fileLocation = getRandomLocation(); |
| try { |
| createFileInFileSystem(resolve(fileLocation), getRandomContents()); |
| |
| // create a linked file in the folder |
| IFile linkedFile = folderWithLinks.getFile(getUniqueString()); |
| try { |
| linkedFile.createLink(fileLocation, IResource.NONE, getMonitor()); |
| } catch (CoreException e) { |
| fail("2.0", e); |
| } |
| |
| // there should be an entry in .project for the linked file |
| String string = readStringInFileSystem(existingProject.getFile(".project")); |
| assertTrue("3.0", string.indexOf(linkedFile.getProjectRelativePath().toString()) != -1); |
| |
| // move the folder |
| try { |
| folderWithLinks.move(otherExistingProject.getFolder(getUniqueString()).getFullPath(), IResource.SHALLOW | IResource.ALLOW_MISSING_LOCAL, getMonitor()); |
| } catch (CoreException e) { |
| fail("4.0", e); |
| } |
| |
| // both the folder and link in the source project should not exist |
| assertFalse("5.0", folderWithLinks.exists()); |
| assertFalse("6.0", linkedFile.exists()); |
| |
| // the project description should not contain links |
| HashMap<IPath, LinkDescription> links = null; |
| try { |
| links = ((ProjectDescription) existingProject.getDescription()).getLinks(); |
| } catch (CoreException e) { |
| fail("7.0", e); |
| } |
| assertNull("8.0", links); |
| |
| // and the entry from .project should be removed |
| string = readStringInFileSystem(existingProject.getFile(".project")); |
| assertEquals("9.0", -1, string.indexOf(linkedFile.getProjectRelativePath().toString())); |
| } finally { |
| Workspace.clear(resolve(fileLocation).toFile()); |
| } |
| } |
| |
| public void testNatureVeto() { |
| //note: simpleNature has the link veto turned on. |
| |
| //test create link on project with nature veto |
| try { |
| IProjectDescription description = existingProject.getDescription(); |
| description.setNatureIds(new String[] {NATURE_SIMPLE}); |
| existingProject.setDescription(description, IResource.NONE, getMonitor()); |
| } catch (CoreException e) { |
| fail("1.0", e); |
| } |
| try { |
| nonExistingFolderInExistingProject.createLink(localFolder, IResource.NONE, getMonitor()); |
| fail("1.1"); |
| } catch (CoreException e) { |
| //should fail |
| } |
| try { |
| nonExistingFileInExistingProject.createLink(localFile, IResource.NONE, getMonitor()); |
| fail("1.2"); |
| } catch (CoreException e) { |
| //should fail |
| } |
| |
| //test add nature with veto to project that already has link |
| try { |
| existingProject.delete(IResource.FORCE, getMonitor()); |
| existingProject.create(getMonitor()); |
| existingProject.open(getMonitor()); |
| nonExistingFolderInExistingProject.createLink(localFolder, IResource.NONE, getMonitor()); |
| } catch (CoreException e) { |
| fail("2.0", e); |
| } |
| try { |
| IProjectDescription description = existingProject.getDescription(); |
| description.setNatureIds(new String[] {NATURE_SIMPLE}); |
| existingProject.setDescription(description, IResource.NONE, getMonitor()); |
| fail("3.0"); |
| } catch (CoreException e) { |
| //should fail |
| } |
| } |
| |
| /** |
| * Tests creating a link within a link, and ensuring that both links still |
| * exist when the project is closed/opened (bug 177367). |
| */ |
| public void testNestedLink() { |
| final IFileStore store1 = getTempStore(); |
| final IFileStore store2 = getTempStore(); |
| URI location1 = store1.toURI(); |
| URI location2 = store2.toURI(); |
| //folder names are important here, because we want a certain order in the link hash map |
| IFolder link = existingProject.getFolder("aA"); |
| IFolder linkChild = link.getFolder("b"); |
| try { |
| store1.mkdir(EFS.NONE, getMonitor()); |
| store2.mkdir(EFS.NONE, getMonitor()); |
| link.createLink(location1, IResource.NONE, getMonitor()); |
| linkChild.createLink(location2, IResource.NONE, getMonitor()); |
| } catch (CoreException e) { |
| fail("0.99", e); |
| } |
| assertTrue("1.0", link.exists()); |
| assertTrue("1.1", link.isLinked()); |
| assertTrue("1.2", linkChild.exists()); |
| assertTrue("1.3", linkChild.isLinked()); |
| assertEquals("1.4", location1, link.getLocationURI()); |
| assertEquals("1.5", location2, linkChild.getLocationURI()); |
| |
| //now delete and recreate the project |
| try { |
| existingProject.delete(IResource.NEVER_DELETE_PROJECT_CONTENT, getMonitor()); |
| existingProject.create(getMonitor()); |
| existingProject.open(IResource.NONE, getMonitor()); |
| } catch (CoreException e) { |
| fail("1.99", e); |
| } |
| |
| assertTrue("2.0", link.exists()); |
| assertTrue("2.1", link.isLinked()); |
| assertTrue("2.2", linkChild.exists()); |
| assertTrue("2.3", linkChild.isLinked()); |
| assertEquals("2.4", location1, link.getLocationURI()); |
| assertEquals("2.5", location2, linkChild.getLocationURI()); |
| |
| } |
| |
| /** |
| * Create a project with a linked resource at depth > 2, and refresh it. |
| */ |
| public void testRefreshDeepLink() { |
| IFolder link = nonExistingFolderInExistingFolder; |
| IPath linkLocation = localFolder; |
| IPath localChild = linkLocation.append("Child"); |
| IFile linkChild = link.getFile(localChild.lastSegment()); |
| createFileInFileSystem(resolve(localChild)); |
| try { |
| link.createLink(linkLocation, IResource.NONE, getMonitor()); |
| } catch (CoreException e) { |
| fail("0.99", e); |
| } |
| assertTrue("1.0", link.exists()); |
| assertTrue("1.1", linkChild.exists()); |
| |
| try { |
| IProject project = link.getProject(); |
| project.refreshLocal(IResource.DEPTH_INFINITE, getMonitor()); |
| } catch (CoreException e) { |
| fail("1.99", e); |
| } |
| |
| assertTrue("2.0", link.exists()); |
| assertTrue("2.1", linkChild.exists()); |
| } |
| |
| public void testLinkedFolderWithOverlappingLocation_Bug293935_() { |
| IWorkspace workspace = getWorkspace(); |
| |
| IPath projectLocation = existingProject.getLocation(); |
| IFolder folderByIPath = existingProject.getFolder("overlappingLinkedFolderByIPath"); |
| assertTrue("1.1", !workspace.validateLinkLocation(folderByIPath, projectLocation).isOK()); |
| try { |
| folderByIPath.createLink(projectLocation, IResource.NONE, getMonitor()); |
| fail("1.2"); |
| } catch (CoreException e) { |
| // expected to fail |
| } |
| |
| URI projectLocationURI = existingProject.getLocationURI(); |
| IFolder folderByURI = existingProject.getFolder("overlappingLinkedFolderByURI"); |
| assertTrue("2.1", !workspace.validateLinkLocationURI(folderByURI, projectLocationURI).isOK()); |
| try { |
| folderByURI.createLink(projectLocationURI, IResource.NONE, getMonitor()); |
| fail("2.2"); |
| } catch (CoreException e) { |
| // expected to fail just like when creating link by IPath |
| } |
| |
| // device is missing |
| |
| IPath projectLocationWithoutDevice = projectLocation.setDevice(null); |
| IFolder folderByUnixLikeIPath = existingProject.getFolder("overlappingLinkedFolderByUnixLikeIPath"); |
| assertTrue("3.1", !workspace.validateLinkLocation(folderByUnixLikeIPath, projectLocationWithoutDevice).isOK()); |
| try { |
| folderByUnixLikeIPath.createLink(projectLocationWithoutDevice, IResource.NONE, getMonitor()); |
| fail("3.2"); |
| } catch (CoreException e) { |
| // expected to fail |
| } |
| |
| URI projectLocationURIWithoutDevice = URIUtil.toURI(projectLocationWithoutDevice.toString()); |
| IFolder folderByUnixLikeURI = existingProject.getFolder("overlappingLinkedFolderByUnixLikeURI"); |
| assertTrue("4.1", !workspace.validateLinkLocationURI(folderByUnixLikeURI, projectLocationURIWithoutDevice).isOK()); |
| try { |
| folderByUnixLikeURI.createLink(projectLocationURIWithoutDevice, IResource.NONE, getMonitor()); |
| fail("4.2"); |
| } catch (CoreException e) { |
| // expected to fail |
| } |
| } |
| |
| public void testLinkedFolderWithSymlink_Bug338010() { |
| // Only activate this test if testing of symbolic links is possible. |
| if (!canCreateSymLinks()) { |
| return; |
| } |
| IPath baseLocation = getRandomLocation(); |
| IPath resolvedBaseLocation = resolve(baseLocation); |
| deleteOnTearDown(resolvedBaseLocation); |
| IPath symlinkTarget = resolvedBaseLocation.append("dir1/target"); |
| symlinkTarget.toFile().mkdirs(); |
| createSymLink(resolvedBaseLocation.toFile(), "symlink", symlinkTarget.toOSString(), true); |
| IPath linkChildLocation = baseLocation.append("symlink/dir2"); |
| IPath resolvedLinkChildLocation = resolve(linkChildLocation); |
| File linkChild = resolvedLinkChildLocation.toFile(); |
| linkChild.mkdir(); |
| assertTrue("Could not create link at location: " + linkChild, linkChild.exists()); |
| |
| IFolder folder = nonExistingFolderInExistingProject; |
| try { |
| folder.createLink(linkChildLocation, IResource.NONE, getMonitor()); |
| } catch (CoreException e) { |
| fail("1.1", e); |
| } |
| // Check that the symlink is preserved. |
| assertEquals("1.2", resolvedLinkChildLocation, folder.getLocation()); |
| } |
| |
| /** |
| * Tests deleting of the target of a linked folder that itself is a symbolic link. |
| */ |
| public void testDeleteLinkTarget_Bug507084() throws Exception { |
| // Only activate this test if testing of symbolic links is possible. |
| if (!canCreateSymLinks()) { |
| return; |
| } |
| IPath baseLocation = getRandomLocation(); |
| IPath resolvedBaseLocation = resolve(baseLocation); |
| deleteOnTearDown(resolvedBaseLocation); |
| IPath symlinkTarget = resolvedBaseLocation.append("dir1/A"); |
| symlinkTarget.append("B/C").toFile().mkdirs(); |
| IPath linkParentDir = resolvedBaseLocation.append("dir2"); |
| linkParentDir.toFile().mkdirs(); |
| createSymLink(linkParentDir.toFile(), "symlink", symlinkTarget.toOSString(), true); |
| |
| IFolder folder = nonExistingFolderInExistingProject; |
| IPath symLink = linkParentDir.append("symlink"); |
| folder.createLink(symLink, IResource.NONE, getMonitor()); |
| assertTrue("1.1", folder.exists()); |
| assertTrue("1.2", folder.getFolder("B/C").exists()); |
| assertEquals("1.3", symLink, folder.getLocation()); |
| // Delete the symlink and the directory that contains it. |
| symLink.toFile().delete(); |
| linkParentDir.toFile().delete(); |
| // Check that the directory that contained the symlink has been deleted. |
| assertFalse("2.1", linkParentDir.toFile().exists()); |
| // Refresh the project. |
| folder.getParent().refreshLocal(IResource.DEPTH_INFINITE, getMonitor()); |
| // Check that the linked folder still exists. |
| assertTrue("3.1", folder.exists()); |
| // Check that the contents of the linked folder no longer exist. |
| assertFalse("3.2", folder.getFolder("B").exists()); |
| assertFalse("3.3", folder.getFolder("B/C").exists()); |
| } |
| } |