6


Bridge Requirements for
Managing Faces

The majority of the Bridge's control function is implemented by overriding various Faces extension points to translate between the corresponding Faces function and the Portlet model.  

6.1 ExternalContext

The Faces ExternalContext provides the container independent abstraction of the request and response to the Faces runtime environment.  By implementing an ExternalContext, the portlet bridge provides access to the portlet request and response.

The ExternalContext is acquired from the FacesContext.  To provide an ExternalContext implementation the bridge must provide a FacesContext implementation.  A FacesContext is manufactured via a FacesContextFactory [Section 6.5 of JSF 1.2 Specification]. The bridge must use the Faces FactoryFinder to acquire the FacesContextFactory which it then uses to instantiate and acquire a FacesContext.  

6.1.1 FacesContextFactory

The bridge provides an implementation of FacesContextFactory in order to expose its ExternalContext.  This FacesContextFactory must be configured as a service provider in the META-INF/services directory of the Java jar file containing the bridge implementation:

The file META-INF/services/javax.faces.context.FacesContextFactory contains the name of the bridge's concrete FacesContextFactory implementation class[6.1].

The bridge's implementation of the FacesContextFactory must follow the decorator design pattern such that there is a constructor with a single argument of type FacesContextFactory so that the custom implementation receives a reference to the implementation that was previously fulfilling the role. In this way, the custom implementation is able to override just a subset of the functionality (or provide only some additional functionality) and delegate the rest to the existing implementation.

In implementing the getFacesContext method, the bridge must provide its own instance of the FacesContext without delegating if and only if the request is being serviced by a portlet in the portlet container.  Otherwise the bridge must delegate to the previous factory and perform no other action.  

The bridge must not assume that the FacesContext returned by calling getFacesContext is an instanceof its FacesContext implementation class[6.2].   Other Faces subsystems running in the portlet bridge environment are free to introduce their own factory and wrapping implementation as long as they follow the decorator pattern described above.

6.1.2 FacesContext

FacesContext contains all of the per-request state information related to the processing of a single Faces request and the rendering of the corresponding response. It is passed to, and potentially modified by, each phase of the request processing lifecycle.

A FacesContext instance is associated with a particular request at the beginning of request processing, by a call to the getFacesContext() method of the FacesContextFactory instance associated with the current web application. The instance remains active until its release() method is called, after which no further references to this instance are allowed. While a FacesContext instance is active, it must not be referenced from any thread other than the one upon which the servlet container executing this web application utilizes for the processing of this request[nt].

Because there are subtle differences between the servlet and portlet models, its recommended that the bridge's FacesContext implementation not delegate any method implementations.  For each method implemented by the bridge's FacesContext, the implementation must meet all the requirements for that method as defined in the JSF 1.2 specification.  

In addition, the bridge's FacesContext is required to do the following:
  • setViewRoot():

    If the class of the UIViewRoot passed to setViewRoot is annotated with javax.portlet.faces.annotation.PortletNamingContainer then it additionally must set the "X-JAVAX-PORTLET-FACES-NAMESPACED-RESPONSE" portlet response property with a String value of "true".  For further explanation see section 6.6.

6.1.3 ExternalContext Methods

The Faces 1.2 ExternalContext javadoc describes specific behaviors for each method executed in the portlet request context.  By and large these descriptions are complete and accurate.  Section 6.1.3.2 provides these descriptions.  However, a few methods aren't adequately described or are incorrect.  For these the bridge must ignore the existing javadoc and implement the behavior as described in the next section [6.1.3.1].  

6.1.3.1 Methods that deviate from Faces 1.2 Javadoc

The following methods require an implementation that aren't adequately described in the Faces 1.2 ExternalContext javadoc:

6.1.3.2 Methods that conform with Faces 1.2 Javadoc

The following methods require an implementation that are adequately described in the Faces 1.2 ExternalContext javadoc. This includes the implicit requirement that each access to the portlet request or response object be done by using the last request or response object set using the corresponding setRequest() or setResponse() methods or the original objects passed to the constructor if none have been directly set.

6.2 ViewHandler

