Následuje přehled možností, v rámci nichž mohou poskytovatelé modulů využít podpory logických modelů týmu:
Každý z těchto bodů je podrobněji popsán v následujících oddílech. Modul plug-in org.eclipse.team.examples.filesystem obsahuje příklad, který ilustruje několik těchto bodů. Při čtení tohoto návodu můžete přezkoušet projekt z úložiště CVS a použít jej jako odkaz. Bez záruky: Zdrojový kód v ukázkových modulech plug-in se může časem měnit. Chcete-li získat kód reflektující vše, co je použito v tomto příkladu, můžete si zapůjčit projekt za použití značky verze 3.2 (nejpravděpodobněji R3_2) nebo značky data 28. června 2006.
Rozhraní API mapování prostředků je záměrně jednoduché a jsou v něm vynechány manipulace s logickými modely. Toto rozhraní neumožňuje klientovi zobrazovat logické modely ani o nich získávat další zajímavé poznatky. Účelem tohoto rozhraní je pouze mapovat jeden nebo více prvků modelů na prostředky pracovního prostoru.
Rozhraní API se skládá z následujících tříd:
Object getModelObject()
: Modelový objekt, ze kterého bylo mapování odvozeno (nebo adaptováno).ResourceTraversal[]
getTraversals(ResourceMappingContext, IProgressMonitor)
: Průchod prostředku pokrývající prostředky, které tvoří modelový objekt.ResourceTraversal
obsahuje soubor prostředků a příznak hloubky udávající míru, do jaké jsou prostředky v průchodu asociovány s původním modelovým objektem. Průchody prostředků jsou poskytovány klientu prostřednictvím mapování prostředků za účelem popsání obsahu modelu takovým způsobem, aby mohl klient (např. poskytovatel úložiště) provádět své operace co možná nejefektivněji. Zkoumané metody jsou:
getResources()
getDepth()
ResourceMappingContext
a RemoteResourceMappingContext
je poněkud komplikovanější a je popsáno v oddílu Kontext mapování prostředků.Existují dva typy modulů plug-in, které by měly být středem zájmu v mapování prostředků. Moduly poskytující model, který se skládá z nebo je obsažen v prostředcích v pracovním prostoru a moduly, které provádějí operace na prostředcích. První typ je popsán v následujícím oddílu, zatímco druhý typ je popsán v oddílu Orientační plán úložiště pro integraci logických modelů.
Moduly plug-in, které přizpůsobily své modelové objekty na IResource
s cílem zobrazit akce specifické pro prostředky v kontextové nabídce mohou nyní adaptovat objekty na ResourceMapping
, pokud je žádoucí bohatší popis adaptace objektu na prostředky. Není to ovšem nezbytně nutné, pokud by to nepředstavovalo žádoucí přínos. Například kompilační jednotka Java (tj. soubor *.java zobrazený v pohledu JDT), která se momentálně adaptuje na IFile
se nemusí přizpůsobit na ResourceMapping
, protože to s sebou nepřinese žádné výhody. Balíček Java by se nicméně měl přizpůsobit na ResourceMapping
, aby indikoval, že se balíček skládá pouze ze souborů v příslušné složce, a nikoli v podsložkách.
Preferovaným způsobem adaptace prvků modelů na mapování prvků je použít továrnu na adaptéry. Následuje markup XML pro přidání továrny na adaptéry do manifestu modulu plug-in.
<extension
point="org.eclipse.core.runtime.adapters">
<factory
class="org.eclipse.example.library.logical.AdapterFactory"
adaptableType="org.eclipse.example.library.Book">
<adapter type="org.eclipse.core.resources.mapping.ResourceMapping"/>
</factory>
<factory
class="org.eclipse.example.library.logical.AdapterFactory"
adaptableType="org.eclipse.example.library.Library">
<adapter type="org.eclipse.core.resources.mapping.ResourceMapping"/>
</factory>
...
</extension>
Implementace továrny na adaptéry by vypadala nějak takto:
public class AdapterFactory implements IAdapterFactory {
public Object getAdapter(Object adaptableObject, Class adapterType) {
if((adaptableObject instanceof EObject) && adapterType == ResourceMapping.class) {
return new EObjectResourceMapping((EObject)adaptableObject);
}
return null;
}
public Class[] getAdapterList() {
return new Class[] {ResourceMapping.class};
}
}
Modelové objekty mohou implementovat rozhraní IAdaptable
. Pokud se tak děje, musí být konzultován správce adaptéru platformy. To lze provést buď vytvořením podtřídy z PlatformObject
, nebo pomocí následujícího řádku kódu:
Platform.getAdapterManager().getAdapter(Object, Class)
Doporučuje se výše uvedený postup. Modelový objekt ovšem může implementovat rozhraní IAdaptable a poskytovat implementaci getAdapter(Class)
, která vytváří a vrací instanci ResourceMapping
, pokud je explicitně vyžádána. Tento přístup je jasnější, ale nejméně žádoucí, protože model musí mít explicitní znalost adaptace na prostředky.
V některých případech nemusí poskytovatel logického modelu chtít, aby se model adaptoval na IResource
v každém kontextu nebo může chtít, aby se objekt adaptoval jinak pro příspěvky objektů než pro ostatní kontexty. Uživatelské rozhraní pracovní plochy poskytuje pro tento účel speciální pomocné adaptační rozhraní API IContributorResourceAdapter
. Při adaptaci objektů na IResource
v kontextu příspěvků objektů se pracovní plocha nejprve pokouší adaptovat prostředek na
IContributorResourceAdapter
předtím, než se pokusí adaptovat přímo na IResource
. Bylo přidáno nové podřízené rozhraní tohoto rozhraní, IContributorResourceAdapter2
, které poskytuje stejnou schopnost pro ResourceMapping
.
Jediným rozdílem je, že poskytovatel modelů by měl registrovat továrnu pro IContributorResourceAdapter
, jelikož Pracovní plocha provádí kontrolu instanceof pro zjištění, zda je přidaný adaptér rovněž instancí IContributorResourceAdapter2
.
Implementace podtřídy ResourceMapping
pro balíček Java by vypadala nějak takto.
public class JavaPackageResourceMapping extends ResourceMapping {
IPackageFragment package;
...
public getModelObject() {
return package;
}
public ResourceTraversals[] getTraversals(
ResourceMappingContext context,
IProgressMonitor monitor) {
return new ResourceTraversal[] {
new ResourceTraversal(
new IResource[] { package.getCorrespondingResource() },
IResource.DEPTH_ONE, IResource.NONE)
}
}
}
Jedná se o poměrně jasné mapování, proto není implementace příliš komplexní. Komplexnost implementace mapování prostředků se bude samozřejmě model od modelu různit.
Jednou z výhod rozhraní API mapování prostředků je, že umožňuje modulům plug-in implementovat libovolné operace co do mapování prostředků (např. aktualizace CVS, potvrzení CVS, značka CVS, nečisté zdobení apod.). Nicméně představené rozhraní API se zatím zabývá pouze lokálním stavem modelu. Při práci s modelem sdíleným mezi vývojáři se ocitnete v situaci, kdy se může vzdálený stav modelu (tzn. stav modelu, který jiný uživatel přihlásil do úložiště) lišit od stavu v pracovním prostoru. Pokud jste provedli aktualizaci CVS, budete pravděpodobně chtít, aby lokální stav modelu odpovídal vzdálenému stavu, i kdyby to znamenalo přidat nebo naopak odebrat některé soubory.
Toto neplatí pro některé logické modely. Například balíček java je kontejner navštěvovaný do hloubky jedna bez ohledu na vzdálený stav modelu. Poskytovatel úložiště tak může jednoduše stanovit, že odchozí odstranění by měla být zahrnuta při potvrzení nebo že příchozí přidání by měla být zahrnuta při aktualizaci. Prostředky tvořící logické modely se ovšem mohou v čase měnit. Například prostředky tvořící prvek modelu mohou záviset na obsahu souboru s manifestem (nebo jiném podobném mechanizmu). Aby mohlo mapování prostředku vrátit správný průchod, musí mít přístup ke vzdálenému obsahu souboru s manifestem (liší se od lokálního obsahu), aby mohlo zjistit, zda se vyskytují další prostředky, které je třeba zahrnout. Tyto dodatečné prostředky nemusí v pracovním prostoru existovat, ale poskytovatel úložiště by měl vědět, jak zajistit, aby tam byly při provádění vybrané akce.
Pro podporu těchto komplexnějších modelů může být RemoteResourceMappingContext
přenesen na metodu
ResourceMapping#getTraversals
.
Při poskytnutí kontextu jej může mapování použít k tomu, aby všechny nezbytné prostředky byly zahrnuty v průchodu. Pokud není kontext poskytován, mapování může předpokládat, že je předmětem zájmu pouze lokální stav.
ResourceMapping
se musí zajímat o kontext poskytovaný metodě getTraversals
pouze v případech, kdy prostředky tvořící změnu modelu v čase a vztah mezi modelem a prostředky nelze popsat jednoduchým průchodem, který důsledně zahrnuje tyto (a pouze tyto) prostředky, které vytváří model. Přestože se například prostředky balíčku Java mohou měnit v čase, balíček lze popsat jako složku s hloubkou jedna, a tudíž mapování prostředků pro balíčky java nevyužije kontextu mapování prostředků.
Jako složitější příklad můžeme použít soubor HTML obsahující několik obrázků. Předpokládejme, že jakékoli odkazy na obrázky ze souboru HTML jsou součástí modelu daného souboru. Při aktualizaci lokálního obsahu souboru HTML z úložiště uživatel předpokládá, že případné nové obrázky budou zahrnuty. Metoda getTraversals
pro ResourceMapping
pro soubor HTML by vypadala nějak takto:
public class HTMLResourceMapping extends ResourceMapping {
private HTMLFile htmlFile;
public ResourceTraversal[] getTraversals(ResourceMappingContext context,
IProgressMonitor monitor)
IResource[] resources = htmlFile.getResources();
if (context instanceof RemoteResourceMappingContext) {
// Vyhledat případné další prostředky na serveru
RemoteResourceMappingContext remoteContext = (RemoteResourceMappingContext)context;
IFile file = htmlFile.getFile();
if (remoteContext.hasRemoteChange(file, monitor)) {
IStorage storage = remoteContext.fetchRemoteContents(file, monitor);
IResource[] additionalResources = getReferences(storage.getContents());
resources = combine(resources, additionalResources);
}
if (remoteContext.isThreeWay() && remoteContext.hasLocalChange(file, monitor)) {
IStorage storage = remoteContext.fetchBaseContents(file, monitor);
IResource[] additionalResources = getReferences(storage.getContents());
resources = combine(resources, additionalResources);
}
}
return new ResourceTraversal[] {
new ResourceTraversal(resources, IResource.DEPTH_ZERO, IResource.NONE)};
}
}
Všimněte si, že v modelu jsou zahrnuty dvě sady prostředků: Prostředky odvozené z lokálního obsahu souboru HTML v pracovním prostoru a prostředky získané z obsahu vzdáleného a základního souboru. V obou těchto sadách mohou být prostředky, které neexistují v pracovním prostoru. Lokální soubor HTML může například obsahovat relativní odkaz na obrázek, který neexistuje v pracovním prostoru. Tento prostředek by měl být zahrnut, aby byl načten, pokud existuje vzdáleně. Vzdálený soubor může obsahovat novou kopii odkazující na další obrázky, které by měly být načteny při stažení nového vzdáleného obsahu.
Poskytovatelé modelů jsou prostředkem pro seskupování mapování souvisejících prostředků dohromady. Zde je odkaz na třídu ModelProvider. Tato třída plní tři hlavní funkce:
IResourceMappingMerger
pro určitý model je získáno adaptováním poskytovatele modelů.Následuje příklad definice rozšíření modelProvider.
<extension
id="modelProvider"
name="Library Example"
point="org.eclipse.core.resources.modelProviders">
<modelProvider
class="org.eclipse.team.examples.library.adapt.LibraryModelProvider"
name="Library Example"/>
<extends-model id="org.eclipse.core.resources.modelProvider"/>
<enablement> <test property="org.eclipse.core.resources.projectNature" value="org.eclipse.team.examples.library.view.nature" />
</enablement>
</extension>
LibraryModelProvider
je podtřídou ModelProvider
.
Pravidlo zpřístupnění se používá pro porovnání prostředků, ve kterých uchovává svůj model Knihovna. Ve výše uvedeném příkladu porovná poskytovatel modelu jakýkoli prostředek v projektu, který má povahu knihovny.
Po definování poskytovatele modelů by měla být potlačena metoda ResourceMapping#getModelProviderId()
, aby vrátila ID poskytovatele modelů.
public String getModelProviderId() {
return "org.eclipse.team.examples.library.adapt.modelProvider";
}
Chcete-li získat správné inverzní mapování prostředků na mapování prostředků pro ty prostředky, které odpovídají pravidlu zpřístupnění vašeho modelu, měli byste rovněž potlačit jednu nebo obě metody
getMapping
. To, která metoda má být potlačena závisí na tom, zda má váš model prvky obsahující více prostředků či nikoli. Pokud se prvky modelu mapují na jediný prostředek, můžete potlačit metodu, která akceptuje jeden argument IResource
. V opačném případě je třeba potlačit metodu, která akceptuje celou řadu prostředků. Zde je příklad případu s jediným prostředkem.
Následující vzorová metoda zabaluje model knihovny do odpovídajícího mapování prostředků. Zároveň zabaluje složky obsahující soubory, které jsou předmětem pozornosti poskytovatele modelů.
public class LibraryModelProvider extends ModelProvider {
public ResourceMapping[] getMappings(IResource resource,
ResourceMappingContext context, IProgressMonitor monitor) {
if (isModelFile(resource)) {
// Vrátit mapování prostředků na soubor
return new LibraryResourceMapping(resource);
} if (containsModelFiles(resource)) {
// Vytvořit hluboké mapování prostředků na kontejner
return new LibraryContainerResourceMapping(resource);
}
// Tento prostředek není pro poskytovatele modelu podstatný
return null;
}
}
Klienti mají poté přístup k poskytovatelům modelů a mohou zjistit, zda jim záleží na prostředcích, na kterých se budou provádět operace. Následující oddíl popisuje rozhraní API, jež bude poskytnuto týmovým operacím, které používají rozhraní API poskytovatele modelů pro zjištění úplného souboru mapování prostředků, na kterých se budou provádět operace při provádění týmových operací na souboru vybraných prostředků nebo prvků modelů.
Operace prováděné na prostředcích by měly být nejprve ověřeny, aby bylo zajištěno, že si je uživatel vědom případných vedlejších účinků. Následují kroky nezbytné pro ověření změny prostředku.
IResourceChangeDescriptionFactory
.
Továrna vytváří IResourceDelta
, která odráží podobu výsledných rozdílových dat prostředku po provedení operace.ResourceChangeValidator
.
Validátor konzultuje všechny poskytovatele modelů, kteří projevili zájem na ovlivněných prostředcích. Výsledkem je jeden nebo více stavů, které obsahují ID původního modelu a popis případných vedlejších účinků operace na model.Při pokusu o sloučení bez hlavičky provádí týmový poskytovatel následující:
Prvky modelu lze zobrazit v kontextu týmové operace prostřednictvím rámce společného navigátoru Common Navigator.
Výše uvedené kroky umožní zobrazení modelů v dialogových oknech použitých týmovými operacemi. Pro integraci do náhledu sloučení jsou nezbytné další kroky.
V oblasti historie souborů a historie prvků modelů bylo dosaženo následujících zlepšení:
Pro podporu vzdáleného procházení je k dispozici následující:
Týmoví poskytovatelé mohou zdobit prvky modelů převedením jejich odlehčených dekorátorů pro fungování s mapováním prostředků, podobně jako jsou takto převáděny příspěvky objektů. Jeden aspekt zdobení prvku logického modelu je ovšem problematický. Pokud prvek modelu nemá jedinečné mapování na prostředek, nemusí při změně základních prostředků obdržet aktualizaci štítku.
Ve snaze o vyřešení této záležitosti byl představen ITeamStateProvider
, který umožňuje poskytovatelům modelů přístup ke změnám stavu, které mohou ovlivnit zdobení týmu. Kromě toho mohou pohledy modelů použít SynchronizationStateTester
pro zjištění, kdy musí být štítky prvků logických modelů aktualizovány. Toto API závisí na rozhraní ITeamStateProvider
při zjišťování, zda se týmový stav prostředku změnil a zda může být předán na týmový dekorátor jako součást IDecorationContext
.