Understøttelse af synkronisering

Eclipse indeholder API'er til styring og fremvisning af synkroniseringstilstand mellem arbejdsområderessourcer og ressourcer på en anden placering. Vi refererer til en ressource uden for arbejdsområdet som en variant. Synkronisering er det at vise ændringer mellem ressourcer på forskellige placeringer og eventuelt give brugeren mulighed for at påvirke synkroniseringstilstanden ved at udføre en funktion. Synkroniserings-API'erne er ortogonale for RepositoryProvider-API'erne og kan bruges uden en udbyder af opbevaringssteder. Formålet med synkroniserings-API'et er at gøre det nemmere at implementere forskellige metoder til at præsentere ressourcers synkroniseringstilstand. API'et kræver en mulighed for at forespørge om ressourcernes synkroniseringstilstand, men det kræver ikke en mulighed for at påvirke tilstanden. Muligheden for at påvirke tilstanden overlades til den, der implementerer synkroniseringen (selvom grænsefladen indeholder hooks til tilføjelse af udbyderspecifikke menupunkter til menuer).

Terminologi

Inden synkroniserings-API'et beskrives, er det nyttigt at præsentere noget af den terminologi og de begreber, der anvendes i forbindelse med synkronisering af arbejdsområdet.

Ressourcevariant: En lokal ressource, der er tilknyttet vha. mapping til en ressource, som befinder sig på en anden placering, kan kaldes en variant af den pågældende ressource. Det vil sige, at ressourcerne normalt er meget ens, men at der kan være en lille forskel (enten på grund af ændringer af den lokale ressource eller på grund af ændringer af den eksterne kopi, foretaget af andre brugere). Vi betragter tingene med udgangspunkt i det lokale arbejdsområde og refererer til den lokale kopi som ressourcen og eksterne kopier som ressourcevarianter.

Synkronisere: Vi refererer til synkronisering som den funktion, hvor forskellene mellem ressourcevarianterne vises for brugeren. Synkronisering påvirker ikke tilstanden af varianterne, men leverer i stedet en oversigt, som kan hjælpe brugeren med at forstå forskellene mellem forskellige sæt varianter. Det er dog almindeligt at give brugerne mulighed for at påvirke varianternes tilstand (f.eks. tillade at tjekke ind eller fortryde) under synkronisering.

Tovejs- i modsætning til trevejssynkronisering: Der er to grundlæggende typer metoder til afgørelse af synkroniseringstilstand: tovejs og trevejs. En tovejssammenligning betragter kun den lokale ressource og en enkelt ressourcevariant, der kaldes den eksterne ressourcevariant. Denne type sammenligning kan kun vise forskelle mellem to ressourcer, men kan ikke tilbyde tip til, hvordan ændringerne er indbyrdes forbundet. De fleste opbevaringsstedsystemer understøtter trevejssammenligning ved afgørelse af synkroniseringstilstand. Denne type sammenligning involverer den lokale ressource, en ekstern ressourcevariant og en basisressourcevariant. Basisressourcevarianten repræsenterer en fælles stamklasse for lokale og eksterne ressourcer. Herved er der mulighed for mere avancerede synkroniseringstilstande, der angiver retningen af ændringen.

Tabel 1: Synkroniseringstilstandene

Tovejs Trevejs
Ændret
Slettet
Tilføjet
Udgående ændring
Indgående ændring
Udgående sletning
Indgående sletning
Udgående tilføjelse
Indgående tilføjelse
Sammenfaldende ændring
Sammenfaldende sletning
Sammenfaldende tilføjelse

Grundbegreber - SyncInfo

Klasserne i org.eclipse.team.core.synchronize bruges til at beskrive synkroniseringstilstanden. Den vigtigste klasse er SyncInfo, fordi det er den klasse, der rent faktisk definerer synkroniseringstilstanden. Den kan bruges som på følgende måde:

