Generating JSNI code for GWT with codemodel 14 Dec 2014
Hi everyone,
In the past 4 months, outside my work time, I have been writing a new GWT wrapper for the great highcharts library. It is not finished yet, but I have now something that is usable I think. If you are interested have a look the the Github project page. If you are not familiar with JSNI please have a look to the corresponding GWT project page.
So the idea was to be able to generate the wrapper code, I wanted to write a wrapper that I would not have to maintain by hand everytime a new option was made available by the highcharts team. The highcharts library use a Json file that describes all the available options, it is available here, just click the “as JSON” to see the raw file.
One option typically looks like this :
So my idea was to read that option file and to generate the wapper for GWT. This is what I am going to talk about in the following article.
##Architecture
Before going into the details of the code generation I would like to explain quickly the architecture I decided to adopt. Below are the classes I want to generate using Codemodel. One interface and two implementations. The “Jso” (JavaScriptObject) implementation will extends the GWT JavascriptObject class. This is where we will code the JSNI methods to wrapp highcharts javascript calls.
The “Mock” is a pure Java implementation that can be used for Unit testing. No need for GWTTestCase, we will just need to inject the mock implementation instead of the JSO one in the context of a test. So that if our wrapper is used inside a presenter, you can still test your presenter in a pure Junit test.
##Codemodel
A good place to start for using codemodel would be on that blog where you will find various very good article to start. I use the following codemodel revision.
My point is not to rephrase what you will find in the blog mentionned before but more to answer this specific question : “how do I generate a native method ?”
##JSNI
This is what a JSNI method looks like
Codemodel is intented to generate Java code, there is no way codemodel will be able to generate the “/*-“ and the “-*/” or the content of the method which is pure Javascript. So I needed to find some hack to do it anyway.
I found out that in codemodel, I could use “throw” part to insert my native code. The only drawback is that all my native method have to throw a RuntimeException. This is acceptable as this is an unchecked exception. So I created a “hack” class to do it.
And this is how you can use it
This will give you