Helyi előzmény példa

A Szinkronizálás alkalmazás programozási felületek megismerésének legjobb módja egy egyszerű példa megvalósítása, amely valójában működik. Ebben a példában a Szinkronizálás nézetben létrehozunk egy oldalt, amely a munkaterület fájljainak legfrissebb előzmény állapotát jeleníti meg. A helyi előzmény szinkronizálás automatikusan frissítésre kerül a munkaterület módosításakor, és böngészéshez, összefésüléshez valamint módosításhoz megnyitható egy összehasonlító szerkesztő. Egy egyéni díszítményt is hozzáadunk a helyi előzmény elem legfrissebb időbélyegének megjelenítése érdekében, és egy tevékenységet a munkaterületfájlok legutóbbi mentett helyi előzmény állapotra visszaállításához. Ez kitűnő példa, mivel már rendelkezünk egy erőforrás-változó tárolóval, és ezt nem kell kezelnünk.

A példa hátralevő részében egy futó példát használunk. A forráskód nagy része - de nem az egész - megjelenítésre kerül ezen az oldalon. A teljes forráskód org.eclipse.team.examples.filesystem bedolgozó helyi előzmény csomagjában található. A projektet ki lehet iktatni a CVS lerakatból, és használható hivatkozásként az ismertető olvasása közben. Jogkizárási nyilatkozat: A példabedolgozókban lévő forráskód változhat. A példában használtnak megfelelő másolat megszerzéséhez a 3.0 verzióhoz tartozó címke (általában R3_0) vagy a June 28, 2004 dátum címke segítségével ellenőrizheti a projektet.

helyi előzmény áttekintése

Ez a képernyőfotó a Szinkronizálás nézetben megjeleníti a helyi előzményszinkronizációt. Ennek segítségével böngészheti a helyi erőforrás és az előzményben lévő legfrissebb állapot közötti különbséget. Egy egyéni díszítménnyel rendelkezik a helyi előzmény bejegyzéshez rendelt időbélyeg megjelenítéséhez és egy egyéni tevékenységgel a fájl helyi előzményben lévő tartalomra visszaállításához. A szabványos Szinkronizálási nézet megjelenítést is használja a rendszer, amely problémafeljegyzéseket, tömörített mappaelrendezést és navigációs gombokat biztosít.

A helyi előzmény változóinak megadása

Az első lépés egy változó megadása a helyi előzményből származó elemek ábrázolásához. Ez lehetővé teszi a szinkronizálás alkalmazás programozási felületek számára, hogy a helyi előzményből hozzáférjenek a tartalomhoz, így ez összehasonlítható az aktuális tartalommal és megjeleníthető a felhasználó számára.

public class LocalHistoryVariant implements IResourceVariant {
private final IFileState state;

public LocalHistoryVariant(IFileState state) {
this.state = state;
}

public String getName() {
return state.getName();
}

public boolean isContainer() {
return false;
}

public IStorage getStorage(IProgressMonitor monitor) throws TeamException {
return state;
}

public String getContentIdentifier() {
return Long.toString(state.getModificationTime());
}

public byte[] asBytes() {
return null;
}
}

Mivel az IFileState felület már hozzáférést biztosít a fájl tartalmához a helyi előzményből (például megvalósítja az IStorage felületet), ez egyszerű volt. Változó létrehozásakor általában meg kell adni a tartalom, a tartalomazonosító - amely megjeleníti ezt a változót a felhasználó számára - és a név elérésének módját. Az asBytes() metódus csak akkor szükséges, ha a változó a munkamenetek között állandó.

Következőnek hozzunk létre egy változóösszehasonlítót, amelynek segítségével a SyncInfo számítás összehasonlíthatja a helyi erőforrásokat a változókkal. Ez egyszerű, mivel a helyi előzmény állapot létezése arra utal, hogy a helyi előzmény állapot tartalma különbözik a fájl aktuális tartalmától. Ez azért van, mert a helyi előzmény specifikációja jelzi, hogy nem hoz létre helyi előzmény állapotot, ha a fájl nem változott.