The Faces ViewHandler is the pluggability mechanism that allows implementations to extend the JavaServer Faces specification to provide their own handling of the activities in the Render Response and Restore View phases of the request processing lifecycle. This allows for implementations to support different response generation technologies, as well as different state saving/restoring approaches.

The bridge is required to provide an implementation of the ViewHandler[nt].  This implementation must be configured in the faces-config.xml file packaged into the bridge's jar file[nt]. The implementation must implement the decorator design pattern described in section 10.4.5 in the JSF 1.2 specification[nt].  

Because configuration is limited to using the faces-config.xml file packaged into the bridge's jar file, ViewHandler order can't be defined if other Faces extensions relying on the same ViewHandler configuration technique exist in the environment.  The bridge implementation must safely cohabit with these other ViewHandlers regardless of precedence order in the particular runtime environment they execute in[nt].  To satisfy this the bridge must delegate to its parent ViewHandler for all methods unless otherwise indicated to do so by a configuration parameter.  For most methods this will be a strict delegation with no pre/post processing of the call.  If pre/post processing is necessary it must be done in a manner that doesn't interfere with the normally processing of the other ViewHandlers in the chain. To facilitate this, implementations are encouraged to subclass javax.faces.application.ViewHandlerWrapper.

Furthermore, where ever the bridge provides bridge specific ViewHandler behavior, it must ensure this behavior is only executed when executing a request via the bridge
[nt].  Because the ViewHandler is a general Faces extension the bridge's ViewHandler methods will be called if the bridge is in this application's classpath regardless of whether the current request has been dispatched through the bridge.

6.2.1 Method Requirements

The following ViewHandler methods must meet specific bridge requirements (i.e. have expected pre/post delegation processing):

6.2.2 Other Methods

The following ViewHandler methods have no specific bridge requirements and hence its expected they will always be delegated.  If a bridge implementation does more then merely delegate if must satisfy the above cohabitation requirements.  This is particularly true for writeState as overriding this commonly interferes with the application developers desired state management.  If getActionURL is modified the bridge must ensure the resulting String it returns is a valid URL.  In particular it can't be an URL derived from a portletResponse.createActionURL().

6.3 StateManager

To properly maintain references to (updated) view state the bridge will likely have to provide its own StateManager in order to override the state writing process allowing it to inspect and preserve (update) the value of the VIEW_STATE_PARAM parameter it manages in its extended bridge scope [5.1.2.2].  For example the bridge can override StateManager.writeState(FacesContext context, Object state):

6.4 Phase Listeners

The bridge must prevent the Faces action phases (ApplyRequestValues, ProcessValidations, UpdateModel, and InvokeApplication) from executing if processing an event or rendering in a restored bridge request scope[6.90, 6.xxx] [5.1.2].  I.e. during either a portlet's EVENT_PHASE or RENDER_PHASE, when the Faces Lifecycle is executed to restore the view, the bridge must ensure the lifecycle falls directly through to render after the view is restored. This is most conveniently supported by implementing a PhaseListener and calling FacesContext.renderResponse() when invoked in the RestoreView phase.

6.5 Expression Language Resolution

Faces relies on the Unified Expression Language architecture to ensure consistent EL evaluation in a JSP page where JSP expressions and Faces expressions can coexist.  During a JSP EL resolution Faces extends the JSP resolvers to process/expose Faces unique variables.  During a Faces EL resolution Faces provides the base resolvers that not only expose the Faces unique variables but also those that the JSP resolvers otherwise have access to during the scope of the page.  In a servlet environment, this ensures evaluation consistency for the same expression whether within a JSP expression or a Faces expression.  However because the EL types are resolved by different resolvers in different contexts when running in a portlet environment evaluation isn't always consistent.  Its important to be aware of the following subtle differences in implicit object evaluation.

6.5.1 Implicit Objects

