JBoss.orgCommunity Documentation

Chapter 3. Bridge Configuration

3.1. Core Setup and Configuration
3.1.1. portlet.xml
3.1.2. faces-config.xml
3.1.3. Facelets Configuration
3.1.4. JSP Only Configuration
3.1.5. JSR-329
3.2. RichFaces Setup and Configuration Options
3.2.1. web.xml
3.3. Seam Setup and Configuration Options
3.3.1. Configuration
3.4. Portlet 2.0 Coordination
3.4.1. Sending and Receiving Events
3.4.2. Public Render Parameters
3.4.3. Serving Your JSF Resources in a Portlet

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 following configuration is designated for portlets using the RichFaces library. These settings will vary based on your individual needs. See this section of the RichFaces documentation for more details.

Sometimes it is better to use the "ALL" load strategy in portlets so you do not need to worry about loading the "framework.pack.js" and "ui.pack.js" files manually in your portlet header.

            <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>

Note

If you use the "NONE" strategy, you must include the following scripts in your portlet or portal page header. If you are using JBoss Portal, you can add this to the jboss-portlet.xml file.

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>

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>