You can find the full source code for this website in the Seam package in the directory /examples/wiki. It is licensed under the LGPL.
 
      
      
       
       This page describes an experimental, model-driven technique for constructing JSF views. The technique aims to reduce boilerplate and improve maintainablity for some normal
 seam-gen use-cases, and it doesn't require deep JSF knowledge. 
The core idea: Suppose we have a CRUD page that needs to display a property of a Java bean. In seam-gen, an FTL template includes logic which examines the property and prints out several lines of JSF. In this document's alternative approach, a runtime component (PropertyTemplateManager) searches for a template file that specifies how to display the property.
To see how this idea plays out, this document describes some key code snippets in an example app. The code-snippets require files from the property-templates-0.1.jar (in this directory).
(Aside: The original JavaBeans specification includes a mechanism for model-driven view construction. This seems similar. To my understanding, though, the JavaBeans spec is geared toward AWT/Swing applications. This mechanism is designed for JSF/Seam applications.)
First, a little glib CW: Code generators, like seam-gen, can help developers get going quickly, and they provide many spots where developers can replace the output with hand-crafted code. Unfortunately, code generators also produce large volumes of slightly-different code, and maintaining that code can suck. In particular, how do we handle systematic changes to code? Perhaps we re-run the generator (and lose our customizations), or we perhaps we get familiar with copy/paste.
Here are a few cases in which one may wish to make systematic changes to code produced by seam-gen:
click-to-editUI that applies to all inputs
mailtolink)
In all of these cases, I was tempted to copy-paste like a maniac, to edit the seam-gen templates, and/or to re-run seam-gen. I settled on an approach which simplifies the seam-gen templates, removes some logic from seam-gen, and handles the logic at runtime.
@Entity
public class Contact ... {
    @Email
    @Length(max=80)
    private contactEmail;
  
    @PhoneNumber
    @Length(max=16)
    private String cellPhone;
    ...
}
 
        Editpage with normal seam-gen
Given the above model, seam-gen would produce an edit page that looks a bit like this:
<!-- File: /ContactEdit.xhtml -->
...
        <rich:panel>
            <f:facet name="header">#{contactHome}.managed ? 'Edit' : 'Add'} Seminar</f:facet>
            <s:decorate id="emailDecoration" template="layout/edit.xhtml">
                <ui:define name="label">email</ui:define>
                <h:inputText id="email"
                           size="60"
                      maxlength="80"
                          value="#{contactHome}.instance.email}">
                    <a:support event="onblur" reRender="emailDecoration" bypassUpdates="true" ajaxSingle="true"/>
                </h:inputText>
            </s:decorate>
            <s:decorate id="cellPhoneDecoration" template="layout/edit.xhtml">
                <ui:define name="label">cellPhone</ui:define>
                <h:inputText id="cellPhone"
                           size="16"
                      maxlength="16"
                          value="#{contactHome}.instance.cellPhone}">
                    <a:support event="onblur" reRender="cellPhoneDecoration" bypassUpdates="true" ajaxSingle="true"/>
                </h:inputText>
            </s:decorate>
        </rich:panel>
...
 
        Editpage with property-templates
With property-templates, the code-generator doesn't make as many decisions about the markup produced for each property. Instead, that decision is delegated to the <dui:include> tag.
<!-- File: /SeminarEdit.xhtml -->
...
        <rich:panel>
            <f:facet name="header">#{contactHome}.managed ? 'Edit' : 'Add'} Contact</f:facet>
            <dui:bean beanClass="org.example.entity.Contact" bean="#{contactHome.instance}" viewType="edit">
              <dui:include id="emailDecoration" property="email" />
              <dui:include id="cellPhoneDecoration" property="cellPhone" />
            </dui:bean>
        </rich:panel>
...
 
        The <dui:include> tags are similar to <ui:include>, but the dui version is a little more dynamic -- it triggers a search (using the PropertyTemplateManager) to dynamically select a template file. For example, given property=email, the search will select the first available file from this list:
The search for cellPhone will choose the first available file from this list:
The first property-template will be a generic one that works for almost any property of any simple type (String, Boolean, double, etc). It relies on JSF/Seam to provide an appropriate converter:
<!-- File: /WEB-INF/property/java/lang/Object-edit.xhtml -->
<ui:composition>
        <s:decorate id="#{id}" template="/layout/edit.xhtml">
                <ui:define name="label">#{messages[property]}</ui:define>
                <h:inputText
                        value="#{bean[property]}"
                        required="#{requiredProperty == null ? false : requiredProperty}"
                        size="#{(size != null) ? size : 32}"
                        maxlength="#{(maxlength != null) ? maxlength : (size != null ? size : 32) }">
                        <a:support event="onblur" reRender="#{id}" bypassUpdates="true" ajaxSingle="true"/>
                </h:inputText>
        </s:decorate>
</ui:composition>
 
         This template resembles the seam-gen code, but it plugs in the parameters from <dui:bean> and <dui:include>. In particular, notice expressions like <s:decorate id=#{id}
> and <h:inputText value=#{bean[property]}
>. 
Of course, like the seam-gen code, this template is pretty generic -- it's designed to work with almost any property. It doesn't provide a very rich interface. We should provide specialized templates based on the type of information we're trying to edit. In the following example, we define a richer UI for @Email properties. The UI includes a mailto link.
<!-- File: /WEB-INF/property/com/example/annotations/Email-edit.xhtml -->
<ui:composition>
        <s:decorate id="#{id}" template="/layout/edit.xhtml" styleClass="emailProperty">
                <ui:define name="label">#{messages[property]}</ui:define>
                <h:inputText
                        value="#{bean[property]}"
                        styleClass="emailPropertyInput"
                        required="#{requiredProperty == null ? false : requiredProperty}"
                        size="#{(size != null) ? size : 32}"
                        maxlength="#{(maxlength != null) ? maxlength : (size != null ? size : 32) }">
                        <a:support event="onblur" reRender="#{id}" bypassUpdates="true" ajaxSingle="true"/>
                </h:inputText>
                <s:span rendered="${! empty bean[property]}">
                        [<a href="#" onclick="window.location = 'mailto:'+findCousinsByClassName(this,'emailProperty','emailPropertyInput')[0].value);return false;">Open</a>
                </s:span>
        </s:decorate>
 
         The second template resembles the first: both of them include an <s:decorate template=/layout/edit.xhtml
> tag. Both define a label. Both use the id parameter. It is very handy to ensure that all PT's that are designed for viewType=edit have these similar features. 
More generally, for viewType=edit, there is an implicit contract between the broader page (/ContactEdit.xhtml) and the property templates (/WEB-INF/property/foo-edit.xhtml). The broader page assumes that any template will include an <s:decorate> tag.
We can adapt the <dui:include> technique to other kinds of views -- such as display views and list views. Of course, the contract would be different. With list views, the broader page assumes that the template will include an <h:column> tag instead of an <s:decorate> tag.
The <dui:include> is useful for many properties, but it is not mandatory. You can easily mix-and-match property templates with hand-crafted code.
Sometimes, the view for one property may be connected to the view for another column, and we need a way to wire them together. In these cases, you might tweak the contract or rip-out the <dui:include>.
 The <dui:bean> and <dui:include> tag require you to explicitly define beanClass and property. There are some alternative formulations (such as <dui:include property=#{myHome.instance.foo}
>) which look nicer but are difficult or impossible to implement. There are a few limitations which lead to the current formulation: 
If you create a new .xhtml file, the file may not be used automatically. A Full Publish will fix this. (It seems like there should be a less drastic way, but I haven't found it.)
The templates don't currently have access to the annotation data, but this could be very useful:
XYZ> could be harmonized with @Length(max=XYZ).
The <dui:include> tag is basically re-entrant -- e.g. a <dui:include> tag may include a template which includes another <dui:include> tag. This functionality provides a natural way to handle JPA's @Embeddable feature. However, a developer must be conscientious about which parameters are passed to which tags: by default, parameters for the outer template will propagate to the inner template. This will not happen, however, if you ensure that the inner <dui:include> explicitly specifies all parameters required for its children. If you're aware of this, then you can easily avoid re-entrancy problems.
