Eclipse 3.0 中新增了一些用于管理和显示工作空间资源与另一个位置的资源之间的同步状态的 API。我们将工作空间外部的资源称为变体。同步是一种操作,它显示不同位置的资源之间的更改,(可选)并允许用户通过执行操作来影响同步状态。同步 API 与 RepositoryProvider API 互不相关,所以,可以在没有存储库提供程序的情况下使用同步 API。通过同步 API 可以很轻松地实现用来表示资源的同步状态的不同方法。因此,API 需要采用一种方法来查询资源的同步状态,但是不需要采用一种方法来影响状态。将由实现器提供影响状态的方法(尽管用户界面确实提供了用于将特定于提供程序的菜单项添加至菜单的挂钩)。
在描述同步 API 之前,提供在讨论工作空间同步时应用的某些术语和概念是很有帮助的。
资源变体:映射至存在于另一个位置的资源的本地资源可以称为该资源的变体。即,资源通常都很相似,但是也可能会稍微有所不同(造成这种不同的原因是对本地资源进行了修改或者其他用户进行远程复制而造成了更改)。从本地工作空间的角度来说,将本地副本称为资源,而将任何远程副本称为资源变体。
同步:我们将同步称为向用户显示资源变体之间区别的一种操作。同步不会影响变体的状态,但是会提供一个视图来帮助用户了解不同变体集合之间的区别。但是,通常允许用户在同步时影响变体的状态(例如,允许检入或还原)。
两方同步与三方同步:有两种基本类型的同步状态确定:两方和三方。两方比较只考虑本地资源和单个资源变体,称为远程资源变体。这种类型的比较只能显示两个资源之间的区别,但是不能提供有关这些更改之间如何相互联系的提示。大多数代码存储库系统支持使用三方比较来进行同步状态确定。这种类型的比较涉及到本地资源、远程资源变体和基本资源变体。基本资源变体表示本地资源和远程资源的公共祖代。这允许用来指示更改方向的更复杂的同步状态。
表 1:同步状态
两方 三方 已更改
已删除
已添加传出更改
传入更改
传出删除
传入删除
传出添加
传入添加
冲突更改
冲突删除
冲突添加
org.eclipse.team.core.synchronize 中的类用来描述同步状态。最重要的类是 SyncInfo,这是因为它是实际定义同步状态的类。可以按如下所示使用它:
SyncInfo info = getSyncInfo(resource); // this is a simulated method of obtaining the sync info for a resource
int changekind = info.getKind();
if(info.getResourceComparator().isThreeWay()) {
if((changeKind & SyncInfo.DIRECTION_MASK) == SyncInfo.INCOMING) {
// do something
}
} else if(changeKind == SyncInfo.CHANGE) {
// do something else
}
SyncInfo 类同时提供了两方和三方比较算法,客户机必须提供资源以及可以比较这些资源的类(IResourceVariantComparator)。下面是变体比较器的一个示例:
public class TimestampVariantComparator implements IResourceVariantComparator {
protected boolean compare(IResourceVariant e1, IResourceVariant e2) {
if(e1.isContainer()) {
if(e2.isContainer()) {
return true;
}
return false;
}
if(e1 instanceof MyResourceVariant && e2 instanceof MyResourceVariant) {
MyResourceVariant myE1 = (MyResourceVariant)e1;
MyResourceVariant myE2 = (MyResourceVariant)e2;
return myE1.getTimestamp().equals(myE2.getTimestamp());
}
return false;
}
protected boolean compare(IResource e1, IResourceVariant e2) {
}
public boolean isThreeWay() {
return true;
}
}
SyncInfo info = new SyncInfo(resource, variant1, variant2, new TimestampComparator());
info.init(); // calculate the sync info
此包还包含了专门用来包含 SyncInfo 的集合以及可以应用于 SyncInfo 实例的过滤器。
正如我们在上面的示例中看到的那样,SyncInfo 和 IResourceVariantComparator 类都提供了对资源的同步状态的访问权。但是,我们尚不了解是如何管理状态的。Subscriber 提供对本地工作空间中的资源与这些资源的一组资源变体之间的同步状态的访问权(是使用两方比较还是使用三方比较则取决于订户的性质)。订户提供了下列功能:
API 不会定义如何创建订户,它将由特定实现来定义。例如,当执行合并时,CVS 插件会创建订户,为了进行比较会创建另一个订户,并在使本地工作空间与当前分支进行同步时又创建另外一个订户。
因此,让我们回顾一下使用 SyncInfo 的第一个示例,并了解可以如何使用订户来访问 SyncInfo。
// Create a file system subscriber and specify that the
// subscriber will synchronize with the provided file system location
Subscriber subscriber = new FileSystemSubscriber("c:\temp\repo");
// Allow the subscriber to refresh its state
subscriber.refresh(subscriber.roots(), IResource.DEPTH_INFINITE, monitor);
// Collect all the synchronization states and print
IResource[] children = subscriber.roots();
for(int i=0; i < children.length; i++) {
printSyncState(children[i]);
}
...
void printSyncState(Subscriber subscriber, IResource resource) {
System.out.println(subscriber.getSyncInfo(resource).toString());
IResource[] children = subscriber.members(resource);
for(int i=0; i < children.length; i++) {
IResource child = children[i];
if(! child.exists()) {
System.out.println(resource.getFullPath() + " doesn't exist in the workspace");
}
printSyncState(subscriber, children[i]);
}
}
要记住的要点是,订户知道工作空间中不存在的资源,并且非现有资源可以从 Subscriber#members() 和 SyncInfo#getLocal() 中返回。
我们可以花更多时间说明如何管理同步状态,但是还是让我们了解如何实际获取对用户显示的状态吧。 ISynchronizeParticipant 是用来显示同步状态的一个用户界面组件,它允许用户影响其状态。“同步视图”显示同步参与者,但是还可以在对话框和向导中显示这些参与者。为了支持用户向用户显示任何类型的同步状态(即使这些同步状态不是基于 SyncInfo 和订户的),参与者是一个很通用的组件。
还有一个名为 org.eclipse.team.ui.synchronizeWizards 的扩展点用来添加同步创建向导。这将使向导处于全局同步操作和“同步视图”中,以便用户能够很容易地创建您的类型的同步。
但是,如果已经实现了订户,则可以得益于称为 SubscriberParticipant 的具体参与者,它将提供以下功能:
说明这些概念的最佳方法是在简单示例的上下文中查看是如何使用这些术语的。转至本地历史同步示例以了解可以如何将这些术语一起使用。或者,如果想要了解有关如何使用更高级的 API 的更多信息,请转至高级。