Hi,
There is a problem in JSF when more than one window are opened
in an application.
There are only a maximum number of NUMBER_OF_VIEWS_IN_SESSION view
states saved at one moment (when server side state saving is enabled).
If you have 2 windows opened and you navigate on one of them for
NUMBER_OF_VIEWS_IN_SESSION times, you will lose the other window's
state.
I've been facing this problem while developing a project so I've
implemented a solution for it.
The solution is having a number of view states saved for each
opened window at one moment.
For determining when a new window (frame) is opened, the target of the
submitting component (or its enclosing form) is used.
This is obtained in the HtmlLinkRendererBase's and
HtmlButtonRendererBase's decode methods and it is set in the
RequestMap.
Using the "submitted" target, the JspStateManagerImpl figures out
whether a new frame was opened.
If so, a new frame id is generated.
In the renderResponse phase, the frameId is encoded in the
javax.faces.ViewState field
and is used along with the viewId to save the state in a
SerializedViewCollection.
In the restore view phase the frameId is decoded from the
javax.faces.ViewState field
and is used along with the viewId to restore the corresponding state
from the SerializedViewCollection.
In SerializedViewCollection instead of a list of recently used
views, now a list is kept for each frameId.
The following context params are defined for configuring this.
NUMBER_OF_FRAMES_IN_SESSION (max frames stored)
NUMBER_OF_VIEWS_IN_FRAME (max views stored per frame)
These replace the old: NUMBER_OF_VIEWS_IN_SESSION context-param.
What is your opinion on this solution?
Of course this solution only works with MyFaces Tomahawk's
commandLink and commandButton.
Ohter component sets that do not use a custom stateManager might use
this feature
if they will just modify the renderers of command components to set
the target attribute in the requestMap.
An extra feature would be to enable this for outputLinks (plain
old links) and for JS (openWindow).
The solution for this is quite simple, just add a GET parameter named
'target' and set the value the same as the target attribute.
In the JspStateManagerImpl this value is obtained from the
requestParameterMap and used the same as in the other case.
Do you think this would be useful too?
Regards,
Nicu