This page last changed on Aug 27, 2006 by afabiani.
On of the most useful features of GeoServer, is a Web User Interface which allows users and administrators to play with configuration, data and most of the GeoServer modules stuff .
Actually, as an eredity of the GeoServer 1.3.x, the Web UI is one big monolitic web application, which has hardcoded the code to interact with each GeoServer module. Such kind of interface is not coeherent with a modular architecture, where each module has to be considered most like a GeoServer plugin which a user can enable or disable by simply respectively add or remove a JAR library.
What we would like to have is a Web UI modular as well, which, for each GeoServer module, has every piece located inside the module JAR itself. In this way, adding/removing a new module will automatically enable/disable the module related UI, and the overall Web application shouldn't know anything about modules, i.e. new modules can be added without modifying the main Web application.
Another important thing on UI modularization, is that this will alow us to think about interfaces for remote access, like JMX.
State of the Art
At this time the Web UI is built over a Struts based architecture. The pages are built on a template which uses Tiles to render the menu, status and navigation bar etc...
The actual architecture, as said before, is monolitic, i.e. the web application must know about the existence of each module, and directly uses modules interfaces to access theyr data and functions. Moreover, the UI is obtained by compiling and rendering JSP pages, and in most of the cases, some code is inserted directly inside the JSP page along with HTML.
With the introduction of Spring framework on GeoServer 1.4.x, thanks to the Inversion of Control and Dependency Injection, the main module beans could be splitted and distributed separately with the JARs.
Objectives and Results
At this point the question is: what is the better solution for a fully modular and dinamic Web UI for GeoServer modules? We made some researces in order to answer this question...
The first step was to try finding a solution to reuse the actual technology and web architecture in order to avoid to completely rewrite the web pages. Our field of investigation the was Spring+Struts architecture.
First of all, what we had to do is to find a way to split the Struts configuration files.
This file contains the definitions of the form and action beans. Every Struts action is defined here and needs a form bean to pass informations to the next page/action.
The first thing to do is to have a struts-config xml file for every module, each one defining the forms and actions used by the module itslef. Moreover those files have to be read directly from the JAR.
The place where to say the Struts sevlet tha path of configuration files is located into the web.xml file. The problem is that the standard Struts action servlet is not able to read and merge config files from classpath JARs. So we had to write a new class which extends the previous and is able to do what we need.
The second issue is the definition of the page layouts.
In the old GeoServer web UI this was done by defining a template JSP page and using the Struts tile tags, which allow a user to include JSPs inside a main page specifing specific HTML tags, which are interpreted by a Struts plugin. Again, the default TilesPlugin has no knowledge on how to find the tiles-defs xml files into the classpath. We created once again an extension of the DefaultTilesDefinitionFactory which is capable to retrieve the information from the JARs and merge them together in order to have a unique, dinamically built, tiles-defs configuration file.
The last thing to do was to find a way the tell the Struts include tag how to find and compile a JSP page which is located inside a classpath JAR.
After a deep analysis, the conclusion was to completely re-think the architecture of the UI. The reasons for this choice are the following:
a) in order to include a JSP page which is located into the classpath, we need to override the include method of the RequestDispatcher to let it get the stream of the JSP source, compile it and write the results to the HTML output.
b) for the reason (a), a better solution to do this would be to completely modify the JSP engine to let it reading the source from a static stream, e.g. an XML file, and producing HTML output in some way, e.g. by applying XSL template.
Well ... those reasons are enough to say that is stupid to reinvent the wheel. A lot of web frameworks alredy let the designer use static contents to render the dinamic pages. We just need to find the best one which interacts with Spring and allows us to find a good solution to split the web UI.
An experiment was made using Wicket, and it was sucessfull.
The Wicket concept is to write Java classes to add components to the page and associate them a Markup, i.e. a static HTML pages which contain tags to say where to put the output of those components.
The really amazing thing is that all the wicket components can be located anywhere into the classpath, and that can be perfectly integrated with Spring.