Repository Resource Management

Once you have created a RepositoryProvider, there are other resource management mechanism that should be understood:

Ignored Files

In several cases, it may be unnecessary to keep certain files under repository control.  For example, resources that are derived from existing resources can often be omitted from the repository.  For example, compiled source files, (such as Java ".class" files), can be omitted since their corresponding source (".java") file is in the repository.  It also may be inappropriate to version control metadata files that are generated by repository providers.  The org.eclipse.team.core.ignore extension point allows providers to declare file types that should be ignored for repository provider operations.  For example, the CVS client declares the following:

<extension point="org.eclipse.team.core.ignore">
<ignore pattern = ".#*" selected = "true"/>
</extension>

The markup simply declares a file name pattern that should be ignored and a selected attribute which declares the default selection value of the file type in the preferences dialog.  It is ultimately up to the user to decide which files should be ignored.  The user may select, deselect, add or delete file types from the default list of ignored files.

File Types

Some repositories implement different handling for text vs. binary files.  The org.eclipse.team.core.fileTypes extension allows plug-ins to declare file types as text or binary files.  For example, the Java tooling declares the following:

<extension point="org.eclipse.team.core.fileTypes">
<fileTypes extension="java" type="text"/>

<fileTypes extension="classpath" type="text"/>
<fileTypes extension="properties" type="text"/>
<fileTypes extension="class" type="binary"/>

<fileTypes extension="jar" type="binary"/>
<fileTypes extension="zip" type="binary"/>
</extension>

The markup lets plug-ins define a file type by extension and assign a type of text or binary.  As with ignored files, it is ultimately up to the user to manage the list of text and binary file types.

Team and Linked Resources

A project may contain resources that are not located within the project's directory in the local file system. These resources are referred to as linked resources.

Consequences for Repository Providers

Linked resources can pose particular challenges for repository providers which operate directly against the file system. This is a consequence of the fact that linked resources by design do not exist in the immediate project directory tree in the file system.

Providers which exhibit the following characteristics may be affected by linked resources:

  1. Those which call out to an external program that then operates directly against the file system.
  2. Those which are implemented in terms of IResource but assume that all the files/folders in a project exist as direct descendents of that single rooted directory tree.

In the first case, lets assume the user picks a linked resource and tries to perform a provider operation on it. Since the provider calls a command line client, we can assume that the provider does something equivalent to first calling IResource.getLocation().toOSString(), feeding the resulting file system location as an argument to the command line program. If the resource in question is a linked resource, this will yield a file/folder outside of the project directory tree. Not all command line clients may expect and be able to handle this case. In short, if your provider ever gets the file system location of a resource, it will likely require extra work to handle linked resources.

The second case is quite similar in that there is an implicit assumption that the structure of the project resources is 1:1 with that of the file system files/folders. In general, a provider could be in trouble if they mix IResource and java.io.File operations. For example, for links, the parent of IFile is not the same as the java.io.File's parent and code which assumes these to be the same will fail.

Backwards Compatibility

It was important that the introduction of linked resources did not inadvertently break existing providers. Specifically, the concern was for providers that reasonably assumed that the local file system structure mirrored the project structure. Consequently, by default linked resources can not be added to projects that are mapped to such a provider. Additionally, projects that contain linked resources can not by default be shared with that provider.

Strategies for Handling Linked Resources

In order to be "link friendly", a provider should allow projects with linked resources to be version controlled, but can disallow the version controlling of linked resources themselves.

A considerably more complex solution would be to allow the versioning of the actual linked resources, but this should be discouraged since it brings with it complex scenarios (e.g. the file may already be version controlled under a different project tree by another provider). Our recommendation therefore is to support version controlled projects which contain non-version controlled linked resources.

Technical Details for Being "link Friendly"

Repository provider implementations can be upgraded to support linked resources by overriding the RepositoryProvider.canHandleLinkedResources() method to return true. Once this is done, linked resources will be allowed to exist in projects shared with that repository provider. However, the repository provider must take steps to ensure that linked resources are handled properly. As mentioned above, it is strongly suggested that repository providers ignore all linked resources. This means that linked resources (and their children) should be excluded from the actions supported by the repository provider. Furthermore, the repository provider should use the default move and delete behavior for linked resources if the repository provider implementation overrides the default IMoveDeleteHook.

Team providers can use IResource.isLinked() to determine if a resource is a link. However, this method only returns true for the root of a link. The following code segment can be used to determine if a resource is the child of a link.

String linkedParentName = resource.getProjectRelativePath().segment(0);
IFolder linkedParent = resource.getProject().getFolder(linkedParentName);
boolean isLinked = linkedParent.isLinked();

Repository providers should ignore any resource for which the above code evaluates to true.

Team Private Resources

It is common for repository implementations to use extra files and folders to store information specific about the repository implementation.  Although these files may be needed in the workspace, they are of no interest to other plug-ins or to the end user.

Team providers may use IResource.setTeamPrivateMember(boolean) to indicate that a resource is private to the implementation of a team provider. Newly created resources are not private members by default, so this method must be used to explicitly mark the resource as team private.  A common use is to mark a subfolder of the project as team private when the project is configured for team and the subfolder is created.

Other resource API that enumerates resources (such as resource delta trees) will exclude team private members unless explicitly requested to include them.  This means that most clients will not "see" the team private resources and they will not be shown to the user.  The resource navigator does not show team private members by default, but users can indicate via Preferences that they would like to see team private resources.

Attempts to mark projects or the workspace root as team private will be ignored.

Project Sets

Since the resources inside a project under version control are kept in the repository, it is possible to share projects with team members by sharing a reference to the repository specific information needed to reconstruct a project in the workspace.  This is done using a special type of file export for team project sets.  

 

In 3.0, API was added to ProjectSetCapability to allow repository providers to declare a class that implements project saving for projects under their control.  When the user chooses to export project sets, only the projects configured with repositories that define project sets are shown as candidates for export. This API replaces the old project set serialization API (see below).

The project set capability class for a repository provider is obtained from the RepositoryProviderType class which is registered in the same extension as the repository provider. For example:

<extension point="org.eclipse.team.core.repository">
<repository
typeClass="org.eclipse.team.internal.ccvs.core.CVSTeamProviderType"

class="org.eclipse.team.internal.ccvs.core.CVSTeamProvider"
id="org.eclipse.team.cvs.core.cvsnature">
</repository>
</extension>

Prior to 3.0, The org.eclipse.team.core.projectSets extension point allowed repository providers to declare a class that implements project saving for projects under their control.  When the user chooses to export project sets, only the projects configured with repositories that define project sets are shown as candidates for export.

For example, the CVS client declares the following:

<extension point="org.eclipse.team.core.projectSets">
<projectSets id="org.eclipse.team.cvs.core.cvsnature" class="org.eclipse.team.internal.ccvs.ui.CVSProjectSetSerializer"/>
</extension>

The specified class must implement IProjectSetSerializer. Use of this interface is still supported in 3.0 but has been deprecated.