Quando è necessario modificare le risorse dello spazio di lavoro, è importante ricordare che altri plugin potrebbero utilizzare le stesse risorse. L'API delle risorse fornisce un solido meccanismo per mantenere i plugin informati delle modifiche allo spazio di lavoro e per verificare che più plugin non modifichino la stessa risorsa contemporaneamente. Laddove possibile, si consiglia di eseguire il batch delle modifiche dei plugin nello spazio di lavoro in unità di lavoro, all'interno di uno spazio di lavoro eseguibile. Questi eseguibili consentono di ridurre la quantità di notifiche delle modifiche generate. Consentono inoltre di individuare la parte dello spazio di lavoro da modificare, in modo da evitare che altri plugin possano modificare la stessa parte di spazio di lavoro.
Il protocollo per IWorkspaceRunnable è abbastanza semplice. Un eseguibile dello spazio di lavoro è simile ad un'operazione di lunga durata o ad un lavoro della piattaforma. Il lavoro effettivo viene eseguito all'interno di un metodo run, con avanzamento riportato nel metodo IProgressMonitor fornito. Il codice che modifica lo spazio di lavoro viene eseguito all'interno del metodo run.
IWorkspaceRunnable myRunnable = new IWorkspaceRunnable() { public void run(IProgressMonitor monitor) throws CoreException { //do the actual work in here ... } }
Al momento di eseguire il codice, il plugin indica allo spazio di lavoro di eseguire il codice per proprio conto. In questo modo, lo spazio di lavoro può generare tutti gli eventi di modifica necessari e garantire che gli altri due plugin non stiano modificando la stessa risorsa allo stesso tempo. Anche se il plugin non utilizza i lavori sullo sfondo e il framework di simultaneità per modificare lo spazio di lavoro, è possibile che ciò non sia valido per gli altri plugin.
Il protocollo IWorkspace viene utilizzato per eseguire l'eseguibile di uno spazio di lavoro. La tecnica consigliata consiste nell'utilizzare il formato lungo del metodo run, che fornisce una regola di pianificazione e specifica il modo in cui vengono trasmessi gli eventi di modifica delle risorse.
Se si specifica una regola di pianificazione quando si esegue un eseguibile di uno spazio di lavoro, lo spazio di lavoro può stabilire se le modifiche delle risorse saranno in conflitto con le modifiche dello spazio di lavoro che si verificano in altri thread. Per una panoramica delle regole di pianificazione e del protocollo ISchedulingRule, fare riferimento alla sezione Pianificazione di regole. Per fortuna, il protocollo IResource include il protocollo per ISchedulingRule, che indica che una risorsa può spesso essere utilizzata come una regola di pianificazione.
Utilizzare il codice per chiarire questo punto. Si supponga che il plugin sia pronto a modificare un insieme di risorse di un determinato progetto. Per apportare le modifiche, è possibile utilizzare il progetto stesso come regola di pianificazione. Il frammento di seguito riportato esegue l'eseguibile dello spazio di lavoro creato in precedenza:
IWorkspace workspace = ResourcesPlugin.getWorkspace(); workspace.run(myRunnable, myProject, IWorkspace.AVOID_UPDATE, null);
L'eseguibile viene trasferito nello spazio di lavoro, seguito dal progetto che il codice sta modificando. Ciò indica allo spazio di lavoro che tutte le modifiche dell'eseguibile si trovano in myProject. Qualsiasi richiesta effettuata da altri thread per modificare myProject verrà bloccata fino a quando l'operazione dell'eseguibile non sarà completata. Allo stesso modo, questa chiamata sarà bloccata se altri thread stanno già modificando myProject. Se si specifica la parte della struttura di risorse che verrà modificata dall'eseguibile, si consente ad altri thread di continuare la modifica di altre parti dello spazio di lavoro. È importante verificare che la regola della risorsa corrisponda al lavoro da eseguire all'interno dell'eseguibile. Qualsiasi tentativo di accedere a una risorsa al di fuori dell'ambito della regola di pianificazione attiverà un'eccezione.
Il terzo parametro del metodo run specifica se eventi periodici di modifica delle risorse devono essere trasmessi durante l'ambito di questa chiamata. Utilizzando IWorkspace.AVOID_UPDATE si indica alla piattaforma di sopprimere gli eventi di modifica delle risorse, mentre l'eseguibile è in esecuzione e di trasmettere un evento alla fine delle modifiche. Durante questa chiamata, qualsiasi altro eseguibile creato nell'eseguibile stesso verrà considerato parte dell'operazione di batch principale. Le modifiche delle risorse apportate in tali eseguibili appariranno nella notifica di modifica delle risorse dell'elemento principale.
Nell'esempio in alto, si presuppone che il codice all'interno dell'eseguibile modifichi solo le risorse di un determinato progetto. Ciò consente di specificare facilmente una regola di pianificazione per l'eseguibile. In pratica, può essere più difficile calcolare le parti dello spazio di lavoro interessate da una determinata modifica. Ad esempio, lo spostamento di una risorsa da un progetto ad un altro influisce su entrambi i progetti. Il protocollo IResourceRuleFactory può essere utilizzato per calcolare una regola di risorsa appropriata per determinati tipi di modifiche di risorse. È possibile visualizzare un factory di regole di risorse dallo spazio di lavoro.
IWorkspace workspace = ResourcesPlugin.getWorkspace(); IResourceRuleFactory ruleFactory = workspace.getRuleFactory();
Il factory può fornire regole appropriate per molti tipi di operazioni. Se l'eseguibile sposta una risorsa da un'ubicazione ad un'altra, può richiamare una regola appropriata per questa operazione:
ISchedulingRule movingRule = ruleFactory.moveResource(sourceResource, destinationResource); workspace.run(myRunnable, movingRule, IWorkspace.AVOID_UPDATE, null);
Fare riferimento al javadoc relativo a IResourceRuleFactory per un elenco delle regole disponibili. Il plugin delle risorse utilizza queste regole per implementare molte operazioni delle risorse. Se si esamina il codice che fa riferimento a queste regole, sarà possibile dimostrare come queste regole vengono utilizzate nella pratica.
Più regole possono essere combinate utilizzando MultiRule.
ISchedulingRule movingRule = ruleFactory.moveResource(sourceResource, destinationResource); ISchedulingRule modifyRule = ruleFactory.modifyResource(destinationResource); workspace.run(myRunnable, MultiRule.combine(movingRule, modifyRule), IWorkspace.AVOID_UPDATE, null);
Il formato breve del metodo run è disponibile anche in IWorkspace. Viene conservato per compatibilità con le versioni precedenti. Il formato breve non include una regola o un indicatore di aggiornamento.
workspace.run(myRunnable, null);
corrisponde alla chiamata di
workspace.run(myRunnable, workspace.getRoot(), IWorkspace.AVOID_UPDATE, null);
Se si specifica l'elemento principale dello spazio di lavoro come regola di pianificazione, verrà posto un blocco all'intero spazio di lavoro, fino a quando l'eseguibile non avrà completato l'elaborazione. Questo è il modo più efficace per eseguire l'aggiornamento di uno spazio di lavoro, ma non è particolarmente adatto agli altri plugin.