Introduction
We encountered an inconsistency between MyFaces and Mojarra that I was surprised was not addressed a long time ago. The issue has to do with the ordinal values assigned to theFacesMessage.Severity
. Mojarra uses a zero(0) based level of Severity
and MyFaces uses a one(1) based Severity
level. As a result, we were trying to use a <rich:notifyMessages/>
component with, as you can expect, some unexpected results.One of the items I always preach is to code to the API. If you code to the API, then you can switch out the implementations should the need occur. This is a best practice, but can be undermined by little subtleties like this. Please don't get me wrong, both Mojarra and MyFaces are great implementations. It is these fine differences that should be consistent that we need to work on to make sure that we are consistent, and that the dream is real; switching implementations will not be painful.
RichFaces is a good framework, and folks like Brian Leathem take personal pride in making it a good implementation to run on top of either Mojarra, or MyFaces. I was really surprised by my discovery of an issue with
<rich:notifyMessages/>
since the <rich:messages/>
works correctly. The problem is focused on the ordinal value I mentioned. I opened a JIRA issue with both MyFaces and RichFaces around the ordinal issue. Please see the references below for details.However, I needed a solution not just report an issue. So I came up with a 10¢ solution based on some work I did at home last night, and a great suggestion by one of my team. I wanted to publish an article, a complaint, and a solution that others may need. These work arounds tend to become more common when doing cross-platform development, and sharing is paramount.
Problem
The RichFaces<rich:notifyMessages/>
does not work consistently across JSF implementations based on Severity
ordinal values.
Solution
Implement a method that checks theFacesMessage.Severity
ordinal values, and change icons and CSS to correct the differences between implementations. We can accomplish this using CSS, and Expression Language (EL) combined with a page backing bean. In this case, I use a simple page backing bean, but it could be converted to a custom EL function.
The code for this example can be found here: myfaces-rf-example
default.css
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 | *.rf-ntf-cnt *.rf-ntf-ico { /* * This accounts for MyFaces Severity Fatal ordinal is 4 and does not work with RichFaces. */ display : block ; background-image : url ( '#{indexBean.iconURL(4)}' ); } *.rf-ntf-sum *.rf-ntf-det { /* * This accounts for MyFaces Severity Fatal ordinal is 4 and does not work with RichFaces. */ color : black !important ; } *.rf-ntf-inf *.rf-ntf-ico { display : block ; color : black !important ; background-image : url ( '#{indexBean.iconURL(0)}' ); } *.rf-ntf-wrn *.rf-ntf-ico{ display : block ; color : black !important ; background-image : url ( '#{indexBean.iconURL(1)}' ); } *.rf-ntf-wrn{ color : black !important ; } *.rf-ntf-err *.rf-ntf-ico { display : block ; color : black !important ; background-image : url ( '#{indexBean.iconURL(2)}' ); } *.rf-ntf-err{ color : black !important ; } *.rf-ntf-ftl *.rf-ntf-ico { display : block ; color : black !important ; background-image : url ( '#{indexBean.iconURL(3)}' ); } *.rf-ntf-ftl{ color : black !important ; } |
iconURL()
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | /** * This method is used in the CSS file to alter the values of the icon URLs * based on whether the underlying {@link FacesMessage#SEVERITY_INFO} value * starts with 0 (Mojarra), or a 1 (MyFaces). * * @param level The {@link FacesMessage.Severity#getOrdinal()) to be evaluated. * @return a RichFaces resource URL for the appropriate notification. */ public String iconURL( int level) { if (FacesMessage.SEVERITY_INFO.getOrdinal() == 0 ) { ++level; } switch (level) { case 1 : { //INFO return "/myfaces-rf-example/faces/javax.faces.resource/info.png?ln=org.richfaces" ; } case 2 : { // WARN return "/myfaces-rf-example/faces/javax.faces.resource/warning.png?ln=org.richfaces" ; } case 3 : { //ERROR return "/myfaces-rf-example/faces/javax.faces.resource/error.png?ln=org.richfaces" ; } case 4 : { //FATAL return "/myfaces-rf-example/faces/javax.faces.resource/fatal.png?ln=org.richfaces" ; } default : { //INFO return "/myfaces-rf-example/faces/javax.faces.resource/info.png?ln=org.richfaces" ; } } } |