Sunday, March 30, 2014

Set up JSF environment for JUnit tests

JUnit tests often need mocked JSF / Servlet objects when you test JSF based web applications. Such objects can be FacesContext, ExternalContext, ApplicationContext, HttpRequest, HttpSession, etc. I already mentioned the MyFaces Test Framework in one of my outdated post. In this post, I would like to introduce a new simple and lightweight approach based on JUnit TestRule. The concept behind TestRule is similar to custom JUnit runners, but without restrictions (you can not use multiple runners, but you can use multiple TestRules). Let's go step by step to explain the idea. A class which implements the interface TestRule must implement the method
Statement apply(Statement base, Description description)
The first Statement parameter is a specific object which reprensents the method under the test from your test class. Such a test method can be invoked by base.evaluate(). You can place any custom code before and after the call base.evaluate(). A typically implementation follows this pattern
public Statement apply(final Statement base, Description description) {
    return new Statement() {
        @Override
        public void evaluate() throws Throwable {
            // do something before invoking the method to be tested
            ...
            try {
                base.evaluate();
            } finally {
                // do something after invoking the method to be tested
                ...
            }
        }
    };
}
In short words: the apply method allows to intercept the base call of every test method and put a custom code around. Your TestRule implementation, say MyRule, can be used in any test class with the @Rule annotation as follows:
@Rule
public TestRule myRule = new MyRule();
Note: The member variable should be public. Let's take more examples. There is a good introduction in this tutorial. The author demonstrates how to implement two TestRules: one for SpringContext to use @Autowired in test classes and one for Mockito to populate the mocks before each test. An excellent example! I allow me to repeat the usage example.
public class FooTest {

    @Rule
    public TestRule contextRule = new SpringContextRule(new String[]{"testContext.xml"}, this);

    @Rule
    public TestRule mockRule = new MockRule(this);

    @Autowired
    public String bar;

    @Mock
    public List baz;

    @Test
    public void testBar() throws Exception {
        assertEquals("bar", bar);
    }

    @Test
    public void testBaz() throws Exception {
        when(baz.size()).thenReturn(2);
        assertEquals(2, baz.size());
    }
}
This can not be achieved with two JUnit runners at once. E.g. you can not annotate a test class at the same time with @RunWith(Parameterized.class) and @RunWith(SpringJUnit4ClassRunner.class) or @RunWith(MockitoJUnitRunner.class).

But back to JSF. I want to show how to implement a TestRule for a simple and extensible JSF environment. First of all, we need a mock for FacesContext. We will implement it with Mockito - the most popular Java test framework. I have seen many different implementations, but in fact it is not difficult to implement a proper mock of FacesContext.
import javax.faces.context.FacesContext;

import org.mockito.Mockito;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;

public abstract class FacesContextMocker extends FacesContext {

    private FacesContextMocker() {
    }

    private static final Release RELEASE = new Release();

    private static class Release implements Answer<Void> {
        @Override
        public Void answer(InvocationOnMock invocation) throws Throwable {
            setCurrentInstance(null);
            return null;
        }
    }

    public static FacesContext mockFacesContext() {
        FacesContext context = Mockito.mock(FacesContext.class);
        setCurrentInstance(context);
        Mockito.doAnswer(RELEASE).when(context).release();
        return context;
    }
}
For all PrimeFaces fan we will provide a similar mock for RequestContext.
import org.primefaces.context.RequestContext;

import org.mockito.Mockito;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;

public abstract class RequestContextMocker extends RequestContext {

    private RequestContextMocker() {
    }

    private static final Release RELEASE = new Release();

    private static class Release implements Answer<Void> {
        @Override
        public Void answer(InvocationOnMock invocation) throws Throwable {
            setCurrentInstance(null);
            return null;
        }
    }

    public static RequestContext mockRequestContext() {
        RequestContext context = Mockito.mock(RequestContext.class);
        setCurrentInstance(context);
        Mockito.doAnswer(RELEASE).when(context).release();
        return context;
    }
}
Now, a minimal JSF / Servlet environment could be set up as follows
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import javax.faces.application.Application;
import javax.faces.component.UIViewRoot;
import javax.faces.context.ExternalContext;
import javax.faces.context.FacesContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.mockito.Mockito;
import org.primefaces.context.RequestContext;

import org.junit.rules.TestRule;
import org.junit.runner.Description;
import org.junit.runners.model.Statement;

