Fornecedores de repositórios

Um fornecedor de repositórios (RepositoryProvider) é a classe central na implementação do repositório.  Esta classe é responsável por configurar um projecto para gestão de repositórios e por facultar os ganchos necessários para modificação de recursos.  Os fornecedor são correlacionados com um projecto através das propriedades persistentes do projecto. O mecanismo para correlacionar fornecedor com um projecto não é central à API de equipa, mas será útil tê-lo em mente quando filtrar recursos na UI.  Regra geral, irá utilizar a API de equipa para trabalhar com projectos e associá-los ao seu fornecedor.   

Para implementar um fornecedor, é necessário definir um repositório com org.eclipse.team.core.repository e facultar a classe derivada de   RepositoryProvider.  Vamos usar o cliente CVS como exemplo para ver como isto funciona.

Ponto de extensão

O ponto de extensão org.eclipse.team.core.repository é utilizado para adicionar uma definição de repositório.   De seguida é apresentada a marcação para o cliente CVS.

<extension
point="org.eclipse.team.core.repository">
<repository
class="org.eclipse.team.internal.ccvs.core.CVSTeamProvider"
id="org.eclipse.team.cvs.core.cvsprovider">
</repository>
</extension>

Isto regista o fornecedor de equipa junto do plug-in de suporte de equipa e atribui um ID que deve ser usado quando o fornecedor for associado a um projecto.   A classe especificada para o repositório deve estender RepositoryProvider.

Implementar um RepositoryProvider

A classe identificada na extensão deve ser subclasse de RepositoryProvider. As suas principais responsabilidades são configurar e desconfigurar um projecto para suporte de repositórios, e fornecer os ganchos de modificação de recursos necessários.   O cliente CVS serve de bom exemplo.  O seu fornecedor de repositórios é CVSTeamProvider.

public class CVSTeamProvider extends RepositoryProvider {
...

RepositoryProvider define dois métodos abstractos, configureProject e deconfigure.  Todos os fornecedores devem implementar estes métodos.  

Um projecto é configurado quando for primeiro associado a determinado fornecedor de repositórios.  Tal acontece regra geral quando o utilizador selecciona um projecto e utiliza os assistentes de equipa para associar um projecto ao nosso repositório. Seja como for a operação desencadeada, trata-se do momento apropriado para calcular ou colocar na cache dados sobre o projecto que seja preciso facultar às funcionalidades do repositório.   (Parta do princípio de que já ocorreu a correlação do projecto com o seu fornecedor.  Será no assistente de configuração que isto se processa.)

O fornecedor CVS simplesmente difunde o facto de que um projecto foi configurado:

public void configureProject() throws CoreException {
CVSProviderPlugin.broadcastProjectConfigured(getProject());
}

Não vamos seguir a implementação do mecanismo de difusão do plug-in.  Basta dizer que as partes que precisarem de calcular ou inicializar dados específicos de projecto o podem fazer nesta altura.

Um projecto é desconfigurado quando o utilizador já não pretende associar um fornecedor de equipa ao projecto.   Compete ao plug-in implementar a acção de utilizador que faz com que isto aconteça (e a descorrelação do projecto do fornecedor de equipa acontece aqui).  O método deconfigure   é o momento apropriado para eliminar memórias cache relacionadas com projectos ou remover referências ao projecto na UI.  O fornecedor CVS esvazia memórias cache relacionadas com projectos mantidas nas suas vistas e difunde o facto de o projecto estar desconfigurado.

public void deconfigure() throws CoreException {
...
try {
EclipseSynchronizer.getInstance().flush(getProject(), true, true /*flush deep*/, null);
} catch(CVSException e) {
throw new CoreException(e.getStatus());
} finally {
CVSProviderPlugin.broadcastProjectDeconfigured(getProject());
}
}

Configurar um projecto

Regra geral, o primeiro passo na construção de uma UI de equipa consiste em implementar uma página assistente que permita aos utilizadores configurar um projecto para o suporte de equipa do plug-in.  É aqui que o ID do fornecedor de equipa é adicionado às propriedades do projecto.  Participa-se na configuração de projectos contribuíndo para o ponto de extensão org.eclipse.team.ui.configurationWizards.  Este assistente é apresentado quando o utilizador escolhe Equipa.>Partilhar Projecto...

Veremos isto no contexto da implementação do cliente CVS.   De seguida é apresentada a marcação da UI CVS para o respectivo assistente de configuração:

<extension
point="org.eclipse.team.ui.configurationWizards">
<wizard
name="%SharingWizard.name"
icon="icons/full/wizards/newconnect_wiz.png"
class="org.eclipse.team.internal.ccvs.ui.wizards.SharingWizard"
id="org.eclipse.team.ccvs.ui.SharingWizard">
</wizard>
</extension>

Como de costume, os plug-ins facultam uma classe que implementa a extensão e um ID único para identificar a respectiva extensão.  O nome e o ícone são mostrados na primeira página do assistente de configuração do projecto se houver vários fornecedores por onde escolher.

Uma vez que o utilizador tenha seleccionado um fornecedor, a página seguinte mostra as informações específicas de configuração do fornecedor.   (Se o fornecedor for o único plug-in de fornecedor de equipa instalado, o assistente salta directamente para a sua página.) O assistente deve implementar IConfigurationWizard, o qual inicializa o assistente para uma área de trabalho e um projecto especificados.  O resto da implementação depende da concepção do assistente. É necessário recolher informações necessárias para associar o projecto ao suporte de equipa.

Quando o assistente estiver concluído, terá de correlacionar o fornecedor de equipa com o projecto através de RepositoryProvider.map(IProject, String). A correlação processa a atribuição da propriedade persistente de projecto correcta ao seu projecto.

O cliente CVS encarrega-se disto no método setSharing do seu fornecedor, o qual é chamado quando o respectivo assistente estiver terminado:

public void setSharing(IProject project, FolderSyncInfo info, IProgressMonitor monitor) throws TeamException {

// Ensure provided info matches that of the project
...
// Ensure that the provided location is managed
...
// Register the project with Team
RepositoryProvider.map(project, CVSProviderPlugin.getTypeId());
}

Localizar um fornecedor

Os métodos estáticos em RepositoryProvider facilitam aos clientes correlacionarem projectos com fornecedores e localizar os fornecedores associados a dado projecto.

Fornecedores de Repositórios e Capacidades

Se um produto optar por adicionar um plug-in de Repositório a uma capacidade, deverá associar a capacidade ao ID do repositório. Seguem-se dois passos a tomar para activar um RepositoryProvider como capacidade:

  1. Associe a capacidade ao ID do fornecedor de repositórios. Isto permite ao plug-in de Equipa activar/desactivar com base nos IDs de fornecedores de repositórios.
    <activityPatternBinding
        activityId="org.eclipse.team.cvs"
        pattern="org\.eclipse\.team\.cvs\.core/.*cvsnature">
    </activityPatternBinding>
  2. Em seguida, associe a capacidade a todos os pacotes da UI relativos ao fornecedor:
    <activityPatternBinding
         activityId="org.eclipse.team.cvs"
         pattern="org\.eclipse\.team\.cvs\.ui/.*">
    </activityPatternBinding>

Há dois pontos activadores de capacidades definidos pelos plug-ins de Equipa. O primeiro é o assistente Equipa > Partilhar Projecto..., o qual permite filtragem de fornecedores de repositórios com base no estado activado/desactivado das capacidades da área de trabalho, e o outros é o activador de activação automática do plug-in de Equipa.

Ganchos de modificação de recursos

A maioria das funcionalidades interessantes associadas a um fornecedor de repositórios ocorre à medida que o utilizador trabalha com recursos no projecto que estiver configurado para o fornecedor.  Para poder ter em mente as alterações que o utilizador realiza a um recurso, o fornecedor pode implementar ganchos de modificação de recursos. O plug-in de recursos faculta estes ganchos como pontos de extensão.  A documentação para IMoveDeleteHook, IFileModificationValidator e ResourceRuleFactory descreve os detalhes da implementação destes ganchos.

O plug-in de equipa optimiza e simplifica a associação do gancho com recursos apropriados mediante registo de ganchos genéricos junto do plug-in de recursos.  Estes ganchos genéricos buscam simplesmente no fornecedor de repositórios determinado recursos e obtêm o respectivo gancho.  Isto tem a vantagem de chamar somente um gancho de fornecedor em vez de ter cada implementação de fornecedor a registar um gancho que primeiro deve verificar se o recurso é gerido pelo fornecedor ou não.

Isto significa para o plug-in que se faculta os ganchos necessários mediante sobreposição de métodos em RepositoryProvider.  A implementação predefinida destes métodos responde nulo, indicando que não é necessário gancho algum (salvo para a fábrica de regras de recursos, como se descreve a seguir).