Eclipse inneholder programmeringsgrensesnitt (APIer) for styring og visning av synkroniseringstilstanden mellom arbeidsområderessurser og ressurser andre steder. Ressurser utenfor arbeidsområdet kalles varianter. Synkroniseringen er funksjonen for visning av endringer mellom ressurser på ulike steder, og gir brukeren mulighet til å påvirke synkroniseringstilstanden ved å utføre en handling. Programmeringsgrensesnitt for synkronisering er ortogonal til programmeringsgrensesnitt for RepositoryProvider og kan brukes uten en datalagerleverandør. Formålet med programmeringsgrensesnittet for synkronisering er å forenkle implementeringen av ulike måter å presentere ressursenes synkroniseringstilstanden på. Programmeringsgrensesnittet må derfor kunne utføre spørringer etter synkroniseringstilstanden for ressurser, men trenger ikke å påvirke tilstanden. Det er med andre ord opp til implementereren å påvirke tilstanden (selv om brukergrensesnittet inneholder bindinger for å legge til leverandørspesifikke menypunkter på menyene).
Før vi beskriver programmeringsgrensesnittet for synkronisering, er det nyttig å se på noe av terminologien og begrepene som brukes når vi diskuterer arbeidsområdesynkronisering.
Ressursvariant: En lokal ressurs som tilordnes en ressurs som eksisterer et annet sted, kan kalles en variant av denne ressursen. Ressursene er med andre ord vanligvis svært like, men kan likevel skille seg noe fra hverandre (enten på grunn av endringer i den lokale ressursen eller endringer i en ekstern kopi som er utført av andre brukere). Vi tar utgangspunkt i et lokalt arbeidsområde og refererer til den lokale kopien som ressursen og eksterne kopier som ressursvarianter.
Synkronisering: Vi refererer til synkronisering som en handling som viser brukeren forskjellen mellom ressursvarianter. Synkronisering påvirker ikke variantenes tilstand, men gir i stedet en visning som hjelper brukeren med å forstå forskjellene mellom ulike variantsett. Brukeren kan imidlertid vanligvis påvirke tilstanden i variantene (dette gjøres for eksempel ved å gi tillatelse til innlegging eller gå tilbake) ved synkronisering.
Toveis kontra treveis synkronisering: Det finnes to grunnleggende typer for fastsettelse av synkroniseringstilstander: toveis og treveis. En toveis sammenlikning tar bare hensyn til den lokale ressursen og en enkelt ressursvariant, som kalles den eksterne ressursvarianten. Denne sammenlikningstypen viser bare forskjeller mellom de to ressursene, men gir ingen informasjon om hvordan endringene er relatert til hverandre. Det er vanlig at koden som benyttes i datalagersystemer, støtter treveis sammenlikning for fastsettelse av synkroniseringstilstand. Denne sammenlikningen omfatter den lokale ressursen, en ekstern ressursvariant og en baseressursvariant. Baseressursvarianten representerer et felles overordnet objekt for lokale og eksterne ressurser. Dette gjør det mulig å vise hvilken retning endringen skal ta ved mer avanserte synkroniseringstilstander.
Tabell 1: Synkroniseringstilstander
Toveis Treveis Endret
Slettet
TilføydUtgående endring
Innkommende endring
Utgående sletting
Innkommende sletting
Utgående tillegg
Innkommende tillegg
Motstridende endring
Motstridende sletting
Motstridende tillegg
Klassene i org.eclipse.team.core.synchronize brukes til å beskrive synkroniseringstilstanden. Den viktigste klassen er SyncInfo fordi det er denne klassen som faktisk definerer synkroniseringstilstanden. Den kan brukes på følgende måte:
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-klassen har algoritmer for både toveis og treveis sammenlikning, og en klient må oppgi ressursene og en klasse som kan sammenlikne resursene (IResourceVariantComparator). Her er et eksempel på en variantsammenlikner:
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
Denne pakken består også av en samling som er utformet spesielt for å inneholde SyncInfo og filtre som kan brukes på SyncInfo-forekomster.
Som vi har sett i eksempelene ovenfor, gir klassene SyncInfo og IResourceVariantComparator tilgang til synkroniseringstilstanden for ressurser. Vi har imidlertid ikke sett på hvordan tilstanden styres. Subscriber gir tilgang til synkroniseringstilstanden mellom ressursene i det lokale arbeidsområdet og et sett med ressursvarianter for disse ressursene, enten ved hjelp av toveis eller treveis sammenlikning, avhengig av typen abonnent. En abonnent har følgende funksjonalitet:
Programmeringsgrensesnittene definerer ikke hvordan en abonnent opprettes, dette overlates til de spesifikke implementeringene. For eksempel opprettes en abonnent for plugin-modulen for CVS når det utføres en sammenslåing, en annen ved sammenlikning og enda en annen ved synkronisering av det lokale arbeidsområdet med den gjeldende grenen.
La oss gå tilbake til det første eksempelet på bruk av SyncInfo og se hvordan en abonnent kan brukes for å få tilgang til 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]);
}
}
Her er det viktig å huske på at abonnenten kjenner til ressurser som ikke finnes i arbeidsområdet og at ikke-eksisterende ressurser kan returneres fra Subscriber#members() og SyncInfo#getLocal().
Vi kunne brukt mer tid på å forklare styring av synkroniseringstilstanden, men la oss heller se hvordan tilstanden faktisk blir vist for brukeren. ISynchronizeParticipant er brukergrensesnittkomponenten som viser synkroniseringstilstanden, og tillater brukeren å påvirke tilstanden. Synkroniseringsvisningen viser synkroniseringsdeltakere, men disse kan også vises i dialogbokser og veivisere. En deltaker er en svært generisk komponent som støtter brukere i å vise en type synkroniseringstilstand, selv typer som ikke er basert på SyncInfo og Subscribers.
Det finnes også et utvidelsespunkt som heter org.eclipse.team.ui.synchronizeWizards. Dette utvidelsespunktet brukes for å legge til en veiviser for opprettelse av synkronisering. Veiviseren settes i en global synkroniseringshandling og i synkroniseringsvisningen slik at brukere uten problemer kan opprette en synkronisering av typen.
Hvis du har implementert en abonnent, kan du imidlertid dra fordel av en konkret deltaker som heter SubscriberParticipant , og som inneholder følgende funksjonalitet:
Det er enklest å forklare disse begrepene ved å se dem i bruk i et enkelt eksempel. I eksempelet med lokal historikksynkronisering
ser du hvordan alle disse delene kan brukes sammen. Hvis du vil ha tips
om hvordan du bruker de mer avanserte programmeringsgrensesnittene, leser du Utover det grunnleggende.