Risorse e file system locale

Quando l'elemento centrale della piattaforma è in esecuzione e il plug-in delle risorse è attivo, l'area di lavoro viene rappresentata mediante un'istanza di IWorkspace, che fornisce il protocollo per l'accesso alle risorse contenute. Un'istanza IWorkspace rappresenta una raccolta associata di file e directory all'interno del file system locale. L'utente può accedere all'area di lavoro dalla classe del plug-in delle risorse in org.eclipse.core.resources.

ResourcesPlugin.getWorkspace();

Quando il plug-in delle risorse non è in esecuzione, l'area di lavoro è presente solo nel file system locale e viene visualizzata o modificata dall'utente attraverso gli strumenti standard basati su file. Mentre viene illustrata l'API del plug-in di risorse, verrà descritto come appare l'area di lavoro sul disco.

La struttura di esempio sul disco

Quando è stato installato l'SDK della piattaforma, i file sono stati decompressi in una directory scelta dall'utente.  Questa directory verrà detta directory principale della piattaforma. Questa è la directory che contiene, tra le altre, la directory plugins. All'interno della directory principale della piattaforma, è presente una directory workspace che viene utilizzata per conservare le risorse create e manipolate dalla piattaforma.  Esaminando la directory workspace, è possibile individuare sottodirectory separate per ciascun progetto esistente nell'area di lavoro. All'interno di queste sottodirectory sono conservate le cartelle e i file che ogni progetto contiene.

Se, nell'esempio, SDK è installato in c:\MySDK, all'interno della directory c:\MySDK\workspace, dopo i progetti dell'area di lavoro sono presenti sottodirectory denominate MyWeb e MyServlet. Queste vengono dette directory del contenuto dei progetti. Le directory del contenuto vengono create dalla piattaforma quando l'utente crea un progetto.

All'interno di ciascuna directory si trovano i file e le cartelle del progetto, disposte esattamente come appaiono nella struttura delle risorse dell'area di lavoro. Tutti i nomi file sono gli stessi e il loro contenuto rimane lo stesso se si accede dal file system oppure dall'area di lavoro. Nessuna sorpresa.

