Traccia delle modifiche delle risorse

È stato illustrato come eseguire il batch delle modifiche delle risorse in un'operazione eseguibile (Batch delle modifiche delle risorse). Si osservi ora l'altro lato della medaglia. Quale operazione è necessario eseguire se si desidera tenere traccia di tutte le modifiche apportate allo spazio di lavoro durante l'esecuzione del plugin? È possibile registrare un IResourceChangeListener con lo spazio di lavoro. Il listener riceverà la notifica delle modifiche attraverso un oggetto IResourceChangeEvent, che descriverà le modifiche.

Registrazione di un listener

Per prima cosa, è necessario registrare un listener di modifiche delle risorse nello spazio di lavoro.

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

Il listener verrà informato dopo l'esecuzione delle modifiche alle risorse dello spazio di lavoro. I metodi dell'API delle risorse che modificano le risorse attivano questi eventi come parte del proprio funzionamento documentato. Il commento del metodo di un'API delle risorse indica esplicitamente l'attivazione o meno di un evento di modifica delle risorse. Ad esempio, quanto riportato di seguito viene incluso nel commento di IFile.setContents():

   Questo metodo modifica le risorse; le modifiche verranno riportate in un successivo
   evento di modifica delle risorse comprendente un'indicazione della modifica del contenuto
   del file.

I metodi per la creazione, l'eliminazione o la modifica di una risorsa generalmente attivano questi eventi. I metodi che consultano le risorse senza intervenire su di esse, generalmente non attivano questi eventi.

Eventi di modifica delle risorse

L'evento di modifica delle risorse descrive le specifiche della modifica (o dell'insieme di modifiche) apportata nello spazio di lavoro. L'evento contiene un delta delle risorse che descrive l'effetto di rete delle modifiche. Ad esempio, se si aggiunge una risorsa e, successivamente, la si elimina durante un batch di modifiche, la risorsa non apparirà nel delta.

Il delta delle risorse è organizzato come una struttura ad albero derivante dalla directory principale dello spazio di lavoro. La struttura del delta delle risorse descrive i seguenti tipi di modifiche:

Per esplorare una struttura di delta delle risorse, implementare l'interfaccia IResourceDeltaVisitor oppure esaminare esplicitamente la struttura utilizzando IResource.getAffectedChildren. I visitatori del delta delle risorse implementano un metodo visit richiamato dal delta delle risorse ad ogni modifica apportata nella struttura.

Nota: le modifiche apportate alle proprietà di sessione o alle proprietà persistenti delle risorse non vengono identificate nel delta delle risorse.

Gli eventi di modifica delle risorse vengono inviati ogni volta che una modifica (o un insieme di modifiche in batch) viene apportata allo spazio di lavoro. Inoltre, tali eventi vengono inviati anche per alcune specifiche operazioni dello spazio di lavoro. La tabella seguente riepiloga i tipi di eventi di modifica delle risorse e quando questi vengono riportati.

Tipo di evento

Descrizione

PRE_CLOSE

Notifica ai listener che sta per essere chiuso un progetto. Questo evento può essere utilizzato per estrarre e salvare informazioni necessarie dalla rappresentazione in memoria (ad es., proprietà di sessione) di un progetto prima che questo venga chiuso. Quando un progetto viene chiuso, la rappresentazione in memoria viene eliminata. Durante questo evento, lo spazio di lavoro è bloccato (nessuna risorsa può essere aggiornata). L'evento contiene il progetto che sta per essere chiuso.

PRE_DELETE

Notifica ai listener che sta per essere eliminato un progetto. Questo evento può essere utilizzato per eseguire operazioni di ripulitura, quali la rimozione di qualsiasi stato salvato relativo al progetto dalla directory del plugin. Durante questo evento lo spazio di lavoro è bloccato (nessuna risorsa può essere aggiornata). L'evento contiene il progetto che sta per essere eliminato.

PRE_AUTOBUILD

