Resurser och filsystemet

När plattformen körs och resursens insticksprogram är aktivt motsvaras arbetsytan av en förekomst av IWorkspace, som tillhandahåller protokoll för access till de resurser som ingår på arbetsytan. En förekomst av IWorkspace representerar en associerad samling filer och kataloger i ett eller flera filsystem. Du kan accessa arbetsytan från resursens insticksprogramklass (som definieras i org.eclipse.core.resources).

   IWorkspace workspace = ResourcesPlugin.getWorkspace(); 

När resursens insticksprogram inte körs finns arbetsytan endast i filsystemet och kan visas eller ändras av användaren genom filbaserade standardverktyg. Vi kan studera hur en arbetsyta ser ut på disk medan vi förklarar APIt för resursens insticksprogram.

Vårt exempelträd på disk

När du startade SDK för plattformen uppmanades du att ange en katalog som arbetsyta. Det är den katalog där olika insticksprogram lagrar intressanta metadata som är unika för en viss förekomst av plattformen. Som standard lagrar resursinsticksprogrammet varje projekt i en underkatalog till arbetsytekatalogen. Inom de här underkatalogerna finns de mappar och filer som varje projekt innehåller.

Anta att du väljer katalogen c:\MySDK\workspace som arbetsyta. I den här katalogen finns underkataloger namngivna efter projekten i arbetsytan, MyWeb and MyServlet. De kallas innehållskataloger för projektet. Innehållskataloger skapas av plattformen när användaren skapar ett projekt.

I varje katalog hittar vi de filer och mappar som ingår i projektet, med exakt samma trädstruktur som i arbetsytans resursträd. Alla filnamn är desamma, och filernas innehåll är detsamma vare sig de accessas från filsystemet eller från arbetsytan. Det enda som inte stämmer med det övriga är filen .project, som strax kommer att beskrivas.

   C:\MySDK\workspace (arbetsytans rot)
      .metadata\ (plattformens metadatakatalog)
      MyWebb\ (projektinnehållskatalog för MyWeb)
	 .project
         index.html
         images\
            logo.png
      MyServlet\ (projektinnehållskatalog för MyServlet)
	 .project
         src\
            main.java
         bin\
            main.class

Plattformen har en speciell .metadata-katalog för plattformsintern information. Katalogen .metadata för en arbetsyta betraktas som en "svart låda". Viktig information om arbetsytans struktur, t.ex. projektreferenser eller resursegenskaper, lagras i metadatadelen av arbetsytan och ska accessas endast av verktyg genom plattformens API.  De här filerna ska aldrig redigeras eller ändras med det generiska filsystemets API.

Dessutom har varje projekt sin egen .project-fil, med metadata om projektet.  Den här filen är egentligen en motsvarighet på disk till den information som finns i ett projekts IProjectDescription.  

Bortsett från katalogen .metadata och filen .project är mapparna och filerna i arbetsytekatalogen helt öppna för andra verktyg.  Det går att ändra filerna och mapparna med verktyg som inte är integrerade, t.ex. textredigerare och verktyg i filsystemet.  Det enda som kan vara ett problem är att användaren måste vara mycket försiktig vid redigeringen av de här filerna, både i arbetsmiljön och externt.  (Det är på samma sätt som när en användare redigerar en fil med två oberoende fristående verktyg.)  I arbetsmiljön finns tillgång till uppdateringsåtgärder som gör att resursvyn i arbetsmiljön visar faktisk status i filsystemet och ett alternativ för regelbunden uppdatering av arbetsytan baserat på status för filsystemet.

Vårt exempelträd i kod

Genom resursens API kan vi ändra resursträdet i kod. Vi ska titta på några delar av koden så att vi får en uppfattning om resurs-APIt. Resurs-APIt definieras i en serie gränssnitt i org.eclipse.core.resources. Det finns gränssnitt för alla resurstyper, till exempel IProject, IFolder och IFile. Ett omfattande gemensamt protokoll definieras i IResource. VI utnyttjar också org.eclipse.core.runtime-gränssnittet IPath, som representerar segmenterade sökvägar, till exempel resurssökvägar eller filsystemsökvägar.

