Support free tutorials:











vogella training Training Books



Eclipse Modeling Framework (EMF) - Persisting models via XMI - Tutorial

Lars Vogel

Version 1.2

24.07.2012

Revision History
Revision 0.1 20.01.2010 Lars
Vogel
split from main EMF article into own article
Revision 0.2 - 1.2 01.03.2010 - 24.07.2012 Lars
Vogel
bug fixes and enhancements

Persistence with Eclipse EMF

This tutorial describes how to persists Eclipse EMF in XMI (XML). This article is based on Eclipse 4.2 (Juno).


Table of Contents

1. Prerequisites
2. Persisting EMF models via XMI
3.
3.1. Example
3.2. Load an existing model
4. Appendix: Encryption
5. Support free vogella tutorials
5.1. Thank you
5.2. Questions and Discussion
6. Links and Literature
6.1. Source Code
6.2. EMF Resources
6.3. vogella Resources

1. Prerequisites

This article focus on the persistence of EMF models via XMI. For an introduction into Eclipse EMF please see Eclipse EMF.

2. Persisting EMF models via XMI

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.

3.1. Example

The following is based on the EMF model created in EMF Tutorial which we are going to persists. 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

package writeWebpage;

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 datamodel.website.MyWeb;
import datamodel.website.Webpage;
import datamodel.website.WebsiteFactory;
import datamodel.website.WebsitePackage;
import datamodel.website.impl.WebsitePackageImpl;

public class CreateSaveTester {

  
/** * @param args */
public static void main(String[] args) { // Initialize the model WebsitePackage.eINSTANCE.eClass(); // Retrieve the default factory singleton WebsiteFactory factory = WebsiteFactory.eINSTANCE; // create the content of the model via this program MyWeb myWeb = factory.createMyWeb(); Webpage page = factory.createWebpage(); page.setName("index"); page.setDescription("Main webpage"); page.setKeywords("Eclipse, EMF"); page.setTitle("Eclipse EMF"); myWeb.getPages().add(page); // 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(); } } }

3.2. Load an existing model

The following code can be used to load an existing model.

package writeWebpage;

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 datamodel.website.MyWeb;
import datamodel.website.WebsitePackage;
import datamodel.website.impl.WebsitePackageImpl;

public class EMFModelLoad {
  public MyWeb load() {
    // Initialize the model
    WebsitePackage.eINSTANCE.eClass();
    
    // 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();

    // Get the resource
    Resource resource = resSet.getResource(URI
        .createURI("website/My.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
    MyWeb myWeb = (MyWeb) resource.getContents().get(0);
    return myWeb;
  }

} 

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

package writeWebpage;

import java.util.Iterator;

import datamodel.website.MyWeb;
import datamodel.website.Webpage;

public class LoadTest {

  
/** * @param args */
public static void main(String[] args) { // Loading the existing model EMFModelLoad loader = new EMFModelLoad(); MyWeb 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 (Iterator<Webpage> iterator = myWeb.getPages().iterator(); iterator .hasNext();) { Webpage page = iterator.next(); System.out.println("Name : " + page.getName()); // We could also iterate over the Articles... } } }

4. Appendix: Encryption

EMF has the possibility to encrypt the data model before writing it and to decrypt it before loading. The following demonstrates this.

Create an model based on the following interface.

package mymodel;

import org.eclipse.emf.ecore.EObject;
/** * @model */
public interface IPerson extends EObject {
/** * @model default=""; */
public String getLastname(); }

Create the following factory which sets the option for encryption.

package factory;

import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.resource.impl.AESCipherImpl;
import org.eclipse.emf.ecore.xmi.XMIResource;
import org.eclipse.emf.ecore.xmi.impl.XMIResourceFactoryImpl;

public class MyXMIFactoryImpl extends XMIResourceFactoryImpl {

  @Override
  public Resource createResource(URI uri) {
    XMIResourceFactoryImpl resFactory = new XMIResourceFactoryImpl();
    XMIResource resource = (XMIResource) resFactory.createResource(uri);
    try {
      resource.getDefaultLoadOptions().put(Resource.OPTION_CIPHER,
          new AESCipherImpl("12345"));
      resource.getDefaultSaveOptions().put(Resource.OPTION_CIPHER,
          new AESCipherImpl("12345"));
    } catch (Exception e) {
      e.printStackTrace();
    }
    return resource;
  }
} 

Create the following test class.

package load;

import java.io.IOException;
import java.util.Collections;
import java.util.Map;

import mymodel.IPerson;
import mymodel.MymodelFactory;
import mymodel.impl.MymodelPackageImpl;

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 factory.MyXMIFactoryImpl;

public class Create {
  public void create() {
    MymodelPackageImpl.init();
    // Retrieve the default factory singleton
    MymodelFactory factory = MymodelFactory.eINSTANCE;

    // create the content of the model via this program
    IPerson person = factory.createIPerson();
    person.setLastname("Lars");

    // 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("person", new MyXMIFactoryImpl());

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

    // create a resource
    Resource resource = resSet.createResource(URI
    .createURI("mymodel.person"));
    resource.getContents().add(person);

    // now save the content.
      try {
        resource.save(Collections.EMPTY_MAP);
      } catch (IOException e) {
        e.printStackTrace();
      }
  }
  
  public void load() {
    // Initialize the model
    MymodelPackageImpl.init();
    // 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("person", new MyXMIFactoryImpl());
    ResourceSet resSet = new ResourceSetImpl();
    Resource resource = resSet.getResource(URI
        .createURI("mymodel.person"), true);
    try {
      IPerson person= (IPerson) resource.getContents().get(0);
      System.out.println(person.getLastname());
    } catch (Exception e) {
      e.printStackTrace();
    }
  }
  
  public static void main(String[] args){
    Create test = new Create();
    test.create();
    test.load();
  }
} 

5. Support free vogella tutorials

Maintaining high quality free online tutorials is a lot of work. Please support free tutorials by donating or by reporting typos and factual errors.

5.1. Thank you

Please consider a contribution if this article helped you.

Flattr this

5.2. Questions and Discussion

If you find errors in this tutorial, please notify me (see the top of the page). Please note that due to the high volume of feedback I receive, I cannot answer questions to your implementation. Ensure you have read the vogella FAQ as I don't respond to questions already answered there.

6. Links and Literature

6.1. Source Code

Source Code of Examples

6.2. EMF Resources

http://www.eclipse.org/modeling/emf Eclipse EMF Homepage

http://www.eclipse.org/modeling/emf/docs/ EMF Documentation

http://www.ibm.com/developerworks/opensource/library/os-ecemf1 Model with the Eclipse Modeling Framework, Part 1: Create UML models and generate code

http://www.ibm.com/developerworks/opensource/library/os-ecemf2 Model with the Eclipse Modeling Framework, Part 2: Generate code with Eclipse's Java Emitter Templates

http://www.eclipse.org/m2m/atl/ ATL allows model to model transformation for EMF

6.3. vogella Resources

vogella Training Android and Eclipse Training from the vogella team

Android Tutorial Introduction to Android Programming

GWT Tutorial Program in Java, compile to JavaScript and HTML

Eclipse RCP Tutorial Create native applications in Java

JUnit Tutorial Test your application

Git Tutorial Put all your files in a distributed version control system