Adding synchronization support to your provider

This section presents a two perspectives on implementing a subscriber on top of a provider. The first assumes that there is no exisiting synchronization infrastructure and illustrates how to use some API that is provided to maintain the synchronization state. The second assumes that there is an existing synchronization infrastructure, perhaps associated with a repository provider.

Implementing a Subscriber From Scratch

This first example assumes that there is no existing infrastructure for maintaining the synchronization state of the local workspace. When implementing a subscriber from scratch, you can make use of some additional API provided in the org.eclipse.team.core plugin. The org.eclipse.team.core.variants package contains two subclasses of Subscriber which can be used to simplify implementation. The first is ResourceVariantTreeSubscriber which will be discussed in the second example below. The second is a subclass of the first: ThreeWaySubscriber. This subscriber implementation provides several helpful classes for managing the synchronization state of a local workspace. If you do not have any existing infrastructure, this is a good place to start.

Implementing a subscriber from scratch will be illustrated using the file system example available in the org.eclipse.team.examples.filesystem plugin. The code in the following description is kept to a minimum since it is available from the dev.eclipse.org repository. Although not technicaly a three-way subscriber, the file system example can still make good use of this infrastructure. The FTP and WebDav plugins also are built using this infrastructure.

ThreeWaySubscriber

For the file system example, we already had an implementation of a RepositoryProvider that associated a local project with a file system location where the local contents were mirrored. FileSystemSubscriber was created as a subclass of ThreeWaySubscriber in order to make use of a ThreeWaySynchronizer to manage workpace synchronization state. Subsclasses of this class must do the following:

In addition to the subscriber implementation, the get and put operations for the file system provider were modified to update the synchronization state in the ThreeWaySynchronizer. The operations are implemented in the class org.eclipse.team.examples.filesystem.FileSystemOperations.

ThreeWaySynchronizer

ThreeWaySynchronizer manages the synchronization state between the local workspace and a remote location. It caches and persists the local, base and remote timestamps in order to support the efficient calculation of the synchronization state of a resource. It also fires change notifications to any registered listeners. The ThreeWaySubscriber translates these change events into the proper format to be sent to listeners registered with the subscriber.

The ThreeWaySynchronizer makes use of Core scheduling rules and locks to ensure thread safety and provide change notification batching.

ThreeWayRemoteTree

A ThreeWayRemoteTree is a subclass of ResourceVariantTree that is tailored to the ThreeWaySubscriber. It must be overridden by clients to provide the mechanism for fetching the remote state from the server. ResourceVariantTree is discussed in more detail in the next example.

CachedResourceVariant

A CachedResourceVariant is a partial implementation of IResourceVariant that caches any fetched contents for a period of time (currently 1 hour). This is helpful since the contents may be accessed several times in a short period of time (for example, to determine the synchronization state and display the contents in a compare editor). Subclasses must still provide the unique content identifier along with the byte array that can be persisted in order to recreate the resource variant handle.

Building on Top of Existing Workspace Synchronization

Many repository providers may already have a mechanism for managing their synchronization state (e.g. if they have exisitng plugins). The ResourceVariantTreeSubscriber and its related classes provide the ability to build on top of an existing synchronization infrastrucuter. For example, this is the superclass of all of the CVS subscribers.

ResourceVariantTreeSubscriber

As was mentioned in the previous example, the ThreeWaySubscriber is a subclass of ResourceVariantTreeSubscriber that provides local workspace synchronization using a ThreeWaySynchronizer. Subclasses of ResourceVariantTreeSubscriber must provide:

The other capabilities of the subscriber are implemented using these facilities.

ResourceVariantTree

ResourceVariantTree is a concrete implementation of IResourceVariantTree that provides the following:

The following must be implemented by subclasses:

Concreate implementations of ResourceVariantByteStore are provided that persist bytes accross workbench invocations (PersistantResourceVariantByteStore) or cached the bytes only for the current session (SessionResourceVariantByteStore). However, building a subscriber on top of an exisiting workspace synchronization infrastructure will typically requie the implementation of ResourceVariantByteStore subclasses that interface with the underlying synchronizer. For example the ThreeWayRemoteTree makes use of a byte store implementation that stores the remote bytes in the ThreeWaySynchronizer.

The creation of resource variant handles for this exampel does not differ from the previous exampel except that the handles are requested from a resource variant tree instance instead of the subscriber.

IResourceVariantComparator

Each subscriber has a IResourceVariantComparator which is used by the SyncInfo class when determining the synchronization state of a resource. The resource comparator determines whether the comparison is two-way or three-way and provides a method to compare a local resource with a resource variant and another method to compare two resource variants (if the comparison is three-way). The resource comparator needs to access the workspace synchronization state when comparing a lcoal resource to a resource variant. A ThreeWayResourceComparator is provided for use with the ThreeWaySynchronizer. Providers that have their own workspace synchronization infrastructure need to provide an IResourceVariantComparator implementation that accesses the local resource state.

SyncInfo

The SyncInfo class is used to communicate the synchronization state of a resource. In addition the class contains the algorithm used to determine the synchronization state given the local, base and remote resources as well as the resource comparator. Although it is possible to use the SyncInfo class without modification, in practice, it is often necessary for a subscriber to subclass it in order to tailor the synchronization state determination.

How Does IRemoteResource/IRemoteSyncElement Relate to the Subsciber API

IResourceVariant is similar to IRemoteResource. However, there is no API on IResourceVariant for obtaining the memebrs of the variant if it is a container. This has been moved to the IResourceVariantTree. This was done to allow the traversal and refresh to be expressed more cleanly. Also, the contents of an IResourceVariant are fetched indirectly by obtaining an IStorage from the handle and then obtaining the contents from the IStorage. This was done to support the local caching of remote contents. The CachedResourceVariant implementation of IResourceVariant provides API that supports content caching.

The behavior of IRemoteSyncElement/RemoteSyncElement has been separated into several classes to get a better separation of concerns. The SyncInfo class provides the synchronization state determination while the ResourceVariantTree capture the logic to refresh the remote state. Traversal is provides by the Subscriber class itself.

Implementing a Two-way Compare Subscriber

To be added

Copyright IBM Corporation and others 2000, 2003.