PyEMOF

PyEMOF is an implementation of the E-MOF (Essential MOF) specification. It provides a mapping from a EMOF 2.0 metamodel definition to a Python model repository as well as utilities to load/save a model to/from a repository from/to an XMI file. This implementation mainly follows ptc/03-10-09 without support for reflection. The Python mapping tries to follow as much as possible the "Python way".

Implementation

It is provided as a python module using distutil. To install PyEMOF as a module to your system just use the setup.py script for building (as lambda user) and for installing (as root / admin). Then PyEMOF is widely available on your system.

PyEMOF-x.y.z $ python setup.py build
PyEMOF-x.y.z $ sudo python setup.py install

The examplse folder of the distributed package contains examples of metamodel definitions (EMOF, that has been use for the generation of PyEMOF itself), as well as this Tutorial.

The following code creates a metamodel which package is registered to the repository. Roots of (meta)models have to be registered in order to be considered for serialization using the dumper utility. In the context of metamodel definition, only the packages (each one is considered as a metamodel) have to be registered.

Python 2.5.1 (r251:54869, Apr 18 2007, 22:08:04)
[GCC 4.0.1 (Apple Computer, Inc. build 5367)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import emof.core as EMOF
>>> rep = EMOF.Repository()
>>> foo = EMOF.Package()
>>> foo.name = 'foo'
>>> bar = EMOF.Class()
>>> bar.name = 'bar'
>>> rep.Package.append(foo)
>>> foo.ownedType.append(bar)
>>> import emof.dumper
>>> emof.dumper.Dumper().dump(rep, 'foo.xmi')

The second way to achieve this metamodel definition is to use the factory provided in the core package. The factory automatically attach metamodel elements to the repository.

Python 2.5.1 (r251:54869, Apr 18 2007, 22:08:04)
[GCC 4.0.1 (Apple Computer, Inc. build 5367)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> from emof.core import Repository, Factory
>>> rep = Repository()
>>> fact = Factory(rep)
>>> foo = fact.create_Package()
>>> foo.name = 'foo'
>>> bar = fact.create_Class()
>>> bar.name = 'bar'
>>> foo.ownedType.append(bar)
>>> from emof.dumper import Dumper
>>> Dumper().dump(rep, 'foo.xmi')

The previous code (whatever the version you use) generates the following metamodel definition (which you can simply type as xml into a file).

$ cat foo.xmi
<?xml version="1.0" ?>
<xmi:XMI xmi:version="2.0"
         xmlns:emof="http://nowhere/emof.xmi"
         xmlns:xmi="http://www.omg.org/XMI"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <emof:Package name="foo" xmi:id="Package:1">
    <ownedType name="bar" xmi:id="Class:1" xsi:type="emof:Class"/>
  </emof:Package>
</xmi:XMI>

In order to produce the repository module together with its loading and dumping utilities, you only have to use the pyemof scripts.

$ ls
foo.xmi
$ pyemof foo.xmi
$ ls
foo.xmi         foo/
$ ls *
foo.xmi

foo:
__init__.py     core.py         dumper.py       loader.py

This shows that for each metamodel, a package (named like the metamodel in lower case) and three modules are generated:

For MS-Windows users, if your installation does not give you easy access to pyemof executable, you can use the script as argument to the Python interpreter. If your Python installation directory is \Python2.4, then you should be able to use the following command.

C:\Temp> python \Python2.4\scripts\pyemof foo.xmi

Finally, you can also write metamodels using a simple textual syntax. However, this facility does not provide (yet) all the possibilities of the XML / programmatic ones (like opposite, uniqueness, order, and so on of attributes). A simple Java metamodel can be defined as follows.

package java {
  primitive String ;
  class Class {
    attribute name : String ;
    attribute attr : Attribute [0..*] isComposite ;
    attribute meth : Method [0..*] isComposite ;
  }
  class Attribute {
    attribute name : String ;
    attribute type : Class ;
  }
  class Method {
    attribute name : String ;
    attribute type : Class ;
    attribute args : Parameter [0..*] isComposite ;
  }
  class Parameter {
    attribute name : String ;
    attribute type : Class ;
  }
}

In order to load this description in memory, a parser is provided in the pyemof module (for programatic use).

>>> import pyemof.parser
>>> rep = pyemof.parser.process('Java.emof')

For a command line use of textual definition (before repository generation) the emof2xmi utility performs the transformation from text to xmi version of a metamodel definition.

$ ls
java.emof
$ emof2xmi java.emof
$ ls
java.emof       java.xmi

For MS-Windows users, the same trick as for pyemof applies, both scripts are stored in the same place.

Limitations Currently PyEMOF does only support Class and Primitive types (no Enumerate). Primitive support should be improved.

Download

_Requires_