Das Ressourcen-Plug-in enthält einen Ereignismechanismus, der Hinweise zu wichtigen Teilen der Änderungen ausgibt, die an Ressourcen vorgenommen wurden. Wenn Sie die Änderungen an der Ressourcenbaumstruktur während der Ausführung des Plug-ins protokollieren wollen, können Sie eine Schnittstelle IResourceChangeListener für den Arbeitsbereich registrieren. Die Listener-Funktion wird von den Änderungen über ein Objekt IResourceChangeEvent benachrichtigt, das die Änderungen beschreibt.
Damit Änderungen an Ressourcen protokolliert werden können, müssen Sie für den Arbeitsbereich eine Listener-Funktion für Ressourcenänderungen registrieren.
IResourceChangeListener listener = new MyResourceChangeReporter(); ResourcesPlugin.getWorkspace().addResourceChangeListener( listener, IResourceChangeEvent.POST_CHANGE);
Die Listener-Funktion wird benachrichtigt, nachdem die Ressourcen im Arbeitsbereich geändert wurden. Methoden der Ressourcen-API, die Ressourcen ändern, lösen solche Ereignisse im Rahmen ihres dokumentierten Verhaltens aus. Der Methodenkommentar für eine Methode der Ressourcen-API gibt explizit an, ob ein Ereignis für eine Ressourcenänderung ausgelöst wird oder nicht. Die folgende Angabe ist beispielsweise im Kommentar IFile.setContents() enthalten:
This method changes resources; these changes will be reported in a subsequent resource change event, including an indication that this file's content have been changed.
Methoden, die eine Ressource erstellen, löschen oder ändern, lösen normalerweise diese Ereignisse aus. Methoden, die Ressourcen lesen, aber nicht in sie schreiben, lösen solche Ereignisse in der Regel nicht aus.
Wenn Sie eine Reihe von Ressourcen gleichzeitig ändern müssen, können Sie die API-Aufrufe zur Ressourcenänderung im Stapelbetrieb ausführen lassen, damit für die gesamte Gruppe der Änderungen lediglich ein Ereignis für Ressourcenänderungen gesendet wird. Mit Hilfe der Methode IWorkspace.run(runnable, monitor) können die Operationen als Stapel definiert werden. Ereignisse für Ressourcenänderungen werden erst dann an registrierte Listener-Funktionen gesendet, wenn die mit "runnable" angegebene ausführbare Datei beendet wurde. Alle zusätzlichen (verschachtelten) ausführbaren Dateien in der übergeordneten ausführbaren Datei werden als Teil der übergeordneten Stapelverarbeitung betrachtet, und die Ressourcenänderungen, die in diesen ausführbaren Dateien vorgenommen werden, werden im Hinweis für die Ressourcenänderung des übergeordneten Elements angezeigt.
Eine Ausführung von Änderungen im Stapelbetrieb sollte definiert werden, wann immer dies möglich ist. Auf diese Weise kann nämlich der Systemaufwand begrenzt werden, der bei einem Broadcast-Betrieb für viele einzelne Änderungen entsteht. Wenn der Stapelbetrieb nicht eingesetzt wird, wird das System wahrscheinlich mit Hinweisen über Ressourcenänderungen und automatischen Erstellungen überflutet.
Das Ereignis für die Ressourcenänderung beschreibt die Änderung (oder die Gruppe der Änderungen), die im Arbeitsbereich vorgenommen wurde. Es enthält ein Ressourcendelta, das den Reineffekt der Änderungen beschreibt. Wenn Sie beispielsweise in ein- und demselben Stapel von Änderungen eine Ressource hinzufügen und an einer späteren Stelle wieder löschen, wird die Ressource im Delta nicht aufgeführt.
Das Ressourcendelta ist als Baumstruktur strukturiert, dessen Stamm das Stammverzeichnis des Arbeitsbereichs ist. Die Baumstruktur des Ressourcendeltas beschreibt die folgenden Typen von Änderungen:
Um die Baumstruktur des Ressourcendeltas zu durchqueren, können Sie die Schnittstelle IResourceDeltaVisitor implementieren oder aber die Baumstruktur durch Verwendung von IResource.getAffectedChildren explizit durchqueren. Funktionen zum Anzeigen von Ressourcendeltas implementieren eine Methode visit, die durch das Ressourcendelta aufgerufen wird, wenn alle Änderungen in der Baumstruktur aufgezählt werden.
Hinweis: Änderungen, die an den Sitzungseigenschaften für eine Ressource oder an den permanenten Eigenschaften einer Ressource vorgenommen wurden, sind im Ressourcendelta nicht angegeben.
Ereignisse für Ressourcenänderungen werden immer dann gesendet, wenn eine Änderung (oder eine im Stapelbetrieb ausgeführte Gruppe von Änderungen) im Arbeitsbereich stattfindet. Außerdem werden Ereignisse für Ressourcenänderungen bei bestimmten Operationen im Arbeitsbereich gesendet. Die folgende Tabelle fasst die Typen der Ereignisse für Ressourcenänderungen zusammen und gibt an, wann diese Ereignisse gemeldet werden.
Ereignistyp |
Beschreibung |
---|---|
PRE_CLOSE |
Benachrichtigt Listener-Funktionen über das anstehende Schließen eines Projekts. Mit solchen Ereignissen können benötigte Informationen aus der speicherinternen Darstellung eines Projekts (z. B. Sitzungseigenschaften) extrahiert und gespeichert werden, bevor das Projekt geschlossen wird. (Beim Schließen eines Projekts wird die speicherinterne Darstellung entfernt.) Während dieses Ereignisses ist der Arbeitsbereich gesperrt (Ressourcen können also nicht mehr aktualisiert werden). Das Ereignis gibt das Projekt an, das geschlossen werden soll. |
PRE_DELETE |
Benachrichtigt Listener-Funktionen über das anstehende Löschen eines Projekts. Mit einem solchen Ereignis können Bereinigungsoperationen ausgeführt werden, beispielsweise das Entfernen von gespeicherten Statuseinträgen aus dem Plug-in-Verzeichnis, die mit dem Projekt zusammenhängen. Während dieses Ereignisses ist der Arbeitsbereich gesperrt, und Ressourcen können nicht mehr aktualisiert werden. Das Ereignis gibt das Projekt an, das gelöscht werden soll. |
PRE_AUTOBUILD |
Benachrichtigt Listener-Funktionen, bevor eine automatische Erstellung stattfindet. Dieses Ereignis wird im Broadcast-Betrieb gesendet, sobald die Plattform feststellt, dass eine automatische Erstellung ausgeführt werden muss, und zwar unabhängig davon, ob die Option für die automatische Erstellung aktiviert ist oder nicht. Während dieses Ereignisses ist der Arbeitsbereich nicht gesperrt (Ressourcen können also aktualisiert werden). Das Ereignis enthält ein Ressourcendelta, das die Änderungen beschreibt, die seit dem letzten Ereignis POST_CHANGE stattgefunden haben. |
POST_AUTOBUILD |
Benachrichtigt Listener-Funktionen, nachdem eine automatische Erstellung stattgefunden hat. Dieses Ereignis wird im Broadcast-Betrieb gesendet, nachdem die Plattform eine automatische Erstellung ausgeführt hat, und zwar unabhängig davon, ob die Option für die automatische Erstellung aktiviert ist oder nicht. Während dieses Ereignisses ist der Arbeitsbereich nicht gesperrt (Ressourcen können also aktualisiert werden). Das Ereignis enthält ein Ressourcendelta, das die Änderungen beschreibt, die seit dem letzten Ereignis POST_CHANGE stattgefunden haben. |
POST_CHANGE |
Beschreibt eine Gruppe von Änderungen, die im Arbeitsbereich seit dem letzten Ereignis POST_CHANGE stattgefunden haben. Es wird ausgelöst, nachdem eine API für die Ressourcenänderung entweder bei einer Einzelaktion oder bei einer im Stapelbetrieb ausgeführten Gruppe von Arbeitsbereichsänderungen verwendet wurde. Außerdem wird dieses Ereignis ausgelöst, nachdem ein Hinweis für PRE_AUTOBUILD oder POST_AUTOBUILD vollständig übergeben wurde. Das Ereignis enthält ein Ressourcendelta, in dem der Reineffekt der Änderungen seit dem letzten Ereignis POST_CHANGE beschrieben wird. Während dieses Ereignisses ist der Arbeitsbereich gesperrt, und Ressourcen können nicht mehr aktualisiert werden. |
Das folgende Beispiel implementiert eine konsolenbasierte Listener-Funktion für Ressourcenänderungen. Eine Listener-Funktion für Ressourcenänderungen wird für spezifische Typen von Ereignissen registriert. Für diese Ereignisse werden dann Informationen an der Konsole ausgegeben:
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);
Die Listener-Funktion prüft jeden Ereignistyp und meldet Informationen über die geänderte Ressource und über die stattgefundenen Änderungen. Das Beispiel stellt zwar eine allgemeine Listener-Funktion dar, die alle Typen von Ressourcenereignissen verarbeitet, in der Regel wird jedoch eine Listener-Funktion nur für einen bestimmten Ereignistyp registriert.
Die Implementierung für POST_CHANGE verwendet eine andere Klasse, mit der die Änderungen im Ressourcendelta angezeigt werden können.
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("Projekt "); System.out.print(res.getFullPath()); System.out.println(" wird demnächst geschlossen."); break; case IResourceChangeEvent.PRE_DELETE: System.out.print("Projekt "); System.out.print(res.getFullPath()); System.out.println(" wird demnächst gelöscht."); break; case IResourceChangeEvent.POST_CHANGE: System.out.println("Ressourcen wurden geändert.") event.getDelta().accept(new DeltaPrinter()); break; case IResourceChangeEvent.PRE_AUTO_BUILD: System.out.println("Automatische Erstellung wird demnächst ausgeführt."); event.getDelta().accept(new DeltaPrinter()); break; case IResourceChangeEvent.POST_AUTO_BUILD: System.out.println("Automatische Erstellung ist abgeschlossen."); event.getDelta().accept(new DeltaPrinter()); break; } } }
Die Klasse DeltaPrinter implementiert die Schnittstelle IResourceDeltaVisitor, um die Ressourcenänderungen abzufragen. Die Methode visit() wird für jede Ressourcenänderung im Ressourcendelta aufgerufen. Die Visitor-Funktion gibt durch einen Rückgabewert an, ob die Deltas für untergeordnete Ressourcen berücksichtigt werden sollten.
class DeltaPrinter implements IResourceDeltaVisitor { public boolean visit(IResourceDelta delta) { IResource res = delta.getResource(); switch (delta.getKind()) { case IResourceDelta.ADDED: System.out.print("Ressource "); System.out.print(res.getFullPath()); System.out.println(" wurde hinzugefügt."); break; case IResourceDelta.REMOVED" System.out.print("Ressource "); System.out.print(res.getFullPath()); System.out.println(" wurde entfernt."); break; case IResourceDelta.CHANGED: System.out.print("Ressource "); System.out.print(res.getFullPath()); System.out.println(" wurde geändert."); break; } return true; // untergeordnete Ressourcen berücksichtigen } }
Weitere Informationen können Sie aus dem gelieferten Ressourcendelta abrufen. Das folgende Snippet zeigt, wie der Fall IResourceDelta.CHANGED implementiert werden könnte, um die Ressourcenänderungen genauer zu beschreiben.
... case IResourceDelta.CHANGED: System.out.print("Ressource "); System.out.print(delta.getFullPath()); System.out.println(" wurde geändert."); int flags = delta.getFlags(); if ((flags & IResourceDelta.CONTENT) != 0) { System.out.println("--> Der Inhalt wurde geändert."); } if ((flags & IResourceDelta.REPLACED) != 0) { System.out.println("--> Der Inhalt wurde ersetzt."); } if ((flags & IResourceDelta.MARKERS) != 0) { System.out.println("--> Markierungsänderung"); IMarkerDelta[] markers = delta.getMarkerDeltas(); // Falls Markierungen wichtig sind, sollen diese Deltas geprüft werden } break; ...
Eine vollständige Beschreibung von Ressourcendeltas, Visitor-Funktionen und Markierungsdeltas finden Sie in der API-Spezifikation für die Schnittstellen IResourceDelta, IResourceDeltaVisitor und IMarkerDelta.
Hinweis: Listener-Funktionen für Ressourcenänderungen sind hilfreich, wenn Änderungen an Ressourcen protokolliert werden sollen, die während eines aktiven Plug-ins stattfinden. Wenn Ihr Plug-in in seinem Startcode eine Listener-Funktion für Ressourcenänderungen registriert, werden viele Ereignisse für Ressourcenänderungen möglicherweise ausgelöst, bevor das Plug-in aktiviert wird. Das Ressourcendelta, das im ersten durch das Plug-in empfangenen Ereignis für eine Ressourcenänderung enthalten ist, enthält dann nicht alle Änderungen, die seit der letzten Aktivierung des Plug-ins stattgefunden haben. Wenn Sie Änderungen protokollieren wollen, die zwischen den Aktivierungen des Plug-ins vorgenommen wurden, sollten Sie zu diesem Zweck die Unterstützung für das Speichern des Arbeitsbereichs verwenden. Diese Unterstützung ist unter Arbeitsbereich speichern beschrieben.