2.12.  Loading and saving models

[Warning]Text not verified for kermeta 2

This section explains how to load and save (deserialize and serialize) an EMF model in Kermeta. For this purpose, we will use the following small example :

cs.ecore sample metamodel

Figure 2.3. cs.ecore sample metamodel


[Note]Note

Loading and saving model has it own tutorial. It provides more information in a step by step approach. See the EMF tutorial at http://www.kermeta.org/documents/emfTutorial/

2.12.1. Prepare a model

The user will refer to Eclipse documentation for the creation of an EMF model from its ECore meta-model. We suggest to use the Wizard samples to create, at the first hand, an Ecore meta-model, and then, at the second hand, instances of this Ecore meta-model, using the generated EMF reflexive editors.

Once you created the ECore meta-model, please check that you correctly filled the property " Ns URI" of the root package of the Ecore meta-model, otherwise the resource load will fail. This NsURI must equal the real path of your metamodel. (You can modify this property through the Properties View of your meta-model)

2.12.2. Load a model from an EMF Resource

In the current version of the EMF resource loader, you have to prepare your EMF Resource following these rules :

  • At the top of the source code where you will access your model, don't forget to add require "your_metamodel.ecore" so you can tell Kermeta that you will create/load/manipulate instances of these metaclasses.

    Alternatively, you can use the Kermeta version of your metamodel using require "your_metamodel.kmt" or require "your_metamodel.km" .

    In this case, be careful that your kmt required metamodel is strictly equivalent to the ecore version of your metamodel that is used in createResource method.

  • Then, create a repository and the resource that will contain the model instance that you want to load. In the following code example, uri stands for the uri (as relative or absolute path [1] ) of the model instance, and mm_uri is the uri of the meta-model of the model instance.

@mainClass "root::TestCSLoading"
@mainOperation "main"

package root;

require kermeta
require "cs.ecore"

using kermeta::standard
using kermeta::persistence

class TestCSLoading
{
     operation initialize(uri : String, mm_uri : String) : Set<Object> is do
         /* Initialize the EMF repository */
         var repository     : EMFRepository init EMFRepository.new
         /* Create an EMF Resource */
         var resource : Resource init repository.createResource(uri, mm_uri)
         /* Load the resource */
         resource.load
         /* Get the loaded __root__ instances (a Set<Object>) */
         result := resource  // a resource is a collection of objects contained
     end
  • Once you loaded your EMF resource, you can get its attribute instances , that contains all the objects that you created through your EMF generated reflexive editor. Now you can "visit" your instances, provided you "visit" them according to their types. In the simplest way, you can make very basic tests to display your instances content, as in the following example, which visit the objects of resource instances which types are cs::Template and cs::Decision.

operation main() is do 
   var instances : Set<Object> init self.initialize("./test.cs", "./cs.ecore")
   instances.each{ o |
      if (o == void) then stdio.writeln("Void object!") 
      else 
         stdio.writeln("---------------------------------") 
         stdio.writeln("Objet : " + o.getMetaClass.typeDefinition.qualifiedName 
            + " ( " + o.getMetaClass.typeDefinition.ownedAttribute.size.toString+ "attr.)" ) 
      end
      var template : cs::Template // Print instances which type is cs::Template 
      if (cs::Template.isInstance(o)) 
      then 
         template ?= o 
         stdio.writeln(" name : " + template.name) 
         stdio.writeln(" decision : " + template.decision.toString) 
         stdio.writeln(" content : " + template.content) stdio.writeln(" referer : " + template.referer.toString) 
      end
      // Print instances which type is cs::Decision 
      if (cs::Decision.isInstance(o)) 
      then
         decision ?= o 
         stdio.writeln(" name : " + decision.name) 
      end
   }
}

If your resource is dependent of other resources and that EMF succed to load it, the Repository that was used to load your resource will automatically load all these dependent resources.

2.12.3. Save a model into an EMF Resource

To save a model, simply add the model elements in a Resource then call the save operation. All model elements contained by these added elements will also be saved in the Resource.

You can split your model in several files by using several resources, but you need to make sure that they all belong to the same Repository. Otherwise, you'll get at best a Dangling exception, or worse create inconsistent files.



[1] in this case, don't forget to put the protocol, i.e. platform:/, file:/, etc.