Skip Headers
Oracle® Fusion Middleware Developer's Guide for Oracle WebCenter Portal
11g Release 1 (11.1.1.6.0)

Part Number E10148-18
Go to Documentation Home
Home
Go to Book List
Book List
Go to Table of Contents
Contents
Go to Index
Index
Go to Feedback page
Contact Us

Go to previous page
Previous
Go to next page
Next
PDF · Mobi · ePub

59 Creating Portlets with the Oracle JSF Portlet Bridge

This chapter explains how to use the Oracle JSF Portlet Bridge to expose an application as a portlet.

This chapter includes the following sections:

59.1 Introduction to the Oracle JSF Portlet Bridge

The Oracle JSF Portlet Bridge enables application developers to quickly and easily expose their existing JSF applications, and Oracle ADF applications and task flows as JSR 286 portlets.

Note:

Unless otherwise noted, the term JSF applications encompasses Oracle ADF applications as well.

The Oracle JSF Portlet Bridge:

Note:

The Oracle JSF Portlet Bridge is based on and conforms to JSR 329. JSR 329 is the standards effort to define the functionality for the Portlet 2.0 Bridge for JavaServer Faces. Oracle is the specification lead for this standard. More information is available at:

http://www.jcp.org/en/jsr/detail?id=329

59.2 Creating a Portlet from a JSF Application

The Oracle JSF Portlet Bridge enables you to expose a JSF application or task flow as a portlet. You do this declaratively, using the Create Portlet Entry dialog; no coding is required. Using the Create Portlet Entry dialog, you can configure Oracle JSF Portlet Bridge on a JSF application to expose the application as a JSR 286 portlet. As part of this configuration, you indicate the initial JSF view (or task flow view) to invoke when the portlet is rendered. From that point on the Oracle JSF Portlet Bridge works with the JSF application to navigate through the additional views that are reachable from this initial view. So in the typical situation when you are exposing the entire JSF application as the portlet, you configure the Oracle JSF Portlet Bridge to render the application's initial view in the portlet and the rest of the navigation works naturally within that same portlet.

This section includes the following subsections:

59.2.1 How to Create a JSF Portlet Based on a Page

The simplest way to create a portlet from a JSF application is to generate a portlet based upon a page.