When running in a JSP context, JSP provides an ELResolver that recognizes and resolves the following implicit objects[6.100]:
applicationScope -> a Map that maps application-scoped attribute names to their values
cookie -> a Map that maps cookie names to a single Cookie object. Cookies are retrieved according to the semantics of HttpServletRequest.getCookies(). 
header -> a Map that maps header names to a single String header value (obtained by calling HttpServletRequest.getHeader(String name))
headerValues -> a Map that maps header names to a String[] of all values for that header (obtained by calling HttpServletRequest.getHeaders(String))
initParam -> a Map that maps context initialization parameter names to their String parameter value (obtained by calling ServletContext.getInitParameter(String name))
pageContext -> the PageContext
pageScope -> a Map that maps page-scoped attribute names to their values
param -> a Map that maps parameter names to a single String parameter value (obtained by calling ServletRequest.getParameter(String name))
paramValues -> Map that maps parameter names to a String[] of all values for that parameter (obtained by calling ServletRequest.getParameterValues(String name))
requestScope -> a Map that maps request-scoped attribute names to their values
sessionScope -> a Map that maps session-scoped attribute names to their values

When the <portlet:defineObjects> tag is used within this JSP page, the following variables are exposed and will be implicitly resolved by this JSP EL resolver[6.100]:

portletConfig: object of type javax.portlet.PortletConfig
actionRequest: object of type javax.portlet.ActionRequest (only accessible in an ActionRequest)
actionResponse: object of type javax.portlet.ActionResponse (only accessible in an ActionRequest)
eventRequest: object of type javax.portlet.EventRequest (only accessible in an EventRequest)
eventResponse: object of type javax.portlet.EventResponse (only accessible in an EventRequest)
renderRequest: object of type javax.portlet.RenderRequest (only accessible in an RenderRequest)
renderResponse: object of type javax.portlet.RenderResponse (only accessible in an RenderRequest)
resourceRequest: object of type javax.portlet.ResourceRequest (only accessible in an ResourceRequest)
resourceResponse: object of type javax.portlet.ResourceResponse (only accessible in an ResourceRequest)
portletSession: current PortletSession object.
portletSessionScope
:  immutable Map containing PortletSession attribute/values at PORTLET_SCOPE.
portletPreferences:  current PortletPreferences object.
portletPreferencesValues: immutable Map containing entries equivalent to PortletPreferences.getMap().

Faces extends this behavior by providing its own ELResolver to recognize and resolve the following implicit objects[6.100]:

facesContext -> the FacesContext for this request
view -> facesContext.getViewRoot()

When running in a Faces context (outside of JSP execution) Faces provides the base implicit object resolver that recognizes and resolves the following implicit objects[6.101]:

application -> externalContext.getContext()
applicationScope -> externalContext.getApplicationMap()
cookie -> externalContext.getRequestCookieMap()
facesContext -> the FacesContext for this request
header -> externalContext.getRequestHeaderMap()
headerValues -> externalContext.getRequestHeaderValuesMap()
initParam -> externalContext.getInitParameterMap()
param -> externalContext.getRequestParameterMap()
paramValues -> externalContext.getRequestParameterValuesMap()
request -> externalContext.getRequest()
requestScope -> externalContext.getRequestScope()
session -> externalContext.getSession()
sessionScope -> externalContext.getSessionMap()
view -> facesContext.getViewRoot()

The primary difference between the ELResolvers used within the JSP context vs outside this context is that the base JSP ELResolver is used to resolve the bulk of the implicit objects and that this resolution is based on the JSPs servlet objects in the page while outside this context these objects are resolved via the ExternalContext.   In a portlet environment, because the JSP ELResolver evaluates based on the servlet objects generated when dispatched from the portlet environment while the JSF ELResolver evaluates based on the ExternalContext, the following difference needs to be considered:

sessionScope:  This Map contains the APPLICATION_SCOPE session attributes if used in JSP EL but PORTLET_SCOPE session attributes if used in Faces EL[6.100, 6.101].


In addition one will note that the Faces implicit object ELResolver recognizes three objects that the JSP Resolver doesn't[6.101]:
application
session

request

In a JSP ELContext one references these objects indirectly via the PageContext[6.100].  I.e.
${pageContext.servletContext}
${pageContext.session}
${pageContext.request}

