Roteiro de Repositório para Integração de Modelo Lógico

Para fornecer suporte total para modelos lógicos, um provedor de repositório pode executar as seguintes etapas:

  1. Contribua com as operações de repositório apropriadas para os elementos que se adaptam ao ResourceMapping.
  2. Assegure-se de que as operações executadas nos mapeamentos de recursos incluam todos os elementos de modelo e recursos apropriados utilizando um ISynchronizationScope e a API de suporte.
  3. Permita que os provedores de modelo participem de mesclagens sem periféricos, por meio da interface IMergeContext e da API de suporte.
  4. Permita que os provedores de modelo participem de visualizações de mesclagem utilizando o 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.
  5. Forneça acesso ao histórico de arquivos de espaço de trabalho por meio da API IFileHistoryProvider
  6. Forneça acesso às configurações remotas utilizando a API do Sistema de Arquivo do Eclipse no plug-in org.eclipse.core.filesystem e vincule isso aos projetos de espaço de trabalho por meio do ProjectSetCapability
  7. Ofereça suporte para decoração de elemento de modelo lógico fornecendo um espaço de trabalho 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.

Contribuindo com Ações para Mapeamentos de Recurso

A API de Mapeamento de Recurso Básico

A API de mapeamento de recurso consiste nas seguintes classes:

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.

Mapeamentos de Recurso e Contribuições de Objeto

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:

  1. Atualize cada objectContributions do ponto de extensão popupMenus em seu arquivo plugin.xml para destinar o ResourceMapping em vez do IResource (para os quais isso for apropriado).
  2. Atualize suas ações para trabalhar no 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.

Escopo de 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:

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:

  1. Fornecendo um RemoteResourceMappingContext para uso ao obter passagens de recurso dos mapeamentos de recurso.
  2. Substituindo SynchronizationScopeManager para adaptar o processo de gerenciamento de escopo conforme necessário.

As duas seções a seguir descrevem esses pontos mais detalhadamente.

Contexto de Mapeamento de Recurso Remoto

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.

Subclassificando SynchronizationScopeManager

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:

  1. O provedor de repositório precisa incluir recursos adicionais devido a um relacionamento de nível de repositório (por exemplo, conjunto de alterações). Isso pode ser executado com a substituição do método adjustInputTraversals(ResourceTraversal[]).
  2. A sincronização tem um ciclo de vida mais longo (por exemplo, visualização versus diálogo Sincronizar) e precisa do potencial para reagir a alterações de escopo. A interface 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.

Mesclagem Baseada em Modelo

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.

  1. API para descrever o estado de sincronização dos recursos envolvidos na mesclagem.
  2. API para permitir que os provedores de modelo mesclem os elementos de modelo.
As seções a seguir descrevem essas duas partes.

API para Descrição do Estado de Sincronização

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.

API para Mesclagem de Modelo

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.

Conteúdo de Modelo em Visualizações de Equipe

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:

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:

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>

Histórico de Arquivo

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:

Recurso de Conjunto de Projetos

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.

Decorando Elementos de Modelo

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.