Serialisation is the process of creating a linear stream of bytes or characters corresponding to an object structure (a graph), so the same structure can be re-constructed by de-serialising the stream. This technique is used both to save the object structure to file and to transmit it across a network.
Introduction
Persistence is the term used for storing (application) state in between sessions, in our case model instances represented by objects structures (graphs), and covers file and database storage, including SQL, object and NoSQL databases. The logic of files and databases are so different that it is easier to treat them separately. A file is essentially a sequence or array of bytes, which often encode characters, and serialisation is the term used for mapping the object structure to byte or character sequences. Although files are mostly meant for consumption by programs, they often need to be edited by hand, so a serialisation format should ideally be human-readable and to some extent editable.
Model instances are graphs in general, but it is easier to think of them as mostly hierarchical, with links across. Hence, a serialisation mechanism will typically need to support the following features:
- type information, i.e. references to EClasses in the model, so instances can be created
- attribute values, corresponding to EAttributes, so attributes of instances can be set or filled
- links, corresponding to EReferences, similar to attributes where the values are strings that can resolve to objects in the context of the object hierarchy
- containment, corresponds to EReference with containment flag set
Given these features, it is pretty easy to make a general algorithm for serialising and de-serialising object structures. To serialise, identify the root object(s) and traverse the object hierarchy. For each object output the EClass reference, and for each EStructuralFeature, output the name and values (for EAttributes) or resolvable object references (for EReferences). For containment, use some kind of nesting indicator, like curly braces and/or indentation, combined with the name of the containment EReference's name. To de-serialise, create the objects and set or fill the attributes while parsing, and store the EReference names and object identities. Containment can also handles during parsing, based on the nesting and EReference names. After the object hierarchy has been created, link them together by resolving the object references and setting or filling the EReferences.
Resources, resource factories and resource sets
The XMI formats
EMF has support for XML Metadata Interchange (XMI), which is an XML-based model format standardised by the Object Management Group (OMG).
<org:OrgModel xmi:version="2.0" xmlns:org="http://plugin/no.hal.org/model/org.ecore" xsi:schemaLocation="http://plugin/no.hal.org/model/org.ecore file:/Users/hal/java/workspaces/tdt4250/no.hal.org/model/org.ecore"> <orgUnits> <workers name="Hallvard "hal" Trætteberg" role="//@roles.0"/> </orgUnits> <roles name="manager"/> </org:OrgModel> | identifies the root object as being of the type org:OrgModel |