To create a JSF portlet from an existing application page:

  1. In the JDeveloper Application Navigator, open the application that contains the .jspx page to portletize.

  2. Right-click the page to portletize and choose Create Portlet Entry.

  3. In the Create Portlet Entry dialog (Figure 59-1), in the Portlet Name field, enter a name for the portlet.

    Figure 59-1 The Create Portlet Entry Dialog for a Page

    Description of Figure 59-1 follows
    Description of "Figure 59-1 The Create Portlet Entry Dialog for a Page"

  4. In the Display Name field, enter a descriptive name for your portlet.

  5. In the Portlet Title field, enter a descriptive title for your portlet.

    The portlet title is displayed in the Resource Palette or Application Resources panel, so make the title something to help users decide whether the portlet is useful to them. The portlet title is also displayed on the portlet header when the portlet appears on a page.

  6. In the Short Title field, enter a shorter title for your portlet. This short title is displayed on the portlet header when the portlet appears on a page on a mobile device.

  7. In the Description field, enter a description for your portlet.

  8. Select Create portlet events for contextual events to create portlet events in the portlet.xml file for any contextual events exposed by the page. This option is selected by default.

    Portlet events enable a portlet to communicate with the page on which it resides and with other portlets on that page.

  9. Click OK.

    The portlet.xml file is created.

    This file contains the portlet entry (Example 59-1) and is opened ready for viewing or editing. By default, the file is opened in Design view. To view or edit the source code, click the Source tab.

    Example 59-1 Generated Portlet Entry for a Page

    <portlet id="adf_jsf__testPage_jspx">
      <description>PortletBridgeApplication_testPage_jspx</description>
      <portlet-name>PortletBridgeApplication_testPage_jspx</portlet-name>
      <display-name>PortletBridgeApplication_testPage_jspx</display-name>
      <portlet-class>
        oracle.portlet.bridge.adf.application.ADFBridgePortlet
      </portlet-class>
      <init-param>
        <name>javax.portlet.faces.defaultViewId.view</name>
        <value>/myPage.jspx</value>
      </init-param>
      <supports>
        <mime-type>text/html</mime-type>
        <portlet-mode>VIEW</portlet-mode>
      </supports>
      <supported-locale>en</supported-locale>
      <portlet-info>
        <title>PortletBridgeApplication_testPage_jspx</title>
        <short-title>PortletBridgeApplication_testPage_jspx</short-title>
      </portlet-info>
      <supported-processing-event id="DepartmentSelectedEvent">
        <qname xmlns:x="http://xmlns.oracle.com/adfm/contextualEvent">
          x:DepartmentSelectedEvent
        </qname>
      <supported-publishing-event id="DepartmentSelectedEvent">
        <qname xmlns:x="http://xmlns.oracle.com/adfm/contextualEvent">
          x:DepartmentSelectedEvent
        </qname>
      </supported-publishing-event>
      <supported-public-render-parameter>
        _adf_event_DepartmentSelectedEvent
      </supported-public-render-parameter>
      <container-runtime-option>
        <name>com.oracle.portlet.requireIFrame</name>
        <value>true</value>
      </container-runtime-option>
      <container-runtime-option>
        <name>com.oracle.portlet.minimumWsrpVersion</name>
        <value>2</value>
      </container-runtime-option>
    </portlet>
    

    The page you selected earlier is used as the entry point for the portlet View mode. This is indicated in the portlet.xml file by the javax.portlet.faces.defaultViewId.view initialization parameter. You can manually edit the portlet.xml file to define the pages for other default and extended portlet modes supported by WebCenter Portal:

    • Edit mode: javax.portlet.faces.defaultViewId.edit

    • Help mode: javax.portlet.faces.defaultViewId.help

    • About mode: javax.portlet.faces.defaultViewId.about

    • Config mode: javax.portlet.faces.defaultViewId.config

    • Edit Defaults mode: javax.portlet.faces.defaultViewId.edit_defaults

    • Preview mode: javax.portlet.faces.defaultViewId.preview

    • Print mode: javax.portlet.faces.defaultViewId.print

    Note:

    The value for the defaultViewId is relative to the application context root and must always start with a /. For example, in Example 59-1, the value for defaultViewId.view is /myPage.jspx.

    If you add defaultViewId for other portlet modes, then ensure that you also add the mode to the <supports> tag. For example, <portlet-mode>HELP</portlet-mode>.

59.2.2 How to Create a JSF Portlet Based on a Task Flow

An advantage of using Oracle ADF is task flows that provide a modular approach for defining control flow in an application. Instead of representing an application as a single large JSF page flow, you can break it up into a collection of reusable task flows. In each task flow, you identify application activities, the work units that must be performed in order for the application to complete. An activity represents a piece of work that can be performed when running the task flow.

Task flows can be unbounded or bounded:

  • An unbounded task flow is a set of activities, control flow rules, and managed beans interacting to allow a user to complete a task. An unbounded task flow consists of all activities and control flows in an application that are not included within any bounded task flow.

  • A bounded task flow is a specialized form of task flow, having a single entry point and one or more exit points. It contains its own set of private control flow rules, activities, and managed beans. An Oracle ADF bounded task flow allows reuse, parameters, transaction management, and reentry. It can have zero to many exit points.

A typical application is a combination of an unbounded and one or more bounded task flows. The application can then call bounded task flows from activities within the unbounded task flow. For more detailed information about bounded and unbounded task flows, see the Oracle Fusion Middleware Fusion Developer's Guide for Oracle Application Development Framework.

This section includes the following subsections:

59.2.2.1 Creating a Portlet From a Task Flow Using the Create Portlet Entry Dialog

Use the Create Portlet Entry dialog to create a portlet from a single task flow.

