Monday, 13 May 2013

JSF 2.2 Stateless views explained

Introduction

The JSF 2.2 specification (JSR-344) is recently approved. There are a few examples available but there seems no detailed explanation yet of the new features.
Although the development is still in progress, I like to start today already with the stateless view features which was fairly late added to the list of JSF 2.2 features.
The ticket had many votes and stateless is hot, so for many people this is a very wanted feature which is added.
But be aware of the implementation details and some other facts that are very good explained in this section of the excellent overview of Arjan Tijms on JSF 2.2 features.

transient=”true”

The explanation of the feature is fairly simply. By specifying the attribute transient on the f:view tag, we are able to run that page in a stateless mode. Stateless here means that the JSF StateManager isn’t storing any data into the memory related to this view.
During restore view phase, the view is created, as always, but now there isn’t any state applied to it.
It is a fairly simple change but has a lot of consequences.

viewScoped beans

The most important effect of the stateless operation mode is that all viewScoped beans are lost. Those kind of beans, tied to a certain view, aren’t stored anymore and thus, when the same page is rendered again, a new version of the bean needs to be instantiated again.
It can easily demonstrated by a ‘classic’ scope testing application, for example the one I used here to test CODI on WLS 12c server. You create beans with a different scope, like requestScope, viewScope, sessionScope and applicationScope and initialize a timestamp in the constructor.  The value of this property is then shown on screen where you can do a post to stay on the same page or go to another page which has the same beans on it.
In the case of the transient view, even if you stay on the same page, a new instance of the viewScoped bean is created. The other scopes aren’t affected.
I tried this with the Glassfish 4 promoted build 87 and a Tomcat 7 instance where I used the latest available Mojarra 2.2 snapshot.

viewScope != viewScope

Although not immediately linked to the stateless view features, there are now 2 ViewScoped annotation classes. We had already the RequestScoped, SessionScoped and ApplicationScoped from JSF (package javax.faces.bean) and the CDI version (in package javax.enterprise.context).
As requested by many developers, there is now also a CDI version of the ViewScoped (from package javax.faces.bean) but defined in JSF (and not CDI). The new class is defined in javax.faces.view. Look careful to import the correct class in relation to the @ManagedBean or @Named annotation because mixing them will lead to unexpected behaviour.

When to use

What are the use cases for the stateless view operation mode. As already mentioned in the feature description by Arjan Tijms, performance and memory gain is minimal, except when you are working with very large pages that contains thousands of components.
Besides the fact that ViewScoped beans behave differently, a lot of components are relying on the fact that they can save and restore their state within the view. So many components, standard ones but also from component libraries like PrimeFaces will not function properly anymore on stateless views.
On the other side, views are stateless and this means you can even post your data back to the server, after your session has expired or even after a server reboot.

Conclusion

Since there is a large impact on AJAX behaviour, commonly used with ViewScoped beans, and the proper functioning of components, considering stateless views must be evaluated thoroughly and tested very profound.
And initiatives like the one from Industrie IT should also be considered when you are interested in those kind of setups.

Thursday, 14 February 2013

Client Behavior functionality with JSF 2.x (part 2)

Introduction

In the previous text, I described how you can create a button that ask for a confirmation.  It showed the basic functionality of creating reusable client side functionality.
The example was very simple, just requiring one javaScript command.
In this text, I'll show some more advanced usages where you need to include an external resource and have to respond on multiple events.
The example shows how you can create the hover functionality for an input field. And of course with most browsers you can specify it as a css selector
    .myHover:hover {
        background-color: red;
    }
Unfortunately, not all browsers supports this and it is a pity that IE9 fails to understand it. So lets write an universal hover functionality.

Specify the event

For the change of color when the mouse is over a field, we need to respond to 2 events.  The mouse that enters the field, mouseover event, to adjust the color and when the mouse leaves the field, mouseout event, to revert the color to his original one.
So we need a client behaviour tag, just like the confirmation tag we have created the last time, lets call it hover so that we can attach the functionality to a field.  We have 2 events but we don't need to create 2 different tags. We are able to retrieve the intended event in the getScript method.
So let start with the definition of the tag in the facelet tag library
    <tag>
        <tag-name>hover</tag-name>
        <behavior>
            <behavior-id>hover<behavior-id>
        </behavior>
    </tag>;
This is identical to the confirmation functionality.  And we can use it in the following way
        <h:inputText value="#{bean.prop}" >
            <custom:hover event="mouseover"/>
            <custom:hover event="mouseout"/>
        </h:inputText>