public class LocalHistoryVariantComparator implements IResourceVariantComparator {
public boolean compare(IResource local, IResourceVariant remote) {
return false;
}

public boolean compare(IResourceVariant base, IResourceVariant remote) {
return false;
}

public boolean isThreeWay() {
return false;
}
}

Mivel tudjuk, hogy a helyi előzmény állapotának megléte azt jelzi, hogy a helyitől különbözik, így a fájl helyi előzmény állapottal összehasonlításakor egyszerűen false érték adható vissza. A helyi előzményszinkronizáció kétlépéses, ezért nem rendelkezünk hozzáféréssel az alap erőforráshoz, így a két erőforrás-változó összehasonlításának metódusát nem használja a rendszer.

Ne feledje el, hogy a szinkronizálási számítás nem hívja meg az összehasonlító összehasonlítás metódusát, ha a változó nem létezik (például null). Ez csak akkor kerül meghívásra, ha minden elem létezik. A példánkban ez helyi előzménnyel nem rendelkező fájlok és az mappák (amely sosem rendelkezik helyi előzménnyel) esetén lehetséges. Ennek kezeléséhez saját SyncInfo alosztályt kell megadni ezen esetek kiszámított szinkronizációs állapotának módosításához.

public class LocalHistorySyncInfo extends SyncInfo {
  public LocalHistorySyncInfo(IResource local, IResourceVariant remote, IResourceVariantComparator comparator) {
    super(local, null, remote, comparator);
  }

  protected int calculateKind() throws TeamException {
    if (getRemote() == null)
      return IN_SYNC;
    else
      return super.calculateKind();
  }
}

Újradefiniáltuk a konstruktort, hogy mindig biztosítson egy alapot, amely null (mivel csak kétlépéses összehasonlítást használunk), és módosítottuk a szinkronizálási számítást, hogy IN_SYNC értéket adjon vissza, ha nincs távoli fájl (mivel csak azokkal az esetekkel foglalkozunk, amelyben egy helyi fájl és egy fájlállapot található a helyi előzményben).

Előfizető létrehozása

Létrehozunk egy előfizetőt, amely hozzáférést biztosít a helyi előzményben lévő erőforrás-változókhoz. Mivel a helyi előzmény a munkaterület tetszőleges fájljához elmenthető, a helyi előzmény ellenőriz minden erőforrást, és a gyökerek a munkaterület projektjei lesznek. Nincs szükség az előfizető frissítésének képességére, mivel a helyi előzmény csak akkor változik, amikor a helyi fájlmódosítások tartalma. Erőforrás-változás bekövetkezésekor frissíthetjük az állapotot. Ez két érdekes metódust hagy a helyi előzményelőfizetőre: SyncInfo lekérése és a munkaterület átvizsgálása.

public SyncInfo getSyncInfo(IResource resource) throws TeamException {
  try {
    IResourceVariant variant = null;
    if(resource.getType() == IResource.FILE) {
      IFile file = (IFile)resource;
      IFileState[] states = file.getHistory(null);
      if(states.length > 0) {
        // csak az utolsó állapot
        variant = new LocalHistoryVariant(states[0]);
      } 
    }
    SyncInfo info = new LocalHistorySyncInfo(resource, variant, comparator);
    info.init();
    return info;
  } catch (CoreException e) {
    throw TeamException.asTeamException(e);
  }
}

Az előfizető egy új SyncInfo állapotot ad vissza, amely tartalmazza a helyi előzményben lévő fájl legfrissebb állapotát. A SyncInfo egy helyi előzményváltozóval kerül létrehozásra a távoli elemhez. A helyi előzménnyel nem rendelkező projektekhez, mappákhoz és fájlokhoz nem áll rendelkezésre távoli erőforrás-változó, melynek eredményeképp a calculateKind metódus hatására az erőforrás a LocalHistorySyncInfo elemben in-sync állapotba kerül.

A helyi előzmény előfizetőben lévő kód további része a members metódus megvalósítása:

public IResource[] members(IResource resource) throws TeamException {
  try {
    if(resource.getType() == IResource.FILE)
      return new IResource[0];
    IContainer container = (IContainer)resource;
    List existingChildren = new ArrayList(Arrays.asList(container.members()));
    existingChildren.addAll(
      Arrays.asList(container.findDeletedMembersWithHistory(IResource.DEPTH_INFINITE, null)));
    return (IResource[]) existingChildren.toArray(new IResource[existingChildren.size()]);
  } catch (CoreException e) {
    throw TeamException.asTeamException(e);
  }
}

A metódus érdekes részlete, hogy egy nem létező leszármazottat ad vissza, ha egy törölt erőforrás helyi előzménnyel rendelkezik. Ez lehetővé teszi, hogy az előfizető SyncInfot adjon vissza azon elemekhez, amelyek csak egy helyi lerakatban léteznek, a munkaterületen pedig már nem.

Helyi előzmény szinkronizálási résztvevő hozzáadása

Eddig létrehoztuk az osztályokat, amelyek a helyi előzményben lévő elemek számára hozzáférést biztosítanak a SyncInfohoz. Következőnek létrehozzuk az UI elemeket, amelyek segítségével a Szinkronizálási nézetben létrehozható egy oldal, amely megjeleníti a helyi előzményben lévő elemek legfrissebb előzmény állapotát. Ha rendelkezik egy előfizetővel, akkor ennek Szinkronizálási nézethez adása egyszerű. Kezdjük a szinkronizálási résztvevő kiterjesztési pont hozzáadásával:

<extension
       point="org.eclipse.team.ui.synchronizeParticipants">
<participant
persistent="false"
icon="synced.png"
class="org.eclipse.team.synchronize.example.LocalHistoryParticipant"
name="A helyi előzményből származó legfrissebb"
id="org.eclipse.team.synchronize.example"/>
</extension>

Következőnek meg kell valósítanunk a LocalHistoryParticipant elemet. Ez létrehozza a SubscriberParticipant alosztályait, amely biztosítja az összes alapértelmezett viselkedést a SyncInfo gyűjtéséhez az előfizetőből, és a szinkronizálási állapotok frissítéséhez a munkaterület módosításakor. Ezen felül felveszünk egy tevékenységet a munkaterület-erőforrások helyi előzményben lévő legutóbbi állapotára visszaállításához.

Először megtekintjük, hogy egy egyéni tevékenység hogyan adható hozzá a résztvevőhöz.

public static final String CONTEXT_MENU_CONTRIBUTION_GROUP = "context_group_1"; //$NON-NLS-1$
  
private class LocalHistoryActionContribution extends SynchronizePageActionGroup {
  public void initialize(ISynchronizePageConfiguration configuration) {
    super.initialize(configuration);
    appendToGroup(
      ISynchronizePageConfiguration.P_CONTEXT_MENU, CONTEXT_MENU_CONTRIBUTION_GROUP, 
      new SynchronizeModelAction("Revert to latest in local history", configuration) { //$NON-NLS-1$
        protected SynchronizeModelOperation getSubscriberOperation(ISynchronizePageConfiguration configuration, IDiffElement[] elements) {
          return new RevertAllOperation(configuration, elements);
        }
      });
  }
}

Az alábbiakban felveszünk egy adott SynchronizeMoidelAction tevékenységet és egy műveletet. Ez biztosítja a háttérben futtatás képességét, és megjeleníti a használt csomópontok foglalt állapotát. A tevékenység visszaállítja a munkaterület összes erőforrását a helyi előzményben lévő legfrissebb állapotra. A tevékenység egy tevékenységkiegészítés résztvevők konfigurációhoz adásával biztosítható. A konfiguráció leírja a résztvevőoldal összeépítéséhez használt tulajdonságokat, amelyek megjelenítik az aktuális szinkronizálási felhasználói felületet.

A résztvevő az alábbi módon inicializálja a konfigurációt a helyi előzmény tevékenységcsoport előugró menühöz adása érdekében:

protected void initializeConfiguration(ISynchronizePageConfiguration configuration) {
super.initializeConfiguration(configuration);
configuration.addMenuGroup(
ISynchronizePageConfiguration.P_CONTEXT_MENU,
CONTEXT_MENU_CONTRIBUTION_GROUP);
configuration.addActionContribution(new LocalHistoryActionContribution()); configuration.addLabelDecorator(new LocalHistoryDecorator());
}

Most tekintsük meg, hogy hogyan biztosítható egyéni dekoráció. A fenti metódus utolsó sora az oldal konfigurációjához bejegyzi az alábbi díszítményt.

public class LocalHistoryDecorator extends LabelProvider implements ILabelDecorator {
public String decorateText(String text, Object element) {
if(element instanceof ISynchronizeModelElement) {
ISynchronizeModelElement node = (ISynchronizeModelElement)element;
if(node instanceof IAdaptable) {
SyncInfo info = (SyncInfo)((IAdaptable)node).getAdapter(SyncInfo.class);
if(info != null) {
LocalHistoryVariant state = (LocalHistoryVariant)info.getRemote();
return text+ " ("+ state.getContentIdentifier() + ")";
}
}
}
return text;
}

public Image decorateImage(Image image, Object element) {
return null;
}
}

A díszítmény kibotja az erőforrást a modellelemből, amely a szinkronizálás nézetben jelenik meg, és a nézetben megjelenő szövegcímkéhez hozzáfűzi a helyi előzmény erőforrás-változó tartalomazonosítóját.

Az utolsó teendő egy olyan varázsló biztosítása, amely létrehozza a helyi előzmény résztvevőt. A Csapatszinkronizálási perspektíva egy globális szinkronizálási tevékenységet ad meg, amelynek segítségével a felhasználók gyorsan létrehozhatnak egy szinkronizálást. Ezen felül a Szinkronizálási eszköztárról létrehozhatók szinkronizálások. Ennek elkezdéséhez hozza létre a synchronizeWizards kiterjesztési pontot:

<extension
point="org.eclipse.team.ui.synchronizeWizards">
<wizard
class="org.eclipse.team.synchronize.example.LocalHistorySynchronizeWizard"
icon="synced.png"
description="Létrehoz egy szinkronizálást a munkaterületen lévő összes erőforrás helyi előzmény állapottal szemben"
name="A helyi előzmény szinkronizálásból származó legfrissebb"
id="ExampleSynchronizeSupport.wizard1"/>
</extension>

Ez hozzáadja a varázslót a listához, és a varázslók finish() metódusában egyszerűen létrehozzuk a résztvevőt, és hozzáadjuk a szinkronizáláskezelőhöz.

LocalHistoryPartipant participant = new LocalHistoryPartipant();
ISynchronizeManager manager = TeamUI.getSynchronizeManager();
manager.addSynchronizeParticipants(new ISynchronizeParticipant[] {participant});
ISynchronizeView view = manager.showSynchronizeViewInActivePage();
view.display(participant);

Összegzés

Ez egy egyszerű példa a szinkronizálás alkalmazás programozási felületek használatára. A példa egyszerű érthetősége érdekében bizonyos részleteket elrejtettünk. Válaszképes és pontos szinkronizálási támogatás írása nem egyszerű feladat. A legbonyolultabb rész a szinkronizálási információk kezelés és a szinkronizálási állapot változásának jelzése. A felhasználói felület egyszerű, amennyiben a SubscriberParticipants elemhez rendelt megfelelő, és az előfizető megvalósítása már készen van. További példákért tekintse meg az org.eclipse.team.example.filesystem bedolgozót és böngésszen az előfizető és ISynchronizeParticipant munkaterületének alosztályai között.

A következő rész néhány osztályt és felületet ír le, amelyek segítségével a nulláról írhat egy egyelőfizetőt a munkaterület-munkamenetek közötti szinkronizálási állapotokok ideiglenes tárolásának módját is beleértve.