Att ändra resurser påminner mycket om att ändra filer med hjälp av java.io.File.  APIt baseras på handtag.  När du använder APIn som getProject eller getFolder returneras ett handtag till resursen.   Det finns inga garantier för eller krav på att själva resursen ska finnas förrän du försöker göra något med handtaget.  Om du räknar med att en resurs ska finnas kan du använda metoden exists till att kontrollera att det stämmer.  

När vi ska navigera på arbetsytan från ett insticksprogram måste vi först hämta IWorkspaceRoot, som representerar den översta nivån av resurshierarkin på arbetsytan.

   IWorkspaceRoot myWorkspaceRoot = ResourcesPlugin.getWorkspace().getRoot();

När vi har en arbetyterot kan vi accessa projekten på arbetsytan.

   IProject myWebProject = myWorkspaceRoot.getProject("MyWeb");
   // öppna om det behövs
   if (myWebProject.exists() && !myWebProject.isOpen())
      myWebProject.open(null);

Innan vi kan ändra ett projekt måste vi öppna det. När vi öppnar projektet läses projektstrukturen från disk och sedan skapas objektrepresentationen av projektets resursträd som finns i minnet. Att öppna ett projekt är en explicit åtgärd eftersom varje öppet projekt förbrukar minne till den interna representationen av resursträdet och öppna projekt medverkar i olika händelser för resursens livscykel (t.ex. bygge), vilket kan ta lång tid.  I allmänhet går det inte att accessa stängda projekt. De visas tomma även om resursen fortfarande finns i filsystemet.

Du kommer att märka att många av de här resursexemplen skickar parametern null när resurserna ändras. Många resursåtgärder är potentiellt tillräckligt tunga för att säkerställa att förloppen rapporteras och att användaren kan avbryta åtgärden. Om koden har ett användargränssnitt kan du vanligtvis skicka IProgressMonitor, vilket gör att resursens insticksprogram rapporterar förloppet när resursen ändras och att användaren kan avbryta åtgärden.  Nu skickar vi helt enkelt null, vilket anger att förloppet inte övervakas.

När vi har ett öppet projekt kan vi accessa mapparna och filerna i det och vi kan skapa ytterligare projekt.  I följande exempel skapar vi en filresurs från innehållet i en fil som finns utanför vår arbetsyta.

   IFolder imagesFolder = myWebProject.getFolder("images");
   if (imagesFolder.exists()) {
      // skapa en ny fil
      IFile newLogo = imagesFolder.getFile("newLogo.png");
      FileInputStream fileStream = new FileInputStream(
         "c:/MyOtherData/newLogo.png");
      newLogo.create(fileStream, false, null);
      // create stänger filströmmen, så det är inga problem.  
   }

I exemplet ovan får den första raden ett handtag till bildmappen.  Vi måste kontrollera att mappen finns innan vi kan göra något intressant med den.  På samma sätt gäller att när vi hämtar filen newLogo representerar handtaget inte en verklig fil förrän vi skapar filen på sista raden.  I det här exemplet skapar vi filen genom att fylla den med innehåll från logo.png.

Nästa del av koden liknar den förra, bortsett från att den kopierar filen newLogo från den ursprungliga logotypen i stället för att skapa en ny från innehållet.

   IFile logo = imagesFolder.getFile("logo.png");
   if (logo.exists()) {
      IPath newLogoPath = new Path("newLogo.png");
      logo.copy(newLogoPath, false, null);
      IFile newLogo = imagesFolder.getFile("newLogo.png");
      ...
   }

