Modellöversikt för integrering av logiska modeller

Nedan följer en lista över vad modelleverantörer kan göra för att dra fördel av funktionerna för logiska modeller för grupper:

  1. Anpassa modellelement i modellvyer till ResourceMapping i syfte att göra det möjligt att visa resursbaserade åtgärder för dina modellelement.
  2. Registrera en ModelProvider för att säkerställa att det görs en kontroll av modellen när åtgärder utförs för resurser som är relaterade till modellen.
  3. Använd ResourceChangeValidator när du utför åtgärder för resurser för att säkerställa att användaren informeras om eventuella bieffekter för de modellelement som är relaterade till de resurserna.
  4. Implementera en IResourceMappingMerger för att delta i konsollösa sammanfogningar som inbegriper de resurser som är relaterade till din modell.
  5. Registrera en teamContentProvider för att delta i gruppvisningsprogram, till exempel förhandsvisning av sammanfogningar.
  6. Tillhandahåll en IHistoryPageSource för att visas historik för logiska modeller i vyn för grupphistorik.
  7. Använd API:t för Eclipse-filsystemet för att visa fjärrstatus för modellprojekt.
  8. Använd SynchronizationStateTester-API:t för att säkerställa att modellelement som inte har en en-till-en-avbildning till resurser dekoreras på rätt sätt.

I följande avsnitt beskrivs de här punkterna närmare. Insticksprogrammet org.eclipse.team.examples.filesystem innehåller ett exempel där flera av de här punkterna åskådliggörs. Du kan checka ut projektet från CVS-lagret och använda som referens medan du går igenom den här självstudiekursen. Obs! Källkoden i exempelinsticksprogrammen kan förändras. Om du vill ha en kopia som matchar det som används i exemplet kan du checka ut projektet med hjälp av 3.2 versionsmärkordet (troligen R3_2) eller datummärkningen 28 juni 2006."

Resursavbildningar

Det allmänna resursavbildnings-API:t

Resursavbildnings-API:t är avsiktligt enkelt och bearbetningar av logiska modeller utelämnas. En klient kan inte använda det här gränssnittet till att visa logiska modeller eller få någon intressant extra information om dem. Syftet med det är helt enkelt att göra det möjligt att avbilda ett eller flera modellelement till arbetsyteresurser.

API:T består av följande klasser:

Det finns två typer av insticksprogram som är relevanta för resursavbildningar. De som tillhandahåller en modell som består av, eller är beständig i, resurser i arbetsytan, och de som utför åtgärder för resurser. De förra beskrivs i nästa avsnitt medan de senare beskrivs i avsnittet Lageröversikt för integrering av logiska modeller.

Anpassa en modell till en ResourceMapping

Insticksprogram som anpassat sina modellobjekt till IResource för att resursspecifika åtgärder ska visas i kontextmenyn kan nu anpassas till ResourceMapping om en mer detaljerad beskrivning av hur objekt anpassas till resurser är till nytta. De behövs dock inte anpassas om det inte är till någon nytta. Till exempel behöver en Java-kompileringsenhet (dvs. en *.java-fil som visas i en JDT-vy) som nu är anpassad till IFile inte anpassas till ResourceMapping eftersom inget uppnås med det. Ett Java-paket bör dock anpassas till ResourceMapping för att ange att paketet endast består av filerna i motsvarande mapp och inte undermapparna.

Den rekommenderade sättet att anpassa modellelement till en resursavbildning är att använda en adapterfabrik. Nedan visas XML-märkordsuppsättningen för tillägg av en adapterfabrik i ett insticksprogramsmanifest.

   <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>

Implementeringen av adapterfabriken ser ut ungefär så här:

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};
}
}

Modellobjekt kan implementera IAdaptable-gränssnittet. När de gör det måste de säkerställa att en kontroll av plattformsadapterhanteraren görs. Det kan göras antingen genom att en underklass till PlatformObject skapas eller med hjälp av följande kodrad:

Platform.getAdapterManager().getAdapter(Object, Class)

Det ovanstående sättet rekommenderas. Modellobjektet kan implementera IAdaptable-gränssnittet och tillhandahålla en implementering av getAdapter(Class) som returnerar en förekomst av ResourceMapping explicit när den tillfrågas om en. Det här är ett mer okomplicerat tillvägagångssätt men rekommenderas inte eftersom modellen måste ha explicit information om anpassningen till resurser.

