Synkroniseringssupport

I Eclipse ingår API:er för hantering och visning av synkroniseringsstatus mellan resurser i arbetsytan och resurser på en annan plats. Den resurs som är utanför arbetsytan kallas för en variant. Synkronisering är funktion för att visa ändringarna mellan resurser på olika platser och valfritt låta användaren påverka synkroniseringsläget genom att utföra en åtgärd. Synkroniserings-API:t är ortogonalt till RepositoryProvider-API:er och kan användas utan en lagerprovider. Syftet med synkroniserings-API:t är att underlätta uppgiften med att implementera olika sätt att presentera synkroniseringsläget för resurser. I API:t krävs därför ett sätt att ställa frågor mot synkroniseringsläget för resurser men behöver inte något sätt att påverka läget. Det innebär att påverkan av läget lämnas till implementatören (även om användargränssnittet innehåller hook-funktioner för att lägga till providerspecifika menyalternativ på menyer).

Terminologi

Innan synkroniserings-API:t beskrivs är det bra att visa viss terminologi och vissa begrepp som gäller vid diskussion av arbetsytesynkronisering.

Resursvariant: En lokal resurs som avbildas till en resurs som finns på annan plats kan kallas för en variant av den resursen. Dvs. resurserna liknar vanligtvis varandra till stor del men kan skilja sig något (antingen beroende på modifieringar av lokal resurs eller på att fjärrkopian ändrats av andra användare). Vi tar ett arbetsytecentrerad vy av detta, där vi kallar den lokala kopian för resursen och eventuella fjärrkopior för resursvarianter.

Synkronisera: Att synkronisera är den åtgärd som visar skillnaderna mellan resurservarianter. Synkronisering påverkar inte varianternas läge men ger i stället en vy som visar skillnaderna mellan olika uppsättningar varianter. Det är emellertid vanligt att låta användare påverkar varianternas läge (t.ex. tillåta incheckning, eller omvänt) vid synkronisering.

Två- resp trevägssynkronisering: Det finns två grundläggande typer för bestämning av synkroniseringsläge: två- och trevägs. En tvåvägsjämförelse beaktar bara den lokala resursen och en enda resursvariant, vilken kallas fjärresursvarianten. Den här typen av jämförelse kan bara visa skillnaderna mellan de två resurserna men kan inte erbjuda tips om hur ändringarna relaterar till varandra. Den mesta kod som kan användas i lagersystem är en trevägsjämförelse för bestämning av synkroniseringsläge. Den här typen av jämförelse inbegriper den lokala resursen, en fjärresursvariant och en basresursvariant. Basresursvarianten representerar ett vanligt överordnat objekt för lokala och fjärresurser. Med detta kan mer sofistikerade synkroniseringslägen, som indikerar ändringens riktning, visas.

Tabell 1: Synkroniseringslägena

Tvåvägs Trevägs
Ändrad
Borttagen
Tillagd
Utgående ändring
Inkommande ändring
Utgående borttag
Inkommande borttag
Utgående tillägg
Inkommande tillägg
Ändring i konflikt
Borttag i konflikt
Tillägg i konflikt

Grunderna - SyncInfo

Klasserna i org.eclipse.team.core.synchronize används för att beskriva synkroniseringsläget. Den viktigaste klassen är SyncInfo eftersom det är den klassen som verkligen definierar synkroniseringsläget. Den kan användas så här:

SyncInfo info = getSyncInfo(resource); // detta är en simulerad metod för att få synk.info för en resurs
int changekind = info.getKind();
if(info.getResourceComparator().isThreeWay()) {
if((changeKind & SyncInfo.DIRECTION_MASK) == SyncInfo.INCOMING) {
// gör något
}
} else if(changeKind == SyncInfo.CHANGE) {
// gör något annat
}

SyncInfo-klassen innehåller algoritmer för både två- och trevägsjämförelse, en klient måste tillhandahålla resurserna och en klass som kan jämföra resurserna (IResourceVariantComparator). Här visas ett exempel på en variantjämförare:

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(); // beräkna synk.info

Paketet innehåller också samlingar som specifikt utformats för att innehålla SyncInfo och filter som kan användas för SyncInfo-förekomster.

Hantera synkroniseringsläget

Som vi såg i ovanstående exempel ger klasserna SyncInfo och IResourceVariantComparator access till resursernas synkroniseringsläge. Men vi har ännu inte sett hur läget hanteras. En Subscriber ger access till synkroniseringsläget mellan resurserna på lokal arbetsyta och en uppsättning resursvarianter för dessa resurser med hjälp av antingen en två- eller en trevägsjämförelse, beroende på prenumeranten. En prenumerant har följande funktioner:

API:erna definierar inte hur en prenumerant skapas, detta görs via specifika implementationer. Exempelvis skapas en prenumerant av CVS-insticksprogrammet vid sammanfogning, en annan vid jämförelse och en annan när den lokala arbetsytan synkroniseras med aktuell gren.

Låt oss åter titta på vårt första exempel på användning av SyncInfo och se hur en prenumerant kan användas till att accessa SyncInfo.

// Skapa en filsystemsprenumerant och ange att
// prenumeranten ska synkronisera med angiven filsystemsplats
Subscriber subscriber = new FileSystemSubscriber("c:\temp\repo");

// Låt prenumeranten uppdatera läget
subscriber.refresh(subscriber.roots(), IResource.DEPTH_INFINITE, monitor);

// Samla in alla synkroniseringslägen och skriv ut
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() + " finns inte på arbetsytan");
}
printSyncState(subscriber, children[i]);
}
}

Det viktiga att komma ihåg är att prenumeranten känner till resurser som inte finns på arbetsytan och icke-befintliga resurser kan returneras från Subscriber#members() och SyncInfo#getLocal().

Visa synkroniseringsläge i användargränssnittet

Vi skulle kunna tillbringa mer tid med att förklara hantering av synkroniseringsläge men låt oss i stället se hur läget visas för användaren. En ISynchronizeParticipant är användargränssnittskomponenten som visar synkronseringsläge och som låter användaren påverkar läget. På synkroniseringsvyn visas synkroniseringsdeltagare, men dessa kan också visas i dialogrutor och i guider. Om support ska kunna ges för användare att visa någon typ av synkroniseringsläge, även de som inte baseras på SyncInfo och Subscribers måste deltagaren vara en mycket generisk komponent.

Det finns också en utökningspunkt som kallas org.eclipse.team.ui.synchronizeWizards för tillägg av en guide för att skapa synkronisering. Med denna placeras guiden i global synkroniseringsåtgärd och på synkroniseringsvyn så att en synkronisering av vald typ lätt kan skapas.

Om du emellertid har implementerat en prenumerant kan du tjäna på en konkret deltagare som kallas för en SubscriberParticipant , vilken ger följande funktioner:

Det bästa sättet att förklara dessa begrepp är att se dem i ett enkelt exempel. I synkronisering av lokal historik finns ett exempel som visar hur alla dessa bitar kan användas tillsammans. Tips om hur du använder mer avancerade API:er finns i Utöver grunderna.