Sample Application Architecture
For my sample application design, I've followed a few patterns and employed
a simple architecture (see Figure 4). In an effort to simplify data access activities,
the dynamic data provider performs a JDBC call and the result set is stored in
an array. One thing missing here is a persistence mechanism for data updates. Ideally, a Service Data Objects (SDO) solution would keep the model simple
enough so it can be easily integrated with any persistence mechanism (for
example, Hibernate). For data access, I use a simple data provider interface to
standardize the data content used in this example and to ensure an
MVC-compliant architecture.

Figure 4. The sample application's architecture
In this example, I focus on the dynamic page and backing bean
(DynamicExample.java) to illustrate the power for dynamic generation (see
Figure 5). The backing bean obtains a provider for retrieving data from the
database and invokes the assistance of the dynamic generator class, Dynamic.java,
to perform its magic.

Figure 5. The dynamic page and backing bean
Not All Components Are Created Equal
When generating dynamic components, it's important to understand how the
components differ from each other, whether they require an event handler, and whether
validation or navigational issues have to be considered. Dynamic validation and
navigation can also be accomplished, but without the proper mapping and logic
to handle process flow, things can get out of control. To keep things simple,
I've omitted from this example any navigation components with the exception of
the tab panes (Grid, Field and Config), which are controlled through
JavaScript.
One of the more powerful features of using this approach is the assignment
of event handlers to components that generate events. This technique is used to
dynamically change event execution at runtime and separates the user interface
components from their event listeners. Also, with the increasing importance of service-oriented architectures
(SOAs), this approach makes it easier to employ service-oriented technologies with
the reuse of events or services (I will explore this option in a future
article).
The following snippet from Dynamic.java demonstrates how to create the
columns that make up the dynamic content:
private UIColumn createColumn(String headerTextValue, String bindingValue, int type, boolean immediate, String componentID, UIComponent parent)
{
UIColumn column = application.createComponent(UIColumn.COMPONENT_TYPE);
ValueBinding binding = null;
UIComponent componentHeader = JSFComponentBuilder.buildComponent(Constants.cComponentTypeOutput, headerTextValue, bindingValue, "", "0", false);
HtmlOutputText headerText = (HtmlOutputText)componentHeader;
headerText.setValue(headerTextValue);
HtmlOutputLinkEx outLink2 = app.createComponent(HtmlOutputLinkEx.COMPONENT_TYPE);
outLink2.setTitle(headerTextValue);
outLink2.setValue(headerTextValue);
headerText.getChildren().add(outLink2);
column.setHeader(headerText);
column.getChildren().add(JSFComponentBuilder.buildComponent(type, headerTextValue, bindingValue, componentID, "0", false));
return column;
}
The following snippet creates a button and assigns it a method-binding
argument:
private static UIComponent buildButton(String displayValue, String bindingValue, String idPrefix, String id)
{
HtmlCommandExButton button = app.createComponent(HtmlCommandExButton.COMPONENT_TYPE);
button.setId(idPrefix + displayValue + "_" + id);
button.setTitle(displayValue);
button.setValue(displayValue);
button.setStyleClass("commandExButton");
MethodBinding mbButton = app.createMethodBinding(bindingValue, null);
button.setAction(mbButton);
return button;
}
Page:
1
2
3