Acabamos de ver como armazenar alterações de recurso em batch em um executável (Armazenando alterações de recursos em batch). Vamos ver o outro lado da moeda. E se você desejar controlar todas as alterações do espaço de trabalho que acontecem enquanto o seu plug-in está em execução? Você pode registrar um IResourceChangeListener com o espaço de trabalho. O ouvinte será notificado das alterações por um objeto IResourceChangeEvent, que descreve as alterações.
Primeiramente, você deve registrar um listener de alteração de recurso com o espaço de trabalho
IResourceChangeListener listener = new MyResourceChangeReporter(); ResourcesPlugin.getWorkspace().addResourceChangeListener( listener, IResourceChangeEvent.POST_CHANGE);
Seu ouvinte será notificado depois que as modificações forem feitas nos recursos da área de trabalho. Os métodos da API de recursos que modificam recursos disparam estes eventos como parte do seu funcionamento documentado. O comentário do método de um método da API de recursos atesta explicitamente se dispara ou não um evento de alteração de recursos. O exemplo a seguir está incluído no comentário IFile.setContents():
Esse método altera os recursos; essas alterações serão informadas em um evento de alteração de recurso subseqüente, incluindo uma indicação de que o conteúdo desse arquivo foi alterado.
Os métodos que criam, excluem ou alteram um recurso disparam tipicamente esses eventos. Os métodos que lêem, mas não gravam, os recursos não disparam esses eventos.
O evento de alteração do recurso descreve as especificações da alteração (ou conjunto de alterações) que ocorreram na área de trabalho. O evento contém um delta de recursos que descreve o efeito de rede nas alterações. Por exemplo, se incluir um recurso e depois excluí-lo durante um batch de alterações, o recurso não aparecerá no delta.
O delta de recursos é estruturado como uma árvore fixada na raiz da área de trabalho. A árvore do delta de recursos descreve estes tipos de alterações:
Para percorrer uma árvore do delta de recursos, implemente a interface IResourceDeltaVisitor ou percorra a árvore explicitamente utilizando IResource.getAffectedChildren. Os visitantes do delta de recursos implementam um método visit que é chamado pelo delta de recursos enquanto ele enumera cada alteração na árvore.
Nota: As alterações feitas nas propriedades de seção de recursos ou nas propriedades persistentes do recurso não são identificadas no delta de recursos.
Os eventos de alteração de recursos são enviados sempre que uma alteração (ou conjunto de alterações com batch) for feita na área de trabalho. Além disso, os eventos de alteração de recursos são enviados para certas operações específicas da área de trabalho. A tabela abaixo resume os tipos de eventos de alteração de recursos e quando foram reportados.
Tipo do evento |
Descrição |
---|---|
PRE_CLOSE |
Notifica os ouvintes que um projeto está para ser fechado. Esse evento pode ser utilizado para extrair e salvar informações necessárias das representações que estão na memória (ex.: propriedades da seção) de um projeto antes de ser fechado. (Quando um projeto for fechado, a representação que está na memória é descartada). A área de trabalho é travada (nenhum recurso pode ser atualizado) durante esse evento. O evento contém o projeto que está sendo fechado. |
PRE_DELETE |
Notifica os ouvintes que um projeto vai ser excluído. Esse evento pode ser utilizado para executar as operações de limpeza, como a remoção de qualquer estado salvo que esteja relacionado com o projeto para o diretório de seus plug-ins. O espaço de trabalho é travado (nenhum recurso pode ser atualizado) durante este evento. O evento contém o projeto que está sendo excluído. |
PRE_AUTOBUILD |
Notifica os atendentes antes de ocorrer a construção automática. Esse evento é difundido quando a plataforma detecta uma necessidade de construção automática, independente da construção automática estar ativa. O espaço de trabalho não fica travado durante esse evento (os recursos podem ser atualizados). O evento contém um delta de recursos descrevendo as alterações que ocorreram desde que o último evento POST_CHANGE foi reportado. |
POST_AUTOBUILD |
Notifica os ouvintes depois que ocorreu a construção automática. Esse evento é difundido depois da plataforma executar uma construção automática, independente da construção automática estar ativada. O espaço de trabalho não fica travado durante esse evento (os recursos podem ser atualizados). O evento contém um delta de recursos descrevendo as alterações que ocorreram desde que o último evento POST_CHANGE foi reportado. |
POST_CHANGE |
Descreve um conjunto de alterações que ocorreram na área de trabalho desde que o último evento POST_CHANGE foi reportado. É disparado após uma API de alteração de recursos ser usada individualmente ou em um conjunto de batch de alterações na área de trabalho. O disparo também é feito depois que qualquer notificação PRE_AUTOBUILD ou POST_AUTOBUILD esteja concluída. O evento contém um delta de recursos descrevendo as alterações na rede desde que o último evento POST_CHANGE. O espaço de trabalho é travado (nenhum recurso pode ser atualizado) durante este evento. |
O exemplo a seguir implementa um ouvinte de alteração de recursos com base no console. Um ouvinte de alteração de recursos é registrado para tipos específicos de eventos, e informações sobre esses eventos são impressas no 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);
O atendente verifica cada tipo de evento e faz um relatório das informações sobre os recursos que foram alterados e os tipos de alterações feitas. Apesar desse exemplo ter sido projetado para mostrar um atendente geral que identifica todos os tipos de eventos de recursos, um atendente típico registraria somente um tipo de evento.
A implementação de POST_CHANGE utiliza outra classe que pode ser utilizada para visitar as alterações no 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("Projeto "); System.out.print(res.getFullPath()); System.out.println(" está prestes a fechar."); break; case IResourceChangeEvent.PRE_DELETE: System.out.print("Projeto "); System.out.print(res.getFullPath()); System.out.println(" está prestes a ser excluído."); break; case IResourceChangeEvent.POST_CHANGE: System.out.println("Os recursos foram alterados."); event.getDelta().accept(new DeltaPrinter()); break; case IResourceChangeEvent.PRE_AUTO_BUILD: System.out.println("Construção automática prestes a ser executada."); event.getDelta().accept(new DeltaPrinter()); break; case IResourceChangeEvent.POST_AUTO_BUILD: System.out.println("Construção automática concluída."); event.getDelta().accept(new DeltaPrinter()); break; } } }
A classe DeltaPrinter implementa a interfaceIResourceDeltaVisitor para interrogar o delta de recursos. O método visit() é chamado para cada alteração de recurso no delta de recursos. O visitante utiliza um valor de retorno para indicar se os deltas para os recursos filhos devem ser visitados.
class DeltaPrinter implements IResourceDeltaVisitor { public boolean visit(IResourceDelta delta) { IResource res = delta.getResource(); switch (delta.getKind()) { case IResourceDelta.ADDED: System.out.print("O recurso "); System.out.print(res.getFullPath()); System.out.println(" foi incluído."); break; case IResourceDelta.REMOVED" System.out.print("O recurso "); System.out.print(res.getFullPath()); System.out.println(" foi removido."); break; case IResourceDelta.CHANGED: System.out.print("O recurso "); System.out.print(res.getFullPath()); System.out.println(" foi alterado."); break; } return true; // visitar os filhos } }
Mais informações podem ser obtidas no delta de recursos fornecido. O fragmento a seguir mostra como o caso IResourceDelta.CHANGED poderia ser implementado para maior descrição das alterações do recurso.
... case IResourceDelta.CHANGED: System.out.print("O recurso "); System.out.print(delta.getFullPath()); System.out.println(" foi alterado."); int flags = delta.getFlags(); if ((flags & IResourceDelta.CONTENT) != 0) { System.out.println("--> Alteração de Conteúdo"); } if ((flags & IResourceDelta.REPLACED) != 0) { System.out.println("--> Conteúdo Substituído"); } if ((flags & IResourceDelta.MARKERS) != 0) { System.out.println("--> Alteração do Marcador"); IMarkerDelta[] markers = delta.getMarkerDeltas(); // se estiver interessado em marcadores, marque esses deltas } break; ...
Para obter uma descrição completa dos deltas de recursos, visitantes, e deltas de marcadores, consulte a especificação API para IResourceDelta, IResourceDeltaVisitor e IMarkerDelta.
Nota: Os listeners de alteração de recursos são úteis para rastrear alterações que ocorrem nos recursos, enquanto o plug-in estiver ativado. Se o plug-in registrar um ouvinte de alteração de recursos durante o código de inicialização, é possível que alguns eventos de alterações de recursos tenham sido disparados antes da ativação do plug-in. O delta de recursos contido no primeiro evento de alteração de recursos recebido pelo plug-in não conterá todas as alterações feitas desde que o plug-in foi ativado pela última vez. Se precisar registrar alterações feitas entre as ativações do plug-in, você deve utilizar o suporte fornecido para salvar na área de trabalho. Isso está descrito em Participação da Área de Trabalho no Salvamento.
Nota: Alguns eventos de alteração de recurso são acionados durante o processamento que ocorre em um encadeamento de segundo plano. Os listeners de alteração de recursos devem ser protegidos de encadeamentos. Consulte Problemas de Encadeamento para obter uma discussão sobre a segurança de encadeamento com a UI.