Issue Details (XML | Word | Printable)

Key: SHALE-371
Type: Bug Bug
Status: Resolved Resolved
Resolution: Fixed
Priority: Major Major
Assignee: Craig McClanahan
Reporter: Stan Zapryanov
Votes: 0
Watchers: 0
Operations

If you were logged in you would be able to see more operations.
Shale

prerender() executes for ViewController not rendered when navigating to page/bean not implementing ViewController

Created: 22/Dec/06 12:01 AM   Updated: 23/Jan/07 04:40 PM
Component/s: View
Affects Version/s: 1.0.4-SNAPSHOT
Fix Version/s: 1.0.4

Environment: Windows XP Pro, Tomcat 5.5, JDK 1.5.0_04, MyFaces

Flags: Important


 Description  « Hide
Not sure if this is a bug but it looks like it.

When navigating to a view (JSF) not implementing the ViewHandler framework from a ViewController t(JSF/bean) that does, currently the prerender() method gets executed on the viewcontroller that you are leaving (that won't get rendered).

My guess is that currently the old FacesConstants.VIEW_NAME_RENDERED entry remains in the request map even though you are not rendering that viewconroller, and that triggers the execution of prerender().

Here is a suggested fix that appears to correct the problem described but I woudn't know if it may brake other stuff.. :

In the setupViewController() method of the ViewViewHandler class:


            vc = vr.resolveVariable(context, viewName);
            if (vc == null) {
                if (log.isDebugEnabled()) {
                    log.debug(messages.getMessage("view.noViewController",
                                                  new Object[] { viewId, viewName }));

                }
// ---- START OF PROPOSED FIX
             context.getExternalContext().getRequestMap() .remove(FacesConstants.VIEW_NAME_RENDERED);
//------END OF FIX-------
                return;
            }

Hope all makes sense and was helpful.

Cheers!



 All   Comments   Change History   Subversion Commits      Sort Order: Ascending order - Click to sort in descending order
Craig McClanahan added a comment - 22/Dec/06 02:40 AM
This is indeed a bug ... the view controller interface promises to call prerender() only for the view that will actually be rendered, so calling it on the "from" view in this case is definitely wrong. On the surface, your fix looks good ... I'll test it before committing. This fix is needed for 1.0.4, but should not take too long.

Craig McClanahan added a comment - 22/Dec/06 05:25 AM
Hmm ... what version of Shale are you seeing these problems with? I just added test cases to the shale-test-view and shale-test-tiger applications for validating the correct behavior of this condition, and I cannot reproduce the behavior you report -- for me, prerender() is *not* being called for the "from" page.

Stan Zapryanov added a comment - 23/Dec/06 07:33 AM
I observed the previously described behavior using shale-view.jar and shale-core.jar taken from the shale-framework-20061220.zip that I downloaded from the nightly builds folder.

Looking at the code I see that whenever vr.resolveVariable(context, viewName)==null then the old viewName remains in the map because the method returns without setting a new viewName. Note that the existing code nevertheless sets the new viewName even if vc !=null and vc is NOT instance of ViewController.

If I have to redefine the 'bug' I would say:
Navigating to a viewName for which the ViewControllerMapper returned mapping (name) is not a valid JSF backing bean name would cause the prerender() to execute on the originating viewcontroller bean.

So it seems the "bug" is observed when the viewControllerMapper returns a viewName for which no backing bean is defined in faces-config.xml, disregarding if that bean is an instance of viewcontroller or not.

Simple scenario that would recreate the bug:
/folder1/bean1.jsp with h:commandLink going to /folder2/bean2.jsp
with only folder1$bean1 backing bean defined in faces-config.xml

In that scenario, 'vc' remains null since no bean is defined/found and the setupViewController method returns with 'folder1$bean1' still in the map.
If folder12$bean2 was defined.. no matter if ViewController or not, the map would be containing 'folder12$bean2' as viewName at the end of the method, and prerender() would not be called on 'folder1$bean1'.

Sorry I didn't get it quite right in my initial analysis. Hopefully this time it should make more sense.

Happy holidays!

Craig McClanahan added a comment - 23/Dec/06 07:52 PM
OK, that makes sense ... and my current test case doesn't cover that combination. I'll dig back in -- thanks for the follow-up details!

Craig McClanahan added a comment - 23/Dec/06 08:58 PM
Stan, your analysis is spot on. I've added test cases (for both shale-test-view and shale-test-tiger) to execute your test case, and added your one-line fix to make it work correctly. This will be available on the 20061224 nightly build, and the upcoming 1.0.4 release. Thanks for the patch, and the patience to get the details through my head :-).