[jsr362-experts:] Thoughts about parameters
- From: Martin Scott Nicklous <
- Subject: [jsr362-experts:] Thoughts about parameters
- Date: Wed, 24 Jul 2013 09:57:44 +0200
I mentioned in the call yesterday that I had been thinking about portlet
parameter handling. I'd like to jot down some of my thoughts and get your
feedback on them.
JSR 286 parameters are string-based and modeled after servlet parameters.
Public parameters are managed by the container and can be shared with other
portlets. By "managed by the container" I mean that they can be ignored by
the portlet programmer until they are needed and they won't go away. They
can be read, set, and removed when needed, but they don't have to be
explicitly tacked on to each URL or response in order to have them
available. Private parameters describe the portlet private state. These
parameters are "managed by the portlet" in that the programmer must
explicitly set the private render parameters on each URL (with the
exception of the Resource URL) and response, otherwise they disappear. As
a portlet programmer you are forced to think of to private parameters as
being attached to a StateAwareResponse or to a URL. Programmers have to
spend considerable effort in handling the portlet state represented by the
private render parameters. If in some special case you forget to set a
parameter on the response or when creating a URL, "poof" it's gone, even if
it was present on the request being processed. I find this to be
counter-intuitive and error-prone.
In fact, a very common portlet programming error is to forget to copy or
set the parameters during request processing. One experienced and very
excellent portlet programmer related to me that the following scenario
catches him again and again: You write a portlet, obtain some input from
the user, get some data from a back-end somewhere, setting your parameters
all the way. Life is good. Then you add eventing. In some abstruse case
during event processing, you forget to copy the parameters from the event
request to the event response. "Poof" the parameters are gone, and your
portlet breaks. Since it only happens during interaction with other
portlets and even then only under certain circumstances, the bug can be
really difficult to find.
Another very counter-intuitive characteristic of the JSR 286 API is setting
or removing a public render parameter on an action URL. Action URLs and
render URLs are both modeled as PortletURL objects, so the methods for
manipulating the public render parameters are available on both action URLs
and render URLs. However, if you try to remove a public render parameter
from an action URL - nothing happens. You don't get an error, but the
public render parameter stays put - it is not affected. If you try to set a
public render parameter to a new value, again you don't get an error.
However, rather than changing the public render parameter, you get a
private parameter with the same name as the public render parameter so that
when the URL is activated, you have both a private parameter AND a public
parameter with the same name but probably different values. I can't imagine
many cases where that would be the expected behavior. Again, for me this
is completely counter-intuitive. And it can lead to the type of problem
where a programmer says, "Well, I KNOW I set it, I can see it right here in
the trace from my processAction method", however, no other portlet using
that shared parameter can see the value change. Call up <your company> -
public render parameters is broken!
(The parameter behavior on the ResourceURL is very, very double-plus
counter-intuitive - both the private and the public parameters are treated
like the public parameters on the action URL - maybe we should fix that,
too, but that is not the main subject of this post).
We need to change how we think about parameters. It's good to have
string-based parameters as we do now. It's good to have both public and
private render parameters. However, ALL parameters should be "managed by
the container" in the sense described above. The basic idea would be that
once the parameters are set, they stay set, until the portlet explicitly
changes them. And that would hold for private as well as for public render
That would have the following implications for version 3 portlets (the
container would still have to managed version 2 portlets in the same manner
as they are currently handled).
* For the StateAwareResponse it would look like the private parameters
would be "automatically copied" from the request to the response, just as
the public render parameters are "automatically copied" under the version 2
model. This would happen for both the action request and the event request.
We could add a container runtime parameter to turn the automatic copying
off for people who like it the old way, or to allow version 2 portlets to
be migrated more easily to the version 3 model.
* For URL creation, it might be best to leave the current createActionURL()
and createRenderURL() methods unchanged and add new methods something like
createActionURL(boolean copyParameters) and createRenderURL(boolean
copyParameters) that allow the current parameter settings to be
automatically copied to the new URLs.
* And to get rid of my pet peeve - I think with regards to parameter
handling, the action URL should be handled the same as the render URL.
I think that these changes would make writing portlets much easier and more
intuitive. I wonder if you think so, too ....