Modellkart for integrering av logisk modell

Her er en liste over det modelleverandører kan gjøre for å fra nytte av gruppestøtten for logisk modell.

  1. Tilpass modellelementer i modellvisninger til ResourceMapping for å gjøre det mulig å vise ressursbaserte operasjoner på modellelementene.
  2. Registrer en ModelProvider for å sikre at modellen rådføres når operasjonene utføres på ressursene knyttet til modellen.
  3. Bruk ResourceChangeValidator ved utførelse av operasjoner på ressurser for å sikre at eventuelle potensielle bivirkninger på modellelementene som er knyttet til disse ressursene, er kjent for brukeren.
  4. Implementer en IResourceMappingMerger for å delta i sammenslåinger av kommandogrensesnitt som omfatter ressurser knyttet til modellen.
  5. Registrer en teamContentProvider for å delta i gruppevisninger som forhåndsvisninger for sammenslåing.
  6. Oppgi en IHistoryPageSource for å vise historikk for logisk modell i Gruppehistorikk-visningen.
  7. Bruk APIet Eclipse File System for å få tilgang til den eksterne statusen til modellprosjekter.
  8. Bruk APIet SynchronizationStateTester for å sikre riktig dekorasjon for modellelementer som ikke har en til en-tilordning til ressurser.

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.

Ressurstilordninger

API for grunnleggende ressurstilordning

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:

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.

Tilpasse en modell til en ResourceMapping

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.

Ressurstilordningskontekst

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.

når må en ResourceMapping bekymre seg for RemoteResourceMappingContext?

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

Modelleverandører er en måte å gruppere beslektede ressurstilordninger sammen. Her er en link til klassen ModelProvider. Denne klassen har tre hovedformål:

  1. Fra en modelleverandør kan klienter hente ytterligere API-stykker for å utføre operasjoner på et sett med ressurstilordninger ved hjelp av en mekanisme som kan tilpasses. For eksempel hentes IResourceMappingMerger for modellen ved å tilpasse modelleverandøren.
  2. Gitt et sett med filsystemressurser kan klienter spørre om en modelleverandør har modellelementer permanent i disse ressursene, og, hvis det ikke har det, få tak i det settet med ressurstilordninger som beskriver forholdet.
  3. For operasjoner på et sett med ressurser, vil ressursendringsvalidatoren spørre modelleverandørene for å bestemme om det er noen potensielle bivirkninger av en operasjon som brukerne bør være klar over. Dette er omhandlet i en egen seksjon om endringsvalidering.

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.

Validere en ressursendring

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.

  1. Bygg opp en beskrivelse av endringen ved hjelp av IResourceChangeDescriptionFactory. Factoryen produserer en IResourceDelta som speiler det den resulterende ressursdeltaen ser ut som når operasjonen utføres.
  2. Valider endringen ved hjelp av 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.
  3. Gjør brukeren klar over eventuelle potensielle bivirkninger fra modeller som er ukjente for operasjonsopphavet. Hvis for eksempel en Java-refaktorisering har mottatt en bivirkning fra Java-modellen, kan den ignoreres, siden refaktoriseringen forstår semantikken i Java-modellen. Hvis en bivirkning av bibliotekmodellen returneres, bør den imidlertid gjøres kjent for brukeren, siden Java ikke har kunnskap om bibliotekmodellen.

Modellbasert sammenslåing

Når en gruppeleverandør forsøker en headless-sammenslåing, vil den gjøre følgende:

  1. Få tak i ressurstilordningene fra de valgte elementene.
  2. Fastslå hvilke modelleverandører som er involvert, ved hjelp av metoden ResourceMapping#getModelProvider().
  3. Utvide omfanget til operasjonen til å inkludere alle nødvendige ressurstilordninger.
  4. Bygge opp en beskrivelse av synkroniseringsstatusen mellom lokal og ekstern. Denne beskrivelsen gis til modellene gjennom APIet IMergeContext.
  5. Tilpasse modelleverandører til IResourceMappingMerger.
  6. Aktivere metoden validateMerge på hver sammenslåing, idet den sendes i synkroniseringsbeskrivelse, for å sikre at det ikke finnes en betingelse som kan hindre en forsøkt sammenslåing.
  7. Delegere sammenslåingen til modellsammenslåinger for å utføre sammenslåingen.
  8. Modelleverandører kan delegere sammenslåingen av enkeltfiler tilbake til gruppeleverandøren hvis de vare vil kontrollere rekkefølgen på sammenslåingen eller utføre sammenslåingen selv og signalisere til gruppeleverandøren når de er ferdige.

Modellinnhold i Gruppeoperasjon-visninger

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.

Historikkvisning

Følgende forbedringer er gjort i området for filhistorikk og modellelementhistorikk:

Ekstern blaing

Følgende støtter ekstern blaing:

Dekorere modellelementer med gruppestatus

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.