public class JsfMock implements TestRule {

    public FacesContext mockFacesContext;
    public RequestContext mockRequestContext;
    public UIViewRoot mockViewRoot;
    public Application mockApplication;
    public ExternalContext mockExternalContext;
    public HttpSession mockHttpSession;
    public HttpServletRequest mockHttpServletRequest;
    public HttpServletResponse mockHttpServletResponse;

    @Override
    public Statement apply(final Statement base, final Description description) {
        return new Statement() {
            @Override
            public void evaluate() throws Throwable {
                init();
                try {
                    base.evaluate();
                } finally {
                    mockFacesContext.release();
                    mockRequestContext.release();
                }
            }
        };
    }

    protected void init() {
        mockFacesContext = FacesContextMocker.mockFacesContext();
        mockRequestContext = RequestContextMocker.mockRequestContext();
        mockApplication = Mockito.mock(Application.class);
        mockViewRoot = Mockito.mock(UIViewRoot.class);
        mockExternalContext = Mockito.mock(ExternalContext.class);
        mockHttpServletRequest = Mockito.mock(HttpServletRequest.class);
        mockHttpServletResponse = Mockito.mock(HttpServletResponse.class);
        mockHttpSession = Mockito.mock(HttpSession.class);

        Mockito.when(mockFacesContext.getApplication()).thenReturn(mockApplication);
        Mockito.when(mockApplication.getSupportedLocales()).thenReturn(createLocales().iterator());

        Mockito.when(mockFacesContext.getViewRoot()).thenReturn(mockViewRoot);
        Mockito.when(mockViewRoot.getLocale()).thenReturn(new Locale("en"));

        Mockito.when(mockFacesContext.getExternalContext()).thenReturn(mockExternalContext);
        Mockito.when(mockExternalContext.getRequest()).thenReturn(mockHttpServletRequest);
        Mockito.when(mockHttpServletRequest.getSession()).thenReturn(mockHttpSession);

        Map<String, String> requestMap = new HashMap<String, String>();
        Mockito.when(mockExternalContext.getRequestParameterMap()).thenReturn(requestMap);        
    }

    private List<Locale> createLocales() {
        ArrayList<Locale> locales = new ArrayList<>();
        locales.add(new Locale("en"));
        locales.add(new Locale("de"));
        ...
        return locales;
    }
}
We mocked the most used JSF / Servlet objects, linked them with each other and provided mocks via public member variables, so that they can be extended in test classes if needed. Below is an usage example which also demonstrates how to extend the mocked objects for a particular test.
public class PaymentRequestFormTest {

    private PaymentView paymentView;

    @Rule
    public JsfMock jsfMock = new JsfMock();

    @Before
    public void initialize() {
        paymentView = mock(PaymentView.class);
        ...
    }

    @Test
    public void toJson() {
        // Mock URL and context path
        StringBuffer requestURI = new StringBuffer("http://localhost:8080/webshop");
        Mockito.when(jsfMock.mockHttpServletRequest.getRequestURL()).thenReturn(requestURI);
        Mockito.when(jsfMock.mockHttpServletRequest.getContextPath()).thenReturn("/webshop");

        // Invoke toJson method
        String json = PaymentRequestForm.toJson(jsfMock.mockFacesContext, paymentView);

        // Verify
        ...
    }
}
Any feedbacks are welcome.

Wednesday, March 5, 2014

Learning Primefaces' Extensions Development

I'm glad to announce a new book Learning Primefaces' Extensions Development. The book is about various JSF components provided in the open source, community driven project PrimeFaces Extensions - an official project with additional components to the great PrimeFaces framework. PrimeFaces is a de-facto standard framework in the Java Web Development. There are already a couple of books about the PrimeFaces core: Cookbook, Started and Beginner's Guide.

What is the new book about? The book covers most important major features of the PrimeFaces Extensions. You will meet the additional JSF components, learn step-by-step how to use them in the PrimeFaces based rich JSF applications and get some ideas for writing your own components. This is a must for every JSF / PrimeFaces developer.

The book has been written by a team member of the PrimeFaces Extensions Sudheer Jonna. Thanks Sudheer for your contribution! I'm sure PrimeFaces users will be happy to hold the book in their hands.


Wednesday, January 1, 2014

PrimeFaces Extensions 1.2.1 was released with a new QRCode component