We now specify the events we like to intercept and based on the event name, we can code the required javaScript        
    @Override
    public String getScript(ClientBehaviorContext behaviorContext) {
        if (MOUSEOVER_EVENT.equals(behaviorContext.getEventName())) {
            return "this.className += ' hoverClass '";
        }
        if (MOUSEOUT_EVENT.equals(behaviorContext.getEventName())) {
            return "this.className = this.className.replace( /(?:^|\\s)hoverClass(?!\\S)/g , '' )";
        }
        return null;
    }
The event name is passed to the getScript method in the behaviorContext parameter. The code adds or removes a CSS class to the HTML element. So when the hoverclass is defined as a red background, the input text element becomes red when the mouse is over the field and returns to his 'normal' color when we move out of it.

A single tag

The above solution is from a developers perspective not an ideal situation. The first improvement we will make is that you only need to specify 1 tag, and not 2.
The hover tag we created earlier was explicitly linked to the client behaviour functionality.  You can also create a tag for other purposes like a converter or your new component.  But there is also the possibility to create a tag for which you must implement the functionality, like this
<tag>
        <tag-name>myHover</tag-name>
        <handler-class>be.rubus.web.jsf.tutorial.clientbehaviour.HoverHandler</handler-class>
    </tag>

Within the HoverHandler, you must program the behaviour that you want. Before you can start with it, you must know what the function of a handler class is.

This class will be used by the JSF system to convert the xhtml page to the component tree. Afterwards this component tree will be converted to the HTML which is sent to the browser in the Render Response phase of the JSF lifecycle.
With a handler class you can change the created component tree. You can manipulate the 'DOM tree' (or what will become the DOM tree) by adding, removing and rearranging nodes but also change the properties of the nodes in the component tree.
The HoverHandler looks like this
public class HoverHandler extends TagHandler {
    private HoverBehavior mouseOver = new HoverBehavior();
    private HoverBehavior mouseOut = new HoverBehavior();
    public HoverHandler(TagConfig config) {
        super(config);
    }
    @Override
    public void apply(FaceletContext ctx, UIComponent parent) throws IOException {
        if (parent instanceof ClientBehaviorHolder) {
            ClientBehaviorHolder comp = (ClientBehaviorHolder) parent;
            comp.addClientBehavior("mouseover", mouseOver);
            comp.addClientBehavior("mouseout", mouseOut);
        }
    }
}
If you want to create a tag handler class of your own, you should extend it from javax.faces.view.facelets.TagHandler and do your work in the apply method. The method has a parameter parent and it is the immediate parent of the tag. In our case, the inputText.
Since we now have a reference to the component we like to modify, we can call the addClientBehavior method twice, once for the mouseover event and once for the mouseout event.
The HoverBehaviour class we pass along with the event names, is the same class as we used in the previous section.  So it will generate the correct javaScript code for each event.
So now we have improved our hover functionality greatly from a developers standpoint.  He doesn't have to type the event names (strings where he can make mistakes) and has to type a lot less characters.

Resource dependency

The only thing that can go wrong now, is the definition of the CSS class.  If we define it in the CSS file of the application, we have it available on every page.

But what if we decide to create some kind of reusable library so that we can use it for all the applications of the company. Or what if the javaScript code is large and we have placed it in an external file?
Maybe you know already that with a JSF renderer, you can specify the external resources the renderer depends on. Resources like javascript files and CSS files, just as we also need for the client behaviour functionality.
The good news is that there exists a special renderer for client behaviour, called ClientBehaviorRenderer.  It has also a getScript method that we need to implement and we can specify the resources we need with the ResourceDependency annotation.  This is the renderer version of the hover functionality
@FacesBehaviorRenderer(rendererType="hover")
@ResourceDependency(name = "hover.css")
public class HoverBehaviorRenderer extends ClientBehaviorRenderer {
    private static final String MOUSEOVER_EVENT = "mouseover";
    private static final String MOUSEOUT_EVENT = "mouseout";
    @Override
    public String getScript(ClientBehaviorContext behaviorContext, ClientBehavior behavior) {
        if (MOUSEOVER_EVENT.equals(behaviorContext.getEventName())) {
            return "this.className += ' hoverCls '";
        }
        if (MOUSEOUT_EVENT.equals(behaviorContext.getEventName())) {
            return "this.className = this.className.replace( /(?:^|\\s)hoverCls(?!\\S)/g , '' )";
        }
        return null;
    }
}
It is a straight copy, only the base class is different and has other annotations.
The client behavior itself becomes now empty, except for the definition of the renderer that must be used.
@FacesBehavior(value = "hover")
public class HoverBehavior extends ClientBehaviorBase {
    @Override
    public String getRendererType() {
        return "hover";
    }
}

