Showing posts with label JSF. Show all posts
Showing posts with label JSF. Show all posts

Tuesday, 12 January 2016

Lambda expression as JSF actionListener

Introduction

Although there is no official version of JSF which supports Java 8, there are various application servers that run on it today. And thus can we use some Java 8 features today.

I'll show you in this blog post an example of using a lambda expression as an action listener. And more specific where we have a custom composite component with multiple actions sources.

And although I'm not a fan of the binding property, probably due to the issues I had with it during the early days of JSF 1.x, it is a nice use case for Lambda expressions.

Custom composite component

Short recap of what a custom composite component is.
If you have on multiple screens a set of components used in the same manner, you can create a custom component for it. The markup doesn't need to be exactly the same on all those pages or linked to the same managed bean, because you can specify parameters.

That way you can also 'build' your screens using different reusable blocks and you have a very modular approach comparable with using Java methods to increase readability.

And creating those custom composite components is very easy in JSF 2.x. Create JSF file with the definition of your component (interface  and implementation parts) in a special specific folder and you are ready to use it due to the convention principles in place.
Have a search on the internet on this topic and you find various examples how you can do it.

Assigning an action listener to a button within your custom composite components seems for some people a bit more difficult but using the actionSource attribute of the composite component namespace makes it very easy.

<ui:component xmlns="http://www.w3.org/1999/xhtml"
              xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
              xmlns:cc="http://xmlns.jcp.org/jsf/composite"
              xmlns:p="http://primefaces.org/ui">

    <cc:interface>
        <cc:actionSource name="submitListener" targets="submitBtn"/>
        <cc:actionSource name="cancelListener" targets="cancelBtn"/>
    </cc:interface>
    <cc:implementation>
        <div>
            Some multiple button component 
            <p:commandButton id="submitBtn" value="Submit"/>
            <p:commandButton id="cancelBtn" value="Cancel" immediate="true"/>
        </div>
    </cc:implementation>
</ui:component>


The above example defines a custom composite component where we have 2 buttons and each of them, we can assign a different actionListener.

ActionListener

ActionListener is a JSF interface defined for those implementations which want to respond on the click on a button (for example there are other components which also generate the same event) on the screen.

The interface has just one method, as you can see;
/**
 * Invoked when an action occurs.
 * @param e the event to be processed
 */
public void actionPerformed(ActionEvent e);

This makes it an ideal candidate to use it in combination with Lambda expressions since we have a functional interface.

So the following lambda expression
e -> System.out.println("Save clicked");

is valid implementation for the actionListener interface and thus we can assign such methods to the button(s).

Binding the actionListener implementation

As a said in the introduction, with the binding attribute, it is very easy to 'bind' an implementation of the ActionListener interface to the button. 

<adv:multiple>
    <f:actionListener for="submitListener" binding="#{cityBean.save}"/>
    <f:actionListener for="cancelListener" binding="#{cityBean.cancel}"/>
</adv:multiple>
In the above example we retrieve the instance to which the listener is bound to, with a method result. The java code can be as follows.

@Modelpublic class CityBean {

   private ActionListener save;
   private ActionListener cancel;

   @PostConstruct
   public void init() {
      save = e -> System.out.println("Save clicked");
      cancel = e -> System.out.println("Cancel clicked");
   }

   public void performSearch() {
      System.out.println("Searching ");
   }

   public ActionListener getSave() {
      return save;
   }

   public ActionListener getCancel() {
      return cancel;
   }

}
As you can see, this is a nice,clean usage of lambda expressions where we have multiple actionListener targets in the custom composite component.

Conclusion

Using a lambda expression for an ActionListener implementation make your code much more readable and reduces the boilerplate in those cases where you need multiple actionSources for a custom composite component.

Enjoy Java 8 and Java EE!



Thursday, 5 November 2015

Show application version on your JSF screens

Introduction

Sometimes it can be handy to show the application version on the screen of your application. 
Users get used to have access to this information and it can also ease the communication in a lot of situations. Especially when you are releasing very often.
  • Users can see when a new version is available
  • When issues are reported, it is easier to indicate in which version it occurred
  • Refer to the version where a certain feature appeared in the application in the documentation.

In this text, I'll show you how you can create this version automatically with Maven and read and show it on a JSF screen.

Create version

Maven has support to put a timestamp and the project version in the manifest file. This file is  specifically designed to contain this kind of information (among other things).
You can configure the maven-war-plugin (this functionality is also available in the maven-jar-plugin) to put additional info in the manifest.mf file which is created by default.