C:\MySDK\workspace  (workspace root)
    .metadata\ (platform metadata directory
    MyWeb\ (project content directory for MyWeb)
        index.html
        images\
            logo.gif
    MyServlet\ (project content directory for MyServlet)
        src\
            main.java
        bin\
            main.class
            main$$1.class

La piattaforma dispone di una speciale directory .metadata per la conservazione di informazioni interne della piattaforma. La directory .metadata di un'area di lavoro viene considerata come una "scatola nera". Le informazioni importanti relative alla struttura dell'area di lavoro, ad esempio i riferimenti di un progetto oppure le proprietà di una risorsa, vengono memorizzate nella porzione di metadati dell'area di lavoro e l'accesso a tali informazioni dovrebbe avvenire solo mediante strumenti attraverso l'API della piattaforma.  Questi file non dovrebbero mai essere modificati o manipolati mediante API generiche del file system.

Oltre che dalla directory .metadata, le cartelle e i file dell'area di lavoro possono essere modificati da altri strumenti.  I file e le cartelle possono essere manipolati da strumenti non integrati come editor di testo e utilità del file system.  L'unico problema è che l'utente deve fare molta attenzione durante la modifica di questi file, sia nel workbench sia esternamente.  (Avviene lo stesso quando un utente modifica un file utilizzando due strumenti autonomi indipendenti.)  Il workbench fornisce operazioni di aggiornamento per riconciliare la visualizzazione delle risorse nell'area di lavoro con lo stato effettivo all'interno del file system.

La struttura di esempio nel codice

L'API di risorse consente all'utente di manipolare questa struttura di risorse in codice. Per una rapida descrizione dell'API di risorse verranno illustrati alcuni frammenti di codice. L'API di risorse è definita in una serie di interfacce in org.eclipse.core.resources. Esistono interfacce per tutti i tipi di risorse, come IProject, IFolder e IFile. Il protocollo comune completo è definito in IResource. Viene anche utilizzata l'interfaccia di org.eclipse.core.runtime, IPath, che rappresenta percorsi segmentati quali i percorsi di risorsa o di file system.

La manipolazione di risorse è molto simile alla manipolazione di file mediante java.io.File.  L'API si basa su handle.  Quando si utilizzano API come getProject o getFolder, viene restituito un handle per la risorsa.   Fino a quando non si prova ad eseguire qualcosa mediante l'handle, non esiste alcuna garanzia che la risorsa stessa esista.  Per determinare se una risorsa esiste, è possibile utilizzare il protocollo exists().  

Per esplorare l'area di lavoro da un plug-in, è prima necessario ottenere IWorkspaceRoot, che rappresenta il livello più alto della gerarchia delle risorse nell'area di lavoro.

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

Una volta ottenuta la directory principale dell'area di lavoro, è possibile accedere ai progetti in essa contenuti.

IProject myWebProject = myWorkspaceRoot.getProject("MyWeb");
// aprire se necessario
if (myWebProject.exists() && !myWebProject.isOpen())
    myWebProject.open(null);

Prima di poter manipolare un progetto, è necessario aprirlo. L'apertura del progetto provoca la lettura della struttura del progetto dal disco e la creazione della rappresentazione di oggetto in memoria della struttura delle risorse del progetto. L'apertura di un progetto è un'operazione esplicita poiché ogni progetto aperto consuma memoria per rappresentare internamente la struttura delle risorse e perché i progetti aperti partecipano a diversi eventi del ciclo di vita della risorsa (ad esempio la creazione) che possono essere lunghi.  In generale, non è possibile accedere a progetti chiusi e questi ultimi appariranno vuoti anche se le risorse sono ancora presenti nel file system.

Si noterà che molti di questi esempi di risorse trasmettono un parametro null durante la manipolazione di risorse. Molte operazioni di risorse sono potenzialmente abbastanza pesanti da garantire il rapporto sull'avanzamento e sull'annullamento da parte dell'utente. Se il proprio codice dispone di un'interfaccia utente, verrà generalmente trasmesso un IProgressMonitor, che consente al plug-in delle risorse di riportare lo stato di avanzamento mentre la risorsa viene manipolata e permette all'utente di annullare l'operazione.  Per il momento, verrà trasmesso semplicemente null, per indicare nessun controllo di avanzamento.

Quando si dispone di un progetto aperto, è possibile accedere alle cartelle e ai file rispettivi, oltre a crearne di nuovi.  Nell'esempio seguente, viene creata una risorsa di file dal contenuto di un file esterno ubicato al di fuori dell'area di lavoro dell'utente.

IFolder imagesFolder = myWebProject.getFolder("images");
if (imagesFolder.exists()) {
    // creare un nuovo file
    IFile newLogo = imagesFolder.getFile("newLogo.gif");
    FileInputStream fileStream = new FileInputStream(
        "c:/MyOtherData/newLogo.gif");
    newLogo.create(fileStream, false, null);
    fileStream.close();
}

Nell'esempio precedente, la prima riga ottiene un handle per la cartella delle immagini.  L'utente deve controllare che la cartella esista prima di qualsiasi operazione.  Allo stesso modo, quando si ottiene il file newLogo, l'handle non rappresenta un file reale fino a quando l'utente non crea il file nell'ultima riga.  In questo esempio, il file viene creato inserendo in esso il contenuto di logo.gif.

Il seguente frammento di codice è simile al precedente, ad eccezione del fatto che copia il file newLogo dal logo originale anziché crearne uno nuovo dal suo contenuto.

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

Infine, verrà creata un'altra cartella di immagini in cui si sposterà il file appena creato. Come conseguenza dello spostamento, si ridenominerà il file.

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

 

Molti dei metodi dell'API di risorse includono un flag boleano force che specifica se aggiornare le risorse non sincronizzate rispetto ai corrispondenti file del file system locale.  Per ulteriori informazioni, vedere IResource.

Mapping delle risorse alle posizioni sul disco

Nella struttura delle risorse di esempio, si presuppone che tutte le directory del contenuto di progetto si trovino nella directory workspace all'interno della directory principale della piattaforma (C:\MySDK\workspace). Questa è la configurazione predefinita per i progetti.  Tuttavia, una directory del contenuto di progetto può essere riassociata a qualsiasi altra directory del file system, anche su una diversa unità disco.

La capacità di associare la posizione di un progetto indipendente ad altri progetti consente all'utente di memorizzare il contenuto di un progetto in un'ubicazione significativa per il progetto e per il team del progetto. La directory del contenuto di un progetto dovrebbe essere considerata "sempre aperta". Ciò significa che gli utenti possono creare, modificare e cancellare risorse utilizzando il workbench e i plug-in, oppure utilizzando direttamente strumenti e editor basati sul file system.

I nomi di percorso delle risorse non sono percorsi di file system completi. I percorsi delle risorse sono sempre basati sulla posizione del progetto (generalmente, la directory workspace).  Per ottenere il percorso completo del file system per una risorsa, è necessario eseguire una query della posizione utilizzando IResource.getLocation().

È possibile determinare la posizione nel file system di una particolare risorsa eseguendo una query della posizione mediante getLocation().  Tuttavia, non è possibile utilizzare IProjectDescription.setLocation per modificare la posizione, dato che questo è semplicemente un metodo di impostazione per una struttura di dati.  

API di risorse e file system

Quando si utilizzano API di risorse per modificare la struttura delle risorse dell'area di lavoro, oltre ad aggiornare gli oggetti risorsa, i file vengono modificati nel file system. E le modifiche di file di risorse apportate al di fuori dell'API della piattaforma?

Le modifiche esterne alle risorse non verranno riflesse nell'area di lavoro e negli oggetti risorsa fino a quando non vengono rilevate dal plug-in di risorse. I client possono utilizzare l'API di risorse per riconciliare l'area di lavoro e gli oggetti risorsa con il file system locale, in modo automatico e senza l'intervento dell'utente.  L'utente può sempre forzare esplicitamente un aggiornamento  nella visualizzazione del navigator delle risorse del workbench.

Nota:  molti dei metodi delle API di risorse includono un parametro force che specifica il modo in cui devono essere gestite le risorse non sincronizzate con il file system. Il Riferimento API di ciascun metodo fornisce informazioni specifiche su questo parametro. Metodi aggiuntivi presenti nell'API consentono il controllo programmatico dell'aggiornamento del file system, ad esempio IResource.refreshLocal(int depth, IProgressMonitor monitor). Per informazioni sul corretto utilizzo e sui costi, vedere IResource.