These differ from the objects returned by the Faces EL Resolver in that[6.101]:
${pageContext.servletContext}: This is an object of type ServletContext while application is an object of type PortletContext.
${pageContext.session}: This is an object of type servlet Session while session is an object of type PortletSession.  The key difference is that PortletSession by default references PORTLET_SCOPE attributes while the servlet Session is a window onto the portlet's APPLICATION_SCOPE.
${pageContext.request}: This is an object of type ServletRequest (through wrapped by the portlet request) while request is an object of type PortletRequest.

6.5.2 Bridge ELResolver

As noted above, when the <portlet:defineObjects> tag is used, the following variables are exposed in the JSP page and will be implicitly resolved by the JSP EL resolver[6.100]:

portletConfig: object of type javax.portlet.PortletConfig
actionRequest: object of type javax.portlet.ActionRequest (only accessible in an ActionRequest)
actionResponse: object of type javax.portlet.ActionResponse (only accessible in an ActionRequest)
eventRequest: object of type javax.portlet.EventRequest (only accessible in an EventRequest)
eventResponse: object of type javax.portlet.EventResponse (only accessible in an EventRequest)
renderRequest: object of type javax.portlet.RenderRequest (only accessible in an RenderRequest)
renderResponse: object of type javax.portlet.RenderResponse (only accessible in an RenderRequest)
resourceRequest: object of type javax.portlet.ResourceRequest (only accessible in an ResourceRequest)
resourceResponse: object of type javax.portlet.ResourceResponse (only accessible in an ResourceRequest)
portletSession: current PortletSession object.
portletSessionScope
:  immutable Map containing PortletSession attribute/values at PORTLET_SCOPE.
portletPreferences:  current PortletPreferences object.
portletPreferencesValues: immutable Map containing entries equivalent to PortletPreferences.getMap().

The bridge must provide a corresponding Faces EL resolver that recognizes these variable names and resolves them to the same object as the JSP resolver[6.101].  In addition, the bridge must not resolve these variables outside of a Faces expression[6.100].  Note:  The mechanism Faces provides for registering a EL resolver causes the EL resolver to be inserted into the resolution chain for both Faces expressions and JSP expressions.  For the above objects, the bridge's EL resolver must delegate resolution to the JSP resolver within JSP expressions while resolving them within Faces expressions.

Because JSP EL evaluation and Faces EL evaluation are handled by different resolvers, the following differences are noted:
portletSessionScope:  This is an immutable Map when referenced in a JSP expression but a mutable Map when referenced in a Faces expression.

6.5.2.1 Additional Implicit Object Support for Portlets

The bridge's ELResolver must additionally recognize and resolve identically  the following EL object references regardless of whether its evaluating in a JSP or Faces expression[6.100, 6.101]:

httpSessionScope:  mutable Map containing PortletSession attribute/values at APPLICATION_SCOPE.
mutablePortletPreferencesValues: mutable Map of type Map<String, javax.portlet.faces.preference.Preference>.  This  EL variable provides read/write access to each  portlet preference.

6.5.2.2 ELResolver Requirements

The bridge's ELResolver must be added through configuration within its faces-config.xml.  e.g.
<el-resolver>
     javax.portlet.faces.el.PortletELResolver
</el-resolver>


The ELResolver must be implemented as follows[6.100, 6.101]:

ELResolver method implementation requirements
getValue If running in a non-portlet request or base is non-null return null.
If evaluating a JSP expression (nonFaces expression) and property is either portletConfig, renderRequest, or renderResponse, return null.
If base is null and property is null, throw PropertyNotFoundException.
If none of the above and base is null and property is a String equal to one of the above names, call setPropertyResolved(true) on
the argument ELContext and return result, where property and result are as follows:


EL object name result
portletConfig portletConfig object (recommended implementation is to place the portletConfig object on the ELContext so can pull it here).
actionRequest If within an ActionRequest then ExternalContext.getRequest() otherwise throw an ELException.
actionResponse If within an ActionRequest then ExternalContext.getResponse() otherwise throw an ELException.
eventRequest If within an EventRequest then ExternalContext.getRequest() otherwise throw an ELException.
eventResponse If within an EventRequest then ExternalContext.getResponse() otherwise throw an ELException.
renderRequest If within an RenderRequest then ExternalContext.getRequest() otherwise throw an ELException
renderResponse If within an RenderRequest then ExternalContext.getResponse() otherwise throw an ELException.
resourceRequest If within an ResourceRequest then ExternalContext.getRequest() otherwise throw an ELException.
resourceResponse If within an ResourceRequest then ExternalContext.getResponse() otherwise throw an ELException.
portletSession ExternalContext.getSession()
portletSessionScope ExternalContext.getSessionMap()
httpSessionScope an internally constructed Map containing those portlet session attributes at APPLICATION_SCOPE.
portletPreferences ExternalContext.getRequest()).getPreferences()
portletPreferencesValues ExternalContext.getRequest()).getPreferences().getMap()
mutablePortletPreferencesValues An internally constructed Map <String, javax.portlet.faces.preference.Preference>. There is one entry per portlet preference. The key is the preference name.  The value is an object representing a single portlet preference (as defined by this interface). Entries may not be added or deleted but and entry can be changed.


If base is null, and property does not match one of the above property names, return null.
getType If running in a non-portlet request or base is non-null, return null.
If base is null and property is null, throw PropertyNotFoundException.
If base is null and property is a String equal to any of the above names, call setPropertyResolved(true) on the argument ELContext and return null to indicate that no types are accepted to setValue() for these attributes.
Otherwise, null;
setValue If running in a non-portlet request or base is non-null, return null.
If base is null and property is null, throw PropertyNotFoundException.
If base is null and property is a String equal to any of the above names throw javax.el.PropertyNotWriteableException, since these objects are read-only.
isReadOnly If running in a non-portlet request or base is non-null, return null.
If base is null and property is null, throw PropertyNotFoundException.
If base is null and property is a String equal to any of the above names call setPropertyResolved(true) on the argument ELContext and return true.

getFeatureDescriptors
If base is non-null, return null.
If base is null, return an Iterator containing java.beans.FeatureDescriptor instances, one for each of the above names. It is required that all of these FeatureDescriptor instances set Boolean.TRUE as the value of the ELResolver.RESOLVABLE_AT_DESIGN_TIME attribute. For the name and short of FeatureDescriptor, return the EL object name. The appropriate Class must be stored as the value of the ELResolver.TYPE attribute as follows:
EL object name ELResolver.TYPE value
portletConfig javax.portlet.PortletConfig.class
actionRequest javax.portlet.ActionRequest.class
actionResponse javax.portlet.ActionResponse.class
eventRequest javax.portlet.EventRequest.class
eventResponse javax.portlet.EventResponse.class
renderRequest javax.portlet.RenderRequest.class
renderResponse javax.portlet.RenderResponse.class
resourceRequest javax.portlet.ResourceRequest.class
resourceResponse javax.portlet.ResourceResponse.class
portletSession javax.portlet.PortletSession.class
portletSessionScope Map.class
httpSessionScope Map.class
portletPreferences javax.portlet.PortletPreferences.class
portletPreferencesValues Map.class
mutablePortletPreferencesValues Map.class

 
The shortDescription must be a suitable description depending on the implementation. The expert and hidden properties must be false. The preferred property must be true.
getCommonPropertyType
If base is non-null, return null.
If base is null and return String.class

6.5.2.3 The javax.portlet.faces.preference.Preference interface

The mutablePortletPreferencesValues EL object allows one to read and update a portlet preference via EL.  It relies on the bridge defined  javax.portlet.faces.preference.Preference interface which allows one to expose each portlet preference as an individual object making operations on portlet preferences EL accessible.  Consult the javax.portlet.faces.preference.Preference javadoc for specific descriptions and requirements of objects implementing this interface.  In general there is a corresponding method for each operation in javax.portlet.Preferences that can be done on a specific preference.   For example, a preference named "title" managed by  the javax.portlet.Preferences object could have its value accessed using its corresponding javax.portlet.faces.preference.Preference instance via title.PrefObj.getValue() rather than the typical preferences.getValue("title").  Equivalent EL access would be: "#{mutablePortletPreferencesValues['title'].value".

