Επισκόπηση του EMF.Edit

Τελευταία ενημέρωση: 1 Ιουνίου 2004

Στο παρόν έγγραφο θεωρείται δεδομένο ότι έχετε κάποια εξοικείωση με τις βασικές έννοιες του EMF (Eclipse Modeling Framework). Για περισσότερες πληροφορίες σχετικά με το EMF, ανατρέξτε στο θέμα Επισκόπηση EMF.

Περιεχόμενα

Εισαγωγή
Εμφάνιση αντικειμένων EMF σε λειτουργίες προβολής JFace
Κλάσεις υλοποίησης παροχέα στοιχείων
Τροποποίηση μοντέλων EMF με χρήση εντολών
Χρήση γεννήτριας κώδικα EMF.Edit

Εισαγωγή

Αν έχετε δημιουργήσει κώδικα για ένα μοντέλο που βασίζεται στο EMF χρησιμοποιώντας τη γεννήτρια του EMF και είστε έτοιμοι να προσθέσετε περιβάλλοντα χρήστη στο μοντέλο και στον κώδικα, μπορείτε να χρησιμοποιήσετε το πλαίσιο EMF.Edit προκειμένου να διευκολυνθεί η εργασία σας.

Το EMF.Edit είναι ένα πλαίσιο Eclipse που περιλαμβάνει γενικές επαναχρησιμοποιήσιμες κλάσεις για τη δημιουργία λειτουργιών επεξεργασίας για μοντέλα EMF. Παρέχει τα εξής:

Το παρόν έγγραφο παρέχει μια επισκόπηση των βασικών εννοιών του πλαισίου EMF.Edit και της γεννήτριας. Για πιο αναλυτικές πληροφορίες, μπορείτε να ανατρέξετε στην τεκμηρίωση για τις κλάσεις πλαισίων, στην οποία περιγράφονται με λεπτομέρειες οι σχετικές συμπεριφορές και οι δυνατότητες.

Εμφάνιση αντικειμένων EMF σε λειτουργίες προβολής JFace

Τι είναι ο παροχέας περιεχομένου;

Το πλαίσιο περιβάλλοντος χρήστη του Eclipse (JFace) περιλαμβάνει ένα σύνολο επαναχρησιμοποιήσιμων κλάσεων λειτουργιών προβολής (για παράδειγμα, TreeViewer και TableViewer) για την εμφάνιση δομημένων μοντέλων. Αντί να απαιτείται από τα αντικείμενα του μοντέλου να ακολουθούν ένα συγκεκριμένο πρωτόκολλο (δηλαδή, να υλοποιούν ένα συγκεκριμένο περιβάλλον), οι λειτουργίες προβολής JFace λειτουργούν με οποιοδήποτε είδος αντικειμένου (δηλαδή, οποιαδήποτε υποκλάση java.lang.Object). Αυτό είναι εφικτό επειδή οι λειτουργίες προβολής αντί να χειρίζονται απευθείας τα αντικείμενα μοντέλων, αποκτούν πρόσβαση στα αντικείμενα μοντέλων μέσω ενός αντικειμένου προσαρμογέα που ονομάζεται παροχέας περιεχομένου.

Κάθε κλάση λειτουργίας προβολής χρησιμοποιεί ένα παροχέα περιεχομένου που υλοποιεί μια συγκεκριμένη διεπαφή παροχέα. Για παράδειγμα, ένα TreeViewer χρησιμοποιεί ένα παροχέα περιεχομένου που υλοποιεί την ακόλουθη διεπαφή:

  public interface ITreeContentProvider ...
  {
    public Object[] getChildren(Object object);
    public Object getParent(Object object);
    ...
  }

Στο ακόλουθο διάγραμμα μπορείτε να δείτε τη βασική δομή:

Παροχέας περιεχομένου JFace

Όσον αφορά το TreeViewer, εμφανίζει μια διακλάδωση αντικειμένων (τα ονομάζει στοιχεία) στην οθόνη. Όλα αυτά τα στοιχεία, εκτός του αντικειμένου εισόδου, τα ανακτά με την κλήση του getChildren() στον παροχέα περιεχομένου του.

Άλλα είδη λειτουργιών προβολής χρησιμοποιούνται με παρόμοιο τρόπο, ωστόσο κάθε λειτουργία προβολής απαιτεί από τον παροχέα περιεχομένου την υλοποίηση της διεπαφής της. Παρόλο που οι διεπαφές λειτουργιών προβολής διαφέρουν, ο παροχέας περιεχομένου συχνά μπορεί να υλοποιήσει ταυτόχρονα πολλαπλές διεπαφές, επιτρέποντας τη χρήση της ίδιας κλάσης παροχέα περιεχομένου για πολλά είδη λειτουργιών προβολής.

Παροχή περιεχομένου για μοντέλο EMF

Το πλαίσιο EMF.Edit παρέχει μια γενική κλάση υλοποίησης παροχέα περιεχομένου που μπορεί να χρησιμοποιηθεί για την παροχή περιεχομένου για μοντέλα EMF. Η κλάση AdapterFactoryContentProvider υλοποιεί τις διεπαφές παροχέων περιεχομένου με την ανάθεση εργασιών σε προσαρμογείς EMF που γνωρίζουν τον τρόπο χειρισμού των αντικειμένων μοντέλων (στοιχεία) για τις λειτουργίες προβολής. Για παράδειγμα, η κλάση προσαρμογέα EMF χρησιμοποιείται για την υποστήριξη μιας λειτουργίας προβολής που υλοποιεί τη διεπαφή EMF.Edit:

  public interface ITreeItemProvider
  {
    public Collection getChildren(Object object);
    public Object getParent(Object object);
    ...
  }

Προσέξτε την ομοιότητα της διεπαφής με τη διεπαφή παροχέα περιεχομένου ITreeContentProvider που περιγράφεται παραπάνω. Το AdapterFactoryContentProvider υλοποιεί τη διεπαφή παροχέα περιεχομένου εντοπίζοντας ένα προσαρμογέα και στη συνέχεια αναθέτοντας σε αυτόν την υλοποίηση για το απαραίτητο στοιχείο. Η αλλαγή ορολογίας από αντικείμενα σε στοιχεία είναι ηθελημένη: όσον αφορά τη λειτουργία προβολής, πρόκειται για στοιχεία και όχι για αντικείμενα.

Η εικόνα του EMF είναι αυτή:

Ανάθεση του AdapterFactoryContentProvider σε παροχείς στοιχείων

Σημείωση: μπορείτε να δημιουργήσετε αυτόματα τις κλάσεις ItemProviderAdapterFactory και ItemProvider για ένα δεδομένο μοντέλο EMF με χρήση της γεννήτριας που παρέχεται με το πλαίσιο EMF.Edit. Περισσότερες πληροφορίες θα δοθούν αργότερα.

Το AdapterFactoryContentProvider δημιουργείται με μία μέθοδο κατασκευής προσαρμογέα η οποία, όπως όλες οι μέθοδοι κατασκευής προσαρμογέων EMF, χρησιμοποιούνται για τη δημιουργία και τον εντοπισμό προσαρμογέων συγκεκριμένου είδους (σε αυτή την περίπτωση, ItemProviders). Ο παροχέας περιεχομένου επεξεργάζεται μια αίτηση όπως η getChildren() καλώντας το adapt(item) στο ItemProviderAdapterFactory, το οποίο θα δημιουργήσει ή θα επιστρέψει το ItemProvider (προσαρμογέας) για το καθορισμένο στοιχείο. Στη συνέχεια, απλά κάνει ανάθεση στη μέθοδο getChildren() της απαιτούμενης διεπαφής (σε αυτή την περίπτωση, ITreeItemProvider).

Η μέθοδος getChildren() στο AdapterFactoryContentProvider έχει μορφή παρόμοια με την εξής:

  public Object[] getChildren(Object object)
  {
    ITreeItemContentProvider adapter =
      (ITreeItemContentProvider)
        adapterFactory.adapt(object, ITreeItemContentProvider.class);
    return adapter.getChildren(object).toArray();
  }

Αυτό το μοτίβο χρησιμοποιείται για όλες τις μεθόδους παροχέα περιεχομένου. Όπως αναφέρθηκε νωρίτερα, το AdapterFactoryContentProvider το μόνο που κάνει είναι να αναθέσει τις μεθόδους παροχέα περιεχομένου στο συγκεκριμένο παροχέα στοιχείων (προσαρμογέα) που γνωρίζει τον τρόπο επεξεργασίας της αίτησης.

Στην παραπάνω μέθοδο getChildren(), το αντικείμενο που μεταβιβάζεται στο adapterFactory.adapt() είναι ένα απλό java.lang.Object (και όχι org.eclipse.emf.ecore.EObject). Αυτή είναι μια σημαντική λειτουργία του πλαισίου EMF.Edit. Το πλαίσιο έχει σχεδιαστεί προσεκτικά ώστε να αξιοποιεί προβολές σε μοντέλα EMF που ενδέχεται να διαφέρουν από το ίδιο το μοντέλο (δηλαδή, προβολές που δεν εμφανίζουν αντικείμενα ή περιλαμβάνουν πρόσθετα αντικείμενα). Προκειμένου να είναι εφικτή αυτή η μίξη αντικειμένων EMF και μη EMF, η βασική κλάση του πλαισίου για μεθόδους κατασκευής προσαρμογέα παρέχει μια υλοποίηση του adapt() που λειτουργεί ως εξής:

  public Object adapt(Object object, Object type)
  {
    if (object instanceof Notifier)
      return this.adapt((Notifier)object, type);
    else
      return object;
  }

Αν το καθορισμένο αντικείμενο δεν είναι λειτουργία ειδοποίησης του EMF [1] , επιστρέφει το ίδιο το αντικείμενο. Με αυτό το σχεδιασμό, ένας παροχέας στοιχείων που επιθυμεί να προσθέσει στοιχεία μη EMF σε μια προβολή μπορεί απλά να επιστρέψει (για παράδειγμα, από τη μέθοδο getChildren()) οποιοδήποτε αντικείμενο μη EMF. Εφόσον το επιστρεφόμενο αντικείμενο υλοποιεί τη διεπαφή παροχέα στοιχείων που απαιτεί η λειτουργία προβολής (για παράδειγμα, ITreeItemProvider) θα χρησιμοποιηθεί όπως κάθε άλλο στοιχείο EMF.

Αυτή η ιδιότητα του σχεδιασμού επιδεικνύει την αιτία για την οποία οι κλάσεις παροχέα/προσαρμογέα ονομάζονται παροχείς στοιχείων και όχι προσαρμογείς. Σε μη σημαντικές εφαρμογές, το μοντέλο προβολής (δηλαδή αυτό που παρέχεται από τον παροχέα περιεχομένου της λειτουργίας προβολής) συχνά θα είναι μια μίξη των "πραγματικών" (EMF) αντικειμένων μοντέλων των οποίων οι παροχείς στοιχείων επίσης είναι προσαρμογείς (EMF) και "εικονικών" αντικειμένων των οποίων οι παροχείς στοιχείων είναι τα ίδια τα αντικείμενα. Συνεπώς, παρόλο που όλοι οι προσαρμογείς είναι επίσης παροχείς στοιχείων, δεν συμβαίνει απαραίτητα και το αντίστροφο.

Παροχείς ετικετών JFace

Στις προηγούμενες ενότητες περιγράφηκε ο τρόπος με τον οποίο οι λειτουργίες προβολής JFace χρησιμοποιούν ένα παροχέα περιεχομένου για την ανάκτηση στοιχείων περιεχομένου. Μια παρόμοια προσέγγιση χρησιμοποιείται για την ανάκτηση της εικόνας και του κειμένου της ετικέτας για τα στοιχεία που εμφανίζονται από μια λειτουργία προβολής. Αντί να ανακτώνται οι ετικέτες από τα στοιχεία, η λειτουργία προβολής χρησιμοποιεί ένα άλλο αντικείμενο που ονομάζεται παροχέας ετικετών (παρόμοιο με τον παροχέα περιεχομένου). Το στοιχείο TreeViewer, για παράδειγμα, αναθέτει σε ένα αντικείμενο που υλοποιεί τη διεπαφή ILabelProvider την ανάκτηση των ετικετών των στοιχείων στη διακλάδωση.

Παροχή ετικετών για αντικείμενα EMF

Το πλαίσιο EMF.Edit χρησιμοποιεί για την υλοποίηση παροχέων ετικετών για μοντέλα EMF τον ίδιο μηχανισμό που χρησιμοποιεί για την παροχή του περιεχομένου. Μια γενική κλάση υλοποίησης παροχέα ετικετών, το AdapterFactoryLabelProvider (που λειτουργεί ακριβώς όπως το AdapterFactoryContentProvider), αναθέτει τη διεπαφή ILabelProvider στους παροχείς στοιχείων για το μοντέλο (τους ίδιους παροχείς στοιχείων που παρέχουν το περιεχόμενο). Η αναπτυγμένη εικόνα είναι η εξής:

ανάθεση του AdapterFactoryLabelProvider στους παροχείς στοιχείων

Ο παροχέας περιεχομένου και ετικέτας μπορούν να ανατεθούν στην ίδια μέθοδο κατασκευής προσαρμογέα, συνεπώς, και στους ίδιους παροχείς στοιχείων. Όπως συμβαίνει και με τον παροχέα περιεχομένου, οι παροχείς στοιχείων είναι αυτοί που εκτελούν το μεγαλύτερο μέρος της εργασίας.

Με τη χρήση των κλάσεων παροχέα EMF.Edit, ο χρήστης μπορεί να κατασκευάσει ένα TreeViewer για ένα μοντέλο EMF ως εξής:

  myAdapterFactory = ...

  treeViewer = new TreeViewer();

  treeViewer.setContentProvider(new AdapterFactoryContentProvider(myAdapterFactory));
  treeViewer.setLabelProvider(new AdapterFactoryLabelProvider(myAdapterFactory));

Αυτό το TreeViewer μπορεί να εμφανιστεί, για παράδειγμα, σε ένα παράθυρο λειτουργίας επεξεργασίας με τον συνηθισμένο τρόπο (καθορισμός από το JFace).

Σε περίπτωση που θεωρείτε ότι όλες αυτές οι διαδικασίες είναι ασήμαντες, αυτό συμβαίνει επειδή έως τώρα έχουμε περιγράψει μόνο τον τρόπο ανάθεσης εργασιών σε κάποιον άλλο (δηλαδή, στη μέθοδο κατασκευής προσαρμογέα). Δεν έχουμε υλοποιήσει καμία μέθοδο. Απλά τις αναθέσαμε αλλού. Ωστόσο, η υλοποίηση μεθόδων υποστηρίζεται από το EMF.Edit, το οποίο περιλαμβάνει μια γεννήτρια κώδικα που δημιουργεί το μεγαλύτερο μέρος του κώδικα του παροχέα στοιχείων και της μεθόδου κατασκευής. Πριν αναλύσουμε αυτή την ιδιότητα, πρέπει να περιγράψουμε τον τρόπο εκτέλεσης εργασιών από τους παροχείς στοιχείων.

Κλάσεις υλοποίησης παροχέα στοιχείων

Όπως περιγράφηκε στην προηγούμενη ενότητα, η πραγματική εργασία παροχής περιεχομένου για μοντέλα EMF γίνεται από τους προσαρμογείς παροχέα στοιχείων που έχει συνδεθεί στο μοντέλο. Το πλήθος και τα είδη προσαρμογέων ItemProvider στο προηγούμενο διάγραμμα παρέμειναν ηθελημένα ασαφή. Αυτό συνέβη επειδή το πλαίσιο EMF.Edit υποστηρίζει δύο διαφορετικά μοτίβα για τους προσαρμογείς παροχέων στοιχείων:

  1. Προσαρμογείς Stateful - ένα αντικείμενο προσαρμογέα για κάθε αντικείμενο του μοντέλου
  2. Προσαρμογείς Singleton - ένα αντικείμενο προσαρμογέα για κάθε είδος αντικειμένου στο μοντέλο (συνιστάται, όταν είναι εφικτό)

Οι παροχείς στοιχείων για ένα δεδομένο μοντέλο μπορούν να υλοποιηθούν με οποιοδήποτε από αυτά τα μοτίβα ή με ένα συνδυασμό αυτών.

Προσαρμογείς παροχέα στοιχείων Stateful

Με το πρώτο μοτίβο, κάθε αντικείμενο ενός μοντέλου διαθέτει επικοινωνία ένα-προς-ένα με τον προσαρμογέα του. Κάθε προσαρμογέας διαθέτει ένα δείκτη (ονομάζεται προορισμός) για το μοναδικό αντικείμενο που προσαρμόζει.

Η εικόνα είναι αυτή:

Προσαρμογείς παροχέα στοιχείων Stateful

Όπως μπορείτε να δείτε, αυτό το μοτίβο διπλασιάζει το πλήθος αντικειμένων στην εφαρμογή, συνεπώς χρησιμεύει μόνο σε εφαρμογές όπου οι χρήσεις απαιτούνται για την αποθήκευση πρόσθετων καταστάσεων. Για αυτό το λόγο ονομάζεται μοτίβο Stateful.

Προσαρμογείς παροχέα στοιχείων Singleton

Μια καλύτερη προσέγγιση, με την οποία αποφεύγεται η δημιουργία πρόσθετων αντικειμένων, είναι το μοτίβο Singleton. Με αυτό το μοτίβο, χρησιμοποιείται ένας παροχέας στοιχείων για όλα τα στοιχεία του ίδιου είδους. Η μορφή του είναι η εξής:

Προσαρμογείς παροχέα στοιχείων Singleton

Σε αυτή την εικόνα, τα αντικείμενα διαθέτουν δείκτες προσαρμογέα, ως συνήθως, ωστόσο οι παροχείς στοιχείων (οι οποίοι είναι κοινόχρηστοι) δεν διαθέτουν δείκτες για τα αντικείμενα. Στο περιβάλλον παροχέα στοιχείων διακλάδωσης που περιγράφηκε νωρίτερα στην ενότητα του παροχέα περιεχομένου, ίσως παρατηρήσατε ότι όλες οι μέθοδοι διέθεταν ένα πρόσθετο όρισμα (ένα αντικείμενο):

  public interface ITreeItemProvider
  {
    public Collection getChildren(Object object);
    public Object getParent(Object object);
    ...
  }

Το όρισμα αντικειμένου προστέθηκε σε κάθε περιβάλλον παροχέα στοιχείων ειδικά για την υποστήριξη αυτού του μοτίβου. Στην περίπτωση το παροχέα Stateful, αυτό το αντικείμενο θα είναι πάντα το ίδιο με τον προορισμό του προσαρμογέα.