Wrap up

We now have created a custom tag which allows us to have the 'hover' functionality using javascript functionalities. We only need a single tag and due to the renderer approach, we can package it in a jar file. When the file is in the classpath and we use the template, the correct coloring is applied to the 'hovered' field.

Conclusion

With the client side behavior of JSF 2, you have the possibilities to further enhance the components in a component library with some client side features in a reusable way. JSF remains mainly a server side framework but the client side representation can now greatly enhanced by the developer.
With these possibilities available, JSF can go along with the recent HTML5 and JavaScript frameworks raise in interest in the application development business.

You can find the code for this tutorial here.




Sunday, 3 February 2013

Client Behavior functionality with JSF 2.x (part 1)

Introduction

One of the lesser know new features of JSF 2, is the ability to define some client behavior for a component in a reusable way. We all know the possibility to enhance a component with ajax, using the tag.  It is also based on the Client Behavior functionality but we can define our custom functionality.

Just as you can define a validator for an input field, you can define a behavior which results in some JavaScript code which can be executed in the browser.

These features shows that, although JSF is still mainly a server side framework, the importance and the popularity of the client side is acknowledged.

Confirm button

We start with a simple example where we like to make a button that first asks for a confirmation before it performs its action.  A classic example is the button that deletes some information but first we ask the user for a confirmation if he is sure to execute this irreversible action.

The key Java class for the Client Behavior is ClientBehaviorBase. It implements the ClientBehavior interface, common to all functionality related to client side behavior, and by implementing the getScript method, half of the work is already done.
For our confirm functionality, we have a method like this

    @Override
    public String getScript(ClientBehaviorContext behaviorContext) {
        return "return confirm('Are you sure ?');";
    }

The return string is the JavaScript we like to execute in the browser, here it is the confirm method which pops-up a javascript ‘window’ with an OK and Cancel button.

When the class is annotated with @FacesBehavior, The JSF system add our class to the list of implemented client behaviors.

@FacesBehavior(value = "confirmation")
public class ConfirmBehavior extends ClientBehaviorBase {

The content of the value member is the, unique, name we can use to refer to our custom client behavior.  This is needed when we define a tag for the behavior.

A tag is needed so that we can specify in the xhtml files which components receive our javascript. In the facelet tag library we can define it as follows.

    <namespace>http://www.rubus.be/jsf/tutorial</namespace>