<plugin>
   <artifactId>maven-war-plugin</artifactId>
   <version>2.4</version>
   <configuration>
      <failOnMissingWebXml>false</failOnMissingWebXml>
      <archive>
         <manifestEntries>
            <version>${project.version}</version>
            <buildTime>${maven.build.timestamp}</buildTime>
         </manifestEntries>
      </archive>
   </configuration>
   <goals>
      <goal>manifest</goal>
   </goals>
</plugin>

The format in which the timestamp is placed in the file can be environment specific, like local settings of your computer.
Therefor you should always define the timestamp format in the pom.xml file so that you have repeatable packaging between different environments.

The format can be specified by using a property like this.

<properties>
   <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
   <maven.build.timestamp.format>yyyyMMdd-HHmm</maven.build.timestamp.format>
</properties>

The result is that we have 2 entries in the manifest file, for example
buildTime: 20151104-1123
version: 1.0.2

Read the info

Reading the information is nothing specific for Java EE of JSF.  We will use the Properties file functionality to read the file.
A lot of people use the '=' sign as delimiter between the key and value pair in the file, but the semicolon (:) is also a default delimiter as you can read from this javadoc.

So if we have a reference to the manifest file, we can feed it in the load method of the properties class and we have the version and build time (as a string).
For this info, we can use the ServletContext and the resource loading which is available.

private Properties loadManifestFile() {
    ServletContext servletContext = (ServletContext) FacesContext
            .getCurrentInstance().getExternalContext().getContext(); 
      Properties prop = new Properties();
      try {
        InputStream resourceAsStream = servletContext.getResourceAsStream("/META-INF/MANIFEST.MF");  
         if (resourceAsStream != null) {
            prop.load(resourceAsStream);        }
    } catch (IOException e) {
        unexpectedTechnicalExceptionController.handleUnexpectedException(e); 
   }
    return prop;
}

As you can see in the above code, we need a reference to the FacesContext, so we need this code to be executed in the JSF context, like a @PostConstruct method of @ApplicationScoped CDI bean which keeps the version and build time, ready to shown it on a JSF screen.

Show the info

Showing the information is of course very specific for each application. And you would probably show it differently in each version.
In my last application, I showed the information  in a floating div in the bottom left area of the screen. That way, it was always visible.

<div style="position: fixed; bottom: 0; right: 0;">
   #{infoBean.version} (#{infoBean.buildTime})
</div>

Conclusion

With some easy configuration of maven, a simple read from the manifest file with the Properties class, we are able to show the version and built time of your application on screen. 
This can help in the good communication with your end users.
And of course, other information can be stored and used in a similar way.
Enjoy.


Monday, 27 July 2015

Temporarily disable or conditional executing of PrimeFaces AJAX calls

Introduction

In JSF 2.0, the AJAX functionality is standardised in the specification and can be used in a consistent way between JSF implementations and component libraries like PrimeFaces.
With the addition of new functionality, new usage patterns become a habit. But new usages also brings more advanced scenarios with their own issues.

The situation I want to discuss today, is where you have the need for some partial screen update with AJAX but which you don't want in all situations. The conditional aspect which I referred to in the title of the text.

Problem description


Suppose you have the following screen area:


It contains the following elements from left to right
* A field to enter an existing code. When the end user leaves the field, the code is looked up.
* A second, read only field or label, where the description of the code is placed when it is an existing one.
* A button, which is only available when the first field doesn't contain an existing code and lets you add a new one.

Within the JSF page, the structure looks something like this.

<h:panelGroup id="codeArea">
    Code :
    <p:inputText value="#{codeBean.code}id="code">
        <p:ajax event="blur" listener="#{codeBean.onBlurCode}" update="codeArea"/>
    </p:inputText>
    <p:inputText value="#{codeBean.codeDescription}" disabled="true" placeholder="description"/>
    <p:commandButton icon="fa fa-plus-circle" actionListener="#{codeBean.addCode}" update="codeArea" disabled="#{empty codeBean.description}"/>
</h:panelGroup>

With the ajax tag within the input field, we can perform the partial screen update when we leave the input field. We need to update the complete group as the button needs to become disabled as we enter an existing code.

Conditional executing

This construct works perfectly when you tab out of the input field.  The blur event triggers the AJAX execution and the server side code checks if the code exists. Due to the partial screen update the button becomes disabled when the code doesn't exists or enabled when the code isn't found.

