If you plan on providing synchronization support and don't have an existing
mechanism for managing synchronization state, this section explains how to implementing
a Subscriber from scratch. This means that there is no existing synchronization
infrastructure and illustrates how to use some API that is provided to maintain
the synchronization state.
For the remainder of this example we will make use of a running example. The source code can be found in the file system provider package of the org.eclipse.ui.examples.filesystem plug-in. You should check the project out from the Git repository and use as a reference while you are reading this tutorial.
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 plug-in. 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.ui.examples.filesystem plug-in. The code in the following description is kept to a minimum since it is available from the Eclipse Git repository. Although not technically a three-way subscriber, the file system example can still make good use of this infrastructure. The FTP and WebDAV plug-ins also are built using this infrastructure.
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 workspace synchronization state. Subclasses 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 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.
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.
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.
Many repository providers may already have a mechanism for managing their synchronization state (e.g. if they have existing plug-ins). The ResourceVariantTreeSubscriber and its related classes provide the ability to build on top of an existing synchronization infrastructure. For example, this is the superclass of all of the Git subscribers.
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:
Subclasses of ResourceVariantTree (or AbstractResourceVariantTree) that provide the behavior for traversing and refreshing the remote resource variants and, for subscribers that support three-way comparisons, the base resource variants.
The other capabilities of the subscriber are implemented using these facilities.
ResourceVariantTree is a concrete implementation of IResourceVariantTree that provides the following:
The following must be implemented by subclasses:
Concrete implementations of ResourceVariantByteStore are provided that persist bytes across workbench invocations (PersistantResourceVariantByteStore) or cached the bytes only for the current session (SessionResourceVariantByteStore). However, building a subscriber on top of an existing workspace synchronization infrastructure will typically require 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 example does not differ from the previous example except that the handles are requested from a resource variant tree instance instead of the subscriber.