    <tag>
        <tag-name>confirmation</tag-name>
        <behavior>
            <behavior-id>confirmation</behavior-id>
        </behavior>
    </tag>



The behavior-id must match the value member of the FacesBehaviour annotation.  The tag name can be freely chosen but here it happens to be the same as the behavior id.

Assigning to a commandButton is not different than using any other custom tag that you have defined in a facelet tag library.

<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:r="http://www.rubus.be/jsf/tutorial"
        >
<h:head>
    ...
</h:head>
<h:body>
    ...
    <h:form>
        ...
        <h:commandButton value="with confirmation" actionListener="#{bean.performAction}">
            <r:confirmation/>
        </h:commandButton>
        ...
    >/h:form>
    ...
</h:body>
</html>

When the user clicks now on the button, a confirmation is asked with the text ‘Are you sure?’. And when he clicks on the cancel button, the action listener method isn’t performed. In the case he has pressed on the OK button, the post to the server is executed as usual.

Which components


To what components can we attach a custom client behaviour? This is determined by the ClientBehaviourHolder interface.  It has a few methods to handle the addition and retrieval of registered client behaviors and event names. More on event names in the next section.

Well almost all components implement that interface.  The most useful ones are of course all the input fields and the buttons. But also on the html body component we can attach a behaviour. More specifically, the load event can be used to attach some additional code to the page when rendered in the browser.

How to specify the event?


In our example with the confirmation question, the javascript method is attached to the onClick method of the button.  This is because the click event is the default event for the commandButton component. If we like to attach the code to some other event, then we have to specify the event name with the event attribute of the tag. We will see an example of it in the second part of this blog.

What are all the events which are supported? This differs from component to component. But the rule is that when you have the onXXX attribute on a component to attach some behaviour, the event XXX is available for creating a reusable client behaviour with the technique explained above.

Conclusion


It is very easy to specify some client behavior in a repeatable manner with JSF 2. And in the second part of this text I’ll explain some more advanced topics of the client behavior functionality.

Sunday, 6 January 2013

DeltaSpike JSF message system

Introduction

One of the main aspects of the Java EE 6 version was type safety. With the introduction of CDI, there are many tasks that can be done in a type safe way, with no needs of Strings anymore.
This improves the quality of the code since it reduces the chance of typo errors. During compilation, you can be warned of your mistake.
DeltaSpike is a CDI extension that combines all the goodies of the Apache CODI and SEAM 3 frameworks. It is a work in progress and lately the work on some JSF goodies is started.
In this text, I want to explain the message feature of DeltaSpike. And although there is still some String handling required, at least it makes it very flexible and extensible.  This is not the case with the default JSF functionality.

Getting started

The message feature is based on some advanced features of CDI where we can define our message as methods in an interface where no implementation is needed. Lets explain this based on the classic Hello world style example.
So we start with an interface that we annotate with MessageBundle

@MessageBundle
public interface ApplicationMessages
{
    String helloWorld(String name);
}
In a managed bean/controller we can inject then the message component and ask for the text linked with the message.  This is an example of a managed bean using the JsfMessage.

@Named
@RequestScoped
public class ControllerView
{
    private String name;
    @Inject
    private JsfMessage msg;
    public void doGreeting()
    {
        msg.addInfo().helloWorld(name);
    }
}

In the typical Hello world style where there is an input field on the screen linked with the name property and a button linked to the doGreeting method, the above code shows a JSF Info message on the screen.

JsfMessage is also an interface and can take only as type parameter an interface which is annotated with MessageBundle such as in our example above.
On the JsfMessage interface there are methods available to add a message to the JSF Message system with a certain severity, like info in our example, add the message for a certain component or just get the text of the message, without adding it.

The default implementation takes care of looking up the correct locale, message text and assembles the resulting String.

It isn't CDI as it wasn't customizable and extensible. But before we look at the possibilities, I have to explain first where, by default, it looks for the text definition.

In the above example, a resource bundle ApplicationMessages in the same directory as the package of the interface is interrogated for the key helloWorld.
So by default, it looks in the same directory for a key which equals the method name.
 
helloWorld=Welcome %s

Also pay attention on how you need to specify the place of the parameter in the text.  The default version uses the String#format() method which requires the %-character as placeholder indicator.  This is different from the standard JSF where we used the {0} type of placeholder.

But this can be customized by the MessageInterpolator but first try some easy configuration options.

Configuration options

In the previous section, we used the JsfMessage feature in his most basic format.  We used all the default settings and implementations.  In this section, I'll explain how you can customize the ResourceBundle and the key which will be used.

On the methods, we can place the MessageTemplate annotation.  With this annotation we can specify the key or the entire text which will be used. In case it is a key in the resource bundle, we need to wrap it inside {} characters as you can see in the example below.
The second customization is the ResourceBundle name which will be searched, in addition to the default one. It can be specified by the MessageContextConfig#messageSource member.

As you noticed in my wording, it defines additional ResourceBundles, so be careful if you define multiple candidates where the resource key can be found.

@MessageBundle
@MessageContextConfig(messageSource = {"org.apache.deltaspike.example.message.ApplicationMessages" }) 
public interface CustomizedMessages
{
    @MessageTemplate(value = "{nowMessage}")
    String getTimestampMessage(Date now);
}

When we use the above code, we look for a key nowMessage in the ApplicationMessages ResourceBundle. Without the curly brackets, the text itself would be used without looking up a ResourceBundle.

Pay attention to the typos in the messageSource member. When you specify a non existing ResourceBundle, you don’t get a warning or error and of course, the text won’t be displayed correctly.

Customizing individual MessageBundles

With the MessageContextConfig annotation, when can also customize other functionality of the Message system. In this section I'll explain how you can change the MessageInterpolator back to the standard JSF version.

The MessageFormatMessageInterpolator class uses the java.text.MessageFormat to replace the placeholders in the string with the arguments as we are used too. The class implements the interpolate method from the MessageInterpolator interface.

The Custom annotation is a CDI qualifier that I created and is required before the example can work.  I'll explain in a moment the reason for this.

@Custom
public class MessageFormatMessageInterpolator implements MessageInterpolator
{
    @Override
    public String interpolate(String messageText, Serializable[] arguments, Locale locale)
    {
        return MessageFormat.format(messageText, arguments);
    }
}

As already mentioned, with the MessageContextConfig annotation we can decide to use this MessageInterpolator on certain MessageBundles like this

@MessageBundle
@MessageContextConfig(messageInterpolator = MessageFormatMessageInterpolator.class)
public interface CustomizedMessages
{

Why do we need a CDI qualifier on our implementation?  We are not using it for injection, we refer to it by its class name!  Since the default implementation is also available in the Bean archive, the CDI container has 2 implementations available and don't know which one to choose when he needs to inject a MessageInterpolator into the default JsfMessage implementation.

So without the qualifier, our application will fail during deployment with an ambiguous dependency error.

So it is easier and probably also much more useful to replace the default implementation with your version.  This is explained in the next section.

Replace default implementation

In the previous section we changed the behavior for one MessageBundle.  But most of the time, we need to change the default implementation and don't want to specify this for each MessageBundle we create in our application.

As an example, I'll show you how you can define that the message bundle in the Faces config file is also used when a resource key is searched in the ResourceBundles.

@Specializes
public class CustomMessageResolver extends DefaultMessageResolver
{
    @Override
    public String getMessage(MessageContext messageContext, String messageTemplate, String category)
    {
        addMessageBundleFromFacesConfig(messageContext);
        return super.getMessage(messageContext, messageTemplate, category);
    }
    private void addMessageBundleFromFacesConfig(MessageContext someMessageContext)
    {
        String messageBundle = FacesContext.getCurrentInstance().getApplication().getMessageBundle();
        if (messageBundle != null && messageBundle.length() > 0)
        {
            someMessageContext.messageSource(messageBundle);
        }
    }
}

For this, we need to override the DefaultMessageResolver and intercept the call to the getMessage method.  This is the only method in the MessageResolver interface and is responsible for looking up the resource key in resource bundles.  But custom implementation can be written to look up the message text in a database system for example.

Here we use the CDI specilization functionality.  When we annotate an extended CDI bean with Specializes, CDI will use our version, the CustomMessageResolver, in all the cases where DefaultMessageResolver would be used.  Without the need of a CDI qualifier and without the issue of having an ambiguous dependency error.

In our extension of the default functionality, we look in the faces configuration to see if there is a MessageBundle defined.  If so, we add it to the list of messageSources maintained and searched to find the requested message.

The same procedure can be used to define a custom MessageInterpolator and LocaleResolver, dedicated to find the language in which the message text must be returned.

Plain message text

In the hello World example at the beginning of the text, we used the JsfMessage DeltaSpike functionality to add a JSF message.  We can also ask for the text without the need to show it as a JSF Message.
The JsfMessage interface has the get() method for this purpose.  The following snippet could be used to display the current time as text on the screen with #{bean.now}

