You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@beehive.apache.org by Apache Wiki <wi...@apache.org> on 2005/12/19 23:13:48 UTC

[Beehive Wiki] Update of "design/PortletScoping" by RichFeit

Dear Wiki user,

You have subscribed to a wiki page or wiki category on "Beehive Wiki" for change notification.

The following page has been changed by RichFeit:
http://wiki.apache.org/beehive/design/PortletScoping

The comment on the change is:
Moving into a /design subdirectory

New page:
= Portlet Scoping =

== Introduction ==
As underlying support for running NetUI applications within portlets (originally within BEA's proprietary Portal), the idea of ''scoping'' is present throughout the NetUI framework.  There are two kinds of scoping:
 * ''Session Scoping'':  Simple.  It means that things like page flow instances are stored in the session under "scoped" names, which are the usual internal attribute names with a Scope ID (portlet ID) prefix.
 * ''Request Scoping'':  More complicated underneath, but simple in concept: prefix all request parameter and attribute names with the Scope ID (portlet ID).

== Session Scoping ==
=== Details ===
All getting/setting of session-scoped attributes for page flow, page flow nesting stack, shared flow, and JSF backing bean instances uses {{{ScopedServletUtils.getScopedSessionAttrName()}}} to construct the actual session attribute name.  By default, this API returns the attribute name unmodified.  If either of the following two conditions are true, then the Scope ID is prefixed to the attribute name:
  * The current request is a {{{ScopedRequest}}}.  {{{ScopedRequest}}} is a wrapper over {{{HttpServletRequest}}} that we use when running inside a portal (more details below).
  * A special request parameter ({{{ScopedServletUtils.SCOPE_ID_PARAM}}}) exists.  This is used to support multiple active page flows in the session, usually for multiple browser frames/windows.  It's important to note that the scoping mechanism is exactly the same as what it is for {{{ScopedRequest}}}/Portal, so a browser window using this mechanism could talk to the page flow from a ''portlet'' with the same Scope ID.

=== Issues and Future Directions ===
If NetUI changes to use a NetUI-controlled ''context object'' for things like request/session access, then this context object can be smart about whether to create scoped attribute names.  It would eliminate the need for calling {{{ScopedServletUtils.getScopedSessionAttrName()}}} whenever setting a managed session attribute.

== Request Scoping ==
=== URL Rewriting ===
A portal framework can register a ''URL rewriter'' that will prefix request parameters with the current Scope ID in any page rendered using NetUI tags.  This makes the names unique, and targeted to a particular portlet.  Some examples (assuming a portlet ID of "portletA":
 * {{{<input type="text" name="portletAfoo">}}} instead of {{{<input type="text" name="foo">}}}
 * {{{<a href="/myApp/someurl?portletAbar=someValue}}} instead of {{{<a href="/myApp/someurl?bar=someValue}}}

The URL rewriter may rewrite the URL in other ways, but this is its main function as it relates to scoping.

=== ScopedRequest ===
A portal framework can create a {{{ScopedRequest}}} wrapper around a basic {{{HttpServletRequest}}} in order to decode scoped requests (normally requests that come from a page rewritten with a URL rewriter, above).  The {{{ScopedRequest}}} does two main things:
  * keeps track of a Scope ID (portlet ID)
  * ''filters'' request parameters and attributes to return only ones that have the desired Scope ID.  In the URL rewriter examples above, a {{{ScopedRequest}}} with Scope ID of "portletA" would see request parameters "foo" and "bar", respectively.

In general, a {{{ScopedRequest}}} would be created/initialized by a portal framework in framework code (or even in a Servlet Filter) before NetUI ever sees the request.

=== Issues and Future Directions ===
A {{{URLRewriter}}} should be responsible for '''decoding''' scoped parameter names, in addition to its current responsibility for rewriting parameter names to be scoped.  Currently, our {{{ScopedRequest}}} (and the rest of the scoping package) assumes that scoping is done by prefixing the Scope ID to the name.  A portal URL rewriter currently has to know this implicitly.

A portal framework is in charge of persisting scoped request attributes as necessary for use during "refresh" requests (requests that involve user interaction with a different portlet than the one being refreshed).  In the case where the NetUI framework knows an attribute ''should'' be persisted, it should use some API for marking a request attribute with a persist-hint, which the portal framework could use as it pleases.  Probably the best thing would be to have this information (which attributes have the persist-hint set) retrievable on {{{ScopedRequest}}}.

Related to the above, there are some attributes that should be persisted, but which are large.  An example is a Struts {{{ModuleConfig}}}, which can be reconstructed based on the module path.  NetUI could offer a {{{ReconstructibleAttribute}}} abstract base class that {{{ScopedRequest}}} would be aware of:

{{{
    public abstract class ReconstructibleAttribute
    {
        private transient Object attribute;
        private Object key;
        public void dropAttribute() {
            attribute = null;
        }
        public abstract void reconstructAttribute(RequestContext context);
    }
}}}

When persisting attributes, a portal framework could call {{{dropAttribute()}}} on anything that derives from {{{ReconstructibleAttribute}}}.  {{{ScopedRequest}}} could automatically call {{{reconstructAttribute()}}} as necessary when reading attributes.

== Response Scoping ==
NetUI also includes a {{{ScopedResponse}}} wrapper that a portal framework would use to wrap the actual response.  The default implementation doesn't do much beyond keeping track of whether a redirect happened, and of errors/status-messages/cookies.

== Public APIs Related to Scoping ==
The most commonly-used APIs are in {{{ScopedServletUtils}}}:
    {{{getOuterRequest}}}: Gets the outer request, which is the one that the {{{ScopedRequest}}} is wrapping.  If there is no {{{ScopedRequest}}}, just returns the given request.
    {{{unwrapRequest}}}: Badly named.  Unwraps until it finds a {{{ScopedRequest}}}, which it returns.  If there is none, returns null.
    {{{getScopedRequest}}}: Used by a portal framework to create or look up a cached {{{ScopedRequest}}}, based on the original request and a Scope ID.
    {{{getScopedResponse}}}: Used by a portal framework to create or look up a cached {{{ScopedResponse}}}, based on the original response and a {{{ScopedRequest}}}.