To make a portlet from a task flow using the Create Portlet Entry dialog:

  1. In the JDeveloper Application Navigator, open the JSF application that contains the task flow from which you want to make a portlet.

  2. Right-click the task flow to portletize and choose Create Portlet Entry.

  3. In the Create Portlet Entry dialog (Figure 59-2), in the Portlet Name field, enter a name for the portlet.

    Figure 59-2 The Create Portlet Entry Dialog for a Task Flow

    Description of Figure 59-2 follows
    Description of "Figure 59-2 The Create Portlet Entry Dialog for a Task Flow"

  4. If the task flow is unbounded, the Entry Point View dropdown list displays all the view activities of the task flow. From this dropdown list, choose the view activity to use as the entry point for the portlet. By default, the first view activity in the task flow is chosen.

    If the task flow is bounded, there is only a single possible entry point, so you do not see the Entry Point View dropdown list.

  5. In the Display Name field, enter a descriptive name for your portlet.

  6. In the Portlet Title field, enter a descriptive title for your portlet.

    The portlet title is displayed in the Resource Palette or Application Resources panel, so make the title something to help users decide whether the portlet is useful to them. The portlet title is also displayed on the portlet header when the portlet appears on a page.

  7. In the Short Title field, enter a shorter title for your portlet. This short title is displayed on the portlet header when the portlet appears on a page on a mobile device.

  8. In the Description field, enter a description for your portlet.

  9. Select Create portlet events for contextual events to create portlet events in the portlet.xml file for any contextual events exposed by the task flow. This option is selected by default.

    Portlet events enable a portlet to communicate with the page on which it resides and with other portlets on that page.

  10. Click OK.

    When your portlet has been created, you should receive a message that says:

    New portlet has been successfully created
    

    In addition, the portlet.xml file is created. The portlet.xml file contains the portlet entry (Example 59-2) and is opened ready for viewing or editing.

    Example 59-2 Generated Portlet Entry for a Task Flow

    <portlet id="adf_taskflow_WEB_INF_department_xml">
        <description>PortletBridgeApplication department</description>
        <portlet-name>PortletBridgeApplication_department</portlet-name>
        <display-name>PortletBridgeApplication department</display-name>
        <portlet-class>oracle.portlet.bridge.adf.application.ADFBridgePortlet</portlet-class>
        <init-param>
          <name>javax.portlet.faces.defaultViewId.view</name>
          <value>
            /adf.task-flow?adf.tfDoc=/WEB-INF/adfp-portlet-bridge-container.xml
            &amp;adf.tfId=adfp-portlet-bridge-container&amp;_fragmentTaskFlowDoc=/WEB-INF/
            department.xml&amp;_fragmentTaskFlowId=department
          </value>
        </init-param>
        <supports>
          <mime-type>text/html</mime-type>
          <portlet-mode>VIEW</portlet-mode>
        </supports>
        <supported-locale>en</supported-locale>
        <portlet-info>
          <title>PortletBridgeApplication department</title>
          <short-title>PortletBridgeApplication department</short-title>
        </portlet-info>
        <supported-publishing-event id="DepartmentSelectedEvent">
          <qname xmlns:x="http://xmlns.oracle.com/adfm/contextualEvent">
            x:DepartmentSelectedEvent
          </qname>
        </supported-publishing-event>
        <supported-public-render-parameter>
          _adf_event_DepartmentSelectedEvent
        </supported-public-render-parameter>
        <container-runtime-option>
          <name>com.oracle.portlet.requireIFrame</name>
          <value>true</value>
        </container-runtime-option>
        <container-runtime-option>
          <name>com.oracle.portlet.minimumWsrpVersion</name>
          <value>2</value>
        </container-runtime-option>
    </portlet>
    

    Note:

    The portlet.xml file can include multiple portlets and can have a combination of pages and task flows exposed as portlets.

59.2.2.2 Creating a Portlet From a Task Flow Using the Manage Portlet Entries of Task Flows Dialog

If your project includes a lot of task flows, you may find it easier to select the task flows to create as portlets from a list. You can do this using the Manage Portlet Entries of Task Flows dialog. This dialog also lets you create portlets from multiple task flows at the same time, rather than having to create them individually.

To create a portlet from a task flow using the Manage Portlet Entries of Task Flows dialog:

  1. From the main menu, choose File and then New.

  2. In the New Gallery, expand Web Tier, select Portlets and then Manage Portlet Entries of Task Flows, and click OK.

  3. In the Manage Portlet Entries of Task Flows dialog, use the shuttle buttons to select which task flows you want to create as portlets.

    Figure 59-3 The Manage Portlet Entries of Task Flows Dialog

    Description of Figure 59-3 follows
    Description of "Figure 59-3 The Manage Portlet Entries of Task Flows Dialog"

  4. Select Create portlet events for contextual events to create portlet events in the portlet.xml file for any contextual events exposed by the task flows. This option is selected by default.

    Portlet events enable a portlet to communicate with the page on which it resides and with other portlets on that page.

  5. Click OK to create portlets for the selected task flows.

