Hacer un seguimiento de los cambios de recursos

Acabamos de ver cómo agrupar por lotes los cambios de recurso en un ejecutable (Agrupar por lotes los cambios de recurso). Observemos ahora la otra cara de la moneda. ¿Qué debe hacer si desea realizar el seguimiento de todos los cambios del área de trabajo que se producen durante la ejecución del conector? Puede registrar un IResourceChangeListener en el área de trabajo. El escuchador recibirá notificación de los cambios por medio de un objeto evento de cambio, IResourceChangeEvent, que describe los cambios.

Registrar un escuchador

En primer lugar, debe registrar un escuchador de cambios de recursos en el área de trabajo.

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

El escuchador recibirá notificación después de que se hayan efectuado modificaciones en los recursos del área de trabajo. Los métodos de la API de recursos que modifican los recursos desencadenan estos eventos como parte del comportamiento documentado en ellos. El comentario de un método de la API de recursos indica explícitamente si dicho método desencadena o no un evento de cambio de recurso. Por ejemplo, en el comentario del método IFile.setContents(), se incluye lo siguiente:

      Este método cambia recursos; los cambios se notificarán en un subsiguiente
   evento de cambio de recurso, e incluirá una indicación de que el contenido
   de este archivo ha cambiado.

Los métodos que crean, suprimen o cambian un recurso suelen desencadenar estos eventos. Los métodos que leen recursos, pero no escriben en ellos, no suelen desencadenar estos eventos.

Eventos de cambio de recurso

El evento de cambio de recurso describe los detalles específicos del cambio (o del conjunto de cambios) que se ha producido en el área de trabajo. El evento contiene un delta de recursos que describe el efecto neto de los cambios. Por ejemplo, si añade un recurso y más adelante lo suprime durante un proceso por lotes de cambios, el recurso no aparecerá en el delta.

El delta de recursos está estructurado en forma de árbol enraizado en el directorio raíz del área de trabajo. El árbol del delta de recursos describe estos tipos de cambios:

Para cruzar un árbol de delta de recursos, puede implementar la interfaz IResourceDeltaVisitor o cruzar el árbol de manera explícita utilizando IResource.getAffectedChildren. Los visitantes del delta de recursos implementan un método visit al que el delta de recursos llama a medida que enumera cada cambio del árbol.

Nota:  los cambios efectuados en las propiedades de sesión de recursos o en las propiedades persistentes de los recursos no se identifican en el delta de recursos.

Los eventos de cambio de recurso se envían siempre que se hace un cambio (o conjunto de cambios por lotes) en el área de trabajo. Los eventos de cambio de recurso también se envían cuando se realizan determinadas operaciones del área de trabajo. La tabla siguiente contiene un resumen de los tipos de eventos de cambio de recurso y de cuándo se notifican.

Tipo de evento

Descripción

PRE_CLOSE

Notifica a los escuchas que se va a cerrar un proyecto. Este evento puede utilizarse para extraer y guardar información necesaria de la representación en la memoria (por ejemplo, propiedades de sesión) de un proyecto antes de cerrarlo. (Cuando se cierra un proyecto, se desecha la representación en la memoria). Durante este evento, el área de trabajo está bloqueada (no se puede actualizar ningún recurso). El evento contiene el proyecto que se está cerrando.

PRE_DELETE

Notifica a los escuchas que se va a suprimir un proyecto. Este evento puede utilizarse para efectuar operaciones de limpieza, como las de eliminar cualquier estado guardado relacionado con el proyecto desde el directorio del conector.  Durante este evento, el área de trabajo está bloqueada (no se puede actualizar ningún recurso).El evento contiene el proyecto que se está suprimiendo.

PRE_AUTOBUILD

Notifica a los escuchas antes de que se produzca una construcción automática.  Este evento se difunde cuando la plataforma detecta que es preciso que tenga lugar una construcción automática, independientemente de si esta está habilitada realmente.  El área de trabajo no está bloqueada durante este evento (se pueden actualizar recursos). El evento contiene un delta de recursos que describe los cambios que se han producido desde que se notificó el último evento POST_CHANGE.

POST_AUTOBUILD

Notifica a los escuchas que se ha producido una construcción automática. Este evento se difunde después de que la plataforma ha efectuado una construcción automática, independientemente de si esta está habilitada realmente.  El área de trabajo no está bloqueada durante este evento (se pueden actualizar recursos).El evento contiene un delta de recursos que describe los cambios que se han producido desde que se notificó el último evento POST_CHANGE.

POST_CHANGE

Describe un conjunto de cambios que se han producido en el área de trabajo desde que se notificó el último evento POST_CHANGE. Se desencadena después de haber utilizado una API de cambio de recurso de manera individual o en un conjunto de cambios de área de trabajo por lotes. También se desencadena una vez completada la notificación de PRE_AUTOBUILD o POST_AUTOBUILD. El evento contiene un delta de recursos que describe los cambios que se han producido desde el último evento POST_CHANGE.  Durante este evento, el área de trabajo está bloqueada (no se puede actualizar ningún recurso).

