Software Engineer

Category: Frameworks (Page 1 of 2)

Django, django_tables2 and Bootstrap Table

I was always intrigued by Django. After all, it’s slogan is “The web framework for perfectionists with deadlines”. Last year I started a project for a client who needed a web app to manage a digital printing workflow. I evaluated Django and did their tutorial (which is really well made by the way). Since the project also required lots of data processing of different data sources (CSV, XML, etc.) Python made a lot of sense. So in the end the choice was to use Django.

I needed to create several tabIes showing data from the Django models. In this post I explain how I combined django_tables2 (for the table definitions) and Bootstrap Table (for visualizing the tables and client-side table features).

Continue reading

Making EMF models serialized in XMI available in JSON with emfjson

This summer we had two interns in our team who started creating a web application for our TouchCORE tool. I have wanted this for a long time. Not only does it allow you to model in your browser, you can also do this collaboratively! For now class diagrams are supported but more supported will be added in the future (for example for sequence diagrams and feature models).

Re-creating the complete application right away was not feasible for this project. Also, we are all about reuse and I had envisioned in the architecture to reuse the backend parts when we build another user interface. Therefore, the goal was to keep our current backend based on the Eclipse Modeling Framework (EMF) and making it available through an API to the web application. Fortunately, there is already support for EMF and JSON by emfjson. The main use case however is to replace the XML/XMI serialization/deserialization with JSON.

There is a way to keep XMI on the backend and making it available through JSON. This allows to keep the XMI serialization which is still being used by the existing application. It requires to use unique IDs when serializing, otherwise you need to manage your own ID mapping (see below).

The emfjson-jackson setup is as follows:

ObjectMapper mapper = new ObjectMapper();
// Optional
mapper.configure(SerializationFeature.INDENT_OUTPUT, true);
        
module = new EMFModule();
module.configure(EMFModule.Feature.OPTION_USE_ID, true);
// Optional
module.configure(EMFModule.Feature.OPTION_SERIALIZE_TYPE, true);

module.setIdentityInfo(new EcoreIdentityInfo("_id"));
mapper.registerModule(module);

The use of IDs along with the EcoreIdentityInfo ensures that the IDs used by EMF during serialization are used. Now, assuming you loaded an existing model from a resource for any EObject of that model you can get the JSON by calling:

mapper.writeValueAsString(eObject)

To do the reverse, you can identify an object by its ID. To retrieve the EObject for a given ID EMF of course has a handy utility method. For this, you need the Resource of your model.

resource.getEObject(id)

To get the ID of an object you can use resource.getURIFragment(eObject).

If you have cross-references in your models to other models, the URI you get is of the form “anotherModel.ext#id”. You can use the ResourceSet to get the resource of the other model or the cross-referenced object using the resource set’s getResource(URI, boolean) and getEObject(URI, boolean) methods.

You can also maintain your own ID mapping by passing a custom ValueWriter as a second parameter to EcoreIdentityInfo, for example:

module.setIdentityInfo(new EcoreIdentityInfo("_id",
    new ValueWriter<EObject, Object>() {
        @Override
        public Object writeValue(EObject eObj, SerializerProvider context) {
            // TODO: return ID of object
        }
    }
));

Furthermore, you need to handle references between objects specifically by customizing the reference serializer:

module.setReferenceSerializer(new JsonSerializer<EObject>() {
    @Override
    public void serialize(EObject eObject, JsonGenerator generator, SerializerProvider serializer) throws IOException {
        generator.writeString(/* TODO: Get the ID of eObject */);
    }
});

There is one caveat though. That is when using EMF notifications on the backend to notify the frontend that something changed. If an object is deleted, EMF does not give you an ID for this deleted object anymore. That’s why we in the end used the custom ID solution.

As I researched some links for this post I noticed that there is now a whole Eclipse project to make EMF available in the cloud (EMF.cloud). It would be interesting to evaluate whether these technologies (Sprotty as the web-diagramming framework and GLSP as the graphical language server protocol) are more suitable instead of a custom-baked solution. Currently we use Spring Boot on the backend with web sockets and Angular with mxgraph on the frontend.

Deploying Angular application on Apache server

If you need to deploy an Angular application on a server running Apache, and are making use of routing for navigation, you can’t just upload the built application onto the server and be done with it. As soon as you navigate to another path, the Apache server will try to look for that resource on the server and most likely will give you an 404 Not Found error.

You need to rewrite all the URLs to the index.html so that the Angular application can take care of it. Your server needs to support mod_rewrite for that. If that is the case, you can upload a file .htaccess with the following content to your directory where the Angular application resides in.

RewriteEngine on
RewriteBase /

RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_URI} !^/assets/(.+)$
RewriteRule ^(.+)$ index.html?path=$1 [L]

This will rewrite all requests to the index.html file and append any extra path to it. Unless, the request is for an existing file or directory on the server, then it will not rewrite it. This is necessary for the additional resources that will need to be loaded, such as CSS and JS files and images.

In order to get the necessary feedback when a resource is requested that does not exist, the third condition excludes to rewrite any request located inside the assets folder.

MT4j with Processing 2

In our TouchCORE project at the Software Engineering Lab at McGill University, we use MT4j (Multitouch for Java) for the multitouch-enabled user interface.

For a long time, we had the problem that we couldn’t run it on OSX using Java 7 and newer, because it is based on an older version of Processing (1.x), which in turn uses an old version of JOGL (Java Binding for the OpenGL API). That version is only compatible with the Java supplied by Apple. As we know, they stopped support with Java 6.

We grudgingly lived with this state for a long time, which meant that OSX users needed to download and use an old version of Java. Now, with the new release of Eclipse Mars, support for Java 6 was dropped, i.e., Java 7 or greater is required. We wanted to update to Mars, and since we use some Eclipse plugins, such as the Eclipse Modeling Framework (EMF), we needed to use at least Java 7.

This finally pushed us to update MT4j ourselves. With the help of the UltraCom project who did the same but added a ton of other stuff. Based on their commits we managed to update it on our copy (which already had some minor improvements) of MT4j’s last official release v0.98.

We put it up on GitHub so hopefully other people can benefit from it: https://github.com/mschoettle/mt4j

How to use OCL when running EMF standalone with Eclipse Mars

I previously explained on how to use OCL when running EMF in standalone (not as an Eclipse application). This method works until Eclipse Luna. With Eclipse Mars, OCL was heavily updated again. For instance, it was promoted out of the examples space.

The good thing is it seems to be much easier to initialize it now. Add a dependency to org.eclipse.ocl.xtext.completeocl and use the following code:

PivotStandaloneSetup.doSetup();
CompleteOCLStandaloneSetup.doSetup();
« Older posts

© 2024 Matthias Schoettle

Theme by Anders NorenUp ↑