Slutligen skapar vi en annan bildmapp och flyttar den nyss skapade filen till den. Samtidigt som vi flyttar filen ändras namnet på den.

   ...
   IFolder newImagesFolder = myWebProject.getFolder("newimages");
   newImagesFolder.create(false, true, null);
   IPath renamedPath = newImagesFolder.getFullPath().append("renamedLogo.png");
   newLogo.move(renamedPath, false, null);
   IFile renamedLogo = newImagesFolder.getFile("renamedLogo.png");

Många av metoderna i resurs-APIt inbegriper den booleska flaggan force. Den anger om resurser som inte är synkroniserade med motsvarande filer i filsystemet ska uppdateras ändå eller om de inte ska uppdateras.  Mer information finns i IResource.  Du kan också använda IResource.isSynchronized till att avgöra om en viss resurs är synkroniserad med filsystemet eller inte.

Avbilda resurser till diskplaceringar

När det gäller exempelresursträdet förutsatte vi att alla innehållskataloger för projektet finns i katalogen arbetsyta under plattformens rotkatalog (C:\MySDK\workspace). Det är standardkonfigurationen för projekt.  En innehållskatalog för ett projekt kan avbildas till valfri katalog i vissa bakomliggande filsystem, kanske även till en annan dator.

Tack vare möjligheten att avbilda placeringen för ett projekt oberoende av andra projekt kan användaren lagra innehållet i ett projekt på en plats som är praktisk för projektet och projektgruppen. Innehållskatalogen för ett projekt bör betraktas som "offentligt", vilket innebär att användarna kan skapa, ändra och ta bort resurser med hjälp av arbetsmiljön och insticksprogram eller genom att använda filsystembaserade verktyg och redigerare direkt.

Sökvägsnamn för resurser är inte fullständiga filsystemsökvägar. Resurssökvägar är alltid baserade på projektets placering (vanligtvis katalogen arbetsyta).  Om du vill ta reda på den fullständiga filsystemsökvägen till en resurs måste du ställa en fråga med hjälp av IResource.getLocationURI.  Men du kan inte använda IProjectDescription.setLocation till att ändra placeringen eftersom den metoden bara är en enkel set-metod för en datastruktur.  

Omvänt gäller att om du vill hämta ett resursobjekt med utgångspunkt från en filsystemsökväg använder du IWorkspaceRoot.findFilesForLocationURI eller IWorkspaceRoot.findContainersForLocationURI.

Resurs-API och filsystemet

När vi använder resurs-APIt till att ändra resursträdet för arbetsytan kommer filerna att ändras i filsystemet utöver att resursobjeken uppdateras. Vad gäller då för ändringar i resursfiler som utförs utanför plattformens API?

Externa resursändringar kommer inte att reflekteras på arbetsytan och resursobjekten förrän de hittas av resursens insticksprogram. Resursens insticksprogram använder också en mekanism som lämpar sig för varje särskilt operativsystem för upptäckt av externa ändringar i filsystemet. Dessutom kan klienterna använda resurs-APIt till att i bakgrunden och utan användaråtgärder få arbetsytan och resursobjekten att överensstämma med det lokala filsystemet. Användaren kan också explicit tvinga fram en uppdatering i resursens navigeringsvy för arbetsmiljön.

Många av metoderna i resurs-APIt inbegriper parametern force, som anger hur resurser som inte är synkroniserade med filsystemet ska behandlas. API-referensen för varje metod ger specifik information om den här parametern. Det finns ytterligare metoder i APIt som ger möjlighet att styra filsystemuppdateringen med programmering, t.ex. IResource.refreshLocal(int depth, IProgressMonitor monitor). Mer information om kostnad och rätt syntax finns i IResource.

Det går att använda insticksprogrammens egna mekanismer för regelbunden uppdatering av arbetsytan baserat på det externa filsystemet med hjälp av utökningspunkten org.eclipse.core.resources.refreshProviders. Mer information finns i Uppdatera provider.