Her er en liste over det modelleverandører kan gjøre for å fra nytte av gruppestøtten for logisk modell.
I seksjonene nedenfor beskrives hvert av disse punktene mer i detalj. Plugin-modulen org.eclipse.team.examples.filesystem inneholder et eksempel som illustrerer flere av disse punktene. Du kan hente ut prosjektet fra CVS-datalageret og bruke det som en referanse mens du leser denne opplæringen. Obs: Kildekoden i eksempel-plugin-modulen kan bli endret. Hvis du vil ha en kopi som tilsvarer det som brukes i dette eksempelet, kan du sjekke ut prosjektet med 3.2-versjonskoden (sannsynligvis R3_2) eller med datoen 28. juni 2006.
APIet for ressurstilordning er enkelt med manipulasjoner av logisk modell utelatt. En klient kan ikke bruke dette grensesnittet for å vise logiske modeller eller få tak i interessant tilleggsinformasjon uten den. Formålet er ganske enkelt å tilordne ett eller flere modellelementer til arbeidsområderessurser.
APIet består av følgende klasser:
Object getModelObject()
: Modellobjektet som tilordningen ble avledet
(eller tilpasset) på grunnlag av.ResourceTraversal[]
getTraversals(ResourceMappingContext, IProgressMonitor)
: Ressurstraverseringen som omfatter ressursene som utgjør modellobjektet.
ResourceTraversal
består av et sett med ressurser og et dybdeflagg som viser til hvilken
dybde ressursene i traverseringen er knyttet til det opprinnelige modellobjektet.
Ressurstraverseringer gis til en klient ved hjelp av en ressurstilordning for å beskrive innholdet i en modell på en slik måte at
klienten (f.eks. en datalagerleverandør) kan utføre sine operasjoner på en mest mulig effektiv måte.
Følgende metoder er interessante:
getResources()
getDepth()
ResourceMappingContext
og RemoteResourceMappingContext
er litt mer komplisert, og er beskrevet i seksjonen Ressurstilordningskontekst.Det er to typer plugin-moduler som kan være interessert i ressurstilordninger: De som besørger en modell som består av, eller er permanent i, ressurser i arbeidsområdet, og de som utfører operasjoner på ressurser. Førstnevnte er omhandlet i neste seksjon, mens sistnevnte er omhandlet i Datalagerkart for integrering av logisk modell.
Plugin-modulene som har tilpasset sine modellobjekter til
IResource
for å hente ressursspesifikke handlinger som er vist i hurtigmenyen, kan nå
tilpasses til ResourceMapping
hvis en rikere beskrivelse av hvordan objektet tilpasses til ressurser, er nyttig.
De må imidlertid ikke gjøre det hvis det ikke er nyttig.
For eksempel er det ikke nødvendig å tilpasse en Java-kompileringsenhet
(dvs. *.java-fil vist i en JDT-visning) som nå tilpasses til
IFile
, til ResourceMapping
, siden man ikke vinner noe på det.
En Java-pakke bør imidlertid tilpasses til
ResourceMapping
for å vise at pakken består av bare filene i tilsvarende mappe og ikke i undermappene.
Den foretrukne måten å tilpasse modellelementer til en ressurstilordning på er å bruke en adapter-factory. Her er XML-koden for bidrag av en adapter-factory i en plugin-manifest:
<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>
Adapter-factoryimplementeringen vil se omtrent slik ut:
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};
}
}
Modellobjekter kan implementere grensesnittet IAdaptable
. Når de gjør det, må de sørge for at plattformadapterstyreren
konsulteres.
Dette kan gjøre ved å subklassifisere PlatformObject
eller ved å bruke følgende kodelinje:
Platform.getAdapterManager().getAdapter(Object, Class)
Ovennevnte er foretrukket fremgangsmåte. Modellobjektet kan imidlertid implementere grensesnittet
IAdaptable og besørge en getAdapter(Class)
-implementering som returnerer en forekomst av
ResourceMapping
eksplisitt ved spørsmål om en.
Dette er en greiere fremgangsmåte, men minst ønsket, fordi modellen må ha eksplisitt kunnskap om tilpasningen til ressursene.
I noen tilfeller er det ikke sikkert leverandøren av en logisk modell vil at modellen skal tilpasses til
IResource
i enhver kontekst, eller den vil kanskje at objektet skal tilpasses forskjellig for objektbidrag enn for andre kontekster.
Arbeidsbenkens brukergrensesnitt har et spesielt mellomliggende adapter-API
IContributorResourceAdapter
, for dette formålet.
Når objekter tilpasses til IResource
i forbindelse med objektbidrag, prøver arbeidsbenken først å tilpasse ressursen til
IContributorResourceAdapter
, før den prøver å tilpasse den direkte til
IResource
. En nytt undergrensesnitt for dette grensesnittet,
IContributorResourceAdapter2
, er tilføyd og gir samme funksjonalitet for
ResourceMapping
.
Den eneste forskjellen er at modelleverandører bør registrere en factory
for IContributorResourceAdapter
, siden arbeidsbenken tar en
instanceof-kontroll for å se om adapteren som bidras, også er en forekomst av
IContributorResourceAdapter2
.
Implementeringen av ResourceMapping
-subklassen for en Java-pakke skulle se ut omtrent som dette:
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)
}
}
}
Dette er en ganske enkel tilordning, så implementeringen er ikke komplisert. Kompleksiteten til ressursimplementeringen vil naturligvis variere fra modell til modell.
En av fordelene med et API for ressurstilordning er at det gjør det mulig for plugin-moduler å implementere alle operasjoner de ønsker, i form av ressurstilordning (f.eks. CVS-oppdatering, CVS-iverksetting, CVS-kode, uren dekorasjon osv.). APIet som er introdusert så langt, handler imidlertid bare om modellens lokale status. Når du arbeider med en modell som kan deles mellom utviklere, ender du opp med en situasjon der modellens eksterne status (dvs. statusen til modellen som en annen bruker har når den er sjekket inn i datalageret) kan vøre forskjellig fra arbeidsområdets status. hvis du har utført en CVS-oppdatering, vil du ønske at den lokale statusen for modellen skal samsvare med den eksterne statusen selv om det betyr at du må inkludere flere filer eller fjerne enkelte filer.
Dette er ikke noe problem for enkelte lokale modeller. For eksempel er en Java-pakke en container som besøkes til dybde en, uansett modellens fjernstarting. gitt dette kan en datalagerleverandør lett bestemme at utgående slettinger skal inkluderes ved iverksetting, eller at innkommende tilføyelser skal inkluderes ved oppdatering. Ressursene som utgjør enkelte logiske modeller, kan imidlertid endres over tid. For eksempel kan ressursene som utgjør et modellelement, avhenge av innholdet i en manifestfil (eller en annen lignende mekanisme). For at ressurstilordningen skal returnere riktig traversering, må den få tilgang til det eksterne innholdet i manifestfilen (hvis det er forskjellig fra det lokale innholdet) så den kan se om det finnes ytterligere ressurser som må inkluderes. Det er ikke sikkert at disse tilleggsressursene finnes i arbeidsområdet, men datalagerleverandøren vil vite hvordan den skal kontrollere om de gjorde det da den valgte handlingen ble utført.
For å støtte mer komplekse modeller kan en RemoteResourceMappingContext
sendes til metoden ResourceMapping#getTraversals
.
Når det gis en kontekst, kan tilordningen bruke den for å sikre at alle nødvendige ressurser inkluderes i traverseringen.
Hvis det ikke gis en kontekst,
kan tilordningen anta at bare den lokale statusen er av interesse.
En ResourceMapping
trenger bare å bekymre seg for en kontekst levert til
getTraversals
-metoden i tilfeller der ressursene som utgjør en modell, endres over tid, og forholdet mellom
modellen og ressursene ikke kan beskrives ved en enkel traversering som er garantert å omfatte de ressursene
(og bare de ressursene) som utgjør modellen.
Selv om ressursene til en Java-pakke, for eksempel, kan endres over tid, kan pakken beskrives som en
mappe med en dybde på en, slik at en ressurstilordning for Java-pakker ikke behøver å benytte seg av ressurstilordningens kontekst.
Som et mer komplisert eksempel kan vi ta for oss en HTML-fil som inneholder flere bilder.
La oss anta at alle bildereferanser fra en HTML-fil er del av filens modell.
Når det lokale innholdet i HTML-filen oppdateres fra et datalager, forventer brukeren av nye bilder er
inkludert.
Metoden getTraversals
for en ResourceMapping
for HTML-filmodellen vil se ut omtrent slik:
public class HTMLResourceMapping extends ResourceMapping {
private HTMLFile htmlFile;
public ResourceTraversal[] getTraversals(ResourceMappingContext context,
IProgressMonitor monitor)
IResource[] resources = htmlFile.getResources();
if (context instanceof RemoteResourceMappingContext) {
// Se etter ytterligere ressurser på serveren
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)};
}
}
Merk at to sett med ressurser er inkludert i modellen: de som er avledet av det lokale innholdet i HTML-filen i arbeidsområdet, og de som er hentet fra innholdet i den eksterne filen og basisfilen. I begge de to settene kan det være ressurser som ikke finnes i arbeidsområdet. For eksempel kan den lokale HTML-filen inneholde en relativ link til en bilde som ikke finnes i arbeidsområdet. Denne ressursen bør inkluderes, slik at den blir hentet hvis den finnes eksternt. Den eksterne filen kan inneholde en ny kopi som refererer til ytterligere bilder som skal hentes når det nye eksterne innholdet lastes ned.
Modelleverandører er en måte å gruppere beslektede ressurstilordninger sammen. Her er en link til klassen ModelProvider. Denne klassen har tre hovedformål:
IResourceMappingMerger
for modellen ved å tilpasse modelleverandøren. Her er et eksempel på en utvidelsesdefinisjon for en modelleverandør:
<extension
id="modelProvider"
name="Bibliotekeksempel"
point="org.eclipse.core.resources.modelProviders">
<modelProvider
class="org.eclipse.team.examples.library.adapt.LibraryModelProvider"
name="Bibliotekeksempel"/>
<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
er en subklasse under ModelProvider
.
Aktiveringsreglene brukes til å avpasse ressurser som bibliotekmodellen oppbevarer sin modell i.
I eksempelet over vil modelleverandøren avpasse enhver ressurs i et prosjekt som har biblioteknaturen.
Når modelleverandøren er definert, må metoden
ResourceMapping#getModelProviderId()
overstyres for å returnere IDen til modelleverandøren.
public String getModelProviderId() {
return "org.eclipse.team.examples.library.adapt.modelProvider";
}
For å få tak i riktig invers tilordning av ressurser til ressurstilordningen for de ressursene som
samsvarer med leverandørens aktiveringsregel, må du overstyre en av eller begge
getMapping
-metodene.
Hvilken metode du må overstyre, avhenger av om modellen har elementer som inneholder flere ressurser,
eller ikke.
Hvis modellelementene tilordnes til en enkelt ressurs, kan du overstyre metoden som aksepterer ett enkelt
IResource
-argument. Eller må du overstyre metoden som aksepterer en matrise av ressurser.
Her er et eksempel på bruk av enkeltressurstilfellet.
Den enkle metoden nedenfor pakker en bibliotekmodell i riktig ressurstilordning.
Den pakker også mapper som inneholder filer som er av interesse for modelleverandøren.
public class LibraryModelProvider extends ModelProvider {
public ResourceMapping[] getMappings(IResource resource,
ResourceMappingContext context, IProgressMonitor monitor) {
if (isModelFile(resource)) {
// Returner en ressurstilordning på filen
return new LibraryResourceMapping(resource);
} if (containsModelFiles(resource)) {
// Opprett en dyp ressurstilordning på containeren
return new LibraryContainerResourceMapping(resource);
}
// Ressursen er ikke av interesse for denne modelleverandøren
return null;
}
}
Klientene kan så få tilgang til modelleverandøren for å avgjøre om modelleverandøren bryr seg om ressursene som det skal handles på. Neste seksjon beskriver APIet som blir besørget for gruppeoperasjoner for å fastsette hele settet av ressurstilordninger som det skal handles på når en gruppeoperasjon utføres på et sett med valgte ressurser eller modellelementer.
Operasjoner som utføres på ressurser, bør valideres først for å sikre at brukeren er oppmerksom på alle potensielle bivirkninger. Her beskrives det hva som skal til for å validere en ressursendring.
IResourceChangeDescriptionFactory
.
Factoryen produserer en IResourceDelta
som speiler det den resulterende ressursdeltaen ser ut som når operasjonen utføres.
ResourceChangeValidator
.
Validatoren konsulterer alle modelleverandører som har registrert en interesse i de påvirkede ressursene.
Resultatet er en eller flere statuser som inneholder IDen til opprinnelsesmodellen og en beskrivelse av den potensielle bivirkningen
av operasjonen på modellen.
Når en gruppeleverandør forsøker en headless-sammenslåing, vil den gjøre følgende:
Visningen av modellelementene i forbindelse med en gruppeoperasjon gjøres mulig av Felles navigator-rammen.
Trinnene ovenfor gjør det mulig å vise modeller i dialogbokser som brukes av gruppeoperasjoner. Det kreves ytterligere trinn for å integrere i en forhåndsvisning for sammenslåing.
Følgende forbedringer er gjort i området for filhistorikk og modellelementhistorikk:
Følgende støtter ekstern blaing:
Gruppeleverandører kan dekorere modellelementer ved å konvertere deres forenklede dekorasjoner til å virke for ressurstilordninger på samme måte som objektbidrag konverteres til å virke for ressurstilordninger. Det er imidlertid ett aspekt ved dekorasjoner for logiske modellelementer som er problematisk. Hvis et modellelement ikke har en en til en-tilordning til en ressurs, kan ikke modellelementet motta en etikettoppdatering når de underliggende ressursene endres.
For å løse dette problemet ble
ITeamStateProvider
innført
og gav modelleverandørene tilgang til statusendringer som kan påvirke gruppedekorasjonene.
Dessuten kan modellvisninger bruke en
SynchronizationStateTester
til å bestemme når
etikettene til logiske modellelementer må oppdateres.
Dette APIet er avhengig av grensesnittet ITeamStateProvider
for å avgjøre når
gruppestatusen til en ressurs er endret og kan sendes til en gruppedekoratør som del av en
IDecorationContext
.