Μια άλλη πιθανή απορία είναι το γιατί δεν υποστηρίζεται ένα "πραγματικό" μοτίβο προσαρμογέα Singleton, δηλαδή ακριβώς ένα προσαρμογέα για όλα τα αντικείμενα; Η απάντηση είναι απλή. Παρότι είναι ένα πιθανό μοτίβο (συμβατό με το πλαίσιο EMF.Edit)[2] , δεν συνιστάται η χρήση του καθώς αποτελεί μια πλήρως δυναμική υλοποίηση, η οποία παρότι απλή, είναι δύσκολο να προσαρμοστεί ( χωρίς τη χρήση πολλών και πολύπλοκων ελέγχων instanceof() ). Η εναλλακτική της χρήσης κλάσεων παροχέα στοιχείων συγκεκριμένου είδους, των οποίων η ιεραρχία μεταβίβασης είναι ίδια με του μοντέλου, παρέχει ένα βολικό σημείο αποστολής για την υλοποίηση σωστού αντικειμενοστραφούς κώδικα προβολής για ένα μοντέλο.

Τροποποίηση μοντέλων EMF με χρήση εντολών

Ως τώρα έχουμε δείξει μόνο τον τρόπο προβολή μοντέλων EMF με χρήση παροχέων περιεχομένου και ετικετών. Μια άλλη λειτουργία του πλαισίου EMF.Edit είναι η υποστήριξη για την τροποποίηση ενός μοντέλου με χρήση εντολών. Χρησιμοποιούμε τον όρο "τροποποίηση" εννοώντας την μη ανατρέψιμη τροποποίηση, σε αντίθεση με την "εγγραφή" ενός μοντέλου.

Τροποποίηση τομέων

Το περιβάλλον EditingDomain του EMF.Edit χρησιμοποιείται για την παροχή πρόσβασης για τροποποίηση σε ένα μοντέλο EMF. Μια άλλη κλάση υλοποίησης του EMF.Edit, το AdapterFactoryEditingDomain, λειτουργεί όπως οι παροχείς περιεχομένου και ετικετών με την ανάθεση της υλοποίησης στους παροχείς στοιχείων (μέσω του ItemProviderAdapterFactory):

Τομέας τροποποίησης

Παρέχει επίσης πρόσβαση σε μια στοίβα εντολών μέσω της οποίας γίνονται όλες οι τροποποιήσεις στο μοντέλο. Ο τομέας τροποποίησης παρέχει δύο βασικές υπηρεσίες:

Μπορείτε να θεωρήσετε ότι ο τομέας τροποποίησης είναι ένα παροχέας δυνατοτήτων τροποποίησης ή εγγραφής για το μοντέλο, ενώ οι παροχείς περιεχομένου και ετικετών είναι ο παροχέας δυνατοτήτων προβολής ή ανάγνωσης. Ακολουθεί μια γενική περιγραφή:

Παροχείς ενεργειών ανάγνωσης και εγγραφής

Τροποποίηση μοντέλου

Ακολουθεί ένα απλό παράδειγμα τροποποίησης ενός μοντέλου.

Έστω ότι η κλάση Company διαθέτει παραπομπές ένα-προς-πολλά, που ονομάζονται τμήματα, με την κλάση Department. Για να αφαιρέσετε ένα τμήμα από την κλάση Company (για παράδειγμα, για την υλοποίηση μιας ενέργειας διαγραφής στη λειτουργία επεξεργασίας) μπορείτε απλά να συντάξετε τον ακόλουθο κώδικα:

  Department d = ...
  Company c = ...
  c.getDepartments().remove(d);

Παρόλο που είναι απλός, αυτός ο κώδικας το μόνο που κάνει είναι η τροποποίηση.

Αντίθετα, αν χρησιμοποιήσουμε την εντολή αφαίρεσης του EMF.Edit (org.eclipse.emf.edit.command.RemoveCommand) για την αφαίρεση του τμήματος, θα πρέπει να συντάξουμε τον ακόλουθο κώδικα:

  Department d = ...
  Company c = ...
  EditingDomain ed = ...
  RemoveCommand cmd = 
    new RemoveCommand(ed, c, CompanyPackage.eINSTANCE.getCompany_Departments(), d);
  ed.getCommandStack().execute(cmd);

Η διαγραφή του τμήματος με αυτό τον τρόπο διαθέτει πολλαπλά πλεονεκτήματα:

  1. Η διαγραφή δεν μπορεί να αναιρεθεί με κλήση του ed.getCommandStack().undo().
  2. Μπορούμε να διαπιστώσουμε αν ένα μοντέλο περιέχει εκκρεμείς αλλαγές (για την ενεργοποίηση ενός μενού αποθήκευσης, για παράδειγμα) ελέγχοντας αν υπάρχουν εντολές στη στοίβα εντολών, θεωρώντας ότι όλες οι τροποποιήσεις γίνονται με χρήση εντολών (το οποίο εφαρμόζεται από το πλαίσιο EMF.Edit).
  3. Θα μπορούσαμε να ελέγξουμε αν η εντολή είναι έγκυρη (για την ενεργοποίηση ενός μενού διαγραφής, για παράδειγμα) πριν από την εκτέλεσή της, καλώντας το cmd.canExecute();

Με τη χρήση των εντολών με αυτό τον τρόπο, ενεργοποιούνται όλες οι λειτουργίες που μπορεί να διαθέσει το πλαίσιο EMF.Edit.

Δημιουργία εντολών με χρήση του τομέα τροποποίησης

Στο προηγούμενο παράδειγμα δημιουργήσαμε ένα στοιχείο RemoveCommand χρησιμοποιώντας μια απλή νέα κλήση. Αυτή η μέθοδος λειτουργεί σωστά, ωστόσο δεν είναι επαναχρησιμοποιήσιμη. Η ενέργεια αφαίρεσης ενός τμήματος από την εταιρεία είναι πολύ συγκεκριμένη. Αν ωστόσο επιθυμούμε να συντάξουμε, για παράδειγμα, μια επαναχρησιμοποιήσιμη ενέργεια διαγραφής με δυνατότητα διαγραφής οποιουδήποτε είδους αντικειμένου, πρέπει να χρησιμοποιήσουμε το EditingDomain ως βοήθημα.

Το περιβάλλον EditingDomain περιέχει (εκτός των άλλων) μια μέθοδο κατασκευής εντολών, την createCommand(), η οποία μπορεί να χρησιμοποιηθεί για τη δημιουργία εντολών:

  public interface EditingDomain
  {
    ...
    Command createCommand(Class commandClass, CommandParameter commandParameter);
    ...
  }

