Όταν πρέπει να τροποποιήσετε πόρους στο χώρο εργασίας, είναι σημαντικό να έχετε υπόψη σας ότι ενδέχεται και άλλες πρόσθετες λειτουργίες να λειτουργούν με τους ίδιους πόρους. Το API των πόρων παρέχει ισχυρούς μηχανισμούς για την ενημέρωση των πρόσθετων λειτουργιών σχετικά με τις αλλαγές στο χώρο εργασίας, και προκειμένου οι πρόσθετες λειτουργίες να μην τροποποιούν ταυτόχρονα τον ίδιο πόρο. Όποτε είναι δυνατόν, οι τροποποιήσεις στο χώρο εργασίας που πραγματοποιούνται από την πρόσθετη λειτουργία σας, θα πρέπει να ομαδοποιούνται σε μονάδες εργασίας μέσα σε ένα εκτελέσιμο χώρου εργασίας. Αυτά τα εκτελέσιμα βοηθούν στη μείωση του αριθμού των ειδοποιήσεων αλλαγής που αποστέλλονται κατά την πραγματοποίηση αλλαγών. Σας επιτρέπουν επίσης να δηλώνετε ποιο τμήμα του χώρου εργασίας πρόκειται να τροποποιηθεί, έτσι ώστε να είναι δυνατή η αποτροπή αλλαγής του ίδιου τμήματος του χώρου εργασίας από άλλες πρόσθετες λειτουργίες.
Το πρωτόκολλο IWorkspaceRunnable είναι ιδιαίτερα απλό. Ένα εκτελέσιμο χώρου εργασίας μοιάζει ακριβώς με μια χρονοβόρα λειτουργία εργασίας πλατφόρμας. Η πραγματική εργασία γίνεται μέσα σε μια μέθοδο run, με την αναφορά προόδου να υποστηρίζεται στην κλάση IProgressMonitor. Ο κώδικας χειρισμού του χώρου εργασίας εκτελείται μέσα στη μέθοδο run.
IWorkspaceRunnable myRunnable = new IWorkspaceRunnable() { public void run(IProgressMonitor monitor) throws CoreException { //do the actual work in here ... } }
Όταν πρέπει να προχωρήσετε στην εκτέλεση του κώδικα, η πρόσθετη λειτουργία σας, δίνει εντολή στο χώρο εργασίας να εκτελέσει τον κώδικα, για λογαριασμό της. Έτσι, ο χώρος εργασίας μπορεί να δημιουργήσει οποιαδήποτε αναγκαία συμβάντα αλλαγής και να βεβαιωθεί ότι δεν γίνεται ταυτόχρονη τροποποίηση του ίδιου πόρου από δύο πρόσθετες λειτουργίες. (Ακόμα κι αν η πρόσθετη λειτουργία σας δεν χρησιμοποιεί εργασίες παρασκηνίου και το πλαίσιο ταυτοχρονισμού για την τροποποίηση του χώρου εργασίας, αυτό ενδέχεται να ισχύει για άλλες πρόσθετες λειτουργίες.)
Το πρωτόκολλο IWorkspace χρησιμοποιείται για την εκτέλεση ενός εκτελέσιμου χώρου εργασίας. Η προτιμώμενη τεχνική χρησιμοποιεί την εκτεταμένη φόρμα της μεθόδου run η οποία παρέχει έναν κανόνα προγραμματισμού και καθορίζει τον τρόπο μετάδοσης των συμβάντων αλλαγής πόρου.
Ο προσδιορισμός ενός κανόνα προγραμματισμού κατά την εκτέλεση ενός εκτελέσιμου χώρου εργασίας επιτρέπει στο χώρο εργασίας να καθορίζει εάν οι αλλαγές πόρου θα προκαλέσουν διένεξη με τις αλλαγές χώρου εργασίας σε άλλα νήματα. (Δείτε την ενότητα Κανόνες προγραμματισμού για μια επισκόπηση των κανόνων προγραμματισμού και του πρωτοκόλλου ISchedulingRule.) Ευτυχώς, το πρωτόκολλο IResource περιλαμβάνει το πρωτόκολλο ISchedulingRule, που σημαίνει ότι ένας πόρος μπορεί συχνά να χρησιμοποιείται ως κανόνας προγραμματισμού για τον ίδιο του τον εαυτό.
Μπερδευτήκατε; Ο κώδικας μπορεί να βοηθήσει στη διευκρίνιση αυτού του σημείου. Υποθέστε ότι η πρόσθετη λειτουργία σας είναι έτοιμη να τροποποιήσει μια δέσμη πόρων σε ένα συγκεκριμένο έργο. Μπορεί να χρησιμοποιήσει το ίδιο το έργο ως κανόνα προγραμματισμού για την πραγματοποίηση των αλλαγών. Το ακόλουθο τμήμα κώδικα εκτελεί το εκτελέσιμο χώρου εργασίας που δημιουργήθηκε νωρίτερα:
IWorkspace workspace = ResourcesPlugin.getWorkspace(); workspace.run(myRunnable, myProject, IWorkspace.AVOID_UPDATE, null);
Το εκτελέσιμο περνά στο χώρο εργασίας, ακολουθούμενο από το έργο το οποίο χειρίζεται ο κώδικας. Ενημερώνεται ο χώρος εργασίας ότι όλες οι αλλαγές στο εκτελέσιμο περιορίζονται στο myProject. Οποιεσδήποτε αιτήσεις από άλλα νήματα για αλλαγή του myProject θα μπλοκάρονται μέχρι την ολοκλήρωση αυτού του εκτελέσιμου. Παρομοίως, αυτή η κλήση θα μπλοκάρει εάν κάποιο άλλο νήμα τροποποιεί ήδη το myProject. Καθορίζοντας ποιο τμήμα της διακλάδωσης πόρου πρόκειται να τροποποιηθεί από το εκτελέσιμο, δίνετε τη δυνατότητα σε άλλα νήματα να συνεχίσουν την τροποποίηση άλλων τμημάτων του χώρου εργασίας. Είναι σημαντικό να βεβαιώνεστε ότι ο κανόνας πόρου ταιριάζει με την εργασία που πραγματοποιείται μέσα στο εκτελέσιμο. Όταν χρησιμοποιείται μη μηδενικός κανόνας προγραμματισμού, οποιαδήποτε απόπειρα πρόσβασης σε έναν πόρο που βρίσκεται εκτός εμβέλειας του κανόνα προγραμματισμού θα προκαλέσει την ενεργοποίηση εξαίρεσης.
Υπάρχουν δύο ειδικοί κανόνες προγραμματισμού οι οποίοι είναι σημαντικοί και πρέπει να τους λάβετε υπόψη. Καταρχήν, αν χρησιμοποιείτε μια χρήση της IWorkspaceRoot ως κανόνα προγραμματισμού, σημαίνει ότι το νήμα σας εμποδίζει την πρόσβαση σε όλους τους πόρους στη διακλάδωση. Ενώ ένα νήμα διατηρεί τον κεντρικό κανόνα, δεν επιτρέπεται σε κανένα άλλο νήμα να τροποποιήσει το χώρο εργασίας. Αντίστροφα, ένας κανόνας null δηλώνει ότι το νήμα δεν θα εμποδίσει την πρόσβαση σε κανένα πόσο στη διακλάδωση. Ενώ ένα νήμα με κανόνα "null" μπορεί να τροποποιήσει το χώρο εργασίας, άλλα νήματα θα μπορούν επίσης να εκτελέσουν τις δικές τους τροποποιήσεις. Οι κανόνες προγραμματισμός IWorkspaceRoot και null καταλαμβάνουν αντίθετες θέσεις στο φάσμα ταυτοχρονισμού. Με τον IWorkspaceRoot δεν υπάρχει ταυτοχρονισμός και μόνο ένα νήμα μπορεί να τροποποιήσει το χώρο εργασίας κάθε φορά. Με τον κανόνα null υπάρχει μέγιστος ταυτοχρονισμός καθώς όλα τα νήματα μπορούν να τροποποιήσουν το χώρο εργασίας ταυτόχρονα.
Η τρίτη παράμετρος της μεθόδου run καθορίζει εάν τα όποια περιοδικά συμβάντα αλλαγής πόρου θα πρέπει να μεταδίδονται κατά την εμβέλεια αυτής της κλήσης. Η χρήση του IWorkspace.AVOID_UPDATE δίνει εντολή στην πλατφόρμα να αποκρύψει οποιαδήποτε συμβάντα αλλαγής πόρου κατά την εκτέλεση του εκτελέσιμου και να μεταδώσει ένα συμβάν στο τέλος των αλλαγών. Κατά τη διάρκεια αυτής της κλήσης, οποιαδήποτε άλλα εκτελέσιμα δημιουργήθηκαν στο εκτελέσιμο στοιχείο θα θεωρούνται τμήμα της λειτουργίας γονικής παρτίδας. Οι αλλαγές πόρου που πραγματοποιούνται σε αυτά τα εκτελέσιμα θα εμφανίζονται στην ειδοποίηση αλλαγής πόρου του γονικού στοιχείου.
Στο παράδειγμα που προηγήθηκε, υποθέσαμε ότι ο κώδικας μέσα στο εκτελέσιμο τροποποίησε πόρους μόνο σε κάποιο συγκεκριμένο έργο. Αυτό κατέστησε πολύ εύκολο τον καθορισμό ενός κανόνα προγραμματισμού για το εκτελέσιμο. Στην πράξη, ο υπολογισμός των τμημάτων του χώρου εργασίας που επηρεάζονται από κάποια συγκεκριμένη αλλαγή μπορεί να είναι δυσκολότερος. Για παράδειγμα, η μετακίνηση ενός πόρου από ένα έργο σε κάποιο άλλο επηρεάζει και τα δύο έργα. Η χρήση του IResourceRuleFactory σας διευκολύνει κατά τον υπολογισμό του κατάλληλου κανόνα πόρου για ορισμένα είδη αλλαγών πόρου. Μπορείτε να αποκτήσετε μια μέθοδο κατασκευής κανόνων πόρου από τον ίδιο το χώρο εργασίας.
IWorkspace workspace = ResourcesPlugin.getWorkspace(); IResourceRuleFactory ruleFactory = workspace.getRuleFactory();
Η μέθοδος κατασκευής μπορεί να παρέχει κανόνες κατάλληλους για πολλά είδη λειτουργιών. Αν το εκτελέσιμό σας μετακινεί έναν πόρο από μια θέση σε κάποια άλλη, μπορεί να αποκτήσει έναν κανόνα κατάλληλο για αυτή τη λειτουργία:
ISchedulingRule movingRule = ruleFactory.moveResource(sourceResource, destinationResource); workspace.run(myRunnable, movingRule, IWorkspace.AVOID_UPDATE, null);
Δείτε το javadoc της διεπαφής IResourceRuleFactory για μια λίστα με τους διαθέσιμους κανόνες. Η ίδια η πρόσθετη λειτουργία πόρων χρησιμοποιεί αυτούς τους κανόνες για την υλοποίηση των περισσοτέρων λειτουργιών πόρου. Η πλοήγηση του κώδικα που συσχετίζεται με αυτές τις μεθόδους κανόνα θα βοηθήσει να δείξουμε πώς αυτές οι μέθοδοι χρησιμοποιούνται στην πράξη.
Χρησιμοποιώντας το MultiRule είναι δυνατός ο συνδυασμός πολλαπλών κανόνων.
ISchedulingRule movingRule = ruleFactory.moveResource(sourceResource, destinationResource); ISchedulingRule modifyRule = ruleFactory.modifyResource(destinationResource); workspace.run(myRunnable, MultiRule.combine(movingRule, modifyRule), IWorkspace.AVOID_UPDATE, null);
Η σύντομη φόρμα της μεθόδου run στο IWorkspace είναι επίσης διαθέσιμη. Διατηρείται για λόγους συμβατότητας με προηγούμενες εκδόσεις. Η σύντομη φόρμα δεν περιλαμβάνει κανόνα ή ενδείκτη ενημέρωσης.
workspace.run(myRunnable, null);
είναι ουσιαστικά σαν να γίνεται κλήση στο
workspace.run(myRunnable, workspace.getRoot(), IWorkspace.AVOID_UPDATE, null);
Ο καθορισμός της ρίζας του χώρου εργασίας ως κανόνα προγραμματισμού κλειδώνει ολόκληρο το χώρο εργασίας μέχρι την ολοκλήρωση του εκτελέσιμου. Πρόκεται για τον πιο απλοϊκό τρόπο εκτέλεσης μιας ενημέρωσης χώρου εργασίας, αν και δεν είναι πολύ φιλικός για άλλες πρόσθετες λειτουργίες ταυτοχρονισμού.