    public String getNow()
    {
        return custom.get().getTimestampMessage(new Date());
    }

Conclusion

There is no type safety, which is popular in Java EE6, with the JsfMessage feature of DeltaSpike because you always need to specify somehow the resource key that needs to be used when the text is looked up.  But you have a flexible and extensible system that is much more readable due to the builder like pattern.
The JsfMessage feature is currently (begin January 2013) under development in the 0.4-INCUBATING version and the code can be found here.
In the JsfExample module you can find the examples described in this text.

Monday, 10 December 2012

Java EE6 as the universal backend

Introduction

Java EE6 is referred to by many people to be the most easy, productive, lightweight and best version of the enterprise environment. As a developer you can concentrate on the business logic and you don't have to spend time on the infrastructure side of the application.
Since J2EE 1.4, they made great efforts for simplifying the creation of Enterprise applications.  With the principles of 'convention over configuration', intelligent defaults and the usage of annotations, you can create EJB's or REST style webservices in minutes.
Due to the lightweight aspect of the current application servers, like JBoss AS 7 starts up in 7 seconds, you can have short development cycles where you can quickly test your new code.
In addition to these developments in the standard, there are other great initiatives which makes the Java EE 6 environment very attractive.
  • You have the Arquillian framework which gives the term testing a complete new dimension.  As it is a container-oriented testing framework, it allows you to execute integration tests in a real container as if it were unit tests.  Since they are portable, you can test for cross container compatibility of your application.
  • Another great framework is MyFaces CODI, a CDI extension, which is currently integrated with JBoss Seam3 into Apache DeltaSpike. It unleashes the power of the CDI framework and enables you to use Dependency Injection in radical new ways.
  • A third initiative I want to mention here is PrimeFaces. The PrimeFaces JSF components became very popular with JSF 2. They allow you to create powerful modern Rich Internet Application and yet keep the component library easy to use.

All on Java EE 6

In October, I had the privilege to give a course and presentation together with Çagatay Çivici, project lead of PrimeFaces project. During my presentation I showed a few cases where you can use the Java EE 6 environment as backend for your applications.
In that week, PrimeUI was first announced. And it made my realize that my story about the Java EE 6 environment could be extended even further. There was yet another type of applications that I could add to the picture.
So here is a short overview of the types of applications that are possible with Java EE 6
  1. JavaServer Faces
    This is the most obvious type of applications since JSF is part of the Java EE 6 specification.  But due to the nature of the framework, it is best suited for administrative applications which run in the browser of the desktop. With his component based nature and the standard facilities for conversion and validation, it makes it excellent for handling user input.
    However it requires some state kept in the session memory of the user. And although they have made quit some improvements in the JSF 2.x versions, it isn't the best choice for high volume websites.
  2. Mobile apps
    With the popularity of smartphones, there is a whole new market emerged that creates applications for the mobile devices.  They are native apps, running on the device itself and can access the services of the device easily.  But most of them also need data that are supplied from an external source, mostly in JSON format.
    With the JAX-RS component of Java EE 6, you can create easily some restful services that, annotated correctly, supply the caller the requested data in JSON format or take some data in. By just adding the @Path annotation to a CDI or EJB bean, you have created a restful services endpoint. This allows you to reuse your knowledge (and even functionality if needed) and support your native application quickly.
  3. Browser based mobile application
    The downside for mobile applications is the fact that you need to learn, or use, a specific language, like Objective C, and that your application is not compatible between all the type of devices.  With PrimeFaces Mobile, based on JQuery Mobile, you can create web applications that run in the browser of the mobile device but has the look and feel of a native app.
    PrimeFaces Mobile is just a component library, so it can be used easily by someone that knows JSF. And of course, here you can also use the complete power and functionality of the Java EE 6 stack.
These type of applications where presented during my presentation and can be summarized in the following picture.
Universal_Java_EE6_Backend

But don't focus on the database in the picture, in the demos I also used Hazelcast as a NoSQL solution and integrated it with CDI.

StatelessPrime

The fourth option in the picture is something I'm experimenting with since October. With PrimeUI, the widgets of the PrimeFaces component library will be available as a JavaScript version.  As communication, JSON data will be used. So why not using Java EE 6 stack then?


That is how the idea of StatelessPrime was born.  Creating stateless Web applications with HTML5, CSS, JavaScript and PrimeUI on the client side and Java EE 6 with the JAX RS module that does the communication in JSON format on the server side.
But the idea goes further. Is it possible to create a component library that allows some kind of compiler to generate the HTML5, JavaScript and JAX RS classes?  That way you can reuse your JSF and CDI knowledge to rapidly create stateless web applications.

You can follow my experiments on the StatelessPrime blog.

Sunday, 25 November 2012

Advanced PrimeFaces Graphic Image renderer for dynamic content

PrimeFaces has a component to render graphic resources and has added support for dynamic generated content.
There is a special StreamedContent class for this, so that you stream the generated resources from the JSF application to the browser.

But there are a few limitations for the component when it comes to dynamic generated content.  And they are not related to PrimeFaces but to the communication model between the browser and the application server.
Since there were lately a few questions in the PrimeFaces forum that had to do with these limitations, I decided to create an advanced renderer for the component. But there are a few warnings in using it.
For the impatient ones, you can find the project on GitHub.

How does the PrimeFaces Graphic Image renderer work?

The PrimeFaces Graphic Image renderer generates a html img tag where the src attribute points back to the application.  The URL contains a unique id and stores within the http session of the user, the EL expression linked to that unique id.
The EL expression comes from the value attribute of the p:graphicImage tag that the developer wrote in the JSF file and which points to the StreamedContent value that contains the dynamic generated content.
The browser interprets the html page and ask for the image content based on the URL found in the src attribute.

Since this URL points back to the JSF application, the PrimeFaces resource handler gets a chance to handle the request.  It recognize that the browser asks for a graphic resource with dynamic content based on the URL parts and parameters.
Based on the unique id which is available as parameter in the URL, it can take the corresponding EL and stream the content to the browser.

At this last step, the limitations can be hit in some use cases. Since the resource handler has no idea whatsoever of the page where the dynamic content is located, which bean is involved etc...  It can only rely on the EL expression the renderer has placed in the http session.  It is possible that this EL expression is only valid within a certain context.

The most striking example is the use of a composite component attribute.  Something like #{cc.attr.image} can be perfectly valid within the context of a custom composite component but it is clearly not when arbitrary executed.
The same reasoning goes for the dataTable component.  Whenever you use the alias defined in the var attribute for indicating the dynamic content, the PrimeFaces resource handler will be unable to retrieve the contents.
And the renderer can't determine the  EL expression that can give us the reference to the StreamedContent

Solution

The solution that I implemented is that we store the contents of the dynamic generated content on a location that can is always accessible, without the restriction of a context. This means we need to copy the contents to another location, the file system in our case.
The renderer copies the StreamedContent to a file in the System temp directory. For scaling reasons, this is a better alternative then storing the content directly in the http session area. We now only need to keep the file name next to the unique id instead of the EL expression.

On the other side, there is also another resource handler defined that uses the contents of the file to serve the browser request for the image resource.
The temporary files are removed when the http session is invalidated so that we don't have a problem with the disk storage size. We can't do it earlier because the browser can request the image multiple times as the user goes back in the screen flow or asks for a refresh.

Usage warnings

There is one issue with the above described solution, there is a performance drop.  It all depends on the size of the images of course but we need to write the content to disk, an additional step, and the resource handler serve it from disk which is slower then memory access.
For optimal performance, the storage on the disk is performed by using java.nio.channel.Channels.  That should guaranty to most efficient solution.

The clearing of the files is done when http session is invalidated by a HttpSessionBindingListener.  And although we can be pretty sure that the files gets removed, if the server implementation is correct, the files are kept during the user session.  When you have an application with a lot of dynamic generated content and the user works for a long time with your application, a lot of files can be created.

Intelligence of the advanced renderer

Therefore, there is some intelligence build into the Graphic Image renderer.  The scenario where the content is stored on disk is by default only used when the graphicImage tag is used within a custom composite component or a component that implements the UIData interface like dataTable.
These 2 cases are the situations where there is a lot of chance that the standard algorithm of PrimeFaces will fail. If this is not the case, the standard PrimeFaces functionality will be used (without the storage on disk).

Intelligent default functionality is fine but sometimes you need to take control yourself. This can be achieved by nesting a advancedRenderering tag within the graphicImage tag.  By specifying a boolean value for the value attribute, you can control the usage of the advanced rendering functionality.

Use cases where this can be handy.
1) You are using the graphicImage tag within a custom composite component but you as developer know that the EL you have specified can be used outside of the component (it is 'general' and not tied to a certain context) then you can disable the advanced rendering.
2) You have created the dynamic content with a bean on a request scope.  The resource handler can perfectly access the bean but in most cases the generated content is lost.  Here you can ask for the advanced rendering so that at render time, the image is stored on disk ready for streaming to the browser.