Though operations performed on javax.portlet.faces.preference.Preference objects are immediately passed through to the underlying portletPreferences object, because the portletPreferences object requires an explicit commit to preserve these changes, developers must take care to finalize changes by calling portletPreferences.store() directly before the request ends.  Typically this is done in the clients ActionHandler executed during the InvokeApplication phase.

6.6 Namespacing

Portlets are components that are aggregated by another application into a response page.  As such a portlet is responsible for namespacing its markup to ensure its names don't collide with other parts of the aggregated page even when that aggregated page contains additional instances of this portlet.  Traditionally, because the Java Portlet standard assumes the aggregated page isolates each portlet in a manner that allows discrete forms,  namespacing is only required for global names such as javascript functions and variables. Unfortunately, many of today's Faces renderkits rely on this type of client side javascript necessitating namespacing when run in the portlet environment.

Additionally, with the emergence of consumer environments based on JSF and .NET in which such forms are collapsed into a a single all encompassing page form, the issue of namespacing form fields has emerged.  Though from the standards perspective such consumers still have the burden of parsing and transforming the portlet markup to work in the single form environment, the ability for consumers to do this is restricted by both its needs to return a response to the user quickly and the complexity of locating (javascript) references to field names. Portlets, therefore, though not required, are encouraged to namespace not only their global (client) references but also their form fields as well.  


Faces supports a notion of namespacing elements in its view tree which in turn impacts form field names and renderkit resources such as its javascript names.  A namespace is introduced using a concept called a NamingContainer.  When Faces needs to construct a name it ascends the view tree looking for the closest parent that implements NamingContainer.  If it finds one this parent gets an opportunity to return a namespace that will be incorporated into the name.

Though structurally supportive, Faces however doesn't inherently provide proper portlet namespacing.  The bridge needs to introduce this support. This is done by returning a UIViewRoot from ViewHandler.createView()that implements NamingContainer in a manner whereby the generated container name is constructed in part by using the unique namespace Id of the portlet. More specifically, a UIViewRoot with the javax.portlet.faces.annotation.PortletNamingContainer annotation must implement getContainerClientId() to return a String containing (at least in part) the portlet's namespace Id, if and only if, called during a portlet request[6.91].  The namespace Id used in processing getContainerClientId() must be consistent for the lifetime of the view (across save and restore)[6.92].  Because getContainerClientId() can be called during any portlet lifecycle phase (action or render)[6.93], care should be taken in implementing this support to ensure such consistency as Portlet 1.0 containers only expose the portlet's namespace Id during the render phase and hence ExternalContext.encodeNamespace() throws an exception if called during a portlet action request.

The convenience class javax.portlet.faces.PortletNamingContainerUIViewRoot
[6.94] is provided to simplify adding portlet namespacing for Faces extensions (and for internal bridge usage).  This class can either be used directly or subclassed. The class is annotated with the javax.portlet.faces.annotation.PortletNamingContainer annotation[6.95] ensuring the bridge will recognize this UIViewRoot as one that implements the portlet namespacing behavior.   It implements getContainerClientId() to meet the above requirements[6.96].  In addition its returns getContainerClientId()null for non-portlet requests.  This ensures the class can be used by the bridge as a replacement for the standard javax.faces.component.UIViewRoot  because it ensures that non-portlet behavior runs unchanged, without NamingContainer function.  

As indicated, annotating the UIViewRoot class with javax.portlet.faces.annotation.PortletNamingContainer allows the bridge's FacesContext to detect that the response will be portlet namespaced. To signal this behavior to the consumer, FacesContext.setViewRoot() sets the "X-JAVAX-PORTLET-FACES-NAMESPACED-RESPONSE" response property with a value of "true"
[nt]. Consumers needing to do response parsing to meet its namespacing requirements (e.g. when inserting the response into a single overall page form) can use the existence of this property as an indication that the form fields in the portlet response have already been properly namespaced and hence need not be fixed up as part of the form parsing process.

6.7 Supporting isPostback() during RENDER_PHASE

