Lorsque vous avez besoin de modifier des ressources dans l'espace de travail, il est important de garder en tête que d'autres plug-ins peuvent utiliser les mêmes ressources. L'API des ressources propose des mécanismes robustes pour tenir les plug-ins informés des modifications intervenues dans l'espace de travail et pour s'assurer que plusieurs plug-ins ne modifient pas les mêmes ressources au même moment. Lorsque cela est possible, les modifications du plug-in que vous apportez à l'espace de travail doivent être regroupées en unités de travail au sein d'un exécutable d'espace de travail. Ces exécutables permettent de réduire la quantité de notifications de modification générées par ces modifications. Ils vous permettent de déclarer la partie de l'espace de travail qui doit être modifiée, afin d'empêcher la modification de la même partie de l'espace de travail pour d'autres plug-ins.
Le protocole deIWorkspaceRunnable est relativement simple. Un exécutable d'espace de travail se présente comme une opération longue ou une tâche de plate-forme. Le travail véritable est effectué dans une méthode run et sa progression est signalé à l'élément IProgressMonitor indiqué. Le code qui permet de manipuler l'espace de travail est développé dans la méthode run.
IWorkspaceRunnable myRunnable = new IWorkspaceRunnable() { public void run(IProgressMonitor monitor) throws CoreException { // le travail véritable est effectué ici ... } }
Lorsqu'il s'agit d'exécuter le code, le plug-in indique à l'espace de travail d'exécuter le code pour son compte. Ainsi, l'espace de travail peut générer des événements de modification nécessaires et s'assurer qu'il n'y a pas deux plug-ins qui modifient la même ressource au même moment (même si le plug-in n'utilise pas de tâches de fond ni la structure concurrente pour modifier l'espace de travail, ce n'est pas forcément le cas des autres plug-ins).
Le protocole IWorkspace est utilisé pour exécuter un exécutable d'espace de travail. La technique préférée est d'utiliser la forme développée de la méthode run, qui fournit une règle de planification et spécifie la manière dont les événements de modification n de ressource sont diffusés.
Si vous spécifiez une règle de planification lors de l'exécution d'un exécutable d'espace de travail, l'espace de travail a la possibilité de déterminer si les modifications des ressources entrent en conflit avec les modifications de l'espace de travail qui ont lieu sur d'autres unités d'exécution (Pour plus d'informations sur les règles de planification, reportez-vous à la section Règles de planification et au protocole ISchedulingRule). Heureusement, le protocole IResource inclut le protocole pour ISchedulingRule, ce qui signifie qu'une ressource peut souvent être utilisée comme règle de planification pour elle-même.
Cela peut paraître compliqué. Le code peut permettre d'éclaircir ce point. Imaginez que le plug-in soit prêt à modifier un groupe de ressources d'un projet donné. Il peut utiliser le projet lui-même comme règle de planification pour apporter les modifications. Le fragment de code ci-dessous exécute l'exécutable d'espace de travail que vous avez créé précédemment :
IWorkspace workspace = ResourcesPlugin.getWorkspace(); workspace.run(myRunnable, myProject, IWorkspace.AVOID_UPDATE, null);
L'exécutable est transmis à l'espace de travail, suivi par le projet que le code manipule. Cette opération indique à l'espace de travail que toutes les modifications apportées à l'exécutable ne s'appliquent qu'à myProject. Les demandes provenant des autres unités d'exécution pour modifier myProject seront bloquées tant que cet exécutable n'est pas interrompu. De même, cet appel est bloqué si d'autres unités d'exécution sont déjà en train de modifier myProject. En spécifiant la partie de l'arborescence des ressources qui va être modifiée par l'exécutable, vous permettez aux autres unités d'exécution de continuer à modifier les autres parties de l'espace de travail. Il est important de s'assurer que la règle des ressources correspond au travail effectué dans l'exécutable. Toute tentative d'accès à une ressource en dehors de la portée de la règle de planification déclenche une exception.
Le troisième paramètre de la méthode run indique si des événements de modification de ressource périodiques doivent être diffusés dans le cadre de la portée de cet appel. En utilisant IWorkspace.AVOID_UPDATE, vous indiquez à la plate-forme de supprimer des événements de modification de ressource alors que l'exécutable est exécuté et de diffuser un événement à la fin des modifications. Lors de cet appel, les autres exécutables créés dans l'exécutable sont considérés comme faisant partie de l'opération par lot parent. Les modifications apportées aux ressources dans ces exécutables s'affichent dans la notification de modification des ressources du parent.
Dans l'exemple ci-dessus, nous sommes partis du principe que le code dans l'exécutable ne modifiait des ressources que pour un projet déterminé. Cela a permis de spécifier une règle de planification pour l'exécutable. Dans la pratique, il peut s'avérer plus difficile de calculer les parties de l'espace de travail qui sont concernées par une modification en particulier. Par exemple, si vous déplacez une ressource d'un projet à un autre, cette modification affecte les deux projets. IResourceRuleFactory peut être utilisé pour calculer une règle de ressource appropriée pour certains types de modification de ressource. Vous pouvez obtenir une fabrique de règle de ressource dans l'espace de travail proprement dit.
IWorkspace workspace = ResourcesPlugin.getWorkspace(); IResourceRuleFactory ruleFactory = workspace.getRuleFactory();
La fabrique peut fournir des règles appropriées à un grand nombre d'opérations. Si l'exécutable déplace une ressource d'un emplacement vers un autre, il peut obtenir une règle appropriée pour cette opération :
ISchedulingRule movingRule = ruleFactory.moveResource(sourceResource, destinationResource); workspace.run(myRunnable, movingRule, IWorkspace.AVOID_UPDATE, null);
Pour obtenir la liste des règles disponibles, reportez-vous à la documentation Java pourIResourceRuleFactory. Le plug-in de ressources utilise ces règles pour implémenter la plupart des opérations sur les ressources. Examinez le code qui fait référence à ces méthodes de règle pour découvrir leur utilisation dans la pratique.
Il est possible de combiner plusieurs règles à l'aide de MultiRule.
ISchedulingRule movingRule = ruleFactory.moveResource(sourceResource, destinationResource); ISchedulingRule modifyRule = ruleFactory.modifyResource(destinationResource); workspace.run(myRunnable, MultiRule.combine(movingRule, modifyRule), IWorkspace.AVOID_UPDATE, null);
La forme abrégée de la méthode run dans IWorkspace est également disponible. Elle est conservée pour la compatibilité amont. La forme abrégée n'inclut pas de règle ou d'indicateur de mise à jour.
workspace.run(myRunnable, null);
est identique à
workspace.run(myRunnable, workspace.getRoot(), IWorkspace.AVOID_UPDATE, null);
Si vous spécifiez la racine de l'espace de travail comme règle de planification, un verrou est placé sur l'espace de travail entier jusqu'à la fin des éléments à exécuter. C'est la manière la plus classique d'effectuer une mise à jour de l'espace de travail, mais elle n'est pas vraiment appropriée pour les autres plug-ins.