Migration to flexible workspaces
[Flexible workspaces home]
Last modified: October 12, 2005

Existing clients of org.eclipse.core.resources might not support the new flexibility afforded by flexible workspaces. Client code that assumes each IResource is located in the local file system will likely no longer work when resources are stored in other kinds of file systems. This guide describes the migration steps for clients that want to start supporting these new flexible workspaces.

IResource.getLocation()

The old method IResource.getLocation() returns the local file system path of a resource. This method no longer works for resources that are not stored in the local file system. Most callers of getLocation() did so in order to obtain an instance of java.io.File, which can no longer be used for resources that are not stored in the local file system.

The new org.eclipse.core.filesystem plugin provides a generic file system API that can be used in place of java.io.File. In particular, an instance of org.eclipse.core.filesystem.IFileStore provides most of the same methods that are available on java.io.File. The following snippet of code obtains an instance of IFileStore for a given resource:

   IResource resource = ...;//some resource
   IFileStore store = EFS.getStore(resource.getLocationURI());

The following table provides equivalent methods on IFileStore for operations usually done with java.io.File:

java.io.FileIFileStore
deletedelete
getNamegetName
getParentgetParent
listchildNames
mkdirmkdir(EFS.SHALLOW, null)
mkdirsmkdir(EFS.NONE, null)
renameTomove
new FileInputStream(file)openInputStream
new FileOutputStream(file)openOutputStream

In the IFileStore API, most information about a file is stored in a structure called IFileInfo, obtained by calling IFileStore.fetchInfo(). This design allows for greater optimization over code using java.io.File, because many attributes about a file can often be obtained with a single file system call. Note that the information in an IFileInfo will become stale if the underlying file is changed, so instances should only be held onto as long as they are needed. Here are some methods on java.io.File that have equivalent methods on IFileInfo:

java.io.FileIFileInfo
canWriteisReadOnly
existsexists
getNamegetName
isDirectoryisDirectory
isFile!isDirectory()
isHiddenisHidden
lastModifiedgetLastModified
lengthgetLength
setLastModifiedsetLastModified
setReadOnlysetAttribute(EFS.ATTRIBUTE_READ_ONLY, true)

As a concrete example, code that was previously calling java.io.File.exists() can now call IFileStore.fetchInfo().exists(). When a IFileInfo is modified, the result needs to be stored back using the IFileStore.putInfo method. For example, this snippet flips the read only attribute on a file

   IFileStore store = ...;//some file store
   IFileInfo info = store.fetchInfo();
   boolean readOnly = info.getAttribute(EFS.ATTRIBUTE_READ_ONLY);
   info.setAttribute(EFS.ATTRIBUTE_READ_ONLY, !readOnly);
   store.putInfo(info, EFS.SET_ATTRIBUTES, null);

IProjectDescription.getLocation()

As with the getLocation() method, the project description's location may no longer be in the local file system. The method IProjectDescription.getLocationURI() can be used to obtain the location of a resource in an arbitrary file system.

Graceful failure

Clients that cannot handle resources outside the local file system may still want to adapt their code to fail more gracefully. Clients can check if a resource is in the local file system, and either ignore the resource or alert the user when they encouter a resource they cannot handle. To determine if a resource is in the local file system, you need to find out its file system scheme. This can be obtained from a resource as follows:

   IResource resource = ...;//some resource
   URI uri = resource.getLocationURI();
   if (uri != null && EFS.SCHEME_LOCAL.equals(uri.getScheme())) {
      //file is in local file system
   } else {
      //file is not in the local file system
   }
If you have an IFileStore instance in hand, you can obtain the scheme as follows:
   IFileStore store = ...;//a file store
   store.getFileSystem().getScheme();