Ressourcer og filsystem

Når platformen udføres, og ressource-plugin'en er aktiv, repræsenteres arbejdsområdet af en IWorkspace-forekomst, som stiller protokollen, der giver adgang til de indeholdte ressourcer, til rådighed. En IWorkspace-forekomst repræsenterer en tilknyttet samling filer og biblioteker i et eller flere filsystemer. Du kan få adgang til arbejdsområdet fra ressource-plugin-klassen (defineret i org.eclipse.core.resources).

IWorkspace arbejdsområde = ResourcesPlugin.getWorkspace();

Når ressource-plugin'en ikke udføres, findes arbejdsområdet kun i filsystemet, hvor det kan vises for og arbejdes med af brugeren via filbaserede standardværktøjer. I det følgende gennemgås, hvordan et arbejdsområde ser ud på disken, og ressource-plugin'ens API forklares.

Eksempel på diskens træstruktur

Da du startede SDK på platformen, blev du bedt om at angive biblioteket for arbejdsområde. I dette bibliotek gemmer forskellige plugins metadata af interesse, der er entydige for en bestemt forekomst af platformen. Som standard gemmer ressourceplugin'en hvert projekt i et underbibliotek til arbejdsområdebiblioteket. Disse underbiblioteker indeholder de foldere og filer, som hvert projekt består af.

Antag, at du vælger biblioteket c:\MinSDK\arbejdsomraede til dit arbejdsområde. I dette bibliotek finder du underbibliotekerne, der er opkaldt efter arbejdsområdets projekter, MinWeb og MinMiniserver. Disse kaldes projekternes indholdsbiblioteker. Indholdsbibliotekerne oprettes af platformen, når en bruger opretter et projekt.

I hvert bibliotek findes projektets filer og foldere, og deres træstruktur er den samme som i arbejdsområdets træstruktur. Alle filnavne er de samme og indholdet af filerne er det samme, uanset om de åbnes via filsystemet eller arbejdsområdet. Den eneste fil, der skiller sig ud fra de andre, er filen .project. Denne gennemgås senere.

   C:\MinSDK\arbejdsomraede  (arbejdsområdets rod)
      .metadata\ (platformens metadata-bibliotek)
      MinWeb\ (projektets indholdsbibliotek for MinWeb)
	 .project
         index.html
         images\
            logo.png
      MinMiniserver\ (projektets indholdsbibliotek for MinMiniserver)
	 .project
         src\
            main.java
         bin\
            main.class

Platformen har et særligt .metadata-bibliotek til opbevaring af interne platformoplysninger. .metadata-biblioteket i et arbejdsområde betragtes som en "sort boks". Vigtige oplysninger om arbejdsområdets struktur, f.eks. et projekts referencer eller en ressources egenskaber, er lagret i metadatadelen af arbejdsområdet, og kun værktøjer kan få adgang til dette bibliotek via platformens API. Disse filer bør aldrig redigeres eller arbejdes med vha. filsystemets generiske API.

Desuden har hvert projekt sin egen .project-fil, hvor metadata om projektet opbevares. Indholdet af denne fil på disken svarer nøjagtigt til de oplysninger, der findes i et projekts IProjectDescription.  

Bortset fra biblioteket .metadata og .project-filerne er foldere og filer til fri afbenyttelse for andre værktøjer. Ikke-integrerede værktøjer, som f.eks. teksteditorer og filsystemprogrammer, kan arbejde med filer og foldere. Brugeren skal blot være forsigtig ved redigering af disse filer både på arbejdsbænken og eksternt. (Det er det samme som, når en bruger redigerer en fil vha. to uafhængige enkeltstående værktøjer). Arbejdsbænken stiller opfriskningsfunktioner til rådighed, så arbejdsområdets oversigt over ressourcer kan afstemmes med filsystemets aktuelle tilstand, og arbejdsområdet opfriskes periodisk på basis af filsystemets tilstand.

Eksempel på træstruktur i kode

Ved hjælp af ressource-API'et kan du arbejde med denne ressourcetræstruktur i kode. I det følgende vises nogle stykker kode for at give en forsmag på ressource-API'et. Ressource-API'et defineres i en række grænseflader i org.eclipse.core.resources. Der er grænseflader for alle ressourcetyper, f.eks. IProject, IFolder og IFile. En bred fællesprotokol er defineret i IResource. Det er også muligt at bruge org.eclipse.core.runtime-grænsefladen IPath, som repræsenterer segmenterede stier, f.eks. ressource- eller filsystemstier.

At arbejde med ressourcer er omtrent det samme som at arbejde med filer vha. java.io.File. API'et er baseret på referencer. Når du bruger et getProject- eller getFolder-API, returneres en reference til ressourcen.  Der er ingen garanti for eller krav om, at ressourcen findes, før du prøver at gøre noget med referencen. Hvis du forventer, at en ressource findes, kan du bruge metoden exists til at sikre dig, at det er tilfældet.  

Hvis du vil navigere arbejdsområdet fra en plugin, skal du først hente IWorkspaceRoot, som repræsenterer toppen af ressourcehierarkiet i arbejdsområdet .

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

Når først du har en arbejdsområderod, kan du få adgang til projekter i arbejdsområdet.

   IProject myWebProject = myWorkspaceRoot.getProject("MyWeb");
   // åbn, hvis nødvendigt
   if (myWebProject.exists() && !myWebProject.isOpen())
      myWebProject.open(null);

Inden du kan arbejde med et projekt, skal du åbne det. Når projektet åbnes, læses projektets struktur fra disken, og objektrepræsentationen af projektets ressourcetræstruktur oprettes i hukommelsen. Åbning af et projekt er en eksplicit funktion, da hvert åbent projekt bruger hukommelse til at repræsentere ressourcetræstrukturen internt, og åbne projekter deltager i diverse livscyklusaktiviteter for ressourcer (f.eks. bygning), som kan tage lang tid. Som regel er der ikke adgang til lukkede projekter, og de vises tomme, selvom ressourcerne stadig findes i filsystemet.