59.2.3 How to Test a JSF Portlet Using the Integrated WebLogic Server

When you have created your JSF portlet you can test it using the Integrated WebLogic Server that comes packaged with JDeveloper.

To test a JSF portlet:

  1. From the main menu, choose Run and then Start Server Instance.

    It may take a few moments for the Integrated WLS to start. When the instance has started, you should see a message similar to the following in your Log panel:

    IntegratedWebLogicServer started.
    

    For more information, see Section 3.4, "Working with the Integrated WebLogic Server."

  2. You are now ready to run or deploy your Portlet Producer application to the Integrated WLS. Because your web application and Portlet Producer application are one and the same (the Portlet Producer application is your existing web application with additional portlet artifacts), you can run or deploy your web application as you normally would or you can run or deploy your portlet following the instructions in Section 62.2.1, "How to Test JSR 286 Portlets on Integrated WebLogic Server."

    Note the distinction between Run and Deploy in the note in that section. Deploy provides a more persistent testing scenario.

  3. When deployed, you can view the Producer Test Page by going to:

    http://host:port/context-root/info
    

    Post deployment you must verify that the application works correctly as a web application before it is consumed as a Portlet Producer application. For example, verify that the page you portletized earlier works:

    http://localhost:7101/myApp-ViewController-context-root/faces/myPage.jspx
    
  4. Once you have successfully deployed the application containing the portlet, you can register it as a portlet producer with any other application. For more information see Section 64.2.1, "How to Register a WSRP Portlet Producer."

    Note:

    Because the Oracle JSF Portlet Bridge uses WSRP 2.0 features, you should register the producer using the WSRP v2 WSDL URL listed in the WSRP Producer Test Page.

    You can continue to access the application as a regular web application or consume it as a portlet producer.

  5. Now that your portlet producer is deployed and registered, you can consume your JSF portlet as you would any other portlet. For more information, see Section 64.3, "Adding Portlets to a Page."

59.2.4 What Happens at Runtime

After having created and tested the JSF portlet you can deploy the application to your production environment.

Note:

Ensure that you deploy your application to a Java EE container with the Oracle Portlet Container installed. The Integrated WLS has the container installed, which is why it is recommended for testing.

After successful deployment, you can access both the application and the portlet producer test page. For example, the application URL would be similar to:

http://host:port/appcontextroot/faces/pagename.jspx

And the portlet producer test URL would be similar to:

http://host:port/appcontextroot/info

For more information, see Section 64.2.1, "How to Register a WSRP Portlet Producer."

59.3 What You May Need to Know When Creating a JSF Portlet

You must code your JSF pages such that they produce markup that conforms with JSR 286 portlet markup fragment rules. If you have chosen to use Oracle ADF, the markup in your page comes mainly from the Oracle ADF Faces components, most of which naturally render markup in a style that is compatible with JSF portlets.

For those components that might cause problems in a portlet environment, the application developer must take special care. Some components generate markup that conflicts with the portlet environment and hence restricts their use. Other components may allow program control (inputs) that enable developers to introduce values that conflict with the portlet environment. In this latter case, you as the developer must be aware of the potential to publish the page as a portlet and therefore properly encode a value.

This section includes the following subsections:

59.3.1 General Guidelines

