U hebt gezien hoe resourcewijzigingen in een runnable als batch worden verwerkt (Resourcewijzigingen als batch verwerken). Er is echter een andere kant van de medaille. Hoe houdt u alle wijzigingen van het werkgebied bij die worden doorgevoerd als uw plugin actief is? U kunt een IResourceChangeListener voor het werkgebied registreren. Uw listener ontvangt een bericht over de wijzigingen via een IResourceChangeEvent-object dat de wijzigingen beschrijft.
Om te beginnen moet u een resourcewijzigingslistener voor het werkgebied registreren.
IResourceChangeListener listener = new MyResourceChangeReporter(); ResourcesPlugin.getWorkspace().addResourceChangeListener( listener, IResourceChangeEvent.POST_CHANGE);
Uw listener wordt op de hoogte gesteld als er wijzigingen in de werkgebiedresources zijn aangebracht. Resource-API-methoden die resources wijzigen, initiëren deze events als onderdeel van hun gedocumenteerde gedrag. Het methodecommentaar voor een resource-API-methode vermeldt expliciet of deze een resourcewijzigingsevent initieert. Het volgende staat bijvoorbeeld in het IFile.setContents()-commentaar:
Deze methode wijzigt resources; deze wijzigingen worden gemeld in een resourcewijzigingsevent, inclusief de vermelding dat de inhoud van het bestand is gewijzigd.
Meestal worden deze events geïnitieerd door methoden die resources maken, wissen of wijzigen. Methoden die resources lezen, maar er niet naar schrijven, initiëren deze events meestal niet.
Een resourcewijzigingsevent beschrijft de specificaties van een wijziging (of set wijzigingen) die in het werkgebied is opgetreden. De event bevat een resourcedelta die het netto-effect van de wijziging beschrijft. Als u bijvoorbeeld een resource toevoegt en deze later weer verwijdert in één batchverwerking, wordt de resource niet in de delta vermeld.
De resourcedelta heeft een boomstructuur waarvan de hoofdmap zich in de hoofdmap van het werkgebied bevindt. De resourcedeltastructuur bevat de volgende soorten wijzigingen:
Om een resourcedeltastructuur te onderzoeken, kunt u de interface IResourceDeltaVisitor implementeren of de structuur expliciet onderzoeken met IResource.getAffectedChildren. Resourcedeltabezoekers implementeren een visit-methode die wordt aangeroepen door de resourcedelta bij het opsommen van de wijzigingen in de boomstructuur.
Opmerking: Wijzigingen in de sessieresource-eigenschappen of permanente resource-eigenschappen worden niet geïdentificeerd in de resourcedelta.
Resourcewijzigingsevents worden verzonden als een wijziging (of een batch wijzigingen) wordt aangebracht in het werkgebied. Verder worden resourcewijzigingsevents verzonden bij bepaalde specifieke bewerkingen van het werkgebied. In de volgende tabel ziet u de verschillende typen resourcewijzigingsevents en wanneer ze worden gemeld.
Eventtype |
Beschrijving |
---|---|
PRE_CLOSE |
Stelt de listeners op de hoogte dat een project op het punt staat gesloten te worden. Deze event kan worden gebruikt om noodzakelijke informatie vóór het sluiten van een project op te halen en op te slaan vanuit het geheugen (d.w.z. sessie-eigenschappen). (Als een project wordt gesloten, wordt de informatie uit het geheugen verwijderd). Het werkgebied wordt tijdens de event vergrendeld (er kunnen geen resources worden bijgewerkt). De event bevat het project dat wordt gesloten. |
PRE_DELETE |
Stelt de listeners op de hoogte dat een project op het punt staat gewist te worden. Deze event wordt gebruikt om opschoningsacties uit te voeren, bijvoorbeeld het verwijderen uit de plugindirectory van opgeslagen items die aan het project zijn gerelateerd. Het werkgebied wordt tijdens de event vergrendeld (er kunnen geen resources worden bijgewerkt). De event bevat het project dat wordt gewist. |
PRE_AUTOBUILD |
Waarschuwt de listeners dat er een automatische build wordt uitgevoerd. Deze event wordt gedistribueerd als het platform vaststelt dat er een automatische build moet worden gemaakt, ongeacht of Automatisch bouwen daadwerkelijk is ingeschakeld. Het werkgebied wordt tijdens deze event niet vergrendeld (resources kunnen worden bijgewerkt). De event bevat een resourcedelta met de wijzigingen die zijn opgetreden sinds de laatste POST_CHANGE-event. |
POST_AUTOBUILD |
Stelt de listeners op de hoogte nadat er een automatische build is uitgevoerd. Deze event wordt gedistribueerd nadat het platform een automatische build zou hebben uitgevoerd, ongeacht of Automatisch bouwen daadwerkelijk is ingeschakeld. Het werkgebied wordt tijdens deze event niet vergrendeld (resources kunnen worden bijgewerkt). De event bevat een resourcedelta met de wijzigingen die zijn opgetreden sinds de laatste POST_CHANGE-event. |
POST_CHANGE |
Beschrijft een set wijzigingen die in het werkgebied zijn opgetreden sinds de laatste POST_CHANGE-event. Ontstaat nadat een resourcewijzigings-API individueel is gebruikt of in een batch werkgebiedwijzigingen. Ook geïnitieerd na het voltooien van een PRE_AUTOBUILD- of POST_AUTOBUILD-melding. De event bevat een resourcedelta met de nettowijzigingen die zijn opgetreden sinds de laatste POST_CHANGE-event. Het werkgebied wordt tijdens de event vergrendeld (er kunnen geen resources worden bijgewerkt). |
Hieronder ziet u een voorbeeld waarin een consolegebaseerde resourcewijzigingslistener wordt geïmplementeerd. Een resourcewijzigingslistener wordt geregistreerd voor specifieke eventtypen en informatie over deze events wordt naar de console geschreven:
IResourceChangeListener listener = new MyResourceChangeReporter(); ResourcesPlugin.getWorkspace().addResourceChangeListener(listener, IResourceChangeEvent.PRE_CLOSE | IResourceChangeEvent.PRE_DELETE | IResourceChangeEvent.PRE_AUTO_BUILD | IResourceChangeEvent.POST_AUTO_BUILD | IResourceChangeEvent.POST_CHANGE);
De listener controleert alle eventtypen en meldt gewijzigde informatie over de resource en de soorten wijzigingen. Dit voorbeeld betreft een algemene listener die alle typen resource-events afhandelt, maar doorgaans registreert een listener slechts één type event.
De implementatie voor POST_CHANGE gebruikt een andere klasse. Deze kan worden gebruikt voor het bekijken van wijzigingen in de resourcedelta.
import org.eclipse.resources.*; import org.eclipse.runtime.*; public class MyResourceChangeReporter implements IResourceChangeListener { public void resourceChanged(IResourceChangeEvent event) { IResource res = event.getResource(); switch (event.getType()) { case IResourceChangeEvent.PRE_CLOSE: System.out.print("Project "); System.out.print(res.getFullPath()); System.out.println(" wordt gesloten."); break; case IResourceChangeEvent.PRE_DELETE: System.out.print("Project "); System.out.print(res.getFullPath()); System.out.println(" wordt gewist."); break; case IResourceChangeEvent.POST_CHANGE: System.out.println("Resources zijn gewijzigd."); event.getDelta().accept(new DeltaPrinter()); break; case IResourceChangeEvent.PRE_AUTO_BUILD: System.out.println("Automatisch bouwen wordt uitgevoerd."); event.getDelta().accept(new DeltaPrinter()); break; case IResourceChangeEvent.POST_AUTO_BUILD: System.out.println("Automatisch bouwen voltooid."); event.getDelta().accept(new DeltaPrinter()); break; } } }
De klasse DeltaPrinter implementeert de interface IResourceDeltaVisitor voor het onderzoeken van de resourcedelta. De methode visit() wordt aangeroepen voor iedere resourcewijziging in de resourcedelta. De bezoeker gebruikt een retourwaarde om aan te geven of delta's van onderliggende resources bezocht moeten worden.
class DeltaPrinter implements IResourceDeltaVisitor { public boolean visit(IResourceDelta delta) { IResource res = delta.getResource(); switch (delta.getKind()) { case IResourceDelta.ADDED: System.out.print("Resource "); System.out.print(res.getFullPath()); System.out.println(" is toegevoegd."); break; case IResourceDelta.REMOVED: System.out.print("Resource "); System.out.print(res.getFullPath()); System.out.println(" is gewist."); break; case IResourceDelta.CHANGED: System.out.print("Resource "); System.out.print(res.getFullPath()); System.out.println(" is gewijzigd."); break; } return true; // onderliggende items doorlopen } }
Verdere informatie is beschikbaar in de verstrekte resourcedelta. In het volgende codefragment ziet u hoe de case IResourceDelta.CHANGED geïmplementeerd kan worden om de resourcewijzigingen verder te beschrijven.
... case IResourceDelta.CHANGED: System.out.print("Resource "); System.out.print(delta.getFullPath()); System.out.println(" is gewijzigd."); int flags = delta.getFlags(); if ((flags & IResourceDelta.CONTENT) != 0) { System.out.println("--> Contentwijziging"); } if ((flags & IResourceDelta.REPLACED) != 0) { System.out.println("--> Content vervangen"); } if ((flags & IResourceDelta.MARKERS) != 0) { System.out.println("--> Merktekenwijziging"); IMarkerDelta[] markers = delta.getMarkerDeltas(); // deze delta's controleren als merktekens belangrijk zijn } break; ...
Voor een volledige beschrijving van resourcedelta's, bezoekers en merktekendelta's raadpleegt u de API-specificatie voor IResourceDelta, IResourceDeltaVisitor en IMarkerDelta.
Opmerking: Resourcewijzigingslisteners zijn nuttig voor het traceren van wijzigingen in resources terwijl uw plugin actief is. Als uw plugin een resourcewijzigingslistener registreert tijdens het opstarten van de code, is het mogelijk dat veel resourcewijzigingsevents zijn geïnitieerd voordat de de plugin is geactiveerd. De resourcedelta in de eerste resourcewijzigingsevent die door de plugin wordt ontvangen, bevat niet alle wijzigingen die sinds de laatste activering van de plugin zijn gemaakt. Als u de wijzingen moet traceren die zijn gemaakt tussen twee activeringen van de plugin, moet u de ondersteuning voor werkgebiedopslag gebruiken. Deze wordt beschreven in Deelnemen aan werkgebiedopslag.
Opmerking: Sommige resourcewijzigingsevents worden geïnitieerd tijdens bewerkingen in een achtergrondthread. Resourcewijzigingslisteners moeten een beveiliging tegen threadactiviteiten hebben. Zie Problemen met threads voor een bespreking van threadbeveiliging in de gebruikersinterface.