Sparprocessen för arbetsytor aktiveras när användaren har avslutat arbetsmiljön och annars tidvis genom plattformen. Insticksprogram kan medverka vid sparprocessen för arbetsytor så att kritiska insticksprogramdata sparas på disk i de fall när resten av arbetsytans återstående data sparas.
Sparprocessen för arbetsytor kan också användas för spårning av ändringar som inträffar mellan de tillfällen då insticksprogrammet aktiveras.
För medverkan vid sparåtgärder för arbetsytor måste du lägga till en medverkande vid sparåtgärder till arbetsytan. Det görs vanligtvis när insticksprogrammet startas. Det är också då du läser eventuell status som sparades när insticksprogrammet senast avslutades.
Här följer ett exempel på ett enkelt insticksprogram som visar sparprocessen.
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; // insticksprogramförekomsten ska läsa eventuell kritisk status från filen. File f = getStateLocation().append(location).toFile(); readStateFrom(f); } protected void writeImportantState(File target) { } }
ISaveParticipant definierar protokollet för en medverkande vid sparåtgärder för arbetsytor. Den som implementerar det här gränssnittet kan ange beteende för olika stadier av sparprocessen. Låt oss se på stadierna och hur klassen WorkspaceSaveParticipant implementerar vart och ett av stegen.
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(); // spara insticksprogrammets status int saveNumber = context.getSaveNumber(); String saveFileName = "save-" + Integer.toString(saveNumber); File f = myPluginInstance.getStateLocation().append(saveFileName).toFile(); // om vi inte skriver returneras ett undantag och sökvägen uppdateras inte myPluginInstance.writeImportantState(f); context.map(new Path("save"), new Path(saveFileName)); context.needSaveNumber(); break; case ISaveContext.PROJECT_SAVE: // hämta det projekt som hör till sparåtgärden IProject project = context.getProject(); // spara informationen om det behövs break; case ISaveContext.SNAPSHOT: // Den här åtgärden måste vara snabb eftersom // statusbilder kan begäras ofta av // arbetsytan. break; } }
I ISaveContext beskrivs informationen om sparåtgärden. Det finns tre typer av sparåtgärder FULL_SAVE, SNAPSHOT och PROJECT_SAVE. Medverkande vid sparåtgärder måste vara noga med att utföra den bearbetning som är lämplig för den typ av sparhändelse som de har tagit emot. Statusbildhändelser kan till exempel inträffa ganska ofta, och de är avsedda att låta insticksprogram spara deras kritiska status. Om det tar lång tid att spara den status som kan beräknas om i händelse av krasch blir plattformen långsammare.
Ett sparnummer används till att skapa datasparfiler som namnges i nummerordning (save-1, save-2 osv.) Varje sparfil avbildas till ett logiskt filnamn (save) som inte är beroende av sparnumret. Insticksprogramdata skrivs till motsvarande fil och kan hämtas senare utan det specifika sparnumret för den senast genomförda sparåtgärden. Den här metoden såg vi i vår startkod för insticksprogrammet:
IPath location = lastState.lookup(new Path("save"));När vi har sparat våra data och avbildat filnamnet anropar vi needSaveNumber och visar på så sätt att vi har medverkat aktivt i sparåtgärden för arbetsytan och vill tilldela ett nummer för sparåtgärden. Sparnumren kan användas till att skapa datafiler som ovan.
public void doneSaving(ISaveContext context) { MyPlugin myPluginInstance = MyPlugin.getDefault(); // ta bort gammal sparad status eftersom den inte behövs längre int previousSaveNumber = context.getPreviousSaveNumber(); String oldFileName = "save-" + Integer.toString(previousSaveNumber); File f = myPluginInstance.getStateLocation().append(oldFileName).toFile(); f.delete(); }
Här kan vi rensa sparinformationen från tidigare sparåtgärd. Med getPreviousSaveNumber kan vi hämta det sparnummer som tilldelades i tidigare sparåtgärd (inte den vi nyss slutförde). Vi använder det här numret till att konstruera namnet på den fil vi behöver ta bort. Lägg märke till att vi inte använder sparstatus logiska filavbildning eftersom vi redan har avbildat det aktuella sparfilsnumret.
public void rollback(ISaveContext context) { MyPlugin myPluginInstance = MyPlugin.getDefault(); // eftersom sparåtgärden misslyckades måste du ta bort den sparade status vi nyss skrev int saveNumber = context.getSaveNumber(); String saveFileName = "save-" + Integer.toString(saveNumber); File f = myPluginInstance.getStateLocation().append(saveFileName).toFile(); f.delete(); }
Här tar vi bort den status vi nyss sparade. Lägg märke till att använder det aktuella sparnumret till att konstruera filnamnet på den nyss sparade filen. Vi behöver inte bekymra oss om att vi avbildade filnamnet i ISaveContext. Sammanhanget tillämpas inte på plattformen när en sparåtgärd misslyckas.
Om insticksprogrammet returnerar ett undantag någon gång under sparandets livscykel kommer det att tas bort från den aktuella sparåtgärden och hämtar inte någon av de återstående livscykelmetoderna. Om till exempel metoden saving misslyckas får du inget rollback- eller doneSaving-meddelande.
När du lägger till en medverkande vid sparåtgärder för arbetsytan returneras ett ISavedState-objekt som beskriver vad insticksprogrammet sparade vid den senaste sparåtgärden (eller null om insticksprogrammet inte har sparat någon status tidigare). Det här objektet kan användas till att accessa information från den tidigare sparade filen (med hjälp av sparnumret och filavbildningen) eller till att bearbeta ändringar som har inträffat mellan de tillfällen ett insticksprogram har aktiverats.
Om en filavbildning användes till att spara logiskt namngivna filer efter sparnummer kan samma avbildning användas till att hämta data från senast kända sparstatus.
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(); // insticksprogramförekomsten ska läsa eventuell kritisk status från filen. myPluginInstance.readStateFrom(f); }
Tänk på att det kan inträffa hur många resursändringshändelser som helst på arbetsytan innan insticksprogrammet ens har aktiverats. Om du vill veta vilka ändringar som har inträffat sedan insticksprogrammet avaktiverades kan du använda sparmekanismen till det, även om du inte behöver spara några andra data.
De medverkande vid sparåtgärder måste begära att plattformen behåller ett resursdeltavärde för den medverkandes räkning. Det görs som en del av sparåtgärden.
public void saving(ISaveContext context) throws CoreException { // ingen status ska sparas av insticksprogrammet, men begär ett // resursdeltavärde som ska användas vid nästa aktivering. context.needDelta(); }
När insticksprogrammet startas går det att accessa tidigare sparad status, och ändringshändelser skapas för alla ändringar som har inträffat sedan den senaste sparåtgärden.
ISaveParticipant saveParticipant = new MyWorkspaceSaveParticipant(); ISavedState lastState = ResourcesPlugin.getWorkspace().addSaveParticipant(myPluginInstance, saveParticipant); if (lastState != null) { lastState.processResourceChangeEvents(new MyResourceChangeReporter()); }
Den tillhandahållna klassen måste implementera IResourceChangeListener, som beskrivs i Spåra resursändringar. Ändringarna efter den senaste sparåtgärden rapporteras som en del av resursändringshändelsen POST_AUTO_BUILD.
Obs! Markeringsändringar rapporteras inte i de ändringshändelser som lagras i en ISavedState. Du måste förutsätta att vissa eller alla markeringar har ändrats sedan senaste status sparades.