I vissa fall kan det hända att leverantören av en logisk modell inte vill att modellen anpassas till IResource i alla kontexter eller att objektet anpassas på olika sätt för objekttillägg och andra kontexter. I arbetsmiljö-UI:t ingår ett särskilt mellanliggande adapter-API, IContributorResourceAdapter, för det ändamålet. När objekt anpassas till IResource i objekttilläggskontext görs först ett försök att anpassa resursen till IContributorResourceAdapter innan det görs ett försök att anpassa resursen till IResource direkt. Ett nytt delgränssnitt i det här gränssnittet, IContributorResourceAdapter2, med samma funktioner för ResourceMapping har lagts till. Den enda skillnaden är att modelleverantören bör registrera en fabrik för IContributorResourceAdapter eftersom arbetsmiljön gör en instanceof-kontroll av om den tillagda adaptern också är en förekomst av IContributorResourceAdapter2.

Implementeringen av ResourceMapping-underklassen för ett Java-paket skulle se ut ungefär på följande sätt:

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)
}
}
}

Det här är en ganska enkel avbildning så implementeringen är inte komplex. Komplexiteten för implementeringen av resursavbildningen varierar förstås från modell till modell.

Kontext för resursavbildning

En av fördelarna med ett resursavbildnings-API är att det gör det möjligt för insticksprogram att implementera valfria åtgärder vad beträffar resursavbildningar (till exempel Uppdatering i CVS, Bekräftelse i CVS, CVS-märkord, osparad dekoration). Det API som har införts än så länge hanterar dock endast lokal status för modellen. När du arbetar med en modell som kan delas av utvecklare uppstår en situation där fjärrstatus för modellen (dvs. status för den modell som en annan användare har checkat in i lagret) kan skilja sig från status i arbetsytan. Om du utförde en uppdatering i CVS vill du att lokal status för modellen ska överensstämma med fjärrstatus även om det innebär att fler filer måste inkluderas eller att några filer måste tas bort.

Det här är inte ett problem för vissa logiska modeller. Till exempel är ett Java-paket en behållare med bläddring på ett djup på ett oavsett fjärrstatus för modellen. Om det är möjligt kan en lagerleverantör enkelt avgöra om utgående borttagningar ska ingå vid bekräftelse eller om inkommande tillägg ska ingå vid uppdatering. De resurser som utgör vissa logiska modeller kan ändras över tid. Till exempel kan de resurser som utgör ett modellelement vara beroende av innehållet i en manifestfil (eller någon liknande mekanism). En förutsättning för att resursavbildningen ska returnera rätt bläddring är att den har åtkomst till fjärrinnehållet för manifestfilen (om det skiljer sig från det lokala innehållet) för att kontrollera om det finns fler resurser som ska ingå. Det kan hända att de här extra resurserna inte finns i arbetsytan men lagerleverantören kan kontrollera att de fanns där när den valda åtgärden utfördes.

Se till att de här mer komplexa modellerna kan användas genom att överföra RemoteResourceMappingContext till metoden ResourceMapping#getTraversals. När en kontext tillhandahålls kan avbildningen använda den till att säkerställa att alla nödvändiga resurser ingår i bläddringen. Om en kontext tillhandahålls kan avbildningen anta att endast lokal status är av intresse.

När måste hänsyn till RemoteResourceMappingContext tas för ResourceMapping?

För ResourceMapping måste hänsyn tas till kontext som tillhandahållits i getTraversals-metoden bara i fall där de resurser som en modell består av ändras över tid och relationen mellan modellen och resurserna inte kan beskrivas med en enkel bläddring som garanterat inbegriper de resurser som modellen består av (och endast de resurserna). Till exempel gäller att även om resurserna för ett Java-paket kan ändras över tid kan paketet beskrivas som en mapp med djupet ett så att en resursavbildning för Java-paket inte behöver använda sig av resursavbildningskontexten.