Implementar un escuchador de cambio de recurso

En el ejemplo siguiente se implementa un escuchador de cambio de recurso basado en la consola. El escuchador de cambio de recurso se registra para tipos de eventos específicos, y la información sobre estos eventos se imprime en la consola:

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

El escuchador comprueba cada tipo de evento e informa sobre el recurso que se ha cambiado y los tipos de cambios que se han producido.  Aunque este ejemplo está diseñado para mostrar un escuchador genérico que maneja todos los tipos de eventos de recursos, un escuchador habitual se registraría para un solo tipo de evento.

La implementación de POST_CHANGE utiliza otra clase que puede servir para visitar los cambios en el delta de recursos.

      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("El proyecto ");
               System.out.print(res.getFullPath());
               System.out.println(" está a punto de cerrarse.");
      break;
            case IResourceChangeEvent.PRE_DELETE:
               System.out.print("El proyecto ");
               System.out.print(res.getFullPath());
               System.out.println(" está a punto de suprimirse.");
      break;
            case IResourceChangeEvent.POST_CHANGE:
               System.out.println("Los recursos han cambiado.");
               event.getDelta().accept(new DeltaPrinter());
      break;
            case IResourceChangeEvent.PRE_AUTO_BUILD:
               System.out.println("La construcción automática está a punto de ejecutarse.");
               event.getDelta().accept(new DeltaPrinter());
      break;
            case IResourceChangeEvent.POST_AUTO_BUILD:
               System.out.println("La construcción automática se ha completado.");
               event.getDelta().accept(new DeltaPrinter());
      break;
         }
      }
   }

La clase DeltaPrinter implementa la interfaz IResourceDeltaVisitor para interrogar el delta de recursos. Se llama al método visit() para cada cambio de recurso del delta de recursos. El visitante utiliza un valor de retorno para indicar si hay que visitar los deltas de los recursos hijo.

      class DeltaPrinter implements IResourceDeltaVisitor {
      public boolean visit(IResourceDelta delta) {
         IResource res = delta.getResource();
         switch (delta.getKind()) {
            case IResourceDelta.ADDED:
      System.out.print("El recurso ");
               System.out.print(res.getFullPath());
               System.out.println(" se ha añadido.");
      break;
            case IResourceDelta.REMOVED"
      System.out.print("El recurso ");
               System.out.print(res.getFullPath());
               System.out.println(" se ha eliminado.");
      break;
   case IResourceDelta.CHANGED:
      System.out.print("El recurso ");
               System.out.print(res.getFullPath());
      System.out.println(" ha cambiado.");
      break;
         }
         return true; // visitar los hijos
      }
   }

Puede obtenerse más información del delta de recursos suministrado. El siguiente fragmento de código muestra cómo podría implementarse el caso IResourceDelta.CHANGED para describir los cambios de recursos de manera más detallada.

   ...
   case IResourceDelta.CHANGED:
      System.out.print("El recurso ");
      System.out.print(delta.getFullPath());
      System.out.println(" ha cambiado.");
      int flags = delta.getFlags();
      if ((flags & IResourceDelta.CONTENT) != 0) {
            System.out.println("--> Cambio de contenido");
      }
      if ((flags & IResourceDelta.REPLACED) != 0) {
            System.out.println("--> Contenido sustituido");
      }
      if ((flags & IResourceDelta.MARKERS) != 0) {
            System.out.println("--> Cambio de marcador");
            IMarkerDelta[] markers = delta.getMarkerDeltas();
            // si está interesado en los marcadores, consulte estos deltas
      }
      break;
   ...

Para obtener una descripción completa de los deltas de recursos, visitantes y deltas de marcadores, consulte la especificación de las API de IResourceDelta, IResourceDeltaVisitor e IMarkerDelta.

Nota:  los escuchas de cambio de recurso resultan útiles para controlar los cambios que se producen en los recursos mientras el conector está activado. Si el conector registra un escuchador de cambio de recurso durante su código de inicio, es posible que se hayan desencadenado muchos eventos de cambio de recurso antes de la activación del conector. El delta de recursos contenido en el primer evento de cambio de recurso recibido por el conector no contendrá todos los cambios efectuados desde la última vez que se activó el conector. Si necesita hacer un seguimiento de los cambios hechos entre las activaciones del conector, debe utilizar el soporte que se proporciona para el guardado del área de trabajo. Esto se describe en Participación del guardado del área de trabajo.
Nota:  algunos eventos de cambio de recurso se desencadenan durante el proceso que se produce en una hebra de segundo plano. Los escuchas de cambios de recurso deben ser seguros en ejecución multihebra. Consulte la sección Elementos acerca de las hebras para obtener una descripción relativa a la seguridad de hebras en la UI.