Spore ressursendringer

Vi har nettopp sett hvordan vi satsvis kjører ressursendringer i en kjørbar fil (Satsvis kjøring av ressursendringer). La oss se på dette fra et annet perspektiv. Hva hvis du vil holde oversikt over alle arbeidsområdeendringene som utføres mens plugin-modulen kjøres? Du kan registrere en IResourceChangeListener med arbeidsmiljøet. Lytteren varsles om endringene via et IResourceChangeEvent-objekt, som beskriver endringene.

Registrere en lytter

Først må du registrere en ressursendringslytter med arbeidsområdet.

   IResourceChangeListener listener = new MyResourceChangeReporter();
   ResourcesPlugin.getWorkspace().addResourceChangeListener(
      listener, IResourceChangeEvent.POST_CHANGE);

Lytteren varsles etter at det er foretatt endringer i arbeidsområderessursene. Ressurs-API-metodene som endrer ressurser, utløser disse hendelsene som en del av den dokumenterte funksjonaliteten deres. Kommentaren for en slik metode uttrykker eksplisitt om det utløses en ressursendringshendelse. For eksempel er følgende inkludert i kommentaren IFile.setContents():

   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.

Metoder som oppretter, sletter eller endrer en ressurs, utløser vanligvis disse hendelsene. Metoder som leser, men ikke skriver ressurser, utløser vanligvis ikke slike hendelser.

Ressursendringshendelser

Ressursendringshendelsen beskriver egenskaper for endringen (eller settet med endringer) som har oppstått i arbeidsområdet. Hendelsen inneholder en ressursdelta som beskriver nettoeffekten av endringene. Hvis du for eksempel legger til en ressurs som du senere sletter under satsvis kjøring av endringer, vises ikke ressursen i deltaen.

Ressursdeltaen er strukturert som et tre med roten i arbeidsområderoten. Ressursdeltatreet beskriver følgende endringstyper:

Hvis du vil gjennomgå ressursdeltatreet, kan du implementere grensesnittet IResourceDeltaVisitor eller gjennomgå treet eksplisitt ved hjelp av IResource.getAffectedChildren. Ressursdeltabesøkende implementerer en visit-metode som kalles av ressursdeltaen ved oppregning av alle endringene i treet.

Merk:  Endringer som er foretatt i ressurssesjonsegenskapene eller ressurspermanente egenskaper, identifiseres ikke i ressursdeltaen.

Det blir sendt ressursendringshendelser hver gang det utføres en endring (eller en satsvis kjøring av sett med endringer) i arbeidsområdet. I tillegg sendes ressursendringshendelser for bestemte arbeidsområdeoperasjoner. Tabellen nedenfor viser de ulike typene ressursendringshendelser og når de rapporteres.

Hendelsestype

Beskrivelse

PRE_CLOSE

Varsler lyttere om at et prosjekt er i ferd med å lukkes. Denne hendelsen kan brukes til å trekke ut og lagre nødvendig informasjon fra minnerepresentasjon (for eksempel sesjonsegenskaper) for et prosjekt før det lukkes. (Når et prosjekt lukkes, slettes minnerepresentasjonen). Arbeidsområdet låses (ingen ressurser kan oppdateres) når denne hendelsen utføres. Hendelsen inneholder prosjektet som lukkes.

PRE_DELETE

Varsler lyttere om et prosjekt er i ferd med å bli slettet. Denne hendelsen kan brukes til å utføre oppryddingsoperasjoner, for eksempel fjerning av lagrede tilstander som er knyttet til prosjektet fra plugin-katalogen.  Arbeidsområdet låses (ingen ressurser kan oppdateres) når denne hendelsen utføres. Hendelsen inneholder prosjektet som slettes.

PRE_AUTOBUILD

Varsler lyttere før det utføres automatisk bygging. Denne hendelsen kunngjøres når plattformen finner ut at en bygging må utføres automatisk, uavhengig av om funksjonen for automatisk bygging er aktivert. Arbeidsområdet er ikke låst når denne hendelsen utføres (ressurser kan oppdateres). Hendelsen inneholder en ressursdelta som beskriver endringene som har oppstått siden siste POST_CHANGE-hendelse ble rapportert.

POST_AUTOBUILD

Varsler lyttere etter at det er utført automatisk bygging. Denne hendelsen kunngjøres etter at plattformen har utført en automatisk bygging, uavhengig av om funksjonen for automatisk bygging er aktivert. Arbeidsområdet er ikke låst når denne hendelsen utføres (ressurser kan oppdateres).Hendelsen inneholder en ressursdelta som beskriver endringene som har oppstått siden siste POST_CHANGE-hendelse ble rapportert.

POST_CHANGE

Beskriver et sett med endringer som har oppstått i arbeidsområdet siden siste POST_CHANGE-hendelse ble rapportert. Utløses etter at programmeringsgrensesnittet for en ressursendring er brukt individuelt eller i en satsvis kjøring av et sett med arbeidsområdeendringer. Utløses også etter at varsel om PRE_AUTOBUILD eller POST_AUTOBUILD er fullført. Hendelsen inneholder en ressursdelta som beskriver nettoendringer siden siste POST_CHANGE-hendelse.  Arbeidsområdet låses (ingen ressurser kan oppdateres) når denne hendelsen utføres.

Implementere en ressursendringslytter

I eksempelet nedenfor implementeres en konsollbasert ressursendringslytter. Det registreres en slik lytter for bestemte typer hendelser, og informasjon om disse hendelsene 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 kontrollerer hver hendelsestype og rapporterer om den endrede ressursen og hva slags endringer som oppstod.  Selv om dette eksempelet er utformet for å vise en generell lytter som håndterer alle typer ressurshendelser, registrerer den typiske lytteren bare en type hendelse.

Implementeringen av POST_CHANGE bruker en annen klasse som kan brukes til å besøke endringene i ressursdeltaen.

   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-grensesnittet for å undersøke ressursdeltaen. For hver ressursendring i ressursdeltaen kalles visit()-metoden. Den besøkende bruker en returverdi for å angi om deltaer for underordnede ressurser skal besøkes.

   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; // visit the children
      }
   }

Du finner mer informasjon fra den oppgitte ressursdeltaen. Følgende snutt viser hvordan IResourceDelta.CHANGED-tilfellet kan implementeres slik at ressursendringene beskrives videre.

   ...
   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();
            // if interested in markers, check these deltas
      }
      break;
   ...

Du finner en fullstendig beskrivelse av ressursdeltaer, besøkende og merkedeltaer i API-spesifikasjonen for IResourceDelta, IResourceDeltaVisitor og IMarkerDelta.

Merk:  Ressursendringslyttere er nyttige ved sporing av endringer som oppstår i ressurser mens plugin-modulen er aktivert. Hvis plugin-modulen registrerer en ressursendringslytter under oppstarten, kan det være at det er aktivert en rekke ressursendringshendelser før plugin-modulen aktiveres. Ressursdeltaen i den første ressursendringshendelsen som er mottatt av plugin-modulen, inneholder ikke alle endringene som er foretatt siden siste aktivering av plugin-modulen. Hvis du vil spore endringer som er foretatt mellom aktiveringene av plugin-modulen, bruker du støtten som er oppgitt for lagring av arbeidsområdet. Dette beskrives nærmere i Medvirkning til arbeidsområdelagring.
Merk:  Noen ressursendringshendelser utløses ved behandling i en bakgrunnstråd. Ressursendringslyttere skal være trådsikre. Du finner mer informasjon om trådsikkerhet i brukergrensesnittet, under Trådbehandlingsspørsmål.