SyncInfo info = getSyncInfo(resource); // dette er en simuleret metode til at hente synkroniseringsoplysningerne for en ressource
int changekind = info.getKind();
if(info.getResourceComparator().isThreeWay()) {
if((changeKind & SyncInfo.DIRECTION_MASK) == SyncInfo.INCOMING) {
// gør noget
}
} else if(changeKind == SyncInfo.CHANGE) {
// gør noget andet
}

Klassen SyncInfo indeholder både tovejs- og trevejssammenligningsalgoritmer. En klasse skal levere ressourcerne og en klasse, der kan sammenligne ressourcerne (IResourceVariantComparator). Her er et eksempel på en variantsammenligner:

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(); // beregn synkroniseringsoplysningerne

Pakken indeholder også samlinger, der er specifikt designet til at indeholde SyncInfo, samt filtre, der kan anvendes på SyncInfo-forekomster.

Administrér synkroniseringstilstand

Som vist i eksemplet ovenfor får klasserne SyncInfo og IResourceVariantComparator adgang til ressourcernes synkroniseringstilstand. Men hvad vi ikke har set endnu er, hvordan tilstanden administreres. En abonnent giver adgang til synkroniseringstilstanden mellem ressourcerne i det lokale arbejdsområde og et sæt ressourcevarianter for disse ressourcer vha. enten en tovejs- eller en trevejssammenligning, afhængig af abonnentens egenskaber. En abonnent giver følgende muligheder:

API'erne definerer ikke, hvordan en abonnent oprettes. Det overlades til de specifikke implementeringer. CVS-plugin'en opretter f.eks. én abonnent, når der udføres en fletning, en anden ved sammenligning og endnu én ved synkronisering af det lokale arbejdsområde med den aktuelle gren.

Så lad os igen kigge på det første eksempel på brug af SyncInfo og se, hvordan en abonnent kan bruges til at få adgang til SyncInfo.

// Opret en filsystemabonnent, og angiv, at
// abonnenten skal synkroniseres med den leverede placering i filsystemet
Subscriber subscriber = new FileSystemSubscriber("c:\temp\repo");

// Giv abonnenten mulighed for at opfriske sin tilstand
subscriber.refresh(subscriber.roots(), IResource.DEPTH_INFINITE, monitor);

// Indsaml alle synkroniseringstilstande, og udskriv
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() + " findes ikke i arbejdsområde");
}
printSyncState(subscriber, children[i]);
}
}

Det vigtige at huske er, at abonnenten kender til ressourcer, der ikke findes i arbejdsområdet, og at ikke-eksisterende ressourcer kan returneres fra Subscriber#members() og SyncInfo#getLocal().

Vis synkroniseringstilstand i UI

Vi kunne bruge mere tid på at forklare, hvordan du administrerer synkroniseringstilstanden, men lad os i stedet se, hvordan du rent faktisk henter den tilstand, der vises for brugeren. En ISynchronizeParticipant er den brugergrænsefladekomponent, der viser synkroniseringstilstanden og giver brugeren mulighed for at påvirke tilstanden. Oversigten Synkronisér viser synkroniseringsdeltagerne, men det er også muligt at vise dem i dialogbokse og guider. For at give brugerne mulighed for at få se enhver type synkroniseringstilstand, også en tilstand, der ikke er baseret på SyncInfo og abonnenter, er en deltager en meget generisk komponent.

Der er også et udvidelsespunkt, som hedder org.eclipse.team.ui.synchronizeWizards, som kan bruges til at tilføje en guide til oprettelse af synkronisering. Dette vil anbringe guiden i den globale synkroniseringsfunktion og i oversigten Synkronisér, så brugerne nemt kan oprette en synkronisering af din type.

Men hvis du har implementeret en abonnent, kan du udnytte en konkret deltager, kaldet SubscriberParticipant, som leverer følgende funktionalitet:

Den bedste måde at forklare disse begreber på er at se dem anvendt i et enkelt eksempel. Gå til eksemplet på synkronisering af lokal historik for at se, hvordan alle disse dele kan bruges sammen. Eller gå til Udvidede indstillinger, hvis du vil vide, hvordan du anvender de mere avancerede API'er.