1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-08-13 19:25:38 +02:00

further changes for Bug 291815 - Add an extension point to allow utilities for virtual EFS filesystems

This commit is contained in:
Chris Recoskie 2010-05-25 17:58:41 +00:00
parent 825017ddae
commit 7038788c04
15 changed files with 658 additions and 350 deletions

View file

@ -45,7 +45,7 @@ import org.eclipse.cdt.make.internal.core.scannerconfig.ScannerConfigUtil;
import org.eclipse.cdt.make.internal.core.scannerconfig.util.CygpathTranslator;
import org.eclipse.cdt.make.internal.core.scannerconfig.util.SymbolEntry;
import org.eclipse.cdt.make.internal.core.scannerconfig.util.TraceUtil;
import org.eclipse.cdt.utils.FileSystemUtilityManager;
import org.eclipse.cdt.utils.EFSExtensionManager;
import org.eclipse.core.filesystem.EFS;
import org.eclipse.core.filesystem.IFileInfo;
import org.eclipse.core.filesystem.IFileStore;
@ -290,7 +290,7 @@ public class PerProjectSICollector implements IScannerInfoCollector3, IScannerIn
URI projectLocationURI = discPathInfo.getProject().getLocationURI();
// use the project's location... create a URI that uses the same provider but that points to the include path
URI includeURI = FileSystemUtilityManager.getDefault().replacePath(projectLocationURI, include);
URI includeURI = EFSExtensionManager.getDefault().createNewURIFromPath(projectLocationURI, include);
// ask EFS if the path exists
try {

View file

@ -0,0 +1,34 @@
/*******************************************************************************
* Copyright (c) 2010 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
*******************************************************************************/
package org.eclipse.cdt.core.internal.efsextension.tests;
import java.net.URI;
import org.eclipse.cdt.core.EFSExtensionProvider;
/**
* Test class that is used to make sure that extensions to the EFSExtensionProvider
* extension point are picked up. Overrrides the default behaviour for isVirtual()
* to return true.
*
* @author crecoskie
*
*/
public class EFSExtensionProviderTestsProvider extends EFSExtensionProvider {
@Override
public boolean isVirtual(URI locationURI) {
return true;
}
}

View file

@ -0,0 +1,223 @@
/*******************************************************************************
* Copyright (c) 2010 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
*******************************************************************************/
package org.eclipse.cdt.core.internal.efsextension.tests;
import java.net.URI;
import java.net.URISyntaxException;
import org.eclipse.cdt.utils.EFSExtensionManager;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Path;
import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;
/**
* Tests the EFSExtensionManager and EFSExtensionProvider classes, as well as the EFSExtensionProvider extension point.
*
* @author crecoskie
*
*/
public class EFSExtensionTests extends TestCase {
public void testReplaceInRSEURI() {
URI originalURI = null;
URI expected = null;
try {
originalURI = new URI("rse", "dbgaix3.torolab.ibm.com", "/home/recoskie", null);
expected = new URI("rse", "dbgaix3.torolab.ibm.com", "/home/recoskie/subdirectory", null);
} catch (URISyntaxException e) {
fail(e.getMessage());
}
String workingDirPath = EFSExtensionManager.getDefault()
.getPathFromURI(originalURI);
IPath path = new Path("subdirectory");
IPath newPath = new Path(workingDirPath).append(path).makeAbsolute();
URI uri = EFSExtensionManager.getDefault()
.createNewURIFromPath(originalURI, newPath.toString());
assertEquals(expected, uri);
}
public void testReplaceInUNIXURI() {
URI originalURI = null;
URI expected = null;
try {
originalURI = new URI("file", "/home/recoskie", null);
expected = new URI("file", "/home/recoskie/subdirectory", null);
} catch (URISyntaxException e) {
fail(e.getMessage());
}
String workingDirPath = EFSExtensionManager.getDefault()
.getPathFromURI(originalURI);
IPath path = new Path("subdirectory");
IPath newPath = new Path(workingDirPath).append(path).makeAbsolute();
URI uri = EFSExtensionManager.getDefault()
.createNewURIFromPath(originalURI, newPath.toString());
assertEquals(expected, uri);
}
public void testReplaceInWindowsURI() {
URI originalURI = null;
URI expected = null;
try {
originalURI = new URI("file", "/c:/foo", null);
expected = new URI("file", "/c:/foo/subdirectory", null);
} catch (URISyntaxException e) {
fail(e.getMessage());
}
String workingDirPath = EFSExtensionManager.getDefault()
.getPathFromURI(originalURI);
IPath path = new Path("subdirectory");
IPath newPath = new Path(workingDirPath).append(path).makeAbsolute();
URI uri = EFSExtensionManager.getDefault()
.createNewURIFromPath(originalURI, newPath.toString());
assertEquals(expected, uri);
}
public void testReplaceInMadeUpURI() {
URI originalURI = null;
URI expected = null;
try {
originalURI = new URI("myfile", "/c:/foo", null);
expected = new URI("myfile", "/c:/foo/subdirectory", null);
} catch (URISyntaxException e) {
fail(e.getMessage());
}
String workingDirPath = EFSExtensionManager.getDefault()
.getPathFromURI(originalURI);
IPath path = new Path("subdirectory");
IPath newPath = new Path(workingDirPath).append(path).makeAbsolute();
URI uri = EFSExtensionManager.getDefault()
.createNewURIFromPath(originalURI, newPath.toString());
assertEquals(expected, uri);
}
public void testReplaceWithWindowsPathNoLeadingSlash() {
URI originalURI = null;
URI expected = null;
try {
originalURI = new URI("file", "/c:/foo", null);
expected = new URI("file", "/c:/foo/subdirectory", null);
} catch (URISyntaxException e) {
fail(e.getMessage());
}
String newPath = "c:\\foo\\subdirectory";
URI uri = EFSExtensionManager.getDefault()
.createNewURIFromPath(originalURI, newPath);
assertEquals(expected, uri);
}
public void testAppendinRSEURI() {
URI originalURI = null;
URI expected = null;
try {
originalURI = new URI("rse", "dbgaix3.torolab.ibm.com", "/home/recoskie", null);
expected = new URI("rse", "dbgaix3.torolab.ibm.com", "/home/recoskie/subdirectory", null);
} catch (URISyntaxException e) {
fail(e.getMessage());
}
URI uri = EFSExtensionManager.getDefault().append(originalURI, "subdirectory");
assertEquals(expected, uri);
}
public void testAppendToUNIXURI() {
URI originalURI = null;
URI expected = null;
try {
originalURI = new URI("file", "/home/recoskie", null);
expected = new URI("file", "/home/recoskie/subdirectory", null);
} catch (URISyntaxException e) {
fail(e.getMessage());
}
URI uri = EFSExtensionManager.getDefault().append(originalURI, "subdirectory");
assertEquals(expected, uri);
}
public void testAppendToWindowsURI() {
URI originalURI = null;
URI expected = null;
try {
originalURI = new URI("file", "/c:/foo", null);
expected = new URI("file", "/c:/foo/subdirectory", null);
} catch (URISyntaxException e) {
fail(e.getMessage());
}
URI uri = EFSExtensionManager.getDefault().append(originalURI, "subdirectory");
assertEquals(expected, uri);
}
public void testGetLinkedURI() {
URI originalURI = null;
try {
originalURI = new URI("file", "/c:/foo", null);
} catch(URISyntaxException e) {
fail(e.getMessage());
}
URI uri = EFSExtensionManager.getDefault().getLinkedURI(originalURI);
assertEquals(originalURI, uri);
}
public void testGetMappedPath() {
URI originalURI = null;
try {
originalURI = new URI("file", "/c:/foo", null);
} catch(URISyntaxException e) {
fail(e.getMessage());
}
String path = EFSExtensionManager.getDefault().getMappedPath(originalURI);
assertEquals(path, "/c:/foo");
}
public void testGetPathFromURI() {
URI originalURI = null;
try {
originalURI = new URI("file", "/c:/foo", null);
} catch(URISyntaxException e) {
fail(e.getMessage());
}
String path = EFSExtensionManager.getDefault().getMappedPath(originalURI);
assertEquals(path, "/c:/foo");
}
public void testExtension() {
URI originalURI = null;
try {
originalURI = new URI("EFSExtensionProviderTestsScheme", "/some/silly/path", null);
} catch(URISyntaxException e) {
fail(e.getMessage());
}
assertTrue(EFSExtensionManager.getDefault().isVirtual(originalURI));
}
public static Test suite() {
TestSuite suite = new TestSuite(EFSExtensionTests.class);
return suite;
}
}

View file

@ -176,4 +176,11 @@
</pattern>
</errorparser>
</extension>
<extension
point="org.eclipse.cdt.core.EFSExtensionProvider">
<EFSExtensionProvider
class="org.eclipse.cdt.core.internal.efsextension.tests.EFSExtensionProviderTestsProvider"
scheme="EFSExtensionProviderTestsScheme">
</EFSExtensionProvider>
</extension>
</plugin>

View file

@ -18,6 +18,7 @@ import junit.framework.TestSuite;
import org.eclipse.cdt.core.cdescriptor.tests.CDescriptorOldTests;
import org.eclipse.cdt.core.cdescriptor.tests.CDescriptorTests;
import org.eclipse.cdt.core.envvar.IEnvironmentVariableManagerTests;
import org.eclipse.cdt.core.internal.efsextension.tests.EFSExtensionTests;
import org.eclipse.cdt.core.internal.errorparsers.tests.ErrorParserTests;
import org.eclipse.cdt.core.internal.tests.PositionTrackerTests;
import org.eclipse.cdt.core.internal.tests.ResourceLookupTests;
@ -70,6 +71,7 @@ public class AutomatedIntegrationSuite extends TestSuite {
suite.addTest(AllLanguageTests.suite());
suite.addTest(RewriteTests.suite());
suite.addTest(CommandLineUtilTest.suite());
suite.addTest(EFSExtensionTests.suite());
// Add in PDOM tests
suite.addTest(PDOMTests.suite());

View file

@ -53,7 +53,7 @@ import org.eclipse.cdt.internal.core.index.IndexBasedFileContentProvider;
import org.eclipse.cdt.internal.core.parser.scanner.InternalFileContentProvider;
import org.eclipse.cdt.internal.core.parser.scanner.StreamHasher;
import org.eclipse.cdt.internal.core.pdom.dom.PDOMNotImplementedError;
import org.eclipse.cdt.utils.FileSystemUtilityManager;
import org.eclipse.cdt.utils.EFSExtensionManager;
import org.eclipse.core.runtime.Assert;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
@ -858,7 +858,7 @@ public abstract class AbstractIndexerTask extends PDOMWriter {
return path;
}
URI uri= ifl.getURI();
return new Path(FileSystemUtilityManager.getDefault().getPathFromURI(uri));
return new Path(EFSExtensionManager.getDefault().getPathFromURI(uri));
}
private void swallowError(IPath file, Throwable e) throws CoreException {

View file

@ -628,7 +628,7 @@
<extension-point id="templateProcessTypes" name="%templateProcessTypes.name" schema="schema/templateProcessTypes.exsd"/>
<extension-point id="templateAssociations" name="%templateAssociations.name" schema="schema/templateAssociations.exsd"/>
<extension-point id="ScannerInfoProvider2" name="%scannerInfoProvider2.name" schema="schema/ScannerInfoProvider2.exsd"/>
<extension-point id="FileSystemUtility" name="File System Utility" schema="schema/FileSystemUtility.exsd"/>
<extension-point id="EFSExtensionProvider" name="EFSExtensionProvider" schema="schema/EFSExtensionProvider.exsd"/>
<extension
point="org.eclipse.cdt.core.templateProcessTypes">

View file

@ -3,17 +3,17 @@
<schema targetNamespace="org.eclipse.cdt.core" xmlns="http://www.w3.org/2001/XMLSchema">
<annotation>
<appInfo>
<meta.schema plugin="org.eclipse.cdt.core" id="FileSystemUtility" name="Filesystem Utility"/>
<meta.schema plugin="org.eclipse.cdt.core" id="EFSFileSystemUtilityProvider" name="EFSFileSystemUtilityProvider"/>
</appInfo>
<documentation>
This extension point allows one to contribute a so-called &quot;Filesystem Utility&quot; class that can manipulate resources in a given EFS filesystem, and extract meaningful information from the filesystem and its resources.
This extension point allows one to contribute a class that provides supplementary support for an EFS filesystem in the form of a provider of a set of utility methods. In particular, the class can extract meaningful information from the filesystem and its resources, and provide useful operations relating to such resources.
</documentation>
</annotation>
<element name="FileSystemUtility">
<element name="EFSExtensionProvider">
<annotation>
<documentation>
An instance of a File System Utility. File System Utilities are mapped to a URI scheme corresponding to an EFS filesystem for which they provide support. These extensions are consulted by CDT in order to extract path information from the filesystem and manipulate filesystem resources.
An instance of an EFS Extension Provider. EFS Extension Providers are mapped to a URI scheme corresponding to an EFS filesystem for which they provide support. These extensions are consulted by CDT in order to extract path information from the filesystem and manipulate filesystem resources.
</documentation>
</annotation>
<complexType>
@ -27,10 +27,10 @@
<attribute name="class" type="string" use="required">
<annotation>
<documentation>
Java class which implements org.eclipse.cdt.core.IFilesystemUtility to provide support for the filesystem.
Java class which extends from org.eclipse.cdt.core.EFSFileSystemSupplementarySupportProvider to provide support for the filesystem.
</documentation>
<appInfo>
<meta.attribute kind="java" basedOn=":org.eclipse.cdt.core.IFilesystemUtility"/>
<meta.attribute kind="java" basedOn="org.eclipse.cdt.core.EFSExtensionProvider:"/>
</appInfo>
</annotation>
</attribute>
@ -45,7 +45,7 @@
</annotation>
<complexType>
<sequence>
<element ref="FileSystemUtility"/>
<element ref="EFSExtensionProvider"/>
</sequence>
<attribute name="point" type="string" use="required">
<annotation>
@ -79,18 +79,10 @@
<meta.section type="since"/>
</appInfo>
<documentation>
5.0.3
5.2
</documentation>
</annotation>
<annotation>
<appInfo>
<meta.section type="examples"/>
</appInfo>
<documentation>
[Enter extension point usage example here.]
</documentation>
</annotation>
<annotation>
<appInfo>
@ -106,7 +98,7 @@
<meta.section type="implementation"/>
</appInfo>
<documentation>
None.
A default implementation is supplied by org.eclipse.cdt.core.EFSFileSystemUtilityProvider that assumes that URIs for the given filesystem map directly to resources in the physical filesystem, and that the path component of the URI is a direct representation of the absolute path to the file in the physical filesystem. Clients can extend this implementation and override its behaviour as needed.
</documentation>
</annotation>

View file

@ -0,0 +1,152 @@
/*******************************************************************************
* Copyright (c) 2010 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
*******************************************************************************/
package org.eclipse.cdt.core;
import java.net.URI;
import java.net.URISyntaxException;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.URIUtil;
/**
* Abstract class providing the basis for supplementary support classes that can extract meaningful
* information from and provide useful operations on EFS filesystems. This allows for operations that can
* operate on virtual EFS filesystems (where IFileStores are just links to other IFileStores), or that operate
* on the physical file backed by an IFileStore, without having to know the implementation details of a given
* EFS filesystem.
*
* Provides a default implementation that assumes that URIs for the given filesystem map directly to resources
* in the physical filesystem, and that the path component of the URI is a direct representation of the
* absolute path to the file in the physical filesystem.
*
* Clients wishing to support a filesystem with different behaviour should extend this class and override its
* methods where appropriate.
*
* Clients should not typically call methods on this class or its descendants directly. Instead, they should
* call the appropriate method in FileSystemUtilityManager so that said manager can properly route calls to
* the proper utility, depending on the filesystem.
*
* <strong>EXPERIMENTAL</strong>. This class or interface has been added as part of a work in progress. There
* is no guarantee that this API will work or that it will remain the same. Please do not use this API without
* consulting with the CDT team.
*
* @author crecoskie
* @since 5.2
*
*/
public abstract class EFSExtensionProvider {
/**
* If the EFS store represented by locationURI is backed by a physical file, gets the path corresponding
* to the underlying file as the operating system on hosting machine would see it. In the future, it would
* be better if EFS had an API for this.
*
* @param locationURI
* @return String representing the path, or <code>null</code> if there is an error or if there is no such
* physical file.
*/
public String getPathFromURI(URI locationURI) {
return locationURI.getPath();
}
/**
* In the case of a virtual filesystem, where URIs in the given filesystem are just soft links in EFS to
* URIs in other filesystems, returns the URI that this URI links to. If the filesystem is not virtual,
* then this method acts as an identity mapping.
*
* @param locationURI
* @return A URI corresponding to the linked store, or <code>null</code> on error.
*/
public URI getLinkedURI(URI locationURI) {
return locationURI;
}
/**
* Creates a new URI which clones the contents of the original URI, but with the path replaced by the
* given absolute path, such that calling getPathFromURI() on the returned URI will return the given path. Returns
* null on error.
*
* The default implementation places the path in the path field of the URI, ensuring that there is a leading slash.
*
* @param locationOnSameFilesystem
* @param path An absolute path.
* @return URI
*/
public URI createNewURIFromPath(URI locationOnSameFilesystem, String path) {
URI uri = locationOnSameFilesystem;
Path p = new Path(path);
String pathString = p.toString(); // to convert any backslashes to slashes
final int length = pathString.length();
StringBuffer pathBuf = new StringBuffer(length + 1);
// force the path to be absolute
if (length > 0 && (pathString.charAt(0) != '/')) {
pathBuf.append('/');
}
//additional double-slash for UNC paths to distinguish from host separator
if (pathString.startsWith("//")) //$NON-NLS-1$
pathBuf.append('/').append('/');
pathBuf.append(pathString);
try {
return new URI(uri.getScheme(), uri.getUserInfo(), uri.getHost(), uri.getPort(), pathBuf.toString(), // replaced!
uri.getQuery(), uri.getFragment());
} catch (URISyntaxException e) {
CCorePlugin.log(e);
}
return null;
}
/**
* For filesystems that map the path to a physical file in one filesystem (say on a remote machine) to
* another path (say, on the local machine), this method returns the path that the store maps to. I.e., it
* returns the path that the path returned by getPathFromURI(URI locationURI) maps to. If there is no such
* mapping, then an identity mapping of the paths is assumed.
*
* Typically if a filesystem maps one filesytem to another, it will place the mapped path in the path
* field of its URIs (which the default implementation assumes), but this is not guaranteed to be so for
* all filesystem implementations.
*
* @return String representing the path, or <code>null</code> on error.
*/
public String getMappedPath(URI locationURI) {
return getPathFromURI(locationURI);
}
/**
* Returns true if the given URI is part of a virtual filesystem and thus points to another underlying
* URI. Returns false otherwise. By default, filesystems are assumed to be non-virtual.
*
* @param locationURI
* @return boolean
*/
public boolean isVirtual(URI locationURI) {
return false;
}
/**
* Creates a new URI with the same components as the baseURI, except that calling
* getPathFromURI() on the new URI will return a path that has the extension appended to
* the path returned by baseURI.getPathFromURI()
*
* The default implementation assumes that the path component of the URI is used
* to store the path.
*
* @param baseURI
* @param extension
* @return the new URI, or <code>null</code> on error.
*/
public URI append(URI baseURI, String extension) {
return URIUtil.append(baseURI, extension);
}
}

View file

@ -29,7 +29,7 @@ import org.eclipse.cdt.internal.core.IErrorMarkeredOutputStream;
import org.eclipse.cdt.internal.core.resources.ResourceLookup;
import org.eclipse.cdt.internal.errorparsers.ErrorParserExtensionManager;
import org.eclipse.cdt.utils.CygPath;
import org.eclipse.cdt.utils.FileSystemUtilityManager;
import org.eclipse.cdt.utils.EFSExtensionManager;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
@ -458,10 +458,7 @@ outer:
URI uri;
if (!path.isAbsolute()) {
URI workingDirectoryURI = getWorkingDirectoryURI();
String workingDirPath = FileSystemUtilityManager.getDefault().getPathFromURI(workingDirectoryURI);
IPath newPath = new Path(workingDirPath).append(path);
uri = FileSystemUtilityManager.getDefault().replacePath(workingDirectoryURI, newPath.toString());
//uri = URIUtil.append(getWorkingDirectoryURI(), path.toString());
uri = EFSExtensionManager.getDefault().append(getWorkingDirectoryURI(), path.toString());
}
else {
uri = toURI(path);
@ -712,7 +709,7 @@ outer:
if (path.isAbsolute() && uriString.charAt(0) != IPath.SEPARATOR)
uriString = IPath.SEPARATOR + uriString;
return FileSystemUtilityManager.getDefault().replacePath(baseURI, uriString);
return EFSExtensionManager.getDefault().createNewURIFromPath(baseURI, uriString);
}
/**

View file

@ -1,77 +0,0 @@
/*******************************************************************************
* Copyright (c) 2010 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
*******************************************************************************/
package org.eclipse.cdt.core;
import java.net.URI;
import java.net.URISyntaxException;
/**
* Abstract class providing the basis for utility classes that can extract meaningful information from EFS filesystems.
* Provides a default implementation that assumes that URIs for the given filesystem map directly to resources
* in the physical filesystem, and that the path component of the URI is a direct representation of the absolute path to
* the file in the physical filesystem.
*
* Clients wishing to support a filesystem with different behaviour should extend this class and override its methods where
* appropriate.
*
* Clients should not typically call methods on this class or its descendants directly. Instead, they should call the approrpriate method
* in FileSystemUtilityManager so that said manager can properly route calls to the proper utility, depending on the filesystem.
*
* <strong>EXPERIMENTAL</strong>. This class or interface has been added as
* part of a work in progress. There is no guarantee that this API will work or
* that it will remain the same. Please do not use this API without consulting
* with the CDT team.
*
* @noinstantiate This class is not intended to be instantiated by clients.
*
* @author crecoskie
* @since 5.2
*
*/
public class FileSystemUtility implements IFilesystemUtility {
/* (non-Javadoc)
* @see org.eclipse.cdt.core.IFilesystemUtility#getPathFromURI(java.net.URI)
*/
public String getPathFromURI(URI locationURI) {
return locationURI.getPath();
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.IFilesystemUtility#getBaseURI(java.net.URI)
*/
public URI getBaseURI(URI locationURI) {
return null;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.IFilesystemUtility#replacePathInURI(java.net.URI, java.lang.String)
*/
public URI replacePathInURI(URI locationOnSameFilesystem, String path) {
URI uri = locationOnSameFilesystem;
try {
return new URI(uri.getScheme(), uri.getUserInfo(), uri.getHost(), uri.getPort(),
path, // replaced!
uri.getQuery(),uri.getFragment());
} catch (URISyntaxException e) {
CCorePlugin.log(e);
}
return null;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.IFilesystemUtility#getMappedPath(java.net.URI)
*/
public String getMappedPath(URI locationURI) {
return getPathFromURI(locationURI);
}
}

View file

@ -1,66 +0,0 @@
/*******************************************************************************
* Copyright (c) 2009, 2010 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
*******************************************************************************/
package org.eclipse.cdt.core;
import java.net.URI;
/**
* An interface for utility classes that can extract meaningful information from EFS filesystems.
*
* <strong>EXPERIMENTAL</strong>. This class or interface has been added as
* part of a work in progress. There is no guarantee that this API will work or
* that it will remain the same. Please do not use this API without consulting
* with the CDT team.
*
* @author crecoskie
* @since 5.2
* @noimplement This interface is not intended to be implemented by clients.
* @noextend This interface is not intended to be extended by clients.
*
*/
public interface IFilesystemUtility {
/**
* Gets the path corresponding to the underlying file as the operating system on the target machine would see it.
* In the future, it would be better if EFS had an API for this.
*
* @param locationURI
* @return String representing the path, or <code>null</code> if there is an error or if there is no such physical file.
*/
public String getPathFromURI(URI locationURI);
/**
* In the case of a managed (linked) filesystem, returns the URI that this URI ultimately will
* point to.
*
* @param locationURI
* @return A uri corresponding to the linked store, or <code>null</code> if no such link exists.
*/
public URI getBaseURI(URI locationURI);
/**
* Creates a new URI on the same filesystem as another URI, but with a different path.
*
* @param locationOnSameFilesystem A URI pointing to another resource on the same filesystem that this resource
* should be on.
* @param path The absolute path to the resource.
* @return URI
*/
public URI replacePathInURI(URI locationOnSameFilesystem, String path);
/**
* Gets the path for this file as it appears when it is mapped into the filesystem. For
* unmapped filesystems, this would return the same path as getPathFromURI(URI locationURI)
*
* @return String representing the path, or <code>null</code> on error.
*/
public String getMappedPath(URI locationURI);
}

View file

@ -0,0 +1,221 @@
/*******************************************************************************
* Copyright (c) 2009, 2010 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
*******************************************************************************/
package org.eclipse.cdt.utils;
import java.net.URI;
import java.util.HashMap;
import java.util.Map;
import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.core.EFSExtensionProvider;
import org.eclipse.core.filesystem.URIUtil;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.IExtension;
import org.eclipse.core.runtime.IExtensionPoint;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Platform;
/**
* Manager class that consults contributors to the EFSExtensionProvider extension point
* to perform operations corresponding to those filesystems. The default behaviour if no provider is present
* is to assumes that URIs for the given filesystem map directly to resources in the physical filesystem, and
* that the path component of the URI is a direct representation of the absolute path to the file in the
* physical filesystem. Also, operations will by default respect the syntax and semantics of the local EFS
* filesystem, if operations are performed with respect to it.
*
* <strong>EXPERIMENTAL</strong>. This class or interface has been added as part of a work in progress. There
* is no guarantee that this API will work or that it will remain the same. Please do not use this API without
* consulting with the CDT team.
*
* @author crecoskie
* @noextend This class is not intended to be extended by clients.
* @since 5.2
*/
public class EFSExtensionManager {
private class DefaultProvider extends EFSExtensionProvider {
}
private DefaultProvider fDefaultProvider = new DefaultProvider();
private static EFSExtensionManager instance;
private Map<String, EFSExtensionProvider> fSchemeToExtensionProviderMap;
private static String EXTENSION_ID = "EFSExtensionProvider"; //$NON-NLS-1$
private EFSExtensionManager() {
fSchemeToExtensionProviderMap = new HashMap<String, EFSExtensionProvider>();
loadExtensions();
}
private void loadExtensions() {
IExtensionPoint extension = Platform.getExtensionRegistry().getExtensionPoint(CCorePlugin.PLUGIN_ID,
EXTENSION_ID);
if (extension != null) {
IExtension[] extensions = extension.getExtensions();
for (int i = 0; i < extensions.length; i++) {
IConfigurationElement[] configElements = extensions[i].getConfigurationElements();
for (int j = 0; j < configElements.length; j++) {
String scheme = configElements[j].getAttribute("scheme"); //$NON-NLS-1$
String utility = configElements[j].getAttribute("class"); //$NON-NLS-1$
if (utility != null) {
try {
Object execExt = configElements[j].createExecutableExtension("class"); //$NON-NLS-1$
if (execExt instanceof EFSExtensionProvider) {
fSchemeToExtensionProviderMap.put(scheme,
(EFSExtensionProvider) execExt);
}
} catch (CoreException e) {
CCorePlugin.log(e);
}
}
}
}
}
}
public synchronized static EFSExtensionManager getDefault() {
if (instance == null) {
instance = new EFSExtensionManager();
}
return instance;
}
/**
* If the EFS store represented by locationURI is backed by a physical file, gets the path corresponding
* to the underlying file. The path returned is suitable for use in constructing a {@link Path} object. This
* method will return the corresponding path regardless of whether or not the EFS store actually exists.
*
*
* @param locationURI
* @return String representing the path, or <code>null</code> if there is an error or if the store
* is not backed by a physical file.
*/
public String getPathFromURI(URI locationURI) {
EFSExtensionProvider provider = fSchemeToExtensionProviderMap.get(locationURI.getScheme());
if (provider == null) {
provider = fDefaultProvider;
}
return provider.getPathFromURI(locationURI);
}
/**
* In the case of a virtual filesystem, where URIs in the given filesystem are just soft links in EFS to
* URIs in other filesystems, returns the URI that this URI links to. If the filesystem is not virtual,
* then this method acts as an identity mapping.
*
* @param locationURI
* @return A URI corresponding to the linked store, or <code>null</code> on error.
*/
public URI getLinkedURI(URI locationURI) {
EFSExtensionProvider provider = fSchemeToExtensionProviderMap.get(locationURI.getScheme());
if (provider == null) {
provider = fDefaultProvider;
}
return provider.getLinkedURI(locationURI);
}
/**
* Creates a new URI which clones the contents of the original URI, but with the path replaced by the
* given path, such that calling getPathFromURI() on the returned URI will return the given path. Returns
* null on error.
*
* @param locationOnSameFilesystem
* @param path
* @return the new URI, or <code>null</code> on error
*/
public URI createNewURIFromPath(URI locationOnSameFilesystem, String path) {
URI uri = locationOnSameFilesystem;
EFSExtensionProvider provider = fSchemeToExtensionProviderMap.get(uri.getScheme());
if (provider == null) {
return fDefaultProvider.createNewURIFromPath(uri, path);
}
else {
return provider.createNewURIFromPath(uri, path);
}
}
/**
* For filesystems that map the path to a physical file in one filesystem (say on a remote machine) to
* another path (say, on the local machine), this method returns the path that the store maps to. I.e., it
* returns the path that the path returned by getPathFromURI(URI locationURI) maps to. If there is no such
* mapping, then an identity mapping of the paths is assumed.
*
* Typically if a filesystem maps one filesytem to another, it will place the mapped path in the path
* field of its URIs (which the default implementation assumes), but this is not guaranteed to be so for
* all filesystem implementations.
*
* @return String representing the path, or <code>null</code> on error.
*/
public String getMappedPath(URI locationURI) {
URI uri = locationURI;
EFSExtensionProvider provider = fSchemeToExtensionProviderMap.get(uri.getScheme());
if (provider == null) {
provider = fDefaultProvider;
}
return provider.getMappedPath(uri);
}
/**
* Returns true if the given URI is part of a virtual filesystem and thus points to another underlying
* URI. Returns false otherwise. By default, filesystems are assumed to be non-virtual.
*
* @param locationURI
* @return boolean
*/
public boolean isVirtual(URI locationURI) {
EFSExtensionProvider provider = fSchemeToExtensionProviderMap.get(locationURI
.getScheme());
if (provider == null) {
provider = fDefaultProvider;
}
return provider.isVirtual(locationURI);
}
/**
* Creates a new URI with the same components as the baseURI, except that calling
* getPathFromURI() on the new URI will return a path that has the extension appended to
* the path returned by baseURI.getPathFromURI()
*
* @param baseURI
* @param extension
* @return the new URI, or <code>null</code> on error.
*/
public URI append(URI baseURI, String extension) {
EFSExtensionProvider provider = fSchemeToExtensionProviderMap.get(baseURI
.getScheme());
if (provider == null) {
provider = fDefaultProvider;
}
return provider.append(baseURI, extension);
}
}

View file

@ -1,177 +0,0 @@
/*******************************************************************************
* Copyright (c) 2009, 2010 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
*******************************************************************************/
package org.eclipse.cdt.utils;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.HashMap;
import java.util.Map;
import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.core.IFilesystemUtility;
import org.eclipse.core.filesystem.URIUtil;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.IExtension;
import org.eclipse.core.runtime.IExtensionPoint;
import org.eclipse.core.runtime.Platform;
/**
* Manager class that consults contributors to the FileSystemUtility extension point to perform operations corresponding to those filesystems.
*
* <strong>EXPERIMENTAL</strong>. This class or interface has been added as
* part of a work in progress. There is no guarantee that this API will work or
* that it will remain the same. Please do not use this API without consulting
* with the CDT team.
*
* @author crecoskie
* @noextend This class is not intended to be extended by clients.
* @since 5.2
*/
public class FileSystemUtilityManager {
private static FileSystemUtilityManager instance;
private Map<String, IFilesystemUtility> fSchemeToUtilityImplementerMap;
private static String EXTENSION_ID = "FileSystemUtility"; //$NON-NLS-1$
private FileSystemUtilityManager() {
fSchemeToUtilityImplementerMap = new HashMap<String, IFilesystemUtility>();
loadExtensions();
}
private void loadExtensions() {
IExtensionPoint extension = Platform.getExtensionRegistry().getExtensionPoint(CCorePlugin.PLUGIN_ID,
EXTENSION_ID);
if (extension != null) {
IExtension[] extensions = extension.getExtensions();
for (int i = 0; i < extensions.length; i++) {
IConfigurationElement[] configElements = extensions[i].getConfigurationElements();
for (int j = 0; j < configElements.length; j++) {
String scheme = configElements[j].getAttribute("scheme"); //$NON-NLS-1$
String utility = configElements[j].getAttribute("class"); //$NON-NLS-1$
if (utility != null) {
try {
Object execExt = configElements[j].createExecutableExtension("class"); //$NON-NLS-1$
if (execExt instanceof IFilesystemUtility) {
fSchemeToUtilityImplementerMap.put(scheme, (IFilesystemUtility) execExt);
}
} catch (CoreException e) {
CCorePlugin.log(e);
}
}
}
}
}
}
public synchronized static FileSystemUtilityManager getDefault() {
if(instance == null) {
instance = new FileSystemUtilityManager();
}
return instance;
}
/**
* Gets the path out of a URI. Right now this is hardcoded to deal with a select few filesystems.
* In the future, it would be better if EFS had an API for this.
*
* @param locationURI
* @return String representing the path.
*/
public String getPathFromURI(URI locationURI) {
IFilesystemUtility utility = fSchemeToUtilityImplementerMap.get(locationURI.getScheme());
if(utility == null) {
return locationURI.getPath();
}
else {
return utility.getPathFromURI(locationURI);
}
}
/**
* In the case of a managed (linked) filesystem, returns the URI that this URI ultimately will
* point to. Otherwise, returns null.
*
* @param locationURI
* @return URI
*/
public URI getManagedURI(URI locationURI) {
IFilesystemUtility utility = fSchemeToUtilityImplementerMap.get(locationURI.getScheme());
if(utility == null) {
return null;
}
else {
return utility.getBaseURI(locationURI);
}
}
/**
* Creates a new URI which clones the contents of the original URI, but with the path
* replaced by the given path. Returns null on error.
*
* @param uri
* @param path
* @return URI
*/
public URI replacePath(URI uri, String path) {
IFilesystemUtility utility = fSchemeToUtilityImplementerMap.get(uri.getScheme());
if(utility == null) {
// if there is no corresponding utility, then assume we can just replace the path field
// Is it a local filesystem uri? Its URIs are a bit weird sometimes, so use URIUtil
if(uri.getScheme().equals("file")) { //$NON-NLS-1$
return URIUtil.toURI(path);
}
try {
return new URI(uri.getScheme(), uri.getUserInfo(), uri.getHost(), uri.getPort(),
path, // replaced!
uri.getQuery(),uri.getFragment());
} catch (URISyntaxException e) {
String message = "Problem converting path to URI [" + path.toString() + "]"; //$NON-NLS-1$//$NON-NLS-2$
CCorePlugin.log(message, e);
}
return null;
}
else {
return utility.replacePathInURI(uri, path);
}
}
public String getMappedPath(URI uri) {
IFilesystemUtility utility = fSchemeToUtilityImplementerMap.get(uri.getScheme());
if(utility == null) {
// if there is no corresponding utility, then assume it's just the path field
return uri.getPath();
}
else {
return utility.getMappedPath(uri);
}
}
}

View file

@ -29,7 +29,7 @@ import org.eclipse.cdt.make.internal.core.scannerconfig.util.KVStringPair;
import org.eclipse.cdt.make.internal.core.scannerconfig.util.SCDOptionsEnum;
import org.eclipse.cdt.make.internal.core.scannerconfig.util.TraceUtil;
import org.eclipse.cdt.make.xlc.core.scannerconfig.util.XLCCommandDSC;
import org.eclipse.cdt.utils.FileSystemUtilityManager;
import org.eclipse.cdt.utils.EFSExtensionManager;
import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
@ -614,7 +614,7 @@ public class XLCBuildOutputParserUtility {
// to the given path
URI projectURI = project.getLocationURI();
URI newURI = FileSystemUtilityManager.getDefault().replacePath(projectURI, path.toString());
URI newURI = EFSExtensionManager.getDefault().createNewURIFromPath(projectURI, path.toString());
IFile[] files = root.findFilesForLocationURI(newURI);