But there is a scenario which fails; when the focus is in the input field and we click on the command button.  You will found out that the click on the button is ignored.  

If we inspect what is happening in the network console of the browser; we see that there is an AJAX request to the server which corresponds to the blur event of the field.  But there is no request which corresponds to the click on the button.
This is because the blur event replaced the DOM element in the browser with another, for the end user identical component. So the click is on an element which no longer exist on the screen after the AJAX  completes.

So how can we solve this? Luckily PrimeFaces uses JQuery on the client side.  So when we could disable the onblur event execution in the case when we click on the button, we have a solution. And the good thing is that we can achieve this, quite easily.

The mousedown event is executed before the blur event. This is can bee seen by the following testing code. (thanks to mudassir)

So by adding the following code:

onmousedown="$(PrimeFaces.escapeClientId('frm:code')).off();"

We can remove all event handlers from the input field, and thus the click is executed.

Conclusion

Making the AJAX functionality can be easily achieved within PrimeFaces with the help of JQuery which is already available in the browser? In this text I showed you how you can disable the blur event in the case when you click a specific button but it will be active in other scenarios.



Monday, 4 May 2015

Introducing Jerry and Valerie

Or the JSF renderer interceptor and the (bean) validation extension.

A major new version is available under the Atbash umbrella: http://www.atbash.be/2018/02/26/a-renderer-interceptor-concept-for-java-serverfaces/

Introduction

The first opensource project where I ever posted a change to, was Apache MyFaces Extension Validation, ExtVal in short. It is a framework for having a validation platform with many great features.

But the last few years, I only used a few specific parts of the platform with some of my own extensions.
Since ExtVal was designed for JSF 1.x and later extended to JSF 2.x, I decided to recreate it.  CDI the cornerstone in every aspect of the version and geared towards JSF 2.x and Bean Validation.
But if you like, you can still create all the features from ExtVal in the new version.

Jerry

One of the features of ExtVal that I use a lot, is the JSF Renderer interceptor around which the complete platform is built. The idea is very simple, during registration of the renderers at startup, they are wrapped with a custom class.
This allows to have a before and after of all the important steps of a rendering; decode phase, encode begin, encode children, encode end and converted value.

This very simple concept has many possibilities. For example, you want to indicate every required input field with a special background colour.  These are the step that you need to do

1- Add Jerry to your maven project
<dependency>
   <groupId>be.rubus.web</groupId>
   <artifactId>jerry</artifactId>
   <version>${jerry.version}</version>
</dependency>

2- Define a ComponentInitializer, this is a specific renderer interceptor which can perform some actions in the before encode begin step.

@ApplicationScoped
public class RequiredInitializer implements ComponentInitializer {
   @Override
   public void configureComponent(FacesContext facesContext, UIComponent uiComponent, Map<String, Object> metaData) {
      InputText inputText = (InputText) uiComponent;

      if (inputText.isRequired()) {
         String style = inputText.getStyle();
         if (style == null) {
            style = "";
         }
         inputText.setStyle(style + " background-color: #B04A4A;");

      }
   }

   @Override
   public boolean isSupportedComponent(UIComponent uiComponent) {
      return uiComponent instanceof InputText;
   }
}

The above code adds the background colour to every PrimeFaces input text field.  This class is found using CDI mechanisms, and that is the reason why we have to annotate it with ApplicationScoped.  But it gives us also the possibility to inject any other CDI bean into this initialiser method.

Jerry is used in the Java EE declarative permission security framework Octopus to handle the security on the JSF component level.

Valerie

Another thing which I always find a bit annoying is that you should redefine the maximum length of a field at the JSF component level, although you have defined a Bean validation constraint on the java property.

For example, suppose you have a property for the name of a person

@Size(max = 50)
private String name;

When you have a JSF input field component pointing to to this property

<h:inputText value="#{personBean.name}"/>

then, the size restriction is checked during the validation phase. But why do you let the user input a longer then allowed value? So you have to use the size attribute on the h:inputText but it should go automatically, no.

That is where Valerie comes into the scene, another extraction from the ExtVal framework. 

side note; How the names are chosen. Jerry was chosen as it sounds phonetic like JRI (JSF Renderer Interceptor) So, I needed a female name to go alone with it and it should be related to validation.

So how can we have in the above example the size restriction from the bean validation property size on the screen?

The only thing you need to do is add the Valerie dependency to your project.  

<dependency>
   <groupId>be.rubus.web</groupId>
   <artifactId>valerie</artifactId>
   <version>${valerie.version}</version>
</dependency>

One renderer interceptor is responsible for retrieving and interpretation of the annotation information. A component initialiser then modifies the JSF component by specifying the size attribute from that info.

Conclusion

Jerry and Valerie are 2 small libraries extracted from the ExtVal framework.  They are centered around the JSF renderer interceptor and the extraction of bean validation information and gives you some handy features which makes your application easier to maintain.

The current version is 0.2, but since they have a firm solid history within ExtVal and are already used in a few projects, they are ready to use.  In the near future there will be some small features added and some more testing will be done before a first final version will be released.

They can be used in any Java EE 6 or Java EE 7 server (or servlet container if JSF, CDI and bean validation are present) and compiled with Java SE 6.

The basic documentation of the project can be found here and feedback, issues, feature request are welcome at the issue tracker on gitHub.

Maven artefacts are available in the C4J OpenSource Nexus 
<url>http://nexus-osc4j.rhcloud.com/content/groups/public/</url>
Have fun with it.

Tuesday, 23 December 2014

My 3 Christmas wishes for Java EE Security

Introduction

Recently, there was the start up of the new Java EE Security JSR, JSR 375. For me, it is one of the areas, together with Integration testing, where the Java EE specs can be improved greatly.
Over the years, I did a few large scale enterprise applications and those applications could benefit a lot if some of the following things would be standardised or available out of the box.

This blog post describes my needs and/or proposals that I have for Security from the JavaSever Faces view technology angle. And I know, there is much more that is vital for a good security implementation.

LoginModule

LoginModule is an interface, part of the Java Authentication and Authorization Service (JAAS), some of the security basics of Java SE.

The LoginModule is responsible for taking the credentials (most of the time, they are the username and the password of the user) and verify it against some kind of store (database, LDAP, file, etc …)

The issue is that JAAS is only standardised within Java SE, so there is nothing specified how the Application servers should integrate it.

Glassfish for instance requires that you extend a custom class (which implements LoginModule of course) and WebSphere has his own extension of the Subject (the class which represents the end user) class.
And all the application servers have heir own way of defining the LoginModule within the configuration.

So why not standardise this, by introducing a new annotation like @Realm, which defines the name of the realm and the LoginModule to use for it.

This name can then be defined in the web.xml file and that is basically all the things you need to do.

Permission Based security

In almost all the cases, you only hear about role based access models as security means.  I have done several, quit large enterprise projects and I never used the role based model.
Simply because it is not flexibel enough. Because any change in what the user role is allowed to do, results in recompilation of the code.  And I’m not even talking about the nightmare it is to properly test the role based security model over and over.

Permission based security on the other hand is much simpler. Every action the end user can perform or any data piece which needs to be displayed conditionally, gets a permission assigned. And the end user needs this permission to be able to perform the action or view the data.
The main task is now the configuration which permissions are assigned to a user.  But this is done outside the application, no recompilation is need as this info can be stored in a database for instance. There can be many permissions, I once had a set of almost 1000 permissions, so you can group them before you assign the groups to users.

The main difference between permissions and roles is that a permission is undividable and guards a single piece of the application.  A role is linked to the end user and what the end user is allowed to do can change over time.

So I would like to see the term Permission appear in the specifications and how they are linked or mapped to users and roles.
And the classic role base model also fits in this model.  Just replace the term Permission with Role and assign the Permission/Role to multiple areas of application.

Declarative security for JSF Components

This is specific for JavaServer Faces, which is the view technology I use most of the time. When data or a button shouldn’t be shown to the end user, the rendered attribute is used in most cases


But rendered attribute can contain also business logic rules that determine the visibility of the button.
But security is a cross cutting concern and should thus be separated from the other logic. So the ideal situation is that you use tags to indicate which permission is needed to render the button.

Some years ago, I prototyped already such functionality.  You can read more on that topic in this blog text.

 

The framework allows you to define some voters that determine if a certain user is allowed to see the button based on a permission.

Beginning of this year, I integrated this feature in a larger security framework called Octopus.  There it is combined with Apache Shiro to have declarative security for JSF components, URL protection and secured methods of EJB and CDI beans.  See this text for some more info.

But enough promotion for my work, the JSF tags for security are very handy and very readable. But it needs something like a Renderer interceptor and although possible today, it should be described in the specs and promoted as the preferred way for security.

OAuth2