Code

The code can be found on GitHub and is released under the Apache License, Version 2.0.

Friday, 2 November 2012

Disabled selection button for PrimeFaces data table

Introduction

When you use the disabled attribute of a button, you can have some troubles executing the action and actionListener bound targets. The same goes for an input component where you can loose the user input.
But there are various use cases where an initial disabled button could be vary handy. The easiest solution could be that you change the scope of the managed bean the property is located that determines the value of the disabled attribute. But in this post I’ll describe an alternative and why it is maybe the best solution.

Disabled button problem

In the Apply request values phase of the JSF life cycle, you can find various resources on the internet that explain this important concept of JSF, there is a check if the post values contains the id of the button.
In that case, the specific button is clicked and an event is generated that the logic attached to the button needs to be executed in the Invoke application phase.
This kind of check is required because a form can contain multiple buttons and thus we need to know which functionality needs to be executed.  But the check that the button must be enabled can give us sometimes a problem.
The EL expression specified in the disabled attribute is evaluated in the Apply request values phase and when it evaluates to true, the event isn't posted.
So even when the button is enabled on the screen, during the Apply request values phase
of the JSF lifecycle, the EL expression can return a disabled true value and thus the click on the button has no effect.

Selection button for PrimeFaces data table

So, let us try with the PrimeFaces data table. You have various row selection options but I want to use the one where a button is placed in a footer of the table.
Suppose you have a JSF managed bean called personListView on a view scope that contains the list of records that you need to show in the page.
The view scope will be used in a lot of cases for the backing of a data table as you don't need to read the data in the database every time you change the sorting or filtering. This of course if the list of records you want to show isn't too long and read them all at once in memory.
The second managed bean, personView called, is on request scope and will be used to edit the selected record. It is on request scope because it only need to capture the data entered by the user and save it to the database.
The JSF page contains a section like this:
<p:dataTable value="#{personListView.personList}" var="person" selectionMode="single"
                     selection="#{personView.selectedPerson}" rowKey="#{person.id}">
   <p:column headerText="first name">
      ...
   </p:column>
   <f:facet name="footer">
     <p:commandButton ajax="false" value="Edit" action="person.jsf"
                      actionListener="#{personView.checkPerson}"/>
   </f:facet>