The guidelines that follow lay out the issues of which you should be aware as you code Oracle ADF pages that you may later choose to publish as portlets.

  • Prior to creating a portlet from your JSF application, the application, including all of its pages and task flows, must run properly after you deploy it to Integrated WLS. If it cannot run as a regular web application, it cannot run as a portlet producer either.

  • When writing an application that is supposed to run in both servlet and portlet environments, avoid casting to HttpServlet objects (or you get a ClassCastException when running as a portlet). Instead, use the abstraction provided by the Faces ExternalContext object. For example, instead of:

    HttpServletRequest request =
    (HttpServletRequest)FacesContext().getCurrentInstance().getExternalContext()
    .getRequest();
    

    Use the following:

    String localContextPath=
    FacesContext().getCurrentInstance().getExternalContext().getRequestContextPath();
    

    To the extent that ExternalContext does not provide that abstraction for you, you can write servlet or portlet specific code. You can use the following method to check if the application runs as portlet:

    public static boolean isPortletRequest() {
        Map<String, Object> m =
            FacesContext.getCurrentInstance().getExternalContext().getRequestMap();
        Object phase = m.get("javax.portlet.faces.phase");
        if (phase != null) {
            return true;
        }
        else {
            return false;
        }
    }
    
  • When consuming a JSF Portlet, the consumer application automatically renders the portlet content within an inline frame (IFRAME). The implication is that any inline popup is then confined within the IFRAME. You should take this into consideration when specifying the size of the portlet.

  • If your application is secured, ensure that you have secured identity propagation as described in Section 69.17, "Securing Identity Propagation Through WSRP Producers with WS-Security."

  • Deep links are not directly supported. A by-product of the JSR 286 portlet container implementation on WSRP is that session cookie management is proxied by the consuming application rather than the client. Portlets that deep link to their full service application usually rely on shared session state to allow the transition from the current portlet context. As most applications rely on maintaining session context with a cookie, the current architecture prevents such state sharing. A deep link from the client directly to the producer server to invoke the application does not establish a session cookie between the consumer and the producer, hence a second session is established. Applications that are required to share such state must implement their own schemes for transferring the data between the two contexts. A common implementation is to write this state to a reachable location and pass a reference to this state in the deep link.

  • Java EE login is not supported. Java EE applications can be configured with different authentication techniques, such as Basic and Digest. As portlets are fragments incorporated into a consumer's page, it is generally expected that direct authentication occurs between the client and the consumer, not the client and the portlet producer. As a result, these authentication techniques are not supported in JSR 286. In the JSR 286 case, Java EE authentication occurs through WS-Security mechanisms that allow the Web service consumer to be authenticated and verified by the producer, and propagate the user identity for user authentication and authorization. Published Oracle ADF artifacts must not contain login links that trigger Java EE authentication.

  • For applications that take a long time to render, consider increasing the time out period when you register a producer that was created by the Oracle JSF Portlet Bridge. Note however that the time out period specified during producer registration is limited by the maximum time out period (maximumTimeout element) specified in adf-config-xml.

59.3.2 Portlet Guidelines

The portlet guidelines are as follows:

  • For resources and links, you must specify the location relative to the web-app-context-root. Otherwise, your images and other resources cannot be found by the portlet. Do not use relative (../) path notation. Portlets in Oracle WebCenter Portal: Framework run remotely and are accessed using a SOAP protocol (WSRP). The latter means that the regular web application concept of request path does not apply in a JSR 286 container. The JSR 286 specification reflects this by mandating that all resource URLs either be absolute or context path relative.

  • Do not redirect or forward a request within your JSP. JSR 286 only supports requestDispatcher.include(). The use of httpServletResponse.sendRedirect() or requestDispatcher.forward() results in exceptions and errors. To work properly in a portlet environment, you must implement JSF navigation rules in faces-config.xml or Oracle ADF task flow control flow rules.

  • To minimize overall memory consumption in the application when running as a portlet, you should only store the minimal amount of data in the request scope.

  • If you portletize an application that contains downloadable resources, the portlet container may rewrite the file name in such a way that it may be too long for the browser to open or save. In such a case, you can save the resource to a different name and open the file using the appropriate program directly.

  • If the portlet uses JSF view components other than ADF Faces (for example, Trinidad components), then you may want to manually change the portlet's minimumWsrpVersion container runtime option to 1 so that it can be registered using the WSRP V1 WSDL. For more information, see Section 61.2.4, "How to Customize the Runtime Environment."

59.3.3 Security Guidelines