Oke, I had already my 3 wishes, but what about other authentication ways which doesn’t fit into the LoginModule concept like OAuth2.  Social media is everywhere and thus also OAuth2 security providers which we can and should use.

JSR 375

This JSR is a good start to modernise the security specification of Java EE.  But I’m also sceptic.  As said, security is a cross cutting concern and therefor can be seen separately from the rest.
But many aspects are specific for the view technology, like the JSF security tags of Octopus.  And will those kind of interaction be tackled by this JSR?

But since the JSR process is much more open nowadays, lets provide them with usecases we need.  This was my contribution to that process.




Sunday, 5 January 2014

Client Side Validation example of PrimeFaces

Introduction

With the latest version of PrimeFaces, version 4, you have the possibility to perform some validations on the client, by the browser.
This features doesn’t replace the standard JSF validation on the server side but is an addition to it.  The server side validation makes sure that any data posted to the server is valid before it is processed any further. The client side validation is there to inform user faster of data problems.
By default, all the standard validations like required fields, minimum and maximum values, string lengths and so on are available.  But you can also create the JavaScript version of your custom JSF validation.
The feature is very good explained in the PrimeFaces users guide. This posts describes the steps that I have done to make a Visa card validation on the client side.

Configuration

In order to activate the feature, you need to put the following content parameter in the web.xml file.
    <context-param>
        <param-name>primefaces.CLIENT_SIDE_VALIDATION</param-name>
        <param-value>true</param-value>
    </context-param>

Now, your application is ready to use the client side validation feature. And whenever you want to make use of it, you just have to specify the attribute validateClient on the commandButton tag for example.

The standard validations known by PrimeFaces are then performed on the fields in the form.  Any validation error is shown by the messages or growl tag which is also available in the form.

Make sure you read the PrimeFaces users guide to know all the requirements and usages.  The most import ones are


  • Put a messages or growl tag within the form. others are not yet discovered. 
  • Severity attribute of these tags is ignored.
  • Invalid fields are marked by a red border but associated label isn’t colored

These shortcomings will be removed in the next release of the framework.

Custom validation

It is also possible to have a client side validation variant of your custom validations.  Therefor I created an example, a visa card number validation.

You start by creating a standard JSF validator, so a class that implements Validator interface.  For the Client Side Validation feature of PrimeFaces, you have to implement also the org.primefaces.validate.ClientValidator interface.

It contains 2 methods, getValidatorId which defines the name of the JavaScript function that implements the validation on the client side. If the JavaScript function needs some values defined by the validator (like the minimum value for the range validation) you have to return it by the getMetadata method.

This is the java side of the solution
@FacesValidator("custom.VisaCardCheck")
public class VisaCardValidator implements Validator, ClientValidator {
    @Override
    public Map<String, Object> getMetadata() {
       return null;  // No metadata required on client side
    }

    @Override
    public String getValidatorId() {
        return "custom.VisaCardCheck";
    }

    @Override
    public void validate(FacesContext someFacesContext, UIComponent someUIComponent, Object o) throws
            ValidatorException {
        ...
    }
}


The JavaScript must be available on the page where we like to use it, the code is shown below.
PrimeFaces.validator['custom.VisaCardCheck'] = {
    reverse: function (s) {
        var o = '';
        for (var i = s.length - 1; i >= 0; i--)
            o += s[i];
        return o;
    },
    throwError: function(detail) {
        throw {
            summary: 'Validation Error',
            detail: detail
        }
    },
    validate: function (element, value) {
        var reg = /^\d+$/,
            digits = this.reverse(value).substring(1).split(""),
            sum = 0;
        if (!value.match(reg)) {
            this.throwError("Not all digits");
        }
        if (value.length < 13 || value.length > 16) {
            this.throwError("Length invalid");
        }
        if (value.charAt(0) != '4') {
            this.throwError("Wrong start digit");
        }
        for (var i = 0; i < digits.length; i++) {
            if (i%2 == 0) {
                digits[i] = digits[i] * 2;
                if (digits[i] > 9) {
                    digits[i] = digits[i] - 9
                }
            }
            sum += parseInt(digits[i]);
        }
        if (value.charAt(value.length - 1) != (sum % 10)) {
            this.throwError("Check digit validation fails");
        }
    }
};


The important thing here is that the name of the validator in the JavaScript object, custom.VisaCardCheck in my case, is the same as the value returned by the getValidatorId method of the JSF validator.

Usage of the validator at the JSF level is the same as usual.
<p:inputText id="myValue" value="#{dataBean.myValue}" required="true" validator="custom.VisaCardCheck" />

