Friday, June 29, 2012

Suppose you have a page project.xhtml. If the request is project.xhtml?project=myproject, you retrieve the 'myproject' Project instance and let user to modify it. If the request is request.xhtml with no query parameter, you instantiate a new Project object and let user edit and add it. How can you do this in J2EE platform?

I used to do this using a PhaseListener. The PhaseListener will inspect the request parameter and create the bean directly or using BeanManager from CDI. However, producer method in CDI provides a good alternative.

Suppose I have a utility object Util which is in application-scoped singleton. In traditional programming model, this object is constructed at application startup using its constructor. At any code location(bean or not bean), I can hold a reference through a static member like this Util.instance.

public class Util

{

public static Util instance;

@Inject Field f1;

...

}

In CDI, reference to Util has to be injected. To be injected, your code location should be a CDI bean. You can not use Util constructor directly since some of its fields such as f1 need injecting from CDI. Its creation needs to be controlled by CDI. You can of course using BeanManager from CDI to look up the singleton instance.

In this example, I have an application-scoped object GlobalObjectFactory which is created at the very beginning of application startup by CDI. Since it is created by CDI, you can ask CDI to inject other bean. Once you have a reference to the injected bean, you can pass the reference to a static member of other class. After this, the reference to the injected bean can be accessed through static member anywhere, bean or non-bean.

Sunday, June 24, 2012

Traditional test approach in J2EE 6 is tough. In J2EE 6, we have bean injection. The Bean by design is created by framework and not by tester. Given the resource injection and persistence, a test setup can be difficulty and easy to break. At least, I tried two days with embedded EJBContainer and did not succeed. Finally, I got this absolutely wonderful test framework for J2EE: Jboss arquillian. Before you tweak anything, you have to check this out.

In my last blog, I showed a method how dynamically add a client row/list entry at client side when JSF is used. I used Richfaces a4j:region and a4j:jsFunction. However, I do not want to use richfaces for two reasons. First, richfaces loads all its component js files although I only uses two simple tags. Second, richfaces loads its stylesheet file I have no easy way to turn it off completely.

Here I use code block for the onclick attribute of commandButton. This code will be called before the generated ajax flow from f:ajax. The generated ajax will not be called since the onclick code block always return false. In the onclick code block, I use jsf.ajax.request to make explicit ajax call if no buffer is available. JSF server does not distinguish whether the ajax call comes from manual javascript or the one generated. We still need the f:ajax tag so listener action can be invoked in server side.

You have a list or a table. You want to add more items to the collection at client side. When user clicks a 'Add' button, a new row or list entry is available for user to enter new data. The list entry or row can be generated by manipulate DOM using JavaScript. However, the newly-added form elements in the row or list entry will be ignored by JSF server code since these elements are not in the JSF component tree.

Here I give a practical solution to this. The idea is like this: I have a real list and buffer list. The real list is visible at UI and the buffer list is hidden. When user clicks 'Add', an list entry from buffer list is displayed using JavaScript.
When the form is submitted, the real list and buffer list is combined.
If user repeatedly clicks 'Add' and buffer exhausts, Ajax call is made to server to reallocate buffer. If the buffer is reasonable large enough, there will not be any Ajax call in most time.

NOTE

In JavaScript, I use live instead of click since the button is dynamically removed and added by JSF ajax call.

I use a4j and h:commandButton instead of f:ajax inside of h:commandButton. A f:ajax will add onclick attribute to the generated button. The onclick javascript invokes JSF ajax call. Any other event listeners added later using javascript will be invoked after this. Right now, we have no way to invoke an event handler before the f:ajax client behaviour. So I separate them into two components to control the invocation flow as desired.

a4j:region and a4j:jsFunction is from Jboss richfaces library .

JSF has a very nice support for ajax. You can specify ajax behavior using f:ajax tag with any input or command components. However, rendered attribute gives you surprise sometime.
Suppose you have a component in xhtml like this

<h:datatable ... rendered="#{empty configs}">

</h:datatable>

In you ajax tag, you'd like to refer to this table in render attribute. Since your table could never be rendered, and not in the component tree, client code and server code will not be able to update it in ajax call. You could use OutputPanel from richfaces library. However, there is a much simple soltuion: render your component in all time. Replace the rendered="false" case with something like style="display:none".
E.g: