Det er netop blevet gennemgået, hvordan ressourceændringer kan udføres i batch (Batchbehandling af ressourceændringer), men nu skal vi undersøge, hvordan det ser ud fra den anden side. Er det muligt at spore alle arbejdsområdeændringer, mens plugin'en udføres? Du kan registrere en IResourceChangeListener i arbejdsområdet. Lytteren underrettes om ændringer via objektet IResourceChangeEvent, som beskriver ændringerne.
Først skal du registrere en ressourceændringslytter i arbejdsområdet.
IResourceChangeListener listener = new MyResourceChangeReporter(); ResourcesPlugin.getWorkspace().addResourceChangeListener( listener, IResourceChangeEvent.POST_CHANGE);
Lytteren underrettes, når der er foretaget ændringer til arbejdsområdets ressourcer. Ressource-API-metoder, der reviderer ressourcer, udløser disse aktiviteter som en del af deres dokumenterede funktionalitet. I metodekommentaren til en ressource-API-metode er der eksplicit angivet, om den udløser en ressourceændringsaktivitet. Eksempel: Det følgende er inkluderet i IFile.setContents()-kommentaren:
Denne metode ændrer ressourcer. Disse ændringer rapporteres i en efterfølgende ressourceændringsaktivitet, inkl. en angivelse af, at indholdet af denne fil er ændret.
Metoder, der opretter, sletter eller ændrer en ressource, udløser typisk disse aktiviteter. Metoder, der læser, men ikke skriver ressourcer, udløser ikke disse aktiviteter.
Ressourceændringsaktiviteten beskriver detaljerne om ændringen/ændringerne, der har fundet sted i arbejdsområdet. Aktiviteten indeholder en ressourcedelta, der beskriver nettovirkningen af ændringerne. Hvis du f.eks. tilføjer en ressource og senere sletter den via et ændringsbatch, vises ressourcen ikke i deltaet.
Ressourcedeltaet er opbygget som en træstruktur, hvis rod er i arbejdsområdets rod. Ressourcedeltaets træstruktur beskriver disse typer ændringer:
For at gennemgå en træstruktur for ressourcedelta skal du implementere IResourceDeltaVisitor-grænsefladen, eller du kan gennemgå træstrukturen eksplicit vha. IResource.getAffectedChildren. Besøgende til ressourcedeltaet implementerer en visit-metode, der kaldes af ressourcedeltaet samtidig med, at det nummererer hver ændring i træstrukturen.
Bemærk: De ændringer, der foretages til ressourcens sessionsegenskaber eller vedvarende egenskaber, identificeres ikke i ressourcedeltaer.
Der sendes ressourceændringsaktiviteter, hver gang en ændring (eller et ændringssæt i batch) foretages til arbejdsområdet. Desuden sendes ressourceændringsaktiviteter for bestemte arbejdsområdefunktioner. Tabellen nedenfor opsummerer de forskellige typer ressourceændringsaktiviteter, og hvornår de rapporteres.
Aktivitetstype |
Beskrivelse |
---|---|
PRE_CLOSE |
Underretter lyttere om, at et projekt skal til at afsluttes. Denne aktivitet kan bruges til at udlede og gemme nødvendige oplysninger fra den repræsentation af projektet, som ligger i hukommelsen, inden det afsluttes. Når et projekt er lukket, går repræsentationen, som ligger i hukommelsen, tabt. Arbejdsområdet er låst (ingen ressourcer kan opdateres) i løbet af denne aktivitet. Aktiviteten indeholder det projekt, der afsluttes. |
PRE_DELETE |
Underretter lyttere om, at et projekt skal til at slettes. Aktiviteten kan bruges til at foretage oprydningsfunktioner, f.eks. at fjerne en gemt tilstand, der har relation til projektet fra plugin'ens bibliotek. Arbejdsområdet er låst (ingen ressourcer kan opdateres) i løbet af denne aktivitet. Aktiviteten indeholde det projekt, der slettes. |
PRE_AUTOBUILD |
Underretter lyttere inden automatisk bygning skal finde sted. Denne aktivitet rundsendes, når platformen registrerer, at automatisk bygning bør udføres, uanset om automatisk bygning er aktiveret. Arbejdsområdet er ikke låst i løbet af denne aktivitet (ressourcer kan opdateres). Aktiviteten indeholder en ressourcedelta, som beskriver de ændringer, der er sket, siden den sidste POST_CHANGE-aktivitet blev rapporteret. |
POST_AUTOBUILD |
Underretter lyttere, når en automatisk bygning har fundet sted. Denne aktivitet rundsendes, når platformen ville have udført automatisk bygning, uanset om automatisk bygning er aktiveret. Arbejdsområdet er ikke låst i løbet af denne aktivitet (ressourcer kan opdateres). Aktiviteten indeholder en ressourcedelta, som beskriver de ændringer, der er sket, siden den sidste POST_CHANGE-aktivitet blev rapporteret. |
POST_CHANGE |
Beskriver et sæt ændringer, der har fundet sted til arbejdsområdet, siden den sidste POST_CHANGE-aktivitet blev rapporteret. Den udløses, når en ressourceændrings-API er brugt individuelt eller i en batch, der indeholder et sæt ændringer til arbejdsområdet. Den udløses også, når underrettelse om PRE_AUTOBUILD eller POST_AUTOBUILD er udført. Aktiviteten indeholder et ressourcedelta, der beskriver de nettoændringerne, som er sket siden sidste POST_CHANGE-aktivitet. Arbejdsområdet er låst (ingen ressourcer kan opdateres) i løbet af denne aktivitet. |
I følgende eksempel implementeres en konsolbaseret ressourceændringslytter. En ressourceændringslytter registreres for specifikke typer aktiviteter, og oplysningerne om disse aktiviteter skrives til konsollen:
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);
Lytteren kontrollere for hver aktivitetstype og rapporter oplysninger om den ressource, der er ændret, og om hvilke typer ændringer der er foretaget. Selvom dette eksempel er lavet for at vise en general lytter, som håndterer alle typer ressourceaktiviteter, vil en typisk lytter kun registrere en type aktivitet.
POST_CHANGE-implementeringen bruger en anden klasse, der kan anvendes til at besøge ændringer i ressourcedeltaer.
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(" is about to close."); break; case IResourceChangeEvent.PRE_DELETE: System.out.print("Project "); System.out.print(res.getFullPath()); System.out.println(" is about to be deleted."); break; case IResourceChangeEvent.POST_CHANGE: System.out.println("Resources have changed."); event.getDelta().accept(new DeltaPrinter()); break; case IResourceChangeEvent.PRE_AUTO_BUILD: System.out.println("Auto build about to run."); event.getDelta().accept(new DeltaPrinter()); break; case IResourceChangeEvent.POST_AUTO_BUILD: System.out.println("Auto build complete."); event.getDelta().accept(new DeltaPrinter()); break; } } }
Klassen DeltaPrinter implementerer IResourceDeltaVisitor-grænsefladen for at undersøge ressourcedeltaet nøje. Metoden visit() kaldes for hver ressourceændring i ressourcedeltaer. Den besøgende bruger en returværdi til at angive, om deltaer for underordnede ressourcer skal besøges.
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(" was added."); break; case IResourceDelta.REMOVED: System.out.print("Resource "); System.out.print(res.getFullPath()); System.out.println(" was removed."); break; case IResourceDelta.CHANGED: System.out.print("Resource "); System.out.print(res.getFullPath()); System.out.println(" has changed."); break; } return true; // besøger de underordnede elementer } }
Du finder flere oplysninger i det leverede ressourcedelta. Følgende stykke kode viser, hvordan IResourceDelta.CHANGED kan implementeres for yderligere at beskrive ressourceændringerne.
... case IResourceDelta.CHANGED: System.out.print("Resource "); System.out.print(delta.getFullPath()); System.out.println(" has changed."); int flags = delta.getFlags(); if ((flags & IResourceDelta.CONTENT) != 0) { System.out.println("--> Content Change"); } if ((flags & IResourceDelta.REPLACED) != 0) { System.out.println("--> Content Replaced"); } if ((flags & IResourceDelta.MARKERS) != 0) { System.out.println("--> Marker Change"); IMarkerDelta[] markers = delta.getMarkerDeltas(); // tjek disse deltaer, hvis du er interesseret i markeringer } break; ...
For at få en komplet beskrivelse af ressourcedeltaer, besøgende og markeringsdeltaer skal du læse API-specifikationerne for IResourceDelta, IResourceDeltaVisitor og IMarkerDelta.
Bemærk: Ressourceændringslyttere er nyttige ifm. at spore ændringer, der finder sted til ressourcer, mens plugin'en er aktiveret. Hvis plugin'en registrerer en ressourceændringslytter, mens dens startkode udføres, er det muligt, at der er udløst mange ressourceændringsaktiviteter, inden plugin'en blev aktiveret. Det ressourcedelta, der er indeholdt i den første ressourceændringsaktivitet, som plugin'en modtager, indeholder ikke alle de ændringer, der er sket, siden plugin'en sidst var aktiveret. Hvis du har brug for at spore de ændringer, der er sket mellem to aktiveringer af plugin'en, skal du bruge den understøtte, der leveres til brug for arbejdsområdelagring. Det er beskrevet i Deltag i lagring af arbejdsområde.
Bemærk: Nogle ressourceændringsaktiviteter udløses under den behandling, der finder sted i en baggrundsprogramdel. Ressourceændringslyttere bør være sikret mod programdele. I Problemer med programdele finder du flere oplysninger om programdelssikkerhed og grænsefladen.