Les ressources et le système de fichiers local

Lorsque l'API principale de la plateforme est en cours d'exécution et que le plug-in des ressources est actif, l'espace de travail est représenté par une instance de IWorkspace qui fournit le protocole permettant d'accéder aux ressources qu'il contient. Une instance IWorkspace représente une collection de fichiers et de répertoires associés dans le système de fichiers local. Vous pouvez accéder à l'espace de travail à partir de la classe du plug-in des ressources dans org.eclipse.core.resources.

ResourcesPlugin.getWorkspace();

Lorsque le plug-in des ressources n'est pas en cours d'exécution, l'espace de travail existe uniquement dans le système de fichiers local et est visualisé ou manipulé par l'utilisateur via des outils basés sur un fichier standard. Regardons ce à quoi ressemble un espace de travail sur le disque tout en expliquant l'API du plug-in des ressources.

Notre exemple d'arborescence sur un disque

Lors de l'installation de la plateforme SDK, vous avez dézippé les fichiers dans un répertoire de votre choix. Nous allons appeler ce répertoire le répertoire racine de la plateforme. Il s'agit du répertoire qui contient entre autre, le répertoire plugins. A l'intérieur du répertoire racine de la plateforme, se trouve un répertoire workspace (espace de travail) utilisé pour stocker les ressources qui sont créées et manipulées par la plateforme. Si vous consultez ce répertoire, vous verrez qu'il contient des sous-répertoires pour chaque projet existant dans l'espace de travail. A l'intérieur de ces sous-répertoires figurent les dossiers et les fichiers que chaque projet contient.

Si le SDK de notre exemple est installé dans c:\MySDK, alors à l'intérieur du répertoire c:\MySDK\workspace, nous trouvons des sous-répertoires sous les projets de l'espace de travail, MyWeb et MyServlet. Il s'agit des répertoires des programmes des projets. Les répertoires des programmes sont créés par la plateforme lorsque l'utilisateur crée un projet.

A l'intérieur de chaque répertoire, figurent les fichiers et les dossiers du projet, présentés exactement comme dans l'arborescence des ressources de l'espace de travail. Tous les noms de fichiers sont identiques et le contenu des fichiers est le même qu'ils soient accédés à partir du système de fichiers ou de l'espace de travail. Cela reste sans surprise.

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 plateforme comporte un répertoire spécial .metadata destiné aux informations internes de la plateforme. Le répertoire .metadata d'un espace de travail est considéré comme une "boîte noire". Les informations importantes concernant la structure de l'espace de travail, telles que les références d'un projet ou les propriétés d'une ressource, sont stockées dans les métadonnées de l'espace de travail et ne doivent être accédées que par des outils via l'API de la plateforme. Ces fichiers ne doivent jamais être édités ou manipulés à l'aide de l'API du système de fichiers générique.

