用來管理和顯示工作區資源和在其他位置的資源之間的同步化狀態的 API,是 Eclipse 3.0 中的新增功能。 我們將在工作區外的資源稱為變式。 同步化是顯示不同位置的資源之間的變更以及選擇性地讓使用者執行動作來影響同步化狀態的行為。 同步化 API 與 RepositoryProvider API 呈正交狀態,不需要儲存庫提供者,就能夠使用。 同步化 API 的用途是將資源同步化狀態之不同呈現方式的實作作業簡化。 因此,這個 API 需要查詢資源同步化狀態的方法,但不需要影響狀態的方法。 影響狀態的方法留給實作者負責(不過,UI 會提供將特定提供者專用的功能表項目加到功表的連結鉤)。
在說明同步化 API 之前,最好先提供一些在討論工作區同步化時會用到的專有名詞和概念。
資源變式:對映至在其他位置的資源之本端資源,可稱為該項資源的變式。 也就是說,這些資源通常非常類似,但可能有少許不同(可能是本端資源有了修正,也可能是其他使用者變更了遠端複本)。 我們採取以本端工作區為中心的角度,將本端複本稱為資源,將任何遠端複本稱為資源變式。
同步化:我們將同步化稱為將資源變式之間的差異呈現給使用者的動作。 同步化不會影響變式的狀態,但會提供一個視圖來協助使用者瞭解不同組變式之間的差異。 不過,在同步化時,通常可讓使用者影響變式的狀態(如移入或回復)。
雙向和三向同步化:同步化狀態的決定有兩個基本類型:雙向和三向。 雙向比較只會考慮本端資源和單一資源變式(稱為遠端資源變式)。 這類型的比較只能顯示兩個資源之間的差異,但不提供變更相互關係的提示。 在同步化狀態的決定上,大部分程式碼儲存庫系統都支援三向比較。 這類型的比較包括本端資源、遠端資源變式和基本資源變式。 基本資源變式代表本端和遠端資源的共同上代。 如此便有可供指示變更方向的更精密的同步化狀態。
表 1:同步化狀態
雙向 三向 已變更
已刪除
已新增送出的變更
送入的變更
送出的刪除
送入的刪除
送出的新增
送入的新增
衝突的變更
衝突的刪除
衝突的新增
org.eclipse.team.core.synchronize 中的類別用來說明同步化狀態。 最重要的類別是 SyncInfo,因為它是實際定義同步化狀態的類別。 它的使用方式如下:
SyncInfo info = getSyncInfo(resource); // 這是取得資源同步化資訊的模擬的方法
int changekind = info.getKind();
if(info.getResourceComparator().isThreeWay()) {
if((changeKind & SyncInfo.DIRECTION_MASK) == SyncInfo.INCOMING) {
// 執行某個動作
}
} else if(changeKind == SyncInfo.CHANGE) {
// 執行其他動作
}
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(); // 計算同步化資訊
這個套件也包含專為了包含 SyncInfo 而設計的集合,以及可套用到 SyncInfo 實例的過濾器。
如我們在上述範例所見,SyncInfo 和 IResourceVariantComparator 類別可用來存取資源的同步化狀態。 但我們目前還沒看到狀態的管理方式。 Subscriber 可利用雙向或三向比較(依訂閱者的性質而定),以供存取本端工作區中的資源和這些資源的一組資源變式之間的同步化狀態。 訂閱者提供下列功能:
API 並未定義 Subscriber 的建立方式,這部分交給特定實作負責。 例如,執行合併時,CVS 外掛程式會建立一個 Subscriber; 執行比較時,會建立另一個 Subscriber; 而當同步化本端工作區和現行分支時,又會建立另一個 Subscriber。
我們重新來看看第一個使用 SyncInfo 的範例,看看如何利用 Subscriber 來存取 SyncInfo。
// 建立一個檔案系統訂閱者,指定
// 這個訂閱者將與所提供的檔案系統位置同步化
Subscriber subscriber = new FileSystemSubscriber("c:\temp\repo");
// 允許訂閱者重新整理它的狀態
subscriber.refresh(subscriber.roots(), IResource.DEPTH_INFINITE, monitor);
// 收集所有同步化狀態並列印
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 知道不在工作區中的資源,且從 Subscriber#members() 和 SyncInfo#getLocal() 可以傳回不存在的資源。
我們原可以花更多時間來說明如何管理同步化狀態,不過,現在我們要看看如何將狀態實際呈現給使用者。 ISynchronizeParticipant 是顯示同步化狀態以及讓使用者影響其狀態的使用者介面元件。 同步化視圖會顯示同步化參與者,但它們也可顯示在對話框和精靈中。 為了支援使用者將任何類型的同步化狀態呈現給使用者,甚至不是以 SyncInfo 和 Subscribers 為基礎者也包括在內,參與者是一個非常通用的元件。
另外還有一個稱為 org.eclipse.team.ui.synchronizeWizards 的延伸點,用來新增同步化建立精靈。 這會將您的精靈放在廣域同步化動作和同步化視圖中,讓使用者很容易建立您的同步化類型。
不過,如果您實作了 Subscriber,您可能會受益於一個稱為 SubscriberParticipant 且提供下列功能的具體參與者:
說明這些概念的最佳方式,是在簡單範例的環境中觀察它們的使用。
請移至本端歷程同步化範例來查看所有這些片段如何共用運作。
如果您需要如何使用更進階的 API 的指示,請移至基本觀念之外。