mercredi 18 août 2010

Gestion des skins et ClientBundle

With GWT 2.0 ClientBundle appeared. This mechanism is very interesting because it optimize the loading time of a web application resources, such as CSS files, images files, and many others.
This mechanism also allows typing of CSS using Java interfaces to access styles; The compiler verifies the existence of CSS classes used.
To do this, simply declare an interface that inherits CssResource and define methods corresponding to names of CSS classes.
To inject the CSS in the HTML page is then necessary to generate an instance of the CSS resource through : GWT.create (MyCSSResource.class). Then call the method "ensureInjected ()" on this instance.

This mechanism works very well, now let us see how to manage skin with this mechanism.

The idea is to change style sheet dynamically. The HTML page elements remain unchanged and refer to the same CSS classes.

For this, we can use the inheritance mechanism between interfaces CssRessources to structure CSS skins. To have identical CSS class names, do not forget to add the annotation @Shared on parent interface.

To inject the selected CSS skin, do not use the method "ensureInjected ()" because it controls the injection of resources and CSS will injected only once. Should be used instead : StyleInjector.inject (cssStyle.getText ())

But not to overload the page, we must removing the contents of the previous CSS, stored in the header of the page.

Here an example of code :


To make dynamic discovery of skins, we can use a generator (see previous article).

Stay tuned

lundi 16 août 2010

GWT and reflexion API

As you probably know, GWT does not emulate the reflection API of Java. It is a conscious choice by Google, which is motivated by the performance degradation induced by the introduction of mechanisms for reflection (not mentioned the lack of control of code).
However, it is sometimes useful to use the reflection API. Recently, I was confronted with the establishment of a GWT application that handles plugins. These plugins must be discovered dynamically. In Java you would use a scan packages with the reflection API or with Spring IOC. But in my case it is not possible because there are plugins that are client side, so that must comply with the constraints of GWT.

So how can i do that ?

To overcome this problem, the GWT team has developed the mechanism called "deffered binding" that allows to perform operations before the compilation of Java code in Javascript.
For my problem, I used a Generator. The generator, as its name suggests will allow to dynamically generate Java code before compiling for a given type.


What is interesting is that at this stage, it is possible to use any Java API that is desired because the generator is running in a JVM.
We can therefore use the reflection API. Furthermore, the scanning of packages is possible because the classes corresponding to the project source code is loaded into the classloader.
Once obtained the list of plugins (a plugin implements an interface call "Plugin"), it must generate a list of plugin object with an object through PluginFactory generator.



On this occasion, I also discovered a very nice API to list the packages in the ClassPath: classpath-explorer

So here we are an elegant technique to develop a plugin mechanism with GWT. The only drawback to this method is that for the addition of a plugin, it is necessary to recompile the project, which is not needed with Java plugins (like Eclipse plugins).