I've been investigating ways to synchronize content across multiple
portlets.  As someone else needed this information, I've written it up and
am posting this summary to the list.  Comments welcome.

Design Objective:
I would like to have a portlet that presents a list of objects.  When a user
selects an object from the list, the portlet would display the object
detail.  Additionally, other portlets also visible on the page would change
their content to show information related to the object whose detail is
being displayed.

For example, a portlet might display a list of inventory items stored in a
given warehouse.  When the user selects one of the items, the portlet would
show the item description.  Simultaneously, another portlet on the page
would show overall sales volumes for all items in the warehouse, but would
switch to volumes of just the selected item when a single item was being
viewed.

Identified Approaches:
1) Have the selection URL for an item place a well known entry in the query
data.
2) Use both action= and eventSubmit_doBla style events simultaneously.
3) Create a custom layout class.
4) Create a custom Page class.

Analysis:
1) Have the selection URL for an item place a well known entry in the query
data.
This is, by far, the easiest approach.  Basically, the idea is that the
"selection URL" would include some type of object identifier that was known
to all portlets as part of the query data.  Upon spying this identifier,
each portlet would tailor it's output to the selected object.  To some
extent, this assumes that the object resides in some type of store, and that
the portlets would fetch the details of the object from the store at render
time.
+ Easy
+ Works regardless of portlet render order
+ Isolated from changes to core Jetspeed code (unless Jetspeed starts using
your well-known tag)
- Potential for way too many store accesses: imagine each portlet going to
the store (likely an RDBMS) at render time: one page could easily force 5 or
10 DB accesses.  (You could get around this by creating a caching 'broker'
service from which each portlet attempted to load the requested object.
This diminished the 'easy' point, though.)
- No ability to pre-fetch other, related information from the DB, though
again a broker service could help with this.
- Depending on the generation of the object identifiers, this could be a
potential information leak exploitable by malicious parties.

2) Use both action= and eventSubmit_doBla style events simultaneously.
The rational behind this is that the action= events appear to be executed by
the Page prior to any portlet rendering.  This would allow the
context/request to be populated with the appropriate information.
-- Doesn't work: JspPortletAction (and presumably VelocityPortletAction) use
the following logic:

Is there an "action" parameter?
  Yes:
    a) Call the specified action
    b) Populate context/request (calls doPerform)
  No:
    a) Call executeEvents, which looks for eventSubmit_* and executes those
    b) Populate context/request (doPerform)

? You might get away with just doing this in an action= class, but you'd get
into some complexity around tracking which portlet should be showing item
detail.  This might work, but I stopped investigating at this point.

3) Create a custom layout class
This option is motivated by the fact that the current rendering order is
done by order of appearance, regardless of associated actions.  Thus, if the
action (eventSubmit_*) is responsible for caching/etc. of the selected
object, it may not get called until after some portlets have been rendered,
defeating the whole point.  You could work around this if you guaranteed
that the portlet with the selected action was rendered first.

+ This would provide a central place for accessing a store, ensuring that
the store was only hit once per request.
- Begins to introduce lots of complexity around portlet rendering that has
nothing to do with the actions.
- Easy to do this improperly, blending store-access logic to layout logic
- Almost certainly will be difficult to maintain across Jetspeed versions
- Requires a very large brain
-- I'm pretty sure that one of other ways would be better, so this isn't
really worth further investigation.

4) Create a custom Page class
The Turbine model provides hooks for the Page to tinker with the request in
the processing pipeline.  Specifically, methods in the Page class are called
three times:
1) Prior to executing any actions
2) After executing actions, but before the screen is rendered
3) After everything's been done

You could use 1 or 2 to look for a specific query tag, and do your object
fetching/caching etc., priming the request (or context) with the appropriate
stuff.

+ Clearly performs the object fetching in a single place, optimizing store
access
+ Provides a nice place to do general pre-layout request priming
+ Seems pretty safe from Jetspeed changes (You'd actually inherit from
Jetspeed's JetspeedJspPage or JetspeedVelocityPage, as appropriate for your
environment.)
- You'd almost certainly still want to do the broker service mentioned in
(1) so as to isolate your fetching code from your request priming code,
adding additional complexity.
- Has the same potential for information leaking as (1)


1 and 4 have potential, depending on the other things you're doing.  Feel
free to comment/discuss.

-- Michael



---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to