Dostawca repozytorium (RepositoryProvider) to centralna klasa w implementacji repozytorium. Klasa ta jest odpowiedzialna za konfigurowanie projektu na potrzeby zarządzania repozytorium i udostępnianie haków dla modyfikacji zasobów. Dostawcy są odwzorowywani na projekt przy użyciu trwałych właściwości projektu. Mechanizm odwzorowania dostawców na projekt nie leży w centrum interfejsu API zespołu, ale trzeba zdawać sobie sprawę z jego istnienia podczas filtrowania zasobów w interfejsie użytkownika. Do pracy z projektami i wiązania ich z dostawcą używany będzie przeważnie interfejs API zespołu.
Aby zaimplementować dostawcę, należy zdefiniować repozytorium przy użyciu punktu rozszerzenia org.eclipse.team.core.repository i dostarczyć klasę utworzoną na podstawie klasy RepositoryProvider. Sposób działania zostanie przedstawiony na przykładzie klienta CVS.
Punkt rozszerzenia org.eclipse.team.core.repository służy do dodawania definicji repozytorium. Oto kod znaczników dla klienta 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>
Powyższy fragment rejestruje dostawcę zespołowego w module dodatkowym wsparcia dla zespołu i przypisuje mu identyfikator, który powinien być używany, gdy dostawca zostanie powiązany z projektem. Klasa class określona dla repozytorium musi rozszerzać klasę RepositoryProvider.
Klasa identyfikowana w rozszerzeniu musi być podklasą klasy RepositoryProvider. Jej głównym zadaniem jest konfigurowanie i dekonfigurowanie projektu do obsługi repozytorium i dostarczanie haków niezbędnych do modyfikacji zasobów. Dobrym przykładem jest tutaj klient CVS. Jego dostawcą repozytorium jest klasa CVSTeamProvider.
public class CVSTeamProvider extends RepositoryProvider {
...
Klasa RepositoryProvider definiuje dwie metody abstrakcyjne: configureProject i deconfigure. Metody te muszą być implementowane przez wszystkich dostawców.
Projekt jest konfigurowany w momencie, gdy jest po raz pierwszy wiązany z konkretnym dostawcą repozytorium. Zwykle ma to miejsce wtedy, gdy użytkownik wybiera projekt i używa kreatora zespołowego, aby powiązać projekt z repozytorium. Niezależnie od tego, jak ta operacja jest wyzwalana, jest to odpowiedni moment do wyliczenia lub zapisania w pamięci podręcznej wszelkich danych dotyczących projektu, które trzeba udostępnić funkcji repozytorium. Zakłada się przy tym, że odwzorowanie projektu na dostawcę już się odbyło. Należy się tym zająć w kreatorze konfiguracji.
Dostawca CVS po prostu rozgłasza fakt, że projekt został skonfigurowany:
public void configureProject() throws CoreException {
CVSProviderPlugin.broadcastProjectConfigured(getProject());
}
Implementacja mechanizmu rozgłaszania modułu dodatkowego nie będzie tutaj omawiana. Wystarczy wspomnieć, że wszystkie elementy, które muszą obliczyć lub zainicjować dane właściwe dla projektu, mogą to zrobić w tym momencie.
Projekt jest dekonfigurowany, gdy użytkownik nie chce już utrzymywać powiązania dostawcy zespołowego z projektem. Do modułu dodatkowego należy implementacja akcji użytkownika, która będzie to powodować (wtedy również usunięte zostanie odwzorowanie projektu na dostawcę zespołowego). Wykonywanie metody deconfigure to odpowiedni moment na skasowanie wszelkich pamięci podręcznych dotyczących projektu oraz usunięcie wszelkich odwołań do projektu w interfejsie użytkownika. Dostawca CVS opróżnia pamięci podręczne dotyczące projektu utrzymywane w widokach projektu oraz rozgłasza fakt, że projekt został zdekonfigurowany.
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());
}
}
Pierwszym krokiem podczas budowania interfejsu użytkownika dla zespołu jest najczęściej zaimplementowanie strony kreatora, która umożliwia użytkownikom skonfigurowanie projektu na potrzeby wsparcia dla zespołów w module dodatkowym. W tym miejscu właśnie do właściwości projektu zostanie dodany identyfikator dostawcy zespołowego. Uczestnictwo w konfigurowaniu projektu polega na dodawaniu elementów w punkcie rozszerzenia org.eclipse.team.ui.configurationWizards. Kreator ten jest wyświetlany, gdy użytkownik wybierze kolejno opcje: Zespół->Współużytkuj projekt.
Warto się temu przyjrzeć w kontekście implementacji klienta CVS. Oto kod znaczników kreatora konfiguracji w interfejsie użytkownika CVS:
<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>
Jak zwykle moduł dodatkowy udostępnia klasę class, która implementuje rozszerzenie, oraz unikalny identyfikator id, identyfikujący rozszerzenie. Parametry name i icon są wyświetlane na pierwszej stronie kreatora konfiguracji projektu, gdy do wyboru jest kilku dostawców.
Po wybraniu przez użytkownika dostawcy na następnej stronie wyświetlane są informacje konfiguracyjne dla danego dostawcy. Gdy dany dostawca jest jedynym zainstalowanym modułem dodatkowym dostawcy zespołowego, kreator przejdzie bezpośrednio na tę stronę. Używany kreator musi implementować interfejs IConfigurationWizard, który inicjuje kreatora dla określonego środowiska roboczego i projektu. Pozostała część implementacji zależy od projektu kreatora. Musi ona umożliwiać zebranie wszelkich informacji, które są potrzebne do powiązania projektu z funkcjami wsparcia dla zespołów.
Po zakończeniu działania kreatora konieczne jest odwzorowanie dostawcy zespołowego na projekt przy użyciu metody RepositoryProvider.map(IProject, String). Odwzorowanie obsługuje przypisanie poprawnej trwałej właściwości do projektu.
Klient CVS wykonuje tę pracę w metodzie setSharing swojego dostawcy, która jest wywoływana po zakończeniu działania kreatora:
public void setSharing(IProject project, FolderSyncInfo info, IProgressMonitor monitor) throws TeamException {
// Dostarczone informacje muszą być zgodne z informacjami o projekcie
...
// Dostarczone położenie musi być obsługiwane
...
// Zarejestruj projekt w menu Zespół
RepositoryProvider.map(project, CVSProviderPlugin.getTypeId());
}
Metody statyczne w klasie RepositoryProvider ułatwiają klientom odwzorowanie projektów na dostawców i znajdowanie dostawców powiązanych z danym projektem.
Gdy produkt dodaje moduł dodatkowy repozytorium do możliwości, powinien powiązać możliwość z identyfikatorem repozytorium. Oto dwa kroki, które należy wykonać, aby włączyć klasę RepositoryProvider jako możliwość:
<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>
Moduły dodatkowe zespołu definiują dwa punkty wyzwalania możliwości. Pierwszy to kreator Zespół > Współużytkuj projekt, który umożliwia filtrowanie dostawców repozytorium na podstawie stanu włączony/wyłączony możliwości środowiska roboczego, a druga to automatycznie włączany wyzwalacz modułu dodatkowego zespołu.
Większość interesujących funkcji powiązanych z dostawcą repozytorium jest dostępnych, gdy użytkownik pracuje z zasobami w projekcie, który jest skonfigurowany dla tego dostawcy. Aby mieć informacje o zmianach zasobu wprowadzanych przez użytkownika, dostawca może implementować haki modyfikowania zasobów. Moduł dodatkowy zasobów udostępnia te haki jako punkty rozszerzeń. Szczegóły implementacji tych haków opisano w dokumentacji interfejsów IMoveDeleteHook, IFileModificationValidator i ResourceRuleFactory.
Moduł dodatkowy zespołu optymalizuje i upraszcza powiązanie haku z odpowiednimi zasobami, rejestrując haki ogólne wraz z modułem dodatkowym zasobów. Te haki ogólne po prostu wyszukują dany zasób w dostawcy repozytorium i uzyskują hak tego zasobu. Zaletą jest występowanie wywołania tylko jednego haku dostawcy. W przeciwnym razie każda implementacja dostawcy musiałaby rejestrować hak, który sprawdzałby najpierw, czy zasób jest zarządzany przez tego dostawcę.
Dla modułu dodatkowego oznacza to, że wszelkie niezbędne haki są mu udostępniane przez przesłonięcie metod w klasie RepositoryProvider. Domyślna implementacja tych metod zwraca wartość NULL, która wskazuje, że żaden hak nie jest potrzebny (oprócz fabryki reguł zasobu, zgodnie z poniższym opisem):