Για να χρησιμοποιήσετε αυτή τη μέθοδο για τη δημιουργία μιας εντολής, πρέπει πρώτα να δημιουργήσετε ένα αντικείμενο CommandParameter, να ορίσετε παραμέτρους εντολών, και στη συνέχεια να καλέσετε τη μέθοδο δημιουργίας μεταβιβάζοντας σε αυτή την επιθυμητή κλάση εντολών (για παράδειγμα, RemoveCommand.class) και τις παραμέτρους.

Αντί να εκτελούν οι πελάτες αυτή τη διαδικασία, χρησιμοποιούμε μια σύμβαση με την παροχή βοηθητικών στατικών μεθόδων create() σε κάθε κλάση εντολών. Με τη χρήση της στατικής μεθόδου create(), μπορείτε να δημιουργήσετε και να εκτελέσετε ένα στοιχείο RemoveCommand ως εξής:

  Department d = ...
  EditingDomain ed = ...
  Command cmd = RemoveCommand.create(ed, d);
  ed.getCommandStack().execute(cmd);

Όπως μπορείτε να δείτε, αυτή είναι απλά μια μικρή συντακτική αλλαγή (RemoveCommand.create() αντί για RemoveCommand). Ωστόσο, υπάρχουν και κάποιες βασικές διαφορές. Μεταβιβάστηκε μόνο ένα όρισμα (δηλαδή, το αντικείμενο που αφαιρείται) εκτός από τον τομέα τροποποίησης, αντί για τα τρία ορίσματα που μεταβιβάζονταν νωρίτερα. Αυτό το τμήμα κώδικα μπορεί πλέον να χρησιμοποιηθεί για την αφαίρεση οποιουδήποτε είδους αντικειμένου. Με την ανάθεση της δημιουργίας της εντολής στον τομέα τροποποίησης, ο τομέας συμπληρώνει τα ορίσματα που λείπουν.

Πώς χειρίζεται ο τομέας τροποποίησης μία αίτηση createCommand();

Για να κατανοήσετε τον τρόπο λειτουργίας, ακολουθεί η περιγραφή της βηματικής εκτέλεσης της κλήσης RemoveCommand.create(). Όπως αναφέρθηκε νωρίτερα, η στατική μέθοδος create() είναι απλά μια βοηθητική μέθοδος που αναθέτει εργασίες στον τομέα τροποποίησης:

  public static Command create(EditingDomain domain, Object value) 
  {
    return domain.createCommand(
      RemoveCommand.class,
      new CommandParameter(null, null, Collections.singleton(value)));
  }

Το AdapterFactoryEditingDomain λαμβάνει την αίτηση και τη μεταβιβάζει σε ένα παροχέα στοιχείων με χρήση του τυπικού μοτίβου ανάθεσης (όπως το AdapterFactorContentProvider ανέθεσε το getChildren() νωρίτερα):

  public Command createCommand(Class commandClass, CommandParameter commandParameter)
  {
    Object owner = ...  // get the owner object for the command
    IEditingDomainItemProvider adapter = 
      (IEditingDomainItemProvider)
        adapterFactory.adapt(owner, IEditingDomainItemProvider.class);
    return adapter.createCommand(owner, this, commandClass, commandParameter);
  }

Σημείωση: αν προσέξετε τη μέθοδο createCommand() θα παρατηρήσετε ότι στην πραγματικότητα είναι πολύ πιο πολύπλοκη. Αυτό συμβαίνει επειδή έχει σχεδιαστεί για να χειρίζεται, μεταξύ άλλων, την ταυτόχρονη διαγραφή πολλαπλών αντικειμένων. Αυτή είναι, ουσιαστικά, η χρησιμότητά του.

Η μέθοδος createCommand() χρησιμοποιεί ένα αντικείμενο κατόχου για την πρόσβαση στον παροχέα στοιχείων για την ανάθεση ενεργειών (δηλαδή, ο κάτοχος χρησιμοποιείται στην κλήση adapterFactory.adapt()). Ο κάτοχος στο παράδειγμά μας θα είναι το αντικείμενο Company (δηλαδή, το γονικό στοιχείο του τμήματος που αφαιρείται). Ο τομέας τροποποίησης καθορίζει τον κάτοχο καλώντας τη μέθοδο getParent() στον παροχέα στοιχείων του αντικειμένου που διαγράφεται.

Το αποτέλεσμα αυτής της συμπεριφοράς είναι ότι η μέθοδος createCommand() καλείται στον παροχέα στοιχείων του γονικού στοιχείου του αντικειμένου που αφαιρείται (δηλαδή, το CompanyItemProvider για την εταιρεία c είναι το αρχικό τμήμα κώδικα). Συνεπώς, το CompanyItemProvider θα μπορούσε να υλοποιήσει το createCommand() ως εξής:

  public class CompanyItemProvider ...
  {
    ...

    public Command createCommand(final Object object, ..., Class commandClass, ...)
    {
      if (commandClass == RemoveCommand.class)
      {
        return new RemoveCommand(object,
                                 CompanyPackage.eINSTANCE.getCompany_Departments(),
                                 commandParameter.getCollection()); 
      }
    ...
   }
  }

Η επιθυμητή εργασία θα εκτελεστεί, ωστόσο υπάρχει καλύτερος τρόπος.

Κάθε κλάση παροχέα στοιχείων (που είναι επίσης προσαρμογέας EMF) επεκτείνεται από μια βασική βοηθητική κλάση του EMF.Edit, την ItemProviderAdapter, η οποία παρέχει μια προεπιλεγμένη υλοποίηση του createCommand(), μεταξύ άλλων. Υλοποιεί το createCommand() για όλες τις τυπικές εντολές που παρέχονται από το πλαίσιο EMF.Edit καλώντας μερικές απλές μεθόδους (οι οποίες έχουν πολλαπλές χρήσεις) που υλοποιούνται στις υποκλάσεις παροχέα στοιχείων. Αυτό είναι ένα παράδειγμα του μοτίβου σχεδίασης μεθόδου προτύπου.

Για να λειτουργήσει σωστά το παράδειγμα RemoveCommand, το CompanyItemProvider χρειάζεται απλά να υλοποιήσει την παρακάτω μέθοδο:

  public Collection getChildrenFeatures(Object object)
  {
    return Collections.singleton(CompanyPackage.eINSTANCE.getCompany_Departments());
  }

Αυτή η μέθοδος επιστρέφει μία ή περισσότερες λειτουργίες (σε αυτή την περίπτωση, μόνο την παραπομπή προς τα τμήματα) που χρησιμοποιούνται για την παραπομπή στα θυγατρικά στοιχεία του αντικειμένου. Μετά την κλήση αυτής της μεθόδου, η προεπιλεγμένη υλοποίηση του createCommand() θα αποφασίσει ποια λειτουργία θα χρησιμοποιηθεί (αν επιστραφούν περισσότερες από μία) και θα δημιουργήσει το στοιχείο RemoveCommand με τη σωστή λειτουργία.

