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]