czwartek, 14 sierpnia 2008

Wicket and Spring

Sometime ago I was evaluating Wicket usefulness in development of lightweight, AJAX enabled UIs for web applications. Apache Wicket is modern framework for creating web UIs, well known for its original features as HTML/Java pages implementing separation between page view and logic. Other unique feature is global Application object, usually containing business logic entry points.


Wide range of modern applications requires complex, multi-tier backend (logic and storage, possibly remote, wired together with Web Services) and quite simple frontend (with few user actions available). Server part of the backend, along with WS clients is typically developed with Spring. As far as frontend is concerned, Wicket could be the solution to use.


There are many great Wicket manuals and tutorials, so I won't post any Wicket code here. Those interested can just take a look at Wicket Examples :) Other aspect is Wicket-Spring integration. After some research I decided to go with "central point" solution. This integration type assumes that all logic entry points (usually managers and DAOs) should be injected into Application object. Therefore all Pages have convenient access to the logic. This is compromise between annotations (performing all work under cover, without developer knowledge) and using no dependency injection at all. Because Application object is global (and singleton) it reminds somewhat hated Resource Locator solution, but for the sake of simplicity (remember, be agile..) I can accept it.


Required web.xml configuration is as follows:

<listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

<filter>
<filter-name>wicket.wicket-demo</filter-name>
<filter-class>org.apache.wicket.protocol.http.WicketFilter</filter-class>
<init-param>
<param-name>applicationFactoryClassName</param-name>
<param-value>
org.apache.wicket.spring.SpringWebApplicationFactory
</param-value>
</init-param>
</filter>

With above entries in webapp config, developer is able to inject logic beans to the Applciation object without problems, as in following example:

<bean id="mrDaoBean"
class="apps.WicketMountains.data.MountainRecordDao">
<property name="sessionFactory">
<ref bean="sessionFactoryBean"/>
</property>
</bean>
<bean id="mrManagerBean"
class="apps.WicketMountains.data.MountainRecordManager">
<property name="mrDao" ref="mrDaoBean"/>
</bean>

<!-- setup wicket application -->
<bean id="wicketApplication"
class="apps.WicketMountains.WicketApplication">
<property name="mrManager" ref="mrManagerBean"/>
</bean>

Wicket components can access logic beans using code similar to call:

((WicketApplication)Application.get()).getMountainRecordManager()

One nice feature of the Wicket framework is bunch of ready to use AJAX components with exhaustive description of use. Beginner in Wicket (as myself) is able to develop first useful, pretty, AJAX enabled webapp in few hours only.

czwartek, 7 sierpnia 2008

HSQL: follow-up

It appears that sometimes one would like to use lightweight HSQL for unit / integration testing of his (hers) Spring-aware application. Nothing simpler ;-)
First thing is preparing Spring bean able to manage lifecycle of an instance of the HSQL database. This could be written by hand, but fortunately convenient class is already available in the Springmodules project. Bean implementation is to be found here.
Second thing is Spring XML configuration of the bean. My sample code is as follows:

<bean id="dataSource"
class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close">
<property name="driverClassName"
value="org.hsqldb.jdbcDriver"/>
<property name="url"
value="jdbc:hsqldb:hsql://localhost/test"/>
<property name="username" value="sa"/>
<property name="password" value=""/>
<property name="defaultAutoCommit" value="true"/>
</bean>

<bean id="dataBase"
class="springmodules.HsqlServerBean"
singleton="true" lazy-init="false">
<property name="dataSource">
<ref bean="dataSource"/>
</property>
<property name="serverProperties">
<props>
<prop key="server.port">9001</prop>
<prop key="server.database.0">
file:webapps/SampleApp/db/test</prop>
<prop key="server.dbname.0">test</prop>
</props>
</property>
</bean>

Configuration is pretty straight-forward. Note that we're using DataSource referring to the database configuration. This is done because:
a) Spring bean requires DataSource to commence db shutdown when container goes down
b) helps encapsulating database properties in one entity
The latter can be used more when Hibernate is also in the game. SessionFactory can be configured to use the DataSource with such code as:

<bean id="sessionFactoryBean" class=
"org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="configLocation"
value="classpath:hibernate.cfg.xml"/>
<property name="dataSource" >
<ref bean="dataSource"/>
</property>
</bean>


Have fun!