Αντικατάσταση εντολών

Ένα άλλο πλεονέκτημα της δημιουργίας εντολών μέσω ενός τομέα τροποποίησης είναι ότι είναι δυνατή η προσθήκη διάφορων υποκλάσεων ή εντελώς νέων υλοποιήσεων τυπικών εντολών τις οποίες οι τυπικές λειτουργίες επεξεργασίας μπορούν να χρησιμοποιήσουν. Για παράδειγμα, έστω ότι επιθυμούμε να εκτελέσουμε ορισμένες πρόσθετες εργασίες εκκαθάρισης κάθε φορά που αφαιρούμε ένα τμήμα από μία εταιρεία. Ο απλούστερος τρόπος επίτευξης αυτού του στόχου είναι η δημιουργίας μιας υποκλάσης του στοιχείου RemoveCommand που ονομάζεται RemoveDepartmentCommand:

  public class RemoveDepartmentCommand extends RemoveCommand
  {
    public void execute()
    {
      super.execute();
      // do extra stuff ...
    }
  }

Αυτό το κομμάτι ήταν εύκολο.

Στη συνέχεια, αν η λειτουργία επεξεργασίας χρησιμοποιεί τη στατική μέθοδο RemoveCommand.create() (η οποία καλεί το editingDomain.createCommand()) αντί για το νέο RemoveCommand(), μπορούμε να αντικαταστήσουμε εύκολα το δικό μας RemoveDepartmentCommand με το τυπικό RemoveCommand αντικαθιστώντας το createCommand() στον παροχέα στοιχείων ως εξής:

  public class CompanyItemProvider ...
  {
    ...

    public Command createCommand(final Object object, ...)
    {
      if (commandClass == RemoveCommand.class)
      {
        return new RemoveDepartmentCommand(...); 
      }
      return super.createCommand(...);
    }
  }

