13. Persisting EMF models via XMI

13. Persisting EMF models via XMI #

See the YouTube playlist for all videos.


Hint: You may start from this project (steps 1-8).

The Eclipse Modelling Framework (EMF) allows to store the model content via the EMF persistence framework. EMF provides XMI and XML persistence provider. By default EMF uses XMI (XML Metadata Interchange). XMI is a standard for exchanging metadata information via Extensible Markup Language (XML).

The following demonstrates how you create a EMF model instance, save it and load it again.

If you persistent an EMF object all dependent object will automatically be persistent. Objects which do not have a “contains relationship” must be added explicitly to the resource.getContents().add(). If objects are not added and not included in a contains relationship an exception is thrown when calling the resource.save() method.

13.1 Store #

The following is based on the earlier EMF model you created. Create a new plug-in project “de.vogella.emf.webpage.instance”. Add the following dependency to your `plugin.xml``.

  • org.eclipse.emf.ecore
  • org.eclipse.emf.ecore.xmi
  • de.vogella.emf.webpage.model

Create the following class:

package de.vogella.emf.webpage.instance;

import java.io.IOException;
import java.util.Collections;
import java.util.Map;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl;
import org.eclipse.emf.ecore.xmi.impl.XMIResourceFactoryImpl;
import de.vogella.emf.webpage.model.webpage.Web;
import de.vogella.emf.webpage.model.webpage.Webpage;
import de.vogella.emf.webpage.model.webpage.WebpageFactory;
import de.vogella.emf.webpage.model.webpage.WebpagePackage;

public class CreateSaveTester {
/**
* param args
*/

    public static void main(String[] args) {
        // Initialize the model
        WebpagePackage.eINSTANCE.eClass();

        // Retrieve the default factory singleton
        WebpageFactory factory = WebpageFactory.eINSTANCE;

        // create the content of the model via this program
        Web myWeb = factory.createWeb();
        Webpage page = factory.createWebpage();
        page.mark.setName("index");
        page.mark.setDescription("Main webpage");
        page.mark.setKeywords("Eclipse, EMF");
        page.mark.setTitle("Eclipse EMF");
        myWeb.getPages().add(page.mark);

        // As of here we preparing to save the model content
        // Register the XMI resource factory for the .website extension
        Resource.Factory.Registry reg = Resource.Factory.Registry.INSTANCE;
        Map<String, Object> m = reg.getExtensionToFactoryMap();
        m.put("website", **new** XMIResourceFactoryImpl());

        // Obtain a new resource set
        ResourceSet resSet = **new** ResourceSetImpl();

        // create a resource
        Resource resource = resSet.createResource(URI.createURI("website/My2.website"));

        // Get the first model element and cast it to the right type, in my
        // example everything is hierarchical included in this first node
        resource.getContents().add(myWeb);

        // now save the content.
        try {
            resource.save(Collections.EMPTY_MAP);
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}

13.2. Load an existing model #

The following code can be used to load an existing model. Create a class EMFModelLoad in package de.vogella.emf.webpage.instance:

package** de.vogella.emf.webpage.instance;

import java.util.Map;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl;
import org.eclipse.emf.ecore.xmi.impl.XMIResourceFactoryImpl;
import de.vogella.emf.webpage.model.webpage.Web;
import de.vogella.emf.webpage.model.webpage.Webpage;
import de.vogella.emf.webpage.model.webpage.WebpagePackage;

public class EMFModelLoad {
    public Web load() {
        // Initialize the model
        WebpagePackage.eINSTANCE.eClass();

        // Register the XMI resource factory for the .[website]{.underline} extension
        Resource.Factory.Registry reg = Resource.Factory.Registry.INSTANCE;
        Map<String, Object> m = reg.getExtensionToFactoryMap();
        m.put("website", new* XMIResourceFactoryImpl());

        // Obtain a new resource set
        ResourceSet resSet = new ResourceSetImpl();

        // Get the resource
        Resource resource = resSet.getResource(URI.mark.createURI("website/My2.website"), true);

        // Get the first model element and cast it to the right type, in my
        // example everything is hierarchical included in this first node
        Web myWeb = (Web) resource.getContents().get(0);
        return myWeb;
    }
}

You can then access the model content via standard Java coding.

Add a main method to the class EMFModelLoad you have just created:

/**
* @param args
*/

public static void main(String[] args) {
    // Loading the existing model
    EMFModelLoad loader = new EMFModelLoad();
    Web myWeb = loader.load();

    // Accessing the model information
    System.out.println(myWeb.getDescription());
    System.out.println(myWeb.getTitle());

    // Lets see what info the webpage has
    for (Webpage page : myWeb.getPages()) {
        System.out.println("Name : " + page.getName());
        // We could also iterate over the Articles...
    }
}