RichFaces component binding in JBoss Seam / JBoss Application Server environment

Sometimes we need to dynamically generate some part of the UI in a way that is difficult or impossible to achieve using the XHTML. In those cases, we can use the JSF binding feature to generate the JSF component on-the-fly using the Java code.

Also, RichFaces, being a standard JSF framework, gives the support for component binding.

Component binding, sometimes, is very useful to use complex logic to dynamically generate UI components in order to achieve some specific task. You can see it as the Swing GUI programming (as you know, JSF is also a component-based framework), but into the web context.

It's very important that you use the binding feature only if strictly necessary, as it makes the view depending on the application logic.

Moving all the libraries to the EAR

If you are packaging your project into an EAR structure, you might have some problem with the class loader.

In those cases (and if you have generated your project using seam-gen), just follow these simple steps:

  • Open the /deployed-jars-war.list file and copy all the content
  • Open the /deployed-jars-ear.list file and paste all the copied content
  • Delete the /deployed-jars-war.list file
  • Open the /build.xml file and delete the following code from the war file:
    <copy todir="${war.dir}/WEB-INF/lib">
    <fileset dir="${lib.dir}">
    <includesfile name="deployed-jars-war.list"/>
    <exclude name="jboss-seam-gen.jar"/>
    </fileset>
    </copy>
    
  • Create the /view/META-INF/ directory
  • Inside the directory just created, create a file called MANIFEST.MF and insert the code:
    Class-Path: lib/
    
  • Using ANT, call the following targets in order: unexploded, clean, explode

Now, all of your library files are in the lib directory of the EAR, and there will be no problem with the class loader while using the binding feature with RichFaces and Seam.

Tip

We decided to move all of the files to the EAR lib directory for simplicity, because it is difficult to manage the right dependences for every library.

A simple binding example

Now that our environment is ready, we can create a simple example.

A very important thing to keep in mind is that you cannot use Seam conversational components to contain binding properties, because they are updated during the Restore View phase that occurs before the restoring of the Seam conversation context. You can see it in the Seam life cycle diagram shown in the next figure:

A simple binding example

Another limitation of JSF component binding using the Seam framework is that you also can't inject conversational components inside EVENT scoped ones.

One solution you can adopt is to use the @Factory annotation (or, the @Out or @Unwrap annotations) to create a non-conversational component, which acts as a binding for the JSF object we need to customize.

The XHTML code for our example is very simple; let's add it to a file called /view/examples/binding/bindingExample.xhtml:

<!DOCTYPE composition PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:rich="http://richfaces.org/rich"
template="/layout/template.xhtml">
<ui:define name="body">
<rich:panel binding="#{myPanel}" />
</ui:define>
</ui:composition>

Also, let's create a bindingExample.page.xml file in the same directory to initiate the conversation:

<?xml version="1.0" encoding="UTF-8"?>
<page xmlns="http://jboss.com/products/seam/pages"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://jboss.com/products/seam/pages http://jboss.com/products/seam/pages-2.1.xsd"
login-required="true">
<begin-conversation join="true"/>
<rewrite pattern="/bindingExample"/>
</page>

The login is required as we are going to use GroupsListeHelper that needs a logged user.

The bean (book.richfaces.advcm.modules.main.examples.binding. BindingExampleHelper) contains just a method that creates the object we need in the EVENT scope:

package book.richfaces.advcm.modules.main.examples.binding;
@Name("bindingExampleHelper")
@Scope(ScopeType.CONVERSATION)
public class BindingExampleHelper {
@In(create = true)
GroupsListHelper groupsListHelper;
@Factory(value = "myPanel",
scope = ScopeType.EVENT,
autoCreate = true)
public UIPanel createPanel() {
FacesContext facesContext = FacesContext.getCurrentInstance();
// Setting up the new panel
UIPanel myPanel = new HtmlPanel();
myPanel.setId("myPanel");
myPanel.setHeader("Panel title");
// A simple text
HtmlOutputText txt = new HtmlOutputText();
txt.setValue("My panel text.<br/>");
txt.setEscape(false);
myPanel.getChildren().add(txt);
// Adding the groups names
for (ContactGroup group : groupsListHelper.getGroups()) {
// Ading the group name to the panel
txt = new HtmlOutputText();
txt.setValue(group.getName()+"<br/>");
txt.setEscape(false);
myPanel.getChildren().add(txt);
}
HtmlOutputText latestTxt = new HtmlOutputText();
component bindingexamplelatestTxt.setValue("Latest panel text.<br/>");
latestTxt.setEscape(false);
myPanel.getChildren().add(latestTxt);
// An Ajax link
UIAjaxCommandLink link = new HtmlAjaxCommandLink();
link.setValue("do something");
link.setAjaxSingle(true);
link.setReRender("myPanel");
link.setActionExpression(facesContext.getApplication(). getExpressionFactory().createMethodExpression(facesContext. getELContext(), "#{someBean.someAction}", Void.TYPE, new Class[0]));
// Adding the children (1 string and 1 link)
myPanel.getChildren().add(link);
return myPanel;
}
}

The myPanel object (its type is UIPanel) is created and put in EVENT scope by the factory method createPanel() it sets up the panel header and then creates some components (reading the groups list from the database) and adds them as children.

As you can notice, the "manager" Seam component (BindingExampleHelper) is conversational, but produces an EVENT scoped object.

The result of the code we have seen is as follows:

A simple binding example
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.227.52.7