</p:dataTable>

In the footer, the button is shown to navigate to the second page, person.jsf, and calls here for demonstration purposes an actionListener method that just add an information message.

The idea is that the edit button stays disabled as long as you haven't selected a record in the data table.

So we change the markup to use the disabled attribute of the commandButton and an ajax call that listens to a row selection so that we can ask for a re-rendering of the button.
<p:dataTable value="#{personListView.personList}" var="person" selectionMode="single"
                     selection="#{personView.selectedPerson}" rowKey="#{person.id}">
  <p:ajax event="rowSelect" update="editBtn" />
  <p:column headerText="first name">
                ...
  </p:column>
  <f:facet name="footer">
    <p:commandButton ajax="false" value="Edit" action="person.jsf"
                     actionListener="#{personView.checkPerson}" id="editBtn"
                     disabled="#{empty personView.selectedPerson}"/>
  </f:facet>
</p:dataTable>    

Now the button is disabled as long as we don’t click on a row in the data table.  If we do so, the ajax event is fired, it sets the selected record to the selectedPerson property of the personView managed bean. The re-rendering of the button enables it so that we can click on it.

But if we do click on it, nothing happens. The first thing you should check with a PrimeFaces commandButton that is supposed to do navigation, is that we aren't using ajax.  But in this case, we haven't made any mistake. (ajax=”false” attribute on the commandButton)