The security guidelines are as follows:

  • When you use the Create Portlet Entry or Manage Portlet Entries of Task Flows dialog to portletize a task flow in an Oracle ADF secured application (the security scheme being Authentication and Authorization), you must manually grant permission to the following wrapper task flow in the jazn-data.xml file of the producer application:

    /WEB-INF/adfp-portlet-bridge-container.xml#adfp-portlet-bridge-container
    

    If you do not grant the permissions, the portlet does not render.

    For example, if you have an application with two roles: authenticated-role, with view permission; and testrole, with customize, edit, grant, personalize, and view permissions, you must add the following entries inside the <permissions> tag of each role:

    • For authenticated-role:

      <permission>
        <class>oracle.adf.controller.security.TaskFlowPermission</class>
        <name>
        /WEB-INF/adfp-portlet-bridge-container.xml#adfp-portlet-bridge-container
        </name>
        <actions>view</actions>
      </permission>
      
    • For testrole:

      <permission>
        <class>oracle.adf.controller.security.TaskFlowPermission</class>
        <name>
          /WEB-INF/adfp-portlet-bridge-container.xml#adfp-portlet-bridge-container
        </name>
        <actions>customize,edit,grant,personalize,view</actions>
      </permission>
      
  • If you are portletizing a task flow or page that has role based authorization (that is, the task flow or page has been granted certain roles), WS-Security is required to propagate the user correctly. If you set up WS-Security, the JSF portlet does not render the content due to lack of permissions.

    For information about setting up WS-Security on the producer, see Section 69.17, "Securing Identity Propagation Through WSRP Producers with WS-Security."

    When registering the producer with the consuming application, you must ensure that you set the appropriate security properties. For more information, see Section 64.2.1, "How to Register a WSRP Portlet Producer."

59.3.4 JSF Guidelines

The JSF guidelines are as follows:

  • When using the h:commandLink JSF standard HTML component ensure that you set the following context-param in web.xml so that the JSF Reference Implementation does not generate any external JavaScript resource. This is to work around an issue in the JSF Reference Implementation where the reference to the JavaScript resource is not properly encoded.

    <context-param>
        <param-name>com.sun.faces.externalizeJavaScript</param-name>
        <param-value>false</param-value>
    </context-param>
    

59.3.5 Oracle ADF Guidelines

