TLDR: RichFaces reached a richly merited end of life in June 2016. It was a poorly managed catastrophe of a project that deserved no better.
Noting here that the official migration guide is no better than about 30% complete. As a metric on that, I wrote an XSLT stylesheet of 378 lines in 2011 based on the migration guide. I then left the project in abeyance until June 2015 and based on further investigations and getting it working it is already up to 1090 lines. Bearing in mind that any XSLT stylesheet has some overhead, 378/1090 = about 35%.
After you've done what it says in the Migration Guide:
Open the TLD/VLD generated documentation for each component you use in adjacent browser tabs, one for each version, and compare them carefully. There are dozens of undocumented changes in attribute names and purposes, and some attributes have been moved from parent containers to child containers.
There are also important things that have just been arbitrarily removed, such as rich:page
and rich:layout.
I'll provide a list of some of the extra things I have discovered at the end of this.
You will then be confronted with the unpleasant realization that they have also changed large numbers of their own style class names, so if you've defined styles for any of those in your own style sheet you have yet more work to do.
You will also discover that their claim that you can define your own style classes and specify them in the rich components to implement your own styles is simply untrue. Your style classes are applied at a containing level but in many cases such as table cells they have seen fit to define fonts etc at the table cell level, where the only way you can override them is by redefining their cells styles by name.
You also have to ensure that your stylesheet is included after the Rich Faces ones. In 3.3 this was automatic, as theirs were included first. Theirs are now included last, so you have to use h:outputStylesheet
and do so as late as possible, to ensure it is generated afterwards.
I used an XSLT transform to implement the Migration Guide and accomplish 1-2 above. It presently has over 1000 lines and I have by no means finished yet. Why they couldn't have provided such a thing themselves is a mystery to me.
Why it was deemed necessary to make such major changes between release 3 and 4 is another and deeper mystery. It is a very poorly managed product. I won't be migrating it again, or deploying it anew.
EDIT Undocumented changes I have found (using XPath syntax for brevity):
a4j:status
The documentation is vague on the point, but the for=
attribute has been removed: it now operates by default within the nearest parent a4j:region
, unless there are tie-ups to specific widgets via the status=
attributes. So if you have multiples within the same region they will now all fire.
If you want it to apply to a specific widget via status=
you have to change the corresponding a4j:status/@id
to an @name
attribute.
After you fix all that, it still doesn't work:
- An
a4j:status
with @for
(removed) attribute won't stop
- with an
@name
attribute and no @id
won't do anything
- and with both
@name
and @id
won't stop.
rich:column/@breakBefore
now breakRowBefore
rich:page
removed.
rich:layout
removed.
rich:column/@sortOrder
now must be lowercase.
rich:dropDownMenu/@value
now rich:dropDownMenu/@label
rich:dropDownMenu/@direction
and rich:dropDownMenu/@jointPoint
The values for these have been changed from {top-left, top-right, bottom-left, bottom-right}
and {tl, tr, bl, br}
respectively to {topLeft, topRight, bottomLeft, bottomRight}
.
rich:contextMenu/@submitMode
, rich:dropDownMenu/@submitMode
, rich:menuItem/@submitMode
These are now all now rich:<whatever>/@mode
, and the value "none"
needs to be changed to "client"
.
rich:isUserInRole
This has simply ceased to work, at least for me, with Mojarra 2.2.08 and EL 2.2. Fortunately with EL 2.2 you don't need it any more and can use request.isUserInRole(...)
.
rich:menuGroup/@value
now rich:menuGroup/@label
.
rich:tab/@label
now rich:tab/@header
.
rich:tab/f:facet/@name[.='label']
now rich:tab/f:facet/@name[.='header']
.
rich:tabPanel/@activeTabClass
, rich:tabPanel/@contentStyle
, rich:tabPanel/@disabledTabClass
, rich:tabPanel/@inactiveTabClass
, rich:tabPanel/@tabClass
Now tabActiveHeaderClass
, tabContentClass
, tabDisabledHeaderClass
, tabHeaderClass
, tabInactiveHeaderClass
, tabContentClass
respectively.
rich:tree/@adviseNodeOpened
This has been removed and rich:treeNode/@expanded
added. This is not well documented: it must be an EL, e.g. "#{true}"
, not "true"
, and it can be a bean property of the tree node, e.g. "#{node.expanded}"
, or of any other bean; must be a boolean. (The same is true of the new rich:collapsibleSubTable/@expanded
attribute.)
rich:tree/@nodeFace
now rich:tree/@nodeType
.
rich:tree/@switchType
now rich:tree/@toggleType
and possibly rich:tree/@selectionType
.
rich:tree/@treeNodeVar
now var
, or possibly just removed.
rich:treeNodesAdaptor
now rich:treeModelAdaptor,
and no longer handles arrays, nodesets, ... or anything not a Map
or Iterable
. It has also lost its var
attribute, which as far as I can see breaks it completely for nested use. The only var
attribute now available is that of the ancestor rich:tree
. So for example if you wanted the parent node and the current child node at the same time, they are simply not available. This change entails either a non-trivial rewrite, or the following kludge.
OLD:
<rich:tree>
<rich:treeNodesAdapter var="vm_host">
<rich:treeNode .../>
<rich:treeNodesAdapter var="vm_guest">
<rich:treeNode .../>
</rich:treeNodesAdapter>
</rich:treeNodesAdapter>
</rich:tree>
NEW:
<rich:tree ... var="node"> <!-- Add a 'var' attribute -->
<rich:treeModelAdapter>
<c:set var="vm_host" value="#{node}"/>
<rich:treeNode .../>
<rich:treeModelAdapter>
<c:set var="vm_guest" value="#{node}"/>
<rich:treeNode .../>
</rich:treeModelAdapter>
</rich:treeModelAdapter>
</rich:tree>
You could also use <ui:param>
instead of <c:set>
.
The conversion process is made a lot more difficult by RichFaces' refusal to error-check attribute names. You can continue to use the old names but they just don't work.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…