The reason why the click on the button has no effect is because of the disabled attribute.  As described above, during Apply request values phase, the EL expression points to a new instance of the personView managed bean, it is at request scope, and thus the selectedPerson property is still null. It will be filled during the Apply model values phase, later on in the life cycle.

Scope change as a solution?


The easiest solution is to change the scope of the personView managed bean to view scope. The bean is first initialized when the ajax call is executing for the row selection. And the bean is kept alive for the click on the button and thus the selectedPerson value has still a value and the button is processed as we expect.

But view scope is a kind of session scope. Surely it has his advantages and usages but a bean with a view scope is stored in the session of the user.  Additional processing is required to remove the bean from the session storage when the user navigates to another view.  So in terms of processing time and server memory consumption, a view scoped bean is worse then a session bean.

So my first reflex is always to use beans on a request scope.  When the situations justifies to use another, longer scope, I will use it of course. So can we fix the above described problem by keeping the personView on request scope?  Yes we can.

The binding attribute.


The solution lies in the binding attribute that each JSF component has. Using this attribute can lead also to some problems (maybe this can be the inspiration for another blog item) but here it makes the selection button responsive again.

The binding attribute gives you to opportunity to have a reference in your backing bean to the java object instance that is used on the component tree representation of your view. It allows programmatic access and changes to the component. So JSF view fragment becomes this:
<p:dataTable value="#{personListView.personList}" var="person" selectionMode="single"
                     selection="#{personView.selectedPerson}" rowKey="#{person.id}">
   <p:ajax event="rowSelect" update="editBtn" listener="#{personView.enableEditBtn}"/>
   <p:column headerText="first name">
      ...
   </p:column>
   <f:facet name="footer">
      <p:commandButton ajax="false" value="Edit" action="person.jsf" binding="#{personView.button}"
                       actionListener="#{personView.checkPerson}" id="editBtn"
                       disabled="#{empty personView.selectedPerson}"/>
   </f:facet>
</p:dataTable>

It has 2 additions; the binding attribute on the commandButton and the listener attribute on the ajax rowSelect tag.

The binding refers to a property in the request scopes personView bean of type HtmlCommanfButton. During the first phase of the life cycle, Restore view Phase, it gets the reference to the java object instance on the component tree for the selection button.
 
private HtmlCommandButton button;

// Setter and getter


The listener attribute of the ajax component is bound to a method in the personView managed bean that manipulates the button programmatically.
 
public void enableEditBtn() {
   button.setDisabled(false);
}
 

When we now click on a record in the data table, the enableEditBtn method is also executed. It 'overrides' the EL expression #{empty personView.seelctedPerson} with the constant value false. It makes the button enabled on the screen when it gets re-rendered but the most important thing of all, the actionListener and navigation are executed since the value of the disabled property is no longer true during the Apply request values phase.

Conclusion

When a JSF commandButton is initially disabled, there are situations that it doesn't respond to a user click when it is re-enabled. Changing the scope of the bean in the EL expression of the disabled button can solve it. But view scope isn't good for the performance of your application. The use of the binding attribute can be the solution.