A munkaterület-mentési feldolgozás akkor aktiválódik, amikor a felhasználó leállítja a munkaterületet és más időpontokban rendszeres időközönként, amikor a platform leállítja. A bedolgozók résztvehetnek a munkaterület-mentési folyamatban, így a kritikus bedolgozóadatok mentésre kerülnek a lemezre, amikor a munkaterület állandó adatainak maradéka mentésre kerül.
A munkaterület-mentési folyamat a bedolgozó tevékenységei közötti módosítások nyomkövetéséhez is használható.
A munkaterület-mentésben részvétel érdekében hozzá kell adni egy mentésrésztvevőt a munkaterülethez. Ez jellemzően a bedolgozó indítási metódusa során történik. Ez szintén az, ahol bedolgozó utolsó leállításakor elmentett állapotok kiolvashatók.
Tekintsen meg egy egyszerű bedolgozót, amely bemutatja a mentési folyamatot.
package com.example.saveparticipant;
import org.eclipse.core.runtime.*;
import org.eclipse.core.resources.*;
import java.io.File;
import java.util.*;
public class MyPlugin extends Plugin {
private static MyPlugin plugin;
public MyPlugin(IPluginDescriptor descriptor) {
super(descriptor);
plugin = this;
}
public static MyPlugin getDefault() {
return plugin;
}
protected void readStateFrom(File target) {
}
public void startup() throws CoreException {
super.startup();
ISaveParticipant saveParticipant = new MyWorkspaceSaveParticipant();
ISavedState lastState =
ResourcesPlugin.getWorkspace().addSaveParticipant(this, saveParticipant);
if (lastState == null)
return;
IPath location = lastState.lookup(new Path("save"));
if (location == null)
return;
// a bedolgozópéldánynak a fontos állapotot a fájlból kell kiolvasni.
File f = getStateLocation().append(location).toFile();
readStateFrom(f);
}
protected void writeImportantState(File target) {
}
}
ISaveParticipant megadja a protokollt a munkaterület-mentési résztvevőhöz. A felület megvalósítói jellemzőt biztosíthatnak a mentési folyamat különböző állapotaihoz. Tekintse meg ezeket a részeket, és hogy a WorkspaceSaveParticipant hogyan valósítja meg ezeket a lépéseket.
public void prepareToSave(ISaveContext context) throws CoreException {
}
public void saving(ISaveContext context) throws CoreException {
switch (context.getKind()) {
case ISaveContext.FULL_SAVE:
MyPlugin myPluginInstance = MyPlugin.getDefault();
// bedolgozóállapot mentése
int saveNumber = context.getSaveNumber();
String saveFileName = "save-" + Integer.toString(saveNumber);
File f = myPluginInstance.getStateLocation().append(saveFileName).toFile();
// ha az írás meghiúsul, akkor kivétel történik, és nem frissítjük az elérési utat
myPluginInstance.writeImportantState(f);
context.map(new Path("save"), new Path(saveFileName));
context.needSaveNumber();
break;
case ISaveContext.PROJECT_SAVE:
// a mentés művelethez tartozó projekt lekérésre
IProject project = context.getProject();
// mentse el az információkat szükség eset
break;
case ISaveContext.SNAPSHOT:
// Ennek a műveletnek igazán gyorsnak kell lennie
// mivel a pillanatképeket a munkaterület
// gyakran lekérheti.
break;
}
}
Az ISaveContext a mentési művelettel kapcsolatos információkat írja le. Háromféle mentési művelet van: FULL_SAVE, SNAPSHOT és PROJECT_SAVE. A mentési résztvevőknek körültekintően kell végrehajtaniuk a kapott mentési események típusának megfelelő feldolgozást. A pillanatkép események például meglehetősen gyakran bekövetkezhetnek, és lehetővé teszik, hogy a bedolgozók elmentsék a kritikus állapotot. Az állapot mentése hosszú ideig tart, amely újra feldolgozható az összeomlás esetén, és ez lelassítja a platformot.
A mentési szám adatmentési fájlokat hoz létre, amelyek a sorszámokkal kerülnek elnevezésre (save-1, save-2, stb.) Minden mentési fájl egy logikai névre van leképezve (mentés), amely a mentési számtól független. A bedolgozóadatok beíródnak a megfelelő fájlba, és később az utolsó mentési művelet mentési számának ismerete nélkül lekérhetők. Ne feledje el, hogy ezt a technikát a saját bedolgozó indítási kódjában láttuk:
IPath location = lastState.lookup(new Path("save"));Miután elmentettük az adatokat és leképeztük a fájlnevet, meghívjuk a needSaveNumber függvényt annak jelzéséhez, hogy aktívan résztvettünk a munkaterület-mentésben, és hogy hozzá kívánunk rendelni egy számot a mentési tevékenységhez. A mentési számok segítségével adatfájlok hozhatók létre a fent látható módon.
public void doneSaving(ISaveContext context) {
MyPlugin myPluginInstance = MyPlugin.getDefault();
// törli a régi mentett állapotot, mivel ez többet nem szükséges
int previousSaveNumber = context.getPreviousSaveNumber();
String oldFileName = "save-" + Integer.toString(previousSaveNumber);
File f = myPluginInstance.getStateLocation().append(oldFileName).toFile();
f.delete();
}
Itt kitisztítjuk a mentési információkat a korábbi mentési műveletből. A getPreviousSaveNumber segítségével lekérhető a korábbi mentési művelethez rendelt mentési szám (nem az éppen befejezett). Ezen szám segítségével állítjuk összes a törölni kívánt fájl nevét. Ne feledje el, hogy nem használjuk a mentési állapot logikai fájlleképezést, mivel már elmentettük az aktuális mentési fájlszámot.
public void rollback(ISaveContext context) {
MyPlugin myPluginInstance = MyPlugin.getDefault();
// mivel a mentés művelet meghiúsult, törölje az éppen írt mentett állapotot
int saveNumber = context.getSaveNumber();
String saveFileName = "save-" + Integer.toString(saveNumber);
File f = myPluginInstance.getStateLocation().append(saveFileName).toFile();
f.delete();
}
Itt töröljük az éppen mentett állapotot. Ne feledje el, hogy az aktuális mentési számot használjuk az éppen mentett fájl nevének összeállításához. Nem kell aggódunk amiatt, hogy a fájlnevet leképeztük az ISaveContext elemre. A platform a mentési művelet meghiúsulásakor törli ezt a kontextust.
Ha a bedolgozó kivételt okoz a mentési életciklus során, akkor eltávolításra kerül az aktuális mentési műveletből és nem kerülnek lekérésre a fennmaradó életciklus-metódusok. Ha a mentés metódus során például hiba történik, akkor egy visszagörgetés vagy doneSaving üzenet érkezik.
Ha mentés résztvevőt ad a munkaterülethez, akkor ez visszaad egy ISavedState objektumot, amely leírja, hogy mely bedolgozó kerül mentésre az utolsó mentési művelet során (vagy üres, ha a bedolgozó korábban nem mentett el egy állapotot sem). Ez az objektum elérheti a korábbi mentésfájl információit (a mentési számmal és a fájltérképpel) vagy feldolgozhatja a bedolgozó aktiválásai között történt módosításokat.
Ha a fájltérkép lokálisan elnevezett fájlokat mentenek el a mentési számnak megfelelően, akkor ugyanez a térkép használható az adatok utolsó ismert mentési állapotból lekéréséhez.
ISaveParticipant saveParticipant = new MyWorkspaceSaveParticipant();
ISavedState lastState =
ResourcesPlugin.getWorkspace().addSaveParticipant(myPluginInstance, saveParticipant);
if (lastState != null) {
String saveFileName = lastState.lookup(new Path("save")).toString();
File f = myPluginInstance.getStateLocation().append(saveFileName).toFile();
// a bedolgozópéldánynak a fontos állapotot a fájlból kell kiolvasnia.
myPluginInstance.readStateFrom(f);
}
Ne feledje el, hogy tetszőleges számú erőforrás-módosítási esemény történhet a munkaterületen a bedolgozó aktiválása előtt. Ha tudni szeretné, hogy milyen módosítások történtek a bedolgozó utolsó leállítása óta, akkor ehhez használhatja a mentési mechanizmust abban az esetben is, ha más adatot nem kell menteni.
A mentés-résztvevőnek kérnie kell, hogy a platform helyette tartson fenn egy erőforrás-változásfájlt. Ez a mentési művelet részeként kerül végrehajtásra.
public void saving(ISaveContext context) throws CoreException {
// nincs olyan állapot, amelyet a bedolgozónak el kell mentenie,
// de egy erőforrás-változások fájl használatát igényli a következő aktiváláskor.
context.needDelta();
}
A bedolgozó indítása során a korábban elmentett állapot elérhető, és módosítási események jönnek létre az utolsó mentés óta történt módosításokhoz.
ISaveParticipant saveParticipant = new MyWorkspaceSaveParticipant();
ISavedState lastState =
ResourcesPlugin.getWorkspace().addSaveParticipant(myPluginInstance, saveParticipant);
if (lastState != null) {
lastState.processResourceChangeEvents(new MyResourceChangeReporter());
}
A biztosított osztálynak az Erőforrás-módosítások nyomkövetése részben leírt módon meg kell valósítani az IResourceChangeListener elemet. Az utolsó mentés óta történt módosítások a POST_AUTO_BUILD erőforrás-módosítási esemény részeként kerülnek jelentésre.
Megjegyzés: A jelzőmódosítások nem kerülnek jelentésre az ISavedState elemben tárolt módosításeseményekben. Fel kell tételezni, hogy a jelzők egy része az összes módosításra került az utolsó mentett állapot óta.