Αν η εντολή που επιθυμείτε να εξειδικεύσετε είναι προκαθορισμένη, (όπως το RemoveCommand), η αντικατάσταση είναι ακόμη ευκολότερη καθώς η προεπιλεγμένη υλοποίηση του createCommand() αναθέτει τη δημιουργία κάθε εντολής σε βοηθητικές μεθόδους, ως εξής:

  public Command createCommand(final Object object, ...
  {
    ...
    if (commandClass == RemoveCommand.class)
      return createRemoveCommand(...); 
    else if (commandClass == AddCommand.class)
      return createAddCommand(...);
    else ...
  }

Συνεπώς, θα μπορούσαμε να δημιουργήσουμε το δικό μας RemoveDepartmentCommand με απλούστερο τρόπο, αντικαθιστώντας το createRemoveCommand(), αντί να δημιουργήσουμε τη μέθοδο createCommand():

  protected Command createRemoveCommand(...) 
  {
    return new RemoveDepartmentCommand(...);
  }

Συνοπτικά, ο τομέας τροποποίησης είναι το σημείο σύνδεσης για την προσαρμογή παραμέτρων εντολών, συμπεριλαμβανόμενης της ίδιας της κλάσης εντολών, με τον οποίο μπορούμε εύκολα να ελέγξουμε τη συμπεριφορά οποιασδήποτε εντολής τροποποίησης στο μοντέλο μας.

Ειδοποίηση για αλλαγή στο μοντέλο

Ένας παράγοντας που δεν αναφέρθηκε είναι η ειδοποίηση για αλλαγές. Πώς θα προκαλέσουμε την ανανέωση των λειτουργιών προβολής μετά από την αλλαγή κάποιου στοιχείου στο μοντέλο; Η απάντηση είναι ότι χρησιμοποιείται ένας συνδυασμός τυπικών ειδοποιήσεων προσαρμογέα EMF και ενός μηχανισμού ανανέωσης λειτουργίας προβολής που παρέχεται από το EMF.Edit.

Όταν δημιουργηθεί, το AdapterFactoryContentProvider εγγράφει τον εαυτό του ως λειτουργία ακρόασης (org.eclipse.emf.edit.provider.INotifyChangedListener) της μεθόδου κατασκευής προσαρμογέα (που υλοποιεί το περιβάλλον org.eclipse.emf.edit.provider.IChangeNotifier). Η μέθοδος κατασκευής προσαρμογέα αποστέλλει τον εαυτό της σε κάθε παροχέα στοιχείων που δημιουργεί ώστε να μπορεί να λειτουργήσει ως η κεντρική λειτουργία ειδοποίησης για αλλαγές στο μοντέλο. Το AdapterFactoryContentProvider καταγράφει επίσης (στη μέθοδο inputChanged()) τη λειτουργία προβολής για την οποία παρέχει περιεχόμενο, ώστε να μπορεί να ενημερώσει τη λειτουργία προβολής του κατά τη λήψη μιας ειδοποίησης για αλλαγή.

Το ακόλουθο διάγραμμα παρουσιάζει τον τρόπο με τον οποίο η αλλαγή σε ένα αντικείμενο μοντέλου EMF (για παράδειγμα, η αλλαγή ενός ονόματος εταιρείας) αποστέλλεται μέσω της μεθόδου κατασκευής προσαρμογέα στις λειτουργίες προβολής του μοντέλου.

Ειδοποίηση για αλλαγή στο μοντέλο

Κάθε φορά που ένα αντικείμενο EMF αλλάζει κατάσταση, η μέθοδος notifyChanged() καλείται σε όλους τους προσαρμογείς του αντικειμένου, συμπεριλαμβανόμενων των παροχέων στοιχείων (σε αυτή την περίπτωση, το CompanyItemProvider). Η μέθοδος notifyChanged() στον παροχέα στοιχείων είναι αυτή που προσδιορίζει το αν θα σταλεί στη λειτουργία προβολής μια ειδοποίηση συμβάντος, καθώς και το είδος της ενημέρωσης που θα εκτελεστεί.

Για να γίνει αυτό, τοποθετεί τις ενδιαφέρουσες ειδοποιήσεις σε ένα ViewerNotification, το οποίο είναι μια απλή υλοποίηση μιας διεπαφής IViewerNotification. Αυτή η διεπαφή επεκτείνει τη βασική διεπαφή ειδοποίησης ως εξής:

  public interface IViewerNotification extends Notification
  {
    Object getElement();
    boolean isContentRefresh();
    boolean isLabelUpdate();
  }

Αυτές οι μέθοδοι καθορίζουν το στοιχείο της λειτουργίας προβολής που θα ενημερωθεί, αν θα ανανεωθεί το περιεχόμενο του στοιχείου, καθώς και το αν θα ενημερωθεί η ετικέτα του στοιχείου. Επειδή ο παροχέας στοιχείων καθορίζει τα θυγατρικά στοιχεία και την ετικέτα ενός αντικειμένου, πρέπει επίσης να καθορίζει τον τρόπο ενημέρωσης της λειτουργίας προβολής.

Η μέθοδος notifyChanged() στην κλάση CompanyItemProvider έχει την εξής μορφή:

  public void notifyChanged(Notification notification)
  {
    ...
    switch (notification.getFeatureID(Company.class))
    {
      case CompanyPackage.COMPANY__NAME:
        fireNotifyChanged(new ViewerNotification(notification, ..., false, true));
        return;
      case CompanyPackage.COMPANY__DEPARTMENT:
        fireNotifyChanged(new ViewerNotification(notification, ..., true, false));
        return;
    }
    super.notifyChanged(notification);
  }

Σε αυτή την υλοποίηση, μια αλλαγή στο γνώρισμα ονόματος έχει ως αποτέλεσμα την ενημέρωση ετικέτας, και η αλλαγή στην παραπομπή τμήματος προκαλεί ανανέωση περιεχομένου. Οι υπόλοιπες ειδοποιήσεις για αλλαγή δεν εφαρμόζονται στη λειτουργία προβολής.

Η μέθοδος fireNotifyChanged() είναι μια βοηθητική μέθοδος στην κλάση ItemProviderAdapter (η βασική κλάση για όλους τους προσαρμογείς παροχέα στοιχείων) η οποία απλά διαβιβάζει την ειδοποίηση στη μέθοδο κατασκευής προσαρμογέα[3] . Η μέθοδος κατασκευής προσαρμογέα (λειτουργία ειδοποίησης για αλλαγές) προχωράει στην αποστολή της ειδοποίησης σε όλες τις λειτουργίες ακρόασης (σε αυτό το παράδειγμα, μόνο ο παροχέας περιεχομένου της λειτουργίας προβολής διακλάδωσης). Τέλος, ο παροχέας περιεχομένου ενημερώνει τη λειτουργία προβολής, σύμφωνα με τις οδηγίες της ειδοποίησης.

Σύνθετες μέθοδοι κατασκευής προσαρμογέα

Τα μοντέλα EMF συχνά συνδέονται μεταξύ τους με παραπομπές. Αν χρειαστεί να δημιουργήσετε μια εφαρμογή για την τροποποίηση ή εμφάνιση αντικειμένων που χρησιμοποιούνται σε περισσότερα από ένα μοντέλα EMF, θα χρειαστείτε μια μέθοδο κατασκευής προσαρμογέα με δυνατότητα προσαρμογής της ένωσης των αντικειμένων από τα δύο (ή περισσότερα μοντέλα).

Συχνά, έχετε ήδη στη διάθεσή σας μεθόδους κατασκευής προσαρμογέα για τα μεμονωμένα μοντέλα και το μόνο που χρειάζεται είναι να τα συνδυάσετε. Για αυτό το σκοπό, μπορείτε να χρησιμοποιήσετε μια άλλη βοηθητική κλάση του EMF.Edit, την ComposedAdapterFactory:

Σύνθεση μεθόδου κατασκευής προσαρμογέα

Η κλάση ComposedAdapterFactory χρησιμοποιείται για την παροχή μιας κοινής διεπαφής με άλλες μεθόδους κατασκευής προσαρμογέα, στην οποία απλά αναθέτει την υλοποίηση.

Για να ρυθμίσετε μια σύνθετη μέθοδο κατασκευής προσαρμογέα, πρέπει να συντάξετε κώδικα ο οποίος θα είναι παρόμοιος με τον εξής:

  model1AdapterFactory = ...
  model2AdapterFactory = ...

  ComposedAdapterFactory myAdapterFactory = new ComposedAdapterFactory();
  myAdapterFactory.addAdapterFactory(model1AdapterFactory);
  myAdapterFActory.addAdapterFActory(model2AdapterFactory);

  myContentProvider = new AdapterFactoryContentProvider(myAdapterFactory);
  ...

Χρήση γεννήτριας κώδικα EMF.Edit

Σημείωση: Μπορείτε να βρείτε ένα αναλυτικό πρόγραμμα εκμάθησης για τη δημιουργία ενός μοντέλου EMF, καθώς και μιας λειτουργίας επεξεργασίας EMF.Edit, στην ενότητα Δημιουργία μοντέλου EMF.

Με ένα ορισμό μοντέλου EMF, η γεννήτρια κώδικα του EMF.Edit μπορεί να δημιουργήσει ένα πλήρως λειτουργικό εργαλείο επεξεργασίας που θα επιτρέπει την προβολή χρήσεων του μοντέλου χρησιμοποιώντας διάφορες λειτουργίες προβολής, καθώς και την προσθήκη, αφαίρεση, αποκοπή, αντιγραφή και επικόλληση αντικειμένων μοντέλων, ή την τροποποίηση των αντικειμένων σε ένα τυπικό φύλλο ιδιοτήτων, όλα με πλήρη υποστήριξη αναίρεσης/ακύρωσης αναίρεσης.

Η γεννήτρια του EMF.Edit παρέχει πλήρως λειτουργικές πρόσθετες λειτουργίες που περιλαμβάνουν τα εξής:

  1. ItemProviderAdapterFactory
  2. ItemProviders (ένα ανά κλάση μοντέλου)
  3. Λειτουργία επεξεργασίας
  4. ModelWizard
  5. ActionBarContributor
  6. Πρόσθετη λειτουργία
  7. plugin.xml
  8. Εικονίδια

Όταν δημιουργηθεί, η λειτουργία επεξεργασίας θα ενεργοποιηθεί. Θα εμφανιστεί, ωστόσο δεν είναι βέβαιο ότι θα λειτουργεί όπως αναμενόταν (δηλαδή, οι προεπιλογές της γεννήτριας ίσως δεν ήταν κατάλληλες για το μοντέλο σας). Ωστόσο, η τροποποίηση του δημιουργημένου κώδικα σε ορισμένα σημεία για τη δημιουργία μιας σωστής λειτουργίας επεξεργασίας είναι μια εύκολη διαδικασία.

Παρακάτω θα βρείτε περισσότερες πληροφορίες για ορισμένες από τις πιο ενδιαφέρουσες δημιουργημένες κλάσεις.

ItemProviderAdapterFactory

Το δημιουργημένο ItemProviderAdapterFactory είναι μια απλή υποκλάση της δημιουργημένης κλάσης AdapterFactory που λάβατε κατά τη δημιουργία του μοντέλου EMF.

Σημείωση: Η δημιουργημένη μέθοδος κατασκευής προσαρμογέα EMF δημιουργεί προσαρμογείς με την αποστολή σε μια μέθοδο create() συγκεκριμένου είδους την οποία οι υποκλάσεις (όπως η ItemProviderAdapterFactory) πρέπει να αντικαταστήσουν. Η μέθοδος κατασκευής προσαρμογέα EMF (για παράδειγμα, ABCAdapterFactory) χρησιμοποιεί μια άλλη δημιουργημένη κλάση (ABCSwitch) για την αποτελεσματική υλοποίηση της αποστολής.

Κατά τη χρήση του μοτίβου Stateful, οι μέθοδοι δημιουργίας της μεθόδου κατασκευής προσαρμογέα απλά επιστρέφουν ένα νέο αντικείμενο:

  class ABCItemProviderAdapterFactory extends ABCAdapterFactoryImpl
  {
    ...
    public Adapter createCompanyAdapter()
    {
      return new CompanyItemProvider(this);
    }
    ...
  }

Διαφορετικά, αν χρησιμοποιηθεί το μοτίβο Singleton, η μέθοδος κατασκευής επίσης παρακολουθεί τη χρήση singleton και την επιστρέφει για κάθε κλήση:

  protected DepartmentItemProvider departmentItemProvider;

  public Adapter createDepartmentAdapter()
  {
    if (departmentItemProvider == null)
    {
      departmentItemProvider = new DepartmentItemProvider(this);
    }
    return departmentItemProvider;
  }

Κλάσεις ItemProvider

Για κάθε κλάση στο μοντέλο, δημιουργείται μία αντίστοιχη κλάση παροχέα. Οι δημιουργημένοι παροχείς στοιχείων συνδυάζουν όλες τις διεπαφές που απαιτούνται για την υποστήριξη των τυπικών λειτουργιών προβολής, των εντολών και του φύλλου ιδιοτήτων:

  public class DepartmentItemProvider extends ...
    implements 
      IEditingDomainItemProvider,
      IStructuredItemContentProvider, 
      ITreeItemContentProvider, 
      IItemLabelProvider, 
      IItemPropertySource
  {
    ...
  }

Αν μια κλάση μοντέλου είναι κεντρικός κόμβος (δηλαδή, δεν διαθέτει ρητή βασική κλάση) ο δημιουργημένος παροχέας στοιχείων θα κάνει επέκταση από τη βασική κλάση παροχέα στοιχείων του EMF.Edit (ItemProviderAdapter):

  public class EmployeeItemProvider extends ItemProviderAdapter ...

Διαφορετικά, αν η κλάση μοντέλου κάνει κληρονόμηση από μία βασική κλάση, ο δημιουργημένος παροχέας στοιχείων κάνει επέκταση από τον βασικό παροχέα στοιχείων ως εξής:

  public class EmployeeItemProvider extends PersonItemProvider ...

Για μια κλάση κληρονόμησης πολλαπλασιασμού, ο δημιουργημένος παροχέας στοιχείων θα επεκτείνει τον παροχέα στοιχείων της πρώτης βασικής κλάσης και θα υλοποιήσει τη λειτουργία του παροχέα για τις υπόλοιπες βασικές κλάσεις.

Αν προσέξετε τις δημιουργημένες κλάσεις παροχέα στοιχείων, θα παρατηρήσετε ότι πολλές από τις λειτουργίες τους υλοποιούνται στη βασική κλάση του παροχέα στοιχείων. Οι πιο σημαντικές λειτουργίες των δημιουργημένων υποκλάσεων παροχέα στοιχείων είναι:

  1. Εντοπισμός θυγατρικών στοιχείων και γονικού στοιχείου
  2. Ρύθμιση αρχείων περιγραφής ιδιοτήτων
  3. Αποστολή των "ενδιαφέροντων" συμβάντων ειδοποίησης.

Λειτουργία επεξεργασίας και ModelWizard

Η δημιουργημένη λειτουργία επεξεργασίας και το δημιουργημένο ModelWizard επιδεικνύουν τον τρόπο συνδυασμού όλων των δημιουργημένων τμημάτων με τα τυπικά λειτουργικά τμήματα JFace για τη δημιουργία μιας λειτουργίας επεξεργασίας.

Το ModelWizard μπορεί να χρησιμοποιηθεί για τη δημιουργία νέων πόρων του είδους του μοντέλου. Αν διαθέτετε ήδη ένα πόρο που δημιουργήθηκε με άλλο τρόπο, μπορείτε να τον εισαγάγετε στο χώρο εργασίας της επιφάνειας εργασίας και να εκκινήσετε τη λειτουργία επεξεργασίας με αυτό τον πόρο, παρακάμπτοντας εντελώς το ModelWizard.



[1] Η λειτουργία ειδοποίησης είναι η βασική διεπαφή στο EMF για αντικείμενα που μπορούν να εγγράψουν προσαρμογείς και να στείλουν ειδοποιήσεις σε αυτούς. Επεκτείνεται από το EObject, τη βασική διεπαφή για όλα τα αντικείμενα μοντέλων.

[2] Στην πραγματικότητα, οι μέθοδοι κατασκευής προσαρμογέα EMF βασίζονται στη μεταβίβαση, συνεπώς μπορείτε να επιλέξετε τη χρήση ενός βασικού προσαρμογέα για το χειρισμό υποκλάσεων σε οποιοδήποτε επίπεδο στο μοντέλο σας. Το EObject αποτελεί ακραία περίπτωση.

[3] Εκτός από τη μέθοδο κατασκευής προσαρμογέα, που χρησιμοποιείται ως λειτουργία ειδοποίησης για αλλαγές για τις λειτουργίες προβολής, το ItemProviderAdapter μπορεί επίσης να διαθέτει άλλες λειτουργίες ακρόασης (άμεσες) οι οποίες επίσης καλούνται στο ItemProviderAdapter.fireNotifyChanged().