The Oracle ADF guidelines are as follows:

  • If you are portletizing an Oracle ADF task flow, ensure that you are able to consume that task flow by dropping it onto a page as a region and running the page. This ensures that the task flow runs correctly before portletizing it.

  • ADF Faces Dialog Framework is not supported. If your application includes any buttons or icons that launch secondary browser windows, then the contents of the new windows are not displayed properly when the application is run as a portlet. As such, you should avoid using these components if you plan to portletize your application. Examples of components that launch secondary windows are:

    • <tr:inputDate>

    • <tr:inputColor>

    • <tr:popup>

    • the useWindow attribute of <af:commandButton>

  • Portletization of pages that contain Composer components is not supported.

  • The <af.fileDownloadActionListener> component is not supported.

  • Oracle ADF components/code that handle prepareModel must be idempotent. Any code running during the prepareModel phase must be rerunnable without effect to the underlying data/business logic. When running in the portlet environment, prepareModel is called twice during the complete JSF life cycle as opposed to being called once when running within a regular web application.

    The reason for this difference is that the Oracle JSF Portlet Bridge runs JSF in two requests not one. It is implemented as if every JSF request redirected before the render phase. The consequence of this approach is that the JSF restoreView phase is called both when the request is first submitted and then again when request to render is received.

  • Do not access or reference request parameters from model code except in page parameters. Besides being a cleaner MVC2 implementation, following this guideline avoids problems when such artifacts are published as portlets. Where regular JSF artifacts run their entire lifecyle in a single request, the Oracle JSF Portlet Bridge runs these artifacts in two requests, as if every JSF request redirected before the render phase.

    This two phase model enables the clearing of submitted parameters before rendering in a manner that allows such clearing to be communicated all the way back to the client, which makes this request something you could bookmark. As a result, request parameters do not exist during the render phase. As described previously, prepareModel is invoked again in this rendering phase. Therefore, any references to request parameters in this phase handler fail. You should avoid code like either of the following fragments:

    <invokeAction id="doExecuteWithParams" 
                  Binds="ExecuteWithParams" 
                  Refresh="prepareModel" 
                  RefreshCondition="${param.id != null}"
    />
    
    <invokeAction id="doExecuteWithParams" 
                  Binds="ExecuteWithParams" 
                  Refresh="renderModel" 
                  RefreshCondition="${param.id != null}"
    />
    
  • Do not reference page parameters in the prepareModel phase. This issue relates to the same problem just described for request parameters. Generally, page parameters depend on request parameters and are evaluated during the restoreView phase. As this phase is called a second time during portlet rendering and request parameters are not available, such use fail. Instead, move any dependency on a page parameter value into the model before JSF transitions from its execute phases to its render phase.

  • If you are portletizing an application that contains only Trinidad components (<tr: > tags only), then you must manually include the following libraries in your project:

    • jdeveloper\modules\oracle.adf.view_11.1.1\adf-richclient-api-11.jar

    • jdeveloper\modules\oracle.adf.view_11.1.1\adf-richclient-impl-11.jar

    This is so that the URLs to icons in the style sheet generated for the producer are encoded correctly.

  • Because a portlet is a naming container, special consideration should be taken when using ADF Faces client-side APIs to find components. An example component ID:

    • When run as a regular web application: id="demoTemplate:popup"

    • When run as a Portlet Producer application: id="__ns12345678:demoTemplate:popup"

    Things to watch out for specifically are:

    • Avoid using the AdfPage.PAGE.findComponentByAbsoluteId() API. Use getSource() and findComponent() methods instead. For example:

      <trh:script text="
      function showPopup(event) {
          event.cancel();
          // var popup =
          //  AdfPage.PAGE.findComponentByAbsoluteId("demoTemplate:popup");
          var source = event.getSource();
          var popup = source.findComponent("popup");
          popup.show({align:"after_end", alignId:"button"});
      }
      "/>
      
    • Use a relative path for clientId instead of an absolute path (starting with a ':'). For example, use:

      <af:showPopupBehavior popupId="demoTemplate:iteratorpop"
                  triggerType="mouseHover"/>
      

      Instead of:

      <af:showPopupBehavior popupId=":demoTemplate:iteratorpop"
                  triggerType="mouseHover"/>
      
    • For more information, see "What You May Need to Know About Using Naming Containers" in the Oracle Fusion Middleware Web User Interface Developer's Guide for Oracle Application Development Framework.

  • If you are portletizing an Oracle ADF task flow that triggers a contextual event, the Oracle JSF Portlet Bridge creates a JSR 286 event to wrap the contextual event. Part of the JSR 286 event's payload is the wrapped contextual event payload, which is serialized. When this wrapped contextual event is delivered, the contextual event payload must be deserialized on the consumer before the contextual event can be forwarded into the consumer application. To deserialize the event, the payload class must be available on the consumer as well as on the producer. This condition is automatically met when the original payload is a Java Runtime Environment class, such as java.lang.String.

  • If your Oracle ADF task flow includes ADFm events that do not have corresponding portlet events declared in the portlet.xml file, you can enable the Oracle JSF Portlet Bridge to raise these undeclared events.

    To raise undeclared events, set the following container runtime option for the portletized task flow:

    <portlet id="Application5untitled1jspx1_1">
       ...
       <container-runtime-option>
          <name>oracle.portlet.bridge.adf.raiseUndeclaredContextualEvents</name>
          <value>true</value>
       </container-runtime-option>
       ...
    </portlet>
    

    Setting this option to true means that any ADFm event raised is forwarded on as a portlet event. If this option is not provided or is set to false, then only events with corresponding portlet event declarations are forwarded.

    You can also enable undeclared portlet events to automatically be forwarded on from the portlet binding as ADFm events.

    In the portlet binding, set the raiseUndeclaredContextualEvent attribute to true, for example:

    <portlet id="Application5untitled1jspx1_1"
             portletInstance="/oracle/adf/portlet/WsrpPortletProducer4/ap/
                   Application5untitled1jspx_2943bd23_012e_1000_8004_0aa7c0849010"
             class="oracle.adf.model.portlet.binding.PortletBinding"
             retainPortletHeader="false"
             listenForAutoDeliveredPortletEvents="true"
             listenForAutoDeliveredParameterChanges="true"
             raiseUndeclaredContextualEvents="true"
             xmlns="http://xmlns.oracle.com/portlet/bindings"/>
    

    Setting this option to true means that if a portlet event is received, a corresponding ADFm event is raised, even if there is no event declaration in the portlet binding. The name of the ADFm event is directly taken from the QName of the portlet event. This is so that ADFm events raised from the Oracle JSF Portlet Bridge have the same name as that used when the event was raised on the remote application.

  • By default, URLs in the portletized page or task flow are encoded such that they are proxied by the consumer application. In some circumstances, you may not want to encode these URLs, for example, when requesting JavaScript libraries from content delivery networks or accessing resources directly from the user's browser to make use of a locally configured HTTP proxy. To bypass the URL encoding, set the _xEncodeUrl parameter to false on URLs that are passed to the Oracle JSF Portlet Bridge for encoding.

    For example, an inline frame that contains a Google Map would typically need to make use of the user's browser HTTP proxy settings to access the external maps.google.com server. The ADF markup to enable the component to work correctly when exposed as a portlet would look like the following:

    <af:inlineFrame id="if1"
                    shortDesc="Location of office"
                    source="http://maps.google.com/maps?q=RG6+1RA&amp;
                            output=embed&amp;_xEncodeUrl=false"/>
    

    Note:

    Do not use this parameter to access resources that reside on the producer server. These resources must be accessed using the portlet client's proxy.

