One of the projects CROZ is currently participating in is dedicated to the production of Rich Client Application. Eclipse Rich Client Platform (Eclipse RCP) has been chosen as a platform for the production of client, whose main characteristic is that it enables XML configuration of user interface. The platform automatically manages various visual elements such as menus, toolbars, view or editor frames etc. User of the platform (or rather developer of the application) should concern himself with only the key business certain element is performing – for instance, about the action which should perform when selected from the menu or about the content of the view frame. The platform takes care of the rest – for instance, concerning the frame, its positioning and size, opening/closing, minimum/maximum, docking, stacking and so forth. That speeds up the development considerably and it is a lot easier to maintain the consistent look&feel of the application. In XML configuration of user interface it is customary to name the class which attends to a particular visual element. Your typical configuration element example:
<extension point="org.eclipse.ui.views"> <view id="net.croz.coolView" position="left"/> </extension>
The basic work mode shows that the platform is controlling class instantiation and instance configuration, therefore the user has the command, via XML configuration, over only those class aspects which emerge form its role of visual element controlled by Eclipse RCP. For instance, it is characteristic that the class for the view frame will have dependencies on some sources of data which needs to be visualized. For all such things the class author is left his own devices. On the other hand, CROZ already has the tradition of exploiting Spring’s IoC object configuration, thus it is only natural that there should be a need for a solution which will enable control of the instantiation and object configuration to be moved from the Eclipse RCP to Spring’s IoC container. Fortunately, Eclipse RCP practices Factory Object approach – if there is a class name in the XML which implements the appropriate Factory interface, RCP will instantiate that class and then let that instance create the final object which controls the visual element.
Another important characteristic of the platform Eclipse RCP is that it enables modularity of application above the level offered by Java language itself. In fact, precisely that modularity is the main motivation for the adoption of XLM configuration. Basic approach is as follows: RCP itself is made of a module set (Eclipse term for “module” is “plugin” which we will use hereafter) of which for example, one is intended for managing visual elements. He declares extension points for each element category, for instance, the views point for view frames. Plugin developed by a platform user defines its extension for that point by stating its class name and other criterions concerning frame display in XML configuration. By the very addition of his plugin to the plugin set which compiles the application we can accomplish that it contributes its visual elements to the application without having to write the control code in Java.
The requirement for modularity of application is reflected on Spring configuration as well. It is obvious that one cannot build the entire application context in a centralized manner because that would mean how a certain “main” plugin should know beforehand about all the other plugins and about the configuration of their respective objects. Thus, each plugin should have its own context but it is preferable to be able to connect that context to some common, universally defined context which would contain objects of greater significance for the entire application.
We found an open-source project on the web [1] (we shall name it ESpring) which enables answering of these questions in a rather sophisticated style. The project in question was in a relatively rudimental state and was more of a proof-of-concept than a finalized product so we needed to finish it and de-bug it a great deal, however the key ideas remained untouched.
The project is composed of a single plugin which declares its extension point. Application plugins join their extensions to this point in order to contribute their application context to the central context register. The context is inscribed in the register under an ID defined in the extension. When producing its application context plugin can by ID ask ESpring for an arbitrary second application context to be used as its parent. Example of extension definition for ESpring:
<extension point="net.croz.espring.appContextContributors"> <appContextContributor id="coolPluginContext" parent="rootContext" /> </extension>
All registered contexts are available anywhere in the Eclipse configuration database plugin.xml, where one customarily states the class name of the visual element. Instead of the class name of the desired object, we state the particular class name of the ESpring plugin, which in turn implements Factory interface and will deliver the object configured in the application context to the platform:
<extension point="org.eclipse.ui.views"> <view id="net.croz.coolView" position="left"/> </extension>
Now comes in another important ability of Eclipse RCP without which this approach could not have become a reality: after the name of Factory-class we can add a colon and a string behind it which will be forwarded to the instance of that class. In this way we can transmit key data necessary for Factory to locate the appropriate application context and the object within it.
With a careful analysis of the described solution’s architecture one could complain that the creation of the application context has been unnecessarily complicated: it not enough to state just the location of configuration database but one needs to create ApplicationContextContributor class which does the creation of the application context itself. The reason for that is the above mentioned modularity of RCP plugins “above the level offered by Java language itself”: namely, one plugin can see only those classes of the other plugin which it explicitly declared to be “public”. Therefore it is necessary that the creation of application context be done by the class of the client plugin.
[1] Neil Bartlett, project „Eclipse RCP Spring Support“, http://sourceforge.net/projects/eclipse-spring
Related News