Repository resource management
Once you have created a
RepositoryProvider
,
there are other resource management mechanism that should be understood:
- In order to allow other plug-ins to indicate special handling for
their projects
and files the team plug-in defines extension points that other
providers and other plug-ins can use to register
file
types and to
declare files that should be
ignored by a
repository provider.
- Team providers can also register a class that can be used to
persist
a
set a projects so that references to the
project can be shared across
a team, with the actual contents coming from the repository.
- Repository providers should consider how they will handle linked resources.
- Finally, team providers can mark resources that should be hidden
from the user as
team private.
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:
- Those which call out to an external program that then operates
directly against the file system.
- 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.