Když potřebujete upravit prostředky v pracovním prostoru, je důležité si uvědomit, že ostatní moduly plug-in mohou pracovat se stejnými prostředky. Rozhraní API prostředků nabízí robustní mechanizmy pro informování modulů plug-in o změnách v pracovním prostoru a zajištění toho, že tentýž prostředek není upravován několika moduly plug-in zároveň. Kdekoli je to možné, měly by být úpravy, které váš plug-in v pracovním prostoru provádí, seskupeny v dávkách v jednotkách práce v procesu runnable pracovního prostoru. Tyto procesy runnable pomáhají snížit množství upozornění na změny generovaných změnami. Také umožňují deklarovat, která část pracovního prostoru má být upravena, takže lze zabránit ostatním modulům plug-in ve změnách stejné části pracovního prostoru.
Protokol pro IWorkspaceRunnable je vcelku jednoduchý. Proces runnable pracovního prostoru vypadá jako dlouhodobá operace nebo úkol platformy. Skutečná práce se provádí uvnitř metody run a průběh je hlášen dodané třídě IProgressMonitor. Kód, který manipuluje pracovním prostorem, se provádí uvnitř metody run.
IWorkspaceRunnable myRunnable = new IWorkspaceRunnable() { public void run(IProgressMonitor monitor) throws CoreException { //tady uvnitř provést skutečnou práci ... } }
Když je na čase spustit kód, řekne váš modul plug-in pracovnímu prostoru, aby sám spustil kód. Tímto způsobem může pracovní prostor generovat veškeré nezbytné události změn a zajistit, že žádné dva moduly plug-in nebudou zároveň upravovat stejný prostředek. (I když váš modul plug-in nepoužívá k úpravám pracovního prostoru úlohy na pozadí a strukturu souběžnosti, je možné, že to dělají ostatní moduly plug-in.)
Ke spuštění procesu runnable pracovního prostoru se používá protokol IWorkspace. Preferovanou technikou je použití dlouhé formy metody run, která poskytuje pravilo plánování a udává, jak jsou vysílány události změn prostředků.
Určení pravidla plánování při spouštění procesu runnable pracovního prostoru umožňuje pracovnímu prostoru určit, zda budou změny prostředku v konfliktu se změnami pracovního prostoru, ke kterým dochází v jiných vláknech. (Viz Pravidla plánování, kde naleznete přehled pravidel plánování a protokol ISchedulingRule.) Protokol IResource naštěstí obsahuje protokol pro ISchedulingRule, což znamená, že prostředek může být často použit jako pravidlo plánování pro sebe sama.
Máte v tom zmatek? Možná to pomůže objasnit kód. Předpokládejme, že se váš modul plug-in připravuje na úpravu skupiny prostředků v určitém projektu. Jako pravidlo plánování pro provedení těchto změn může použít samotný projekt. Následující úsek spouští proces runnable pracovního prostoru, který jsme si vytvořili:
IWorkspace workspace = ResourcesPlugin.getWorkspace(); workspace.run(myRunnable, myProject, IWorkspace.AVOID_UPDATE, null);
Proces runnable je předán pracovnímu prostoru, následovaný projektem, kterým kód manipuluje. To pracovnímu prostoru řekne, že se všechny změny v procesu runnable omezují na myProject. Dokud nebude dokončen tento proces runnable, budou jakékoli požadavky na změnu projektu myProject ze strany ostatních vláken blokovány. Podobně bude toto volání blokováno, pokud již myProject upravuje nějaké jiné vlákno. Určením toho, která část stromu prostředku bude procesem runnable upravena, umožňujete ostatním vláknům pokračovat v úpravách ostatních částí pracovního prostoru. Je důležité být si jistý, že vaše pravidlo pro prostředek odpovídá práci, která se provádí uvnitř procesu runnable. Jakýkoli pokus o přístup k prostředku mimo rozsah pravidla plánování spustí výjimku.
Třetí parametr metody run určuje, zda mají být během rozsahu tohoto volání vysílány nějaké periodické události změn prostředků. Použití IWorkspace.AVOID_UPDATE říká platformě, aby potlačila veškeré události změn prostředků, zatímco běží proces runnable, a aby po ukončení změn vyslala jednu událost. Během tohoto volání budou všechny ostatní procesy runnable vytvořené v tomto procesu runnable považovány za součást nadřazené dávkové operace. Změny prostředků provedené v těchto procesech runnable se objeví v upozornění na změny prostředků nadřazeného prvku.
Ve výše uvedeném příkladě jsme předpokládali, že kód uvnitř našeho procesu runnable upravuje pouze prostředky v jednom konkrétním projektu. Díky tomu bylo velice jednoduché určit pravidlo plánování pro daný proces runnable. V praxi může být těžší vypočítat, na které části pracovního prostoru má daná změna vliv. Například přesun prostředku z jednoho projektu do druhého ovlivní oba projekty. Při výpočtu příslušného pravidla prostředků pro jisté druhy změn prostředků vám může pomoci IResourceRuleFactory. Továrnu na pravidla prostředků můžete získat ze samotného pracovního prostoru.
IWorkspace workspace = ResourcesPlugin.getWorkspace(); IResourceRuleFactory ruleFactory = workspace.getRuleFactory();
Tato továrna může dodávat pravidla odpovídající různým druhům operací. Pokud váš proces runnable přesouvá prostředek z jednoho umístění do jiného, může získat pravidlo odpovídající této operaci:
ISchedulingRule movingRule = ruleFactory.moveResource(sourceResource, destinationResource); workspace.run(myRunnable, movingRule, IWorkspace.AVOID_UPDATE, null);
Seznam dostupných pravidel naleznete v dokumentaci Javadoc pro IResourceRuleFactory. Plug-in prostředků tato pravidla sám používá k implementaci většiny operací s prostředky. Prohlédnutí kódu, který odkazuje na tyto metody pravidel, pomůže ukázat, jak se používají v praxi.
Je možné zkombinovat několik pravidel pomocí MultiRule.
ISchedulingRule movingRule = ruleFactory.moveResource(sourceResource, destinationResource); ISchedulingRule modifyRule = ruleFactory.modifyResource(destinationResource); workspace.run(myRunnable, MultiRule.combine(movingRule, modifyRule), IWorkspace.AVOID_UPDATE, null);
K dispozici je i zkrácená forma metody run v IWorkspace. Ta zůstala zachována kvůli zpětné kompatibilitě. Tato zkrácená forma nezahrnuje příznak aktualizace ani pravidla.
workspace.run(myRunnable, null);
je ve svém účinku stejné jako volání
workspace.run(myRunnable, workspace.getRoot(), IWorkspace.AVOID_UPDATE, null);
Určení kořenu pracovního prostoru jako pravidla plánování uzamkne celý pracovní prostor, dokud proces runnable neskončí. Jedná se o nejkonzervativnější způsob provádění aktualizace pracovního prostoru, není však příliš přátelský k ostatním modulům plug-in, které se orientují na souběžnost.