Para fornecer suporte total para modelos lógicos, um provedor de repositório pode executar as seguintes etapas:
ResourceMapping
.ISynchronizationScope
e a API de suporte.IMergeContext
e da API de
suporte.teamContentProviders
para os modelos
envolvidos na mesclagem. Uma classe ModelSynchronizeParticipant
é fornecida
para ajudar a gerenciar o relacionamento entre o conteúdo de modelo, um contexto de
mesclagem e a estrutura de Comparação.IFileHistoryProvider
ProjectSetCapability
Assinante
para uso com a API SynchronizationStateTester
API.As seções a seguir descrevem cada um desses pontos mais detalhadamente. O plug-in org.eclipse.team.examples.filesystem contém um exemplo que ilustra vários desses pontos. Você pode registrar a saída do projeto do repositório CVS e utilizá-lo como referência enquanto está lendo este tutorial. Renúncia: O código-fonte no plug-in de exemplo pode ser alterado com o tempo. Para obter uma cópia que corresponda à utilizada neste exemplo, você pode efetuar o registro de saída do projeto utilizando a marcação da versão 3.2 (muito provavelmente R3_2) ou uma marcação de data de 28 de junho de 2006.
A API de mapeamento de recurso consiste nas seguintes classes:
Object getModelObject()
: O objeto modelo do qual o mapeamento se
originou (ou foi adaptado).ResourceTraversal[] getTraversals(ResourceMappingContext,
IProgressMonitor)
: A passagem de recurso que cobre os recursos que constituem o
objeto modelo.ResourceTraversal
contém um conjunto de recursos e um sinalizador de
profundidade que indica a profundidade na qual os recursos na passagem estão associados
ao objeto modelo de origem. As passagens de recurso são fornecidas a um cliente por um
mapeamento de recurso para descrever o conteúdo de um modelo, de tal forma que o cliente
(por exemplo, um provedor de repositório) possa executar suas operações da forma mais
eficiente possível. Os métodos de interesse são: getResources()
getDepth()
ResourceMappingContext
e do RemoteResourceMappingContext
é um pouco mais complicado e é descrito posteriormente.Há dois tipos de plugins que deverão estar interessados em mapeamentos de recursos. Aqueles que fornecem um modelo que consiste, ou persiste, em recursos no espaço de trabalho e aqueles que desejam executar operações em recursos. O caso mencionado primeiro será coberto no roteiro de modelo; o último, na próxima seção.
Plug-ins que contribuem com extensões para pontos de extensão adaptáveis terão de
fazer duas alterações para suportar as novas APIs ResourceMapping
:
ResourceMapping
em vez do IResource
(para os quais isso for apropriado).ResourceMapping
em vez de no
IResource
, e respeite as restrições de profundidade fornecidas nas passagens.Plug-ins que incluem contribuições de objeto no IResource
agora também
podem incluí-las no ResourceMapping
, se a ação puder ser aplicada a
múltiplos recursos. Aqui está um snippet XML que contribui com uma ação de menu para
objetos que se adaptam a mapeamentos de recurso:
<extension point="org.eclipse.ui.popupMenus"> <objectContribution objectClass="org.eclipse.core.resources.mapping.ResourceMapping" adaptable="true" id="org.eclipse.team.ccvs.ui.ResourceMapperContributions"> <enablement>
<adapt type="org.eclipse.core.resources.mapping.ResourceMapping">
<test
property="org.eclipse.core.resources.projectPersistentProperty"
args="org.eclipse.team.core.repository,org.eclipse.team.cvs.core.cvsnature" />
</adapt>
</enablement>
<action
label="%UpdateAction.label"
definitionId="org.eclipse.team.cvs.ui.update"
class="org.eclipse.team.internal.ccvs.ui.actions.UpdateAction"
tooltip="%UpdateAction.tooltip"
menubarPath="team.main/group2"
id="org.eclipse.team.cvs.ui.update">
</action>
...
</objectContribution>
</extension>
As contribuições para ResourceMapping
se aplicarão automaticamente aos
objetos que se adaptam ao IResource
. Essa associação transitiva é tratada
pelo Ambiente de Trabalho. A filtragem das contribuições para mapeamentos de
recurso pode ser feita utilizando expressões de ativação. Uma expressão para filtragem
por propriedade de projeto persistente foi incluída para permitir que os provedores de
repositório tenham seus menus exibidos nos projetos mapeados para seus repositórios.
As ações que contribuíram para a classe ResourceMapping
receberão uma
seleção que contém um ou mais ResourceMappings
.
É de responsabilidade das ações converter o mapeamento de recurso em um conjunto de
recursos nos quais operar. Isso pode ser feito chamando getTraversals
para
obter as passagens do mapeamento. As passagens são utilizadas para permitir aos
clientes da passagem otimizar suas operações com base na profundidade dos
recursos que estão sendo transmitidos. Um cliente pode transmitir o recurso manualmente
ou pode utilizar o recurso e a profundidade como entrada em uma operação que a ação
delega para fazer o trabalho. Como exemplo, se o usuário executar uma atualização CVS em
um pacote java e o mapeamento de recurso do pacote java for mapeado para uma pasta de
profundidade um, o CVS emitirá um comando apropriado ("cvs update -l" para aqueles que
desejarem) que executará uma atualização superficial na pasta que o pacote representa.
Embora seja possível obter um conjunto de passagens diretamente dos mapeamentos de recursos selecionados, há relacionamentos de modelo (ou relacionamentos de repositório) que podem exigir a inclusão de recursos ou elementos de modelo adicionais em uma operação. A próxima seção descreve como assegurar-se de que todos os recursos necessários sejam incluídos em uma operação.
Para operações de equipe, os mapeamentos selecionados precisam ser convertidos no conjunto de mapeamentos nos quais operar. Esse processo envolve a consulta de todos os provedores de modelo para assegurar-se de que eles sejam incluídos nas operações dos recursos que correspondem a suas regras de ativação. O termo utilizado para descrever o conjunto completo de mapeamentos de recurso nos quais operar é o escopo de operação. A seguinte API foi fornecida para isso:
ISynchronizationScope
:
Interface que define a API para acessar o escopo da operação. Ela fornece acesso a
todos os mapeamentos de recurso nos quais operar e as passagens para esses mapeamentos,
conforme calculados durante o processo de criação de escopo.ISynchronizationScopeManager
:
Interface que define a API para criar e gerenciar um escopo.SynchronizationScopeManager
:
Classe extensível que fornece uma implementação padrão da API ISynchronizationScopeManager
.ModelOperation
:
Classe de operação extensível que gera um escopo utilizando um gerenciador de
escopo fornecido e avisa se recursos ou mapeamentos adicionais foram incluídos
na operação devido aos relacionamentos do provedor de modelo.O método initialize(IProgressMonitor) da classe
SynchronizationScopeManager
controla todo o processo de conversão de um
conjunto de entrada de mapeamentos de recurso no conjunto completo de mapeamentos nos
quais é necessário operar, bem como no conjunto completo de passagens que incluem esses
mapeamentos. Um provedor de repositório pode adaptar o processo da seguinte forma:
RemoteResourceMappingContext
para uso ao obter passagens
de recurso dos mapeamentos de recurso.SynchronizationScopeManager
para adaptar o processo de
gerenciamento de escopo conforme necessário.As duas seções a seguir descrevem esses pontos mais detalhadamente.
Para garantir que todos os recursos necessários sejam incluídos em uma operação de equipe, o provedor de modelo pode precisar da capacidade de ver o estado de um ou mais recursos no repositório. Para alguns modelos, isso pode não ser necessário. Por exemplo, pacote java é um contêiner visitado a uma profundidade de um, independentemente do estado remoto do modelo. Isso determinado, um provedor de repositório pode facilmente determinar que as exclusões de saída deverão ser incluídas ao confirmar ou que adições de entrada deverão ser incluídas ao atualizar. Entretanto, os recursos que constituem alguns modelos lógicos podem ser alterados além do tempo. Por exemplo, os recursos que constituem um elemento de modelo podem depender do conteúdo de um arquivo de manifesto (ou outro mecanismo semelhante). Para que o mapeamento de recurso retorne a passagem apropriada, ele deverá acessar o conteúdo remoto do arquivo de manifesto (se diferir do conteúdo local) para ver se há recursos adicionais que precisam ser incluídos. Esses recursos adicionais podem não existir no espaço de trabalho, mas o provedor de repositório saberia como certificar-se de que eles existiam quando a ação selecionada foi executada.
Para oferecer suporte a esses modelos mais complexos, um
RemoteResourceMappingContext
pode ser transmitido ao método
ResourceMapping#getTraversals
. Quando um contexto é fornecido, o mapeamento
pode utilizá-lo para assegurar-se de que todos os recursos necessários sejam incluídos na
passagem. Se um contexto não for fornecido, o mapeamento poderá assumir que apenas o
estado local é de interesse.
O contexto de mapeamento de recurso remoto fornece três consultas básicas:
A resposta à primeira pergunta anterior depende do tipo de operação que está sendo executada. Normalmente, atualizações e mesclagens são em três direções, enquanto as operações de comparação e substituição (pelo menos, para CVS) são em duas direções.
A API de Equipe do Eclipse inclui uma classe Assinante
que define uma API
para fornecer o estado de sincronização entre o espaço de trabalho local e um servidor
remoto. É fornecido um SubscriberResourceMappingContext
que utiliza um Assinante
para acessar o estado remoto necessário. Os clientes que tiverem um
Assinante
não precisarão executar nenhum trabalho adicional para obter um
contexto de mapeamento de recurso.
A classe SynchronizationScopeManager
pode ser subclassificada para
adaptar o processo de gerenciamento e geração de escopo. Os dois motivos principais para
subclassificar o gerenciador de escopo são:
ISynchronizationScopeParticipant
define a API que os provedores de modelo podem utilizar para participar do processo de
gerenciamento de escopo. A classe SubscriberScopeManager
é uma subclasse de SynchronizationScopeManager
baseada no
Assinante
que envolve os participantes do processo de gerenciamento de
escopo. Os conjuntos de trabalho são um exemplo do motivo pelo qual esse tipo de processo é necessário. Se um conjunto de trabalho for um dos mapeamentos de recurso em um escopo, o
conjunto de passagens coberto pelo escopo aumentará se recursos forem incluídos no
conjunto de trabalhos.O tipo de operação de repositório principal que exige participação de modelo é a
mesclagem. Em diversos casos, os modelos só precisam participar no nível de arquivo. Para
isso, a API IStorageMerger
foi introduzida para permitir que os provedores
de modelo contribuam com mescladores que deverão ser utilizados para mesclar arquivos de
uma determinada extensão ou tipo de conteúdo. Entretanto, em alguns casos, os
modelos podem precisar de contexto adicional para participar corretamente de uma
mesclagem. Para essa finalidade, foram introduzidas as APIs
IResourceMappingMerger
e IMergeContext
.
As operações de mesclagem são ainda acionadas pelas ações associadas a um provedor de repositório. Entretanto, depois que uma operação do tipo mesclagem é solicitada pelo usuário, o provedor de repositório precisa envolver os provedores de modelo no processo de mesclagem para garantir que a mesclagem não corrompa o modelo de alguma forma.
Há duas partes principais da API do provedor de repositório relacionadas ao suporte de mesclagem baseada em modelo.
Um aspecto importante da mesclagem baseada em modelo é a API utilizada para comunicar o estado de sincronização dos recursos envolvidos ao provedor de modelo. As interfaces a seguir são utilizadas para descrever o estado de sincronização:
Classes abstratas são fornecidas para todas as interfaces com a convenção que os nomes
de classe correspondem aos nomes de interface com o prefixo "I" removido. A única classe
que os provedores de repositório devem substituir é a classe ResourceDiff
para que as revisões apropriadas de arquivo anterior e posterior possam ser fornecidas.
A interface IMergeContext estende o contexto de sincronização com métodos adicionais que suportam mesclagem. Existem métodos de retorno de chamada para:
É fornecida uma classe MergeContext abstrata que contém implementações padrão para grande parte do comportamento de mesclagem, além de utilizar o IStorageMerger para executar mesclagens em três direções. É fornecida também uma classe SubscriberMergeContext que controla o preenchimento e a manutenção da descrição do estado de sincronização associado ao contexto de mesclagem.
É fornecida uma classe de operação, ModelMergeOperation,
que utiliza a API IResourceMappingMerger
para executar uma operação de
mesclagem baseada em modelo. As subclasses precisam substituir o método
initializeContext(IProgressMonitor)
para retornar um contexto de mesclagem. A
operação utiliza esse contexto para tentar uma mesclagem baseada em modelo e sem periféricos. Se
houver conflito, a visualização da mesclagem será deixada para a subclasse. Como veremos
na próxima seção, há um ModelParticipantMergeOperation
que fornece recursos de visualização utilizando um ModelSynchronizeParticipant.
O suporte para a exibição de modelos lógicos em uma operação de equipe é fornecido
utilizando a estrutura de Navegador Comum que foi introduzida no Eclipse 3.2. Os
modelos lógicos podem associar uma extensão de conteúdo a um provedor de modelo
utilizando o ponto de extensão org.eclipse.team.ui.teamContentProvider. Os
provedores de equipe acessam esses provedores de conteúdo por meio do
ITeamContentProviderManager
.
Há vários locais onde um provedor de equipe pode desejar exibir modelos lógicos:
ModelOperation
fornece um aviso que utiliza os
provedores de conteúdo de equipe registrados para informar o usuário de uma expansão de
escopo.O ModelSynchronizeParticipant
fornece integração na visualização
Sincronizar ou em qualquer contêiner que possa exibir iSynchronizePages
.
O participante faz uso dos recursos de participante de sincronização pré-existente e de
Navegador Comum para permitir que provedores de equipe e modelos adaptem a barra de
ferramentas, o menu de contexto e os outros aspectos da visualização de mesclagem. O
ModelSynchronizeParticipant
fornece o seguinte:
Aqui está uma lista de verificação das etapas de adaptação de um participante de sincronização de modelo para um determinado provedor de Equipe:
ModelSynchronizeParticipant
ISynchronizePageConfiguration.P_VIEWER_ID
como o id do
visualizador especificado na etapa anterior.MergeActionGroup
para adaptar a aparência das ações relacionadas a
mesclagem.ModelParticipantMergeOperation
para
manipular a transição de uma mesclagem baseada em modelo para uma visualização em um
diálogo ou na visualização Sincronizar.Os seguintes snipets XML ilustram como a classe de participante CVS é registrada e como seu visualizador é definido.
<extension point="org.eclipse.team.ui.synchronizeParticipants"> <participant name="CVS" icon="$nl$/icons/full/eview16/cvs_persp.gif" class="org.eclipse.team.internal.ccvs.ui.mappings.WorkspaceModelParticipant" id="org.eclipse.team.cvs.ui.workspace-participant"> </participant> </extension> <extension point="org.eclipse.ui.navigator.viewer"> <viewer viewerId="org.eclipse.team.cvs.ui.workspaceSynchronization"> <popupMenu allowsPlatformContributions="false" id="org.eclipse.team.cvs.ui.workspaceSynchronizationMenu"> <insertionPoint name="file"/> <insertionPoint name="edit" separator="true"/> <insertionPoint name="synchronize"/> <insertionPoint name="navigate" separator="true"/> <insertionPoint name="update" separator="true"/> <insertionPoint name="commit" separator="false"/> <insertionPoint name="overrideActions" separator="true"/> <insertionPoint name="otherActions1" separator="true"/> <insertionPoint name="otherActions2" separator="true"/> <insertionPoint name="sort" separator="true"/> <insertionPoint name="additions" separator="true"/> <insertionPoint name="properties" separator="true"/> </popupMenu> </viewer> </extension>
Uma API de histórico de arquivo foi incluída para permitir que os modelos acessem o histórico de arquivos. A API do histórico de arquivos consiste nas seguintes interfaces:
Junto com essa API, uma visualização de Histórico de arquivo genérica foi incluída. Isso permitirá que os provedores de Equipe exibam seu histórico de arquivo/recurso em uma visualização compartilhada, além de permitir que os modelos exibam o histórico de elementos de modelo para elementos que não são mapeados diretamente para arquivos. A visualização de Histórico é do tipo baseada em página, que obtém uma página para o elemento selecionado da seguinte maneira:
RepositoryProvider
associado ao projeto que contém o recurso para um IHistoryPageSource.
IHistoryPageSource
.Foram incluídos métodos no ProjectSetCapability
para suportar a conversão entre uma cadeia de referência utilizada para identificar um
mapeamento entre um projeto e o conteúdo remoto e os URIs que identificam um esquema de
sistema de arquivo registrado no ponto de extensão org.eclipse.core.filesystem.filesystems. Os
provedores de equipe podem opcionalmente fornecer suporte para isso para permitir que
os modelos lógicos executem navegação remota e carregamento de projeto.
Provedores de equipe podem decorar elementos de modelo convertendo seus decoradores leves para trabalhar em mapeamentos de recurso, da mesma maneira que contribuições de objeto são convertidos para trabalhar em mapeamentos de recurso. Entretanto, há um aspecto da decoração de elemento de modelo lógico que é problemático. Se um elemento de modelo não tiver um mapeamento direto para um recurso, ele poderá não receber uma atualização de rótulo quando os recursos subjacentes forem alterados.
Para tratar esse problema, o ITeamStateProvider
foi introduzido a fim de dar aos provedores de modelo acesso a alterações de estado que
podem afetar decorações de equipe. Além disso, visualizações de modelo podem utilizar um SynchronizationStateTester
para determinar quando os rótulos de elementos de modelo lógico precisam ser
atualizados. Essa API conta com a interface ITeamStateProvider
para
determinar quando o estado de equipe do recurso foi alterado e pode ser
transmitido a um decorador de equipe como parte de um IDecorationContext
.