Conclusion


With the Client Side Validation framework, we can inform the user faster about issues with data, without the need to go to the server.

The best thing is that it integrates very well with JSF and it is hard to tell if the message came from the client side validation or from the server side.

The default validations are already available in their javaScript counterpart, also if you use BeanValidation. When you create a custom validation, you have to write the JavaScript yourself, of course.

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.

Wednesday, 9 November 2011

Custom reference resolver tutorial : creating a grammar


Introduction

In my previous blog entry, I presented an example on the new reference resolver add-on of ExtVal. It was able to read from a property from a MBean and use that value for validation.
As it was designed as a Reference Resolver, you had to specify a parameter at the cross field validation annotation of ExtVal where you needed the resolver. This is not friendly if you have designed some kind of resolver that you would use on a lot of locations.  Therefore the add-on has foreseen the option to create a new Reference Grammar. In this text I'll explain you how you can convert a reference resolver to a reference grammar.

Coding it

Basically, there are 2 small differences between a Reference Resolver and a Reference Grammar and you can use almost the same code in both situations. You only need to structure it a bit different.  Besides the registration of your grammar with the ExtVal add-on, see further, you should extend from the AbstractReferenceGrammar class. This class has a type parameter that needs to be specified.  In our case, it is just a simple object that holds the bean and property name. If you remember from my previous text, we invented a new grammar 'mbean@property' and the object just holds the 2 parts of the grammar (before and after the @-sign).
Your grammar has to implement 4 methods, so the empty grammar looks like this

@InvocationOrder(100)
public class MBeanGrammar extends AbstractReferenceGrammar
{

    @Override
    public void initGrammar()
    {
    }

    @Override
    protected boolean targetNotCompatibleWithGrammar(String targetValue)
    {
    }

    @Override
    protected MBeanGrammarData determineReference(String targetValue, MetaDataEntry metadataEntry)
    {
    }

    @Override
    public ReferencedValue resolveReference(MBeanGrammarData targetValue, MetaDataEntry metadataEntry)
    {
    }
}

where the (MBeanGrammarData object holds the bean and property name the user specified.

The initGrammar method is called when you register the grammar with the add-on.  You can use this interception point to do any initialization required to have a proper function of the grammar.  In our case we grab a reference to the MBean server we will be using for the resolving of the value.  Important thing to remember is that this method is just executed once.
When the ExtVal add-on encounters an annotation related to the cross field validation feature, it will ask to all the grammars if it can handle the specified reference.  Our implementation should return false for the targetNotCompatibleWithGrammar method when it contains the @-sign (our grammar can handle the reference) and true when we don't know it (like some EL-reference).  The first grammar that says that it can handle, will be used by the add-on.  How is the order determined? Grammars can be annotated with @InvocationOrder and the value you specify determines the order.  The default grammars (JavaBean and EL) have values of 950 and 1000.  So when we specify a value of 100, our new grammar is the first to be contacted to resolve the reference.
If we have a reference that we should handle, the add-on calls the determineReference method next. There we have the opportunity to parse the reference according to the grammar.  In our case it is just splitting the reference around the @-sign and put it into the MBeanGrammarData instance.

As a last step, the resolveReference method is called where we get the MBeanGrammarData instance we prepared in the previous step and we need to resolve the reference.  In our case we contact the MBean server, ask for the correct bean and extract the value of the property.  That value is wrapped nicely into the ReferencedValue and returned.

So the main difference is that the reference resolver contained all the logic in the resolveReference method and in the grammar version, we have the functionality split into 4 methods. You can find the code here.

Configuration

This is an additional step we need to do to integrate our grammar in the ExtVal add-on.  With the following 2 lines, placed in a startupListener, the Reference Grammar is registered and ready to use.

 ExtValContext extValContext = ExtValContext.getContext();
        extValContext.getModuleConfiguration(AdvancedCrossValidationAddonConfiguration.class).addReferenceGrammar(new MBeanGrammar());


Testing it

This version behaves exactly the same as our previous example, so I refer to the other text on how you can test it.

Conclusion

As easy it was to create a Reference Resolver, as easy it is to create a reference Grammar.  The grammar has the advantage that you don’t have to specify a parameter at the cross field validation annotation. But on the other side, if you only using it on a few locations, the add-on will ask your code for every reference, if you understand it.  So based on the concrete situation you have to decide what you need, a resolver or a reference.