JBoss.orgCommunity Documentation
The 329 specification is aimed at making the developers life as easy as possible with JSF+Portlet development. You will see below that there are minimal settings to getting any JSF web application up and running in the Portal environment.
If you are starting from scratch, we highly recommend you use the Section 2.4, “Maven Archetypes”.
The basic JSR-329 portlet configuration.
<portlet> <portlet-name>yourPortletName</portlet-name> <portlet-class> javax.portlet.faces.GenericFacesPortlet </portlet-class> <init-param> <name>javax.portlet.faces.defaultViewId.view</name> <value>/welcome.xhtml</value> </init-param> <init-param> <name>javax.portlet.faces.defaultViewId.edit</name> <value>/jsf/edit.xhtml</value> </init-param> <init-param> <name>javax.portlet.faces.defaultViewId.help</name> <value>/jsf/help.xhtml</value> </init-param>
When preserveActionParams is set to TRUE, the bridge must maintain any request parameters assigned during the portlet's action request. The request parameters are maintained in the"bridge request scope". When this attribute isn't present or is FALSE the action's request parameters are only maintained for the duration of the portlet request scope.
<init-param> <name>javax.portlet.faces.preserveActionParams</name> <value>true</value> </init-param>
The PortletViewHandler ensures that each JSF portlet instance is properly namespaced.
<faces-config> <application> <view-handler> org.jboss.portletbridge.application.PortletViewHandler </view-handler> <state-manager>org.jboss.portletbridge.application.PortletStateManager</state-manager> </application> ...
The following web.xml setting is only for Facelets based applications
<web-app xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd" version="2.4"> ... <!-- This is optional parameters for a facelets based application --> <context-param> <param-name>org.ajax4jsf.VIEW_HANDLERS</param-name> <param-value>org.jboss.portletbridge.application.FaceletPortletViewHandler</param-value> </context-param>
<context-param> <param-name>javax.portlet.faces.RENDER_POLICY</param-name> <param-value> ALWAYS_DELEGATE </param-value> </context-param> ... </web-app>
ALWAYS_DELEGATE
Indicates the bridge should not render the view itself but rather always delegate the rendering.
NEVER_DELEGATE
Indicates the bridge should always render the view itself and never delegate.
DEFAULT
Directs the bridge to first delegate the render and if and only if an Exception is thrown then render the view based on its own logic. If the configuration parameter is not present or has an invalid value the bridge renders using default behavior. I.e. as if DEFAULT is set.
The following web.xml setting is only for JSP based applications. Download the demo application here.
<web-app xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd" version="2.4"> <context-param> <param-name>javax.portlet.faces.renderPolicy</param-name> <param-value> NEVER_DELEGATE </param-value> </context-param> ... </web-app>
The Jboss Portlet Bridge can be used with a any compatible implementation ( for example, MyFaces implementation). Simply put the following into web.xml :
<context-param> <param-name>javax.portlet.faces.BridgeImplClass</param-name> <param-value>org.apache.myfaces.portlet.faces.bridge.BridgeImpl</param-value> </context-param>
The following configuration is designated for portlets using the RichFaces library in GateIn. These settings will vary based on your individual needs. See this section of the RichFaces documentation for more details.
<context-param> <param-name>org.richfaces.LoadStyleStrategy</param-name> <param-value>ALL</param-value> </context-param> <context-param> <param-name>org.richfaces.LoadScriptStrategy</param-name> <param-value>ALL</param-value> </context-param>
If you use the "NONE" strategy, you must include the following scripts in your portlet or portal page header.
The org.ajax4jsf.RESOURCE_URI_PREFIX
configuration cross references the path to your scripts below. These settings are required for RichFaces using the "NONE" strategy.
<script src="/faces/rfRes/org/ajax4jsf/framework.pack.js" type="text/javascript"></script> <script src="/faces/rfRes/org/richfaces/ui.pack.js" type="text/javascript"></script> <link rel="stylesheet" type="text/css" href="/faces/rfRes/org/richfaces/skin.xcss"/>
Seam automatically configures your Ajax4JSF Filter, so if you are running a Seam portlet, you do not need the following Filter config. (But you do need the RESOURCE_URI_PREFIX no matter what)
<context-param> <param-name>org.ajax4jsf.RESOURCE_URI_PREFIX</param-name> <param-value>rfRes</param-value> </context-param> <filter> <display-name>Ajax4jsf Filter</display-name> <filter-name>ajax4jsf</filter-name> <filter-class>org.ajax4jsf.Filter</filter-class> </filter> <filter-mapping> <filter-name>ajax4jsf</filter-name> <servlet-name>FacesServlet</servlet-name> <dispatcher>FORWARD</dispatcher> <dispatcher>REQUEST</dispatcher> <dispatcher>INCLUDE</dispatcher> </filter-mapping> ... </web-app>
The ExceptionHandler is used to clean Seam contexts and transactions after errors.
<context-param> <param-name>org.jboss.portletbridge.ExceptionHandler</param-name> <param-value> org.jboss.portletbridge.SeamExceptionHandlerImpl </param-value> </context-param>
If you are using this bridge packaged from 2.0.0.BETA onward, you must define the following web.xml parameter to use the JBoss Portlet Bridge provided Seam Phase Listener. This is done by the bridge automatically (if needed) in 2.0.0.FINAL.
<context-param> <param-name>javax.faces.LIFECYCLE_ID</param-name> <param-value>SEAM_PORTLET</param-value> </context-param>
One very important thing to note before using either of the following mechanisms, is that you must have the proper 2.0 schema and xsd definition at the top of your portlet.xml.
<portlet-app xmlns="http://java.sun.com/xml/ns/portlet/portlet-app_2_0.xsd" version="2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/portlet/portlet-app_2_0.xsd http://java.sun.com/xml/ns/portlet/portlet-app_2_0.xsd">
Just like with any portlet 2.0 event consumer and receiver, you must define them in the portlet.xml. To see a working example, checkout the Seam Booking Demo portlet. http://anonsvn.jboss.org/repos/portletbridge/tags/2.0.0.CR1/examples/seam/booking/
You must also define the following init params in your portlet.xml.
<init-param> <name>javax.portlet.faces.autoDispatchEvents</name> <value>true</value> </init-param> <init-param> <name>javax.portlet.faces.bridgeEventHandler</name> <value>org.foo.eventhandler</value> </init-param>
For now, you must dipatch the event in the JSF or Seam backing bean. Future versions on the 2.0 bridge will automate the dispatching and consuming of events.
if (response instanceof StateAwareResponse) { StateAwareResponse stateResponse = (StateAwareResponse) response; stateResponse.setEvent(Foo.QNAME, new Bar()); }
Then you must also create the event handler class by implementing the BridgeEventHandler interface to process the event payload.
public class BookingEventHandler implements BridgeEventHandler { public EventNavigationResult handleEvent(FacesContext context, Event event) { //process event payload here } }
Public Render Parameters (or PRPs) are one of the most powerful and simple Portlet 2.0 features. Several portlets (JSF or not) can share the same render parameters. This feature can be use to present a cohesive UI to the user across all portlets on the page (i.e. using an employee ID to display relative data).
The bridge maps a render parameter to a backing bean using settings in your faces-config.xml and portlet.xml. A clear and working example can be found in the Seam Booking Demo portlet. http://anonsvn.jboss.org/repos/portletbridge/tags/2.0.0.CR1/examples/seam/booking/
You must define the following init params in your portlet.xml.
<init-param> <name>javax.portlet.faces.bridgePublicRenderParameterHandler</name> <value>org.foo.PRPHandler</value> </init-param> ... <supported-public-render-parameter>myCoolPRP</supported-public-render-parameter>
Create a managed bean and public-parameter-mappings in your faces-config.xml. This should be a basic bean that you can bind the passed parameter to a string with getter and setter.
<managed-bean> <managed-bean-name>bookingPRP</managed-bean-name> <managed-bean-class>your.class.Name</managed-bean-class> <managed-bean-scope>session</managed-bean-scope> </managed-bean> <application> <application-extension> <bridge:public-parameter-mappings> <bridge:public-parameter-mapping> <parameter>"the name of your portlet":hotelName</parameter> <model-el>#{bookingPRP.hotelName}</model-el> </bridge:public-parameter-mapping> </bridge:public-parameter-mappings> </application-extension> </application>
You must set the parameter in the JSF or Seam backing bean, if you are providing one from your portlet.
if (response instanceof StateAwareResponse) { StateAwareResponse stateResponse = (StateAwareResponse) response; stateResponse.setRenderParameter("hotelName",selectedHotel.getName()); }
Then you must also implement the BridgePublicRenderParameterHandler interface to process any updates from the received parameter.
public void processUpdates(FacesContext context) { ELContext elContext = context.getELContext(); BookingPRPBean bean = (BookingPRPBean) elContext.getELResolver().getValue(elContext, null, "bookingPRP"); if(null != bean){ //Do something with bean.getHotelName()); } else { } }
We have setup a few examples to show you how to use EL and a simple bean that will allow you to use the portlet resource serving mechanism within a JSF portlet.
In ResourceBean.java, you can see a very simple implementations of a Map object that uses the bridge to get and encode a resource url served from the portlets web application.
So, when you have the normal "/images", "/styles" and other resource folders in your web app, you can use the following EL expression to serve them in your JSF application.
#{resource['/img/the-path-to-my-image.png']}
Just copy the ResourceBean.java code above, and add an entry to you faces-config.xml for the bean:
<managed-bean> <managed-bean-name>resource</managed-bean-name> <managed-bean-class>org.richfaces.demo.common.ResourceBean</managed-bean-class> <managed-bean-scope>application</managed-bean-scope> </managed-bean>