EMF JSON mapper at EMF.cloud!

Do you want to convert EMF model instances into JSON or vice versa? Do you want to make EMF data available via REST services? Then carry on reading. In this post, we introduce the EMF JSON Jackson mapper that has been contributed to EMF.cloud!

When implementing tools or business applications using EMF in the backend, you often have to bridge between Java (EMF) and JavaScript (JSON). This also applies, if you migrate existing Eclipse applications, e.g. by keeping EMF for the business logic, but adding a browser-based frontend.

To solve the conversion between EMF and JSON, the EMF.cloud project provides a mapper between the two formats based on Jackson. It allows you to transform an EMF model instance into JSON and vice versa. There are essentially two ways of using the EMF.cloud EMF JSON mapper. First, in case you use the EMF resource API, it provides a resource implementation that allows you to serialize EMF into JSON. This can be stored into a file, but also used in memory with a virtual resource.

ResourceSet resourceSet = new ResourceSetImpl();
resourceSet.getResourceFactoryRegistry().getExtensionToFactoryMap().put("json", new JsonResourceFactory());
Resource resource = resourceSet.createResource(URI.createFileURI("my.json"));
resource.getContents().add(myEMFObject);
resource.save(null);

Second, if you do not want to use the EMF resource API, the EMF JSON mapper also directly supports the Jackson Object Mapper API. So after configuring the mapper the conversion would simply look like this for a resource:

JsonNode jsonNode = mapper.valueToTree(resource);

This even supports converting single objects like this:

String jsonString = mapper.writeValueAsString(bob);

Both ways produce JSON as you would expect, e.g. like this:

{
  "eClass": "http://myURI//User",
  "firstName": "Jonas",
  "lastName": "Helming"
}

As you can see, the mapper adds the class information by default. However, using Jackson as an existing mapping technology allows you to fully customize the conversion. As an example you can adapt the property name in JSON to be different from the one in EMF. Jackson provides several ways to do that, e.g. by annotation properties or by using the mapper API. You can even register a custom serializer and deserializer in case… For Ecore specific concepts, such as the class information, the id or for reference handling, there are existing “TypeInfos” you can use for customization. As an example, if you want to change the name and value of the “eClass” property, you can do that like this:

module.setTypeInfo(new EcoreTypeInfo("type",
  new ValueWriter<EClass, String>() {
    @Override
    public String writeValue(EClass value, SerializerProvider context) {
      return value.getName();
    }
  }));

It changes the name of the property to “type” (first argument) and the value to the name of the EClass (ValueWriter). This would result in the following JSON output:

{
  "type": "User",
  "firstName": "Jonas",
  "lastName": "Helming"
}

Similarly, you can customize other properties, including the way that references are serialized. Therefore, the solution provides a lot of flexibility to match your respective and potentially custom use case.

The EMF JSON mapper can be easily integrated into any existing application. It can be used in plain Java, no OSGi is even required. A very common use case is to use it for the implementation of REST services that provide access to model instances. While the in-memory representation is using EMF, the REST service provides the data as JSON.

The EMF JSON Jackson mapper was contributed to the EMF.cloud project by Guillaume Hillairet, we are grateful for this very valuable addition! Please find more details and links to the documentation on the EMF.cloud project homepage.

The EMF JSON mapper has already been adopted in several projects. It is also a central part of the EMF.cloud model server, that allows you to connect various clients/editors to one model entity hosted on the server (see this example web-based tool based on Theia to see the model server in action).

The EMF.cloud project is an umbrella project for components that enables the benefits of EMF in the web and cloud. The EMF JSON mapper is a perfect example of this and there are other components like this, such as the model server or the framework to build tree editors. So take a look at the EMF.cloud website to find out more. In case you own a component like the EMF JSON mapper or in case you want to adapt any existing component: EMF.cloud is very open to any contributions!

Finally, if you need support and consulting to implement a new tool for the web or to migrate your existing toolchain, please get in contact with us. We provide support for EMF.cloud and EMF plus we can support you in implementing a web-based tool based on Eclipse Theia, VS Code or any other platform that suits your specific project.