Thursday, February 16, 2012

First Eclipse Modeling Framework (EMF) example - 2

In the previous article we started exploring Eclipse EMF. In this article we will build a domain model (persistent data model) of a small library management system.

To start, let us create a new project:

        - select File --> New --> Project
        - Then, in the opening window, select Eclipse Modeling Framework --> Empty EMF Project



Let's name our project testemf.

Then, in folder model, use the mouse's right button,



and select New --> Other. A new window opens:



Here, select EcoreTools --> Ecore Diagram. The goal is to create a domain model by using the UML class diagram editor.

Creating the Ecore Diagram is a nice way of creating an Ecore model, instance of the Ecore metamodel. We can, then, understand this as the creation of a DSL (Domain Specific Language). Let us name our DSL as LibraryModel.


In the diagrams editor, we create the intended class model:



To do that, we drag and drop metamodel elements from the Pallete, of which we want to create instances. For example, to create class Book (instance of EClass) we drag element EClass from the Pallete, and name it Book. To create attributes we drag element EAttribute, and drop it in the class' attributes area, and so on.

As we want to generate code from our diagram, this must be complete. Thus, we shall specify the data type of each attribute.

To create relations (associations) between classes, we must drag fro the Pallete the element EReference. A relation is, by default, of type one to many and is navigable in that direction, that is only the side "many" is referrable. In the relation's properties we may modify the name and cardinality of the relation attribute.

If we want a relation to be navigable in both directions, we must create two relations and specify one as the opposite relation of the other.

More information about editting diagrams using this editor can be obtained from:

        - Eclipse Modeling Framework (EMF) - Tutorial

More information about UML (Unified Modeling Language) can be obtained, for example, in:

        - Capítulo 2. Fundamentos do UML

When creating the Ecore diagram (LibraryModel.ecorediag), an Ecore model (LibraryModel.ecore) is automatically created with the same information.



From the ecore model, we are going to create a model for code generation. With the right hand mouse button over the ecore model file (LibraryModel.ecore), we select New --> Other,




Then, select EclipseModelingFramework --> EMF Generator Model:



And we select the Ecore model importer:



Model LibraryModel.genmodel is then generated:



From this model, we are going to generate Java code corresponding to the classes in the initial model:


The project, then, becomes with the following files:

Three Java packages have been generated:

        - LibraryModel - contains the Java interfaces corresponding to the classes in the model, and the Factory class that enables the creation of classes' instances.
        - LibraryModel.impl - contains the classes that implement the interfaces.
        - LibraryModel.util - contains the AdapterFactory.

Let's look at the generated code for class Author in our model:

- Author.java:

package LibraryModel;

import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.ecore.EObject;

public interface Author extends EObject {
    String getName();
    void setName(String value);
    String getSurname();
    void setSurname(String value);
    EList<Book> getBooks();
} // Author

- AuthorImpl.java:

package LibraryModel.impl;

import LibraryModel.Author;
import LibraryModel.Book;
import LibraryModel.LibraryModelPackage;
import java.util.Collection;
import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.common.util.EList;
...

public class AuthorImpl extends EObjectImpl implements Author {
    protected static final String NAME_EDEFAULT = null;
    protected String name = NAME_EDEFAULT;
    protected static final String SURNAME_EDEFAULT = null;
    protected String surname = SURNAME_EDEFAULT;
    protected EList<Book> books;

    protected AuthorImpl() {
        super();
    }

    @Override
    protected EClass eStaticClass() {
        return LibraryModelPackage.Literals.AUTHOR;
    }

    public String getName() {
        return name;
    }

    public void setName(String newName) {
        String oldName = name;
        name = newName;
        if (eNotificationRequired())
            eNotify(new ENotificationImpl(this, Notification.SET, LibraryModelPackage.AUTHOR__NAME, oldName, name));
    }

    public String getSurname() {
        return surname;
    }

    public void setSurname(String newSurname) {
        String oldSurname = surname;
        surname = newSurname;
        if (eNotificationRequired())
            eNotify(new ENotificationImpl(this, Notification.SET, LibraryModelPackage.AUTHOR__SURNAME, oldSurname, surname));
    }

    public EList<Book> getBooks() {
        if (books == null) {
            books = new EObjectWithInverseResolvingEList.ManyInverse<Book>(Book.class, this, LibraryModelPackage.AUTHOR__BOOKS, LibraryModelPackage.BOOK__AUTHORS);
        }
        return books;
    }

 . . .

    @Override
    public String toString() {
        if (eIsProxy()) return super.toString();

        StringBuffer result = new StringBuffer(super.toString());
        result.append(" (name: ");
        result.append(name);
        result.append(", surname: ");
        result.append(surname);
        result.append(')');
        return result.toString();
    }

} //AuthorImpl



We may create the documentation about the generated classes, using Javadoc. For that, in the Project menu, select Generate Javadoc...:




And the documentation is generated:


In the next article we will test the generated classes through a simple method Main()...


Related articles:
        - First Eclipse Modeling Framework (EMF) example - 1
        - First Eclipse Modeling Framework (EMF) example - 3


No comments:

Post a Comment