Hormis le répertoire .metadata, les dossiers et les fichiers du répertoire de l'espace de travail sont accessibles par d'autres outils. Les fichiers et les dossiers peuvent être manipulés par des outils indépendants, tels que des éditeurs de texte et des utilitaires de système de fichiers. Cependant, l'utilisateur doit être attentif lors de l'édition de ces fichiers dans le plan de travail et en dehors de ce dernier. (Il n'y a pas de différence lorsqu'un utilisateur édite un fichier à l'aide de deux outils autonomes et indépendants.) Le plan de travail fournit des opérations de régénération pour synchroniser la vue des ressources dans l'espace de travail avec l'état réel dans le système des fichiers.

Notre exemple d'arborescence dans le code

L'API des ressources permet de manipuler cette arborescence de ressources dans le code. Nous allons examiner plusieurs extraits de code pour avoir un rapide aperçu de l'API des ressources. Cette dernière est définie dans une série d'interfaces dans org.eclipse.core.resources. Il existe des interfaces pour tous les types de ressources, tels que IProject, IFolder et IFile. Un protocole commun extensif est défini dans IResource. Nous utilisons également IPath de l'interface org.eclipse.core.runtime qui représente des chemins d'accès segmentés, des chemins d'accès au système de fichiers ou à une ressource par exemple.

La manipulation des ressources est très similaire à celle des fichiers avec java.io.File. L'API est basée sur les descripteurs. Lorsque vous utilisez une API telle que getProject ou getFolder, vous recevez un descripteur de la ressource. Il n'existe aucune garantie, ni exigence que la ressource elle-même existe tant que vous n'essayez pas de faire quelque chose avec le descripteur. Si vous vous attendez à ce qu'une ressource existe, vous pouvez utiliser le protocole exists() pour vous assurer que c'est le cas.

Pour naviguer dans l'espace de travail à partir d'un plug-in, nous devons d'abord obtenir IWorkspaceRoot, qui représente le niveau le plus haut dans la hiérarchie des ressources de l'espace de travail.

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

Dès que nous avons une racine de l'espace, nous pouvons accéder aux projets dans l'espace de travail.

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

Pour pouvoir manipuler un projet, celui-ci doit d'abord être ouvert. L'ouverture du projet lit la structure du projet à partir du disque et crée la représentation objet en mémoire de l'arborescence des ressources du projet. L'ouverture d'un projet est une opération explicite du fait que chaque projet ouvert consume de la mémoire pour représenter l'arborescence des ressources en interne et les projets ouverts participent à des événements du cycle de vie des ressources (la génération par exemple) qui peuvent s'avérer interminables. En règle générale, les projets fermés ne peuvent pas être accédés et apparaissent vides mêmes si les ressources sont toujours présentes dans le système de fichiers.

Vous noterez que de nombreux exemples de ressource transmettent un paramètre null lors de la manipulation des ressources. De nombreuses opérations de ressource sont potentiellement suffisamment lourdes pour garantir la génération de rapport de progression et l'annulation utilisateur. Si votre code dispose d'une interface utilisateur, vous transmettrez généralement un IProgressMonitor qui permet au plug-in des ressources de générer un rapport de progression à mesure que les ressources sont manipulées et à l'utilisateur d'annuler l'opération s'il le souhaite. Pour le moment, nous transmettons simplement la valeur null, indiquant qu'il n'y a pas de contrôle de la progression.

Dès que nous disposons d'un projet ouvert, nous pouvons accéder à ses dossiers et à ses fichiers, et en créer d'autres. Dans l'exemple ci-dessous, nous créons une ressource de fichier à partir du contenu d'un fichier externe situé en dehors de notre espace de travail.

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

Dans l'exemple ci-dessus, la première ligne obtient un descripteur du dossier des images. Nous devons vérifier que le dossier existe avant de pouvoir faire quelque chose d'intéressant avec. De même, lorsque nous extrayons le fichier newLogo, le descripteur ne représente pas un fichier réel jusqu'à ce que le fichier soit créé à la dernière ligne. Dans cet exemple, nous créons le fichier en le remplissant avec le contenu de logo.gif.

L'extrait suivant est similaire au précédent, mais il copie le fichier newLogo du logo d'origine plutôt que d'en créer un à partir de son contenu.

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

Enfin, nous allons créer un autre dossier d'images et déplacer le fichier nouvellement créé dedans. Comme effet secondaire de son déplacement, nous renommons le fichier.

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

 

Un grand nombre de méthodes d'API de ressources inclut un indicateur booléen force qui spécifie si les ressources situées en dehors de la synchronisation avec les fichiers correspondants du système de fichiers local seront mises à jour. Pour plus d'informations, reportez-vous à la section IResource.

Mappage des ressources sur les emplacements du disque

Dans l'exemple d'arborescence des ressources, nous avons présumé que tous les répertoires des programmes de projet se trouvent dans le répertoire workspace sous le répertoire racine de la plateforme (C:\MySDK\workspace). Il s'agit de la configuration par défaut des projets. Cependant, le répertoire des programmes d'un projet peut être remappé sur n'importe quel répertoire du système de fichiers, éventuellement sur une autre unité de disque.

La capacité de mapper l'emplacement d'un projet indépendamment des autres projets permet à l'utilisateur de stocker le contenu d'un projet à un endroit qui tombe sous le sens pour le projet et l'équipe du projet. Le répertoire des programmes (contenu) d'un projet doit être considéré comme étant "en dehors". Ceci signifie que les utilisateurs peuvent créer, modifier et supprimer des ressources à l'aide du plan de travail et des plug-ins, ou en utilisant directement le système de fichiers basé sur les outils et les éditeurs.

Les noms des chemins d'accès aux ressources ne sont pas des chemins d'accès complets au système de fichiers. Les chemins d'accès sont toujours basés sur l'emplacement du projet (généralement le répertoire de l'espace de travail). Pour obtenir le chemin d'accès complet du système de fichiers à une ressource, vous devez requérir son emplacement à l'aide de IResource.getLocation().

Vous pouvez déterminer l'emplacement du système de fichiers d'une ressource particulière endemandant son emplacement à l'aide de getLocation(). Cependant, vous ne pouvez pas utiliser IProjectDescription.setLocation pour modifier son emplacement, car la méthode n'est qu'un simple setter pour une structure de données.

L'API des ressources et le système de fichiers

Lorsque nous utilisons l'API des ressources pour modifier l'arborescence des ressources de notre espace de travail, les fichiers sont modifiés dans le système de fichiers en plus de la mise à jour des objets ressources. Qu'en est-il des modifications apportées aux fichiers de ressources en dehors de l'API de la plateforme ?

Les modifications externes aux ressources ne sont pas reflétées dans l'espace de travail et les objets ressource tant qu'elles ne sont pas détectées par le plug-in des ressources. Les clients peuvent utiliser une ressource pour synchroniser l'espace de travail et les objets ressource avec le système de fichiers local, simplement et sans intervention de l'utilisateur. Ce dernier peut toujours forcer une régénération de manière explicite dans la vue du navigateur des ressources du plan de travail.

Remarque : Un grand nombre de méthodes des API de ressources inclut un paramètre "force" qui spécifie le mode de traitement des ressources situées en dehors de la synchronisation avec le système de fichiers. Les références de l'API pour chaque méthode fournissent des informations spécifiques sur ce paramètre. Des méthodes supplémentaires de l'API permettent un contrôle programmatique de la régénération du système de fichiers, tel que IResource.refreshLocal(int depth, IProgressMonitor monitor). Pour plus d'informations sur les coûts et l'utilisation correcte de ces méthodes, reportez-vous à la section IResource.