blob: 5609551545b7263fdf3f52822b8ce9b4c8928e21 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2000, 2015 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
* Martin Oberhuber (Wind River) - testImportWrongLineEndings() for bug [210664]
* Serge Beauchamp (Freescale Semiconductor) - [229633] Add Project Path Variables
*******************************************************************************/
package org.eclipse.core.tests.resources;
import java.io.*;
import java.net.URI;
import java.util.ArrayList;
import junit.framework.Test;
import junit.framework.TestSuite;
import org.eclipse.core.filesystem.*;
import org.eclipse.core.filesystem.URIUtil;
import org.eclipse.core.internal.resources.Workspace;
import org.eclipse.core.resources.*;
import org.eclipse.core.runtime.*;
import org.eclipse.core.tests.harness.FileSystemHelper;
/**
* This class extends <code>LinkedResourceTest</code> in order to use
* randomly generated locations that are always variable-based.
* TODO: add tests specific to linking resources using path variables (then
* removing the variable, change the variable value, etc)
*/
public class LinkedResourceWithPathVariableTest extends LinkedResourceTest {
private final static String VARIABLE_NAME = "ROOT";
private final static String PROJECT_VARIABLE_NAME = "PROOT";
private final static String PROJECT_RELATIVE_VARIABLE_NAME = "RELATIVE_PROOT";
private final static String PROJECT_RELATIVE_VARIABLE_VALUE = "${PROOT}";
private final ArrayList<IPath> toDelete = new ArrayList<>();
private IFileStore toSetWritable = null;
public LinkedResourceWithPathVariableTest() {
super();
}
public LinkedResourceWithPathVariableTest(String name) {
super(name);
}
public static Test suite() {
return new TestSuite(LinkedResourceWithPathVariableTest.class);
// TestSuite suite = new TestSuite();
// suite.addTest(new LinkedResourceWithPathVariableTest("testMoveFile"));
// return suite;
}
@Override
protected void setUp() throws Exception {
IPath base = super.getRandomLocation();
toDelete.add(base);
getWorkspace().getPathVariableManager().setValue(VARIABLE_NAME, base);
base = super.getRandomLocation();
toDelete.add(base);
super.setUp();
existingProject.getPathVariableManager().setValue(PROJECT_VARIABLE_NAME, base);
existingProject.getPathVariableManager().setValue(PROJECT_RELATIVE_VARIABLE_NAME, Path.fromPortableString(PROJECT_RELATIVE_VARIABLE_VALUE));
}
@Override
protected void tearDown() throws Exception {
if (toSetWritable != null) {
IFileInfo info = toSetWritable.fetchInfo();
info.setAttribute(EFS.ATTRIBUTE_READ_ONLY, false);
toSetWritable.putInfo(info, EFS.SET_ATTRIBUTES, getMonitor());
toSetWritable = null;
}
getWorkspace().getPathVariableManager().setValue(VARIABLE_NAME, null);
IPath[] paths = toDelete.toArray(new IPath[toDelete.size()]);
toDelete.clear();
for (IPath path : paths) {
Workspace.clear(path.toFile());
}
super.tearDown();
}
/**
* Copy file "inStore" into file "outStore", converting line endings as follows:
* <ul>
* <li>DOS, or MAC (CR or CRLF) into UNIX (LF)</li>
* <li>UNIX (LF) into DOS (CRLF)</li>
* </ul>
* @param inStore handle to an existing text file to convert
* @param outStore handle to non-existing file which will be written
*/
protected void convertLineEndings(IFileStore inStore, IFileStore outStore, IProgressMonitor mon) throws CoreException, IOException {
InputStream is = null;
OutputStream os = null;
try {
is = inStore.openInputStream(EFS.NONE, mon);
os = outStore.openOutputStream(EFS.NONE, new NullProgressMonitor());
int prevb = 0;
int ib = is.read();
while (ib >= 0) {
switch (ib) {
case '\r' :
os.write('\n');
break;
case '\n' :
if (prevb != '\r') { /* not converted already */
os.write('\r');
os.write('\n');
}
break;
default :
os.write(ib);
break;
}
prevb = ib;
ib = is.read();
}
} finally {
if (is != null) {
is.close();
}
if (os != null) {
os.close();
}
}
}
/**
* @see org.eclipse.core.tests.harness.ResourceTest#getRandomLocation()
*/
@Override
public IPath getRandomLocation() {
IPathVariableManager pathVars = getWorkspace().getPathVariableManager();
//low order bits are current time, high order bits are static counter
IPath parent = new Path(VARIABLE_NAME);
IPath path = FileSystemHelper.computeRandomLocation(parent);
while (pathVars.resolvePath(path).toFile().exists()) {
try {
Thread.sleep(10);
} catch (InterruptedException e) {
// ignore
}
path = FileSystemHelper.computeRandomLocation(parent);
}
toDelete.add(pathVars.resolvePath(path));
return path;
}
/**
* @see org.eclipse.core.tests.harness.ResourceTest#getRandomLocation()
*/
public IPath getRandomProjectLocation() {
IPathVariableManager pathVars = getWorkspace().getPathVariableManager();
// low order bits are current time, high order bits are static counter
IPath parent = new Path(PROJECT_VARIABLE_NAME);
IPath path = FileSystemHelper.computeRandomLocation(parent);
while (pathVars.resolvePath(path).toFile().exists()) {
try {
Thread.sleep(10);
} catch (InterruptedException e) {
// ignore
}
path = FileSystemHelper.computeRandomLocation(parent);
}
toDelete.add(pathVars.resolvePath(path));
return path;
}
/**
* @see org.eclipse.core.tests.harness.ResourceTest#getRandomLocation()
*/
public IPath getRandomRelativeProjectLocation() {
IPathVariableManager pathVars = getWorkspace().getPathVariableManager();
// low order bits are current time, high order bits are static counter
IPath parent = new Path(PROJECT_RELATIVE_VARIABLE_NAME);
IPath path = FileSystemHelper.computeRandomLocation(parent);
while (pathVars.resolvePath(path).toFile().exists()) {
try {
Thread.sleep(10);
} catch (InterruptedException e) {
// ignore
}
path = FileSystemHelper.computeRandomLocation(parent);
}
toDelete.add(pathVars.resolvePath(path));
return path;
}
/**
* @see LinkedResourceTest#resolve(org.eclipse.core.runtime.IPath)
*/
@Override
protected IPath resolve(IPath path) {
return getWorkspace().getPathVariableManager().resolvePath(path);
}
/**
* @see LinkedResourceTest#resolve(java.net.URI)
*/
@Override
protected URI resolve(URI uri) {
return getWorkspace().getPathVariableManager().resolveURI(uri);
}
public void testProjectResolution() {
final IPathVariableManager manager = existingProject.getPathVariableManager();
IPath value = manager.getValue(PROJECT_VARIABLE_NAME);
IPath relativeValue = manager.getValue(PROJECT_RELATIVE_VARIABLE_NAME);
assertTrue("1.0", !value.equals(relativeValue));
IPath resolvedValue = manager.resolvePath(value);
assertTrue("1.1", value.equals(resolvedValue));
IPath resolvedRelativeValue = manager.resolvePath(relativeValue);
assertTrue("1.2", !relativeValue.equals(resolvedRelativeValue));
assertTrue("1.3", resolvedValue.equals(resolvedRelativeValue));
}
/**
* Tests a scenario where a variable used in a linked file location is
* removed.
*/
public void testFileVariableRemoved() {
final IPathVariableManager manager = getWorkspace().getPathVariableManager();
IFile file = nonExistingFileInExistingProject;
IPath existingValue = manager.getValue(VARIABLE_NAME);
// creates a variable-based location
IPath variableBasedLocation = getRandomLocation();
// the file should not exist yet
assertDoesNotExistInWorkspace("1.0", file);
try {
file.createLink(variableBasedLocation, IResource.ALLOW_MISSING_LOCAL, null);
} catch (CoreException e) {
fail("1.1", e);
}
try {
file.setContents(getContents("contents for a file"), IResource.FORCE, null);
} catch (CoreException e) {
fail("1.2", e);
}
// now the file exists in both workspace and file system
assertExistsInWorkspace("2.0", file);
assertExistsInFileSystem("2.1", file);
// removes the variable - the location will be undefined (null)
try {
manager.setValue(VARIABLE_NAME, null);
} catch (CoreException e) {
fail("3.0", e);
}
assertExistsInWorkspace("3,1", file);
//refresh local - should not fail or make the link disappear
try {
file.refreshLocal(IResource.DEPTH_ONE, getMonitor());
file.getProject().refreshLocal(IResource.DEPTH_INFINITE, getMonitor());
} catch (CoreException e) {
fail("3.2");
}
assertExistsInWorkspace("3.3", file);
// try to change resource's contents
try {
file.setContents(getContents("new contents"), IResource.NONE, null);
// Resource has no-defined location - should fail
fail("3.4");
} catch (CoreException re) {
// success: resource had no defined location
}
assertExistsInWorkspace("3.5", file);
// the location is null
assertNull("3.6", file.getLocation());
// try validating another link location while there is a link with null location
IFile other = existingProject.getFile("OtherVar");
getWorkspace().validateLinkLocation(other, getRandomLocation());
// re-creates the variable with its previous value
try {
manager.setValue(VARIABLE_NAME, existingValue);
} catch (CoreException e) {
fail("4.0", e);
}
assertExistsInWorkspace("5.0", file);
assertNotNull("5.1", file.getLocation());
assertExistsInFileSystem("5.2", file);
// the contents must be the original ones
try {
assertTrue("5.3", compareContent(file.getContents(true), getContents("contents for a file")));
} catch (CoreException e) {
fail("5.4", e);
}
}
/**
* Tests a scenario where a variable used in a linked file location is
* removed.
*/
public void testFileProjectVariableRemoved() {
final IPathVariableManager manager = existingProject.getPathVariableManager();
IFile file = nonExistingFileInExistingProject;
IPath existingValue = manager.getValue(PROJECT_VARIABLE_NAME);
// creates a variable-based location
IPath variableBasedLocation = getRandomProjectLocation();
// the file should not exist yet
assertDoesNotExistInWorkspace("1.0", file);
try {
file.createLink(variableBasedLocation, IResource.ALLOW_MISSING_LOCAL, null);
} catch (CoreException e) {
fail("1.1", e);
}
try {
file.setContents(getContents("contents for a file"), IResource.FORCE, null);
} catch (CoreException e) {
fail("1.2", e);
}
// now the file exists in both workspace and file system
assertExistsInWorkspace("2.0", file);
assertExistsInFileSystem("2.1", file);
// removes the variable - the location will be undefined (null)
try {
manager.setValue(PROJECT_VARIABLE_NAME, null);
} catch (CoreException e) {
fail("3.0", e);
}
assertExistsInWorkspace("3,1", file);
// refresh local - should not fail or make the link disappear
try {
file.refreshLocal(IResource.DEPTH_ONE, getMonitor());
file.getProject().refreshLocal(IResource.DEPTH_INFINITE, getMonitor());
} catch (CoreException e) {
fail("3.2");
}
assertExistsInWorkspace("3.3", file);
// try to change resource's contents
try {
file.setContents(getContents("new contents"), IResource.NONE, null);
// Resource has no-defined location - should fail
fail("3.4");
} catch (CoreException re) {
// success: resource had no defined location
}
assertExistsInWorkspace("3.5", file);
// the location is null
assertNull("3.6", file.getLocation());
// try validating another link location while there is a link with null
// location
IFile other = existingProject.getFile("OtherVar");
getWorkspace().validateLinkLocation(other, getRandomLocation());
// re-creates the variable with its previous value
try {
manager.setValue(PROJECT_VARIABLE_NAME, existingValue);
} catch (CoreException e) {
fail("4.0", e);
}
assertExistsInWorkspace("5.0", file);
assertNotNull("5.1", file.getLocation());
assertExistsInFileSystem("5.2", file);
// the contents must be the original ones
try {
assertTrue("5.3", compareContent(file.getContents(true), getContents("contents for a file")));
} catch (CoreException e) {
fail("5.4", e);
}
}
/**
* Tests a scenario where a variable used in a linked file location is
* moved to a new project.
* This is a regression test for bug 266679
*/
public void testMoveFileToDifferentProject() {
IFile file = existingProjectInSubDirectory.getFile("my_link");
// creates a variable-based location
IPath variableBasedLocation = null;
IPath targetPath = existingProjectInSubDirectory.getLocation().removeLastSegments(1).append("outside.txt");
if (!targetPath.toFile().exists()) {
try {
targetPath.toFile().createNewFile();
} catch (IOException e2) {
fail("0.4", e2);
}
}
toDelete.add(targetPath);
try {
variableBasedLocation = convertToRelative(targetPath, file, true, null);
} catch (CoreException e1) {
fail("0.99", e1);
}
IPath resolvedPath = URIUtil.toPath(file.getPathVariableManager().resolveURI(URIUtil.toURI(variableBasedLocation)));
// the file should not exist yet
assertDoesNotExistInWorkspace("1.0", file);
try {
file.createLink(variableBasedLocation, IResource.ALLOW_MISSING_LOCAL, null);
} catch (CoreException e) {
fail("1.1", e);
}
assertExistsInWorkspace("2.0", file);
assertExistsInFileSystem("2.1", file);
IFile newFile = nonExistingFileInExistingFolder;
try {
file.move(newFile.getFullPath(), IResource.SHALLOW, null);
} catch (CoreException e) {
fail("3.0", e);
}
assertExistsInWorkspace("3,1", newFile);
assertTrue("3,2", !newFile.getLocation().equals(newFile.getRawLocation()));
assertEquals("3,3", newFile.getLocation(), resolvedPath);
}
private IPath convertToRelative(IPath path, IResource res, boolean force, String variableHint) throws CoreException {
return URIUtil.toPath(res.getPathVariableManager().convertToRelative(URIUtil.toURI(path), force, variableHint));
}
/**
* Tests a scenario where a variable used in a linked file location that is
* relative to PROJECT_LOC is moved to a different project.
* This is a regression test for bug 266679
*/
public void testPROJECT_LOC_MoveFileToDifferentProject() {
String[] existingVariables = nonExistingFileInExistingFolder.getProject().getPathVariableManager().getPathVariableNames();
for (String existingVariable : existingVariables) {
try {
nonExistingFileInExistingFolder.getProject().getPathVariableManager().setValue(existingVariable, null);
} catch (CoreException e) {
}
}
IFile file = existingProjectInSubDirectory.getFile("my_link2");
// creates a variable-based location
IPath variableBasedLocation = null;
IPath targetPath = existingProjectInSubDirectory.getLocation().removeLastSegments(3).append("outside.txt");
if (!targetPath.toFile().exists()) {
try {
targetPath.toFile().createNewFile();
} catch (IOException e2) {
fail("0.4", e2);
}
}
toDelete.add(targetPath);
try {
existingProjectInSubDirectory.getPathVariableManager().setValue("P_RELATIVE", Path.fromPortableString("${PARENT-3-PROJECT_LOC}"));
variableBasedLocation = Path.fromPortableString("P_RELATIVE/outside.txt");
} catch (CoreException e1) {
fail("0.99", e1);
}
IPath resolvedPath = existingProjectInSubDirectory.getPathVariableManager().resolvePath(variableBasedLocation);
// the file should not exist yet
assertDoesNotExistInWorkspace("1.0", file);
try {
file.createLink(variableBasedLocation, IResource.ALLOW_MISSING_LOCAL, null);
} catch (CoreException e) {
fail("1.1", e);
}
assertExistsInWorkspace("2.0", file);
assertExistsInFileSystem("2.1", file);
IFile newFile = nonExistingFileInExistingFolder;
try {
file.move(newFile.getFullPath(), IResource.SHALLOW, null);
} catch (CoreException e) {
fail("3.0", e);
}
assertExistsInWorkspace("3,1", newFile);
IPath newLocation = newFile.getLocation();
assertTrue("3,2", !newLocation.equals(newFile.getRawLocation()));
IPath newRawLocation = newFile.getRawLocation();
/* we cannot test the value of the location since the test machines generate an incorrect value
IPath newValue = newFile.getProject().getPathVariableManager().getValue("P_RELATIVE");
assertEquals("3,3", Path.fromPortableString("${PARENT-1-PROJECT_LOC}/sub"), newValue);
*/
assertTrue("3,4", newRawLocation.equals(variableBasedLocation));
assertTrue("3,5", newLocation.equals(resolvedPath));
}
/**
* Tests a scenario where a linked file location is
* is moved to a new project.
*/
public void testMoveFileProjectVariable() {
final IPathVariableManager manager = existingProject.getPathVariableManager();
IFile file = nonExistingFileInExistingProject;
// creates a variable-based location
IPath variableBasedLocation = getRandomProjectLocation();
IPath resolvedPath = manager.resolvePath(variableBasedLocation);
// the file should not exist yet
assertDoesNotExistInWorkspace("1.0", file);
try {
file.createLink(variableBasedLocation, IResource.ALLOW_MISSING_LOCAL, null);
} catch (CoreException e) {
fail("1.1", e);
}
try {
file.setContents(getContents("contents for a file"), IResource.FORCE, null);
} catch (CoreException e) {
fail("1.2", e);
}
// now the file exists in both workspace and file system
assertExistsInWorkspace("2.0", file);
assertExistsInFileSystem("2.1", file);
IFile newFile = nonExistingFileInExistingFolder;
// removes the variable - the location will be undefined (null)
try {
file.move(newFile.getFullPath(), IResource.SHALLOW, null);
} catch (CoreException e) {
fail("3.0", e);
}
assertExistsInWorkspace("3,1", newFile);
assertTrue("3,2", !newFile.getLocation().equals(newFile.getRawLocation()));
assertTrue("3,3", newFile.getRawLocation().equals(variableBasedLocation));
assertTrue("3,4", newFile.getRawLocation().equals(variableBasedLocation));
assertTrue("3,5", newFile.getLocation().equals(resolvedPath));
}
/**
* Tests a scenario where a variable used in a linked file location is
* removed.
*/
public void testMoveFileToNewProjectProjectVariable() {
final IPathVariableManager manager = existingProject.getPathVariableManager();
IFile file = nonExistingFileInExistingProject;
// creates a variable-based location
IPath variableBasedLocation = getRandomRelativeProjectLocation();
IPath resolvedPath = manager.resolvePath(variableBasedLocation);
// the file should not exist yet
assertDoesNotExistInWorkspace("1.0", file);
try {
file.createLink(variableBasedLocation, IResource.ALLOW_MISSING_LOCAL, null);
} catch (CoreException e) {
fail("1.1", e);
}
try {
file.setContents(getContents("contents for a file"), IResource.FORCE, null);
} catch (CoreException e) {
fail("1.2", e);
}
// now the file exists in both workspace and file system
assertExistsInWorkspace("2.0", file);
assertExistsInFileSystem("2.1", file);
IFile newFile = nonExistingFileInOtherExistingProject;
// moves the variable - the location will be undefined (null)
try {
file.move(newFile.getFullPath(), IResource.SHALLOW, getMonitor());
} catch (CoreException e) {
fail("3.0", e);
}
assertExistsInWorkspace("3,1", newFile);
assertTrue("3,2", !newFile.getLocation().equals(newFile.getRawLocation()));
assertTrue("3,3", newFile.getRawLocation().equals(variableBasedLocation));
assertTrue("3,4", newFile.getLocation().equals(resolvedPath));
}
/**
* Tests a scenario where a variable used in a linked file location is
* removed.
*/
public void testFileProjectRelativeVariableRemoved() {
final IPathVariableManager manager = existingProject.getPathVariableManager();
IFile file = nonExistingFileInExistingProject;
IPath existingValue = manager.getValue(PROJECT_RELATIVE_VARIABLE_NAME);
// creates a variable-based location
IPath variableBasedLocation = getRandomRelativeProjectLocation();
// the file should not exist yet
assertDoesNotExistInWorkspace("1.0", file);
try {
file.createLink(variableBasedLocation, IResource.ALLOW_MISSING_LOCAL, null);
} catch (CoreException e) {
fail("1.1", e);
}
try {
file.setContents(getContents("contents for a file"), IResource.FORCE, null);
} catch (CoreException e) {
fail("1.2", e);
}
// now the file exists in both workspace and file system
assertExistsInWorkspace("2.0", file);
assertExistsInFileSystem("2.1", file);
// removes the variable - the location will be undefined (null)
try {
manager.setValue(PROJECT_RELATIVE_VARIABLE_NAME, null);
} catch (CoreException e) {
fail("3.0", e);
}
assertExistsInWorkspace("3,1", file);
// refresh local - should not fail or make the link disappear
try {
file.refreshLocal(IResource.DEPTH_ONE, getMonitor());
file.getProject().refreshLocal(IResource.DEPTH_INFINITE, getMonitor());
} catch (CoreException e) {
fail("3.2");
}
assertExistsInWorkspace("3.3", file);
// try to change resource's contents
try {
file.setContents(getContents("new contents"), IResource.NONE, null);
// Resource has no-defined location - should fail
fail("3.4");
} catch (CoreException re) {
// success: resource had no defined location
}
assertExistsInWorkspace("3.5", file);
// the location is null
assertNull("3.6", file.getLocation());
// try validating another link location while there is a link with null
// location
IFile other = existingProject.getFile("OtherVar");
getWorkspace().validateLinkLocation(other, getRandomLocation());
// re-creates the variable with its previous value
try {
manager.setValue(PROJECT_RELATIVE_VARIABLE_NAME, existingValue);
} catch (CoreException e) {
fail("4.0", e);
}
assertExistsInWorkspace("5.0", file);
assertNotNull("5.1", file.getLocation());
assertExistsInFileSystem("5.2", file);
// the contents must be the original ones
try {
assertTrue("5.3", compareContent(file.getContents(true), getContents("contents for a file")));
} catch (CoreException e) {
fail("5.4", e);
}
}
/**
* Tests a scenario where a variable used in a linked folder location is
* removed.
*/
public void testFolderVariableRemoved() {
final IPathVariableManager manager = getWorkspace().getPathVariableManager();
IFolder folder = nonExistingFolderInExistingProject;
IFile childFile = folder.getFile(childName);
IPath existingValue = manager.getValue(VARIABLE_NAME);
// creates a variable-based location
IPath variableBasedLocation = getRandomLocation();
// the file should not exist yet
assertDoesNotExistInWorkspace("1.0", folder);
try {
folder.createLink(variableBasedLocation, IResource.ALLOW_MISSING_LOCAL, null);
childFile.create(getRandomContents(), IResource.NONE, getMonitor());
} catch (CoreException e) {
fail("1.1", e);
}
try {
childFile.setContents(getContents("contents for a file"), IResource.FORCE, null);
} catch (CoreException e) {
fail("1.2", e);
}
// now the file exists in both workspace and file system
assertExistsInWorkspace("2.0", folder);
assertExistsInWorkspace("2.1", childFile);
assertExistsInFileSystem("2.2", folder);
assertExistsInFileSystem("2.3", childFile);
// removes the variable - the location will be undefined (null)
try {
manager.setValue(VARIABLE_NAME, null);
} catch (CoreException e) {
fail("3.0", e);
}
assertExistsInWorkspace("3.1", folder);
//refresh local - should not fail but should cause link's children to disappear
try {
folder.refreshLocal(IResource.DEPTH_INFINITE, getMonitor());
folder.getProject().refreshLocal(IResource.DEPTH_INFINITE, getMonitor());
} catch (CoreException e) {
fail("3.2", e);
}
assertExistsInWorkspace("3.3", folder);
assertDoesNotExistInWorkspace("3.4", childFile);
//try to copy a file to the folder
IFile destination = folder.getFile(existingFileInExistingProject.getName());
try {
existingFileInExistingProject.copy(destination.getFullPath(), IResource.NONE, getMonitor());
//should fail
fail("3.5");
} catch (CoreException e) {
//expected
}
assertTrue("3.6", !destination.exists());
//try to create a sub-file
try {
destination.create(getRandomContents(), IResource.NONE, getMonitor());
//should fail
fail("3.7");
} catch (CoreException e) {
//expected
}
//try to create a sub-folder
IFolder subFolder = folder.getFolder("SubFolder");
try {
subFolder.create(IResource.NONE, true, getMonitor());
//should fail
fail("3.8");
} catch (CoreException e) {
//expected
}
// try to change resource's contents
try {
childFile.setContents(getContents("new contents"), IResource.NONE, null);
// Resource has no-defined location - should fail
fail("4.0");
} catch (CoreException re) {
// success: resource had no defined location
}
assertExistsInWorkspace("4.1", folder);
// the location is null
assertNull("4.2", folder.getLocation());
// re-creates the variable with its previous value
try {
manager.setValue(VARIABLE_NAME, existingValue);
} catch (CoreException e) {
fail("5.0", e);
}
assertExistsInWorkspace("6.0", folder);
assertNotNull("6.1", folder.getLocation());
assertExistsInFileSystem("6.2", folder);
assertDoesNotExistInWorkspace("6.3", childFile);
assertExistsInFileSystem("6.4", childFile);
// refresh should recreate the child
try {
folder.refreshLocal(IResource.DEPTH_INFINITE, getMonitor());
} catch (CoreException e) {
fail("7.0", e);
}
assertExistsInWorkspace("7.1", folder);
assertExistsInWorkspace("7.2", childFile);
}
/**
* Tests importing a project with a Linked Resource and Path Variable,
* where the line endings in the .project file do not match the local
* Platform.
* The .project file must not be modified on import, especially if it
* is marked read-only.
* See <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=210664">Bug 210664</a>.
*/
public void testImportWrongLineEndings_Bug210664() throws IOException {
// Choose a project to work on
IProject proj = existingProject;
IFileStore projStore = null;
IPath randomLocationWithPathVariable = getRandomLocation();
try {
projStore = EFS.getStore(proj.getLocationURI());
} catch (CoreException e) {
fail("1.0", e);
}
// Don't run this test if we cannot set a file read-only
if ((projStore.getFileSystem().attributes() & EFS.ATTRIBUTE_READ_ONLY) == 0) {
return;
}
try {
// Create a linked resource with a non-existing path variable
IFolder folder = proj.getFolder("SOME_LINK");
folder.createLink(randomLocationWithPathVariable, IResource.ALLOW_MISSING_LOCAL, null);
// Close the project, and convert line endings
IFileStore projFile = projStore.getChild(".project");
proj.delete(IResource.NEVER_DELETE_PROJECT_CONTENT, getMonitor());
IFileStore projNew = projStore.getChild(".project.new");
convertLineEndings(projFile, projNew, getMonitor());
// Set the project read-only
projNew.move(projFile, EFS.OVERWRITE, getMonitor());
IFileInfo info = projFile.fetchInfo(EFS.NONE, getMonitor());
info.setAttribute(EFS.ATTRIBUTE_READ_ONLY, true);
projFile.putInfo(info, EFS.SET_ATTRIBUTES, getMonitor());
toSetWritable = projFile; /* for cleanup */
} catch (CoreException e) {
fail("2.0", e);
}
try {
//Bug 210664: Open project with wrong line endings and non-existing path variable
proj.create(null);
proj.open(IResource.NONE, getMonitor());
} catch (CoreException e) {
fail("3.0", e);
}
}
/**
* Tests a scenario where a variable used in a linked folder location is
* removed.
*/
public void testFolderProjectVariableRemoved() {
final IPathVariableManager manager = existingProject.getPathVariableManager();
IFolder folder = nonExistingFolderInExistingProject;
IFile childFile = folder.getFile(childName);
IPath existingValue = manager.getValue(PROJECT_VARIABLE_NAME);
// creates a variable-based location
IPath variableBasedLocation = getRandomProjectLocation();
// the file should not exist yet
assertDoesNotExistInWorkspace("1.0", folder);
try {
folder.createLink(variableBasedLocation, IResource.ALLOW_MISSING_LOCAL, null);
childFile.create(getRandomContents(), IResource.NONE, getMonitor());
} catch (CoreException e) {
fail("1.1", e);
}
try {
childFile.setContents(getContents("contents for a file"), IResource.FORCE, null);
} catch (CoreException e) {
fail("1.2", e);
}
// now the file exists in both workspace and file system
assertExistsInWorkspace("2.0", folder);
assertExistsInWorkspace("2.1", childFile);
assertExistsInFileSystem("2.2", folder);
assertExistsInFileSystem("2.3", childFile);
// removes the variable - the location will be undefined (null)
try {
manager.setValue(PROJECT_VARIABLE_NAME, null);
} catch (CoreException e) {
fail("3.0", e);
}
assertExistsInWorkspace("3.1", folder);
// refresh local - should not fail but should cause link's children to
// disappear
try {
folder.refreshLocal(IResource.DEPTH_INFINITE, getMonitor());
folder.getProject().refreshLocal(IResource.DEPTH_INFINITE, getMonitor());
} catch (CoreException e) {
fail("3.2", e);
}
assertExistsInWorkspace("3.3", folder);
assertDoesNotExistInWorkspace("3.4", childFile);
// try to copy a file to the folder
IFile destination = folder.getFile(existingFileInExistingProject.getName());
try {
existingFileInExistingProject.copy(destination.getFullPath(), IResource.NONE, getMonitor());
// should fail
fail("3.5");
} catch (CoreException e) {
// expected
}
assertTrue("3.6", !destination.exists());
// try to create a sub-file
try {
destination.create(getRandomContents(), IResource.NONE, getMonitor());
// should fail
fail("3.7");
} catch (CoreException e) {
// expected
}
// try to create a sub-folder
IFolder subFolder = folder.getFolder("SubFolder");
try {
subFolder.create(IResource.NONE, true, getMonitor());
// should fail
fail("3.8");
} catch (CoreException e) {
// expected
}
// try to change resource's contents
try {
childFile.setContents(getContents("new contents"), IResource.NONE, null);
// Resource has no-defined location - should fail
fail("4.0");
} catch (CoreException re) {
// success: resource had no defined location
}
assertExistsInWorkspace("4.1", folder);
// the location is null
assertNull("4.2", folder.getLocation());
// re-creates the variable with its previous value
try {
manager.setValue(PROJECT_VARIABLE_NAME, existingValue);
} catch (CoreException e) {
fail("5.0", e);
}
assertExistsInWorkspace("6.0", folder);
assertNotNull("6.1", folder.getLocation());
assertExistsInFileSystem("6.2", folder);
assertDoesNotExistInWorkspace("6.3", childFile);
assertExistsInFileSystem("6.4", childFile);
// refresh should recreate the child
try {
folder.refreshLocal(IResource.DEPTH_INFINITE, getMonitor());
} catch (CoreException e) {
fail("7.0", e);
}
assertExistsInWorkspace("7.1", folder);
assertExistsInWorkspace("7.2", childFile);
}
/**
* Tests scenario where links are relative to undefined variables
*/
public void testUndefinedVariable() {
IPath folderLocation = new Path("NOVAR/folder");
IPath fileLocation = new Path("NOVAR/abc.txt");
IFile testFile = existingProject.getFile("UndefinedVar.txt");
IFolder testFolder = existingProject.getFolder("UndefinedVarTest");
//should fail to create links
try {
testFile.createLink(fileLocation, IResource.NONE, getMonitor());
fail("1.0");
} catch (CoreException e) {
//should fail
}
try {
testFolder.createLink(folderLocation, IResource.NONE, getMonitor());
fail("1.1");
} catch (CoreException e) {
//should fail
}
//validate method should return warning
assertTrue("1.2", getWorkspace().validateLinkLocation(testFolder, folderLocation).getSeverity() == IStatus.WARNING);
assertTrue("1.3", getWorkspace().validateLinkLocation(testFile, fileLocation).getSeverity() == IStatus.WARNING);
//should succeed with ALLOW_MISSING_LOCAL
try {
testFile.createLink(fileLocation, IResource.ALLOW_MISSING_LOCAL, getMonitor());
} catch (CoreException e) {
fail("2.0", e);
}
try {
testFolder.createLink(folderLocation, IResource.ALLOW_MISSING_LOCAL, getMonitor());
} catch (CoreException e) {
fail("2.1", e);
}
//copy should fail
IPath copyFileDestination = existingProject.getFullPath().append("CopyFileDest");
IPath copyFolderDestination = existingProject.getFullPath().append("CopyFolderDest");
try {
testFile.copy(copyFileDestination, IResource.NONE, getMonitor());
fail("3.0");
} catch (CoreException e) {
//should fail
}
try {
testFolder.copy(copyFolderDestination, IResource.NONE, getMonitor());
fail("3.1");
} catch (CoreException e) {
//should fail
}
//move should fail
IPath moveFileDestination = existingProject.getFullPath().append("MoveFileDest");
IPath moveFolderDestination = existingProject.getFullPath().append("MoveFolderDest");
try {
testFile.move(moveFileDestination, IResource.NONE, getMonitor());
fail("4.0");
} catch (CoreException e) {
//should fail
}
try {
testFolder.move(moveFolderDestination, IResource.NONE, getMonitor());
fail("4.1");
} catch (CoreException e) {
//should fail
}
//refresh local should succeed
try {
testFile.refreshLocal(IResource.DEPTH_INFINITE, getMonitor());
testFolder.refreshLocal(IResource.DEPTH_INFINITE, getMonitor());
testFile.refreshLocal(IResource.DEPTH_ZERO, getMonitor());
testFolder.refreshLocal(IResource.DEPTH_ZERO, getMonitor());
existingProject.refreshLocal(IResource.NONE, getMonitor());
} catch (CoreException e) {
fail("5.0", e);
}
//renaming the project shallow is ok
try {
IProject project = testFolder.getProject();
IProjectDescription desc = project.getDescription();
desc.setName("moveDest");
project.move(desc, IResource.SHALLOW | IResource.FORCE, getMonitor());
} catch (CoreException e) {
fail("6.0");
}
//delete should succeed
try {
testFile.delete(IResource.NONE, getMonitor());
testFolder.delete(IResource.NONE, getMonitor());
} catch (CoreException e) {
fail("9.0", e);
}
}
/**
* Tests a scenario where a variable used in a linked file location is
* changed.
*/
public void testVariableChanged() {
final IPathVariableManager manager = getWorkspace().getPathVariableManager();
IPath existingValue = manager.getValue(VARIABLE_NAME);
IFile file = nonExistingFileInExistingProject;
// creates a variable-based location
IPath variableBasedLocation = getRandomLocation();
// the file should not exist yet
assertDoesNotExistInWorkspace("1.0", file);
try {
file.createLink(variableBasedLocation, IResource.ALLOW_MISSING_LOCAL, getMonitor());
} catch (CoreException e) {
fail("1.1", e);
}
try {
file.setContents(getContents("contents for a file"), IResource.FORCE, getMonitor());
} catch (CoreException e) {
fail("1.2", e);
}
// now the file exists in both workspace and file system
assertExistsInWorkspace("2.0", file);
assertExistsInFileSystem("2.1", file);
// changes the variable value - the file location will change
try {
IPath newLocation = super.getRandomLocation();
toDelete.add(newLocation);
manager.setValue(VARIABLE_NAME, newLocation);
} catch (CoreException e) {
fail("2.2", e);
}
// try to change resource's contents
try {
file.setContents(getContents("new contents"), IResource.NONE, getMonitor());
// Resource was out of sync - should not be able to change
fail("3.0");
} catch (CoreException e) {
assertEquals("3.1", IResourceStatus.OUT_OF_SYNC_LOCAL, e.getStatus().getCode());
}
assertExistsInWorkspace("3.2", file);
// the location is different - does not exist anymore
assertDoesNotExistInFileSystem("3.3", file);
// successfully changes resource's contents (using IResource.FORCE)
try {
file.setContents(getContents("contents in different location"), IResource.FORCE, getMonitor());
} catch (CoreException e) {
fail("4.0", e);
}
// now the file exists in a different location
assertExistsInFileSystem("4.1", file);
// its location must have changed reflecting the variable change
IPath expectedNewLocation = manager.resolvePath(variableBasedLocation);
IPath actualNewLocation = file.getLocation();
assertEquals("4.2", expectedNewLocation, actualNewLocation);
// its contents are as just set
try {
assertTrue("4.3", compareContent(file.getContents(), getContents("contents in different location")));
} catch (CoreException e) {
fail("4.4", e);
}
// clean-up
ensureDoesNotExistInFileSystem(file);
// restore the previous value
try {
manager.setValue(VARIABLE_NAME, existingValue);
} catch (CoreException e) {
fail("5.0", e);
}
assertExistsInWorkspace("5.1", file);
assertExistsInFileSystem("5.2", file);
// the contents must be the original ones
try {
assertTrue("5.3", compareContent(file.getContents(true), getContents("contents for a file")));
} catch (CoreException e) {
fail("5.4", e);
}
}
/**
* Tests a scenario where a variable used in a linked file location is
* changed.
*/
public void testProjectVariableChanged() {
final IPathVariableManager manager = existingProject.getPathVariableManager();
IPath existingValue = manager.getValue(PROJECT_VARIABLE_NAME);
IFile file = nonExistingFileInExistingProject;
// creates a variable-based location
IPath variableBasedLocation = getRandomProjectLocation();
// the file should not exist yet
assertDoesNotExistInWorkspace("1.0", file);
try {
file.createLink(variableBasedLocation, IResource.ALLOW_MISSING_LOCAL, getMonitor());
} catch (CoreException e) {
fail("1.1", e);
}
try {
file.setContents(getContents("contents for a file"), IResource.FORCE, getMonitor());
} catch (CoreException e) {
fail("1.2", e);
}
// now the file exists in both workspace and file system
assertExistsInWorkspace("2.0", file);
assertExistsInFileSystem("2.1", file);
// changes the variable value - the file location will change
try {
IPath newLocation = super.getRandomLocation();
toDelete.add(newLocation);
manager.setValue(PROJECT_VARIABLE_NAME, newLocation);
} catch (CoreException e) {
fail("2.2", e);
}
// try to change resource's contents
try {
file.setContents(getContents("new contents"), IResource.NONE, getMonitor());
// Resource was out of sync - should not be able to change
fail("3.0");
} catch (CoreException e) {
assertEquals("3.1", IResourceStatus.OUT_OF_SYNC_LOCAL, e.getStatus().getCode());
}
assertExistsInWorkspace("3.2", file);
// the location is different - does not exist anymore
assertDoesNotExistInFileSystem("3.3", file);
// successfully changes resource's contents (using IResource.FORCE)
try {
file.setContents(getContents("contents in different location"), IResource.FORCE, getMonitor());
} catch (CoreException e) {
fail("4.0", e);
}
// now the file exists in a different location
assertExistsInFileSystem("4.1", file);
// its location must have changed reflecting the variable change
IPath expectedNewLocation = manager.resolvePath(variableBasedLocation);
IPath actualNewLocation = file.getLocation();
assertEquals("4.2", expectedNewLocation, actualNewLocation);
// its contents are as just set
try {
assertTrue("4.3", compareContent(file.getContents(), getContents("contents in different location")));
} catch (CoreException e) {
fail("4.4", e);
}
// clean-up
ensureDoesNotExistInFileSystem(file);
// restore the previous value
try {
manager.setValue(PROJECT_VARIABLE_NAME, existingValue);
} catch (CoreException e) {
fail("5.0", e);
}
assertExistsInWorkspace("5.1", file);
assertExistsInFileSystem("5.2", file);
// the contents must be the original ones
try {
assertTrue("5.3", compareContent(file.getContents(true), getContents("contents for a file")));
} catch (CoreException e) {
fail("5.4", e);
}
}
/**
* Tests a scenario where a variable used in a linked file location is
* changed.
*/
// public void testGetPathVariable() {
// final IPathVariableManager manager = existingProject.getPathVariableManager();
// IPathVariable variable = manager.getPathVariable("PROJECT_LOC");
// assertTrue("1.0", variable != null);
// assertTrue("1.1", variable.isReadOnly());
// assertEquals("1.2", null, variable.getVariableHints());
//
// variable = manager.getPathVariable("PROJECT_LOC_does_not_exist");
// assertTrue("2.0", variable == null);
//
// variable = manager.getPathVariable("PARENT");
// assertTrue("3.0", variable != null);
// assertTrue("3.1", variable.isReadOnly());
// Object[] extensions = variable.getVariableHints();
// assertTrue("3.2", extensions == null);
//
// try {
// IPath newLocation = super.getRandomLocation();
// toDelete.add(newLocation);
// manager.setValue(PROJECT_VARIABLE_NAME, newLocation);
// } catch (CoreException e) {
// fail("4.1", e);
// }
// variable = manager.getPathVariable(PROJECT_VARIABLE_NAME);
// assertTrue("4.0", variable != null);
// assertTrue("4.1", !variable.isReadOnly());
// assertEquals("4.2", null, variable.getVariableHints());
// }
/**
* Test Bug 288880 - Redundant path variables generated when converting some linked resources to path variable-relative
*/
public void testNonRedundentPathVariablesGenerated() {
IFile file = existingProjectInSubDirectory.getFile("my_link");
IPathVariableManager pathVariableManager = existingProjectInSubDirectory.getPathVariableManager();
// creates a variable-based location
IPath variableBasedLocation = null;
IPath targetPath = existingProjectInSubDirectory.getLocation().removeLastSegments(1).append("outside.txt");
if (!targetPath.toFile().exists()) {
try {
targetPath.toFile().createNewFile();
} catch (IOException e2) {
fail("1.0", e2);
}
}
toDelete.add(targetPath);
try {
variableBasedLocation = convertToRelative(targetPath, file, true, null);
} catch (CoreException e1) {
fail("2.0", e1);
}
IPath resolvedPath = URIUtil.toPath(pathVariableManager.resolveURI(URIUtil.toURI(variableBasedLocation)));
// the file should not exist yet
assertDoesNotExistInWorkspace("3.0", file);
assertEquals("3.1", targetPath, resolvedPath);
try {
variableBasedLocation = convertToRelative(targetPath, file, true, null);
} catch (CoreException e1) {
fail("4.0", e1);
}
resolvedPath = URIUtil.toPath(pathVariableManager.resolveURI(URIUtil.toURI(variableBasedLocation)));
// the file should not exist yet
assertDoesNotExistInWorkspace("5.0", file);
assertEquals("5.1", targetPath, resolvedPath);
}
public void testConvertToUserEditableFormat() {
IPathVariableManager pathVariableManager = existingProject.getPathVariableManager();
String[][] table = { // format: {internal-format, user-editable-format [, internal-format-reconverted]
{"C:\\foo\\bar", "C:\\foo\\bar", "C:/foo/bar"}, //
{"C:/foo/bar", "C:/foo/bar"}, //
{"VAR/foo/bar", "VAR/foo/bar"}, //
{"${VAR}/foo/bar", "${VAR}/foo/bar"}, //
{"${VAR}/../foo/bar", "${VAR}/../foo/bar", "${PARENT-1-VAR}/foo/bar"}, //
{"${PARENT-1-VAR}/foo/bar", "${VAR}/../foo/bar"}, //
{"${PARENT-0-VAR}/foo/bar", "${VAR}/foo/bar", "${VAR}/foo/bar"}, //
{"${PARENT-VAR}/foo/bar", "${PARENT-VAR}/foo/bar"}, //
{"${PARENT-2}/foo/bar", "${PARENT-2}/foo/bar"}, //
{"${PARENT}/foo/bar", "${PARENT}/foo/bar"}, //
{"${PARENT-2-VAR}/foo/bar", "${VAR}/../../foo/bar"}, //
{"${PARENT-2-VAR}/foo/${PARENT-4-BAR}", "${VAR}/../../foo/${BAR}/../../../.."}, //
{"${PARENT-2-VAR}/foo${PARENT-4-BAR}", "${VAR}/../../foo${BAR}/../../../.."}, //
{"${PARENT-2-VAR}/${PARENT-4-BAR}/foo", "${VAR}/../../${BAR}/../../../../foo"}, //
{"${PARENT-2-VAR}/f${PARENT-4-BAR}/oo", "${VAR}/../../f${BAR}/../../../../oo"} //
};
for (int i = 0; i < table.length; i++) {
String result = pathVariableManager.convertToUserEditableFormat(toOS(table[i][0]), false);
assertEquals("1." + i, toOS(table[i][1]), result);
String original = pathVariableManager.convertFromUserEditableFormat(result, false);
assertEquals("2." + i, toOS(table[i].length == 2 ? table[i][0] : table[i][2]), original);
}
String[][] tableLocationFormat = { // format: {internal-format, user-editable-format [, internal-format-reconverted]
{"C:\\foo\\bar", "C:\\foo\\bar", "C:/foo/bar"}, //
{"C:/foo/bar", "C:/foo/bar"}, //
{"VAR/foo/bar", "VAR/foo/bar"}, //
{"${VAR}/../foo/bar", "${VAR}/../foo/bar", "PARENT-1-VAR/foo/bar"}, //
{"PARENT-1-VAR/foo/bar", "VAR/../foo/bar"}, //
{"PARENT-0-VAR/foo/bar", "VAR/foo/bar", "VAR/foo/bar"}, //
{"PARENT-VAR/foo/bar", "PARENT-VAR/foo/bar"}, //
{"PARENT-2/foo/bar", "PARENT-2/foo/bar"}, //
{"PARENT/foo/bar", "PARENT/foo/bar"}, //
{"PARENT-2-VAR/foo/bar", "VAR/../../foo/bar"}, //
{"PARENT-2-VAR/foo/PARENT-4-BAR", "VAR/../../foo/PARENT-4-BAR"}, //
{"PARENT-2-VAR/fooPARENT-4-BAR", "VAR/../../fooPARENT-4-BAR"}, //
{"PARENT-2-VAR/PARENT-4-BAR/foo", "VAR/../../PARENT-4-BAR/foo"}, //
{"PARENT-2-VAR/fPARENT-4-BAR/oo", "VAR/../../fPARENT-4-BAR/oo"}, //
{"/foo/bar", "/foo/bar"}, //
};
for (int i = 0; i < table.length; i++) {
String result = pathVariableManager.convertToUserEditableFormat(toOS(tableLocationFormat[i][0]), true);
assertEquals("3." + i, toOS(tableLocationFormat[i][1]), result);
String original = pathVariableManager.convertFromUserEditableFormat(result, true);
assertEquals("4." + i, toOS(tableLocationFormat[i].length == 2 ? tableLocationFormat[i][0] : tableLocationFormat[i][2]), original);
}
}
private String toOS(String path) {
return path.replace('/', File.separatorChar);
}
/**
* Regression for Bug 305676 - Selecting PARENT_LOC as the relative path variable in the ImportTypeDialog causes an error
*/
public void testPrefixVariablesAreNotConfused() {
URI uri = nonExistingFileInExistingFolder.getPathVariableManager().getURIValue("PARENT");
assertEquals("1.0", uri, null);
uri = nonExistingFileInExistingFolder.getPathVariableManager().getURIValue("PARENT_LOC");
assertNotNull("1.1", uri);
}
/**
* Regression test for Bug 338185 - Core Resource Variable Resolvers that do not specify the 'class' attribute are not displayed
*/
public void test338185() {
final IPathVariableManager manager = existingProject.getPathVariableManager();
String[] variables = manager.getPathVariableNames();
boolean found = false;
for (String variable : variables) {
if (variable.equals("Test338185")) {
found = true;
}
}
assertTrue(found);
}
}