Invia una notifica ai listener prima dell'esecuzione di una generazione automatica. Questo evento viene trasmesso quando la piattaforma rileva la necessità di eseguire una generazione automatica, indipendentemente dal fatto che tale funzione sia o meno attivata. Durante questo evento lo spazio di lavoro non è bloccato (le risorse possono essere aggiornate). L'evento contiene un delta delle risorse che descrive le modifiche occorse dalla notifica dell'ultimo evento POST_CHANGE.

POST_AUTOBUILD

Invia una notifica ai listener in seguito all'esecuzione di una generazione automatica. Questo evento viene trasmesso dopo che la piattaforma ha eseguito una generazione automatica, indipendentemente dal fatto che tale funzione sia o meno attivata. Durante questo evento lo spazio di lavoro non è bloccato (le risorse possono essere aggiornate). L'evento contiene un delta delle risorse che descrive le modifiche occorse dalla notifica dell'ultimo evento POST_CHANGE.

POST_CHANGE

Descrive un insieme di modifiche occorse nello spazio di lavoro dal momento in cui è stato riportato l'ultimo evento POST_CHANGE. Viene attivato dopo l'utilizzo singolo di un'API di modifica delle risorse o in un insieme in batch di modifiche dello spazio di lavoro. Viene attivato anche dopo il completamento di una notifica PRE_AUTOBUILD o POST_AUTOBUILD. L'evento contiene un delta delle risorse che descrive le modifiche apportate in seguito all'ultimo evento POST_CHANGE. Durante questo evento lo spazio di lavoro è bloccato (nessuna risorsa può essere aggiornata).

Implementazione di un listener di modifica delle risorse

Il seguente esempio implementa un listener di modifica delle risorse basato sulla console. Un listener di modifica delle risorse viene registrato per tipi specifici di eventi e le informazioni su tali eventi vengono visualizzate sulla console:

   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);

Il listener controlla ogni tipo di evento e segnala le informazioni sulla risorsa modificata e sui tipi di modifiche apportate. Sebbene questo esempio sia progettato per un listener generico che gestisce tutti i tipi di eventi di risorse, un listener tipico registrerà un solo tipo di evento.

L'implementazione per POST_CHANGE impiega un'altra classe utilizzabile per "visitare" le modifiche nel delta delle risorse.

   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;
         }
      }
   }

La classe DeltaPrinter implementa l'interfaccia IResourceDeltaVisitor per interrogare il delta delle risorse. Il metodo visit() viene richiamato per ogni modifica di risorsa presente nel delta delle risorse. Il visitatore utilizza un valore restituito per indicare se visitare i delta delle risorse secondarie.

   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; // visitare gli elementi secondari
      }
   }

Ulteriori informazioni sono reperibili nel delta delle risorse fornito all'utente. Il frammento di codice seguente mostra come può essere implementato il case IResourceDelta.CHANGED per descrivere ulteriormente le modifiche delle risorse.

   ...
   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();
            // se interessano gli indicatori, controllare questi delta
      }
      break;
   ...

Per una descrizione completa dei delta delle risorse, dei visitatori e dei delta degli indicatori, consultare la specifica API per IResourceDelta, IResourceDeltaVisitor e IMarkerDelta.

Nota: i listener di modifica delle risorse sono utili per la traccia delle modifiche che si verificano nelle risorse mentre il plugin è attivato. Se il plugin dell'utente registra un listener di modifica delle risorse durante il proprio codice di avvio, è possibile che molti eventi di modifica di risorse siano stati attivati prima dell'attivazione del plugin stesso. Il delta delle risorse contenuto nel primo evento di modifica delle risorse ricevuto dal plugin non conterrà tutte le modifiche effettuate poiché il plugin è stato attivato successivamente. Se è necessario tenere la traccia delle modifiche effettuate tra le attivazioni del plugin, utilizzare il supporto fornito per il salvataggio dello spazio di lavoro. Tale supporto è illustrato in Partecipazione di salvataggio dello spazio di lavoro.
Nota:  gli eventi di modifica di alcune risorse sono attivati durante l'elaborazione che si verifica in un thread di sfondo. I listener di modifica delle risorse devono disporre della protezione thread. Per informazioni sulla protezione thread con l'UI, fare riferimento alla sezione Problemi del thread.