Ett mer komplicerat exempel är en HTML-fil som innehåller flera bilder. Låt oss anta att eventuella bildreferenser från en HTML-fil är en del av modellen för den filen. När du uppdaterar det lokala innehållet i HTML-filen från ett lager förväntar sig användaren att eventuella nya bilder ingår i uppdateringen. getTraversals-metoden för en ResourceMapping för HTML-filmodellen skulle se ut ungefär så här:

public class HTMLResourceMapping extends ResourceMapping {
private HTMLFile htmlFile;
public ResourceTraversal[] getTraversals(ResourceMappingContext context,
IProgressMonitor monitor)
IResource[] resources = htmlFile.getResources();
if (context instanceof RemoteResourceMappingContext) {
// Sök efter extra resurser på servern
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)};
}
}

Lägg märke till att det finns två uppsättningar resurser i modellen: de som härrör från det lokala innehållet i HTML-filen i arbetsytan och de som hämtats från innehållet i fjärrfilen och basfilen. I en av de här uppsättningarna kan det finnas resurser som inte finns i arbetsytan. Till exempel kan den lokala HTML-filen innehålla en relativ länk till en bild som inte finns i arbetsytan. Den här resursen bör inkluderas så att den hämtas om den finns som en fjärresurs. Vad gäller fjärrfilen kan den innehålla en nya kopia som refererar till fler bilder som bör hämtas när det nya fjärrinnehållet hämtas.

Modelleverantörer

Modelleverantörer kan användas till att gruppera relaterade resursavbildningar. Här är en länk till ModelProvider-klassen. Den här klassen har tre huvudfunktioner:

  1. Från en modelleverantör kan klienter sedan erhålla fler API-delar för att utföra åtgärder för en uppsättning resursavbildningar med hjälp av den anpassningsbara mekanismen. Till exempel erhålls IResourceMappingMerger för modellen genom att modelleverantören anpassas.
  2. Klienter kan fråga om en modelleverantör har modellelement som är beständiga i en viss uppsättning filsystemresurser och om så är fallet erhålla de resursavbildningar som beskriver relationen.
  3. När åtgärder utförs för en uppsättning resurser ställer valideringsfunktionen för resursändringar en fråga till modelleverantören för att avgöra om det finns några potentiella bieffekter av en åtgärd som användare bör vara medvetna om. Det här beskrivs i ett separat avsnitt om ändringsvalidering.

Här följer ett exempel på en definition av en modelProvider-utökning.

   <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 är en underklass till ModelProvider. Aktiveringsregeln används till att hitta överensstämmelser med resurser där biblioteksmodellen är beständig. I ovanstående exempel överensstämmer modelleverantören med alla resurser med biblioteksnatur i ett projekt.

När modelleverantören har angetts bör ResourceMapping#getModelProviderId()-metoden åsidosättas för att ID:t för modelleverantören ska returneras.

   public String getModelProviderId() {
return "org.eclipse.team.examples.library.adapt.modelProvider";
}

I syfte att få rätt omvänd avbildning av resurser till resursavbildning för de resurser som överensstämmer med leverantörens aktiveringsregel bör du även åsidosätta en av eller båda getMapping-metoderna. Vilken metod som ska åsidosättas beror på om modellen har element som innehåller flera resurser. Om modellelementen avbildas till en enda resurs kan du åsidosätta den metod som accepterar enstaka IResource-argument. I annat fall måste du åsidosätta den metod som accepterar flera resurser. Här följer ett exempel på fallet med en resurs.

I följande exempelmetod innefattas en biblioteksmodellsfil i lämplig resursavbildning. Mappar som innehåller filer som är av intresse för modelleverantören inbegrips också.

public class LibraryModelProvider extends ModelProvider {
public ResourceMapping[] getMappings(IResource resource,
ResourceMappingContext context, IProgressMonitor monitor) {
if (isModelFile(resource)) {
// Returnera en resursavbildning för filen
return new LibraryResourceMapping(resource);
} if (containsModelFiles(resource)) {
// Skapa en djup resursavbildning för behållaren
return new LibraryContainerResourceMapping(resource);
}
// Resursen är inte av intresse för den här modelleverantören
return null;
}
}