Bemærk, at mange af disse ressourceeksempler sender en Null-parameter ved manipulation af ressourcer. Mange ressourcefunktioner er så tunge, at de berettiger statusrapportering og brugerannullering. Hvis koden har en brugergrænseflade, overfører du typisk en IProgressMonitor, som tillader ressource-plugin'en at rapportere om status, efterhånden som der arbejdes med ressourcen, og giver brugeren mulighed for at annullere funktionen. Nu sendes null for at angive, at der ikke skal foretages statusovervågning.

Når du har åbnet et projekt, kan du få adgang til dets foldere og filer, og du kan desuden også oprette yderligere. I følgende eksempel oprettes en filressource fra indholdet af en fil, der er placeret i arbejdsområdet.

   IFolder imagesFolder = myWebProject.getFolder("images");
   if (imagesFolder.exists()) {
      // opretter en ny fil
      IFile newLogo = imagesFolder.getFile("newLogo.png");
      FileInputStream fileStream = new FileInputStream(
         "c:/MyOtherData/newLogo.png");
      newLogo.create(fileStream, false, null);
      // create lukker filstrømmen.
   }

I ovenstående eksempel henter den første linje en reference til billedfolderen. Du skal kontrollere, at folderen exists (findes), inden du gøre noget med den. På samme måde når filen newLogo hentes, repræsenterer referencen ikke en egentlig fil, før du opretter filen i sidste linje. I dette eksempel opretter du filen ved at udfylde den med indholdet af logo.png.

Det næste stykke kode ligner den forrige, bortset fra at den kopierer filen newLogo fra det oprindelige logo frem for at oprette et nyt fra indholdet.

   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");
      ...
   }

Til sidst skal du oprette en yderligere billedfolder og flytte den nyoprettede fil til den. Du skal omdøbe filen i stedet for at flytte 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");

Mange af ressource-API-metoderne indeholder et gennemtvunget boolesk flag, som angiver, om ressourcer, som ikke er synkrone med de tilsvarende filer i filsystemet, skal opdateres alligevel. I IResource finder du flere oplysninger. Du kan også bruge IResource.isSynchronized til at bestemme, om en bestemt ressource er synkron med filsystemet.

Tilknyt ressourcer til diskplaceringer vha. mapping

I eksemplet på ressourcetræstrukturen antages det, at alle projektets indholdsbiblioteker er i biblioteket arbejdsomraede under platformens rodbibliotek (C:\MinSDK\arbejdsomraede). Det er standardkonfigurationen for projekter.  Men et projekts indholdsbibliotek kan knyttes til et vilkårligt bibliotek i et filsystemet i baggrunden, måske endda på en anden maskine.

Muligheden for at tilknytte placeringen af et projekt uafhængigt af andre projekter vha. mapping gør det muligt for brugeren at gemme indholdet af et projekt et sted, der giver mening for projektet og projektteamet. Et projekts indholdsbibliotek skal betragtes som værende "ude i det åbne". Det betyder, at brugere kan oprette, ændre og slette ressourcer vha. arbejdsbænken og plugins eller direkte vha. filsystemet på basis af værktøjer og editorer.

Ressourcestinavne er ikke komplette filsystemstier. Ressourcestier er altid baseret på projektets placering (som regel arbejdsområde-biblioteket). For at få den fuldstændige filsystemsti til en ressource skal du forespørge på dens placering vha. IResource.getLocationURI. Men du kan ikke bruge IProjectDescription.setLocation til at ændre dens placering, fordi metoden blot er til angivelse af en datastruktur.  

Hvis du omvendt vil hente det tilsvarende ressourceobjekt ud fra en given systemsti, kan du bruge IWorkspaceRoot.findFilesForLocationURI eller IWorkspaceRoot.findContainersForLocationURI.

Ressource-API og filsystem

Når du bruger ressource-API'et til at ændre arbejdsområdets ressourcetræstruktur, ændres filerne i filsystemet, foruden at ressourceobjekterne opdateres. Hvordan finder ændringer til ressourcefiler sted, når de sker uden for platformens API?

Eksterne ændringer til ressourcer afspejles ikke i arbejdsområdet og ressourceobjekter, før de registreres af ressource-plugin'en. Ressource-plugin'en bruger også en mekanisme, der er relevant for det pågældende indbyggede operativsystem, til registrering af eksterne ændringer, som er foretaget i filsystemet. Desuden kan klienter bruge ressource-API'et til at afstemme arbejdsområdet og ressourceobjekter med det lokale filsystem uden brugerintervention. Brugeren kan også eksplicit gennemtvinge en opfriskning på arbejdsbænkens oversigt Resource Navigator.

Mange af metoderne i ressource-API'erne omfatter en gennemtvinge-parameter, som angiver, hvordan ressourcer, som ikke er synkrone med filsystemet, skal håndteres. API-referencen for hver metode stiller specifikke oplysninger om denne parameter til rådighed. Yderligere metoder i API'et tillader programmatisk styring af opfriskning af filsystemet, f.eks. IResource.refreshLocal(int depth, IProgressMonitor monitor). I IResource finder du flere oplysninger om korrekt brug og omkostninger.

Plugins, der ønsker at levere deres egen mekanisme, som er baseret på det eksterne filsystems tilstand, til periodisk opfriskning af arbejdsområdet kan benytte udvidelsespunktet org.eclipse.core.resources.refreshProviders. I Opfrisk udbydere finder du flere oplysninger.