Sunday, May 20, 2012

Wicket 1.5 + Spring Framework + Hibernate + jDTO Binder Sample Application

In this post I'll go through a sample project I've created to demonstrate jDTO Binder in action with some of the most popular frameworks on the Java world. The sample project is publicly available on GitHub.

To get the project running without too much fuss, then just checkout the project, open it on netbeans 7.1.2 and hit run :)

If you're on linux or mac os X then you can do something like this:

$ git clone git://github.com/jDTOBinder/jdto-sample-projects.git
$ cd jdto-sample-projects/jdto-wicket-demo/
$ mvn clean tomcat:run

After that you may point your browser to http://localhost:8080/jdto-wicket-demo/ and that's it, you should see something like this:


The CSS3 Highlights:

The styling is pretty standard styling what can be kind of uncommon is the menu box which is rotated and it has a little shadow, also some google web fonts are being used, let's go with the easiest first, the shadow:

box-shadow: 6px 6px 5px #888;

The parameters mean in order, the horizontal distance, the vertical distance the blur distance and the shadow color.

Also you can see that the box is kind of rotated let's say 8 degrees to the left? Normally that would have been defined by using the transform property, but it seems that is still not that supported in all browsers, so I have added three rules to support webkit, mozilla and internet explorer 9:

-webkit-transform:rotate(-8deg);
-moz-transform:rotate(-8deg);
-ms-transform: rotate(-8deg);

Finally, to include some web fonts, some import statements must be added:

/* import the google web font  */
@import url(http://fonts.googleapis.com/css?family=Averia+Libre:700);
@import url(http://fonts.googleapis.com/css?family=Oxygen);

That enabled me to use the "Averia Libre" and "Oxygen" fonts on my styles.

The Wicket Highlights

Apache Wicket is a really nice web framework that you can use to build everything in Java, from websites to web applications, there are some things that may be uncommon for some developers, I've used the wicket:link tag to include css resources packaged on the classpath:

<head>
    <title>jDTO Binder Pizza Orders!</title>
    <wicket:link>
        <link rel="stylesheet" type="text/css" href="jdtopizzas.css" />
    </wicket:link>
</head>

Normally one would have had that css resource included on the java code but this wicket magic makes it more intuitive and consistent.

Another use of the tag is to link between pages, as I show in the following example:

<p>Take a look at the <wicket:link><a href="ViewOrdersPage.html">orders you have already created</a></wicket:link>.</p>

In this case, I have a ViewOrdersPage.java file and by creating the link this way, wicket takes care of pointing the href to the right place without adding extra Java code.

DTOs as the Wicket Models

Wicket extensively uses "intermediate" objects to act as the model of it components this is where DTOs come in handy, since you can modify the data they carry without affecting the data on the database, they are perfect for using them as the components model. The following code shows how you bind a wicket form with the "form" that takes the service to create a new pizza order:

PizzaOrderForm form = new PizzaOrderForm();
form.setPizzas(new ArrayList<PizzaDTO>());

//create the order form.
orderForm = new Form<PizzaOrderForm>(
        "orderForm",
        new CompoundPropertyModel<PizzaOrderForm>(form));

//for the case you want to add pizzas and you have already filled the form elements.
//this is only necessary because I left out the menu list from the form.
orderForm.add(new TextField("customerName").add(new BlurAjaxFormSubmitBehavior()));
orderForm.add(new TextField("customerPhone").add(new BlurAjaxFormSubmitBehavior()));
orderForm.add(new TextField("customerAddress").add(new BlurAjaxFormSubmitBehavior()));

With the use of CompoundPropertyModel things are really easy. I've added a behavior that submits the form data every time the field losses focus, this prevents unwanted data erasing on the client side. (Also I could have designed my page a little better hehe).

Spring and Hibernate Highlights

As this is a sample application but is intended to show real-life stuff, it uses spring framework and hibernate, but if you had to install and configure a database server to test the application, you probably wouldn't test it, so here is how I've used the H2 embedded database engine to use just your computers memory a little bit more:

<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
    <property name="driverClassName" value="org.h2.Driver"/>
    <property name="url" value="jdbc:h2:mem:pizza"/>
</bean>

As you can see, the database connection pool has the url "jdbc:h2:mem:pizza" and that is all what it takes to tell H2 that you don't want to persist anything.

Finally, I've used a singleton bean to load the sample data when the application starts, this bean loads the list of available products.

<!-- initial data loader bean -->
<bean id="initialDataLoader" class="org.jdto.demo.InitialDataLoader" />

class InitialDataLoader {
    
    private static final Logger logger = LoggerFactory.getLogger(InitialDataLoader.class);
    
    @Autowired
    private HibernateTemplate template;
    
    @PostConstruct
    @Transactional(propagation= Propagation.REQUIRES_NEW)
    private void init() {
        createPizzas();
    }

    private void createPizzas() {
        logger.info("Creating initial set of pizzas!");
        
        Pizza pepperoni = new Pizza("Pepperoni Pizza", 4, 8.50);
        Pizza mozzarella = new Pizza("Mozzarella Pizza", 3, 7.50);
        Pizza special = new Pizza("Special Ham Pizza", 5, 10.0);
        Pizza onion = new Pizza("Onion Pizza", 4, 9.0);
        Pizza anchovy = new Pizza("Anchovy Pizza", 2, 7.95);
        
        template.save(pepperoni);
        template.save(mozzarella);
        template.save(special);
        template.save(onion);
        template.save(anchovy);
    }
}

One of the beauties of Spring is that you can use package-scoped classes as beans so you don't expose them to the team developers (and they don't feel tempted to use them).

Since this bean will be executed on startup time we will need a brand new transaction, so I've set the propagation attribute to "requires new".

jDTO Binder Highlights

In this application, jDTO Binder takes care of copying data between domain objects and DTO objects, how it's being used is described on the project's README file.


That would be all for now, please feel free to make comments on the post and I hope you find it useful for starting a new project with this great technologies.