Klienter kan sedan få åtkomst till modelleverantören för att avgöra om modelleverantörerna har intresse av de resurser som ska bearbetas. I nästa avsnitt beskrivs det API som tillhandahålls för gruppåtgärder där modelleverantörs-API:t används till att bestämma den fullständiga uppsättningen resursavbildningar som ska bearbetas när en gruppåtgärd utförs för en uppsättning valda resurser eller modellelement.

Validering av resursändringar

Åtgärder som utförs för resurser bör först utvärderas för att säkerställa att användaren är medveten om eventuella bieffekter. Här följer de nödvändiga stegen för validering av en resursändring.

  1. Skapa en beskrivning av ändringen med hjälp av IResourceChangeDescriptionFactory. Fabriken skapar ett IResourceDelta som speglar hur det resulterande resursdeltat kommer att se ut när åtgärden utförts.
  2. Validera ändringen med hjälp av ResourceChangeValidator. Valideringsfunktionen stämmer av med alla modelleverantörer som har registrerat intresse i de resurser som påverkas. Resultatet är en eller flera statusfiler som innehåller ID:t för den ursprungliga modellen och en beskrivning av den potentiella bieffekten av åtgärden för modellen.
  3. Informera användaren om potentiella bieffekter från modeller som är okända för den som utförs åtgärden. Till exempel om en Java-omfaktorisering har tagit emot en bieffekt från Java-modellen kan den ignoreras eftersom omfaktoriseringen kan tolka semantiken för Java-modellen. Men om en bieffekt från biblioteksmodellen returneras bör användaren informeras om det eftersom Java inte känner till biblioteksmodellen.

Modellbaserad sammanfogning

En gruppleverantör försöker genomföra en konsollös sammanfogning på följande sätt:

  1. Hämta resursavbildningarna från de valda elementen
  2. Avgöra vilka modelleverantörer som ingår med hjälp av metoden ResourceMapping#getModelProvider().
  3. Utöka omfånget för åtgärden så att alla nödvändiga resursavbildningar inkluderas.
  4. Skapa en beskrivning av synkroniseringsstatus mellan lokal status och fjärrstatus. Den här beskrivningen tillhandahålls modellerna via IMergeContext-API:t.
  5. Anpassa modelleverantörerna till IResourceMappingMerger.
  6. Anropa validateMerge-metoden för varje sammanfogning och ange synkroniseringsbeskrivningen för att säkerställa att det inte förekommer villkor som kan förhindra en sammanfogning.
  7. Delegera sammanfogningen till modellsammanfogningsfunktionen så utförs sammanfogningen.
  8. Modelleverantörer kan delegera sammanfogning av enskilda filer tillbaka till gruppleverantören om de endast vill kontrollera ordningsföljden för sammanfogningen eller utföra sammanfogningen själva och informera gruppleverantören när de är klara.

Modellinnehåll i gruppåtgärdsvyer

Det går att visa modellelement i kontexten för en gruppåtgärd i ramverket för den gemensamma navigeringsvyn.

Med hjälp av ovanstående anvisningar kan modeller visas i dialogrutor som används av gruppåtgärder. Ytterligare steg krävs för integrering till en förhandsvisning av en sammanfogning.

Historikvy

Följande förbättringar har gjorts i vyn för filhistoriken och modellelementhistoriken:

Fjärrbläddring

Det följande har lagts till för att göra fjärrbläddring möjlig:

Dekorera modellelement med gruppstatus

Gruppleverantörer kan dekorera modellelement genom att konvertera Lightweight-dekoratörer så att de kan användas för resursavbildningar på samma sätt som objekttillägg konverteras för att användas för resursavbildningar. Det finns dock en aspekt av dekoration av element för logiska modeller som är problematisk. Om det inte finns en ett-till-ett-avbildning till en resurs för ett modellelement kan modellelementet inte ta emot en etikettuppdatering när de underliggande resurserna ändras.

I syfte att åtgärda det här problemet infördes ITeamStateProvider så att modelleverantörer får åtkomst till tillståndsändringar som kan påverka gruppdekorationer. Dessutom kan en SynchronizationStateTester användas i modellvyer för att bestämma när etiketterna för element för logiska modeller måste uppdateras. I det här API:t används ITeamStateProvider-gränssnittet till att bestämma när gruppstatus för resurser har ändrats och kan överföras till en gruppdekoreringsfunktion som en del av en IDecorationContext.