同期サポート

Eclipse 3.0 の新機能として、ワークスペース・リソースと別のロケーションにあるリソース間の同期状態を管理および表示する API があります。 ワークスペース外部のリソースをバリアントと呼びます。 同期化は、異なるロケーションにあるリソース間の変更点を表示する動作であり、ユーザーはオプションで操作を実行することにより、 同期状態に影響を与えることができます。 同期 API は RepositoryProvider API と直交し、リポジトリー・プロバイダーなしで使用できます。 同期 API の目的は、リソースの同期状態を表示するためのさまざまな方法を実装するタスクを簡単にすることです。 そのため、API にはリソースの同期状態を問い合わせる手段が必要ですが、状態に影響を与える手段は必要ありません。 状態に影響を与える手段は、実装者に任されています (ただし、UI には、 プロバイダー固有のメニュー項目をメニューに追加するためのフックが提供されています)。

用語

同期 API について説明する前に、ワークスペースの同期化の説明で使用されるいくつかの用語と概念について解説します。

リソース・バリアント: 別のロケーションにあるリソースにマップされるローカル・リソースは、リソースのバリアントと呼ばれることがあります。 つまり、リソースは通常よく似ていますが、わずかに異なることがあります (ローカル・リソースへの変更や、他のユーザーによってリモート・コピーに行われた 変更などにより)。これをローカル・ワークスペース中心の観点で捕らえ、ローカル・コピーをリソースと呼び、リモート・コピーをリソース・バリアントと 呼びます。

同期化: 同期化とは、リソース・バリアント間の差をユーザーに表示する動作を言います。 同期化はバリアントの状態に影響しません。その代わりに、ユーザーが異なる複数のバリアント・セット間の差を理解するのに役立つビューを提供します。 ただし、同期化の際にユーザーがバリアントの状態に影響を与えることができるようにするのが一般的です (チェックインや、チェックインを元に戻すなど)。

両方向同期化と 3 方向同期化: 同期状態を判別する方法には、両方向と 3 方向という 2 つの基本的なタイプがあります。 両方向比較では、ローカル・リソースと、リモート・リソース・バリアントと呼ばれる単一のリソース・バリアントのみを考慮します。 このタイプの比較は 2 つのリソース間の差を表示するのみで、差の相互関係についてのヒントを提示することはできません。 ほとんどのコード・リポジトリー・システムは、同期状態を判別するために 3 方向比較をサポートしています。 このタイプの比較では、ローカル・リソース、リモート・リソース・バリアントおよびベース・リソース・バリアントが考慮されます。 ベース・リソース・バリアントは、ローカル・リソースとリモート・リソースの共通上位を表します。 これにより、変更の方向を示す、より高度な同期状態を使用できます。

表 1: 同期状態

両方向 3 方向
変更
削除
追加
発信変更
着信変更
発信削除
着信削除
発信追加
着信追加
競合変更
競合削除
競合追加

基本 - SyncInfo

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 クラスは、両方向比較および 3 方向比較の両方のアルゴリズムを提供します。クライアントは、リソースおよびリソースを比較できるクラス (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 クラスは、 リソースの同期状態へのアクセスを提供します。 しかし、状態を管理する方法については、まだ説明していません。 サブスクライバーは、 サブスクライバーの性質に応じて両方向比較または 3 方向比較を使用し、ローカル・ワークスペース内のリソースと、 これらのリソースのリソース・バリアント・セットとの間の同期状態へのアクセスを提供します。 サブスクライバーには以下の機能があります。

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() から戻ることができるということです。

UI での同期状態の表示

同期状態の管理についての説明は以上とし、次に、ユーザーに表示する状態を実際に取得する方法を見ていきます。 ISynchronizeParticipant は、同期状態を表示し、ユーザーが同期状態に影響を与えることができるようにするユーザー・インターフェース・コンポーネントです。 同期の参加プログラムは同期ビューに表示されますが、ダイアログやウィザードに表示することも可能です。 任意のタイプの同期状態をユーザーに表示するためのサポートを提供するには、SyncInfo およびサブスクライバーに基づいていない場合でも、 参加プログラムが非常に汎用的なコンポーネントとなります。

また、同期作成ウィザードを追加するための org.eclipse.team.ui.synchronizeWizards という拡張ポイントもあります。 この拡張ポイントはグローバル同期アクションおよび同期ビューにウィザードを配置し、ユーザーが簡単に必要なタイプの同期化を作成できるようにします。

ただし、サブスクライバーを実装した場合は、SubscriberParticipant と呼ばれる具体的な参加プログラムの利点を活用できます。この参加プログラムには以下の機能があります。

これらの概念を説明する最適な方法は、簡単なコンテキストでの使用例を示すことです。 これらの断片をすべてまとめて使用する方法については、ローカル・ヒストリーの同期の例を参照してください。 または、より高度な API の使用方法の参照先については、『追加情報』を参照してください。