We are glad to announce the next release 1.2.1 of PrimeFaces Extensions (yes, 1.2.1 and not 1.2.0 due to some encountered issues in the newly released 1.2.0). This is a maintenance release which contains fixes for the components AjaxErrorHandler, FluidGrid, DynaForm, TimePicker, InputNumber and new features in Exporter (possibility to skip some components during export) and Waypoint (can be used now for horizontal scrolling as well).

Beside fixed issues (full list on GitHub) we added a new JSF component QRCode. QR Code is a two-dimensional barcode for multi-purpose using. Refer this article on Wikipedia if you don't know what it is.


The QR Code is generated completely on the client-side. Usage example:
<pe:qrCode renderMethod="canvas" 
           renderMode="2" 
           text="http://primefaces-extensions.github.io/"
           label="PF-Extensions"
           size="200"                 
           fillColor="7d767d"
           fontName="Ubuntu"
           fontColor="#01A9DB"
           ecLevel="H"                   
           radius="0.5"/>
Furthermore, the component library and the showcase were updated to fit JSF 2.2. The PrimeFaces team lead Çagatay Çivici has provided us his dedicated server for deployment. We would like to thank him for that! This is the same server the PrimeFaces showcase is running on. Please consider a new URL for our showcase. The old URLs are out of date (I've canceled my VPS). The showcase is running on Mojarra 2.2.x. But of course we test it on MyFaces as well.

The new release is available as usually in the Maven central repository. Have fun!

Edit: Çagatay Çivici told us that the demos including PrimeFaces showcase, labs and extensions crashed a couple of times, so that he had to undeploy the extensions' showcase. The current showcase is deployed to Amazon EC2 instance and is running on Tomcat 7 now. Thanks to our user sebargarcia.

Wednesday, December 11, 2013

Modular JSF applications

Everybody heard about portals which combine single web applications to a big one. A portal software works like mashups - content from several sources is picked up in a single service, mostly displayed in a single web page. A portal software also allows to change user settings, such as language or theme, across all single web applications (independent modules) embedded into the portal software. Furthermore, a single sign-on (SSO) is expected and it should work as well. That means, a single login permits an user to access all embedded web applications. It would be interesting to know if there is a simple and lightweight solution in the JEE world to develop modular JSF 2 applications, to gather and to present them in one portal-like web application automatically. Sure, there are OSGi and complex Portals Bridges providing support for JSR-168 or JSR-286 compliant Portlet development. But fortunately, JSF 2 already provides a simple possibility for that "under the hood". With less effort we can build a portal-like software. All what we need are JSF 2 and CDI - de-facto standard DI framework in the Java world.

The topic of this post is not new. You can find some discussions and ideas in the web. I would only mention here two links. The first one is the article "How-to: Modular Java EE Applications with CDI and PrettyFaces" in the ocpsoft's blog. The second one "Modular Web Apps with JSF2" was presented in the JBoss' wiki. The idea is to create JAR files containing single web applications and to supply them with a main WAR file. The WAR file bundles JARs during build process, e.g. via Maven dependencies. That means, JARs are located in the WAR under WEB-INF/lib/. XHTML files in JARs are placed below /META-INF/resources/ and will be fetched automatically by JSF 2. They are available to JSF as if they were in the /webapp/resources/ folder. You can e.g. include facelets from JARs with a quite common ui:include. This works like a charm. To be able to pick up generic informations about every JSF module at runtime, we also need empty CDI's beans.xml in JARs files. They are located as usually below the META-INF folder.

Now let's start with the coding. But first, let's define the project's structure. You can find a complete implemented example on the GitHub. This is just a proof of concept for a lightweight JSF 2 portal-like implementation with demo web apps (written with JSF 2.2). There are 5 sub-projects

jsftoolkit-jar Base framework providing interfaces and utilities for modular JSF applications.
modA-jar First web application (module A) which depends on jsftoolkit-jar.
modB-jar Second web application (module B) which depends on jsftoolkit-jar.
portal-jar Java part of the portal-like software. It also depends on jsftoolkit-jar.
portal-war Web part of the portal-like software. It aggregates all artefacts and is a deployable WAR.

The base framework (jsftoolkit-jar) has interfaces which should be implemented by every single module. The most important are
/**
 * Interface for modular JSF applications. This interface should be implemented by every module (JSF app.)
 * to allow a seamless integration into a "portal" software.
 */
public interface ModuleDescription {

    /**
     * Provides a human readable name of the module.
     *
     * @return String name of the module
     */
    String getName();

    /**
     * Provides a description of the module.
     *
     * @return String description
     */
    String getDescription();

    /**
     * Provides a module specific prefix. This is a folder below the context where all web pages and
     * resources are located.
     *
     * @return String prefix
     */
    String getPrefix();

    /**
     * Provides a name for a logo image, e.g. "images/logo.png" (used in h:graphicImage).
     *
     * @return String logo name
     */
    String getLogoName();

    /**
     * Provides a start (home) URL to be navigated for the module.
     *
     * @return String URL
     */
    String getUrl();
}

/**
 * Any JSF app. implementing this interface can participate in an unified message handling
 * when all keys and messages are merged to a map and available via "msgs" EL, e.g. as #{msgs['mykey']}.
 */
public interface MessagesProvider {

    /**
     * Returns all mesages (key, text) to the module this interface is implemented for.
     *
     * @param  locale current Locale or null
     * @return Map with message keys and message text.
     */
    Map<String, String> getMessages(Locale locale);
}
Possible implementations for the module A look like as follows:
/**
 * Module specific implementation of the {@link ModuleDescription}.
 */
@ApplicationScoped
@Named
public class ModADescription implements ModuleDescription, Serializable {

    @Inject
    private MessagesProxy msgs;

    @Override
    public String getName() {
        return msgs.get("a.modName");
    }

    @Override
    public String getDescription() {
        return msgs.get("a.modDesc");
    }

    @Override
    public String getPrefix() {
        return "moda";
    }

    @Override
    public String getLogoName() {
        return "images/logo.png";
    }

    @Override
    public String getUrl() {
        return "/moda/views/hello.jsf";
    }
}

/**
 * Module specific implementation of the {@link MessagesProvider}.
 */
@ApplicationScoped
@Named
public class ModAMessages implements MessagesProvider, Serializable {

    @Override
    public Map<String, String> getMessages(Locale locale) {
        return MessageUtils.getMessages(locale, "modA");
    }
}
The prefix of this module is moda. That means, web pages and resources are located under the folder META-INF/resources/moda/. That allows to avoid path collisions (identical paths) across all single web applications. The utility class MessageUtils (from the jsftoolkit-jar) is not exposed here. I will only show the class MessagesProxy. The class MessagesProxy is an application scoped bean giving an access to all available messages in a modular JSF web application. It can be used in Java as well as in XHTML because it implements the Map interface. All found available implementations of the MessagesProvider interface are injected by CDI automatically at runtime. We make use of Instance<MessagesProvider>.
@ApplicationScoped
@Named(value = "msgs")
public class MessagesProxy implements Map<String, String>, Serializable {

    @Inject
    private UserSettingsData userSettingsData;

    @Any
    @Inject
    private Instance<MessagesProvider> messagesProviders;

    /** all cached locale specific messages */
    private Map<Locale, Map<String, String>> msgs = new ConcurrentHashMap<Locale, Map<String, String>>();

    @Override
    public String get(Object key) {
        if (key == null) {
            return null;
        }

        Locale locale = userSettingsData.getLocale();
        Map<String, String> messages = msgs.get(locale);

        if (messages == null) {
            // no messages to current locale are available yet
            messages = new HashMap<String, String>();
            msgs.put(locale, messages);

            // load messages from JSF impl. first
            messages.putAll(MessageUtils.getMessages(locale, MessageUtils.FACES_MESSAGES));

            // load messages from providers in JARs
            for (MessagesProvider messagesProvider : messagesProviders) {
                messages.putAll(messagesProvider.getMessages(locale));
            }
        }

        return messages.get(key);
    }
    
    public String getText(String key) {
        return this.get(key);
    }
    
    public String getText(String key, Object... params) {
        String text = this.get(key);

        if ((text != null) && (params != null)) {
            text = MessageFormat.format(text, params);
        }

        return text;
    }

    public FacesMessage getMessage(FacesMessage.Severity severity, String key, Object... params) {
        String summary = this.get(key);
        String detail = this.get(key + "_detail");

        if ((summary != null) && (params != null)) {
            summary = MessageFormat.format(summary, params);
        }

        if ((detail != null) && (params != null)) {
            detail = MessageFormat.format(detail, params);
        }

        if (summary != null) {
            return new FacesMessage(severity, summary, ((detail != null) ? detail : StringUtils.EMPTY));
        }

        return new FacesMessage(severity, "???" + key + "???", ((detail != null) ? detail : StringUtils.EMPTY));
    }
    
    /////////////////////////////////////////////////////////
    // java.util.Map interface
    /////////////////////////////////////////////////////////

    public int size() {
        throw new UnsupportedOperationException();
    }

    // other methods ...
}
Well. But where the instances of the ModuleDescription are picked up? The logic is in the portal-jar. I use the same mechanism with CDI Instance. CDI will find out all available implementations of the ModuleDescription for us.
/**
 * Collects all available JSF modules.
 */
@ApplicationScoped
@Named
public class PortalModulesFinder implements ModulesFinder {

    @Any
    @Inject
    private Instance<ModuleDescription> moduleDescriptions;

    @Inject
    private MessagesProxy msgs;

    private List<FluidGridItem> modules;

    @Override
    public List<FluidGridItem> getModules() {
        if (modules != null) {
            return modules;
        }

        modules = new ArrayList<FluidGridItem>();

        for (ModuleDescription moduleDescription : moduleDescriptions) {
            modules.add(new FluidGridItem(moduleDescription));
        }

        // sort modules by names alphabetically
        Collections.sort(modules, ModuleDescriptionComparator.getInstance());

        return modules;
    }
}
We are equipped now for creating dynamic tiles in UI which represent entry points to the corresponding web modules.
<pe:fluidGrid id="fluidGrid" value="#{portalModulesFinder.modules}" var="modDesc"
              fitWidth="true" hasImages="true">
    <pe:fluidGridItem styleClass="ui-widget-header">
        <h:panelGrid columns="2" styleClass="modGridEntry" columnClasses="modLogo,modTxt">
            <p:commandLink process="@this" action="#{navigationContext.goToPortlet(modDesc)}">
                <h:graphicImage library="#{modDesc.prefix}" name="#{modDesc.logoName}"/>
            </p:commandLink>

            <h:panelGroup>
                <p:commandLink process="@this" action="#{navigationContext.goToPortlet(modDesc)}">
                    <h:outputText value="#{modDesc.name}" styleClass="linkToPortlet"/>
                </p:commandLink>

                <p/>
                <h:outputText value="#{modDesc.description}"/>
            </h:panelGroup>
        </h:panelGrid>
    </pe:fluidGridItem>
</pe:fluidGrid>
Tiles were created by the component pe:fluidGrid from PrimeFaces Extensions. They are responsive, means they get rearranged when resizing the browser window. The next picture demonstrates how the portal web app looks like after the starting up. It shows two modular demo apps found in the classpath. Every modular web app is displayed as a tile containing a logo, name and short description. Logos and names are clickable. A click redirects to the corresponsing single web app.

As you can see, on the portal's homepage you can switch the current language and the theme. The second picture shows what happens if the user clicks on the module A. The web app for the module A is shown. You can see the Back to Portal button, so a back navigation to the portal's homepage is possible.


Two notes at the end:
  1. It is possible to run every module as a standalone web application. We can check at runtime (again by means of CDI) if the module is within the "portal" or not and use different master templates. A hint is here.
  2. I didn't implement a login screen, but there is no issue with single sign-on because we only have one big application (one WAR). Everything is delivered there.

Monday, November 11, 2013

PrimeFaces Extensions 1.1.0 released. Introduction to flexible grid layout.

We are glad to announce the next release 1.1.0 of PrimeFaces Extensions. Beside fixed issues (full list on GitHub) we added a new JSF component FluidGrid. FluidGrid is a cascading grid layout component. It works by placing elements in optimal position based on available vertical space, sort of like a mason fitting stones in a wall. It is responsive, meaning the grid will reflow as the window size changes. Modern web sites are not imaginable without a responsive design. Good designed web sites look well on every device and with every screen resolution. The basic prerequisite for that is a dynamic fluid layout which fits any browser sizes. The new component FluidGrid allows to set up a nice tight grid with items that have variable heights and widths. Items inside of FluidGrid can have any content: text, images, links, input fields, etc. They can be defined in a static or in a dynamic way as in data iteration components.

Let me show some features to get a first impression what the component can. The first example demonstrates a simple usage with static items. Static items are defined by the tag pe:fluidGridItem which can be placed multiple times below the main tag pe:fluidGrid. Items can have different width / height specified by style classes. The main container for the pe:fluidGrid has the style class pe-fluidgrid and the container of the pe:fluidGridItem has the style class pe-fluidgrid-item.
<pe:fluidGrid hGutter="10" vGutter="10">
    <pe:fluidGridItem styleClass="ui-widget-header">Item 1</pe:fluidGridItem>
    <pe:fluidGridItem styleClass="ui-widget-header w2 h2">Item 2</pe:fluidGridItem>
    <pe:fluidGridItem styleClass="ui-widget-header h3">Item 3</pe:fluidGridItem>
    <pe:fluidGridItem styleClass="ui-widget-header h2">Item 4</pe:fluidGridItem>
    <pe:fluidGridItem styleClass="ui-widget-header w3">Item 5</pe:fluidGridItem>
    <pe:fluidGridItem styleClass="ui-widget-header">Item 6</pe:fluidGridItem>
    <pe:fluidGridItem styleClass="ui-widget-header">Item 7</pe:fluidGridItem>
    <pe:fluidGridItem styleClass="ui-widget-header h2">Item 8</pe:fluidGridItem>
    <pe:fluidGridItem styleClass="ui-widget-header w2 h3">Item 9</pe:fluidGridItem>
    <pe:fluidGridItem styleClass="ui-widget-header">Item 10</pe:fluidGridItem>
    ... etc. ...
</pe:fluidGrid>
            
<h:outputStylesheet id="fluidGridCSS">
    .pe-fluidgrid {
        max-width: 900px;
    }
    
    .pe-fluidgrid .pe-fluidgrid-item {
        width:  60px;
        height: 60px;
        border-radius: 5px;
        padding-top: 0.5em;
        text-align: center;
    }
    
    .pe-fluidgrid-item.w2 {width: 130px;}
    .pe-fluidgrid-item.w3 {width: 200px;}    
    .pe-fluidgrid-item.h2 {height: 100px;}
    .pe-fluidgrid-item.h3 {height: 130px;}
</h:outputStylesheet>
In the example we used two attributes hGutter and vGutter for horizontal and vertical space between items. The result look like


After browser resizing all items are rearranged according to the available browser window size. No horizontal scrollbar appears.


Dynamic items can be put in a collection or list of FluidGridItem instances. A FluidGridItem instance contains a data object (of any data types) and an optional property type to match the type attribute in pe:fluidGridItem (see the last example with dynamic form). Dynamic items can be accessed in XHTML via the value attribute and exposed via the var attribute.
<pe:fluidGrid value="#{fluidGridDynamicController.images}" var="image" fitWidth="true" hasImages="true">
    <pe:fluidGridItem>
        <h:graphicImage library="images" name="fluidgrid/#{image.name}"/>
    </pe:fluidGridItem>
</pe:fluidGrid>
The bean looks like
@ManagedBean
@ViewScoped
public class FluidGridDynamicController implements Serializable {

    private List<FluidGridItem> images;

    @PostConstruct
    protected void initialize() {
        images = new ArrayList<FluidGridItem>();

        for (int j = 0; j < 3; j++) {
            for (int i = 1; i <= 10; i++) {
                images.add(new FluidGridItem(new Image(i + ".jpeg")));
            }
        }
    }

    public List<FluidGridItem> getImages() {
        return images;
    }
}
The result and more details can be seen in the showcase (second use case).

The next example demonstrates how to specifies elements which are stamped within the grid layout. These are special layout elements which will not be laid out by FluidGrid. Rather, FluidGrid will layout items below stamped elements. To specify stamped elements, use the stamp attribute which can be any search expression supported by the PrimeFaces Search Expression Framework. The XHTML code looks as follows
<pe:fluidGrid stamp="@(.pe-fluidgrid .stamp)" resizeBound="false" widgetVar="fluidGridWdgt">
    <div class="stamp"></div>
    
    <pe:fluidGridItem styleClass="ui-widget-header"/>
    <pe:fluidGridItem styleClass="ui-widget-header w2 h2"/>
    <pe:fluidGridItem styleClass="ui-widget-header h3"/>
    <pe:fluidGridItem styleClass="ui-widget-header h2"/>
    <pe:fluidGridItem styleClass="ui-widget-header w3"/>
    <pe:fluidGridItem styleClass="ui-widget-header"/>
    <pe:fluidGridItem styleClass="ui-widget-header"/>
    <pe:fluidGridItem styleClass="ui-widget-header h2"/>
    <pe:fluidGridItem styleClass="ui-widget-header w2 h3"/>
    <pe:fluidGridItem styleClass="ui-widget-header"/>
    ... etc. ...
</pe:fluidGrid>
More infos can be seen in the showcase (third use case). The next screenshots show a grid layout with a stamped element and without stamping after the button "Toggle stumped" was pressed.


 

Now the last, the most important example, the FluidGrid was implemented for. The example demonstrates how to design a responsive dynamic grid with input fields. This is similar to the DynaForm component in PrimeFaces Extensions, but the grid is not a fixed table in this case. It is responsive! The grid layout with input fields is placed within the center pane in pe:layout. The results before and after resizing the center layout pane are shown below. Try to resize the browser window of this example to see it in action.



The XHTML code looks like
<pe:fluidGrid id="fluidGrid" value="#{fluidGridDynaFormController.items}" var="data"
              resizeBound="false" hGutter="20" widgetVar="fluidGridWdgt">
    <pe:fluidGridItem type="input">
        <div class="dynaFormLabel">
            <p:outputLabel for="txt" value="#{data.label}"/>
        </div>
        <p:inputText id="txt" value="#{data.value}" required="#{data.required}"/>
    </pe:fluidGridItem>
    <pe:fluidGridItem type="select" styleClass="select">
        <div class="dynaFormLabel">
            <p:outputLabel for="menu" value="#{data.label}"/>
        </div>
        <p:selectOneMenu id="menu" value="#{data.value}" required="#{data.required}">
            <f:selectItems value="#{data.selectItems}"/>
        </p:selectOneMenu>
    </pe:fluidGridItem>
    <pe:fluidGridItem type="calendar" styleClass="calendar">
        <div class="dynaFormLabel">
            <p:outputLabel for="cal" value="#{data.label}"/>
        </div>
        <p:calendar id="cal" value="#{data.value}" required="#{data.required}" showOn="button"/>
    </pe:fluidGridItem>
</pe:fluidGrid>
The bean and model classes are straightforward.
@ManagedBean
@ViewScoped
public class FluidGridDynaFormController implements Serializable {

    private List<FluidGridItem> items;

    @PostConstruct
    protected void initialize() {
        items = new ArrayList<FluidGridItem>();

        List<SelectItem> selectItems = new ArrayList<SelectItem>();
        selectItems.add(new SelectItem("1", "Label 1"));
        selectItems.add(new SelectItem("2", "Label 2"));
        selectItems.add(new SelectItem("3", "Label 3"));

        items.add(new FluidGridItem(new DynamicField("First Label", null, true, null), "input"));
        items.add(new FluidGridItem(new DynamicField("Second Label", "Some default value", false, null), "input"));
        items.add(new FluidGridItem(new DynamicField("Third Label", null, false, selectItems), "select"));
        items.add(new FluidGridItem(new DynamicField("Fourth Label", "2", false, selectItems), "select"));
        items.add(new FluidGridItem(new DynamicField("Fifth Label", null, true, null), "calendar"));
        items.add(new FluidGridItem(new DynamicField("Sixth Label", new Date(), false, null), "calendar"));
        items.add(new FluidGridItem(new DynamicField("Seventh Label", null, false, null), "input"));
        items.add(new FluidGridItem(new DynamicField("Eighth Label", null, false, selectItems), "select"));
        items.add(new FluidGridItem(new DynamicField("Ninth Label", null, false, null), "calendar"));
    }

    public List<FluidGridItem> getItems() {
        return items;
    }
}

public class DynamicField implements Serializable {

    private String label;
    private Object value;
    private boolean required;
    private List<SelectItem> selectItems;

    public DynamicField() {
    }

    public DynamicField(String label, Object value, boolean required, List<SelectItem> selectItems) {
        this.label = label;
        this.value = value;
        this.required = required;
        this.selectItems = selectItems;
    }

    // getter / setter methods
    ...
}
Have fun with this release! Tip: it is also worth to check a new example for our JsonConverter. The example shows how to pre-initialize any UI forms on initial page load (GET request) with default values passed in URL. Any data types are supported (also Java Generics!).