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.
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.
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());
}
}
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());
}
Os métodos estáticos em RepositoryProvider facilitam aos clientes correlacionarem projectos com fornecedores e localizar os fornecedores associados a dado projecto.
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:
<activityPatternBinding
activityId="org.eclipse.team.cvs"
pattern="org\.eclipse\.team\.cvs\.core/.*cvsnature">
</activityPatternBinding>
<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.
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).