Affects Version/s: 1.3.0-beta3
Fix Version/s: None
Supporting statefull detached/popup pages from a Portlet is tricky business.
With JSR-168, Portlet API 1.0, this is completely impossible without using portal specific extensions.
In JSR-168, a portlet is only allowed to write out content the render phase.
That content is, potentially together with content produced by other portlets, aggregated by the portal in one single page before it is send out to the client.
Furthermore, as each render or action request may change portlet navigational state maintained by the portal, even if you would create a page with a single portlet, interacting with that portlet through the popup window can cause navigational state changes which is not reflected on the page containing the original portlet initiating the popup page (window). So, after coming back to that portlet window, interacting with it might result in unexpected/invalid behavior.
But, with JSR-286, Portlet API 2.0, this now changes
The new Portlet ResourceURL and serveResource phase will allow "directly" calling a portlet, albeit still only through the portal, and has full control over the response/content it produces.
Furthermore, navigational state changes are not allowed/possible during serverResource thus there is less danger of inconsistent state between the two browser windows. Note: you are allowed to changes server state like the session or the portlet preferences.
Using the preliminary, pre-JSR-286 support for ResourceURLs from Apache Portals Bridges (
PB-65) which I already integrated in wicket, rendering detached/popup pages is possible to implement.
Although, because JSR-286 nor container implementations are available yet, at runtime we still need a portal specific implementation for handling ResourceURLs.
But, for Wicket there is another problem: how to detect when a page url is going to be used for opening a popup page?
There are many different ways to create an url, but in a servlet environment, it doesn't matter if it will be used as popup or not: they are just the same.
All (most all) Wicket url generation is manged through RequestCycle.urlFor(..) calls which delegates this in the end to the RequestEncodingStrategy.encode(..).
For Wicket portlet-support, the only sensible location to "intercept" page url generation is within the RequestEncodingStrategy.encode(..) method, see
WICKET-655, but there it is currently impossible to detect what the usage of the url will be (popup or non-popup).
To solve this there are 3 different solutions AFAICS:
a) Add a boolean popup parameter to to RequestEncodingStrategry.encode(...)
This solution will have a very big cascading effect as this means adding this parameter to all RequestCycle urlFor methods, and from there to Component and all its children which override or call that method. Of course, the current method signatures should also be preserved with a default value false, but still ...
b) Find some other way to pass the popup target information through the calling chain, like setting some transient property on the (page) Component.
This won't be possible with one a single solution though as there are so many different ways urlFor can be called.
c) Add a "hacky" temporary flag in RequestCycle only valid for the duration of one urlFor method call, indicating if the next call is intended for a popup or not.
Yes, I know this isn't going to win a coding beauty contest either, but neither will the above alternatives.
As solution c) is at least the least intrusive, I've chosen to implemented that for now.
I'm definitely all ears if someone can come up with: "hey dude, that's what I call mighty stupid! Why not use this much easier and cleaner solution..."