59.4 Copying a Runtime-Created Skin to a JSF Portlet Producer Application

In a WebCenter Portal application, you can create skins at runtime, using the Resource Manager. When you do this, you may encounter rendering issues on pages that include JSF portlets. This is because the skin used by the WebCenter Portal application is not available to the remote application rendering the task flow.

To rectify this issue, you must copy the runtime-created skin to the Portlet Producer application created when the task flow was portletized.

To copy a runtime-created skin to a Portlet Producer application:

  1. Export the skin from the Framework application to an EAR file.

    For information about how to do this, see Section 17.4.1, "How to Download a Resource Using the Resource Manager."

  2. Repackage the exported skin as a shared library (a JAR file):

    1. Extract the transport.mar file:

      $ jar xvf myskin.ear
      inflated: transport.mar
      
    2. Extract the metadata files:

      $ jar xvf transport.mar
      inflated: oracle/webcenter/siteresources/.../Skin.css
      inflated: oracle/webcenter/siteresources/.../generic-site-resources.xml
      ...
      
    3. Locate and view the file generic-site-resources.xml among the metadata files. Normally, this file is in a directory like:

      oracle/webcenter/siteresources/scopedMD/scopeGUID/generic-site-resources.xml
      

      The file should have a section that describes the exported skin, similar to the following example:

      <resourceType name="skin" ...>
        <resource displayName="MySkin"
           metadataFile="/oracle/webcenter/siteresources/.../Skin.css" ...>
          <customAttributes>
            <customAttribute name="skinId"
               value="gsr616d879d_99e0_4bd9_8c10_98e7ea272a6a.desktop" .../>
            <customAttribute name="skinFamily"
               value="gsr616d879d_99e0_4bd9_8c10_98e7ea272a6a" ...>
            <customAttribute name="skinExtends"
               Value="webcenter-fusion-internal.desktop" .../>
          </customAttributes>
        </resource>
      </resourceType>
      
    4. Note the following information from generic-site-resources.xml:

      • skinId (for example, gsr616d879d_99e0_4bd9_8c10_98e7ea272a6a.desktop)

      • skinFamily (for example, gsr616d879d_99e0_4bd9_8c10_98e7ea272a6a)

      • skinExtends (for example, webcenter-fusion-internal.desktop)

    5. Build the directory structure for the JAR file:

      $ mkdir META-INF
      
    6. Copy the Skin.css file into the META-INF directory:

      $ cp oracle/webcenter/siteresources/.../Skin.css META-INF
      
    7. Create a new file called trinidad-skins.xml under the META-INF directory:

      $ edit META-INF/trinidad-skins.xml
      
    8. Add the following XML to the new trinidad-skins.xml file:

      <?xml version="1.0" encoding="ISO-8859-1"?>
      <skins xmlns="http://myfaces.apache.org/trinidad/skin">
        <skin>
          <style-sheet-name>Skin.css</style-sheet-name>
          <id>skinId</id>
          <family>skinFamily</family>
          <extends>skinExtends</extends>
          <render-kit-id>org.apache.myfaces.trinidad.desktop</render-kit-id>
        </skin>
      </skins>
      

      where skinId, skinFamily, and skinExtends are the values noted earlier.

    9. Package the JAR file:

      $ jar cvf myskin.jar META-INF
      adding: META-INF/trinidad-skins.xml(in = 359) (out= 171)(deflated 52%)
      adding: META-INF/Skin.css(in = 5560) (out= 1413)(deflated 74%)
      

      The JAR file should contain two files: Skin.css and trinidad-skins.xml.

  3. Copy the new myskin.jar file to the Portlet Producer application.

    The easiest way to do this is to copy the file to the WEB-INF/lib directory of the Portlet Producer web application.