Sabemos que os plug-ins podem definir extensões de arquivos e editores de contribuição especializados que fornecem recursos de edição especiais destes tipos de arquivos. Durante a edição (ou construção) de um recurso, um plug-in pode precisar de recursos de marcação para comunicar problemas ou outras informações ao usuário. O mecanismo marcador de recurso é utilizado para gerenciar esse tipo de informação.
Um marcador é como uma nota tipo barra amarela aderida a um recurso. Em um marcador é possível gravar informações sobre um problema (ex.: localização, severidade) ou uma tarefa a ser executada. Ou é possível simplesmente gravar uma localização para um marcador como marcador.
Os usuários podem pular rapidamente para a localização marcada dentro de um recurso. A UI do workbench suporta apresentações de marcadores e de ponto de interrupção, tarefas e problemas ao lado do editor. Esses marcadores também são mostrados como itens em exibições, como a exibição de tarefas ou marcadores.
Os recursos de API de plataforma definem os métodos para criar marcadores, definir valores de marcador e aumentar a plataforma com novos tipos de marcadores. Enquanto a plataforma gerencia marcadores, são os plug-ins que controlam sua criação, remoção e valores do atributo.
Os marcadores são objetos pequenos e leves. Poderiam haver centenas e até mesmo milhares de marcadores em um único projeto. Por exemplo, o compilador Java utiliza um marcador para indicar cada problema que encontra no código fonte.
A plataforma descartará marcadores anexados aos recursos que são excluídos, mas os plug-ins são responsáveis pela remoção dos marcadores stale quando não são mais aplicados a um recurso que ainda existe.
A manipulação de um marcador é similar à manipulação de um recurso. Os marcadores são objetos identificadores. É possível obter um indicador de marcador a partir de um recurso, mas você não sabe se ele existe atualmente até que utilize o protocolo existente() ou, por outro lado, tente manipulá-lo. Assim que estabelecer que um marcador existe, é possível localizar o recurso ao qual ele pertence; consulte seu id, ou consulte atributos nomeados que podem ter sido atribuído a ele.
Os marcadores pertencem e são gerenciados pela plataforma, que oferece marcadores persistentes e notifica atendentes conforme os marcadores são incluídos, excluídos ou alterados. Os plug-ins são responsáveis pela criação de qualquer marcador necessário, alterando seus atributos e removendo-os quando não forem mais necessários.
Os marcadores não são criados diretamente utilizando um construtor. Eles são criados utilizando um método de fábrica (IResource.createMarker()) no recurso associado.
IMarker marker = file.createMarker(IMarker.TASK);
Para criar um marcador que possua escopo global (não associado a qualquer recurso específico), é possível utilizar a raiz da área de trabalho (IWorkspace.getRoot()) como recurso.
O código para excluir um marcador é straightforward.
try {
marker.delete();
} catch (CoreException e) {
// Há algo errado
}
Quando um marcador é excluído, seu objeto do marcador (identificador) torna-se"stale." Os plug-ins devem utilizar o protocolo IMarker.exists() para certificar-se de que um objeto marcador ainda é válido.
Os marcadores podem ser excluídos no batch perguntando se os marcadores de um recurso serão excluídos. Esse método é útil quando remover muitos marcadores de uma vez ou se referências do marcador individual ou ids não estão disponíveis.
int depth = IResource.DEPTH_INFINITE;
try {
resource.deleteMarkers(IMarker.PROBLEM, true, depth);
} catch (CoreException e) {
// há algo errado
}
Quando excluir um grupo de marcadores, você especifica um tipo de marcador para excluir, como IMarker.PROBLEM, ou nulo para excluir todos os marcadores. O segundo argumento indica se deseja excluir marcadores de subtipo. (Veremos subtipos no momento em que definimos novos tipos de marcadores.) O argumento profundidade controla a profundidade da exclusão.
É possível também excluir marcadores utilizando deleteMarkers(IMarker []).
Dando um marcador, é possível solicitar seu recurso associados, seu id (único relativo àquele recurso) e seu tipo. É possível também acessar informações adicionais via atributos genéricos.
Cada tipo de marcador possui um conjunto específico de atributos que são definidos pelo criador do tipo de marcador utilizando convenções de nomes. A interface IMarker define um conjunto de constantes contendo os nomes do atributo padrão (e alguns dos valores esperados) para os tipos de marcador de plataforma. O método a seguir manipula atributos utilizando as constantes da plataforma.
IMarker marker = file.createMarker(IMarker.TASK);
se (marker.exists())
try {
marker.setAttribute(IMarker.MESSAGE, "Uma mensagem de marcador de amostra");
marker.setAttribute(IMarker.PRIORITY,
IMarker.PRIORITY_HIGH);
} catch (CoreException e) {
// Você precisa identificar o caso onde o recurso não existe
}
Os atributos são mantidos genericamente como pares de nome/valor, onde os nomes são cadeias e um valor pode ser qualquer um dos tipos de valores suportados (boleano, inteiro, cadeia). A limitação nos tipos de valor permite que a plataforma preserve os valores rápida e simplificadamente.
Os recursos podem ser consultados pelos seus marcadores e pelos marcadores dos filhos. Por exemplo, consultar a raiz da área de trabalho com profundidade infinita, considera todos os marcadores na área de trabalho.
IMarker[] problems = null;
int depth = IResource.DEPTH_INFINITE;
try {
problems = resource.findMarkers(IMarker.PROBLEM, true, depth);
} catch (CoreException e) {
// há algo errado
}
O resultado exibido pelo findMarkers depende dos argumentos passados. No fragmento acima, procuramos todos os marcadores de tipo PROBLEMA que aparecem no recurso e todos os seus descendentes diretos e indiretos.
Se você passar nulo como o tipo de marcador, você obterá todos os tipos de marcadores associados ao recurso. O segundo argumento especifica se deseja ver os filhos do recurso. O argumento profundidade controla a profundidade da busca quando estiver procurando os filhos do recurso. A profundidade pode ser DEPTH_ZERO (somente o recurso informado), DEPTH_ONE (os recurso e todos os seus filhos diretos) ou DEPTH_INFINITE (os recursos e todos os seus descendentes diretos e indiretos).
Os marcadores padrão da plataforma (tarefa, problema e marcador) são persistentes. Isso significa que seus estados serão salvos no encerramento e na inicialização da área de trabalho.
Novos tipos de marcadores declarados pelos plug-ins não são persistentes, a não ser que sejam declarados como tal.
Os plug-ins podem declarar seus próprios tipos de marcadores utilizando o ponto de extensão org.eclipse.core.resources.markers. Os tipos de marcador padrão para problemas, tarefas e marcadores são declarados pela plataforma na marcação do plug-in dos recursos.
<extension
id="problemmarker"
point="org.eclipse.core.resources.markers"
name="%problemName">
<super type="org.eclipse.core.resources.marker"/>
<persistent value="true"/>
<attribute name="severity"/>
<attribute name="message"/>
<attribute name="location"/>
</extension>
<extension
id="taskmarker"
point="org.eclipse.core.resources.markers"
name="%taskName">
<super type="org.eclipse.core.resources.marker"/>
<persistent value="true"/>
<attribute name="priority"/>
<attribute name="message"/>
<attribute name="done"/>
</extension>
<extension
id="bookmark"
point="org.eclipse.core.resources.markers"
name="%bookmarkName">
<super type="org.eclipse.core.resources.marker"/>
<persistent value="true"/>
<attribute name="message"/>
<attribute name="location"/>
</extension>
Novos tipos de marcadores são derivados de marcadores existentes utilizando herança múltipla. Novos tipos de marcadores herdam todos os atributos de seus super tipos e incluem qualquer novo atributo definido como parte da declaração. Eles também herdam transitivamente atributos de super tipos dos seus super tipos. A marcação a seguir define um novo tipo de marcador em um plug-in hipotético com.example.markers.
<extension
id="mymarker"
point="org.eclipse.core.resources.markers" />
<extension
id="myproblem"
point="org.eclipse.core.resources.markers">
<super type="org.eclipse.core.resources.problemmarker"
/>
<super type="com.example.markers.mymarker"
/>
<attribute name="myAttribute" />
<persistent value="true" />
</extension>
Observe que o tipo org.eclipse.core.resources.problemmarker é atualmente um dos tipos pré-definidos (aka IMarker.PROBLEM).
O único aspecto de um marcador super tipo que não é herdade é seu flag persistência. O valor padrão para persistência é falso, então qualquer tipo de marcador que deveria ser persistente deve especificar <persistent value="true"/>.
Depois de declarar o novo tipo de marcador no arquivo de manifest de plug-in, é possível criar ocorrências de tipo de marcador com.example.markers.myproblem e definir livremente o atributo myAttribute.
A declaração de novos atributos permite que você associe dados a marcadores que planeja utilizar em qualquer outro lugar (nas exibições e editores). Os marcadores de um tipo determinado não têm que ter valores para todos os atributos declarados. As declarações de atributo são mais para resolver problemas de convenções de nomenclatura (para todos usarem"mensagem" para falar sobre uma descrição de marcador) que para limitar conteúdo.
public IMarker createMyMarker(IResource resource) {
try {
IMarker marker = resource.createMarker("com.example.markers.myproblem");
marker.setAttribute("myAttribute", "MYVALUE");
return marker;
} catch (CoreException e) {
// É necessário identificar os caso onde o valor do atributo é rejeitado
}
}
É possível consultar seus próprios tipos de marcador da mesma forma que consulta os tipos de marcador de plataforma. O método abaixo localiza todos os mymarkers associados ao recurso de destino informado e todos os seus descendentes. Observe que isso localizará também todos osmyproblems desde que verdadeiro for passado para o argumento includeSubtypes.
public IMarker[] findMyMarkers(IResource target) {
String type = "com.example.markers.mymarker";
IMarker[] markers = target.findMarkers(type, true,
IResource.DEPTH_INFINITE);
}