When rendering, Faces depends on distinguishing between renders that follow action processing within the same request and renders that do not. This is determined by calling ResponseStateManager.isPostback().  Because portlet renders occur in distinct requests from actions, the state Faces depends on to make this determination isn't naturally present.  As discussed in section 5.1.2 the bridge is required to ensure the existence and/or absence of such state within its render phase in order to ensure proper execution of isPostback(). Specifically, the bridge is required to always preserve the ResponseStateManager.VIEW_STATE_PARAM parameter in each bridge request scope.  This is done at the at the end of the ACTION_PHASE and EVENT_PHASE phase.  Furthermore it must restore this request parameter at the beginning of each RENDER_PHASE phase that corresponds to this bridge request scope such that a call to ExternalContext.getRequestParameterMap().get(ResponseStateManager.VIEW_STATE_PARAM) returns the restored value[6.97]. Finally, when its able to restore this parameter the bridge must also set the request attribute javax.portlet.faces.isPostback with a Boolean object whose value is Boolean.TRUE[6.98].  This allows alternative isPostback() implementations that do not rely on the existence of the ResponseStateManager.VIEW_STATE_PARAM to recognize they are running in a postback situation.


6.8 Supporting PreDestroy Annotated Methods

Faces requires that all managed beans be given the opportunity to clean themselves up when they are being removed from one of the three container scopes (application, session, request).  The function is managed via annotations and injection.  A managed bean with one or more public no-argument void return methods annotated with javax.annotation.PreDestroy will be called when either the object is removed from scope or the scope terminates.  

When running in the bridge, the lifetime of the application and session scopes aren't modified but the request scope is.  The bridge implements an extended request scope called the bridge request scope. This scope preserves managed beans across physical requests ensuring that applications written in a style where request scoped managed beans are used to maintain state between the Faces action and render lifecycles will function properly in the portlet's multi-request lifecycle.  However, because bridge request scope data is transferred into the portlet request scope when processing a request, special handling is required by managed beans utilizing the annotation to avoid releasing the bean prematurely.  This is because the bridge can't prevent the PreDestroy method from being called when the portlet request scope ends even though it is managing the attribute in its request scope.  I.e. managed beans managed by the bridge in its bridge request scope will still be notified they are being destroyed at the end of each portlet request.  To work properly clients must change their managed bean implementations for those beans not excluded from the bridge request scope and the bridge must provide new (additional) mechanisms.

6.8.1 Managed Bean Changes

Managed beans that want to utilize PreDestroy and run properly when not explicitly excluded from the bridge request scope must:

6.8.2 Bridge requirements

To satisfy the Faces requirement that managed beans managed in the bridge's request scope have an opportunity to release themeselves when the bridge request scope ends, the bridge must provide the following once it has acquired a FacesContext for a given request:

6.9 Setting the RenderKit used by a Portlet

Faces resolves the renderkit used in a given request by first looking for a request parameter whose name is the value of ResponseStateManager.RENDER_KIT_ID_PARAM. If this parameter doesn't exist the id is next determined from a configuration parameter in the application's faces-config.xml and finally an internal setting.  Given that the faces-config.xml is an application wide setting, the request parameter is the sole mechanism for managing the needs of portlets that use distinct renderkits.  As this may not be uncommon and most portlets use the same renderkit throughout all its views, the bridge simplifies the use of this request parameter if the proper context attribute has been set prior to it being initialized.

Specifically, when the bridge is initialized, if the portlet context attribute javax.portlet.faces.<portletName>.defaultRenderKitId is set, the bridge is responsible for ensuring that in every request the request parameter Map(s) returned from ExternalContext.getRequestParameterMap() and and the ExternalContext.getRequestParameterValuesMap()Iterator returned from the ExternalContext.getRequestParameterNames() contain an entry for ResponseStateManager.RENDER_KIT_ID_PARAM[6.xxx]. In the Map(s), the value for this entry must be the value from the underlying request, if it exists, otherwise it must be the value in the javax.portlet.faces.<portletName>.defaultRenderKitId context attribute[6.xxx].


  Previous Portlet 2.0 Bridge for JavaServerTM Faces 1.2 -- October 14th, 2010 Next