Platinum Partner
java,ajax,seam,ejb 3.0

Integrating Direct Ajax into the Enterprise Environment

I'd like to introduce an Ajax framework which combines the ease of Direct Ajax with the benefit of the J2EE container, using JBoss SEAM. I've found the most appropriate name:

Distributed Ajax Application Model

 

Motivation

Developing enterprise applications with a web-based user interface is not at all a trivial task, as everyone knows. If we tend to use standard Java solutions, our best choice might be Facelets with JBoss SEAM, however if we develop an enterprise application rather than a dynamic web page, we won't be quite satisfied. Or at least I was not. So I turned to the ITMill framework, which I knew earlier. This framework allows us to develop our user interface code totally Swing-like, and the framework is responsible of handling all HTML and HTTP related stuff. This solution evolved to what we nowadays call Direct Ajax. But I was still not satisfied, for I lost the ease of enterprise development SEAM gave me with Faces.

The idea

So I wanted to have injected EJB dependencies and a JPA session in my server-side user interface code. Normally Swing-like user interface code is not split into container managed beans, but that's actually far from impossible. Applications can usually be split into several functional groups which have little communication with each other, so why not put these into Seam components?

The solution

Decomposing a windowed application is done by introducing two special elements to the user interface model. A special type of Panel is used to be the actual SEAM component. This ContainerComponent is responsible of handling the rendering and event dispatching of the Controls it contains. On the other side a remote ContainerComponent can be added to a Control tree by a reference to that component. The ContainerComponentRef object is responsible of invoking the remote render method. These components do not access the Controls of each other.

To dispatch the events coming from the client-side user interface component, we need to know which component contains the server-side instance of the Control. To be able to do this, we use a composite Id of Controls which has the JNDI name of the container component and a number which is unique in itself for the application. The lifecycle of the components is handled by SEAM and the EJB container.

Direct Ajax is implemented mostly as seen in the ITMill framework. The client side UI code is written in GWT, so the framework can be extended with custom components quite easily. Finally, a simple servlet does the trick to initiate SEAM on each request, just as SeamListener does in Faces.

Some code

So what does it look like? Let's see a simple container:

@Stateful
@Local(ContainerComponent.class)
@Scope(ScopeType.SESSION)
@Name("productsPanel")
@AutoCreate
public class ProductsPanel extends AbstractContainerComponent {

Label title = new Label("Products");

Table productTable = new Table();

@PersistenceContext
EntityManager em;

@PostConstruct
public void init() {
addControl(title);
title.setStyleClass("h1");
productTable.setHeaders(Arrays.asList(
new String [] { "Id", "Name", "Price", "-", "-" }));
addControl(productTable);
}
}


And a listener might look like this:

        @Override
public void buttonClicked(ButtonBase button) {
product.setName(nameField.getText());
em.merge(product);
}

Current state

The framework currently is quite minimal. I'm going to go on extending it into a really useful UI framework, but I'd like to rely on community feedback and support. An example application project is available at http://hhc.intro.hu/daam/: it can be built to run on JBoss. The whole project will be available as soon as I get my sourceforge project approval and finish some documentation.

Finally, I wish you all a happy new year! :)

 

{{ tag }}, {{tag}},

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}
{{ parent.authors[0].realName || parent.author}}

{{ parent.authors[0].tagline || parent.tagline }}

{{ parent.views }} ViewsClicks
Tweet

{{parent.nComments}}