EMF: Load Model with eProxyURI References

The Eclipse EMF persistence framework enables you to store your model into separate Resources combined in a ResourceSet. This makes absolutely sense e.g. for large models or conceptual separated model parts. By simply initializing a resource set and loading the model, you will end up with a eProxyURI element instead of a reference to the linked model and you will not be able to navigate this. Loading these models via the EMF persistency framework requires to prepare some infrastucuture to make this working as described below.

For example, extracting a OMG KDM model using the MoDisco Java Discoverer (http://wiki.eclipse.org/MoDisco/SimpleTransformationChain#Contextual_menu) results in a set of models representing your software artifacts of a JDT project:

The model file _java2kdm.xmi represents the starting point to enter the model. It contains only references to the other models containing different parts of the overall model.

To load a complete resource set you need to

  1. load the required packages
  2. register the xmi resource factory (if not registered by default in your environment)
  3. create the resource set
  4. load the resource
  5. resolve all proxies

This can be done by he following code:


// load the required meta class packages
JavaapplicationPackage.eINSTANCE.eClass();
JavaPackage.eINSTANCE.eClass();

// register the factory to be able to read xmi files
Resource.Factory.Registry.INSTANCE.getExtensionToFactoryMap()
.put(Resource.Factory.Registry.DEFAULT_EXTENSION,new XMIResourceFactoryImpl());

// load the resource and resolve the proxies
ResourceSet rs = new ResourceSetImpl();
Resource r = rs.createResource(URI.createFileURI(java2kdmModelFile.getAbsolutePath()));
r.load(null);
EcoreUtil.resolveAll(rs)

Now the model can be loaded and the references will be resolved. If you want to access the JavaApplicationModel you can access the first element of the resource and convert it:

// convert the model to a java model
EObject model = r.getContents().get(0);
if(!(model instanceof JavaApplication)){
throw new IllegalArgumentException("Model is not a JavaApplication: "+model.getClass().getName());
}
JavaApplication javaApplicationModel = (JavaApplication)model;

The code provided below manages to load a java / kdm model extracted by the MoDisco tooling. Note that the class KDMUtils has a method loadKDMModelFromDirectory() which requires the base path where all of your models are stored in (as shown in the picture above)

package org.splevo.diffing.kdm;

import java.io.File;
import java.io.IOException;

import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EObject;
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.util.EcoreUtil;
import org.eclipse.emf.ecore.xmi.impl.XMIResourceFactoryImpl;
import org.eclipse.gmt.modisco.java.emf.JavaPackage;
import org.eclipse.modisco.java.composition.javaapplication.JavaApplication;
import org.eclipse.modisco.java.composition.javaapplication.JavaapplicationPackage;

/**
 * The Class KDMUtils. Utility class to handle omg kdm models in general and
 * java specific extended models in specific.
 */
public class KDMUtil {

	  /**
	   * Load Java2KDM model from the standard java2kdm file set.
	   * 
	   * Based on a supplied main file loads the complete resource set, resolves all proxies 
	   * and returns the JavaApplication model.
	   * 
	   * Note that the method is limited to java specific application models because their is no
	   * other discoverer available at the moment.
	   * 
	   * @param java2kdmModelFile
	   *            The file object pointing to the main model file
	   * @return the loaded java application model
	   * @throws IOException
	   *             Identifies that the file could not be loaded
	   */
	  public static JavaApplication loadKDMModel(File java2kdmModelFile) throws IOException{

		// check that the file is accessible
		if (!java2kdmModelFile.canRead()) {
			throw new IOException("cannot read model file "+ java2kdmModelFile);
		}
	    
	    // load the required meta class packages
	    JavaapplicationPackage.eINSTANCE.eClass();
	    JavaPackage.eINSTANCE.eClass();

	    // register the factory to be able to read xmi files
	    Resource.Factory.Registry.INSTANCE.getExtensionToFactoryMap()
	    				.put(Resource.Factory.Registry.DEFAULT_EXTENSION,new XMIResourceFactoryImpl());
	    
	    // load the resource and resolve the proxies
	    ResourceSet rs = new ResourceSetImpl();
	    Resource r = rs.createResource(URI.createFileURI(java2kdmModelFile.getAbsolutePath()));
	    r.load(null);
	    EcoreUtil.resolveAll(rs);
	    
	    // convert the model to a java model
	    EObject model = r.getContents().get(0);
	    if(!(model instanceof JavaApplication)){
	      throw new IllegalArgumentException("Model is not a JavaApplication: "+model.getClass().getName());
	    }
		JavaApplication javaApplicationModel = (JavaApplication)model;
	    
	    return javaApplicationModel;
	  }
}

Leave a Comment