Description
In JSF 2.2, the viewAction component has a phase attribute which a user can specify what JSF lifecycle phase the action is executed in.
For example:
---------
<f:metadata>
<f:viewAction action="#
" phase="PROCESS_VALIDATIONS"/>
</f:metadata>
---------
In the backing bean, the checkPhase method simply gets the current phase we are in like this:
PhaseId phase = FacesContext.getCurrentInstance().getCurrentPhaseId();
The issue is that this is always called during the INVOKE_APPLICATION phase regardless of what is specified in the phase attribute.
I tested this scenario with Mojarra 2.2.10 and it works as I expect it to...meaning it gets called in the phase that is specified in the phase attribute.
In an initial investigation, I think the problem is in the javax.faces.component.UIViewAction class in the queueEvent method.
Before going in to the if/else block below, the event.getPhaseId will have the value that was set on the phase attribute in the JSF page. However, this block of code will change it to INVOKE_APPLICATION, which is the default phase the viewAction is called in:
public void queueEvent(FacesEvent event)
{
if (event != null && event instanceof ActionEvent)
{
UIComponent component = event.getComponent();
if (component instanceof ActionSource)
{
if (((ActionSource)component).isImmediate())
else
{ event.setPhaseId(PhaseId.INVOKE_APPLICATION); } }
}
super.queueEvent(event);
}
I believe the fix should change the else block to leave the phaseId on the event object as is if it one of the valid values:
APPLY_REQUEST_VALUES
PROCESS_VALIDATION
UPDATE_MODEL_VALUES
INVOKE_APPLICATION
Note: RESTORE_VIEW and RENDER_RESPONSE are not valid values for the phase attribute of viewAction.
Note2: INVOKE_APPLICATION is the default phase a viewAction is called, so that needs to be taken in to consideration as well (e.g. if some invalid value specified in the phase attribute)