Skip Headers
Oracle® Fusion Applications Developer's Guide
11g Release 1 (11.1.1.5)

Part Number E15524-01
Go to Documentation Home
Home
Go to Book List
Book List
Go to Table of Contents
Contents
Go to Feedback page
Contact Us

Go to previous page
Previous
Go to next page
Next
View PDF

14 Implementing the UI Shell

This chapter discusses the UI Shell and the components used to implement user interface features in JDeveloper.

This chapter includes the following sections:

For basic information and detailed information of the features, see:

14.1 Introduction to Implementing the UI Shell

The UI Shell is a page template containing default information, such as a logo, menus and facets. To supplement the UI Shell template, there also is a UIShellMainArea template. Because you can load information into dynamic tabs, the Main area (the center and the right as shown in Figure 14-1) cannot be a part of the page itself since it is loaded dynamically.

The UI Shell design supports task-based and user-based navigation and way-finding, and organizes screen real estate more effectively by collating tasks, providing dedicated spaces for primary-task supporting information, and maintains general order and appropriate hierarchy between various elements on the screen.

The UI Shell for Applications User Experience (Applications UX) patterns provides a system of containers that fulfill common layout and navigational requirements in a structured, consistent manner. The UI Shell focuses on providing detailed design for defining and organizing various types of navigation and other functionality such as search and auxiliary information for Oracle Fusion Middleware alone.

Before you begin:

You should be familiar with JDeveloper, be able to create and run JSF pages, and be able to create an Oracle Application Development Framework (Oracle ADF) task flow.

14.1.1 Standard Related to UI Shells

Almost all shipped Oracle Fusion Applications pages are built using the UIShell page template. Exceptions include the login page, and the password preferences page.

14.1.2 UI Shell Description

The UI Shell is composed of four default, mandatory areas: global, regional, local, and contextual, as shown in Figure 14-1.

Figure 14-1 UI Shell Areas

Example showing the four UI Shell areas.
  • The shell is optimized for a screen resolution of 1280x1024 pixels.

  • The four areas are:

    • Global Area: The global area, across the full width at the top of the UI shell, is stable, consistent, and persistent for an individual user. It contains controls that, in general, drive the contents of the other three areas. See Section 14.1.2.1, "Global Area Standard Links."

    • Regional Area: The regional area is in the left pane of the UI shell. It has controls and content that, in general, drive the contents of the local and contextual areas. Tasks lists in the Regional Area automatically are bulleted to make it clear when a line item wraps to the next line.

    • Local Area: The local area is in the center of the UI shell, where users do their work. It is the main work area and typically contains the transaction form with the menus and controls that enable users to be productive. Controls in, and the content or state of, the local area, in general, drive the contents of the contextual area.

      • Main Area: This term designates the combination of the Local Area and the Contextual Area.

    • Contextual Area: The contextual area is in the right pane of the UI shell, with controls and contents that, in general, are driven by controls in, or the content or state of, the local area; although in specific cases the contextual area can also, in turn, drive the contents of the local area (causing a local-area reload).

  • Application designers, customers, and administrators can set the regional area and contextual areas as collapsed for specific applications. End-users can expand those areas at runtime.

  • If there is no content in the regional or contextual area, the area is collapsed and the ability to expand it is disabled.

  • The Contextual area is directly bound to the Local area. The application developer shall be able to bind contextual area content to the local area such that each invocation of a local area shall automatically cause a relevant contextual area in the right state to show up alongside the local area.

14.1.2.1 Global Area Standard Links

The Global Area incorporates a number of built-in indicators and links.

  • Home

    Click this link to return to the defined Home page. See Section 14.18, "Implementing the Oracle Fusion Home Page UI."

  • Navigator

    The Navigator menu, shown in Figure 14-18, is rendered when the Navigator link is clicked on the UI Shell. See Section 14.5.1.2, "Displaying the Navigator Menu."

  • Recent Items

    Recent Items tracks a list of the last 20 task flows visited by a user. See Section 14.11, "Implementing Recent Items."

  • Favorites

    Add to Favorites takes the most recent Recent Item (see Section 14.11, "Implementing Recent Items") and persists it into the Favorites list.

  • Tags

    Tagging is a service that allows users to add tags to arbitrary resources in Oracle Fusion Applications so they may collectively contribute to the overall taxonomy and discovery of resources others have visited. See Section 14.10, "Implementing Tagging Integration."

  • Watchlist

    Watchlist is a user-accessible UI that provides a summary of items the user can track with drilldown shortcuts. See Section 14.12, "Implementing the Watchlist."

  • Group Spaces

    Group Spaces bundle all the collaboration tools and provide an easy way for users to create their own ad hoc collaborative groups around a project or business artifact. See Section 14.13, "Implementing Group Spaces."

  • Personalization

    The Personalization menu options let you set your preferences, edit the current page, and reset the content and layout. See Section 14.6, "Using the Personalization Menu."

  • Accessibility

    The Accessibility link appears on pages that can be accessed without logging in. It will allow users to set their accessibility preferences because the Personalization menu, which includes preferences, is hidden for anonymous users.

  • Administration

    The Administration menu options allow you to customize the current page at a multi-user level, allows you to manage sandboxes, and allows you access to the setup applications. See Section 14.8, "Using the Administration Menu."

  • Help

    The Help menu options let you control trace levels, run diagnostics, and provide an About page that lists information about the application. See Section 14.9, "Using the Help Menu."

  • Sign In / Sign Out

    There are two possible scenarios during run-time:

    • The application is not secured. In this case, there is no concept of the user being Logged In (authenticated) or Logged Out (not authenticated).

      • The commandLink displays the text Sign In and is disabled.

      • There is no user name displayed next to the commandLink.

    • The application is secured with ADF Security.

      If the user is Logged In:

      • The commandLink displays the text Sign Out and is enabled.

      • The logged-in user name is displayed next to the Sign Out link.

      • If Oracle WebLogic Server is configured to authenticate with Oracle Internet Directory (OID) LDAP, the user name is the display name of the authenticated user principal.

      If the user is Logged Out. (The only way for an unauthenticated user to view a page is if a page either has no databinding (no pagedef) or has databinding but is granted to the anonymous role.)

      • The commandLink displays the text Sign In and is enabled.

      • No user name is displayed next to the Sign In link.

When the Sign Out link is clicked, the page is always redirected back to the current page. On clicking the Sign Out link, the user session is cleared from the cookie and terminated. If the page was secured, the user is logged out of ADF/SSO Authentication and redirected to a login page. If the page was not secured, or if the anonymous role has been granted view permission to the current page, the same page will be displayed with the Sign In link and a blank username.

14.2 Populating a UI Shell

The UIShell is a page template with some facets for content that may be placed directly on the page, but it usually has its content inserted dynamically. The dynamic insertion happens by reading metadata in the form of a menu metadata. This informs it of which taskflows to load and where. The UIShell also can create a list of tasks, from the same metadata, that, when clicked, can load into the Main Area. All task flows and the page built by the UIShell template follow the normal ADF Security framework.

When you create an application using the Fusion Web Application (ADF) template, two projects automatically are created for you: the data model and the user interface projects. The default names for these projects that JDeveloper provides are Model and ViewController. You then add the Applications Core (ViewController) tag library to the user interface project.

14.2.1 How to Create a JSF Page

Creating a page also creates your application's workspace, where you will later place your page fragments and task flows. For more information about task flows, see the "Getting Started with ADF Task Flows" section of the Oracle Fusion Middleware Fusion Developer's Guide for Oracle Application Development Framework.

For more information about starting JDeveloper, see Chapter 2, "Setting Up Your Development Environment."

To create a JSF page:

  1. Select the user interface project in the Application Navigator.

  2. Choose File > New > Web Tier > JSF > JSF Page.

    The Create JSF Page dialog is displayed, as shown in Figure 14-2.

    Figure 14-2 Create JSF Page Dialog

    Create JSP Page dialog example.
  3. In the dialog:

    • Enter a file name and directory path.

      The filename should follow these patterns:

      • [<Product Code><LBA Prefix>]<Role>Dashboard.jspx

      • [<Product Code><LBA Prefix>]<Object>Workarea.jspx

    • From the Use Page Template list, select UIShell.

      Note:

      The af:skipLinkTarget tag has been incorporated in the UIShell.jspx template so developers do not need to code this required accessibility feature in each page.

      Specifically, <af:skipLinkTarget/> has been inserted before the SingleObjectContextArea facet in UIShell.jspx:

      <af:panelGroupLayout inlineStyle="width:100%;"
      id="soContextParent">
           <af:skipLinkTarget/>
              <af:facetRef facetName="SingleObjectContextArea"/>
      </af:panelGroupLayout>
      
    • Check Create as XML Document (*.jspx).

    • Click OK.

  4. The new JSF page is displayed in the editor. Note that the page headers in the Design view do not display exactly as they will at runtime.

    Note:

    This JSPX page is just the container for the UI Shell template. All other page content, such as the regional, local, and contextual area flows, and the dynamic task flows, are defined independently. At runtime, the menu definition assembles the various parts. All task flows are loaded into a page created with the UI Shell template by configuring the Menu file. This is done to control the behavior and for dynamic loading of task flows at runtime. It also creates the Navigator Menu and Task List Menu. See Section 14.5, "Working with the Global Menu Model" and Section 14.2.1.1, "Working with the Applications Menu Model."

Now you can add components to the page. Table 14-1 lists the itemNode properties that can be used for a JSF page. See Section 14.2.1.1, "Working with the Applications Menu Model" for how to add a menu to the page.

Table 14-1 itemNode Properties of a JSF Page

ItemNode Property Property Value Description

action

Name that has been assigned to the action.

Navigate to the page defined by the action.

dataControlScope

string

Values are shared (the default) or isolated.

This is set at the page level itemNode. When dataControlScope is set to "isolated", the UI Shell loads the Main Area and Regional Area task flows with dataControlScope set to "isolated". When dataControlScope is set to "shared", the UI Shell loads the Main Area and Regional Area task flows with dataControlScope set to "shared".

For example:

<itemNode id="itemNode_AppsPanelTests_TabsWA"
label="label_AppsPanelTests_TabsWA" action="AppsPanelTests_TabsWA"
focusViewId="/AppsPanelTests_TabsWA" dataControlScope="isolated">

isDynamicTabNavigation

True or False

Provides an option to suppress dynamic tab navigation and just display one main area at a time. To do this, add the following property and value to the itemNode that represents your JSPX:

isDynamicTabNavigation="false"

Other menu metadata stay the same. Tasks List will continue to render. Clicking a Tasks Link will replace the current main area task flow with the new one.

Multiple defaultMain definitions are allowed and will open multiple tabs on page load. The first one with disclosed="true" will be the tab in focus.

If the property value is not defined, it defaults to true.

id

Unique identifier.

 

label

string

What appears in the work area title.

Note: For all UIShell work area pages with Data Visualization Tool (DVT) components in the default Main flow, and for Home pages with DVT components, you must create the af:document title as an Expression Language expression that sets the title with the default Main flow label, as shown in this example:

<af:document id="d1"
   title="#{adfBundle['oracle.apps...resource.xyzGenBundle']['Header.DefaultMain']} -
   #{adfBundle['oracle.apps...resource.xyzGenBundle']['Header.WorkAreaLabel']} -
   #{adfBundle['oracle.apps.common.acr.resource.ResourcesGenBundle']['Header.OracleApplications']}" >

For UIShell pages with DVT components in their dynamic Main flows, the title is set on the AdfRichDocument by UIShell code for openMainTask, closeMainTask and tab switch.

focusId

Name of the View Activity.

 

formUsesUpload

True or False. Default is False.

To set the UI Shell's af:form uses Upload value to "true," product teams need to add the formUsesUpload="true" property to the itemNode that represents the JSPX (similar to the way isDynamicNavigation is set.)

regionalAreaWidth

Numeric value

See Section 14.4.2, "How to Control Regional Area Task Flows".

isRegionalAreaCollapsed

True or False

See Section 14.4.2, "How to Control Regional Area Task Flows".


14.2.1.1 Working with the Applications Menu Model

Page and task flow information are local to a particular JDeveloper application or project and are exposed using the Applications Menu Model.

An Applications Menu is related to a local JSPX file and includes the tasks list, defaultMain, and defaultRegional. A menu is created for each J2EE application.

14.2.1.1.1 How to Create an Applications Menu

To create an ADF menu to access page elements through the Navigator menu on JSF pages or task flows that are based on the UI Shell template:

Select the JSPX page in the Application Navigator, then right-click and select the Create Application Menu option.

This step creates the menu file with one itemNode. The menu file will be named <view id>_taskmenu.xml. For example, if there is a PageA.jspx, its view id in adfc-config.xml is PageA, and the menu file name is PageA_taskmenu.xml. This step also should add the ApplicationsMenuModel managed bean entry into adfc-config.xml. The managed bean entry should not have the topRootModel managed bean property set. Example 14-1 shows a sample of the generated content in PageA_taskmenu.xml.

Example 14-1 Example of Generated Content in a taskmenu.xml

<?xml version="1.0" encoding="UTF-8" ?>
<menu xmlns="http://myfaces.apache.org/trinidad/menu">
  <!-- This is the page level node -->
  <itemNode id="itemNode_PageA" label="label_PageA" action="adfMenu_PageA"
            focusViewId="/PageA">
            <!-- Optional itemNode for Regional Task List task flow. Your task menu def may omit this if your page does not display a Regional Task List. -->
            <itemNode id="__myProduct_RegionalTaskList"
                      focusViewId="/PageA"
                      label="#{applcoreBundle.TASKS}" taskType="defaultRegional"
                      taskFlowId="/WEB-INF/oracle/apps/fnd/applcore/patterns/uishell/ui/publicFlow/TasksList.xml#TasksList"
                      disclosed="true"
                      parametersList="fndPageParams=#{pageFlowScope.fndPageParams}"/>
            <!-- Typical itemNode entry for a task flow -->
            <itemNode id="__myProductTFId"
                      focusViewId="/PageA"
                      label="#{myBundle.myProductTFxyz}" taskType="defaultMain"
                      taskFlowId="<fully-qualified-TFid>"
                      disclosed="true""/>
            <!-- .. additional itemNodes for other task flows on PageA -->
  </itemNode>
</menu>

Creating ADF Menus for Multiple JSF Pages

Use this alternate method to create menus for multiple pages at once. This will create an empty menu on each page.

  1. Right-click the adfc-config.xml file and choose Open to display it in the JDeveloper editor.

    The adfc-config.xml file is located in the following location: <project_name> > WEB INF.

  2. Drag pages from the Application Navigator panel to the adfc-config.xml file in the editor.

    View nodes that represent the pages or task flows are displayed in the editor.

    When you drag the pages or task flows, they automatically are grouped into the same menu.

  3. Right-click the adfc-config.xml file and choose Create Applications Menus. An empty panel, as shown in Figure 14-3, displays.

    Figure 14-3 Initial Create Applications Menus Display

    Initial Create Applications Menus Display
  4. Click Find Pages to populate the display with all the JSPX pages that have been added to adfc_config.xml. As shown in Figure 14-4, pages that do not yet have a menu associated with them will have a checkbox that defaults to being selected, and pages that already have an associated menu are shown with a checkmark to the right.

    Figure 14-4 Populated Create Applications Menus Display

    Populated Create Applications Menus Display
  5. Click OK to automatically create a menu file for each selected page and to update the task flow with a managed bean.

    Note:

    Menu files will follow the <focusViewId>_taskmenu.xml naming standard. For example, the menu file for Example.jspx will be /WEB-INF/menus/Example_taskmenu.xml.

    When you create this menu file, the following occurs:

    • The menu file is generated and placed into the following directory: ViewController/public_html/WEB-INF/menus.

    • The following are generated and appear in the adfc-config.xml file:

      • A new control-flow rule

      • A managed bean entry

    The new menu that contains your pages is now accessible from the Navigator panel.

14.2.2 How to Add Default Main Area Task Flows to a Page

When a user opens an application, he or she expects something to be displayed automatically. A task flow in the default main area accomplishes this.

To add a task flow to the default main area:

  1. Choose File > New > Web Tier > JSF > JSF Page Fragment.

    The Create JSF Page Fragment dialog shown in Figure 14-5 is displayed.

    Figure 14-5 Create New JSF Page Fragment Dialog

    Create a New JSF Page Fragment Dialog
  2. In the Create New JSF Page Fragment dialog:

    1. Enter a page-fragment name. For example, you might enter def_main.jsff.

      The filename should follow these patterns:

      • <Object><Function>.jsff

      • <Object>.jsff

      The page name should convey the object it presents (an employee, a supplier, an item, a purchase order, an applicant, and so on), and the function being performed (search, promote, hire, approve, view). For some pages, the object is sufficient.

      For update/create pages, just the object should be used (unless the create and update pages are different as shown in the examples).

      Never give pages step number names, such as PoCreateStep1.jsff or PoCreateStep2.jsff. Always describe the page function, such as PoDesc.jsff or PoLines.jsff.

    2. From the Use Page Template list, select UIShellMainArea.

      Note:

      The UIShellMainArea template is only for main-area task flows, not regional area task flows.
  3. Click OK.

    The local and contextual area facets of the page fragment appear in the editor.

  4. Choose File > New > JSF > ADF Task Flow to create a default task flow.

    Note:

    Most applications will have multiple task flows for the Regional, Local and Contextual areas. For instance, Figure 14-1, "UI Shell Areas" shows 10 task flows.

    The Create ADF Task Flow dialog shown in Figure 14-6 is displayed.

    Figure 14-6 Create ADF Task Flow Dialog

    Create ADF Task Flow dialog.
  5. Make sure that the JSF page fragment file is selected in the Application Navigator and is displayed in the Edit view.

    1. In the Edit view, click the Source tab.

    2. Locate the line that resembles <f:facet name="localArea"/>.

    3. In the Application Navigator pane, select an applicable task flow, such as the one you created in Step 4, to add to the localArea. This should be an XML file located under ViewController > Web Content > WEB-INF > oracle > apps > application_name > ui > flow.

    4. Drag and drop the appropriate flow from the Navigator pane to immediately following <f:facet name="localArea"/>.

    5. From the Create menu that displays, select Region.

      The <f:facet name="localArea"/> changes to <f:facet name="localArea"> and code resembling that shown in Example 14-2 will be inserted after it.

      Example 14-2 Creating Region localArea Facet Added Code

      <af:region value="#{bindings.EmpCreateUpdateFlow1.regionModel}"
                       id="EmpCreateUpdateFlow1"/>
      </f:facet>
      

      In the Structure window, an af:region entry is added following the f:facet - localArea entry.

    6. Note: This step is optional. If you do not need a contextualArea, skip to Step 6.

      In the Structure window, select f:facet - contextualArea.

    7. In the Component Palette, select ADF Faces > Layout.

    8. Click Panel Accordian. An af:showDetailItem entry is created automatically under af:panelAccordian.

    9. In the Source view, find and highlight the new <af:showDetailItem ...> entry.

    10. In the Application Navigator pane, select an applicable task flow, such as the one you created in Step 4, and drag and drop it onto the highlighted entry in Source view.

    11. From the Create menu that displays, select Region.

    12. Click OK on the Edit Task Flow Binding dialog that displays.

      Code resembling that shown in Example 14-3 will be inserted after <af:showDetailItem ...> and the page fragment in the editor will resemble Figure 14-7.

      Example 14-3 Example Edit Task Flow Binding Code

      <af:region value="#{bindings.EmpSummaryTF2.regionModel}"
       id="EmpSummaryTF2"/>
      

    Figure 14-7 ADF Faces Components in Page Fragment Editor

    ADF Faces Components in Page Fragment Editor

    Now that you have created the Main Area page fragment, you must wrap it in an ADF task flow.

  6. In the Create ADF Task Flow dialog:

    • Enter a descriptive name for the task flow.

      For example, enter def_main_task-flow-definition.xml.

    • Make sure that the Create as Bounded Task Flow and the Create With Page Fragments boxes are checked.

      Do not change the other default settings.

  7. Click OK.

    The new task flow is displayed as a blank visual editor in the JDeveloper middle section.

  8. In the Application Navigator, select your recently-created page fragment (.jsff file), and drag and drop it onto the editor.

    The page fragment itemNode appears in the editor, as shown in Figure 14-8.

    Figure 14-8 Page Fragment itemNode

    Page fragment item node.
  9. To load the menu metadata:

    Note:

    The menu data accomplishes several important jobs for you:
    • It defines properties of the page for you. For instance, it will be displayed in no-tab mode or with dynamic tabs, and define the width of Regional Area.

    • Can create a task list menu for each page.

    • Can create labels for groups of tasks.

    1. In the Application Navigator, select the test_menu_taskmenu.xml file that you created using the ADF Menu Model dialog. For details about creating the menu, see Section 14.2.1.1.1, "How to Create an Applications Menu."

    2. In the test_menu_taskmenu.xml structure view menu tree, shown in Figure 14-9, right-click the itemNode item and choose Insert inside itemNode <task_flow_name> > itemNode.

    Figure 14-9 Task-Flow Item Node Menu Choices

    Task-Flow Item Node menu choices.

    The Insert itemNode - Common Properties dialog, shown in Figure 14-10, is displayed.

    Figure 14-10 Insert itemNode - Common Properties Dialog

    Insert itemNode Common Properties dialog.
  10. To the right of the focusViewId field, click the ellipsis to display the Edit Property dialog.

    In the dialog, choose the ADFc View Activity id of the page under which you are registering the task flow, then click OK.

  11. Enter a unique ID using this standard format:

    <pageID>_<taskFlowName>

    This ID example consists of the concatenated page ID (or page name), an underscore, and the task flow name. For example, ExpenseWorkArea_CreateExpense.

  12. Click Finish.

    The new item node is displayed in the structure view, under the menu tree.

  13. With the item node selected in the structure view, click the Property Inspector tab, as shown in Figure 14-11.

    Figure 14-11 Task Flow Property Inspector

    Task flow property inspector editing
  14. In the label field, enter a label for the task flow, such as CreateExpense.

    This label will be the title of the tab that is opened by the Task Type defaultMain.

    Note:

    Do not leave this field null. This is the label that will appear in the tab header when in a tabs page. Even if you are in a no-tabs page (see Section 14.2.3.4, "Supporting No-Tab Workareas"), do not leave it blank because this label will be used in other ways, such as Add to Favorites, or when the system tracks the Recent Items.
  15. Select test_menu_taskmenu.xml in the Project Navigator tree, and your task flow in the structure view to display its Property Inspector, or select the Property Inspector tab.

    In the Advanced section of the Property Inspector, enter the following values:

    • Task Type: defaultMain (task flow is displayed by default whenever the page is rendered).

      The Data Control Scope should have been set to isolated, inside the task flow definition for any taskflow in the menu (defaultMain or dynamicMain) or any call from openMainTask. See dataControlScope in Table 14-1.

    • Task Flow Id: ID of the task flow to be loaded.

      To enter the ID, click the ellipsis to display the Select Task Flow Id dialog, shown in Figure 14-12, and browse to the task-flow definition location. By default, following the standard naming structure, the location will be in path_to_application directory\ViewController\public_html\WEB-INF.

      Figure 14-12 Select Task Flow Id Dialog

      Select Task Flow Id Dialog.

      Click Open to automatically enter the location in the Task Flow field. The task flow ID is a concatenation of the file location for the task-flow definition and the task-flow name. It typically resembles /WEB-INF/MyTaskFlow.xml#MyTaskFlow. The Property Inspector for the itemNode should resemble the example shown in Figure 14-11, "Task Flow Property Inspector".

  16. To run the JSPX page, select the page in the Application Navigator, right-click the page file, and choose Run.

    The new page, shown in Figure 14-13, is displayed in a web browser.

    Figure 14-13 Rendered Page in Browser

    Rendered page in browser
  17. Check that the newly rendered page contains one tab whose content is the task flow that you defined in this procedure.

The available itemNode properties for Main and Regional task flows for application menus are shown in Table 14-2.

Table 14-2 itemNode Properties for Main and Regional Task Flows for Application Menus

itemNode Property Property Value What Happens on the Rendered Page

taskType

Note: taskType can have four values:

  • dynamicMain

  • defaultMain

  • defaultRegional

  • taskCategory

  • If the value is dynamicMain, the page contains a new link in the regional area. When you click the link, a new tab with the loaded task opens.

    If the no-tabs model is used, no new tab is opened. Rather, the current main area contents are replaced. (See Section 14.2.3.4, "Supporting No-Tab Workareas.")

  • If the value is defaultMain, the page contains a tab already running this task in the main area.

    If the no-tabs model is used, only one itemNode should be defined as a defaultMain. (See Section 14.2.3.4, "Supporting No-Tab Workareas.")

  • If the value is defaultRegional, the task is loaded into the regional area.

label

String

Note: When passing parameters, do not leave the label field null. This is the label that would appear in the tab header when in a tabs page. Even if you are in a no-tabs page (see Section 14.2.3.4, "Supporting No-Tab Workareas"), do not leave it blank because this label will be used in other ways, such as Add to Favorites, or when the system tracks the Recent Items.

taskFlowId

ID of the task flow to be loaded.

The task flow ID is a concatenation of the file location for the task-flow definition, and the task-flow name. For example:

/WEB-INF/MyTaskFlow.xml#MyTaskFlow

 

reuseInstance (optional)

True or False

If True, when the link is clicked a second time, the tab is brought to the top.

A False value means that clicking the corresponding task link opens new tabs.

However, if the no-tabs model is used, no new tab is opened. Rather, the current main area contents are replaced. (See Section 14.2.3.4, "Supporting No-Tab Workareas.")

keyList

String

Important: keyList is used with the task flow ID to identify the target "tab" in the Main Area. As such, keyList is only applicable in dynamic tabs mode, and is ignored in no-tabs mode.

keyList provides a way to identify a task flow instance. When reuseInstance is true, use the specified keyList in addition to the task flow ID to identify the target tab.

The keyList parameter has been implemented for the following FndUIShellController DataControl methods:

  • openMainTask

  • discloseRegionalTask

  • collapseRegionalTask

  • navigate

  • openSubTask

In dynamic tabs mode, when looking for a match of a existing tab, these APIs will first look for any instances of the task flow that is already open, which has the same task flow ID as the one passed into them as the parameter. In addition, it will compare the keyList values, such that the existing task flow will be picked only if its keyList values match the ones specified in the keyList parameter.

It does not matter if the task flow parameters are the same or different. If the keylist is not set in the menu metadata, you can only reuse a tab if you pass in a null keylist.

loadPopup

True or False

See Section 14.2.3.5, "Implementing the Task Popup."

Provides a way to load the task flow into a Popup when the user clicks one of the Tasks List links.

loadDependentFlow

True or False

No-tab navigation mode can load a main flow and a dependent flow simultaneously, while displaying only one flow at a time. (See Section 14.2.3.4, "Supporting No-Tab Workareas.")

The UI Shell is limited to 12 flows: 10 tabs in tab mode; 1 tab in no-tab mode and 1 dependent in no-tab mode.

Dependent Flow is applicable only to no-tab navigation model. Instead of having only one region for the no-tab navigation model, there are two regions: one for the main flow and another for the dependent flow. These regions are in a switcher, so that only one is visible at a time. If a dependent flow is loaded, only the dependent flow region is shown, and the main flow region is hidden. When the dependent flow is closed, the main flow region is redisplayed, with its state preserved.

When loadDependentFlow is "true," the openMainTask API will load the target task flow in the dependent region. Loading a new task flow in the main flow will close both the existing main flow and, if any, the existing dependent flow. Loading a new task flow in the dependent flow will replace only the existing dependent flow, if any, and leave the main flow intact.

forceRefresh

True or False

If forceRefresh = true, the contents are refreshed. If forceRefresh is set to false, if the task flow parameters are identical, no refresh will occur, but if they are different, the task flow is refreshed using the new parameters.

stretch

True (default) or False

When the UIShellMainArea stretch attribute is set to "true", contents under "localArea" will be stretched when rendered in the Local Area. When set to "false," contents under "localAreaScroll" will not be stretched, but will render with a scroll bar, if necessary, in the Local Area. (This facet is contained within an af:panelGroupLayout with layout=scroll.)

disclosed (optional)

True or False

All the task flows will render in the Main area. The task flow that has disclosed set to True will be in focus.

More than one defaultRegional task can have a True disclosed value, because more than one detail item may be disclosed at a time under a panelAccordion component. If the disclosed value is true, the regional area is expanded. If the disclosed value is false, the regional area is collapsed.

active

True or False

Default is false.

Task flow definitions use conditional activation. There are a number of cases in which Oracle Fusion Applications run with the regional area collapsed by default. Unless the user expands it, there is no need to activate the task flows for the regional area. However, some use cases depend on the task flow that is under the regional area being active even when collapsed. In this case, the active attribute can be set in the property inspector for the item node. active has three possible values:

  • default <False>

  • False

  • True

If you require that your task flows be activated or run even though they are not displayed, you will need to change the active property on the itemNode to True.

taskFlow

 

The Tasks List is exposed as a task flow. See Section 14.2.4, "How to Pass Parameters into Task Flows from Tasks List."

destination

String

The destination attribute is supported on the item nodes for Task List; that is, for item nodes that have task type set to dynamicMain. The destination is intended only for navigating to an external web site. When it is defined, it takes precedence over all other attributes. Example of the menu data:

<itemNode id="__ServiceRequest_itemNode_externalUrl"
   destination="http://www.yahoo.com"/>

14.2.3 How to Add Dynamic Main Area and Regional Area Task Flows to a Page

Unless otherwise noted, follow the procedure outlined in Section 14.2.2, "How to Add Default Main Area Task Flows to a Page," to insert the appropriate itemNode properties listed inTable 14-2.

  • To add a dynamic main area task flow, set taskType="dynamicMain".

  • To add a default regional area task flow, set taskType="defaultRegional".

14.2.3.1 Adding the Tasks List Menu to the Page

A tasks list is not a default widget as part of the UI Shell Regional Area. A tasks list is packaged as an ADF Controller task flow. You must manually add this task flow as you would any other defaultRegional Task.

You need to specify the tasks list task flow as a defaultRegional Task explicitly. If you do not do this, the tasks list does not render.

Add the following entry to your menu.xml file prior to the item node of tree structure and tree versions:

<itemNode id="__YourPage_itemNode__FndTasksList"
        focusViewId="/YourPage" label="#{applcoreBundle.TASKS}"
        taskType="defaultRegional"

Note: The taskFlowId value path must appear in a single line to avoid an exception during runtime.

taskFlowId="/WEB-INF/oracle/apps/fnd/applcore/patterns/
                    uishell/ui/publicFlow/TasksList.xml#TasksList"
        disclosed="true"
        parametersList="fndPageParams=
                             #{pageFlowScope.fndPageParams}"/>

where:

  • Id needs to be unique within the menu metadata.

  • focusViewId is the focusViewId of your page.

  • Set label to the default label provided by the Oracle Fusion Middleware Extensions for Applications (Applications Core).

  • taskType should be defaultRegional.

  • taskFlowId should point to the tasks list task flow provided by Applications Core.

  • disclosed attribute is usually set to true. Although, it can be set to false if you do not want to disclose Tasks List by default.

  • parametersList should set fndPageParams as shown above so that this object is available in the pageFlowScope of the tasks list task flow. This context is necessary for Single Object WorkArea. For more information, see Section 14.19, "Using the Single Object Context Workarea."

14.2.3.2 Grouping Tasks in the Tasks Pane into a Category

The Task Category is a label that is used to group tasks in a task list.

  1. In the Structure window for the menu, right-click the page itemNode whose taskType value is dynamicMain and choose Surround with... .

    The Surround dialog is displayed.

  2. Select itemNode and click OK.

    The Insert Item Node dialog page opens to the Common properties tab.

  3. In the Common properties tab, enter these values:

    • id field: Concatenation of the page id and a short category name, using the following format, is suggested:

      pageId_categoryName

      For example, you might enter: ExpenseWorkArea_NewExpense.

    • focusViewId: Click the ellipsis to open the Advanced Editor.

      Select the focusViewId of the page.

  4. Click Finish.

  5. In the Property Inspector for itemNode - ExpenseWorkArea_NewExpense, enter these values:

    • label: name of the label, such as NewExpense.

      Do not leave this field null. This is the label that would appear in the tab header when in a tabs page. Even if you are in a no-tabs page (see Section 14.2.3.4, "Supporting No-Tab Workareas"), do not leave it blank because this label will be used in other ways, such as Add to Favorites, or when the system tracks the Recent Items.

      Note:

      The label should be defined in a resource bundle so it can be translated more readily.
    • Task Type: taskCategory

  6. Run the page.

    To run the page, right-click the JSPX page file in the Projects tree view and choose Run.

    Check that the page contains task links arranged by category. The Task List is in the left Regional Area of the page. Items in the Task List are bulleted to make it clear when a line wraps.

14.2.3.3 Linking to a Task Flow in a Different Page

The Tasks Pane can link to a task flow in a different JSPX. It can pass page-level and task-level parameters.

The navigateViewId attribute supports this feature.

Example 14-4 shows a sample of the metadata for a link in a Task list that links to another page:

Example 14-4 Example Metadata for a Link in a Task List that Links to Another Page

<itemNode id="__ServiceRequest_itemNode__toTestPage1"
                focusViewId="/ServiceRequest" label="Go to different page"
navigateViewId="/TestPage1"
                taskType="dynamicMain"
taskFlowId="/oracle/apps/fnd/applcore/patterns/demo/SRTree.xml#SRTree"/>

14.2.3.4 Supporting No-Tab Workareas

Product teams can suppress dynamic tab navigation and just display one main area at a time. To do this, add isDynamicTabNavigation="false" to the itemNode that represents your JSPX page, as shown in Example 14-5.

Example 14-5 Implementing No-Tab Workarea

<itemNode focusViewId="/SelTestWorkarea" id="stp1" taskType="dynamicMain"
  taskFlowId="/WEBINF/oracle/.../ProductMainFlow.xml#ProductMainFlow"
  label="#{adfBundle
      ['oracle.apps....SelTestWorkarea_taskmenuBundle'].DEFINE_PRODUCT}"
  isDynamicTabNavigation="false"/>

Note that the default value of isDynamicTabNavigation is true.

You also can set no-tab mode declaratively in the Property Inspector:

  1. Select the itemNode from the Structure window.

  2. Go to Property Inspector.

  3. Select Advanced > Page > Dynamic Tab Navigation. Selecting the Page tab lets you set attribute values for Page-level item nodes.

  4. Set the Dynamic Tab Navigation property to false.

Other menu metadata stay the same. Tasks List will continue to render. Clicking a Tasks Link will replace the current main area task flow with the new one.

14.2.3.5 Implementing the Task Popup

The Task Popup provides a way for product teams to:

  • Load their task flow into a popup when the user clicks one of the Tasks List links.

  • Cancel from the popup or open a new Main Area Task, passing in parameter values from the popup.

Implementation Notes

The UI Shell provides an af:popup component with a modal af:panelWindow as its immediate child, which would again contain a dynamic region defined in it. On user click, the UI Shell will load the product team's task flow into the dynamic region, and show the modal af:popup panelWindow without any buttons. Therefore, the product team's task flow must include the OK and Cancel buttons that are used to launch a dynamic tab and dismiss the popup, respectively. The dialog title will be set according to the label mentioned in the menu meta data of the dynamic task link. There is a refresh condition set on the dynamic region that refreshes the task flow and reloads it each time the popup is launched.

Developer Implementation

There are several considerations to keep in mind when you implement the Task Popup:

  • For a dynamicMain Task item that you would like to load into the popup, specify the loadPopup property as true. For example, as shown in Example 14-6, the ChooseSR Task Flow would be loaded in a popup when the user clicks its link in the Tasks List. The label that is mentioned will be displayed as the dialog title of the popup that launches the task flow.

    Example 14-6 Example Use of loadPopup Property

    <itemNode id="__ServiceRequest_itemNode__ChooseSR"
              focusViewId="/ServiceRequest" label="Choose SR"
              taskType="dynamicMain" taskFlowId="/WEB-INF/ChooseSR.xml#ChooseSR"
              parametersMap="#{pageFlowScope.Mybean.Map}"
              loadPopup="true"/>
    
  • Developers can define any components within this task flow, except the af:popup and its child components, such as af:dialog, af:panelWindow, and af:menu.

  • Teams cannot have a UIShellMainArea page template or any other templates inside the popup task flow.

  • Developers must add the necessary buttons as part of the task flow. For example, if the task flow has a simple .jsff file, it should contain OK and Cancel buttons, along with other components.

  • Create a managed bean to set the action listener for the Cancel button. See Section 16.4.1.3, "Implementing OK and Cancel Buttons in a Popup."

  • Create another method for the OK button that calls the method in Example 16-5, and any additional processing logic. The common use case would be opening a new task in the Main Area by using the openMainTask API. For example, you can bind the OK button to a managed bean and add your own action listeners. See Section 16.4.1.3, "Implementing OK and Cancel Buttons in a Popup."

  • Developers then can pass the parameters directly from the managed bean to the openMainTask API bindings for the popup task flow page to launch a new dynamic tab. The menu data entries for parameters will not have any bearing on the dynamic taskFlow tab that they are loading in the main area. The details of that task flow should come from the openMainTask API that is bound to the OK button.

14.2.4 How to Pass Parameters into Task Flows from Tasks List

itemNodes with taskType of dynamicMain, defaultMain, and defaultRegional have parameter support. In addition to specifying the taskFlowId to load when the user clicks a Task link, developers can specify which parameters to pass into that task flow. This is accomplished with the parametersList and methodParameters properties on the itemNode.

For the itemNode where you would like to specify parameter passing, add the parametersList property. The value of this property is a delimited list of parameter name-value pairs that will resemble Example 14-7.

Example 14-7 Using the parametersList Property

<itemNode id="__ServiceRequest_itemNode__SRDefault" focusViewId="/ServiceRequest" label="Pending Service Requests"
taskType="dynamicMain"
taskFlowId="/oracle/apps/fnd/applcore/patterns/demo/SRTable.xml#SRTable"
parametersList="param1=value1;param2=value2;param3=#{ELForValue3}"/>

methodParameters can be used for passing a Java object into the task flow that is specified in the taskFlowId parameter. Use the setCustomObject() API in FndMethodParameters for setting the Java object.

Example of Passing a Java Object Using openMainTask

Bind the methodParameters parameter value to a managed bean property. Example 14-8 shows the method action binding in the page definition of the page fragment that calls openMainTask. Also see Table 14-2, "itemNode Properties for Main and Regional Task Flows for Application Menus".

Example 14-8 Method Action Binding to Call openMainTask

<methodAction id="openMainTask" RequiresUpdateModel="true"
                  Action="invokeMethod" MethodName="openMainTask"
                  IsViewObjectMethod="false" DataControl="FndUIShellController"
                  InstanceName="FndUIShellController.dataProvider"
                  ReturnName="FndUIShellController.methodResults.openMainTask_FndUIShellController_dataProvider_openMainTask_result">
      <NamedData NDName="taskFlowId"
                 NDValue="/WEB-INF/TestPanelSplitterTaskFlow#TestPanelSplitterTaskFlow"
                 NDType="java.lang.String"/>
      <NamedData NDName="keyList" NDType="java.lang.String"/>
      <NamedData NDName="parametersList" NDValue="" NDType="java.lang.String"/>
      <NamedData NDName="label" NDValue="Test App Panel"
                 NDType="java.lang.String"/>
      <NamedData NDName="reuseInstance" NDType="java.lang.Boolean"/>
      <NamedData NDName="forceRefresh" NDType="java.lang.Boolean"/>
      <NamedData NDName="loadDependentFlow" NDValue=""
                 NDType="java.lang.Boolean"/>
      <NamedData NDName="methodParameters" NDValue="#{TestOpenMainTaskMBean.fndMethodParams}"
                 NDType="oracle.apps.fnd.applcore.patterns.uishell.ui.bean.FndMethodParameters"/>
    </methodAction>

Code in the managed bean for passing a hashmap to the task flow would resemble Example 14-9.

Example 14-9 Example Code for Passing a Hashmap

private FndMethodParameters fndMethodParams;
  ...
  public void setRichCommandLink1(RichCommandLink richCommandLink1)
  {
    this.richCommandLink1 = richCommandLink1;
    FndMethodParameters methodParams = new FndMethodParameters();
    HashMap testHashMap = new HashMap();
    testHashMap.put("param1", "12345");
    testHashMap.put("param2", "67890");
    methodParams.setCustomObject(testHashMap);
    fndMethodParams = methodParams;
  }

Then, in the managed bean of the task flow, the Java object can be read, as shown in Example 14-10.

Example 14-10 Reading Java Object in Managed Bean

public String getTestValue()
  {
    Map pageFlowScope =
      AdfFacesContext.getCurrentInstance().getPageFlowScope();
    Object custom = pageFlowScope.get("fndCustomObject");
    String outputTextString = "";
    if (custom != null && custom instanceof HashMap)
    {
      HashMap myHashMap = (HashMap)custom;
      String temp1 = (String)myHashMap.get("param1");
      String temp2 = (String)myHashMap.get("param2");
      outputTextString = temp1 + temp2;
    }
    testValue = outputTextString;
    return testValue;
  }

where testValue is bound to an af:outputText value attribute, such as <af:outputText value="#{TestPanelSplitter1MBean.testValue}"/>, in the page fragment of the task flow.

14.2.5 How to Launch Data Files from a Tasks List Link

The UI Shell implements this feature by using the URLView activity that is a task flow component of ADF. URLView generally is used to redirect the current request state of the application to an external or internal URL. With UI Shell, this URLView activity is only being used to launch files that are internal to the current web application.

Therefore, the only input that the task list link will need is the internal path (within the webApp) of the file. Once the path is provided to UI Shell, it will determine the current contextual root of the application and append it to the internal path of the file. Once the URI for the file is generated, this is set on the URLView activity and an action expression is set on the task link to launch the URL view. UI Shell also needs to call an actionEvent javascript method on the client side that will not allow the page to lose its current state upon redirection from the URLView activity.

Limitations

Product teams can only launch data files that are part of their webApp, such as /oracle/apps/fin/acc/file1.xls. This feature only supports the launch of data files through the task list. Any other URI paths, such as a JSPX or a JSF page, are not supported.

Developer Implementation

For a dynamicMain task item that you would like to use to launch the data file, there is a property called filePath in the Menu Panel for the UI Shell page XML file. To enable this property in the Menu panel, during design time, the task type of the itemNode must be dynamicMain. The file URI path then should be specified against the filePath attribute in the Menu panel, as shown in Example 14-11.

Example 14-11 Specifying the File URI Path

<itemNode id="__ServiceRequest_itemNode__ChooseSR"
          focusViewId="/ServiceRequest" label="Download File"
          taskType="dynamicMain" filePath="/WEB-INF/oracle/apps/Accounts.xls" />

You can specify any file type, such as xls, doc, pdf, txt, rtf, and ppt, that is within the application.

The Preference link and other links only appear if you have the ApplSession filter and mapping setup. See Section 48.2, "Configuring Your Project to Use Application User Sessions."

14.3 Implementing Application Menu Security

Security of menus has two parts: actual access to the page or task flow, and the rendering of the menu itself. Any page or task flow is protected to only run for a user if that user has access to run the page or task flow. Directions for setting this up are in the "Adding Security to an Oracle Fusion Web Application" chapter in the Oracle Fusion Middleware Fusion Developer's Guide for Oracle Application Development Framework.

Application menus and taskList menus will automatically have their page security checked by the menu utilities. If the user does not have access, the menu entry will not be rendered. If these three conditions are true, security checks if a logged-in user has view privilege for a given task flow.

If any of these conditions are not true, security is not checked and the itemNode will be protected only by the rendered attribute.

Application menus can have a security Expression Language expression on the rendered attribute that, if it returns false, will not render the menu entry. To do this, set the rendered attribute of the menu entry to an expression that evaluates anything. For instance, if the task list is to edit certain tax forms, this could be a business rule to hide or show links based on whether or not the customer is a non-profit company. If it evaluates to false, the menu will not appear. For more information on all the security expressions, see the "Adding Security to an Oracle Fusion Web Application" chapter in the Oracle Fusion Middleware Fusion Developer's Guide for Oracle Application Development Framework.

If your UI Shell pages are secured by ADF Security, you must add a policy, similar to Example 14-12, to the jazn-data.xml file and the system-jazn-data.xml file.

Example 14-12 Adding a Security Policy to the jazn-data.xml File

<grant>
  <grantee>
     <principals>
        <principal>
           <class>oracle.security.jps.internal.core.principals.JpsAnonymousRoleImpl</class>
           <name>anonymous-role</name>
        </principal>
     </principals>
  </grantee>
  <permissions>
      <permission>
         <class>oracle.adf.share.security.authorization.RegionPermission</class>
         <name>oracle.apps.fnd.applcore.uicomponents.view.pageDefs.oracle_apps_fnd_applcore_templates_UIShellPageDef</name>
         <actions>view</actions>
     </permission>
     <permission>
        <class>oracle.adf.controller.security.TaskFlowPermission</class>
        <name>/oracle/apps/fnd/applcore/patterns/uishell/MainArea.xml#MainArea</name>
        <actions>view</actions>
     </permission>
     <permission>
        <class>oracle.adf.controller.security.TaskFlowPermission</class>
        <name>/oracle/apps/fnd/applcore/patterns/uishell/RegionalArea.xml#RegionalArea</name>
        <actions>view</actions>
     </permission>
     <permission>
        <class>oracle.adf.controller.security.TaskFlowPermission</class>
        <name>/WEB-INF/oracle/apps/fnd/applcore/patterns/uishell/ui/publicFlow/TasksList.xml#TasksList</name>
        <actions>view</actions>
     </permission>
  </permissions>
</grant>

Task Flow Example

Bounded task flows are secure by default, and require the policy shown in Example 14-13.

Example 14-13 Required Policy for Bounded Task Flows

<permission>  <class>oracle.adf.controller.security.TaskFlowPermission</class>  <name>/WEB-INF/audit-expense-report.xml#audit-expense-report</name>  <actions>view</actions></permission>

If the policy is missing, then framework level checks will prevent access to the task flow (typically by throwing an error).

But how would a menu item or command link disable or hide itself based on a pre-check of the same permission? That's where an Expression Language expression comes in.

Example 14-14 shows the generic Expression Language expression being used to perform a pre-check of the Task Flow Permission. Note that this is only needed for an itemNode with taskType="defaultMain" or "defaultRegional". The security check is performed automatically for an itemNode with taskType="dynamicMain" (that is, what is in the tasks list).

Example 14-14 Generic Expression Language Expression Used for Task Flow Permission Pre-check

rendered = "#{securityContext.userGrantedPermission['permissionClass=oracle.adf.controller.security.TaskFlowPermission;
               target=/WEB-INF/audit-expense-report.xml#audit-expense-report;
               action=view']}"

Example 14-15 shows the task flow-specific Expression Language.

Example 14-15 Task Flow-specific Expression Language Expression Used for Task Flow Permission Pre-check

rendered="#{securityContext.taskflowViewable[/WEB-INF/audit-expense-report.xml#audit-expense-report]}"

Note that both of these checks actually go directly against the policy store; that is, they don't interrogate the task flow definition. This avoids the overhead of loading a large number of ADF artifacts to render links and menus.

14.4 Controlling the State of Main and Regional Area Task Flows

UI Shell tasks to open up or close a Main Area tab are exposed as data control methods so that you easily can create such UI artifacts through drag and drop. You do not need to create your own data control methods and manually raise Contextual Events.

14.4.1 How to Control Main Area Task Flows

Data control APIs are:

  • FndUIShellController.openMainTask

    Note:

    When passing parameters, do not leave the label field null. This is the label that would appear in the tab header when in a tabs page. Even if you are in a no-tabs page (see Section 14.2.3.4, "Supporting No-Tab Workareas"), do not leave it blank because this label will be used in other ways, such as Add to Favorites, or when the system tracks the Recent Items.
  • FndUIShellController.closeMainTask. See Section 14.4.1.1, "closeMainTask History" for more information.

For example, to open or close a Main Area tab, drag and drop the appropriate data control method to create the UI affordance. Having specified the parameter values into these methods, user clicks will prompt UI Shell to react accordingly.

To use the openMainTask data control method:

  1. Expand the Data Controls and select the openMainTask item, as shown in Figure 14-14.

    Figure 14-14 Selecting openMainTask from Data Controls

    Selecting openMainTask from Data Controls
  2. Drag openMainTask and drop it onto the page fragment. When you do, the Applications Context menu shown in Figure 14-15 displays so you can choose one of the three options.

    Figure 14-15 Selecting an Open Option from the Applications Context Menu

    Selecting from the Applications Context menu

To use the closeMainTask data control method:

  1. Expand the Data Controls and select the closeMainTask item, as shown in Figure 14-16.

    Figure 14-16 Selecting closeMainTask from Data Controls

    Selecting closeMainTask from Data Controls
  2. Drag closeMainTask and drop it onto the page fragment. When you do, the Applications Context menu shown in Figure 14-17 displays so you can choose one of the three options.

    Figure 14-17 Selecting a Close Option from the Applications Context Menu

    Selecting a close option from the Applications Context menu

Two APIs, shown in Example 14-16, are exposed to open and close a Main Area tab.

Example 14-16 APIs Exposed to Open and Close a Main Area Tab

/**
   * Opens a Main Area task.
   *
   * @param taskFlowId Task flow to open
   * @param keyList Key list to locate the task flow instance.
   *                This is a semicolon delimited keys or key-value pairs.
   *                For example, "key1;key2=value2". If only the key is specified,
   *                the value is picked up from parametersList with the same
   *                name as the key.
   * @param parametersList Parameters list for the task flow.
   *                       This is a semicolon delimited String
   *                       of name value pairs. For example,
   *                       "param1=value1;param2=value2".
   * @param label Label for the task flow
   * @param reuseInstance Default true. If true, refocus an existing instance
   *                      of the task flow, if such a one exists, without
   *                      opening a new instance of the task flow. If false,
   *                      always open a new instance of the task flow.
   * @param forceRefresh Default false. If false, task flow reinitialization
   * depends on whether some parameters are passed into parametersList, where
   * the presence of parameter values causes reinitializaiton and the absence of
   * parameter values does not. forceRefresh true always causes reinitialization
   * of the task flow regardless of the value for parametersList.
   * @param loadDependentFlow Effective only in No-Tab navigation model.
   *                          Defaults to false. When set to true, the specified
   *                          task flow is loaded into the dependent region
   *                          of the No-Tab navigation model, preserving the
   *                          state of the main flow.
   * @param methodParameters From Drop 6 Build 7, this can be used for passing
   *                         java object into the task flow that's specified
   *                         in taskFlowId parameter. Use setCustomObject() API
   *                         in FndMethodParameters for setting the java object.
   * @return For internal Contextual Event processing
   */
  public FndMethodParameters openMainTask(String taskFlowId,
                                          String keyList,
                                          String parametersList,
                                          String label,
                                          Boolean reuseInstance,
                                          Boolean forceRefresh,
                                          Boolean loadDependentFlow,
                                          FndMethodParameters methodParameters)
 
/**
   * Closes the current focused task flow.
   *
   * @param methodParameters For future implementation. No-op for now.
   * @return For internal Contextual Event processing
   */
  public FndMethodParameters closeMainTask(FndMethodParameters methodParameters)

Bind the methodParameters parameter value to a managed bean property. Example 14-17 shows the method action binding in the page definition of the page fragment that calls openMainTask.

Example 14-17 Method Action Binding in Page Definition of Page Fragment That Calls openMainTask

<methodAction id="openMainTask" RequiresUpdateModel="true"
                  Action="invokeMethod" MethodName="openMainTask"
                  IsViewObjectMethod="false" DataControl="FndUIShellController"
                  InstanceName="FndUIShellController.dataProvider"
                  ReturnName="FndUIShellController.methodResults.openMainTask_FndUIShellController_dataProvider_openMainTask_result">
      <NamedData NDName="taskFlowId"
                 NDValue="/WEB-INF/TestPanelSplitterTaskFlow#TestPanelSplitterTaskFlow"
                 NDType="java.lang.String"/>
      <NamedData NDName="keyList" NDType="java.lang.String"/>
      <NamedData NDName="parametersList" NDValue="" NDType="java.lang.String"/>
      <NamedData NDName="label" NDValue="Test App Panel"
                 NDType="java.lang.String"/>
      <NamedData NDName="reuseInstance" NDType="java.lang.Boolean"/>
      <NamedData NDName="forceRefresh" NDType="java.lang.Boolean"/>
      <NamedData NDName="loadDependentFlow" NDValue=""
                 NDType="java.lang.Boolean"/>
      <NamedData NDName="methodParameters" NDValue="#{TestOpenMainTaskMBean.fndMethodParams}"
                 NDType="oracle.apps.fnd.applcore.patterns.uishell.ui.bean.FndMethodParameters"/>
    </methodAction>

Example 14-18 shows code in a managed bean for passing a hashmap to the task flow.

Example 14-18 Sample Code in a Managed Bean for Passing a Hashmap to the Task Flow

private FndMethodParameters fndMethodParams;
  ...
  public void setRichCommandLink1(RichCommandLink richCommandLink1)
  {
    this.richCommandLink1 = richCommandLink1;
    FndMethodParameters methodParams = new FndMethodParameters();
    HashMap testHashMap = new HashMap();
    testHashMap.put("param1", "12345");
    testHashMap.put("param2", "67890");
    methodParams.setCustomObject(testHashMap);
    fndMethodParams = methodParams;
  }

Then, in the managed bean of the task flow, the Java object can be read, as shown in Example 14-19.

Example 14-19 Reading Java Object in a Managed Bean

public String getTestValue()
  {
    Map pageFlowScope =
      AdfFacesContext.getCurrentInstance().getPageFlowScope();
    Object custom = pageFlowScope.get("fndCustomObject");
    String outputTextString = "";
    if (custom != null && custom instanceof HashMap)
    {
      HashMap myHashMap = (HashMap)custom;
      String temp1 = (String)myHashMap.get("param1");
      String temp2 = (String)myHashMap.get("param2");
      outputTextString = temp1 + temp2;
    }
    testValue = outputTextString;
    return testValue;
  }

Where testValue is bound to an af:outputText value attribute, such as <af:outputText value="#{TestPanelSplitter1MBean.testValue}"/>, in the page fragment of the task flow.

14.4.1.1 closeMainTask History

Dynamic tabs mode tracks the last tab that was displayed before the current tab. When the current tab is closed, that last tab is brought back into focus.

In no-tabs mode, a stack of all the task flows that were opened is maintained, along with the parameter values. When the current task is closed, the task flow, with its original parameters, that was open before the current one, is reinitialized.

There are two ways in which the previous tab information is set for a given tab. When a new tab is opened, the tab that was in focus is the new tab's previous tab. When the user clicks a tab UI, the last tab that had the focus becomes the current tab's previous tab.

MainAreaHandler.handleOpenMainTaskEvent has a mechanism to handle the new tab. The managed bean for the tab adds an additional property for the previous tab. When a new tab is configured to be launched, the current tab is set as the previous tab for the managed bean for the new tab.

A disclosure listener, MainAreaBackingBean.setLastDisclosedItem, handles user clicks in the tab UI. When the user clicks a tab, two events fire: one for the tab that is going out of focus, and one for the tab that is coming into focus. First, during the out-of-focus event, the tab that is going out of focus is captured in the managed bean's instance variable. Then, during the in-focus event, that instance variable's value is set as the previous tab in the managed bean for the newly-focused tab.

Through user clicks, it is possible to end up in a circular dependency, in which TabA's previous tab is TabB, whose previous tab is TabA. In this case, when TabA is closed, TabB would come into focus. However, when TabB is consequently closed, TabA would have to be focused, but it has already been closed. This corner case is handled by moving the focus to the first tab in the Main Area.

No-Tab Navigation

To keep track of all task flows that have been opened, a Stack instance variable is introduced in the MainAreaHandler. When a new task flow is opened, the task flow ID and its associated parameter values are pushed onto the stack.

Having this information, the call to closeMainTask pops the stack to get the last task flow ID and its parameter values that were displayed, and reinitializes the Main Area with that task flow and parameter information.

See also Section 14.2.3.4, "Supporting No-Tab Workareas."

14.4.2 How to Control Regional Area Task Flows

The UI Shell exposes the means to control the disclosure state of the Regional Area as a whole, and the disclosure state of individual panels within the Regional Area panelAccordian.

Declarative support: (to allow the developer to specify the initial state of the following on loading a Work Area JSPX page)

  • Within the Regional Area, whether or not a Regional Area Task Panel is collapsed or disclosed.

  • A given Regional Area panel that is disclosed on initial rendering of the page should honor its assigned pixel height to determine how much screen real estate it occupies.

Programmatic support: (to allow the developer to control the initial or subsequent state of the following within a Work Area JSPX page)

  • By default, the disclosure state is driven by what is specified declaratively. However, after initial page load, the developer can override the declarative default and, for example, render the Work Area with the Regional Area collapsed (overriding the declarative setting of rendering that Work Area with the Regional Area disclosed).Disclosing a collapsed Regional Area splitter programmatically in response to a UI gesture by the user (such as a button click or menu selection).

Declarative support is provided using attributes exposed on the respective item node in the Menu Model.

For regional panels:

There are separate APIs that expose parameters to refresh the task flow and set the disclosure state for the showDetail items in the panel accordian. The showDetail items are identified by the task flow id specified.

Developer Implementation

  • Specify the default values for the regional or main splitter position and collapsed state in the menu for the item node that represents the page, using the regionalAreaWidth and isRegionalAreaCollapsed properties. A sample entry in the menu file resembles Example 14-20.

    Example 14-20 Sample Menu File Entry

    <itemNode id="itemNode_SvcCenter"
                label="#{adfBundle['oracle.apps.fnd.applcore.patterns.demo.patterns_demo_menuBundle'].SERVICE_CENTER}"
                action="adfMenu_SvcCenter" focusViewId="/SvcCenter"
                isDynamicTabNavigation="false" regionalAreaWidth="250" isRegionalAreaCollapsed="false">
    
  • If these properties are not set in the menu for the top-level item node that represents the page, the default values used are:

    regionalAreaWidth="256"
    isRegionalAreaCollapsed ="false"
    
  • For programmatic control, drag and drop the corresponding method from the FndUIShellController data control.

    • discloseRegionalArea

    • collapseRegionalArea

    • setRegionalAreaWidth

Two APIs, shown in Example 14-21, are exposed as data control methods under FndUIShellController.

Example 14-21 APIs Exposed as Data Control Methods Under FndUIShellController

/**
   * Discloses a Regional Area task.
   *
   * @param taskFlowId Task flow to disclose
   * @param keyList Key list to locate the task flow instance.
   *                This is a semicolon delimited keys or key-value pairs.
   *                For example, "key1;key2=value2". If only the key is specified,
   *                the value is picked up from parametersList with the same
   *                name as the key.
   * @param parametersList Parameters list for the task flow.
   *                       This is a semicolon delimited String
   *                       of name value pairs. For example,
   *                       "param1=value1;param2=value2".
   * @param label Label for the task flow*
   * @param forceRefresh Default false. If false, task flow reinitialization
   * depends on whether some parameters are passed into parametersList, where
   * the presence of parameter values causes reinitializaiton and the absence of
   * parameter values does not. forceRefresh true always causes reinitialization
   * of the task flow regardless of the value for parametersList.
   * @param methodParameters For future implementation. No-op for now.
   * @return For internal Contextual Event processing
   */
  public FndMethodParameters discloseRegionalTask(String taskFlowId,
                                                  String keyList,
                                                  String parametersList,
                                                  String label,
                                                  Boolean forceRefresh,
                                                  FndMethodParameters methodParameters)
 
  /**
   * Collapses a Regional Area task.
   *
   * @param taskFlowId Task flow to collapse
   * @param keyList Key list to locate the task flow instance.
   *                This is a semicolon delimited key-value pairs. For example,
   *                "key1=value1;key2=value2".
   * @param methodParameters For future implementation. No-op for now.
   * @return For internal Contextual Event processing
   */
  public FndMethodParameters collapseRegionalTask(String taskFlowId,
                                        String keyList,
                                        FndMethodParameters methodParameters)

Limitations

  • Declarative support allows the inflexibleHeight property to control the pixel height of the Regional panel. Programmatic support does not have this allowance.

  • Programmatic support allows for forceRefresh property to make it possible to refresh a Task without passing in any parameters. Declarative support does not have this allowance.

  • Refreshing a Regional Task without disclosing the task is not supported.

  • Multiple Regional Tasks are allowed to be disclosed at the same time. A switch to force showing only one task at a time is not provided.

  • Support for persisting any of these settings explicitly altered by the user during a session, across sessions, is not a part of this feature.

14.4.3 How to Control the State of the Contextual Area Splitter

This section discusses the declarative and programmatic means of controlling the state of the Contextual Area splitter.

The UI Shell must expose the means to control the disclosure state of the Contextual Area.

Declarative support lets the developer specify the initial state when loading a Work Area JSPX page. It determines whether or not the Contextual Area (as a whole) is collapsed or disclosed.

Programmatic support lets the developer control the initial or subsequent state of the Contextual Area within a Work Area JSPX page.

  • By default, the disclosure state is driven by what is specified declaratively. However, after the initial page load, the developer can override the declarative default and, for example, render the Work Area with the Contextual Area collapsed (overriding the declarative setting of rendering that Work Area with the Contextual Area disclosed).

  • Disclosing the collapsed Contextual Area splitter programmatically in response to a UI gesture by the user, such as a button click or menu selection.

Samples of Expected Behavior

  • A Work Area page (JSPX) loads with the Contextual Area collapsed or disclosed when the page renders, based on the declarative setting. If the Work Area is loaded as a result of a Main Menu invocation, declarative options always are used for the disclosure state.

  • If a Work Area loads as a result of a page navigation from another Work Area, programmatically set options may override declarative settings.

14.4.3.1 Implementing the Contextual Area Splitter

  • Extend the contextual-area-task-flow-template Task Flow Template into the page task flow, as shown in Example 14-22.

    Example 14-22 Extending the Task Flow Template

    <template-reference>
       <document>/oracle/apps/fnd/applcore/patterns/uishell/templates/contextual-area-task-flow-template.xml</document>
       <id>contextual-area-task-flow-template</id>
    </template-reference>
    
  • Specify values for the contextual area splitter position and the collapsed state in the menu for the item node that represents the page using contextualAreaWidth and contextualAreaCollapsed properties. A sample entry in the menu file will resemble Example 14-23.

    Example 14-23 Example of contextualAreaWidth and contextualAreaCollapsed Properties

    <itemNode focusViewId="<focus_view_id>" id="<page_id>" label="<page_label>"
         taskType="dynamicMain"
         taskFlowId="/WEB-INF/page2-task-flow-definition.xml#page2-task-flow-definition"
         contextualAreaCollapsed="true"
         contextualAreaWidth="0"/>
    
  • If these properties are not set in the menu for the top-level item node that represents the page, these default values are used:

    contextualAreaWidth="256"
    contextualAreaCollapsed ="false"
    
  • For programmatic control, drag and drop the corresponding method from the data control named FndUIShellController:

    • collapseContextualArea

    • contextualAreaWidthSelection

  • To set these values when opening a new task, drag and drop the openMainTask method from FndUIShellController and pass in the contextualAreaWidth and contextualAreaCollapsed parameters through "methodsParameters > NamedData" as shown in Example 14-24.

    Set the method in the page managed bean to set the contextualAreaWidth and contextualAreaCollapsed values, as shown in Example 14-24.

    Example 14-24 Setting the contextualAreaWidth and contextualAreaCollapsed Values for openMainTask

    <methodAction id="openMainTask" RequiresUpdateModel="true"
                Action="invokeMethod" MethodName="openMainTask"
                IsViewObjectMethod="false" DataControl="FndUIShellController"
                InstanceName="FndUIShellController.dataProvider"
                ReturnName="FndUIShellController.methodResults.openMainTask_FndUIShellController_dataProvider_openMainTask_result">
          <NamedData NDName="taskFlowId"
           NDValue="/WEB-INF/page6-task-flow-definition.xml#
                                      page6-task-flow-definition"
                NDType="java.lang.String"/>
          <NamedData NDName="keyList" NDValue="" NDType="java.lang.String"/>
          <NamedData NDName="parametersList" NDType="java.lang.String"/>
          <NamedData NDName="label" NDType="java.lang.String"/>
          <NamedData NDName="reuseInstance" NDType="java.lang.Boolean"/>
          <NamedData NDName="forceRefresh" NDType="java.lang.Boolean"/>
          <NamedData NDName="loadDependentFlow" NDType="java.lang.Boolean"/>
          <NamedData NDName="methodParameters"
                NDValue="#{<ManagedBean.Method>}"
                NDType="oracle.apps.fnd.applcore.patterns.uishell.ui.
                                            bean.FndMethodParameters"/>
    
  • For setting these values using the Navigate API to navigate to a task flow, drag and drop the navigate method from FndUIShellController and pass in the contextualAreaWidth and contextualAreaCollapsed parameters through "methodsParameters > NamedData" as shown in Example 14-25.

    Set the method in the page managed bean to set the contextualAreaWidth and contextualAreaCollapsed values, as shown in Example 14-25.

    Example 14-25 Setting the contextualAreaWidth and contextualAreaCollapsed Values for navigate

    <methodAction id="navigate" RequiresUpdateModel="true" Action="invokeMethod"
           MethodName="navigate" IsViewObjectMethod="false"
           DataControl="FndUIShellController"
           InstanceName="FndUIShellController.dataProvider"
           ReturnName="FndUIShellController.methodResults.navigate_FndUIShellController_dataProvider_navigate_result">
        <NamedData NDName="viewId" NDType="java.lang.String"/>
        <NamedData NDName="webApp" NDType="java.lang.String"/>
        <NamedData NDName="pageParametersList" NDType="java.lang.String"/>
        <NamedData NDName="navTaskFlowId" NDType="java.lang.String"/>
        <NamedData NDName="navTaskKeyList" NDType="java.lang.String"/>
        <NamedData NDName="navTaskParametersList" NDType="java.lang.String"/>
        <NamedData NDName="navTaskLabel" NDType="java.lang.String"/>
        <NamedData NDName="methodParameters"
            NDValue="#{<ManagedBean.Method>}"   
            NDType="oracle.apps.fnd.applcore.patterns.uishell.ui.
                                         bean.FndMethodParameters"/>
    </methodAction>
    

14.4.4 Sizing Regional Area Panels

Multiple Regional Area panels will be open at the same time, instead of showing only one panel at a time.

Because the desired size of each panel will be different for each panel, developers can set the pixel height for each of the panels by specifying the inflexibleHeight property in the itemNode that represents a Regional Area panel, as shown in Example 14-26.

Example 14-26 Using inflexibleHeight to Set Panel Height

<itemNode id="__ServiceRequest_itemNode__SRSearch"
 focusViewId="/ServiceRequest" label="SR Search"
 taskType="defaultRegional"
 taskFlowId="/oracle/apps/fnd/applcore/patterns/demo/SRSearch.xml#SRSearch"
 inflexibleHeight="200"/>

14.5 Working with the Global Menu Model

Menu metadata used in Oracle Fusion Applications is divided into global menu data, consisting of the Home Page tabs, the Navigator Menu (also known as the main menu), and the Preferences Menu.

The Navigator Menu and Home Page tabs contain information from different applications, yet each application must be able to be developed independently. To bring this information together, a Global Menu Model is provided.

Navigation to a page is accomplished by constructing and executing a URL. Matching the application name from the distributed menu metadata to its deployment information will dynamically create the host/port portion of the URL. Other page parameters are held in the existing page-level menu metadata.

The Task Menu, create URL, and navigation API allow other declarative and programmatic access to page navigation. The UI Shell global area also will support a Home link for page navigations.

Global Menu Model Service

This model:

Example of Global Menus

The global menu model presents a cascading appearance, shown in Example 14-31.

Global Menu Behavior

14.5.1 How to Implement a Global Menu

Note:

Before you create menus, you first must create JSF pages using the UI Shell template.

These Global Menus span J2EE applications.

  • Navigator Menu: This is the global menu that displays in the UI Shell global area.

  • Home Page Menu: The home page tabs are actually each a JSPX page assembled using menu metadata.

  • Preferences Menu: The User Preferences page has a tasklist to all other preference pages within Oracle Fusion Middleware. This is assembled using menu metadata.

14.5.1.1 Menu Attributes Added by Oracle Fusion Middleware Extensions for Applications (Applications Core)

Table 14-3, Table 14-4, and Table 14-15 list the menu attributes added by Applications Core to the menu XML above what is provided by Oracle ADF.

Table 14-3 <groupNode> Attributes

Attribute Data Type Required Description

labelKey

xsd:string

N

Bundle key used for label; the key will be looked up in the resource bundle specified by the resourceBundle attribute of <menu>.


Table 14-4 <itemNode> Attributes for Global Menus

Attribute Data Type Required Description

webApp

xsd:string

Y

The webApp attribute is used to look up the host and port of the associated Workarea or Dashboard from the ASK deployment tables. These tables are populated at deployment time through Oracle Fusion Functional Setup Manager tasks.

focusViewId

xsd:string

N

This is the page Id. This can be found by looking in the adfc-config.xml file. The name under each page in the diagram view is the page Id.

securedResourceName

xsd:string

N

The resource name that is used for securing the item node.

applicationStripe

string

 

(This attribute is used for pages.) Check security of the page against the policies that are located in LDAP. The applicationStripe name must be the same as the stripe name of the LDAP policy store, which is the same as the web.xml application.name attribute.

parametersList

string

 

This is a task-level itemNode attribute that is a parameters list to pass in to the task flow to open in the target workspace. This is a semicolon-delimited string of name value pairs. For example, "param1=value1;param2=value2."

pageParametersList

string

 

This is a page-level itemNode attribute that is the parameters list for the page. This is a semicolon-delimited string of name value pairs. For example, "param1=value1;param2=value2". If the Expression Language expression evaluates to an Object, the toString value of that Object will be passed as the value of the parameter.

destination

string

 

The destination attribute is supported on the item nodes for the Navigator menu. The destination should only be used for navigating to an external web site. When it is defined, it takes precedence over all attributes. Example of the menu data:

<itemNode id="itemNode_otn"
destination="http://www.oracle.com/technology/index.html"/>

14.5.1.2 Displaying the Navigator Menu

The Navigator menu, shown in Figure 14-18, is rendered when the Navigator link is clicked on the UI Shell.

Figure 14-18 Navigator Menu Example

Navigator Menu Example

14.5.1.3 Implementing a Global Menu

Note:

The Navigator menu is used as the example for how a developer implements a Global Menu, but the steps will be similar for the Preferences and Home menus.

The Navigator menu metadata may be pointing to target workarea pages in various applications. To simplify the runtime behavior, one XML file contains all the menu entries. An Applications Core application will deploy these menus to MDS. Each application will read these directly from MDS.

Each application must be configured so that the shared library can read the menus from MDS.

To implement a Global Menu:

  1. Verify that the web.xml of the application has the correct Java Authentication and Authorization Service (JAAS) filter to enable checking menu security against Oracle Platform Security Services (OPSS), as shown in Example 14-27.

    Example 14-27 Sample JAAS Filter

    <filter>
            <filter-name>JpsFilter</filter-name>
            <filter-class>oracle.security.jps.ee.http.JpsFilter</filter-class>
            <init-param>
                <param-name>enable.anonymous</param-name>
                <param-value>true</param-value>
            </init-param>
            <init-param>
                <param-name>remove.anonymous.role</param-name>
                <param-value>false</param-value>
            </init-param>
            <init-param>
              <param-name>application.name</param-name>
              <param-value>crm</param-value>
            </init-param>
            <init-param>
              <param-name>oracle.security.jps.jaas.mode</param-name>
              <param-value>subjectOnly</param-value>
            </init-param>
    </filter>
    

    application.name, as shown in the example, in web.xml is the application family value. The choices are crm, fscm, and hcm. This value is used to create the stripe in LDAP.

  2. Update weblogic-application.xml. As shown in Example 14-28, set the application-param that has the param-name jps.policystore.migration to OFF.

    Example 14-28 Setting jps.policystore.migration to OFF

    <application-param>
        <param-name>jps.policystore.migration</param-name>
        <param-value>OFF</param-value>
    </application-param>
    
  3. In weblogic-application.xml, make sure the application-param that has the param-name jps.policystore.applicationid is set to the correct stripe, as shown in Example 14-29. This is the same as the application.name property of web.xml.

    Example 14-29 Setting jps.policystore.applicationid to the Correct Stripe

    <application-param>
        <param-name>jps.policystore.applicationid</param-name>
        <param-value>crm</param-value>
    </application-param>
    
  4. Add the following entry in web.xml:

    <listener> <listener-class>oracle.apps.fnd.applcore.menu.service.MenuFragmentServiceContextListener</listener-class>
    </listener>
    

14.5.2 How to Set Up Global Menu Security

Global Menu security depends on applications using a standalone LDAP server.

Note:

Global security only works with standalone WebLogic Server.

ADF Menu Security is enabled by default. If you need to disable menu security, such as for testing, launch WebLogic Server after setting the JAVA_OPTIONS environmental variable in the setDomainEnv.sh file:

JAVA_OPTIONS = -DAPPLCORE_TEST_SECURED_MENU=N

14.5.2.1 Enforcing User Privileges and Restrictions

Before you enforce user actions, you should already have defined roles, principals, and actions in the database.

Functional security will always prevent a user from accessing a page or task flow that the user does not have access to. To improve the user experience, global menus can be hidden if the user does not have access to that page. There are two different security features for this:

  • The global menus have a securedResourceName attribute, which should be the value of the page resource against which security can be checked. For pages, this is the page definition file.

  • The menus also have a rendered attribute. This can be used to evaluate an Expression Language security expression. If rendered="false" (false being the outcome of the expression), the menu item will be hidden even if the user has access to the page. There are certain times you would want to do this. For instance, consider a person working in HR as a consultant, not an Employee. You might want a menu entry for editing employee data under an HR category, but not to show an entry under the Employee Self-Service category that also led to the same page. See Example 14-30.

    Example 14-30 Expression Language Expression to Evaluate a User's Access Rights

    rendered="#{securityContext.userInRole['EMPLOYEE_ROLE']}"
    

    The Expression Language expression should never check the pageDef. However, you can use the Expression Language expression to check security of a person's role since that is in LDAP.

  • The applicationStripe attribute determines which LDAP stripe is checked for the securedResourceName.

14.5.3 How to Create the Navigator Menu

Menu files will be references through MDS. This means they can be located in a table or in a file system directory. Determine where this directory will be now. This is where your root_menu.xml and other menu files will be located. For Global Menu attributes, see Section 14.5.1.1, "Menu Attributes Added by Oracle Fusion Middleware Extensions for Applications (Applications Core)."

  1. Create the root menu.

    Example 14-31 shows a sample root menu.

    Example 14-31 Example of a Navigator Menu

    <menu xmlns="http://myfaces.apache.org/trinidad/menu">
      <groupNode id="groupNode_my_information" 
        idref="_groupNode_my_information_" 
        label="#{menuBundle['oracle.apps.menu.ResourcesAttrBundle'].MY_INFORMATION}">
          <itemNode id="itemNode_my_information_my_portrait" 
             label="#{bundleVar.MY_PORTRAIT}" focusViewId="/MyPortrait" webApp="HcmCore" 
             securedResourceName="oracle.apps.hcm.people.portrait.ui.page.MyPortraitPageDef" 
        <groupNode id="groupNode_my_information_compensation" 
          idref="_groupNode_my_information_compensation_" 
          label="#{menuBundle['oracle.apps.menu.ResourcesAttrBundle'].COMPENSATION}">
          applicationStripe="hcm"
        </groupNode>
        <groupNode id="groupNode_my_information_career" 
          idref="_groupNode_my_information_career_" 
          label="#{menuBundle['oracle.apps.menu.ResourcesAttrBundle'].CAREER}">
             <itemNode id="itemNode_my_information_goals" 
                label="#{menuBundle['oracle.apps.menu.ResourcesAttrBundle'].GOALS}" 
                focusViewId="/ManageGoalsWorkArea" webApp="HcmTalent" 
                securedResourceName="oracle.apps.hcm.goals.core.publicUi.page.ManageGoalsWorkAreaPageDef"/>
                  <itemNode id="itemNode_my_information_performance_management" 
                     label="#{menuBundle['oracle.apps.menu.ResourcesAttrBundle'].PERFORMANCE}" 
            applicationStripe="hcm"
                     focusViewId="/PerformanceWorkArea" webApp="HcmTalent" 
                     securedResourceName="oracle.apps.hcm.performance.documents.publicUi.page.PerformanceWorkAreaPageDef"/>
        </groupNode>
        <groupNode id="groupNode_my_information_procurement" 
          idref="_groupNode_my_information_procurement_" 
          label="#{menuBundle['oracle.apps.menu.ResourcesAttrBundle'].PROCUREMENT}">
             <itemNode id="itemNode_my_information_purchase_requisitions" 
                label="#{menuBundle['oracle.apps.menu.ResourcesAttrBundle'].PURCHASE_REQUISITIONS}" 
                focusViewId="/PrcPorCreateReqWorkarea" webApp="Procurement" 
                securedResourceName="oracle.apps.prc.por.createReq.publicUi.page.PrcPorCreateReqWorkareaPageDef" applicationStripe="hcm"/>
                   <itemNode id="itemNode_my_information_self_service_receipts" 
                       label="#{menuBundle['oracle.apps.menu.ResourcesAttrBundle'].RECEIPTS}" 
                       applicationStripe="hcm"
                       focusViewId="/RcvSelfServWorkarea" webApp="Logistics" 
                       securedResourceName="oracle.apps.scm.receiving.selfService.workarea.ui.page.RcvSelfServWorkareaPageDef"/>
           applicationStripe="hcm"/>
        </groupNode>
      </groupNode>
    </menu>
    
  2. Create the application's Navigator menu files.

    The next files in the menu hierarchy can contain groupNodes that appear as non-clickable categories, itemNodes that are clickable to launch a page, or references to more menu files. If itemNodes were included that were not deployed, they will not appear since a check is done against the deployment tables of what was deployed. Applications Core requires that if a groupNode has no children, which could happen through security enforcement, the groupNode itself will not be rendered.

14.5.3.1 Rendering the Navigator Menu as Pull-down Buttons

There are situations, particularly with more simple applications, when the default enterprise-level menu structure is not suitable. In these cases, you may want to display the Navigator menu as a series of pull-down buttons.

To switch the UI Shell rendering so the Navigator menu renders as pull-down buttons in a horizontal row, set the isSelfService attribute to "true" on the .jspx page that extends the UI Shell template. That is, inside the <af:pageTemplate> tag, add the following:

<f:attribute name="isSelfService" value="true"/>

14.6 Using the Personalization Menu

The Personalization menu options, shown in Figure 14-19, let you set your preferences, edit the current page, and reset the content and layout. The menu is supplied automatically by the UI Shell and requires no developer work.

Figure 14-19 Personalization Menu

Personalization Menu

The Preference Menu only appears if you have the ApplSession filter and mapping set up. See Section 48.2, "Configuring Your Project to Use Application User Sessions.".

Set Preferences

The actual Preferences dialog, such as shown in Figure 14-22, is created by developers. See Section 14.7 for the details of how to implement the menu.

Edit Current Page

This option displays only if the displayed page has been marked as able to be user-edited (if the isPersonalizableInComposer attribute in af:pageTemplate is set to true). Selecting this option will start the editing feature and the page will resemble Figure 14-20. Click Close to return to the page. Click Customization Manager to change the displayed page in Composer. For more information about the Customization Manager, see the "Customization Manager" section in the "Extending Runtime Editing Capabilities Using Oracle Composer" chapter, and the "Manage Customizations" section of the "Introduction to Oracle Composer" chapter of the Oracle Fusion Middleware Developer's Guide for Oracle WebCenter. Note that changes are for just this user and therefore are called personalization. See Chapter 61, "Creating Customizable Applications".

Figure 14-20 Edit Current Page Display

Edit Current Page Display

Reset Content and Layout

Select this option to discard any personalization changes and return to the default settings. Note that resetting layout and content is for that page. In particular, if any taskflows are personalized on that page via Composer, they are not reset by this menu item.

14.7 Implementing End User Preferences

Set Preferences, shown in Figure 14-21, is a link in the global area for easy access to setting preferences for the current application, general user preferences, or for any other application preference in Oracle Fusion Middleware. For more information about this global menu, see Section 14.5, "Working with the Global Menu Model."

Preferences are pages that can set system-wide settings that applications can access. There are general preferences that affect all applications, and there can be application-specific preferences. General preferences include language, date format, and currency. General preferences are stored in LDAP so they can be accessed from any application. Application preferences are usually stored in the applications on database tables but can be stored in LDAP.

Figure 14-21 Preferences Menu Example

Preferences menu example

14.7.1 How to Use Preferences Link Navigation

The Preferences link from the global area will launch a Workarea that shows the preferences related to the currently-displayed page.

Links in the left hand side will allow navigation to any Preferences Workarea page within the entire Oracle Fusion product. This menu will be rendered using Applications Core menu federation abilities. Development teams will own the menu files.

If an application is not installed, or the user does not have access, the entry in the tasklist menu should not appear. If a user does not have access to a particular setting within a page, application teams need to use the rendered property with a security expression behind it.

For each application, there should be a preferences page. The preferences page will be found by looking for a page using the same path of the current application, but with a page name of preferences.jspx.

If no associated preferences page exists, a default General Preferences page will be shown. This page shows global Applications Core most-used preferences.

If there are several preference pages associated to an application, such as a Common Setting page and more specific pages, only one preferences page as a target from the global preferences link can be defined per application. (There will be a default name for the target focusViewID of the preferences page for an application.) Once in the preferences workarea, other links are available from the tasklist to more specific pages or task flows. (Links in the tasklist can contain other focusViewIDs that belong to the same application as the default preference page.)

When the first application is deployed, it should become the location of the General Preferences page.

Several pages of an application can all point to the same preferences page.

More than one application cannot point to the same preferences page. This implies that each application can have its own preferences page, and if two applications want to share a common preferences page, they can, but it can only be navigated to from the task list. Therefore, from the Preferences link, the user always displays the more specific preferences page of that application.

14.7.2 How to Use the Preferences Workarea Page

A Preferences page will be like any other Workarea page. Preference values are not supported in integrated WLS LDAP, only an external LDAP is supported. The Tasks list will be loaded as a defaultRegional flow and the main area will be a defaultMain flow.

Workarea Title

Each Preferences page should display a title similar to {Category_name:Page_name}. This can be done though Expression Language and will not be created automatically from the framework.

The name that appears in the tasklist can be different from the page title. This is allowed since the tasklist name is generated from the tasklist preference distributed menu metadata, while the page title will be from the local page level menu metadata.

Tasklist / Navigation Pane

Each page needs its Application Menu metadata to specify that it wants the Preferences tasklist menu in the defaultRegional area as well as the defaultMain flow.

This menu can be a two-level menu having categories with links under each category.

Tasklist Federation

The tasklist will be a task flow that will contain links to all Preference pages throughout Oracle Fusion Middleware.

Each application will provide the preference menu files that contain tasklist links to preference pages delivered by that application. The preferences tasklist should follow the Navigator Menu architecture recommendations where it uses sharedNode references to bring in menus from each application so they can be patched independently. Applications Core will automatically federate the menu metadata so the tasklist that renders will contain all the entries from all applications (filtered by security).

Individual menu files will be versioned like other distributed menu files, so any application can apply a patch and the new menu will take precedence over an older version when federated.

Tasklist Only Can Link to Full Pages (not specific task flows)

The tasklist will not launch task flows dynamically, but will load a Preferences workarea page. This is because the tasklist menu needs to be federated and only page-level entries are allowed in a federated menu.

No-tabs Mode

The Preferences page should use a no-tabs mode. This is a standard, not controlled through any code. Teams could use tabs if all flows are defaultMain if desired. See also Section 14.2.3.4, "Supporting No-Tab Workareas."

Tasklist Security

The tasklist will be filtered by functional page level security for that user. If all entries in a category are restricted then the category should not appear either.

Preference Settings

Settings will be a view activity in a task flow. It will follow other UX standards so it should be built using an Applications Panel. This means the action buttons will appear at the top.

Different Preference pages can change the same back end setting. This is up to Applications design. If this is needed, it should be stored in a common area, such as LDAP, or be in the General Preferences page.

14.7.3 How to Deploy Application Preferences Pages

Application preferences pages are deployed with the corresponding product pages.

14.7.4 How to Design General Preferences Content

The design should be similar to that shown in Figure 14-22.

Figure 14-22 General Preferences Example

General preferences example

14.7.5 How to Configure End-User Preferences

This section discusses how to set up and configure Preferences.

14.7.5.1 Implementing User General Preferences Flow

Once the WebLogic Server console is configured, create an Oracle Fusion web application that uses UI Shell pages.

  1. Create a UI Shell page that is used solely for the user preferences, such as PreferencesUI.jspx.

  2. Set the isDynamicTabNavigation to false for the PreferencesUI page entry in the menu.

  3. Add the following task flow as default regional under the preferences page entry: "/WEB-INF/oracle/apps/fnd/applcore/pref/ui/mainflow/GeneralPreferencesFlow.xml#GeneralPreferencesFlow"

  4. The final menu entries for the page will appear similar to those shown in Example 14-32.

    Example 14-32 Sample General Preferences Menu Entries

    <itemNode id="itemNode_untitled2" label="Preferences"
              action="adfMenu_PreferencesUI" focusViewId="/PreferencesUI"
              isDynamicTabNavigation="false" webApp="Demo">
         <itemNode id="def1" focusViewId="/PreferencesUI" label="General Preferences"
                  taskType="defaultRegional"
                  taskFlowId= "/WEB-INF/oracle/apps/fnd/applcore/pref/ui/mainflow/GeneralPreferencesFlow.xml#GeneralPreferencesFlow"/>
    </itemNode>
    

    This should display the basic Preferences in the default regional area that can be launched to display sub-flows for each preference sub task (for instance, Accessibility and Appearance).

14.7.5.2 Using the Preferences Menu Model

The General Preferences flow that is exposed also renders the Preferences Menu Model links by using a call to the Menu Service API.

The Preferences menu will be part of a central Utility application (Menu web service) that will be deployed in the server. The Preferences menu will be maintained by the development team.

On any UI Shell page, the Global Area contains a Personalization menu that contains a Set Preferences link. This Preference link will redirect the user to a webApp-specific Preference page, depending upon the entry in Menu data.

Example 14-33 shows sample preferences menu data.

Example 14-33 Example Preferences Menu Data

<?xml version="1.0" encoding="UTF-8" ?>
<menu xmlns="http://myfaces.apache.org/trinidad/menu" version="1">
  <itemNode id="preferences_node_a" label="Preferences Page A"
            action="preferences_node_a" focusViewId="/preferencesA"
            webApp="fnd" prefForApps="gl, hr" >
    <itemNode id="Flow 1" label="Service Flow"
              focusViewId="/preferencesA"  taskFlowId="/WEB-INF/oracle/apps/fnd/applcore/finance/ServiceFlow.xml#ServiceFlow"
              parametersList="id=userName" />
  </itemNode>
  <itemNode id="preferences_node_b" label="Preferences Page B"
            action="preferences_node_b" focusViewId="/preferencesB"
            webApp="fnd" prefForApps="fn" >
     <itemNode id="Flow 2" label="Request Flow"
              focusViewId="/preferencesB"  taskFlowId="/WEB-INF/oracle/apps/fnd/applcore/finance/RequestFlow.xml#RequestFlow"
              parametersList="id=userName" />
  </itemNode>
  <itemNode id="preferences_node_d" label="Preferences Page D"
            action="preferences_node_d" focusViewId="/PreferencesUI"
            webApp="Demo" prefForApps="Demo"
     <itemNode id="Flow 2" label="Request Flow"
              focusViewId="/preferencesB"  taskFlowId="/WEB-INF/oracle/apps/fnd/applcore/finance/AcceptanceFlow.xml#AcceptanceFlow"
              />
  </itemNode>
</menu>

In the example menu XML file, each parent item node represents a Preferences UIShell page. Its child nodes refer to the webApp-specific flow in which the Preference page exists.

For example, the first itemNode refers to the preferencesA page that is part of the FND webApp. The ServiceFlow child node is a task flow that belongs to FND webApp.

For each parent itemNode, there is an attribute called prefForApps that contains a list of webApp names. This means that the itemNode is a common preference page for those listed webApps.

For example, the Preferences page is common for two webApps -- gl and hr. This essentially means that all the DashBoards and Workarea UI Shell pages in gl and hr webApps will be redirected to this preferencesA page, which is in webApp FND, when the Set Preferences link is clicked.

All the task flows under each preference page itemNode will display in the General Preferences Flow as navigate links. Therefore, all preference pages will have access to these flows.

14.7.5.3 Configuring User Session and ADF Security

To test the general preferences flows, you need to configure user session and ADF Security for the test application. See Chapter 48, "Implementing Application User Sessions."

When configuring ADF Security, there is no need to define users, because you already are using an OID store that will authenticate the users existing in the store.

14.7.5.4 Using Static APIs to Retrieve Preference Values

The general user preferences can be obtained from the static APIs of the GeneralPreferences class. Example 14-34 shows the method signatures and the values they can return.

Example 14-34 Obtaining General User Preferences from GeneralPreferences Class

String getAccessibilityMode()
Return Values List : { 'default' , 'screenReader' }
 
boolean isAnimationEnabled()
Return Values List : { true , false }
 
String getColorContrast()
Return Values List : { 'STANDARD' , 'HIGH' }
 
String getFontSize()
Return Values List : { 'LARGE' , 'MEDIUM' }
 
String getSessionLanguage()
Return Values List : { Valid Oracle Fusion NLS values for Language }
 
String getApplicationLanguage()
Return Values List : { Valid Oracle Fusion NLS values for Language }
 
boolean isEmbeddedHelpEnabled()
Return Values List : { true , false }
 
String getTerritory()
Return Values List : { Valid Oracle Fusion NLS values for Territory }
 
String getCurrency()
Return Values List : { Valid Oracle Fusion NLS values for Currency }
 
String getCharacterEncoding()
Return Values List : { Valid Oracle Fusion NLS values for Character Encoding }
 
String getNumberFormat()
Return Values List : { English , German } (Use number NumberFormat class to interpret them}
14.7.5.4.1 How to Check Accessibility Mode by Using an Expression Language Expression

A use case exists where the UI needs to use an Expression Language expression to check whether the accessibility mode is set to screenReader to render screen reader-friendly components in screenReader mode. The recommended method to do this uses #{requestContext.accessibilityMode} and is documented in "How to Configure Accessibility Support in trinidad-config.xml" in "Developing Accessible ADF Faces Pages" in Oracle Fusion Middleware Web User Interface Developer's Guide for Oracle Application Development Framework.

14.7.5.5 Implementing the Password Management Page

The Password link on the General Preferences page will point to the Password Management page from the Oracle Identity Management administration application. This page is maintained by the OIM team. For the Password link to redirect to the pwdmgmt.jspx page, the deployment information of the current application and the OIM administration application must be populated correctly in the ASK tables.

14.8 Using the Administration Menu

The Administration Menu, shown in Figure 14-23, is displayed only if the logged-in user has the appropriate privileges. See Section 14.8.1, "How to Secure the Administration Menu". The menu is supplied automatically by the UI Shell and requires no developer work.

Figure 14-23 Administration Menu

Administration Menu

Customize Case List Table Pages ...

Select this option to customize the current page for multiple users using the customization layer picker dialog.For information about customization, see Chapter 61, "Creating Customizable Applications" and the "Customizing Applications with MDS" chapter in the Oracle Fusion Middleware Fusion Developer's Guide for Oracle Application Development Framework.

Customization Manager ...

Select this option to launch the Customization Manager.

For information about customization, see Chapter 61, "Creating Customizable Applications" and the "Customizing Applications with MDS" chapter in the Oracle Fusion Middleware Fusion Developer's Guide for Oracle Application Development Framework. For more information about the Customization Manager, see the "Customization Manager" section in the "Extending Runtime Editing Capabilities Using Oracle Composer" chapter, and the "Manage Customizations" section of the "Introduction to Oracle Composer" chapter of the Oracle Fusion Middleware Developer's Guide for Oracle WebCenter.

For information about defining and configuring namespaces when promoting a page fragment to a label, see "Updating Your Application's adf-config.xml File" in the "Performing Oracle Composer-Specific MDS Configurations" chapter of Oracle Fusion Middleware Developer's Guide for Oracle WebCenter.

Manage Sandboxes ...

Select this option to manage sandboxes on your system.

The Sandbox is built on top of the standard Sandbox feature from Oracle Metadata Services. See "Using the Sandbox Manager" in the "Understanding the Customization Development Lifecycle" chapter of the Oracle Fusion Applications Extensibility Guide.

Setup and Maintenance ...

Select this option to launch the Oracle Fusion Functional Setup Manager application. See the Oracle Fusion Applications Common Implementation Guide.

14.8.1 How to Secure the Administration Menu

All teams that need the Administration link need to include the privilege and the permission in their JAZN file as defined in Example 14-35. All Administrator Roles must inherit the Applications Core "Administration Link View Duty" duty role. This duty role gives access to the "View Administration Link" privilege.

Example 14-35 Required Privilege and Permission in JAZN File

<app-role>
  <name>FND_ADMINISTRATION_LINK_VIEW_DUTY</name>
  <display-name>Administration Link View Duty</display-name>
  <description>Provides access to the Administration Link on the UI Shell</description>
  <guid>EA1D0BF0BC096F11B18BDEBD5F4BDB48</guid>
  <class>oracle.security.jps.service.policystore.ApplicationRole
  </class>
 <members>
   <member>
     <class>oracle.security.jps.internal.core.principals.JpsXmlEnterpriseRoleImpl
     </class>
     <name>FND_APPLICATION_DEVELOPER_JOB</name>
     </member>
   <member>
     <class>oracle.security.jps.internal.core.principals.JpsXmlEnterpriseRoleImpl
     </class>
     <name>FND_APPLICATION_ADMINISTRATOR_JOB</name>
   </member>
 </members>
</app-role>
 
Privilege
 
<app-role>
  <name>FND_VIEW_ADMIN_LINK_PRIV</name>
  <display-name>View Administration Link</display-name>
  <description>Privilege to view administration link in UI shell. This privilege is available from Roles(s): Supply Chain Application Administrator,Cost Accountant,Application Implementation Consultant,Application Developer,Application Administrator</description>
  <guid>B14A48E74ECF633A3C6E4AF95816474D</guid>
  <class>oracle.security.jps.service.policystore.ApplicationRole</class>
 <members>
   <member>
     <class>oracle.security.jps.service.policystore.ApplicationRole</class>
     <name>FND_ADMINISTRATION_LINK_VIEW_DUTY</name>
     <guid>EA1D0BF0BC096F11B18BDEBD5F4BDB48</guid>
  </member>
 </members>
</app-role>
 
Permission and Grant to be included in JAZN file
 
<grant>
 <grantee>
  <principals>
   <principal>
     <class>oracle.security.jps.service.policystore.ApplicationRole</class>
     <name>FND_VIEW_ADMIN_LINK_PRIV</name>
     <guid>B14A48E74ECF633A3C6E4AF95816474D</guid>
   </principal>
  </principals>
 </grantee>
 <permissions>
   <permission>
     <class>oracle.security.jps.ResourcePermission</class>
     <name>resourceType=FNDResourceType,resourceName=FND_Administration_Menu</name>
     <actions>launch</actions>
   </permission>
 </permissions>
</grant>

14.9 Using the Help Menu

The Help Menu, shown in Figure 14-24, provides user access to the standard help system and to troubleshooting and diagnostic tools. The menu is supplied automatically by the UI Shell and requires no developer work.

Figure 14-24 Help Menu

Help Menu

Oracle Fusion Applications Help

Select this option to launch the help system in a separate window.

Troubleshooting

When you select the Troubleshooting option, an additional menu, similar to Figure 14-25, displays.

Figure 14-25 Troubleshooting Menu

Troubleshooting Menu

About Fusion

Select this option to display the Oracle copyright statement and information about the application.

14.10 Implementing Tagging Integration

Tagging is a service that allows users to add tags to arbitrary resources in the Oracle WebCenter so they may collectively contribute to the overall taxonomy and discovery of resources others have visited.

Tagging is a component of Oracle WebCenter. For complete information, see the Oracle Fusion Middleware Developer's Guide for Oracle WebCenter. Specific information about tagging that you will need is in these chapters:

This section assumes that:

Important Considerations

Preliminary Setup

The following steps are condensed from the Oracle Fusion Middleware Developer's Guide for Oracle WebCenter.

  1. Open your current application in JDeveloper.

  2. Make sure that your database connection has access to Oracle WebCenter Schema. If it does not, create another connection to access Oracle WebCenter Schema. Name the connection WebCenter. Tagging looks for this connection to access the data.

    Note:

    You should now see at least two connections in your connections.xml: WebCenter and ApplicationDB.
  3. In the resource Palette, open My Catalog > Web Center Service Catalog > Task Flows. Make sure that you see task flows similar to tagging-launch-dialog.

  4. In the Component Palette, right-click your View Controller project and select Project Properties > Technology Scope > Project Properties. Ensure that Tagging Service is selected. In the Component Palette, search for tagging. You should see Tagging Button and Tagging Menu Item.

  5. Add users and roles, and configure security and authorization for the application. Though not mandatory, it is highly recommended. Furthermore, it is required for implementing security for Tagging.

You now can enable Tagging for your business objects.

14.10.1 How to Use the Delivered Oracle WebCenter Tagging Components

Three pieces of information are needed to define Tagging to a business object:

  1. The unique key of the object given which one can identify the object. This is stored in a field called RESOURCE_ID (VARCHAR2(200)) in the tagging schema. If you have multiple fields that define the unique key, use a period as the separator. For example, PK1.PK2. Additional restrictions include these:

    • There can be a maximum five columns as primary keys, such as PK1.PK2.PK3.PK4.PK5.

    • If any primary key column is null, put "null" in the concatenated Resource Id String. For example, if Resource Id is of type PK1.PK2.PK3, the value can be 123.ABC.null. Do not use just 123.ABC.

    • If your primary key consists of a Date, although this is highly unlikely, make sure the date value that you use in String concatenation is date formatted in Database format.

    • Teams cannot implement their own resource parser.

  2. SERVICE_ID (VARCHAR2(200)): This is used to identify the object. The Applications standard is to use the logical business object name.

  3. NAME

    (VARCHAR2(200)): This is what will be displayed as the resource that is tagged in the Tag Center, and that will be visible to the end users when they search for a tagged item. Give it a meaningful name, such as <PO Number>+<PO Title> or Invoice Description or Customer Name.

Note:

All fields are varchar2(200). Make sure that you are not violating the constraint. Also note that if, for instance, your product has three business objects that you are planning to tag, you will build three different services with the proper business object name as the service id.

14.10.1.1 Tagging a Resource (Business Object)

Follow these steps to tag a resource:

  1. From the Component Palette, select WebCenter Tagging Service. Drag and drop the Tagging Button onto the page. (If you do not find the button, make sure you added the WebCenter Tagging JSP Tag Library to your user interface project.)

  2. Open the Property Inspector for the Tagging Button. Enter the bound values for ResourceId, ResourceName and ServiceId, similar to Example 14-36.

    Example 14-36 Entering Property Information for Tagging Button

    <tag:taggingButton
    resourceId="#{row.AuctionHeaderIdString}"
    resourceName="#{row.AuctionTitle}"
    serviceId="oracle.apps.pon.auctionheadersall"/>
    

    Note:

    Make sure all the values are of type String.
  3. From the Resource Palette, under My Catalogs > WebCenter Services Catalog > Task Flows, drag and drop the Tagging Dialog (as a Region). If you do not find the Tagging Dialog, make sure you added the WebCenter Tagging Service View to your user interface project (Properties > Libraries and classpath). Note that you may drop multiple tagging buttons on your page depending upon your requirement. You need to drop the tagging dialog only once on the page. Whenever you click a tag icon (tagging button) on the page, it will call the same tag dialog region.

    Note:

    If placing tags within rows of a table, this region must be dropped outside of the table. Otherwise, it is instantiated for every row, which will not work.

    The ability to tag an object is now enabled on the page. The code will look similar to that shown in Example 14-37.

    Example 14-37 Enabling Tagging

    <af:region
    value="#{bindings.tagginglaunchdialog1.regionModel}"
    id="taggi1"/>
    

If you have multiple objects to tag, there will be multiple tag buttons you will drop on your page, whereas there will be only one tagging dialog.

Tagging is enabled, but to see the Tagged resource in the Tag Center, you must create a service definition.

To create a service definition:

  1. Expand Application Resources > Descriptors > ADF Meta-INF. If you already have the service-definition.xml file, open it. Otherwise, create the service-definition.xml file. Important fields are:

    • taskFlowId: The task flow where you want to go.

    • resourceParamList: The list of parameters which you want to pass to task flow. For example, your task flow takes invoiceId and invoiceType. If the RESOURCE_ID for the tagged item is 123.C45 where 123 is the invoice ID and C45 is the invoiceType, in resourceParamList you should specify invoiceId;invoiceType. The Applications Core class will parse the resource id 123.C45 and pass invoiceId=123,invoiceType=C45 to the task flow. To use a different delimiter, use the customDelimiter attribute.

    • taskParametersList: These are parameters that can be passed to the task flow in addition to the resourceParamList.

    • navTaskKeyList: Do not specify this if it is not used. Otherwise, task flows from TagCenter will always go to a specific tab while the same taskfow opened from the Tasklist or API will go to a different tab.

    • navTaskLabel: If using tabbed workareas, this is needed to give a title to the tab that opens showing the tagged object. An Expression Language expression can be used. It will be evaluated on page load, so it can be an Expression Language expression that the landing page can resolve.

    • pageResourceParamList: If the RESOURCE_ID for the tagged item is, for example, "EastCoast.C45" where EastCoast will be a page level parameter called Region and a taskflow parameter called InvoiceType. It is assumed an object will always need both composite keys to be identified as a unique entity. So, the resourceParamList will always contain the same number of parameter names as the composite keys. The taskflow must take both EastCoast and C45 as parameters. But the page level parameters can be called out in the pageParametersList. For example:

      resourceParamList = "Region,InvoiceType"
      pageResourceParamList = "Region"
      
    • pageParametersList: Additional page parameters where the value is static. Example: pageParametersList = "Campaign=Sales"

    • customDelimiter: This is optional. The default is a ".". If you want something different, add this parameter.

      For ease of deployment, service definition files will be stored in Oracle Metadata Services (MDS). Add the service-definition.xml file to the Metadata Archive (MAR) file definition.

      A sample service-definition.xml is provided in Example 14-38.

      Example 14-38 Sample service-definition.xml

      <service-definition id="FND_DEMO_DOC_TAG" version="11.1.1.0.0"  >
          <resource-view taskFlowId="/WEB-INF/task-flow-1.xml#task-flow-1" >
          <parameters>
              <parameter name="viewId"
                         value="RevenueWorkArea"/>
              <parameter name="webApp"
                         value="ProjectsFinancials"/>
              <parameter name="pageParametersList"
                         value="p1=viewContext"/>
              <parameter name="navTaskKeyList"
                         value="ViewRevenueItem"/>
              <parameter name="taskParametersList"
                        value="a=1;b=2"/>
              <parameter name="resourceParamList"
                          value="invoiceId;invoiceType" />
              <parameter name="navTaskLabel"
                         value="Details"/>
              <parameter name="customDelimiter"
                         value="," />
              <resource-type-key>PAGE_OBJECT_NAME</resource-type-key>
          </parameters>
          </resource-view>
          <name-key>CUSTOM_NA_KEY_TYPE</name-key>
          <description-key>CUSTOM_TY_DESCRIPTION_KEY</description-key>
      </service-definition>
      

      You want to put the service-definition.xml file in a standardized location so there are no conflicts. Create or copy the file, which by default is located at .adf/META_INF/service-definition.xml, to the new standardized location. There are two goals for where to put the service-definition.xml:

      • Make it unique so two teams are not trying to push files to the exact same location in MDS.

      • Standardize it to be in meta/oracle/apps/meta. The /oracle/apps/meta makes the location specific to Oracle applications. The parent meta/ directory is used for MAR selection. The directory structure and contents then resemble:

        meta/ (this directory plus a specific sub-directory structure goes into the MAR)
             oracle/apps/meta/ (namespace unique to MDS)
                  <product-specific-directory-structure>/ (each team has a unique name)
                       service-definition.xml (located in the product directory)
        

        If you use an application-level or project-level service-definition.xml file, you do not need to make any changes so long as your name will be unique to other applications and projects. You should never have two entries for the same SERVICE_ID, whether within the same service-definition.xml file or in separate service-definition.xml files.

        That is, the service-definition.xml file should be under the data model project that contains the entity objects and view objects used for the detail page. If the view object is:

        oracle.apps.scm.receiving.receipts.receiptSummary.protectedUiModel.view.ReceiptSummaryHeaderVO,

        the service-definition.xml location will be:

        oracle.apps.scm.receiving.receipts.receiptSummary.protectedUiModel.meta.oracle.apps.meta.scm.receiving.receipts.receiptSummary.service-definition.xml.

  2. Add the directory, such as meta/oracle/apps/meta/<lba>/<product>/, into the MAR.

    • Open Application > Application Properties > Deployment. Select the MAR file and choose Edit.

    • In the Edit dialog, select User Metadata and choose Add. Browse to select the meta directory you just added and click OK.

    • Select the meta directory (under oracle/apps/) and click OK.

    • Click OK in the Edit MAR dialog.

  3. Add the namespace path /oracle/apps/meta to adf-config.xml, as shown in Example 14-39.

    Example 14-39 Adding the Namespace Path to adf-config.xml

    <adf-config
      <adf-mds-config xmlns="http://xmlns.oracle.com/adf/mds/config"
                      version="11.1.1.000">
        <mds-config xmlns="http://xmlns.oracle.com/mds/config" version="11.1.1.000">
           <persistence-config>
              <metadata-namespaces>
                 <namespace path="/oracle/apps/meta"
                  metadata-store-usage="WebCenterFileMetadataStore"/>
              </metadata-namespaces>
              <metadata-store-usage id="WebCenterFileMetadataStore"
                 default-cust-store="true" deploy-target="true">
                 <metadata-store class-name="oracle.mds.dt.persistence.stores.file.SrcControlFileMetadataStore">
                      <property name="metadata-path" value="../../mds"/>
                 </metadata-store>
              </metadata-store-usage>
           </persistence-config>
        </mds-config>
      </adf-mds-config>
    </adf-config>
    
  4. Add the entry shown in Example 14-40 to your adf-config.xml to enable the default resource action handler from Applications Core:

    Example 14-40 Enabling the Default Resource Action Handler

    <wpsC:adf-service-config>
        <resource-handler class="oracle.apps.fnd.applcore.tags.handler.FndResourceActionViewHandler"/>
    </wpsC:adf-service-config>
    

    Add this instruction in the header:

    xmlns:wpsC="http://xmlns.oracle.com/webcenter/framework/service"

  5. Run the page.

    • The tag icon will appear on the page. When you click the Tag icon, it will take you to the UI where you can enter a new Tag.

    • You can share the tag or not share it. Only shared tags are available to Oracle Fusion Applications Search.

    • After creating the tag for the first time, again hover the mouse over the icon. It will display My Tags and Popular Tags.

    • Clicking the Tag takes you to the Tag Center UI where you are shown all resources that have been tagged by that word.

    • Clicking a resource from TagCenter will navigate you to the task flow defined in your service definition, passing the parameters you specified so you can view the object.

14.10.1.2 Enabling Multiple Navigation Targets

Searchable and taggable objects are defined at the view object/logical business object level. The same view object/business object can be viewed and tagged in more than one workarea and taskflow. The requirement is that all users must be able to navigate from TagCenter to a detail taskflow for which they have privileges. If this taskflow is available in the current workarea, use this target before any other.

This is implemented by supplying multiple navigation targets in the current service-definition.xml. Each target will have its parameter separated by a caret (^).

Example 14-41 shows how to define a list of three targets:

Example 14-41 Defining a List of Three Targets

<resource-view
    taskFlowId="/WEB-INF/dummy^/WEB-INF/dummy^/WEB-INF/Test1Frag2TF.xml#Test1Frag2TF">
  <parameters>
    <parameter name="viewId" value="DummyView^Region6UIShellPage^Test2"/>
    <parameter name="webApp"
      value="ApplCoreCRMDemo^ApplCoreCRMDemo^SimpleApplication1_application1"/>
    <parameter name="pageParametersList" value=""/>
    <parameter name="taskParametersList" value=""/>
    <parameter name="resourceParamList" value="val"/>
    <parameter name="navTaskLabel" value="My Employee Details^My Employee Details 2^My Employee Details"/>
    <parameter name="applicationStripe"
       value="ApplicationsCommon^ApplicationsCommon^AppStripe1"/>
    <parameter name="pageDefinitionName"
       value="pageDef.not.exist^oracle.apps.view.pageDefs.Region6UIShellPagePageDef^oracle.apps.view.pageDefs.Test1PageDef"/>
   </parameters>
</resource-view>

The lists of taskFlowId, viewId, webApp, and so on, are specified as a delimited string, with each value delimited by a caret. Two parameters, applicationStripe and pageDefinitionName, are available for checking security when the target is in a different webApp.

If the current view id matches any one of the viewId values in the target list, you take the corresponding task flow (that is, if the third viewId value matches the current view id, you take the third taskFlowId value) and launch it in the current page, if the user has view access to that task flow, which overrides the order of the list. Otherwise, you check a list of link targets for the first target to which the current user has access. Application teams are responsible for making sure that all users who can access this object have at least one match to a target taskflow defined in the service-definition.xml.

When the target is in a different webApp, the security check is performed by calling checkBulkAuthorization API. Therefore, using a standalone WebLogic Server and LDAP policy store are required. This requirement is optional when the lists of targets are within the same webApp.

14.10.1.3 Tagging a Resource at the Row Level of a Table

To add row-level tagging to a table, add a new empty column to hold the tag button/link.

All other steps remain the same as described in Section 14.10.1.1, "Tagging a Resource (Business Object).".

14.10.1.4 Searching for a Tag

The Applications Standard recommends that you do not add the Tag Search in your page. The standard way is to launch the Tag Center UI by clicking the Tag icon, or from Tags in the UI Shell global area and do the search there.

14.10.1.5 Resource Viewer for Tagged Items

It can be handy for a user to be able to click a tag and open a document. To do this, Web Center Tagging needs to know a resource viewer (a task flow) where it should take the user to show the required information.

Each development team will build a task flow where they can take the user for that resource and show the desired additional information.

  1. Select or create a new task flow that will act as your resource viewer for a service (business object).

    1. In the task flow definition, define an input parameter that is called resourceId (in this example), class equal to java.lang.String, value equal to #{pageFlowScope.resourceId}, and required enabled.

      Note that the value for resourceId is set automatically when clicking a tagged item link in TagCenter.

    2. Create a method with a parameter of object id in the application module for a tagged item (named, for instance, setCurrentRow) to set the view object row based on the passed resource id parameter.

    3. Add the setCurrentRow method as the default activity in the task flow and bind the method (right click on the method in the task flow and go to page definition) with the parameter value of #{pageFlowScope.resourceId}, type java.lang.String, and name equal to the parameter variable name in the setCurrentRow method signature.

    4. Add to the new task flow the bounded task flow for the details/information page of the tagged item.

    5. Add a control flow case from the setCurrentRow method to the details/information page task flow, as shown in Figure 14-27.

      Figure 14-27 Adding A Control Flow to Details Task Flow

      Adding Control Flow to Details Task Flow
  2. Register the new task flow in the service-definition.xml file. You will register the resource viewer for a particular service (business object) to its section in the service definition file. See Example 14-38 for samples of the service-definition and resource-view entries.

Basically, you have defined a task flow that takes the resource id as input. Use the resource id to uniquely identify the business object and display any desired extra detail. Note that clicking a tagged item in TagCenter displays the details/information page for the tagged item in the local area of the workarea page for that task flow.

14.10.2 Implementing Tagging Security

By default, tagging does not provide any security. To avoid this problem, the development teams will implement security for each service (business object) for which tagging is enabled.

  • For a business object, first implement Oracle Fusion Data Security.

  • Add the authorizerClass and the dataSecurityObjectName parameter to the service-definition.xml file, as shown in Example 14-42.

    Example 14-42 Registering a New Class in service-definition.xml

    <service-definition id="FND_DEMO_DOC_TAG" version="11.1.1.0.0"  >
        <resource-view taskFlowId="/WEB-INF/task-flow-1.xml#task-flow-1" >
         authorizerClass="oracle.apps.fnd.applcore.tags.util.FndTagSecurity"/>
        <parameters>
           <parameter name="dataSecurityObjectName" value="FND_CRM_CASES"/>
           <parameter name="dataSecurityPrivilegeName" value="read"/>
    

    FND_CRM_CASES is the object you want to secure that is found in the FND_OBJECTS table. This is normally the object's main table name.

    If the dataSecurityPrivilegeName parameter is not set, it defaults to read privilege. This attribute is used in cases where a single table has different privileges for different users.

  • Put the service definition into MDS. For ease of deployment, service definition files will be stored in MDS.

14.10.3 How to Use Tagging in a UI Shell Application

This section presents examples of how tagging appears in the UI Shell.

  • Tagging an object by having the tagging button and tagging dialog in the task flow. On clicking the tagging button, a tagging dialog displays and prompts the user to tag the object with a name, as shown in Figure 14-28.

    Figure 14-28 Tagging an Object with a Name

    Tagging an Object with a Name
  • To see the tagged object in the tag center flow, click the Tags link in the UI Shell global area and the tag center flow displays the list of tags available, as shown in Figure 14-29.

    Figure 14-29 Displaying the List of Available Tags

    Displaying the List of Available Tags
  • Click one of the tags in the tag cloud region of the tag center to view the tagged items, as shown in Figure 14-30.

    Figure 14-30 Viewing Tagged Items

    Viewing Tagged Items
  • Click the tagged item to view the object in the task flow mentioned in the service definition file, as shown in Figure 14-31.

    Figure 14-31 View Object Listed In Service Definition File

    View Object from Service Definition File
  • To check whether or not the object is already tagged, hover over the tagging button to see the tags. On clicking the tag link on the hover dialog, the tag center flow will be launched with the selected tag, as shown in Figure 14-32.

    Figure 14-32 Launching Flow with Selected Tag

    Launching Flow with Selected Tag

14.11 Implementing Recent Items

Recent Items tracks a list of the last 20 task flows visited by a user. The Recent Items list is persistent across user sessions and a task can be relaunched from the Recent Items list. The feature is automatically turned on and will be available automatically in pages using the UI Shell template. Security must be disabled to turn Recent items off.

Before you begin:

For the Recent Items feature to work, product teams must configure the user session and ADF Security. See Chapter 48, "Implementing Application User Sessions." Without security enabled, recent items will not be captured, because the data is recorded for each authenticated user.

14.11.1 How to Choose Labels for Task Flows

Recent Items records the task flow labels for a launched task flow. Therefore, product teams must carefully choose the labels for task flows, and must provide task flow labels for all task flows, even if they are meant to be used in no-tab mode (see Section 14.2.3.4, "Supporting No-Tab Workareas").

14.11.2 How to Call Sub-Flows

openMainTask is used to open a new task in the Main Area of Oracle Fusion web applications that use UIShell templates. Besides opening a new tab, openMainTask also pushes a new task flow history object onto a stack, which is used to keep track of all task flows that have been opened. The task flow ID and its associated parameter values are encapsulated in the task flow history object.

Having this information, the call to closeMainTask pops the stack to get the last task flow ID and its parameter values that were displayed, and reinitializes the Main Area with that task flow and parameter information.

When a task flow is called from the local area task flow using task flow call activity, it is called a sub-flow. By default, sub-flows will not be recorded on the stack as described. Two new APIs are exposed in FndUIShellController data control for registering sub-flows: openSubTask and closeSubTask.

14.11.2.1 Sub-Flow Registration APIs

Use the openSubFlow and closeSubFlow APIs to record sub-flows to Recent Items. Whenever an ADF Controller task flow call takes place, no notification is raised to Applications Core or UI Shell. So, unlike launching a task from a tasks list, product teams need to explicitly notify the UI Shell for sub-flow calls.

When openSubTask is called before a sub-flow is launched, the sub-flow ID and its parameter values are pushed onto the stack. Applications Core also notifies the Recent Items implementation with recorded task flow information. This essentially makes a sub-flow able to be bookmarked by Recent Items, and can be launched directly from the selection of menu items on Recent Items.

Note that registering sub-flows to Recent Items is optional. The decision is up to a product team's product manager.

Implementation

This API is exposed as the Data Control methods FndUIShellController.openSubTask and FndUIShellController.closeSubTask that developers will drag and drop to their page fragments to create links to notify UI Shell. The FndUIShellController Data Control is automatically available to all Oracle Fusion applications that reference Applications Core libraries.

Example 14-43 shows the signature and Javadoc of the method.

Example 14-43 Recent Items API

/**
* Notify UIShell to record given sub-flow on the stack and 
* also notify Recent Items to include it on the list.
*
* @param taskFlowId Task flow to open
* @param parametersList Parameters list for the task flow.
*                       This is a semicolon delimited String
*                       of name value pairs. For example,
*                       "param1=value1;param2=value2".
*
* @param label Label for the task flow.
* @param keyList Key list to locate the task flow instance.
*                This is a semicolon delimited keys or key-value pairs.
*                For example, "key1;key2=value2". If only the key is specified,
*                the value is picked up from parametersList with the same
*                name as the key.
*
* @param taskParametersList Parameters list to pass in to the task flow to open
*                in the target workspace. This is a semicolon delimited String
*                of name value pairs. For example,
*                "param1=value1;param2=value2."
*
* @param methodParameters This can be used for passing
*                Java object into the task flow that's specified 
*                in taskFlowId parameter. Use <code>setCustomObject() API</code>
*                in FndMethodParameters for setting the java object.
*
* @return For internal Contextual Event processing
*/
 
public FndMethodParameters openSubTask(String taskFlowId,
String parametersList,
String label,
String keyList,
String taskParametersList,
String viewId,
String webApp,
FndMethodParameters methodParameters)
 
/**
* Closes the currently-focused sub-task and the focus moves to the 
* task from which this sub-task was launched.
*
* @param methodParameters For future implementation. No-op for now.
* @return For internal Contextual Event processing
*/
public FndMethodParameters closeSubTask(FndMethodParameters methodParameters)

All the parameters required to be passed in openSubTask are exactly same as used by the Section 14.16, "Introducing the Navigate API.".

14.11.2.2 openSubTask API Labels

The openSubTask API accepts the same set of parameters as used by the Section 14.16, "Introducing the Navigate API." If no label is specified in the openSubTask API, Recent Items will register it with the name of the parent task flow's label. You should set a different label based on the business use case in the openSubTask API. Failing to do so will register this flow with the same label as the parent task flow's label and, therefore, will make it impossible to distinguish between the parent flow and the sub-flow entry in the Recent Items list.

14.11.2.3 Launching from Recent Items

Whatever task flow details are registered while invoking the openSubTask API will be used by Recent Items to launch it. Recent Items takes care of launching the task flow in the right work area and web application. Product teams do not need to do anything for that. Because the openSubTask API supports parametersList, product teams can pass some requirement-specific values to it while registering their task flow to Recent Items. On launching, those passed values are available in the pageFlowScope. So, product teams can analyze these values and make decisions, such as if they need to first initialize the parent flow, or if they need to set Visible to False on some of the actions on the page.

14.11.3 How to Enable a Sub-flow to Be Bookmarked in Recent Items

To record sub-flows into the Recent Items list, applications need to call the openSubTask API right before sub-flows are launched. openSubTask takes parameters similar to the Navigate API. One of these is task flow ID. For this, you need to specify the parent flow's ID (or main task's ID). In other words, sub-flows need to be executed via parent flow, even though they are launched from the Recent Items menu.

If your sub-flow does not need to be bookmarked by Recent Items, you do not need to change anything. Otherwise, you need to modify your parent flow and sub-flow as described in this section. After the changes, sub-flows can be launched in two ways:

  • From original flows

  • From Recent Items menu items using recorded information

Both will start the execution in the parent flow. Because the sub-flow needs to be piggybacked on the parent flow when it is launched from the Recent Items menu, you need to change the parent flow following these directions:

  • Add a new router activity at the beginning of the parent flow. Based on a test condition, it will route the control to either the original parent flow or the task flow call activity (that is, the sub-flow).

  • Add an optional method call activity to initialize the sub-flow before it is launched from the Recent Items menu. Product teams can code the method in such a way that it can navigate to the sub-flow after initializing the parent state. This allows product teams to render the contextual area, navigating back to the parent flow from the sub-flow, and any other customizations.

  • Bind openSubTask to the command component (such as a link or button) which causes the flow to navigate to the task flow call activity in the original parent flow. The openSubTask API registers the parent flow details and input parameters to the sub-flow (to be launched as a sub-flow later) to the Applications Core task flow history stack.

Usually, you do not need to modify your sub-flow for this task. However, you can consolidate the initialization steps from two execution paths in this way:

  • Remove initialization parts from both paths in the parent flow. Instead, set input parameters in both paths only.

  • Modify the sub-flow to take input parameters.

  • Add a new method call (such as initsubflow) at the beginning of the sub-flow to initialize states in the parent flow (for example, parent table) so that the sub-flow can be launched in the appropriate context.

Note that the design pattern also requires the application to be able to navigate back to the parent flow from the sub-flow. The initialization code should take this into consideration, such as by setting up states to allow the sub-flow to navigate back.

In this example, you will use an Employee sample implementation to demonstrate the details of this design pattern.

Sub-flow Sample Application

As shown in Figure 14-33, users select Subflow Design Pattern from the task list. They then specify some criteria to search for a specific employee or employees. From the list, they can choose the employee for whom they want to show the details.

Figure 14-33 Example List of Employees

Example List of Employees

The Ename column in the search result table is a link that can be used to navigate to the employee detail page of a specific employee. When this link is clicked, a sub-flow (or nested bounded task flow) is called to display the Employee Complete Detail page, as shown in Figure 14-34.

Figure 14-34 Example Employee Complete Detail Page

Example Employee Complete Detail Page

If users would like to add this Employee Complete Detail page of a specific employee to their Recent Items, product teams need to set up something extra to make this happen. If this page (actually a bounded task flow whose default page is displayed) has been bookmarked, the next time users can click it on the Recent Items list and launch it directly by skipping the search step.

14.11.3.1 Implementing the Sub-flow Design Pattern

The parent task flow named ToParentSFFlow is shown in Figure 14-35.

Figure 14-35 Example Parent Task Flow

Example Parent Task Flow

decideFlow is the router activity that decides whether the control flow should go to the original parent flow path (initParent) or to the sub-flow path (toChild). The condition used is defined as:

<router id="decideFlow">
  <case>
    <expression>#{pageFlowScope.Empno == null}</expression>
    <outcome id="__9">initParent</outcome>
  </case>
 
  <case>
    <expression>#{pageFlowScope.Empno != null}</expression>
    <outcome id="__10">toChild</outcome>
  </case>
 
  <default-outcome>initParent</default-outcome>
</router>

The test checks whether or not the Empno variable in the parent flow's pageFlowScope is null. #{pageFlowScope.Empno} is set using its input parameter Empno when the parent flow is called. The input parameters on the parent flow (that is, ToParentSFFlow) is defined as:

<input-parameter-definition>
  <name>Empno</name>
  <value>#{pageFlowScope.Empno}</value>
  <class>java.lang.String</class>
</input-parameter-definition>

When the parent flow is launched from the task List, the Empno parameter is not set (that is, it is not defined in the application menu's itemNode). Therefore, it is null and the router will route it to the initParent path.

When the sub-flow is recorded through the openSubTask API, Empno is set on the parametersList as:

<methodAction id="openSubTask" RequiresUpdateModel="true"
                 Action="invokeMethod" MethodName="openSubTask"
                 IsViewObjectMethod="false" DataControl="FndUIShellController"
                 InstanceName="FndUIShellController.dataProvider"
                 ReturnName="FndUIShellController.methodResults.openSubTask_FndUIShellController_dataProvider_openSubTask_result">
     <NamedData NDName="taskFlowId" NDType="java.lang.String"
         NDValue="/WEB-INF/oracle/apps/xteam/demo/ui/flow/ToParentSFContainerFlow.xml#ToParentSFContainerFlow"/>
     <NamedData NDName="parametersList" NDType="java.lang.String"
                NDValue="Empno=#{row.Empno}"/>
     <NamedData NDName="label" NDType="java.lang.String"
                NDValue="#{row.Ename} complete details"/>
     <NamedData NDName="keyList" NDType="java.lang.String"/>
     <NamedData NDName="taskParametersList" NDType="java.lang.String"/>
     <NamedData NDName="viewId" NDType="java.lang.String"
                NDValue="/DemoWorkArea"/>
     <NamedData NDName="webApp" NDType="java.lang.String"
                NDValue="DemoAppSource"/>
     <NamedData NDName="methodParameters"
         NDType="oracle.apps.fnd.applcore.patterns.uishell.ui.bean.FndMethodParameters"/>
</methodAction>

You also set up:

  • taskFlowId to be the parent flow's, not the sub-flow's

  • label to be the sub-flow's

When end users click the link (the Ename) to which the openSubTask method is bound, openSubTask will be called. This link component is defined as:

<af:column sortProperty="Ename" sortable="false"
           headerText="#{bindings.ComplexSFEmpVO.hints.Ename.label}"
           id="resId1c2">
  <af:commandLink id="ot3" text="#{row.Ename}"
                  actionListener="#{bindings.openSubTask.execute}"
                  disabled="#{!bindings.openSubTask.enabled}"
                  action="toChild">
    <af:setActionListener from="#{row.Empno}"
                          to="#{pageFlowScope.Empno}"/>
  </af:commandLink>
</af:column>

Note that when the link is clicked:

  • actionListener and the action specified on the link are executed, in that order.

  • openSubTask needs to be called only from the original parent flow path (that is, initParent), not from the sub-flow path (that is, toChild).

EmployeeDetails activity in Figure 14-35 is a Task Flow Call activity that invokes the ToChildSFFlow sub-flow. Before the sub-flow is executed, you need to add initialization steps. These initialization steps could include, but are not limited to:

  • Set up parent states. For this example, you need to set the selected employee's row to be the current row.

  • Set up the contextual area state.

  • Set up states to allow the sub-flow to navigate back to the parent flow.

There are two approaches to set up the initialization steps:

  • In the parent flow

  • In the sub-flow

For the first approach, you can add logic to initialize both paths before the task flow call activity in the parent flow. For the second approach, you initialize states in the sub-flow by using input parameters of the sub-flow. For example, the sub-flow will take an input parameter named Empno. In effect, the second approach just postpones the initialization to the sub-flow.

The definition of input parameters in the Task Flow Call activity is:

<task-flow-call id="EmployeeDetails">
     <task-flow-reference>
       <document>/WEB-INF/oracle/apps/xteam/demo/ui/flow/ToChildSFFlow.xml</document>
       <id>ToChildSFFlow</id>
     </task-flow-reference>
     <input-parameter>
       <name>Empno</name>
       <value>#{pageFlowScope.Empno}</value>
     </input-parameter>
</task-flow-call>

Note that this means that the calling task flow needs to store the value of Empno in #{pageFlowScope.Empno}. For example, from the original parent flow path, it is set to be #{row.Empno} using the setActionListener tag. For the sub-flow path, it is set using the parent flow's input parameter Empno. On the sub-flow, you need to specify its input parameters as:

<task-flow-definition id="ToChildSFFlow">
   <default-activity>TochildSFPF</default-activity>
   <input-parameter-definition>
     <name>Empno</name>
     <value>#{pageFlowScope.Empno}</value>
     <class>java.lang.String</class>
   </input-parameter-definition>
   ...
</task-flow-definition>

Note that the name of the input parameter (Empno) needs to be the same as the parameter name defined on the Task Flow Call activity. When the parameter is available, ADF will place it in #{pageFlowScope.Empno} to be used within the sub-flow. However, this pageFlowScope is different from the one defined in the Task Flow Call activity because they have a different owning task flow (that is, parent task flow versus sub-flow).

The definition of the sub-flow is shown in Figure 14-36:

Figure 14-36 Example Sub-flow Definition

Example Sub-flow Definition

In the sample implementation, you chose to implement the initialization step in the sub-flow. Empno is passed as a parameter to the sub-flow and used to initialize the parent state. When the sub-flow is launched, the default view activity (ToChildSFPF) displays. Before it renders, the initPage method on the ChildSFBean will be executed. The page definition of the default page is defined as:

<pageDefinition xmlns="http://xmlns.oracle.com/adfm/uimodel">
 <parameters/>
 <executables>
   ...
   <invokeAction id="initPageId" Binds="initPage" Refresh="always"/>
 </executables>
 <bindings>
   ...
   <methodAction id="initPage" InstanceName="ChildSFBean.dataProvider"
                 DataControl="ChildSFBean" RequiresUpdateModel="true"
                 Action="invokeMethod" MethodName="initPage"
                 IsViewObjectMethod="false"
                 ReturnName="ChildSFBean.methodResults.initPage_ChildSFBean_dataProvider_initPage_result"/>
    ...
 </bindings>
</pageDefinition>

initPage is specified in the executables tag and will be invoked when the page is refreshed. The initPage method itself is defined as:

public void initPage()
{ 
    FacesContext facesContext = FacesContext.getCurrentInstance();
    ExpressionFactory exp = facesContext.getApplication().getExpressionFactory();
    DCBindingContainer bindingContainer =
      (DCBindingContainer)exp.createValueExpression(
          facesContext.getELContext(),"#{bindings}",DCBindingContainer.class).getValue(facesContext.getELContext());
    ApplicationModule am = bindingContainer.getDataControl().getApplicationModule();
 
    ViewObject vo = am.findViewObject("ComplexSFEmpVO");
    vo.executeQuery();
 
    Map map = AdfFacesContext.getCurrentInstance().getPageFlowScope();
    if(map !=null){
         Object empObj = map.get("Empno");
         if(empObj instanceof Integer){
             Integer empno =(Integer)map.get("Empno");// new Integer(empnoStr);
             Object[] obj = {empno};
             Key key = new Key(obj);
             Row row = vo.getRow(key);
             vo.setCurrentRow(row);
         }
         else
         {
             String empnoStr = (String)map.get("Empno");
             Integer empno = new Integer(empnoStr);
             Object[] obj = {empno};
             Key key = new Key(obj);
             Row row = vo.getRow(key);
             vo.setCurrentRow(row);
         }
     }
}

initPage takes the input parameter Empno from #{pageFlowScope.Empno} as a key to select a row and set it to be the current row in the master Employee table.

14.11.4 How to Use Additional Capabilities of Recent Items

The openSubTask API has additional capabilities. For example, consider an employee search page in which you enter parameters such as department number and manager id, and search for the matching employee records. This is a case that a user may have to perform often. You can use the openSubTask API to register a search page with search parameters. The next time the user can see the search results by just launching it from Recent Items. This is similar to using parametersList to specify search parameters while registering the search flow. While launching, a little programming can be done to retrieve the search parameters and execute the query with the parameter values.

Once tasks are recorded on the Recent Items list, they are eligible for Favorites. The Favorites menu is implemented on top of Recent Items. Any current task on the Recent Items list can be bookmarked and placed in Favorites' folders. Currently, only a one-level folder is supported. Similar to Recent Items, tasks on the Favorites list can be launched directly from the menu. So, the description in this section for Recent items applies similarly to the Favorites implementation. For example, sub-flows based on the design pattern described in this section can be registered on the Favorites list as well as the Recent Items list.

14.11.5 Known Issues

  • Recent Items are persistent across user sessions.

  • You may see a null pointer exception when all the task flow parameters are not supplied values.

14.12 Implementing the Watchlist

The Watchlist is a portlet/menu, accessible to Oracle Fusion Applications users, that provides a summary of items that a user wants to track. The Watchlist includes seeded items (items that are provided out of the box) categorized by functional areas, and items created by the user. Technically, the Watchlist presents a list of pre-queried searches (saved searches or standard queries) of things the user needs to track. Each item is comprised of descriptive text followed by a count. Each item also is linked to a page in a workarea where the individual items of interest are listed.

The Watchlist is available both as a dashboard region in the Welcome tab of the Home dashboard, and as a global menu. These are two views of the same content. The dashboard region is available to the users as soon as they login, while the global menu is accessible as they navigate through the suite.

The Watchlist will be refreshed to fetch new counts and items whenever the user navigates to the Home page. The Watchlist can refresh the entire watchlist or individual categories as needed. Users will be able to personalize the Watchlist to hide or show items.

Figure 14-37 shows an example of the Watchlist portlet and menu.

Figure 14-37 Example Watchlist Portlet and Menu

Example Watchlist Portlet and Menu

Implementing teams have these high-level tasks:

14.12.1 Watchlist Data Model Effects

Product teams will seed data into the ATK_WATCHLIST_CATEGORIES and ATK_WATCHLIST_SETUP tables. Rows in the ATK_WATCHLIST_ITEMS will be managed by Watchlist code, but developers will query it for testing verification.

The only other data model effect will be in the creation of summary tables. These summary tables help with retrieving the count of Watchlist items with data security. See Section 14.12.4.3.1, "Summary Tables."

14.12.2 Watchlist Physical Data Model Entities

The Watchlist data model is supported by ATK. The tables are:

Table 14-5 ATK_WATCHLIST_CATEGORIES

Column Name Datatype Required Comments

WATCHLIST_CATEGORY_CODE

VARCHAR2(100)

Yes

PK - Unique code based on Product code Prefix. Ensure that this code begins with <PRODUCT SHORT CODE>_, so that it does not overlap with other others.

CATEGORY_LOOKUP_TYPE

VARCHAR2(30)

Yes

Reference to FND_STANDARD_LOOKUP_TYPES.LOOKUP_TYPE

Product teams to seed lookup type with meaning for category (VIEW_APPLICATION_ID = 0 and SET_ID = 0). The translated lookup type meaning is shown in the Watchlist UI for category.

OWNING_MODULE_NAME

VARCHAR2(4000)

Yes

Reference to FND_APPL_TAXONOMY.MODULE_NAME for the owning product/module. This is used for seed data purposes.

OWNING_MODULE_ID

VARCHAR2(32)

Yes

Reference to FND_APPL_TAXONOMY.MODULE_ID for the owning product/module. This is used for seed data purposes.

OWNING_APPLICATION_ID

NUMBER

Yes

Reference to FND_APPL_TAXONOMY.ALTERNATIVE_ID for the owning product/module. This is used for seed data purposes.

REFRESH_SERVICE_ENDPOINT_KEY

VARCHAR2(60)

Yes

This is the key to determine the host, port, context root, etc. to construct the URL for service endpoint (wsdl location).

This will be based on the Applications Core lookup API that will be used for determining the end point.

REFRESH_SERVICE_NAME

VARCHAR2(400)

Yes

This is the service that needs to be invoked for count calculation (for refreshing this category).

REFRESH_SERVICE_METHOD_NAME

VARCHAR2(400)

Yes

This column is obsoleted. The hard-coded method name will be refreshWatchlistCategory. Product teams will create this hard-coded service method.

ENABLED

VARCHAR2(1)

Yes

Defaults to Y. This defines if this Watchlist category is enabled/active.

CREATED_BY

VARCHAR2(64)

Yes

Standard WHO Column

CREATION_DATE

TIMESTAMP

Yes

Standard WHO Column

LAST_UPDATED_BY

VARCHAR2(64)

Yes

Standard WHO Column

LAST_UPDATE_DATE

TIMESTAMP

Yes

Standard WHO Column

LAST_UPDATE_LOGIN

VARCHAR2(32)

Yes

Standard WHO Column


Table 14-6 ATK_WATCHLIST_SETUP

Column Name Datatype Required Comments

WATCHLIST_ITEM_CODE

VARCHAR2(100)

Yes

PK - Needs to use Category Code Prefix

ITEM_LOOKUP_CODE

VARCHAR2(30)

Yes if WATCHLIST_ITEM_TYPE != USER_SAVED_SEARCH

Reference to FND_LOOKUPS.LOOKUP_CODE

Product teams to seed lookup code with meaning for the parent category lookup type. The translated lookup meaning is shown in the Watchlist UI with the count appended.

CATEGORY_CODE

VARCHAR2(30)

Yes

 

PRIVILEGE_BASED

VARCHAR2(1)

Yes

Specifies if this Watchlist item is created against a security action instead of a specific user.

OWNING_PRIVILEGE_NAME

 

Yes if

PRIVILEGE_BASED = Y

Defines if this item is created against a security action - users that have this action will be able to view this item.

Required if PRIVILEGE_BASED = Y

FUNCTION_PRIVILEGE_NAME

VARCHAR2(400)

 

Defines the region action for this item's drilldown workarea. This is the page definition for the drilldown view/jspx that is part of your jazn-data.xml. The user needs to have this permission policy to view the item in the Watchlist UI.

WATCHLIST_ITEM_TYPE

VARCHAR2(30)

Yes

Defines the Watchlist item type - maps to lookup. Valid values are:

SEEDED_QUERY (Seeded Query)

SEEDED_SAVED_SEARCH (Seeded Saved Search)

USER_SAVED_SEARCH (User-created Saved Search)

HUMAN_TASK (Worklist item)

HUMAN_TASK_DEF_ID

VARCHAR2(200)

Yes if WATCHLIST_ITEM_TYPE = HUMAN_TASK

Human Task Definition Identifier.

Required if WATCHLIST_ITEM_TYPE = HUMAN_TASK

HUMAN_TASK_STATE

VARCHAR2(100)

Yes if WATCHLIST_ITEM_TYPE = HUMAN_TASK

Human Task State Identifier.

Required if WATCHLIST_ITEM_TYPE = HUMAN_TASK

REFRESH_AGE

NUMBER(9)

Yes if WATCHLIST_ITEM_TYPE != HUMAN_TASK

Defines the age for count in seconds. After this many seconds have passed since the last refresh time, the Watchlist UI would issue a count recalculation request

Required if

WATCHLIST_ITEM_TYPE != HUMAN_TASK

VIEW_OBJECT

VARCHAR2(400)

Yes if WATCHLIST_ITEM_TYPE != HUMAN_TASK

Complete path of the view object that needs to be executed for count calculation.

Required if

WATCHLIST_ITEM_TYPE != HUMAN_TASK

SUMMARY_VIEW_ATTRIBUTE

VARCHAR2(400)

Yes if WATCHLIST_ITEM_TYPE != HUMAN_TASK and this is a summary view object

Indicates the view object attribute name if using a summary view object for Watchlist count calculation. On execution, this view object returns only one row with the Watchlist item count.

Required if WATCHLIST_ITEM_TYPE != HUMAN_TASK and this is a summary view object.

APPLICATION_MODULE

VARCHAR2(400)

Yes if WATCHLIST_ITEM_TYPE != HUMAN_TASK

Complete path of the application module that contains the view object instance that needs to be executed for count calculation.

Required if

WATCHLIST_ITEM_TYPE != HUMAN_TASK

AM_CONFIG_NAME

VARCHAR2(400)

Yes if WATCHLIST_ITEM_TYPE != HUMAN_TASK

The application module Configuration Name for creating an instance of the application module from code. This is typically AMLOCAL.

Required if

WATCHLIST_ITEM_TYPE != HUMAN_TASK

VIEW_OBJECT_INSTANCE

VARCHAR2(400)

Yes if WATCHLIST_ITEM_TYPE != HUMAN_TASK

The Instance Name for the view object in the application module.

Required if

WATCHLIST_ITEM_TYPE != HUMAN_TASK

VIEW_CRITERIA_ID

VARCHAR2(400)

Yes if WATCHLIST_ITEM_TYPE = SEEDED_SAVED_SEARCH

The View Criteria that needs to be applied when executing the view object.

Required if

WATCHLIST_ITEM_TYPE != HUMAN_TASK

NAVIGATION_URL_KEY

VARCHAR2(60)

Yes

This is the key to determine the host, port, and context root to construct the URL for the UI drilldown for Watchlist item.

This will be based on the Applications Core lookup API that will be used for UI navigation across J2EE applications.

VIEW_ID

VARCHAR2(400)

Yes

The view id (as per the UI Shell menu) for the workarea/page that contains the task flow for this Watchlist item's drilldown from the Watchlist UI.

PAGE_PARAM_LIST_STRING

VARCHAR2(400)

No

Parameters list for the page. If the target workarea page accepts page parameters, this is a semicolon-delimited String of name value pairs.

TASKFLOW_ID

VARCHAR2(400)

Yes

The task flow for this Watchlist item's drilldown from the Watchlist UI.

TF_KEY_LIST_STRING

VARCHAR2(400)

No

Key list to pass into the task flow to open in the target workspace. This is a semicolon-delimited keys or key-value pairs. For example, "key1;key2=value2"

TF_PARAMETER_STRING

VARCHAR2(400)

Yes if WATCHLIST_ITEM_TYPE IN (SEEDED_SAVED_SEARCH, USER_SAVED_SEARCH)

Parameters list to pass in to the task flow to open in the target workspace. This is a semicolon-delimited String of name value pairs. For example, "param1=value1;param2=value2"

For user created saved search, the view criteria id will be appended to this string (the string will need to end with <paramName>= for saved search).

TASK_TAB_LABEL

VARCHAR2(400)

Yes

Label for the task flow to open in the target workspace.

ENABLED

VARCHAR2(1)

Yes

Defaults to Y. This defines if this Watchlist category is enabled/active.

CREATED_BY

VARCHAR2(64)

Yes

Standard WHO Column

CREATION_DATE

TIMESTAMP

Yes

Standard WHO Column

LAST_UPDATED_BY

VARCHAR2(64)

Yes

Standard WHO Column

LAST_UPDATE_DATE

TIMESTAMP

Yes

Standard WHO Column

LAST_UPDATE_LOGIN

VARCHAR2(32)

Yes

Standard WHO Column


14.12.3 Supported Watchlist Items

Supported Watchlist items are all asynchronous (that is, queries are executed on demand when the user requests a refresh or just before the Watchlist UI is shown). There are four types of asynchronous Watchlist items (watchlist_item_type):

  • Seeded queries (SEEDED_QUERY)

  • Seeded saved searches (SEEDED_SAVED_SEARCH)

  • User-created saved searches (USER_SAVED_SEARCH)

  • Human task-flow items (HUMAN_TASK)

14.12.3.1 Asynchronous Items Overview: Expense Reports Saved Search

For asynchronous Watchlist items, the count is only updated upon request. For example, in Expenses, there is an expense reports search panel from which users can make searches and save them in MDS for future use. Users should be able to promote their saved searches to the Watchlist for tracking. This Watchlist item (of type USER_SAVED_SEARCH) is asynchronous in that the Watchlist count will only be updated upon request, and events that change the count will not simultaneously be updating the Watchlist. In this case, Watchlist code is responsible for querying the count of an asynchronous Watchlist item on demand. Figure 14-38 shows the flow of an asynchronous Watchlist item.

Figure 14-38 Asynchronous Watchlist Item Flow

Asynchronous Watchlist Item Flow

For the Expense report saved search panel example:

  • Since this item is of type USER_SAVED_SEARCH, Watchlist items are created when the user promotes a saved search on the search panel in Expenses. This invokes a Watchlist service on the Watchlist that does the Watchlist item creation. This is not needed for Watchlist items of type SEEDED_QUERY or SEEDED_SAVED_SEARCH.

  • A request to refresh the Watchlist item count comes from the Watchlist portlet. This will invoke an exposed service, which delegates the call to a method on a provided Watchlist JAR file.

  • The method on the Watchlist JAR file will take care of rerunning the query (on the expenses database) and taking the results to update the Watchlist item count (on the Watchlist database).

14.12.3.2 Summary of Implementation Tasks

At a high-level, for asynchronous Watchlist items, the developer tasks are:

  • (Not needed for Human Task) Determine/set up view objects to execute the query for Watchlist count. You may want to include view criteria with bind variables and specify default values for bind variables.

    For example, most view objects seeded for the Watchlist would need to filter by user to show counts specific to the logged-in user. You could create a view criteria with a bind variable called userId and specify the default value as a groovy expression to determine the current user id from the security context. You then would seed this view criteria id in the setup table along with the view object. The Watchlist API would execute the view object by applying this view criteria to get the row count. Example 14-44 shows a code snippet from the view object xml for bind variable with default value.

    Example 14-44 Example Code from the View Object XML for Bind Variable with Default Value

    <Variable
                Name="userId"
                Kind="where"
                Type="java.lang.String">
                <TransientExpression><![CDATA[return adf.context.securityContext.userName;]]></TransientExpression>
              </Variable>
    
  • (Optional) Set up a Summary view object to facilitate refresh count and specify the summary attribute in the Watchlist setup table. Watchlist code would use this information to query the count instead of doing a rowcount on the executed view object results.

  • Include Watchlist model JAR files in your service project and set up a refreshWatchlistCategory service method. This method will only contain code to delegate the call to the nested Watchlist application module method that actually executes the view object queries by reading your Watchlist setup data. This requires that all the corresponding model projects are included as JAR files in this service project so view objects are available in the class path. This service should be exposed so that the Watchlist UI can use it to launch the refresh process.

  • Determine/code task flows for drill-down from the Watchlist UI. There is no special coding required for these task flows; the key-value parameter string that you specify in the setup table will be used as the input parameter list when invoking the specified task flow for the UI drilldown on Watchlist items.

  • (Optional) Enable saved search promotion to the Watchlist: Include Watchlist model JAR files in the corresponding project for query panel and work with Watchlist API. For promotion and unpromotion of user-saved searches, code will have to invoke a method in the provided Watchlist JAR, which will then handle interaction back to the Watchlist. Add promotion and unpromotion components on the search panel so that saved searches can be used as Watchlist items.

  • Include Watchlist UI and Protected model JAR files in your UI Superweb project, to enable Watchlist menu drilldown in the UI Shell global area, as shown in Figure 14-39.

    Figure 14-39 Example Watchlist Menu Drilldown

    Example Watchlist Menu Drilldown
  • Create FND_LOOKUPS for displayed Watchlist category and item meaning (FND_STANDARD_LOOKUP_TYPES.LOOKUP_TYPE). Product teams will need to seed the lookup type with meaning for category (VIEW_APPLICATION_ID = 0 and SET_ID = 0). The translated lookup type meaning is shown in the Watchlist UI for category, while the corresponding lookup value meanings are shown in the Watchlist UI for items (user saved search item meanings come from saved search directly). Product teams will need to create seed data for this lookup.

  • Example 14-45 presents sample code to create or update the lookup.

    Example 14-45 Sample Code to Create/Update Watchlist Lookup

    declare
    begin
    FND_LOOKUP_TYPES_PKG.CREATE_OR_UPDATE_ROW (
      X_VIEW_APPSNAME => 'FND',
      X_LOOKUP_TYPE => 'FIN_EXM_WATCHLIST_CATEGORY',
      X_APPLICATION_SHORT_NAME => 'EXM',
      X_MEANING => 'Expenses',
      X_DESCRIPTION => 'Expenses Watchlist Category',
      X_REFERENCE_GROUP_NAME => null
    );
    end;
     
    declare
    begin
    FND_LOOKUP_VALUES_PKG.CREATE_OR_UPDATE_ROW (
      X_LOOKUP_TYPE           => 'FIN_EXM_WATCHLIST_CATEGORY',
      X_VIEW_APPSNAME         => 'FND',
      X_LOOKUP_CODE           => 'SAVED_EXPENSE_REPORTS',
      X_MEANING               => 'In Progress Expense Reports'
    --  X_SET_CODE              IN VARCHAR2 DEFAULT NULL,
    --  X_DESCRIPTION           IN VARCHAR2 DEFAULT NULL,
    --  X_ENABLED_FLAG          IN VARCHAR2 DEFAULT 'Y',
    --  X_START_DATE_ACTIVE     IN VARCHAR2 DEFAULT NULL,
    --  X_END_DATE_ACTIVE       IN VARCHAR2 DEFAULT NULL,
    --  X_DISPLAY_SEQUENCE      IN NUMBER DEFAULT NULL
      );
    end;
    

Seed Watchlist categories and setup information. Create your category in ATK_WATCHLIST_CATEGORIES and then seed your items in the reference data table (ATK_WATCHLIST_SETUP). The watchlist_item_type determines how the Watchlist code will handle the item.

Note:

HUMAN_TASK items only require seeding in the tables to work; there are no view objects to create.

14.12.4 How to Use the Watchlist

Developers should follow these procedure to use the Watchlist.

14.12.4.1 Making the Watchlist Link in UI Shell Global Area Work

To ensure the Watchlist link works in your pages, complete these steps.

  • Add this ADF library JAR file to the SuperWeb user interface project for your application (the JAR file must be part of your WAR in WEB-INF/lib):

    fusionapps/jlib/AdfAtkWatchListPublicUi.jar

  • Add this dependent model ADF library JAR file in your application (the JAR file must be part of your EAR in APP-INF/lib):

    fusionapps/jlib/AdfAtkWatchListProtectedModel.jar

  • Add this dependent resource bundle ADF library JAR file in your application (the JAR file must be part of your EAR in APP-INF/lib):

    fusionapps/jlib/AdfAtkWatchListPublicResource.jar

  • Add these resource-ref entries to web.xml in your SuperWeb user interface project:

    <resource-ref>
        <res-ref-name>wm/WorkManager</res-ref-name>
        <res-type>commonj.work.WorkManager</res-type>
        <res-auth>Container</res-auth>
    </resource-ref>
    <resource-ref>
        <res-ref-name>jdbc/ApplicationDBDS</res-ref-name>
        <res-type>javax.sql.DataSource</res-type>
        <res-auth>Container</res-auth>
    </resource-ref>
    

14.12.4.2 Seed Reference Data (All items)

Refer to Section 14.12.2, "Watchlist Physical Data Model Entities" for details of the entire Watchlist data model. Seed only ATK_WATCHLIST_CATEGORIES and ATK_WATCHLIST_SETUP.

14.12.4.3 Create Summary View Object (SEEDED_QUERY)

  • By default, Watchlist code will access the application module/view object that is specified in the setup table, and rerun the query to refresh the Watchlist count. The summary view object is a way for a product team to get the count in its own way. Usually this will be for efficiency reasons.

  • The product team can signal that it wants the Watchlist code to use its summary view object by seeding something in SUMMARY_VIEW_ATTRIBUTE of ATK_WATCHLIST_SETUP. If this is not null, the Watchlist code will get the view object, but instead of running the query, it will just take the first row and get the specified attribute.

  • Thus, the developer task is to create a view object with the correct count in the attribute specified in the setup table.

14.12.4.3.1 Summary Tables

One common reason to use a Summary view object is if the seeded query is based on Multiple-Organization Access Control (MOAC) data security. This is because you can calculate the count of this query per BUID. The count of a user is just the sum of the counts of the BUIDs that the user can access.

For example, say you have a table (or query) that has three rows of BUID #1, three rows of BUID #2, and three rows of BUID #3. The current user has access to BUIDs #1 and #2.

If you wanted to get the count, MOAC would filter the rows by BUID and return six rows.

However, since you are only interested in the count, a more efficient way would be to create a summary table for this table. The summary table keeps track of the count for each BUID. For the example table, the summary table would resemble Table 14-7.

Table 14-7 Example Summary Table

BUID Count

1

3

2

3

3

3


Now, instead of using MOAC to find a count for a particular user, you use MOAC to find the SUM of counts for the user. The example user would get the first two rows returned, and you can calculate the total count by summing the count column.

Developers can use summary tables to populate their Summary view object attribute.

14.12.4.4 Create Seeded Saved Searches in MDS (SEEDED_SAVED_SEARCH)

In addition to seeding seeded saved searches in the reference tables, the saved searches need to be seeded in MDS so that when the user visits the saved search panel, the saved search will show as one of the choices in the drop-down box. Currently, saved searches in MDS are stored in the file system as an XML file for each view object. The developer steps to create this file are:

  • Make sure you have enabled MDS for your application.

  • Run the application and visit the desired search page.

  • Use the UI to create saved searches and name them. For each saved search, select Run Automatically.

  • Examine the adf-config.xml file to determine where your file-based MDS repository is located.

  • In a terminal, change to the directory:

    <MDS repository>/persdef/oracle/apps/.../mdssys/cust/user/<user>/

    <user> would be the user you used to save the search with, or 'anonymous' by default.

  • Inside that directory, there should be an xxxVO.xml.xml file that contains the created saved searches. Keep that file.

  • In that XML file, note the saved search id, which should match the View Criteria Id in the reference data.

    Note:

    This Id can be different than the display name that you entered in the saved search UI.

14.12.4.5 Creating Application Module/View Objects (All except HUMAN_TASK)

Refer to Section 14.12, "Implementing the Watchlist."

14.12.4.6 Setting Up Service (All except HUMAN_TASK)

For the same Watchlist items, the Watchlist portlet needs to be able to invoke a refresh. Each product team will set up and expose a service that includes local JAR files for this purpose. The nested Watchlist JAR file can use those local JAR files in its refresh code.

The service will expose the refreshCategory method, which will, in turn, delegate the call to the same method in the nested Watchlist application module. This method will be provided in the Watchlist JAR file and will contain code to perform the category-wide refresh.

14.12.4.7 Importing All Watchlist-Related AMs

Your Service project will need to import the other JAR files from your product that will need to be used by the Watchlist code.

14.12.4.8 Nesting Watchlist Application Module

Include AdfAtkWatchListProtectedModel.jar and AdfAtkWatchListPublicModel.jar in your service project, and nest AdfAtkWatchListPublicUi.jar in your service application module.

Set up the AppMasterDB connection that comes with it. Point it to the database where you have seeded your data in the Watchlist tables. This usually is your development database that is used for the ApplicationDB connection.

14.12.4.9 Using the refreshWatchlistCategory Method

public void refreshWatchlistCategory(String categoryCode)

This method, shown in Example 14-46, refreshes all Watchlist items in the corresponding category.

Example 14-46 Refreshing Watchlist Items

public void refreshWatchlistCategory(String categoryCode) {
    AtkWatchlistPublicAMImpl wlAM = this.getAtkWatchlistPublicAMImpl();
    wlAM.refreshWatchlistCategory(categoryCode);
}

14.12.4.10 Importing Watchlist JAR Files into the Saved Search Project (USER_SAVED_SEARCH)

For subsequent steps that require running Watchlist APIs from your code, you will need to import the Watchlist JAR files. These also contain an AppMasterDB connection that will need to point to the Watchlist database.

  • Add AdfAtkWatchlistProtectedModel.jar and AdfAtkWatchlistPublicService.jar (fusionapps > jlib) as ADF libraries in the appropriate data model projects, preferably in a model project that is visible to both service and user interface model project application modules.

  • Add AdfAtkWatchlistPublicUi.jar as an ADF library to your user interface project.

  • Configure the AppMasterDB connection.

14.12.4.11 Promoting Saved Search to the ATK Watchlist (USER_SAVED_SEARCH)

Every Watchlist-enabled saved search panel will need to include a component to let the user control which of the saved searches to promote. The pre-seeded saved searches will be shown as static, while the user can use checkboxes to determine which of his or her own saved searches should be promoted. There will be listeners to this component that will publish Business Events to make the appropriate worklist changes.

Before you begin

Ensure that the following steps have been performed.

  • Populate ATK tables with SEED watchlist category information. Product teams need to provide information about the service that refreshes the watchlist item count.

  • Populate ATK tables with appropriate watchlist setup information. There must be a watchlist setup item of type "USER_SAVED_SEARCH".

  • Make sure the application is MDS enabled so users can save their searches and that the saved searches exist across sessions.

  • From the watchlist UI, users can drill down to the transactional UI flows. Make sure that the transactional UI flow is properly set up so that it can show the search page when the user clicks the watchlist item in the watchlist UI.

  • In the application project, create a backing bean and register it as a backingBeanScope bean. In the backing bean, create the Java method shown in Example 14-47:

    Example 14-47 Creating the Backing Bean

    import oracle.adf.view.rich.model.QueryDescriptor;
    import oracle.adf.view.rich.model.QueryModel;
    ..................
     
        public List<String> getWatchListUserSavedSearchList() {
            if (AppsLogger.isEnabled(AppsLogger.FINEST)) {
              AppsLogger.write(this, "Watchlist saved search promotion: Entering method getWatchListUserSavedSearchList", AppsLogger.FINEST);
            }
            List<String> WatchListUserSavedSearchList = new ArrayList<String>();
            QueryModel queryModel =
                (QueryModel)evaluateEL("#{bindings.ImplicitViewCriteriaQuery.queryModel}");//See next code sample for evaluateEL()
            if (queryModel != null) {
              if (AppsLogger.isEnabled(AppsLogger.FINEST)) {
                AppsLogger.write(this, "Watchlist saved search promotion: getWatchListUserSavedSearchList method: queryModel is not null", AppsLogger.FINEST);
              }
                List userQueries = queryModel.getUserQueries();
                if (userQueries != null & userQueries.size() > 0) {
                  if (AppsLogger.isEnabled(AppsLogger.FINEST)) {
                    AppsLogger.write(this, "Watchlist saved search promotion: getWatchListUserSavedSearchList method: User Saved Searches exist", AppsLogger.FINEST);
                  }
                    for (int i = 0; i < userQueries.size(); i++) {
                        QueryDescriptor qd = (QueryDescriptor)userQueries.get(i);
                        if(qd != null){
                          if (AppsLogger.isEnabled(AppsLogger.FINEST)) {
                            AppsLogger.write(this, "Watchlist saved search promotion: getWatchListUserSavedSearchList method: Adding user saved search name to the watchListUserSavedSearchList using QueryDescriptor getName: " + qd.getName(), AppsLogger.FINEST);
                          }
                          WatchListUserSavedSearchList.add(qd.getName());
                        }
                    }
                }
            }
            if (AppsLogger.isEnabled(AppsLogger.FINEST)) {
              AppsLogger.write(this, "Watchlist saved search promotion: Exiting method getWatchListUserSavedSearchList: returning watchListUserSavedSearchList: " + WatchListUserSavedSearchList, AppsLogger.FINEST);
            }
            return WatchListUserSavedSearchList;
        }     
    
14.12.4.11.1 How to Promote a User-Saved Search to the Watchlist

Follow these steps to integrate the ATK team-provided task flow to promote saved searches to the Watchlist.

Note:

If you already have implemented promoting the user-saved search to the Watchlist, see Additional Steps for Existing Consumers.
  1. Make sure the AdfAtkWathcListPublicUi.jar file is available (usually in fusionapps/jlib).

  2. Launch JDeveloper and open the .jspx or .jsff page containing the query region whose saved searches have to be promoted.

  3. In the query region, add a toolbar facet.

    1. Right-click the component.

    2. In the menu that opens, select Facets-Query.

    3. From the submenu, select Toolbar, as shown inFigure 14-40.

      Figure 14-40 Adding Toolbar Facet to Query Region

      Adding Toolbar Facet to Query Region
  4. In the toolbar facet of the query region, drag and drop an ADF Toolbar component, such as Toolbar (ADF Faces.Common Components) shown in Figure 14-41, onto the page.

    Figure 14-41 Adding an ADF Toolbar Component

    Adding an ADF Toolbar Component

    The toolbar facet in the Source view will look similar to:

    <f:facet name="toolbar">
      <af:group id="g1">
        <af:toolbox id="t1">
          <af:region value="#{bindings.AtkWatchlistUserSavedSearchPromotionTF1.regionModel}"
                     id="r7"/>
        </af:toolbox>
        <af:toolbar id="t2"/>
      </af:group>
    </f:facet>
    
  5. Open the Resource Palette and create a File System connection to the directory containing the AdfAtkWatchListPublicUI.jar file, as shown in Figure 14-42.

    Figure 14-42 Creating the File System Connection

    Creating the File System Connection
  6. Expand the connection node and the ADF library node in the Resource Palette as shown in Figure 14-43.

    Figure 14-43 Expanding the Connection Node

    Expanding the Connection Node

    Once the ADF Task Flows node is expanded, you should see two task flows. The task flow AtkWatchlistUserSavedSearchPromotionTF is the one to be used by product teams.

  7. Drag and drop the AtkWatchlistUserSavedSearchPromotionTF task flow as a region into the toolbar component (present in the query region toolbar facet), created in the previous steps. As soon as the task flow is dropped onto the page, the Edit Task Flow Binding dialog displays. Enter the following values for the mandatory parameters.

    • categoryCode: Provide the WATCHLIST_CATEGORY_CODE that has been seeded in the ATK tables.

    • watchlistItemCode: Provide the WATCHLIST_ITEM_CODE provided while creating the Watchlist setup data.

    • userSavedSearchList: This represents the model object of the query region. To populate this field:

      1. Select the userSavedSearchList input field, click the small "v" icon present at the end of the field and select the Expression Builder option.

      2. Select the value from the Java method shown in Example 14-47. In this case, the value is watchListUserSavedSearchList, found in ADF Managed Beans > backingBeanScope > searchOrderScheduleBackingBean > watchListUserSavedSearchList.

        The Expression will be:

        #{backingBeanScope.searchOrderScheduleBackingBean.watchListUserSavedSearchList}
        
      3. Click OK to insert the value in the userSavedSearchList field.

    • internalCriteriaName: This represents the ViewCriteria Name of the search binding executable of the query region present in the UI page. To populate this field, follow the same steps as you did to populate the userSavedSearchList field, but select internalCriteriaName. Also see Additional Steps for Existing Consumers.

    When you are finished, the Edit Task Flow Binding dialog will resemble Figure 14-44.

    Figure 14-44 Completed Edit Task Flow Binding Dialog

    Completed Edit Task Flow Binding Dialog
  8. Click OK. This creates a region component in the UI page, as shown in Figure 14-45.

    Figure 14-45 Created Region Component

    Created Region Component
  9. Open the page definition file and select the executable associated with the Watchlist-related task flow.

  10. Open the Property Inspector and set the Refresh field to ifNeeded, as shown in Figure 14-46. The ATK saved search promotion task flow has to be refreshed each time the query model changes. This step ensures that the task flow is refreshed whenever the query model changes.

    Figure 14-46 Setting Refresh to ifNeeded

    Setting Refresh to ifNeeded
  11. Add a task flow security permission to the AtkWatchlistUserSavedSearchPromotionTF task flow in the jazn-data.xml file.

    1. Open the jazn-data.xml file and select the ADF Policies tab.

    2. From the Task Flow list, select the AtkWatchlistUserSavedSearchPromotionTF, grant it to an appropriate role, and select appropriate actions as shown inFigure 14-47.

      Figure 14-47 Adding Security Permissions to jazn_data.xml

      Adding Security Permissions to jazn_data.xml
  12. Run the UI page. In the toolbar facet of the query region, there will be a Watchlist Options button, as shown in Figure 14-48.

    Figure 14-48 Watchlist Options Button in Toolbar Facet

    Watchlist Options Button in Toolbar Facet

    When you click the button, a popup with the list of all saved searches displays, as shown in Figure 14-49.

    Figure 14-49 List of Saved Searches

    List of Saved Searches

Additional Steps for Existing Consumers

For product teams that already have implemented promoting Saved Search to the ATK Watchlist, there are four additional steps.

  • In your pageDef, change the WatchList task flow parameter called queryModel from:

    <parameter id="queryModel"     value="#{bindings.ExistingCriteria.queryModel}"/>
    

    to:

    <parameter id="userSavedSearchList"
      value="#{backingBeanScope.YourBean.watchListUserSavedSearchList}"/>
    
  • Use the public List<String> getWatchListUserSavedSearchList() Java method by passing the QueryModel binding of your af:query.

  • Change the old queryBinding parameter to the new internalCriteriaName parameter. For example, change:

    parameter id="queryBinding" value="#{bindings.SearchPageVOCriteriaQuery}"
    

    to:

    parameter id="internalCriteriaName" value="#{backingBeanScope.searchRelatedBean.internalCriteriaName}"
    
  • In someBackingBeanScopeBean.java, such as the one you created in Example 14-47, add the two methods shown in Example 14-48.

    Example 14-48 Additions to the backingBeanScopeBean

    import javax.el.ExpressionFactory;
    import javax.el.MethodExpression;
    import javax.el.ValueExpression;
    import javax.faces.context.FacesContext;
    import oracle.adf.model.binding.DCBindingContainer;
    import oracle.jbo.uicli.binding.JUSearchBindingCustomizer;
     
      public Object evaluateEL(String expr)
      {
          FacesContext facesContext=FacesContext.getCurrentInstance();
          ExpressionFactory exprFactory=facesContext.getApplication().getExpressionFactory();
          ValueExpression valueExpr=exprFactory.createValueExpression(facesContext.getELContext(), expr, Object.class);
          return valueExpr.getValue(facesContext.getELContext());
      }
     
      public String getInternalCriteriaName() {
         if (AppsLogger.isEnabled(AppsLogger.FINEST)) {
           AppsLogger.write(this, "Watchlist saved search promotion: Entering method getInternalCriteriaName", AppsLogger.FINEST);
         }
         String queryBinding = "#{bindings.SearchPageVOCriteriaQuery}";
         DCBindingContainer  searchBinding = (DCBindingContainer)evaluateEL(queryBinding);       
         internalCriteriaName = JUSearchBindingCustomizer.getCriteriaName(searchBinding);
         if (AppsLogger.isEnabled(AppsLogger.FINEST)) {
           AppsLogger.write(this, "Watchlist saved search promotion: Exiting method getInternalCriteriaName with return value for internalCriteriaName: " + internalCriteriaName, AppsLogger.FINEST);
         }     
         return internalCriteriaName;
      } 
    

    Note: In someBackingBeanScopeBean.getInternalCriteriaName(), the queryBinding variable in the first line is the one you see in af:query. For example, af:query queryListener="#{bindings.SearchPageVOCriteriaQuery.processQuery}" Just take the QueryBinding, #{bindings.SearchPageVOCriteriaQuery}.

14.12.4.12 Code Task Flows to Accept Parameters (All except HUMAN_TASK)

If you have seeded the information properly, your normal task flows should work when drilled-down to from the Watchlist portlet.

14.12.4.12.1 Saved Search

For saved search Watchlist items, you will want the drilldown to load a specific saved search by default.

One function of the Watchlist portlet will be to take a user to the corresponding action area when the user clicks a Watchlist item. For saved searches, the desired functionality is to open the task flow containing the saved search panel, and by default, show the clicked saved search.

On the portlet, upon clicking the link, code will put the proper ViewCriteria name into the PageFlowScope with the parameter name vcName.

When loaded, the destination task flow will have two tasks:

  • Look into the PageFlowScope to retrieve the ViewCriteriaName.

  • Obtain the RichQuery object, and apply the ViewCriteriaName to it, if one is given.

The developer will be concerned with implementing the two steps for the destination task flow. First, he or she can retrieve the ViewCriteriaName from the PageFlowScope with the code shown in Example 14-49.

Example 14-49 Retrieving the ViewCriteriaName from the PageFlowScope

Map pfs = RequestContext.getCurrentInstance().getPageFlowScope(); String vcName = (String) pfs.get("vcName");

Second, the developer can use the code shown in Example 14-50 to apply the ViewCriteria to the search panel. If no ViewCriteria was passed, the code loads the default ViewCriteria.

Example 14-50 Applying ViewCriteria to the Search Panel

if (vcName == null || vcName.equals("")) {
        // If no ViewCriteria is given, load default VC
        DCBindingContainer dcbc = 
(DCBindingContainer)BindingContext.getCurrent()
                .getCurrentBindingsEntry();
FacesCtrlSearchBinding fcsb = 
(FacesCtrlSearchBinding)dcbc
.findExecutableBinding("ImplicitViewCriteriaQuery");
FacesCtrlSearchDef def = (FacesCtrlSearchDef)fcsb.getDef();
DCParameterDef paramDef = 
(DCParameterDef)def.getParameterDef(
JUSearchBindingCustomizer.PARAMCRITERIA);
fcsb.evaluateParameter(paramDef.getExpression(),false));
} else {
        QueryModel model = search_query.getModel();
        QueryDescriptor selDescriptor = model.create(vcName, null);
if (selDescriptor != null) {
model.setCurrentDescriptor(selDescriptor);
}
BindingContainer bindings = 
BindingContext.getCurrent().getCurrentBindingsEntry();
OperationBinding method = (OperationBinding) 
bindings.getControlBinding("applyViewCriteriaByName");
method.getParamsMap().put("name", vcName);
method.execute();
}

This code should be run once upon loading the destination task flow. One solution is to connect it to the rendered property of the search panel, and use static variable to ensure that it only runs once.

14.12.4.13 Import Watchlist UI JAR File in User Interface Project

There is a link in the UI Shell for Watchlist in the global area. To make it work, the user interface project that you will ultimately run will need to include these Watchlist UI JAR files: AdfAtkWatchListPublicUI and its dependent model JAR file AdfAtkWatchListProtectedModel.

14.12.4.14 Additional Entries for Standalone Deployment

These entries are required for the Watchlist service and UI to be able to work in a standalone deployment.

  • Add this entry in ejb-jar.xml in your service project that contains the watchlist service next to the similar entry for ApplicationDB. You need resource-ref entries for both ApplicationDB and AppMasterDB:

    <resource-ref> 
      <res-ref-name>jdbc/AppMasterDBDS</res-ref-name> 
      <res-type>javax.sql.DataSource</res-type> 
      <res-auth>Container</res-auth> 
    </resource-ref>
    
  • Add this entry in web.xml in your SuperWeb project next to the similar entry for ApplicationDB. You need resource-ref entries for both ApplicationDB and AppMasterDB:

    <resource-ref> 
      <res-ref-name>jdbc/AppMasterDBDS</res-ref-name> 
      <res-type>javax.sql.DataSource</res-type> 
      <res-auth>Container</res-auth> 
    </resource-ref>
    
  • connections.xml should have a valid database entry for AppMasterDB.

14.13 Implementing Group Spaces

Group Spaces bundle all the collaboration tools and provide an easy way for users to create their own ad hoc collaborative groups around a project or business artifact.

This section describes how to implement the Group Spaces functionality that is available in UI Shell.

14.13.1 Assumptions

These assumptions are made:

  • The implementation is occurring in a label that is either dependent on ATGPF_MAIN or uptakes ATGPF_MAIN on a regular basis.

  • The spaces application and the JDeveloper Standalone WebLogic Server that would run the application have the requisite setup done.

  • The consuming applications are secure. GroupSpaces functionality attempts to retrieve the group spaces for the logged-on user. Without a secure application, this functionality would fail.

14.13.2 How to Implement Group Spaces

Follow these steps to implement GroupSpaces.

  1. Make sure the Oracle WebCenter Spaces Client library, spaces-webservice-client.jar, has been added to the Project.

  2. Define an application connection to point to the URL of the Oracle WebCenter Spaces WebService. To do this:

    1. Right-click Connections in the Application Resource palette.

    2. Choose New Connection > URL.

    3. Enter the value $HOST:$PORT/webcenter/SpacesWebService, where $HOST and $PORT are the hostname and the port on which the spaces application is running.

    4. Save this connection with the name SpacesWebServiceEndpoint.

  3. To make a homepage tab appear within UI Shell, deploy the Functional Setup Manager application.

14.13.3 Overview of Group Spaces Functionality

The Group Spaces functionality implements these features:

  • When the GroupSpaces link is clicked, a popup displays the logged-in user's Group Spaces.

  • When the user clicks a Group Space from the list, the Group Space's home page is opened in an iFrame. This iFrame is rendered within a Home Page tab called WebCenter. The Group Space is opened suppressing the WebCenter chrome but will still render all the tabs within that Group Space. This chrome level suppresses the WebCenter chrome but will still render all the tabs within that Group Space.

  • When the user clicks View All GroupSpaces, the same UI as the My Group Spaces in the spaces application is rendered. This is also rendered as an iFrame within the WebCenter HomePage tab where it suppresses the chrome as well as the top level WebCenter tabs.

14.13.4 How to Pass a Chromeless Template

When navigating to the WebCenter home page, a WebCenter template that does not contain the header chrome is desired. This can be done by appending &wc.pageTemplate=oracle.webcenter.spaces.siteTemplate.gsContent.

Pass this parameter when navigating to a Group Space from the Group Spaces global dialog, TagCenter, Global Search, or an Activity Stream link.

Use a question mark (?) instead of an ampersand (&) if this is the only request parameter for that URL.

14.14 Implementing Activity Streams and Business Events

Activity Streams is a feature provided by the WebCenter. Product teams use Activity Streams to capture changes and publish Activity messages. Customer Relations Management (CRM), in particular, makes heavy use of this feature to keep abreast of service requests and opportunities. Users subscribe to Activity Streams by using the Activity Streams user interface.

For business events, Activities are shown only to users who subscribe to the stream and who have the necessary security access.

Activity Streams can be connected to:

This section is concerned only with Business Objects.

14.14.1 Introduction to WebCenter Activities

A WebCenter Activity is comprised of the following:

  • Actors - The user who performed the action that triggered the Business Event. For Oracle Fusion Applications, this will be the userid fetched from the user session.

  • ActivityType - The type of Activity to be published. This defines the format of the Activity message.

  • Objects - The objects associated with the Activity. There could be multiple objects associated with a Activity but for Business Events, only the event source is used as an object.

WebCenter Activities are defined in the service-definition.xml file. The scope of service_definition.xml is per business object. The service id attribute should match the name of the entity object. The service-definition.xml file contains ActivityTypes, Object Types and resource-view definitions. An ActivityType needs to be defined for every business event on the Entity Object. The type name should match the business event's name. The messageFormatKey attribute in the ActivityType element points to a message key in a ResourceBundle. It defines the format of the message displayed in the Activity Stream UI. These tokens are supported in a message.

  • {actor[0]}: Replaced by the display name of the user who triggered the event.

  • {object[0]}: Replaced by the value of the attribute in the event payload whose attribute name matches the object type name.

  • {custom[attr1].value}: Replaced by the value of the attr1 attribute in the event's payload.

The message format would look similar to:

{actor[0]} updated Opportunity {object[0]} status to {custom[status].value}

14.14.2 How to Publish Business Events to Activities

ADF Business Components Business Events are, by default, published to SOA Event Delivery Network (EDN). Applications Core implements a BusinessEventAdapter to listen to these events, transition them to Activities, and asynchronously publish them to the ActivitiyStream Service. This adapter is a singleton per application and publishes the Business Events raised to the ActivityService in the order they are produced. A Business Event is published as an Activity only when an ActivityType matching the name of the event is found in the service definition for the Business Object.

While mapping a Business Event to an Activity, keep these notes in mind:

  • There is one-to-one mapping between an Activity Service definition and a Business Object. The service id attribute in the service-definition.xml file should match the Entity name.

  • The ActivityType name should match the name of the Business Event.

  • Define an ObjectType with the name attribute matching an attribute name in the payload. This attribute value will replace the {object[0]} token in the message format. WebCenter supports multiple object types for an Activity, but for Business Events-related Activities, only one Object that corresponds to the event source is supported. The Object type name should match the name of the attribute whose value should be displayed in the hyper link for the object.

  • Define a message format using tokens for Actor, Object and customAttributes. The custom attribute names used in the token should match the attribute names in the payload.

  • In the Activity message displayed in the UI, only Actor and Object display values will be rendered as hyper links. If an Activity involves multiple objects, hyper links will be supported only for the event source object. Multiple attributes from the event payload can be referenced in the message.

  • The hyper link for the object allows users to navigate to the Business Object's work area. The target page for navigation can be configured through the resource-view element in the service-definition.xml file.

14.14.3 How to Publish Activities Using a Programmatic API

For certain scenarios, Oracle Fusion Applications are required to publish Activities for model changes that are not based on Entity Objects. Since ADF Business Components Business Events are based on Entity Objects, it is not possible to use these events for publishing Activities for non Entity Object-based model changes. For such scenarios, product teams could use the Applications Core API shown in Example 14-51 to programmatically publish Activities to the ActivityStream service.

BusinessActivityPublisher

This class provides the publishActivity API that can be used to publish Activities asynchronously. This is a singleton per J2EE application. An instance of this class can be obtained using the getInstance API. This lets product teams define such things as ActivityTypes, ObjectTypes, and resource-view definitions, declaratively in the service-definition.xml file, similar to Business Event-related activities.This would allow product teams to follow the same mechanism to define and publish Activities for both Entity Object and non-Entity Object-based model changes with very little code changes.

Example 14-51 BusinessActivityPublisher.java

/**
 * This class is responsible for publishing business events as WebCenter Activities to
 * the ActivityStreaming service. This is a singleton per J2EE application.
 * An instance of this object is obtained using the getInstance() method. This class
 * transforms business events into Activities and publishes them to Activity
 * Service asynchronously. Resources held by the class are released by using
 * release() method. In J2EE container, release is done by Applications Core when 
 * the application is undeployed or stopped.
 */
public class BusinessActivityPublisher
{
    /**
     * Returns and instance of BusinessActivityPublisher if one exists or
     * creates anew one.
     * @return
     */
    public synchronized static BusinessActivityPublisher getInstance()
 
    /**
     * Queues the Activity for publishing. The queued activities are published
     * to the Activity Streaming service asynchronously if there is a matching
     * ActivityType defined for the source business event. If no matching
     * ActivityType is found in the service-definition.xml corresponding to the
     * source Entity Object, the activity is ignored.
     * @param activity
     */
    public void publishActivity(BusinessActivity activity)
 
    /**
     * Should be called during App undeploy to stop the publisher thread.
     * In a J2EE container, this method is called by Applications Core
     * ServletContextListener.
     */
    public void release()

BusinessActivity Class

This is an abstract class that is used to represent an Activity corresponding to a Business Event. BusinessActivityPublisher:publishActivity() takes an instance of this class as a parameter. Product teams would implement an instance of this class to encapsulate the details of the Activity corresponding to the non Entity Object-based model changes and invoke the publishActivity API with this as a parameter. BusinessActivityPublisher will find the matching ActivityType and ObjectType defined for this Activity in service-definition.xml and publish the Activity to the ActivityStreaming Service asynchronously. Details of the API on this class are shown in Example 14-52.

Example 14-52 BusinessActivity.java

/**
   * Name of the ActivityType defined in service-definition that
   * corresponds to serviceId returned by getServiceId().
   * @return Name of the ActivityType
   */
  public String getName()
 
  /**
   * id of the service-definition containing the metadata for this
   * Activity.
   * @return serviceId
   */
  public abstract String getServiceId();
 
  /**
   * Array of GUIDs for Actors of the Activity.
   * @return array of guids for the Actors.
   */
  public abstract String[] getActors();
 
  /**
   * This api will return  additional service ids
   * @return Array of ServiceIds
   */
  public String[] getAdditionalServiceIds(){ return null};
 
  /**
   * This attr provides a "," separated list of object type
   * names associated with a particular Activity.
   * @return
   */
  protected String getActivityObjectTypeNames(){
   return null;
  } 
 
  **
   * Payload for the Activity. Every attribute that is part of this payload is
   * persisted in WC as custom attribute of the Activity Object so only
   * attributes needed for the Activity Message should be added to the payload
   * to avoid performance overhead.
   * The payload typically  contains:
   * 1. Attribute(s) whose name matches the object-type name attribute in
   *    service-definition. This value is used in generating the object-id
   *    of the object referenced in the Activity Stream message.
   * 2. All the attributes referenced in the Message format using {custom}
   *    token.
   * @return a map containing the attribute names and their values needed to
   * display the Activity Message for this Activity.
   */
  public abstract Map getPayload();

BusinessActivity

This is an abstract class that is used to represent an Activity corresponding to a business event. BusinessActivityPublisher:publishActivity() takes an instance of this class as a parameter. Product teams would implement an instance of this class to encapsulate the details of the Activity corresponding to the non Entity Object-based model changes and invoke the publishActivity API with this as a parameter. BusinessActivityPublisher will find the matching ActivityType and ObjectType defined for this Activity in the service-definition.xml file and publish the Activity to the ActivityStreaming Service asynchronously. Details of the API on this class are shown in Example 14-53.

Example 14-53 BusinessActivity.java

/**
  * Name of the ActivityType defined in service-definition that
  * corresponds to serviceId returned by getServiceId().
  * @return Name of the ActivityType
  */
 public String getName()
 
 /**
  * id of the service-definition containing the metadata for this
  * Activity.
  * @return serviceId
  */
 public abstract String getServiceId();
 
 /**
  * Array of GUIDs for Actors of the Activity.
  * @return array of guids for the Actors.
  */
 public abstract String[] getActors();
 
 /**
  * This api will return  additional service ids
  * @return Array of ServiceIds
  */
 public String[] getAdditionalServiceIds(){ return null};
 
 /**
  * This attr provides a "," separated list of object type
  * names associated with a particular Activity.
  * @return
  */
 protected String getActivityObjectTypeNames(){
  return null;
 } 
 
 **
  * Payload for the Activity. Every attribute that is part of this payload is
  * persisted in WC as custom attribute of the Activity Object so only
  * attributes needed for the Activity Message should be added to the payload
  * to avoid performance overhead.
  * The payload typically  contains:
  * 1. Attribute(s) whose name matches the object-type name attribute in
  *    service-definition. This value is used in generating the object-id
  *    of the object referenced in the Activity Stream message.
  * 2. All the attributes referenced in the Message format using {custom}
  *    token.
  * @return a map containing the attribute names and their values needed to
  * display the Activity Message for this Activity.
  */
 public abstract Map getPayload();

14.14.4 How to Implement Activity Streams

This section provides details about the steps involved in integrating this feature with Oracle Fusion Applications.

14.14.4.1 Defining and Publishing Business Events in JDeveloper

To define a Business Event, follow these steps:

  1. In the Application Navigator, double-click an entity object.

  2. In the overview editor, click the Business Events navigation tab.

  3. On the Business Events page, expand the Event Publication section and click the Edit event publications icon.

  4. In the Edit Event Publications dialog, click New to create a new event.

  5. Double-click the new cell in the Event column, and select the appropriate event.

  6. Double-click the corresponding cell in the Event Point column, and select the appropriate event point action.

  7. You optionally can define conditions for raising the event using the Raise Conditions table.

  8. Click OK.

An event definition in the Entity XML file would look similar to:

<EventDef  Name="OpportunityStatusUpdate">
  <Payload>
    <PayloadItem AttrName="OpptyId"/>
    <PayloadItem AttrName="Status"/>
    <PayloadItem AttrName="Customer.CustomerId"/>
  </Payload>
</EventDef>

14.14.4.2 Overriding isActivityPublishingEnabled() to Enable Activity Publishing

By default, Business Events are not published as Activities. Product teams should override the isActivityPublishingEnabled() method to enable Activity publishing for an Entity Object. Table 14-8 shows the details about the APIs exposed in OAEntityImpl that product teams can override.

Note that, except for the isActivityPublishingEnabled() method, other methods mentioned in Table 14-8 should be avoided in favor of transient attributes specified in Section 14.14.4.3, "Defining Activity Attributes Declaratively."

Table 14-8 Overriding isActivityPublishingEnabled()

Method Return Type Description Optional/Mandatory Corresponding Declarative Transient Attribute (See Section 14.14.4.3)

isActivityPublishingEnabled()

boolean

By default the base class implementation returns false. This will enable Activity publishing for this Entity Object.

Mandatory

 

getActivityActorsGUIDs()

String []

Can be overridden to provide an Array of GUIDS for the Actors involved with the Activity. By default, the framework will use the GUID of the user currently logged when the Business Event is raised.

Optional

WCActivityActorGuid1, WCActivityActorGuid2

getActivityStreamServiceId()

String

Returns the service id to be used to publish the Activities for the Business Events raised for this Entity. By default this returns null. When null is returned, the service id is defaulted to the full name of the Entity Object.

Optional

WCActivityServiceId

getAdditionalServiceIds()

String []

Override this API to support publishing multiple Activities in response to a single event. So additional Service ids can be passed for a single activity.

Optional

WCAdditionalActivityServiceId1, WCAdditionalActivityServiceId2

getActivityObjectTypeNames()

String

This API can be overridden to return multiple object type names. Value provided should be a "," separated list of object type names associated with a particular Activity.

The first object-type in this String will be used to create the custom attributes needed for primary object. When creating the primary object for a Activity, object-type of the first object listed in service-definition xml should be used even though the custom attrs used to construct this object are fetched from a diff object-type based on getActivityObjectTypeNames() or WCActivityObjectTypeNames. This is necessary for follow model to work. The order of the objects in this array can be used to reference the objects in Activity message format string.

Optional

WCActivityObjectTypeNames


14.14.4.3 Defining Activity Attributes Declaratively

Some of the attributes, such as Actor, Service Ids and Additional Service Ids, can be passed as a part of the payload. The basic process steps are:

  • Define a transient attribute in the Enterprise Object.

  • Give a default value to the transient attribute.

  • Include the transient attribute as a part of the payload.

The different transient attributes that can be passed with the payload are shown in Table 14-9.

Table 14-9 Transient Attributes that Can Be Passed with the Payload

Attribute Type Description Sample Value

WCActivityServiceId

String

This attribute's value is used to identify the Business Object service to be associated with the Activity.

"oracle.apps.crmdemo.model.OpportunityEO"

WCAdditionalActivityServiceId1

String

This attribute's value is used to identify any additional service that needs to be associated with the Activity.

Values are similar to those of WCActivityServiceId

WCAdditionalActivityServiceId2

String

This attribute's value is used to identify any additional service that needs to be associated with the Activity.

Values are similar to those of WCActivityServiceId

WCActivityActorGuid1

String

This attribute's value is used to identify any actor that needs to be associated with the Activity if the default actor value needs to be overridden. For instance, in the message it can be accessed as actor[0]

"<User_GUID>"

WCActivityActorGuid2

String

This attribute's value is used to identify any actor that needs to be associated with the Activity if the default actor value needs to be overridden. For instance, in the message it can be accessed as actor[1]

"<User_GUID>"

WCActivityObjectTypeNames

String

This attribute should provide a "," separated list of object type names associated with a particular Activity. Programmatically getActivityObjectTypeNames() API in the Entity Object's EntityImpl.

The first object-type in this String will be used to create the custom attributes needed for primary object. When creating the primary object for a Activity, object-type of the first object listed in service-definition xml should be used even though the custom attrs used to construct this object are fetched from a diff object-type based on getActivityObjectTypeNames() or WCActivityObjectTypeNames. This is necessary for the follow model to work.

The order of the objects in this array can be used to reference the objects in the Activity message format string.

Emp, Dept


14.14.5 How to Define Activities

Defining Activities requires:

  • Adding the ActivityStream UI Task Flow

  • Defining Activities in service-definition.xml

14.14.5.1 Adding the ActivityStream UI Task Flow

To add the ActivityStream task flow:

  1. Make sure your user interface project includes the WebCenter Activity Streaming Service library in the Libraries and Classpath section in the project properties dialog.

  2. From Resource Catalog > TaskFlows, drag and drop either an "Activity Stream" or "Activity Stream Summary - View" task flow onto the page where you want to display the Activity Stream UI.

  3. Set the taskFlow resourceId parameter to #{securityContext.userName}. This will tie the task flow to the current user at runtime.

  4. For additional details about the Activity Stream task flow, see the "Integrating the People Connections Service" chapter in the Oracle Fusion Middleware Developer's Guide for Oracle WebCenter.

14.14.5.2 Defining Activities in service-definition.xml

The default location of the service-definition.xml file is under META-INF in the project. For Oracle Fusion Applications, this file will be stored in MDS so you need to put it into a directory that can be added to your Metadata Archive (MAR) file.

The standardized location that all applications should use is:

<app>/<lba>/<product>/<*project*>/*meta/oracle/apps/meta*/<lba>/<product>/service-definition.xml

The name must be unique, such as:

helpPortal/atk/helpPortal/model/meta/oracle/apps/meta/atk/helpPortal/service-definition.xml

To define Activities in service-definition.xml, follow these steps.

  1. If necessary, add the directory to the application's MAR profile. To add a MAR, select Application > Application Properties > Deployment. In the dialog that displays, select the MAR file and click Edit.

  2. In the Edit dialog, select User Metadata and click Add. Browse to the meta directory just added and click OK.

  3. Set the id attribute on the service-definition element to the Entity Object name for which you want to define the Activities.

    <service-definition xmlns="http://xmlns.oracle.com/webcenter/framework/service"
                  id="oracle.apps.crmdemo.model.OpportunityEO"
                  version="11.1.1.0.0">
    
  4. Define an activity-type for every business event in the Entity Object for which you want to display the Activities in the Activity Stream UI. Make sure the event name of the Entity Object matches the activity-type name attribute value.

    <activity-types>
      <generic-activity-category name="UPDATE">
        <activity-type name="OpportunityStatusUpdate"
                       displayName="Opportunity Status Update"
                       description="Opportunity Status Update"
                       messageFormatKey="OPPTY_STATUS_UPDATED"
                       iconURL=""
                       defaultPermissionLevel="SHARED"/>
      </generic-activity-category>
    </activity-types>
    
  5. Set message format strings.

    Each activity-type should have a message format defined. The message format string can be translated and is stored in a ResourceBundle or an XLIFF bundle. Oracle Fusion Applications use XLIFF bundles to store the Activity message format strings. The activity-type element in the service-definition.xml file has messageFormatKey attributes that are used to refer to the format strings in the XLIFF bundle.

    Activity Stream supports only Java ResourceBundles. The Common String Repository is used for the message format strings.

    These attributes are supported on the activity-type element:

    • messageFormatKey - Used on Activity Stream full view task flow.

    • summaryByListMessageFormatKey - Used in summary view Activity Stream task flow.

    • summaryByCountMessageFormatKey - Used in summary view task flow.

    messageFormatKey

    The value of this attribute points to the key defined in ResourceBundle. These tokens are supported in the message format string.

    • {actor[0]}: Replaced by the display name of the user who triggered the event.

    • {object[0]}: Replaced by the value of the attribute in the event payload whose attribute name matches the object type name.

    • {custom[attr1].value}: Replaced by the value of the attr1 attribute in the event's payload.

    Sample using Java ResourceBundle:

    <resource-bundle-class>oracle.apps.crm.OpportunityResourceBundle</resource-bundle-class>
     <activity-types>
       <generic-activity-category name="OPPTYUPDATE">
         <activity-type name="OpptyStatusUpdate"
                        displayName="OPPTY_UPDATE"
                        description="OPPTY_UPDATE_DESCRIPTION"
                        messageFormatKey="OPPTY_STATUS_UPDATED"
                        defaultPermissionLevel="SHARED"/>
        </generic-activity-category>
     </activity-types>
    

    In OpportunityResourceBundle, the OPPTY_STATUS_UPDATED key is defined as:

    {"OPPTY_STATUS_UPDATED", "{actor\[0\]} updated {object\[0\]} status to {custom\['status'\].value}"}
    

    summaryByListMessageFormatKey and summaryByCountMessageFormatKey

    These attributes are used only when the Activity Stream summarized view task flow is used. The summarized view task flow is used on the portrait page in My Activities and Network Activities mini cards. In summarized view, the Activity messages are summarized or grouped based on an Activity Type. For instance, if multiple Activities of the same Type are published, they are combined and displayed as a single Activity message. Within the group of Activities of the same type, the following algorithm is used to generate summarized messages:

    1. Summarize activities by finding a common object referenced in the Activity.

    2. Summarize/aggregate the Actors either by listing them if there are 3 or fewer, or by counting them if there more than 3.

    3. For remaining activities, summarize by finding a common Actor. Summarize/aggregate the objects either by listing them if there are 3 or fewer, or by counting them if there are more than 3.

    For example, for the following activities:

    1. James updated Project Alpha tasks.

    2. Viju updated Project Alpha tasks.

    3. Ling updated Project Alpha tasks.

    4. Monty updated Oppty 200 laptops status

    5. Monty updated Oppty solaris workstations status

    6. Monty updated Oppty 2 DB machines status.

    In the summarized view, the Activities are summarized as follows:

    • Activities a-c : James, Viju, Ling updated Project Alpha tasks.

    • Activities d-f: Monty updated 200 laptops, solaris workstations, 2 DB machines opportunities status.

    Example 14-54 shows sample format strings for the above scenario.

    Example 14-54 Sample Format Strings for a Summarized View

    <resource-bundle-class>oracle.apps.crm.OpportunityResourceBundle</resource-bundle-class>
     <activity-types>
       <generic-activity-category name="OPPTYUPDATE">
         <activity-type name="OpptyStatusUpdate"
                   displayName="OPPTY_UPDATE"
                   description="OPPTY_UPDATE_DESCRIPTION"
                   messageFormatKey="OPPTY_STATUS_UPDATED"
                   summaryByListMessageFormatKey="OPPTY_STATUS_UPDATED_SUMMARY_LIST"
                   summaryByCountMessageFormatKey="OPPTY_STATUS_UPDATED_SUMMARY_CNT"
                   defaultPermissionLevel="SHARED"/>
        </generic-activity-category>
     </activity-types>
    

    In OpportunityResourceBundle, the keys are defined as:

    {"OPPTY_STATUS_UPDATED_SUMMARY_LIST", "{actor\[0\]} updated status for opportunity {object\[0\]} }"}
    {"OPPTY_STATUS_UPDATED_SUMMARY_CNT", "{actor\[0\]} updated {object\[0\].count} opportunities status"}
    
  6. Define an object type for the Entity Object that is the source of the events. Even though WebCenter supports multiple object types, for Oracle Fusion Applications, only one object type that corresponds to the source of the events is supported. The value of the name attribute should match the name of the attribute in the Business Event's payload. This attribute's value will be used as the display name of the object when displayed in the Activity message. The primary key of the event source will be used as the object id.

    <object-types>
       <object-type name="OpptyId"
                    displayName="Opportunity Object"
                    description="Opportunity Object"
                    iconURL="">
       </object-type>
    </object-types>
    
  7. ObjectType custom attributes can be used to provide additional metadata for handling business object references in Activity Stream messages. The custom attributes shown in Table 14-10 will be used.

    Table 14-10 ObjectType Custom Attributes

    Name Description

    service-ref-id

    id of the service-definition of a Business Object referenced in the Activity Message of the current Business Object. This is used when an Activity Message contains multiple object references and used to reference serviceId of some other Business Object.

    object-id-attr

    The name of the attribute in the business event payload that should be used as the object-id for an Activity object. Typically this corresponds to the primary key attribute of a Business Object. If this attribute is not specified, the object-type element's name attribute is used as the default.

    display-name-attr

    The name of the attribute in the business event payload that should be used as the display name of the Activity object. This attribute's value will be used to replace the {object} token in the Activity's message format.


    <object-type>
      <custom-attributes>
        <custom-attribute name="service-ref-id" defaultValue="oracle.apps.crm.model.OpptyEO"/>
        <custom-attribute name="object-id-attr" defaultValue="opptyId"/>
        <custom-attribute name="display-name-attr" defaultValue="opptyName"/>
      </custom-attributes>
    </object-type>
    
  8. Define resource view handler parameters to allow custom navigation for links rendered in the Activity message. Navigation from the Actor link in the Activity message navigates to the user's portrait page. Custom navigation to the Business Object workarea is supported. Important fields include:

    • taskFlowId: The task flow where you want to go.

    • resourceParamList: The list of parameters that you want to pass to the task flow. For example, if a Business Object task flow takes the opptyId parameter, in resourceParamList you should specify "opptyId". If multiple parameters are required, the parameters should be separated by a semi-colon (;), for example "opptyId;opptyType". When the hyper link is clicked, parameters opptyId="oppty id value" and opptyType="type value" will be passed as input parameters to the task flow.

      <resource-view taskFlowId="/WEB-INF/OpportunityTF.xml#OpportunityTF">
        <parameters>
          <parameter name="viewId" value="Opportunity"/>
          <parameter name="webApp" value="CRMApp"/>
          <parameter name="pageParametersList" value=""/>
          <parameter name="taskParametersList" value=""/>
          <parameter name="resourceParamList" value="opptyId"/>
        </parameters>
      </resource-view>
      

      Custom navigation is handled by the Applications Core ResourceViewHandler registered in adf-config.xml. You must add this entry to all adf-config.xml files:

      <wpsC:adf-service-config xmlns:wpsC="http://xmlns.oracle.com/webcenter/framework/service">
          <resource-handler class="oracle.apps.fnd.applcore.tags.handler.FndResourceActionViewHandler"/>
      </wpsC:adf-service-config>
      

14.14.6 How to Implement Comments and Likes

Commenting allows users to comment on objects that are created or published by various users on the site, and engage in discussions revolving around those objects via replies to comments and comments upon comments. This feature in Activity Stream allows users to comment on specific Activity related to a object.

The Likes feature allows users to express their liking for any object in the system to which they have access. This feature is exposed in message board, activity stream, doclib and replies on topics discussion forum. In ActivityStream, this feature allows users to indicate if they like a particular Activity.

To enable Comments and Likes for a service, add these ActivityTypes to the service-definition xml:

<activity-type name="postComment"
               messageFormatKey="ACTIVITY_COMMENT_STATUS"/>
<activity-type name="expressLike"
               messageFormatKey="ACTIVITY_LIKE_STATUS"/>

Make sure the activity-type names are as shown. The messageFormatKey values refer to the ResourceBundle keys that provide strings displayed for "comments" and "likes" links displayed in the ActivityMessage.

14.14.7 How to Implement Follow for an Object

Users will be able to see ActivityMessages belonging to the Business Objects they are following. Users should either explicitly follow a business Object, or product teams should provide a way for users to follow certain Business Objects implicitly. A Business Object can be followed for a user by using the WebCenter Follow API. A sample implementation of Follow is shown in Example 14-55.

Example 14-55 Sample Implementation of the Follow Model

public void follow() {
   System.out.println("Follow method invoked!!!");
   try
   {
   OAViewObjectImpl vo = getCaseList1();
   Row row = vo.getCurrentRow();
   Object id = row.getAttribute("Id");
   System.out.println("Case Id in follow : " + id);
 
   ActivityStreamingService asService = ActivityStreamingServiceFactory
     .getInstance().getActivityStreamingService();
   FollowManager followManager = asService.getFollowManager();
   String serviceID = "oracle.apps.fnd.applcore.crmdemo.model.business.CasesEO";
   String userGUID = ApplSessionUtil.getSession().getUserGuid();
   ActivityActor actor = asService.createActor(userGUID);
   String objectTypeName = "Id";
   ServiceObjectType objectType = asService.findObjectType(serviceID, objectTypeName);
   ActivityObject followedObject = asService.createObject(id.toString(),
                                    objectType, "");
   System.out.println("Calling Follow for Case : " + id);
 
   followedObject.setServiceID(serviceID);
   followManager.followObject(actor, followedObject);
   }
   catch(ActivityException ae) {
     ae.printStackTrace();
     System.out.println("Case follow failed");
   }
}

14.14.7.1 Defining the Service Category

The Follow model is enforced for Activity Messages when the category-id of a service contains "business" in its name. A sample service-category-definition and its reference in service-definition are provided in Example 14-56 and Example 14-57.

Note that the id in the service-category-definition file matches the category-id in service-definition.xml and it contains "business".

Example 14-56 Sample service-category-definition.xml

<service-category-definition xmlns="http://xmlns.oracle.com/webcenter">
 <category id="oracle.apps.fnd.applcore.crmdemo.model.business.CasesEO"
           resourceBundle="oracle.apps.fnd.applcore.crmdemo.BusinessActivityServiceResourceBundle"
           titleKey="CASE_SERVICE_CATEGORY"
           icon="/a/s/g.gif"/>
</service-category-definition>

Example 14-57 Sample service-category-definition Reference

<category-id>oracle.apps.fnd.applcore.crmdemo.model.business.CasesEO</category-id>

14.14.7.2 Adding ActivityTypes for Follow and Unfollow

The ActivityTypes shown in Example 14-58 should be added to the service-definitions of all services that use the Follow model. These ActivityTypes are used to construct the message published when an object belonging to the service is Followed or Unfollowed.

Example 14-58 Adding ActivityTypes for Follow and Unfollow

<activity-type name="followObject"
   displayName="Follow Object"
   messageFormatKey="ACTIVITY_FOLLOW_OBJECT_MSG"
   description="Follow Object">
</activity-type>
 
<activity-type name="unfollowObject"
   displayName="Unfollow Object"
   messageFormatKey="ACTIVITY_UNFOLLOW_OBJECT_MSG"
   description="Unfollow Object">
</activity-type>

14.14.8 How to Render Contextual Actions in Activity Streams

Contextual Actions are rendered for Business Objects or other resources referenced in ActivityStream messages when contextInfoPopupId is configured in the service-definition.xml file of the Business Object or resource. ActivityStream launches an ADF popup using the popup id from the service-definition.xml file. The contextInfoPopupId should provide the absolute id of the popup used for the Contextual Action. A popup with the specified id should exist in the pages where ActivityStream is used. This is already a requirement for all pages where Contextual Actions-enabled objects are rendered. Activity Stream will make the serviceId, resourceId, and resourceType properties available to the launched pop-up. The pop-up should process these parameters and convert them to Contextual Actions-specific parameters and make them available to the Contextual Actions task flow or another component.

This element, which is the direct child of service-definition element, is used to configure the Contextual Actions popup id in service-definition.xml.

<contextInfoPopupId>:pt1:r1:casePopup</contextInfoPopupId>

The popup sample shown in Example 14-59 uses the serviceId, resourceId, and resourceType properties from ActivityStream that are made available through the launch variable, and makes them available to the popup.

Example 14-59 Sample Popup for ActivityStream

<af:popup id="casePopup" contentDelivery="lazyUncached"
    eventContext="launcher" launcherVar="source"
    clientComponent="true">
  <af:noteWindow id="nw" >
  <af:panelFormLayout id="pflTst">
  <af:inputText id="itSID"
    label="Service ID"
    value="#{pageFlowScope.serviceId}"
    readOnly="true"/>
  <af:inputText id="itRID"
    label="Resource ID"
    value="#{pageFlowScope.resourceId}"
    readOnly="true"/>
  <af:inputText id="itRType"
    label="Resource Type"
    value="#{pageFlowScope.resourceType}"
    readOnly="true"/>
 </af:panelFormLayout>
</af:noteWindow>
<af:setPropertyListener from="#{source.attributes.serviceId}"
                         to="#{pageFlowScope.serviceId}"
                         type="popupFetch"/>
<af:setPropertyListener from="#{source.attributes.resourceId}"
                         to="#{pageFlowScope.resourceId}"
                         type="popupFetch"/>
<af:setPropertyListener from="#{source.attributes.resourceType}"
                        to="#{pageFlowScope.resourceType}"
                        type="popupFetch"/>
</af:popup>

14.15 Implementing the Oracle Fusion Applications Search Results UI

The Oracle Fusion Applications Search Results UI provides a front-end, launched from a page using the UI Shell template, that is used to query the Oracle Enterprise Crawl and Search Framework (ECSF).

The minimum requirement is to implement and run a UI Shell Template page. A page using the UI Shell template will automatically contain the search components in the Global Area and can be activated when running the page.

Where you have implemented ECSF for your product, you will need to make sure that you have followed all of the instructions in Chapter 2, "Setting Up Your Development Environment," Chapter 26, "Getting Started with Oracle Enterprise Crawl and Search Framework," and Chapter 27, "Creating Searchable Objects" and in particular:

If you have implemented ECSF and defined the SearchDB connection, the saved searches go to the Oracle database and are persisted across sessions.

Data Security Integration

Data security, that is, limiting search results to only those items to which the user has authorized access, is handled by the ECSF.

14.15.1 How to Disable Oracle Fusion Applications Search

There are occasions when you will want to disable Oracle Fusion Applications Search for an application, such as for public (unauthenticated) pages. There are four ways to disable the function:

  • Remove the ECSF libraries (oracle.ecsf shared lib). Oracle Fusion Applications Search will detect the missing dependency and disable itself for all pages in the current user session, even if the user navigates to a web application that does have the ECSF libraries available.

  • Setup switch via JVM system property.

    -DFUSION_APPS_SEARCH_ENGINE_AVAILABLE=N
    
  • Use Customization by setting rendered to false on the panelGroupLayout with id "_UISpg6" (the panel containing the Oracle Fusion Applications Search fields) in the UI Shell main area. Note that by customizing the fields out of the current page, you are not disabling search; the Expression Language bindings on the fields are still evaluated and if the user navigates to a non-customized page, Oracle Fusion Applications Search will be available.

  • Setting profile option Fusion Apps Search Enabled to 'N', either at Site or User level.

14.15.2 How to Use Basic Search

From the main page of the project in the global area, the Categories and Search terms fields can be seen, as shown in Figure 14-50.

Figure 14-50 Basic Search Fields in UI Shell

Basic Search Fields in UI Shell

If you expand the Categories field, a list, similar to that shown in Figure 14-51, displays:

Figure 14-51 Search Categories Field Expanded

Search Categories field expanded

Categories

The end-user can select from the list of Categories and enter a search string. Unchecking the All category unchecks all of the categories. The subset of selected categories will be displayed in the entry area of the drop list as a concatenated list separated by a semi-colon (;).

Note:

Categories are not set up at design time by developers. They should be set up either by customers or seeded by teams. Categories are created and stored in ECSF schema, and ECSF provides an API to get a list of categories to the UI for a given user.

Search Term

This is a text field for the values on which to search. The field defaults to showing 20 characters, and can hold a maximum of 2048 characters.

The term is searched in any of the crawled data, which includes the title, fixed and variable content, attached documents, and tags. So if the search term was foo, the search returns any data containing the word foo.

To find only items with the tag foo, enter ecsf_tags:foo as the search word. No data will be returned if the word foo is in the transactional data but not in the tag.

Click the Play button to initiate the search.

Saved Searches

Click the icon to open a list of saved searches. The list, shown in Figure 14-52, includes a Personalize… action item that will display the Personalize Saved Searches dialog so that saved searches can be deleted or renamed.

Figure 14-52 Saved Searches List

Saved Searches list
  • Show Results of Last Search: Displays the output of the last search.

  • Personalize: This becomes active if there is a saved search. Click this link to rename or delete a saved search, as shown in Figure 14-53.

    Figure 14-53 Personalized Saved Searches Dialog

    Personalize Saved Searches dialog

    To rename a saved search, select it, enter a new name in the Name field, and click OK.

    To delete a saved search, select it and click Delete.

14.15.2.1 Search Results

After clicking Search, a modal dialog will display the results of the search. Hovering over the main link will show the last crawled date. Figure 14-54 shows typical results.

Note:

If a search application, such as Finance or HCM, is down and does not respond to the search request within a pre-determined period of time, the search results will display but there will be a notice that one or more applications did not respond.

Figure 14-54 Search Results Example

Search results example

To improve performance, the result set size is limited to 10.

The Search Results display consists of:

  • A repetition of the fields displayed in the global area.

  • A Filter Tree of Categories: Selected filter values will be applied to the search results. A remove filter icon will appear next to a filter value that has been added. Clicking this icon will remove the filter from the search criteria.

    A category is a group of related objects. Examples include any Oracle Fusion business object, and WebCenter objects such as wikis and blogs.

    Searchable Object is the second level. A searchable object is the view object.

    Facets are formed by the Lists of Values defined on an attribute in the Searchable Object. There may be many facets for a Searchable Object, and the facets may be hierarchical, such as is the case in Figure 14-54, where a State facet contains a City facet, which contains a County facet. Only the name of the highest level facet in the hierarchy is shown.

  • A Results section. On the initial query, all selected Categories will be displayed. Only the first category will be displayed expanded. The other Categories will need to be manually expanded.

    Each result found under a category provides a navigation link back to the record.

Result Counts Do Not Add Up

It is possible when viewing the search results, and narrowing your selections using the facet tree, to see counts against the nodes that do not add up. For example, a search on Glasses might return 16. Then if you filter the result by color, you may find Blue (5) and Red (10), which do not add up to 16. This count is the Oracle Secure Enterprise Search (SES) Approximate count based on heuristics, and not an exact count. To make the count exact, launch SES and select Global Settings > Query Configuration, and click the Exact count radio button, as shown in Figure 14-55. Note that SES warns against this for performance reasons. See the Oracle Secure Enterprise Search Administration Online Help.

Figure 14-55 Setting the Exact Hit Count in SES

Setting Exact Hit Count in SES

14.15.3 How to Implement the GlobalSearchUtil API

A public API is available to call Oracle Fusion Applications Search without requiring the user to use the global search fields at the top of the UI Shell page template.

You can use this API within your UI, such as in a main area task flow, and bring up the same UI. You must use the UI Shell.

This API, shown in Example 14-60, is available from the oracle.apps.fnd.applcore.globalSearch.ui package in the jdev/oaext/adflib/UIComponents-Viewcontroller.jar and is the only public API supported by Oracle Fusion Applications Search.

Example 14-60 Oracle Fusion Applications Search API

/**
 * Run a search from a backing bean and have the search results ui component
 * display.
 * @param searchCategories A list of SearchCategory objects to search within.
 * Can be obtained by calling getCategories() from this class.
 * @param searchString The string to search on
 * @param callerContext a String which represents to the caller, the context
 * in which the search result will be called.  This primarily relates to saved
 * searches, which will be saved with this context, and only saved searches
 * with this context shown to the user.
 * @param e The ActionEvent from the page UIComponent that triggered this
 * functionality.
*/
public static void runSearch(List<SearchCategory> searchCategories,
                             String searchString,
                             String callerContext,
                             ActionEvent e)
/**
 * Run a search from a backing bean and have the search results ui component
 * display at a set size.
 * @param searchCategories A list of SearchCategory objects to search within.
 * Can be obtained by calling getCategories() from this class.
 * @param searchString The string to search on
 * @param callerContext a String which represents to the caller, the context
 * in which the search result will be called.  This primarily relates to saved
 * searches, which will be saved with this context, and only saved searches
 * with this context shown to the user.
 * @param e The ActionEvent from the page UIComponent that triggered this
 * functionality.
 * @param popupDimension A Dimension object containing the height and width
 * to display the search results popup.
*/
  public static void runSearch(List<SearchCategory> searchCategories,
                               String searchString,
                               String callerContext,
                               ActionEvent e,
                               Dimension popupDimension)
/**
 * Get a list of all the SearchCategory objects.
 * @return  A List of SearchCategory objects containing all possible search
 * categories.
*/
  public static List<SearchCategory> getCategories();

14.15.3.1 Using the Search API

Create the component and have an actionListener to a backing bean, as shown in Example 14-61. Note that GlobalSearchUtilBean is just an example, not a real bean.

Example 14-61 Creating a Component with actionlistener to Backing Bean

<af:commandButton text="commandButton 1"
          actionListener="#{backingBeanScope.GlobalSearchUtilBean.runSearch}">
</af:commandButton>

From that backing bean, you can call the Oracle Fusion Applications Search API to run the search, as shown in Example 14-62.

Example 14-62 Calling Oracle Fusion Applications Search API to Run Search

public class GlobalSearchUtilBean {
    public GlobalSearchUtilBean()
    {
    }
    public void runSearch(ActionEvent actionEvent)
    {
      List<SearchCategory> categories =GlobalSearchUtil.getCategories();
      // manipulate search category list here
      String searchString = "some search string";
      GlobalSearchUtil.runSearch(categories, searchString, actionEvent);
    }
}

14.15.3.2 Running the Oracle Fusion Applications Search UI Under WebLogic Server

For details of running the ECSF artifacts, such as the SearchFeedServlet, see Chapter 27, "Creating Searchable Objects."

To run the UI Shell and Oracle Fusion Applications Search, follow the setup instructions for running Applications Core under WebLogic Server in Chapter 2, "Setting Up Your Development Environment" and the instructions on how to set up a UI Shell page, menu entries and task flows from Section 14.1, "Introduction to Implementing the UI Shell". This should give you a running UI Shell project.

Add the SearchDB database connection to the project. For more information about creating the SearchDB connection, see Section 31.5.1, "How to Create the SearchDB Connection on Oracle WebLogic Server Instance".

14.15.4 Introduction to the Crawled Objects Project

The Crawled Objects Project lets you crawl your Search view objects in WebLogic Server, and set up Oracle Fusion Applications Search to use those crawled view objects.

The business component objects you will create (specifically the Searchable view object) will contain references to the Oracle Fusion Middleware Extensions for Applications base classes.

Update the ECSF command line script (runCmdLinScript.sh) to reference the JAR files containing the base classes. Example 14-63 shows the UNIX version; the DOS version will be similar.

Example 14-63 Updating ECSF Command Line Script to Reference Applications Core JAR Files

export APPLCORE_CP=${ORACLE_HOME}/jdeveloper/jdev/oaext/adflib/Common-Model.jar:${ORACLE_HOME}/jdeveloper/jdev/oaext/adflib/Tags-Model.jar
export ADMIN_CLASS=oracle.ecsf.cmdlineadmin.CmdLineAdmin
 
${JAVA_HOME}/java -cp ${ADMIN_CP}:${APPLCORE_CP} ${ADMIN_CLASS} ${CONNECT_INFO}

14.15.5 How to Implement Tags in Oracle Fusion Applications Search

A view object is available to reference Oracle WebCenter Tags. This view object is available in ORACLE_HOME/jdeveloper/jdev/oaext/adflib/Tags-Model.jar library jar.

You may use this view object using a view-link and a pre-defined Search Plugin to enable the crawling of Oracle WebCenter Tags, both in initial and incremental (someone has updated the tags) crawls.

Steps:

  1. Create your Searchable view object as normal. Example 14-64 uses a Searchable view object over FND_LOOKUPS_VL in the query.

    Example 14-64 Creating a Searchable View Object

    SELECT LOOKUP_TYPE,
           VIEW_APPLICATION_ID,
           LANGUAGE,
           SOURCE_LANG,
           MEANING,
           DESCRIPTION,
           CREATED_BY,
           CREATION_DATE,
           LAST_UPDATED_BY,
           LAST_UPDATE_DATE,
           LAST_UPDATE_LOGIN,
           'oracle.apps.fnd.applcore.lookuptype' AS SERVICE_ID,
           lookup_type||'.'||to_char(view_application_id)||'.'||language||'.'||meaning as RESOURCE_ID
    FROM FND_LOOKUP_TYPES_TL
    

    The SERVICE_ID specifically identifies your Searchable view object.

    The RESOURCE_ID identifies the specific row for the SERVICE_ID. It is essentially a dot-separated primary key of the entity.

    These two values will be used when setting up tags in your regular UI and will need to match.

    For example, if you have a page with a form and tag button, the Web Center tag would be set up as shown in Example 14-65.

    Example 14-65 Setting up the WebCenter Tag

    <af:panelFormLayout id="pfl1">
       <tag:taggingButton serviceId="oracle.apps.fnd.applcore.lookuptype"
                   resourceName="#{bindings.Description.inputValue}"
                   resourceId="#{bindings.LookupType.inputValue}.#{bindings.ViewApplicationId.inputValue}.#{bindings.Language.inputValue}.#{bindings.Meaning.inputValue}"/>
       <af:region value="#{bindings.tagginglaunchdialog1.regionModel}"
                           id="r1"/>
       <af:panelLabelAndMessage label="#{bindings.LookupType.hints.label}"
                                       id="plam4">
         <af:outputText value="#{bindings.LookupType.inputValue}" id="ot9"/>
    </af:panelLabelAndMessage>
    

    See Section 14.10, "Implementing Tagging Integration" for setting up Tags in your UI. Figure 14-56 shows the attributes for lookup types.

    Note:

    Do not forget to mark your key columns and make sure the order is consistent between the view object and the tag:taggingButton.resourceId attribute.

    Figure 14-56 Tags - Searchable View Object Lookup Types

    Tags - SVO Lookup types

    Figure 14-57 shows the attributes for Searchable view object lookup types.

    Figure 14-57 Tags - Lookup Types

    Tags - Lookup types.
  2. Add a view link to the TagSVO (Service view object) linking the Search view object and Applications Core Tag view object.

    The view link should look similar to Figure 14-58.

    Figure 14-58 View Link Example

    View link example
  3. Update the Body field to include the Tags of the child view object in the relevant position in the String as defined by your product management.

    This will be an expression of the form <accessor Name>.Tag, such as tagSVO.Tag.

How to Do an Incremental Crawl

To do an incremental crawl:

  1. Update the Searchable View Object Search Plugin field (see Figure 14-58, "View Link Example") to "oracle.apps.fnd.applcore.search.TagSearchPlugin", or as shown in Example 14-66, create a subclass so that you can incorporate your security rules.

    Example 14-66 Creating a Subclass

    package oracle.apps.fnd;
    import oracle.apps.fnd.applcore.search.TagSearchPlugin;
    public class WlsTestTagSearchPlugin
    extends TagSearchPlugin
    {
      // All implementation through super class, or overide methods important to you.
      // Be careful if implementing
      //  public Iterator getChangeList(SearchContext ctx, String changeType)
      // to call super(ctx, changeType) to get the applcore functionality.
    }
    

    Make sure you add a parameter passing the service Id of the Search view object. This may be done by clicking the LOV symbol next to the Search Plugin Field. See Figure 14-59.

    Figure 14-59 Search Plugin

    Search Plugin example

    There are two parameters, shown in Table 14-11, that may be passed to the plugin.

    Table 14-11 Parameters that can be passed to the plug-in

    Parameter Required Description

    TAG_SERVICE_ID

    Yes

    Service Id of the Searchable view object. This value must match the value in the tag:taggingButton component and the service_id of the Searchable view object query.

    KEY_SPLITTER_CLASS

    No

    An optional class that extends oracle.apps.fnd.applcore.search.BaseKeySplitter.

    This is a strategy class for splitting the resourceId value into individual primary key attribute values. By default, oracle.apps.fnd.applcore.search.DefaultKeySplitter is used which will split values based on a period separator (the applications standard). The separated PS attribute values are matched to the PK columns in the order the primary key columns are defined in the view object flat table editor.

    For more flexible arrangements, teams can implement any scheme they want (such as name-value pairs) by creating their own key splitter class and setting this parameter.


  2. Start the SearchFeedServlet in the user interface project.

You now can crawl using the command line script. A full crawl will be done first, then on subsequent crawls the incremental functionality will call the getChangeList() method.

14.15.6 How to Use the Actionable Results API with Oracle Fusion Applications Search

This section details how to set up ECSF searchable objects to use with Oracle Fusion Applications Search. For information about setting up your global search infrastructure, see Chapter 26, "Getting Started with Oracle Enterprise Crawl and Search Framework."

Figure 14-60 shows the result that will be produced (a single row in the search results table).

Figure 14-60 Search Results Example

Search results example

The terminology referred to in this result is:

  • Flat Table URL Action is the Action Link.

  • Title for Flat Table 1:Col1619:Col2619 is the Fixed Content.

  • Any other required information would be added later is the Variable Content.

  • Task Action 1 is Other Actions.

As shown in Figure 14-61, ECSF searchable objects support two distinct Action Types: URL and Task. See also Figure 14-62 and Figure 14-63.

Most Oracle Fusion Applications will use the Task type with specific named parameters to integrate with the UI Shell; however both types will work.

Figure 14-61 Search Properties Example

Search properties example

Fixed Content

The Fixed Content is derived from the Search Properties Title field.

Variable Content

The Variable Content is derived from the Search Properties Body field.

14.15.6.1 Implementing the URL Action Type

Figure 14-62 shows a URL Action.

Figure 14-62 Search Result Actions - URL Action

Search Result Actions - URL Action

For URL Action Types, the Oracle Fusion Applications Search will open a new browser tab or window containing the URL. To configure this type, add a URL Search Result Action with these parameters.

  • A unique name

  • Action Type of URL

  • An Action Target to the required destination, including groovy substitution parameters

  • A Title

No Parameters are required; however a single iconURL parameter may be defined if an icon is required for the URL action. See Table 14-12.

Table 14-12 iconURL Parameter

Name Required Description

iconURL

No

URL of icon to show next to the Action. Can be a relative reference such as /media/search/mime_doc.gif or a full URL such as http://host:port/path/to/icon.gif.


This will be shown in the search results with the title given in the Title field. When clicked, a new browser tab or window will open with this URL.

14.15.6.2 Implementing the Task Action Type

Figure 14-63 shows a Task Action.

Figure 14-63 Search Result Actions - Task Action

Search Result Actions - Task Action

For Action Types of Task, the Oracle Fusion Applications Search will open a UI Shell tab in the current page, or a new page containing the task flow. To configure this type, add a Task Search Result Action with these parameters.

  • A unique name

  • Action Type of Task

  • A Title

  • Parameters are shown in Table 14-13. Note that, although this table resembles Table 14-14, it presents the use case that the majority of users will use. The information in Table 14-14 is for a very small use case.

    This will be shown in the search results with the title given in the Title field. When clicked, a new UI Shell tab window will open with this task flow. If the viewId parameter is for the current page, the UI Shell tab will be in the current page; otherwise the current page will be replaced with a new UI Shell page with the search result.

    Note:

    Do not enter double quotes around the groovy expressions; use single quotes instead.

    Table 14-13 Task Action Type Parameters

    Name Required Description

    viewId

    Y

    Name of the page. This is shown in the browser URL bar. For example, in http://127.0.0.1:8989/context-root/faces/TestUIShellPage, it would be "/TestUIShellPage" (Note the leading slash).

    pageParametersList

    N

    Parameters list for the page. This is a semicolon delimited String of name value pairs. For example, "param1=value1;param2=value2"

    taskFile

    Y

    Name of the task definition file. For example, /WEB-INF/task-flow-definition.xml. See Section 14.15.6.3, "Passing Parameters in Oracle Fusion Applications Search".

    taskName

    Y

    The task flow definition id. Available from the task definition file <task-flow-definition> id attribute. For example, <task-flow-definition id='task-flow-definition'> would be "task-flow-definition". See Section 14.15.6.3, "Passing Parameters in Oracle Fusion Applications Search".

    navTaskKeyList

    N

    Key list to pass into the task flow to open in the target workspace. This is a semicolon delimited keys or key-value pairs. For example "key1;key2=value2"

    navTaskParametersList

    N

    Parameters list to pass in to the task flow to open in the target workspace. This is a semicolon delimited String of name value pairs. For example "param1=value1;param2=value2"

    iconURL

    N

    URL of icon to show next to the Action. Can be a relative reference such as '/media/search/mime_doc.gif' or a full URL such as 'http://host:port/path/to/icon.gif'

    toolTip

    N

    Tooltip of action. This also is available for URL actions.

    navTaskLabel

    N

    Label to show on the results tab. (Set the tab title of the tab that is opened after clicking a search result action.) If unset, it will use the Action Name (the value shown in the results).

    webApp

    Y

    The webApp attribute is used to look up the host and port of the associated WorkArea or Dashboard from the ASK deployment tables. These tables are populated at deployment time through Functional Setup tasks.


Caution:

If you have a searchable view object with a task search action, the parameters passed to the task flow from FndUIShellController.navigate(...) will be Strings, not the native type of the view object attributes. You must ensure these values are converted from their native type to a String (in the navTaskParametersList) and back correctly (in your task flow).

For Integer types, this is largely automatic (as long as you reference the parameter as a String in the task flow), but for dates and decimals, care should be taken.

14.15.6.2.1 How to Implement Preferred Navigation

Fusion Applications Search supports two parameters, applicationStripe and pageDefinitionName, in task search actions that, if they are present, change the definition of the other task action parameters used for navigation. These parameters all become "caret delimited." That is, instead of having one value per parameter, they have multiple, and they are delimited by the caret "^" character. In this case, all parameters must have the same number of delimited parts.

This additional configuration allows the developer to set up different navigation targets for the same action. The actual target followed will be determined when the user clicks the result and will be based on a permissions check based on the applicationStripe and pageDefinitionName parameters. If these two parameters are not supplied, the other parameters will be used "as is," and navigation will be performed based on their values.

If the applicationStripe and pageDefinitionName parameter values are supplied, the algorithm used is the same as for tagging.

  • Divide all delimited parameters based on caret, and produce an ordered list of navigation targets,

  • If there is only one target defined, use it with no permission check.

  • For each target, determine if the user can navigate to the page and task flow.

  • If a navigable target is in the current view, use it.

  • Take the first navigable target.

Whatever the outcome of the permissions check, the developer must ensure that at least one target is navigable, otherwise users will be presented with a blank page when they click the search result.

The parameters and descriptions for Preferred Navigation are shown in Table 14-14. Note that, although this table resembles Table 14-13, it presents a more complicated use case in which teams want to do a security check, and navigate the user to the most secure endpoint (the first allowed one in the list). The meaning of these columns changes with the caret delimitation; that is, a caret-delimited list of the old values, as well as two new parameters. Most users only need to use the information in Table 14-13.

Table 14-14 Parameters for Preferred Navigation

Name Required Delimited by caret "^" Description

applicationStripe

N

Y

(This attribute is used for pages.) Check security of the page against the policies that are located in LDAP. The applicationStripe name must be the same as the stripe name of the LDAP policy store, which is the same as the web.xml application.name attribute. If this parameter is supplied, the pageDefinitionName parameter must be supplied also. Example: crm^hcm

pageDefinitionName

N

Y

A delimited String of page definition names. If this parameter is supplied, the applicationStripe parameter must be supplied also. Example: oracle.apps.view.pageDefs.Test1PageDef^oracle.apps.view.pageDefs.AnotherPageDef

viewId

Y

Y

Name of the page for the pillar. This is shown in the browser URL bar. For example, in http://127.0.0.1:8989/context-root/faces/TestUIShellPage, it would be "TestUIShellPage^AnotherUIShellPage".

webApp

Y

Y

The webApp attribute is used to look up the host and port of the associated WorkArea or Dashboard from the ASK deployment tables. These tables are populated at deployment time through Functional Setup tasks.

pageParametersList

N

Y

Parameters list for the page. This is a semicolon delimited String of name value pairs. For example, "param1=value1;param2=value2^anotherParam1=value1;anotherParam2=value2"

taskFile

Y

Y

Name of the task definition file. For example, "/WEB-INF/task-flow-definition.xml^/WEB-INF/anothertask-flow-definition.xml". See Section 14.15.6.3, "Passing Parameters in Oracle Fusion Applications Search".

taskName

Y

Y

The task flow definition id. Available from the task definition file <task-flow-definition> id attribute. For example, <task-flow-definition id='task-flow-definition'> would be "task-flow-definition^another-task-flow-definition". See See Section 14.15.6.3, "Passing Parameters in Oracle Fusion Applications Search".

navTaskKeyList

N

Y

Key list to pass into the task flow to open in the target workspace. This is a semicolon delimited keys or key-value pairs. For example "key1;key2=value2^anotherKey1;anotherKey2=value2"

navTaskParametersList

N

Y

Parameters list to pass in to the task flow to open in the target workspace. This is a semicolon delimited String of name value pairs. For example "param1=value1;param2=value2^anotherParam1=value1;anotherParam2=value2"

navTaskLabel

N

Y

Label to show on the results tab. (Set the tab title of the tab that is opened after clicking a search result action.) If unset, it will use the Action Name (the value shown in the results). For example: "Manage user^View User" (Note: This will be shown on the UI, so use resource bundles.)

iconURL

N

N

URL of the icon to show next to the Action. Can be a relative reference, such as '/media/search/mime_doc.gif' or a full URL, such as 'http://host:port/path/to/icon.gif'.

Tooltip

N

N

Tooltip of action. This also is available for URL actions.


14.15.6.3 Passing Parameters in Oracle Fusion Applications Search

Normally, taskFlowID uses the format <path><name>.xml#<name>; for instance taskFlowID="/WEB-INF/CaseDetails.xml#CaseDetails". However, Oracle Fusion Applications Search has taskFile and taskName attributes as shown in Figure 14-63. The Oracle Fusion Applications Search code will merge them, adding the "#," so they become <taskFile>#<taskName>.

Parameters are always passed as Parameter Name=value. Often, it is either a literal value or an expression such as #{pageFlowScope.val}. Example 14-67 shows how it is done, passing four parameters.

Example 14-67 Parameter Passing in Oracle Fusion Applications Search

<SearchResultActions>
  <Action
    Name="View Lookup Type"
    ActionType="Task"
    DefaultAction="true">
    <Title>
      <![CDATA["Lookup: " + Meaning]]>
    </Title>
    <ActionTarget>
      <![CDATA[null]]>
    </ActionTarget>
    <Parameters>
      <Parameter Name="navTaskParametersList">
        <Value>
          <![CDATA["lookupType=" + LookupType + ";viewApplicationId=" + ViewApplicationId + ";language=US;meaning=" + Meaning]]>
        </Value>
      </Parameter>
      <Parameter Name="webApp">
        <Value>
          <![CDATA['GlobalSearch']]>
        </Value>
      </Parameter>
      <Parameter Name="TaskFile">
        <Value>
          <![CDATA["/WEB-INF/LookupTypeSearchResultsTaskFlow.xml"]]>
        </Value>
      </Parameter>
      <Parameter Name="navTaskKeyList">
        <Value>
          <![CDATA["meaning=" + Meaning]]>
        </Value>
      </Parameter>
      <Parameter Name="TaskName">
        <Value>
          <![CDATA["LookupTypeSearchResultsTaskFlow"]]>
        </Value>
      </Parameter>
      <Parameter Name="viewId">
        <Value>
          <![CDATA["TestUIShellPage"]]>
        </Value>
      </Parameter>
    </Parameters>
  </Action>

14.15.6.4 Ordering the Other Actions

In the ECSF search UI in JDeveloper, it is possible to define no action, or a single default action.

If a default action is defined, it will be used. The other actions will be shown in sorted order based on task title. If no default action is defined, the first sorted action will be used as the default action.

This sorting mechanism is used as there is no way, using the current ECSF APIs, to provide a stable order of actions.

Due to this sorting mechanism, it is strongly recommended to have stable, sortable task titles (they may be groovy bound and therefore mutate based on an individual search result) to prevent confusing the end user.

14.15.6.5 Using Click Path and the Saved Search

When the user is using Oracle Fusion Applications Search prior to saving a search, he or she may perform a number of interactions with the UI including:

  • Expanding the attribute filters by selection (performs searches)

  • Narrowing the search terms

  • Opening unsearched groups (which performs searches in those groups)

  • Scrolling through results in a group

This is called the click path of the user.

When a search is saved, some of this information (the structural part at the tip of the click path) is saved, but prior actions and exact scroll positions are not. This means that when running a saved search, the following is not restored to the user:

  • Exact expanded groups in the result at the time of save

  • Scroll positions within a group

  • Full LOV expansion state of attribute filters

When ECSF returns facet information, it returns only facet entries for the level below that which is selected. For example, if there are no filters, the facets will be shown correctly with one level of detail. If a first level facet is selected, that selection will be shown, but not its siblings. If there are facets below that level, this next level will be shown as these are returned. As the user starts to refine/expand the attribute filters, the search filters will be filled-in based on this new click path.

14.15.7 How to Integrate Non-Applications Data into Oracle Fusion Applications Search

Oracle Fusion Applications Search can also be used with non-standard ECSF searchable view objects.

14.15.7.1 Oracle Business Intelligence Integration

Oracle Business Intelligence results will be shown in a results area separate from Oracle Fusion Applications Search view object results. To implement this separation, Oracle Fusion Applications Search shows results in a multi-tab format.

The tabs are named Applications, where all Search view objects and Oracle WebCenter results will reside, and Business Intelligence. The split is performed at a category (or searchable groups) level, so you will see a consolidated list of categories in the multi-select category dropdown. These categories are split at search time.

The business rule that splits categories into the Oracle Business Intelligence table is lower-case category_name, such as bi_%.

Although the formatting of Oracle Business Intelligence results will be slightly different, no developer uptake is required.

Oracle Secure Enterprise Search (SES) Setup

  • Source

    See the Oracle Fusion Middleware Developer's Guide for Oracle Business Intelligence Enterprise Edition for how to create your Oracle Business Intelligence source. Define a source based on the Oracle EBusiness Suite R12, and give the following parameters:

    SES Source Configuration:
    Configuration URL: http://10.156.30.40:9704/bisearch/crawler/oracle.biee.search.BISearchableTreeObject/ConfigFeed?forceInitialCrawl=true
    User ID: Administrator
    Password: Admin123
     
    Authorization Tab:
    HTTP endpoint for authorization: http://10.156.30.40:9704/bisearch/crawler/SecurityService
    User ID: Administrator
    Password: Admin123
    Business Component: oracle.biee.search.BISearchableTreeObject
    Display URL Prefix: http://10.156.30.40:9704/bisearch/urlbuilder
     
    where the IP address is your Oracle Business Intelligence server installation, and the username/password are for a sufficiently authorized Oracle Business Intelligence user.
     
    Leave all other values at default.
    
  • Source Group

    Create a source group (SES Searchtab > Source groups) and name it bi_<some code name>.

    It must start with bi_ so Oracle Fusion Applications Search can recognize it as an Oracle Business Intelligence category.

    You may go into Global Settings and translate the group name so the users see a more friendly name.

    Import the group as an external category into ECSF. See "Importing Source Group into ECSF".

  • Searching

    When Searching, the Oracle Business Intelligence results will display in a separate tab, as shown in Figure 14-64.

    Figure 14-64 Oracle Business Intelligence Search Results in New Tab

    BI Search Results in New Tab

    If there are only Oracle Business Intelligence, or only Oracle Fusion Applications/Oracle WebCenter categories selected, only the one tab appropriate to those categories displays. Otherwise, you can search both and tab between the results.

    When you click a link, you will be redirected to Oracle Business Intelligence. If you do not have a consolidated OID setup, you will be asked to log in again.

14.15.7.2 Integrating the Oracle WebCenter

To set up and crawl an Oracle WebCenter environment, see "Managing the Search Service" in Oracle Fusion Middleware Administrator's Guide for Oracle WebCenter and then import the searchable objects into ECSF as external categories.

Importing Source Group into ECSF

The group now should be searchable from within the SES Search UI.

To allow the group to be searchable from Oracle Fusion Applications Search, it needs to be imported via the cmdLineAdmin tool or Oracle Enterprise Manager Fusion Middleware Control. Follow these steps if you use the tool:

  1. Launch the cmdLineAdmin tool. Its prompt will display.

  2. Issue this command at the prompt:

    > manage instance 124 (where 124 differs for each developer).

    The prompt will change to show that an instance is being managed.

  3. Enter this command:

    Instance: 124> list external categories

    This information displays:

    List of External Categories for Instance with ID 124:
    ---------------------------------------------------
    ID               | Name                           |
    ---------------------------------------------------
    100000000013878  | bi_SearchableTreeDirectory     |
    100000000013879  | WebCenter                      |
    
  4. Enter this command:

    Instance: 124> import external categories

    This command should return an Import successful message.

  5. Enter this command:

    Instance: 124> list external categories

    This information displays:

    List of External Categories for Instance with ID 124:
    List of External Categories for Instance with ID 124:
    ---------------------------------------------------
    ID               | Name                           |
    ---------------------------------------------------
    100000000014896  | bi_SearchableTreeDirectory     |
    100000000014897  | WebCenter Jive Forums          |
    100000000014898  | WebCenter Jive Announcements   |
    100000000014899  | WebCenter                      |
    

14.15.7.3 Ensuring Parity of Users

Users must be defined in multiple applications if you do not have a single authentication store.

Ensure you have a user defined that is common across both Oracle Fusion Applications and Oracle WebCenter.

For instance, you can create an fmwadmin user on the Oracle Fusion Applications side to do this by adding to the jazn-data.xml file.

With Oracle Secure Enterprise Search (SES) Authentication pointing to the ECSF SearchFeedServlet, which is using the WebLogic Server container security, this user will be verified by the SES authentication callbacks.

In a true enterprise environment, both the Oracle Fusion Applications web container and Oracle WebCenter would be set up with the same OID.

Using two different authentication stores will mean you get multiple logins when clicking results.

14.16 Introducing the Navigate API

Product teams can create a link in the task flow to navigate to a different UI Shell page. Because navigation can occur across different web applications, a single consistent API performs browser redirect. See Table 14-15. This API is exposed as the FndUIShellController.navigate Data Control method.

Note:

When launching a new window, whenever possible, you should use the Navigate API instead of using the ADF Controller sub-flow calls. This is because the UI Shell has no information about sub-flows. For instance, if you perform a search that returns clickable results and use sub-flows to display the results, and if you then choose to save the page to your Favorites, the search page is saved; not the results page you want. If you use the Navigate API, however, the UI Shell knows about the opened results page and saving the page to your Favorites works as you expect.

14.16.1 How to Use the Navigate API Data Control Method

Developers will drag and drop the Data Control method on page fragments to create links to invoke navigation.

  1. Expand the Data Controls and select the navigate item, as shown in Figure 14-14.

    Figure 14-65 Selecting navigate from Data Controls

    Selecting navigate from Data Controls
  2. Drag navigate and drop it onto the page fragment. When you do, the Applications Context menu shown in Figure 14-15 displays so you can choose one of the three options.

    Figure 14-66 Selecting a Navigate Option from the Applications Context Menu

    Selecting a Nav Option from the Applications Context Menu

Developers can specify a task flow to load on the target page. Page level parameters can also be specified.

Table 14-15 Navigate API Parameters

Navigate API Parameter Attribute Name

viewId

navigateViewId

webApp

The webApp attribute is used to look up the host and port of the associated Workarea or Dashboard from the ASK deployment tables. These tables are populated at deployment time through Oracle Functional Setup Manager tasks.

You need to pass the deployed module name to the webApp parameter.

requestContextPath

Obsolete. Replaced by webApp.

pageParametersList

navigateParamsList

navTaskFlowId

taskFlowId

navTaskKeyList

keyList

navTaskParametersList

parametersList

Developers can load the task flow specified in the navTaskFlowId parameter of the Navigate API as a dependent flow if the destination page is in no tab mode by adding a name/value pair of "loadDependentFlow=true" to navTaskParametersList. For example: "customerId=123;loadDependentFlow=true"

navTaskLabel

label


Certain parameters, summarized in Table 14-16, can be passed using the Navigate API's argument list.

Table 14-16 Parameters Passed Using Navigate API Arguments

Parameter Name Passed Using Description

fndNavForceRefresh

pageParametersList

Default: false

The Navigate API is used to navigate from one work space to another. If the current view id is the same as the viewId parameter, and if navTaskFlow is null, the current page will be refreshed. If the current view id is the same as the viewId parameter, and if navTaskFlowId is not null, the current page will not be refreshed, and the Navigate API will delegate to the openMainTask API to open the task flow in the Main Area. This can be overridden by passing in fndNavForceRefresh=true in pageParametersList to force the page refresh so that openMainTask would not be used.

Example:

pageParametersList = "fndNavForceRefresh=true;param2=value2";

Details:

pageParametersList is a semicolon delimited String of name value pairs.

ContextualAreaCollapsed

methodParameters

Default: false

Example:

FndMethodParameters methodParameters = new FndMethodParameters();
methodParameters.setContextualAreaCollapsed(Boolean.TRUE);
methodParameters.setContextualAreaWidth(200);

contextualAreaWidth

methodParameters

Default: 256

Example:

FndMethodParameters methodParameters = new FndMethodParameters();
methodParameters.setContextualAreaCollapsed(Boolean.TRUE);
methodParameters.setContextualAreaWidth(200);

loadDependentFlow

navTaskParametersList

Default: false

Example:

navTaskParametersList = "loadDependentFlow=true;param2=value2";

Note that the value for loadDependentFlow is case sensitive.

Details:

navTaskParametersList is a parameter list to pass in to the task flow to open in the target workspace. This is a semicolon delimited string of name/value pairs.


Note:

When passing parameters, do not leave the label field null. This is the label that would appear in the tab header when in a tabs page. Even if you are in a no-tabs page (see Section 14.2.3.4, "Supporting No-Tab Workareas"), do not leave it blank because this label will be used in other ways, such as Add to Favorites, or when the system tracks the Recent Items.

The signature and Javadoc of the method are shown in Example 14-68.

Example 14-68 Navigating from One Work Space to Another

/**
* Navigate from one work space to another. If the current view id is the
* same as the viewId parameter, and if navTaskFlow is null, the current page
* will be refreshed. If the current view id is the same as the viewId
* parameter and if navTaskFlowId is not null, the current page will not
* be refreshed. The Navigate API will delegate to openMainTask API to open the
* task flow in the Main Area. This can be overriden by passing in
* fndNavForceRefresh=true in pageParametersList to force the page refresh so
* that openMainTask would not be used.
*
* @param viewId viewId of the target workspace
* @param webApp Deployed Module Name of the target workspace.
*        It only needs to be set when the target workspace is in a different 
*        deployed module than the origin workspace. When this is null, it means 
*        the target workspace is in the same deployed module of the origin 
*        workspace. The webApp attribute is used to look up the host and port of
*        the associated Workarea or Dashboard from the ASK deployment
*        tables. These tables are populated at deployment time through
*        Functional Setup Manager tasks.
* @param pageParametersList Parameters list for the page. This is a semicolon 
*                   delimited String of name value pairs. For example,
*                   "param1=value1;param2=value2"
*                   If the Expression Language expression evaluates to an Object, 
*                   toString value of that Object will be passed as the value of 
*                   the parameter.
* @param navTaskFlowId ID of the taskFlow to open in the target workspace
* @param navTaskKeyList Key list to pass into the task flow to open in the
*                   target workspace. This is a semicolon delimited
*                   keys or key-value pairs. For example,
*                   "key1;key2=value2"
* @param navTaskParametersList Parameters list to pass in to the task flow to open
*                   in the target workspace. This is a semicolon delimited String
*                   of name value pairs. For example,
*                   "param1=value1;param2=value2."
* @param navTaskLabel Label for the task flow to open in the target workspace.
* @param methodParameters Construct FndMethodParameters object for setting the 
*                   width of the contextual area, and/or setting the disclosed 
*                   state of the contextual area.
* @throws IOException
*/
  public void navigate(String viewId, String webApp,
                       String pageParametersList, String navTaskFlowId,
                       String navTaskKeyList,
                       String navTaskParametersList,
                       String navTaskLabel,
                       FndMethodParameters methodParameters)

The main navigation is driven by two attributes: viewId and webApp.

  • webApp determines which web application to navigate to.

  • viewId determines the view activity within the target web application.

pageParametersList defines custom URL parameters that product teams can define.

The three parameters navTaskFlowId, navTaskParametersList, and navTaskLabel, provide support for loading a task flow on the target page, in addition to the default Main Tasks of the target page.

FndMethodParameters are placed as a future extension mechanism. The parameters that can be set through FndMethodParameters are: contextualAreaWidth and contextualAreaCollapsed. Example 14-69 shows how to set up these two parameters.

Example 14-69 Setting contextualAreaWidth and contextualAreaCollapsed Parameters

FndMethodParameters methodParameters = new FndMethodParameters();
  methodParameters.setContextualAreaCollapsed(Boolean.FALSE);
  methodParameters.setContextualAreaWidth(200);

Notes:

  • The task flow to be opened in the target Work Area need not be pre-registered as a defaultMain or dynamicMain Task for that page. The TaskFlow ID, parameters for it, and the label are all explicitly passed to the target page, and the target page does not perform any validation.

  • The webApp value that is passed into the Navigate API is used to look up the host and port of the associated WorkArea or Dashboard from the ASK deployment tables. These tables are populated at deployment time through Functional Setup tasks.

  • Because the Navigate API is based on URL redirect, only String representations of the parameter values can be passed to the target page. It is not possible to pass an Object as a parameter value. For example, a Java Map cannot be passed as a parameter.

  • When navigating using this API, the ADF Controller state of the source page is not cleaned up.

14.16.2 How to Implement Navigation Across Web Applications

Navigating across web applications requires the webApp parameter in the menu meta data. For this parameter to work properly, the ApplicationDB and the AppMasterDB connections must be set. The webApp parameter must be specified for each parent node in the menu meta data. Child nodes inherit the value of this parameter from the parent node if not specified. The Navigate API is also modified to add the webApp parameter. Similarly, when using the openSubTask API, product teams must specify the webApp parameter correctly. There are no design or compile time checks that can catch an invalid value for the webApp parameter. It will throw null pointer exceptions at run time only.

Note that you need to pass the DEPLOYED_MODULE_NAME in the ASK_DEPLOYED_MODULES table as the webApp parameter. The DEPLOYED_MODULE_NAME, by standard, should be the same as the context root of the application to which you are trying to navigate.

14.17 Warning of Pending Changes in the UI Shell

When there are pending changes in the UI Shell Main Area, and the user is navigating out of the page, or is refreshing the tab or taskflow, or is closing the tab, the UI Shell will provide a modal confirmation dialog to the user. If confirmed, the operation will be allowed to proceed. Otherwise, the user will remain on the original page or tab.

Cases where pending changes are checked in the UI Shell Main Area include:

Search Panel and Warning of Pending Changes

Search is treated as a special case and no warning for pending changes is shown when a user enters some data in a query panel provided by the Application Development Framework. But, from the search results page, drilling down to a subflow and making the flow dirty marks the subflow as a candidate for warn about changes.

14.17.1 How to Implement Warning of Pending Changes

To implement warning of pending changes, developers need to follow these steps.

  • All the main taskflows that render in MainArea should have the data-control-scope set to isolated.

    <data-control-scope id="dc">
      <isolated/>
    </data-control-scope>
    
  • Make changes to the Main Area.

    Note that inner taskflows and regions inside the main flow can have the data-control-scope set to shared.

    Other than tasklist, if developers are using Data Control APIs, such as openMainTask, closeMainTask or navigate, to relaunch or close a flow in the MainArea, they should add the clientListener to post the changes. Adding the clientListener on a commandButton that is bound to closeMainTask to post pending changes before the currently focused tab/flow is closed is shown in Example 14-70.

    Example 14-70 Adding the clientListener on a commandButton

    <af:commandButton actionListener="#{bindings.closeMainTask.execute}"
                 text="closeMainTask- with - CL"
                 disabled="false"
                 id="cb1">
          <af:clientListener method="queueActionEventOnMainArea" type="action"/>
    </af:commandButton>
    

    When a command link/button invokes Data Control APIs programmatically, developers should add a client listener on the command link/button, as shown in Example 14-71.

    Example 14-71 Adding a client listener when a command link/button invokes Data Control APIs programmatically

    <af:commandButton text="Calling datacontrol api programmatically"
             binding="#{backingBeanScope.backing_Navigateviaprogramatically.cb1}"
             id="cb1" action="go">
      <af:clientListener method="queueActionEventOnMainArea" type="action"/>
    </af:commandButton>
    

    In addition to adding the clientListener, when Data Control APIs are executed from within the MainArea, developers must add the methodAction shown in Example 14-72 to their main page fragment's pageDef whose taskflow is attached to the tab in MainArea.

    Example 14-72 Adding the checkDataDirty methodAction

    <methodAction id="checkDataDirty"
         InstanceName="FndUIShellController.dataProvider"
         DataControl="FndUIShellController" RequiresUpdateModel="true"
         Action="invokeMethod" MethodName="checkDataDirty"
         IsViewObjectMethod="false"
         ReturnName="FndUIShellController.methodResults.checkDataDirty_FndUIShellController_dataProvider_checkDataDirty_result"/>
    

    The Data Control API shown in Example 14-72 lets you check for data dirty from within the child region and identify any pending changes in the child region.

    After adding above API to the main page fragment's pageDef, developers should let the UI Shell know about that by sending the parameter "fndCheckDataDirty=true" in the parametersList or navTaskParametersList.

14.17.2 How to Suppress Warning of Pending Changes

Developers can suppress warning of pending changes for a particular flow by sending the parameter "fndWarnChanges=false" to the parametersList or navTaskParametersList, as shown in Example 14-73.

Example 14-73 Suppressing warning of pending changes for a flow

<methodAction id="openMainTask" RequiresUpdateModel="true"
              Action="invokeMethod" MethodName="openMainTask"
              IsViewObjectMethod="false" DataControl="FndUIShellController"
              InstanceName="FndUIShellController.dataProvider"
              ReturnName="FndUIShellController.methodResults.openMainTask_FndUIShellController_dataProvider_openMainTask_result">
  <NamedData NDName="taskFlowId" NDValue="/WEB-INF/task-flow-definition.xml#task-flow-definition" NDType="java.lang.String"/>
  <NamedData NDName="keyList" NDType="java.lang.String"/>
  <NamedData NDName="parametersList" NDValue="fndWarnChanges=false" NDType="java.lang.String"/>
  <NamedData NDName="label" NDValue="Suppress Warn About Msg" NDType="java.lang.String"/>
  <NamedData NDName="reuseInstance" NDValue="true" NDType="java.lang.Boolean"/>
  <NamedData NDName="forceRefresh" NDValue="true" NDType="java.lang.Boolean"/>
  <NamedData NDName="loadDependentFlow" NDType="java.lang.Boolean"/>
  <NamedData NDName="methodParameters"
  NDType="oracle.apps.fnd.applcore.patterns.uishell.ui.bean.FndMethodParameters"/>
</methodAction>

14.18 Implementing the Oracle Fusion Home Page UI

The Oracle Fusion Home Page UI consists of a series of JSPX pages, each of which provides product- or role-specific content, that are visually tied together using a tabbed navigation interface.

Terms

Home page: any one of these JSPX pages.

Oracle Fusion Home: the overall Oracle Fusion Home Page UI.

14.18.1 Supported Behavior

The following key requirements are supported by the Oracle Fusion UI Shell:

  • To conform to Oracle Fusion Applications modularity requirements, the Oracle Fusion Home provides a common entry point across multiple J2EE web applications. A given home page can be hosted on any one of these distinct J2EE web applications. A tab click on a given home page therefore needs to issue a request for another home page that may be hosted on a different web app. When the new page is displayed, its tab must be visually selected.

  • Each home page should display content that includes navigation means to resources that may be hosted on a different web application. For example, a command navigation link on a home page may target a bounded task flow located on a different web application and designed to run on a Workarea or Dashboard page located on that web application.

  • A given home page may include content from a bounded task flow (presumably displayed within an ADF region or portlet) that has command navigation links within its view activities. These links or other navigation means must work correctly on the home page. For example, on click, navigate to the correct Workarea page and launch the intended task flow.

  • The Home link in the Global Area will be disabled on all home pages.

  • By default, the Home link will go to the Welcome tab and, if a different tab is selected, the Home link will go back to the last tab that was selected for that session. If, however, the user navigates to any Oracle Fusion page through a direct URL navigation, such as an email that contains a link to a Workarea, the Home link will again return to the Welcome tab. By default, the Welcome tab will be the first itemNode defined.

  • A home page will display the same layout and content in the Global Area and for the page footer as other pages that extend the UI Shell page template. Unlike a Workarea page, however, the intervening content and its layout between the Global (top) and footer (bottom) sections of the page will be determined and provided by product teams.

14.18.2 How to Create a Home Page

To create a home page, follow these basic steps.

  1. Create a JSPX page that extends UIShell.jspx.

  2. From the JSPX page, select the <af:pageTemplate> tag. On the property inspector, set the isHomePage attribute to true. Note that when isHomePage is set to true, the Regional, Local and Contextual Areas of the UI Shell will not be rendered.

  3. Add content to the HomePageContent facet, following the ADF Layout Basics guideline for laying out the components.

  4. Drop the JSPX to adfc-config.xml.

  5. Repeat Steps1 through 4 for all home page JSPX pages.

  6. Create the Home Page menu. See Section 14.5, "Working with the Global Menu Model."

  7. When running a home page JSPX, the page should look similar to Figure 14-67.

Figure 14-67 Home Page Example

Home Page example

14.18.3 Getting the URL

There are two APIs located in the UIShellContext class that you can use to return a URL without actually performing the navigation to the URL:

  • getURL : getURL is the same as a navigate call, but it returns the URL as a string instead of doing the navigation. See Example 14-74.

    Example 14-74 Example Use of getURL

    public java.lang.String getURL(   java.lang.String    viewId,
       java.lang.String webApp,
       java.lang.String pageParametersList,
       java.lang.String navTaskFlowId,
       java.lang.String navTaskKeyList,
       java.lang.String navTaskParametersList,
       java.lang.String navTaskLabel,
    FndMethodParameters methodParameters)
    throws  java.io.IOException
    
  • getURLForCurrentTask : getURLForCurrentTask, shown in Example 14-75, is good for getting the URL of the Main area flow in focus so you could send it in an email to someone else. When clicked, it would open the correct workarea (.jspx page) and the correct flow with the correct parameters. If you did have other dynamic tabs open when you called getURLForCurrentTask, it would not open those when clicked.

    Example 14-75 Example Use of getURLForCurrentTask

    public java.lang.String getURLForCurrentTask( )
    throws  java.io.IOException
    

14.19 Using the Single Object Context Workarea

The Single Object Context Workarea is a facet that defines an area between the Global Area and the Main and Regional areas into which developers can add what they want. If the facet is empty, the area does not appear. You also can create a view scope parameter so other flows on the page can get the context. See Figure 14-68.

Figure 14-68 Context Area Example

Context Area example

This area is useful for creating Single Object Workareas, which are particularly useful in tabbed page mode. A Single Object Workarea is a page that is devoted to one object so the information of that one object can be put above the Workarea.

Single Object Workareas provide a context for addressing the tasks and processes for the business process of a single complex object instance at a time. Usually, single object workareas will use multiple defaultMain flows. Each flow can be about a different aspect of the same object. For instance, you could have one tab showing recent activity, and another tab showing payments.

14.19.1 Implementation Notes

The SingleObjectContextArea facet has been added to the UI Shell template for Context Area task flow.

A managed bean entry, shown in Example 14-76, has been added to adfc-config.xml for viewScope Hashmap.

Example 14-76 Managed Bean viewScope Hashmap Entry in adfc-config.xml

<managed-bean>
    <managed-bean-name>fndPageParams</managed-bean-name>
    <managed-bean-class>java.util.HashMap</managed-bean-class>
    <managed-bean-scope>view</managed-bean-scope>
  </managed-bean>

Support for URL parameters defined in the view activity for the page (JSPX) in adfc-config is to be set in the fndPageParams Hashmap defined in viewScope. This Hashmap is also passed onto the pageFlowScope of the task flows in the context area, regional area and main area.

This is accomplished by enabling the Bookmarkable property on the view activity for the page and specifying the URL parameter names with the value set to be added to the fndPageParams Hashmap defined in viewScope. See the "How to Create a Bookmarkable View Activity" section in Chapter 15, "Working with Task Flow Activities," of the Oracle Fusion Middleware Fusion Developer's Guide for Oracle Application Development Framework.

Product team task flows running in the Single Object Context Workarea must be designed to take in the appropriate context values as input parameters. The pageFlowScope values must be passed to the appropriate input parameters through the parametersList for the item node in the menu or the openMainTask API.

Product teams can cause URL navigation (using the navigate data control method provided by UI Shell by passing required parameters in the pageParametersList) for changing context or updating context information. This will cause the entire page to be refreshed based on new context parameter values.

Product teams can also check for the input parameter values (the context) within the context area task flow. If invalid, a modal dialog can be launched for the end user to choose a context (rendered as links based on the navigate data control method provided by UI Shell) before proceeding.

14.19.1.1 Developer Implementation

Enable the Bookmarkable property on the view activity for the single object context page and specify the URL parameter names with the corresponding fndPageParams viewScope Hashmap key where the value should be stored. See the "How to Create a Bookmarkable View Activity" section in Chapter 15, "Working with Task Flow Activities," of the Oracle Fusion Middleware Fusion Developer's Guide for Oracle Application Development Framework.

Example 14-77 shows a sample entry in adfc-config.xml for such a view activity.

Example 14-77 Sample Entry in adfc-config.xml for a View Activity

<view id="SingleDeptContextPage">
 <page>/oracle/apps/empdeptdemo/ui/page/SingleDeptContextPage.jspx</page>
 <bookmark>
  <url-parameter>
   <name>Deptno</name>
   <value>#{viewScope.fndPageParams.Deptno}</value>
  </url-parameter>
 </bookmark>
</view>

Product teams must create a bounded task flow for the Context Area that appears at the top of the page. This task flow must accept the context values as input parameters. This task flow is dropped as a static region onto the Context Area facet in the JSPX page based on the UI Shell template. In the task flow binding, set the input parameter values to the corresponding key in fndPageParms viewScope Hashmap.

Example 14-78 shows a sample entry in the page definition for the JSPX file for passing the viewScope values into the Context Area task flow as input parameter.

Example 14-78 Sample Page Definition for Passing viewScope Values into Context Area Task Flow

<taskFlow id="ContextDeptSummary1"
              taskFlowId="/WEB-INF/oracle/apps/empdeptdemo/ui/flow/ContextDeptSummary.xml#ContextDeptSummary"
              xmlns="http://xmlns.oracle.com/adf/controller/binding">
      <parameters>
        <parameter id="Deptno" value="#{viewScope.fndPageParams['Deptno']}"
                   xmlns="http://xmlns.oracle.com/adfm/uimodel"/>
      </parameters>
    </taskFlow>

The UI Shell code passes this viewScope Hashmap onto the pageFlowScope of the main area and regional area task flows. Product team task flows, which are initialized in the regional and main area, can access this in pageFlowScope (of main/regional area container task flow owned by Applications Core) for the appropriate input parameters through the menu model and openMainTask API.

Example 14-79 shows a sample entry for a child item node for defaultMain task in the menu.xml to pass the appropriate deptno in the single object context to a task flow that is initialized based on this input value.

Example 14-79 Sample Child Item Node for defaultMain Task

<itemNode id="SingleDeptContextPage_EmpListingDefaultTab"
              focusViewId="/SingleDeptContextPage"
              label="#{adfBundle['oracle.apps.empdeptdemo.ui.test_menuBundle'].EMPLOYEE_LISTING}"
              taskType="defaultMain" reuseInstance="false"
              taskFlowId="/WEB-INF/oracle/apps/empdeptdemo/ui/flow/ContainerTF.xml#ContainerTF"
              parametersList="Deptno=#{pageFlowScope.fndPageParams['Deptno']}"/>

Product teams can cause URL navigation (through the navigate data control method provided by UI Shell) for changing context or after updating context information. This will cause the entire page to be refreshed based on new context parameter values.

Product teams can also check for the input parameter values within the pageFlowScope of the context area task flow. If invalid, a modal dialog can be launched for the end user to choose a context (by providing links based on the navigate data control method provided by the UI Shell by passing required parameters in the pageParametersList) before proceeding. This can be achieved by defining an invoke action executable in the page def for the context area page fragment which checks for existence of the pageFlowScope value and programmatically shows a modal dialog for the user to choose the context. The other alternative is to use this approach to cause navigation to a completely different page where the user can select the context.

Also, it is important to note that all the bounded task flows that will be initialized in the Single Object Context Workarea need to check for input parameter values and show/query data ONLY if the input parameter values are passed. Basically, if the input parameter values are empty, the task flows handle that, such as in a router activity, and avoid showing any transaction data to the end user.

14.20 Implementing the Third Party Component Area

The Third Party Component Area, shown in Figure 14-69, is a facet in the UI Shell template for showing content just above the Single Context Workarea in the global area. Although originally designed to contain a Call Telephony Interface (CTI) showing incoming calls in a call center operation, the facet can contain anything.

Figure 14-69 Third Party Component Area Facet Containing A CTI

Third Party Facet Containing a CTI

14.20.1 How to Implement the ThirdPartyComponentArea Facet Developer

The ThirdPartyComponentArea facet should be added within a flexible layout component that will allow you to control the amount of screen real estate that the content added to the facet can consume.

  • A facet ref is under the global area content with its width set to 100 percent.

  • Add content to this facet.

  • You should create a bounded task flow with page fragment for the content and drop it into this facet as a static region. This supports personalization through web composer since the content is within a page template.

  • The height property of the panelStretchLayout in the UI Shell template defaults to 33 px. To view or enable the third party component area (see the dark blue area at the top of Figure 14-1), specify the globalAreaHeight property as auto in the pageTemplate property Inspector.

    When the height of the top facet is specified as a CSS length or as auto, this facet will no longer be stretched and instead will consume the initial offsetHeight given to its children by the browser. It is important to note that in an average page, a switch to a layout using automatic heights exhibited a 5- to 10-percent degradation in initial layout speed. Also, an automatic height will cause the facet child to not be stretched both vertically and horizontally.

  • You can set the height of the root layout component within the facet to auto to ensure auto-resizing of contents within the facet. Consider a showDetailHeader that is the root element within the facet (in the default view activity for the bounded task flow dropped in as a region). If the height property for this showDetailHeader component is set to auto, collapsing the header would resize the contents and open more real estate in the screen for showing other components in the page.

14.21 Developing an Activity Guide Client Application with the UI Shell

The Oracle UI Shell can be used to develop an Activity Guide client application.

Before you begin:

Copy the file oracle.bpm.activityguide-ui_11.1.1.jar to a local directory from the following location in the bpm-jdev-extension.zip file:

jdev_install/jdeveloper/soa/modules/oracle.bpm.activityguide-ui_11.1.1.jar

To develop an activity guide client application using Oracle UI Shell:

  1. Create a new application. In the Application Package Prefix field, enter oracle.ag.

    Figure 14-70 Filling-in the Application Package Prefix Field

    Enter oracle.ag in the Application Package Prefix field.

    When prompted to create a new project, click Cancel.

  2. In the new application, create a new project using the Web Project template by right-clicking the application and selecting New Project > Project > Web Project. Select Servlet 2.5/JSP 2.1 (Java EE 1.5). Click through the wizard, accepting all default values.

  3. Add the ADF Faces and ADF Page Flow technologies to the client application project. Right-click the project and select Project Properties > Technology Scope. Shuttle ADF Faces and ADF Page Flow from the Available Technologies list to the Selected Technologies list.

    Make sure the following technologies are also selected: HTML, Java, JSP and JSF and Servlets.

    Figure 14-71 Adding the ADF Faces and ADF Page Flow Technologies to the Client Application

    Add ADF Faces and ADF Page Flow to the client application.
  4. Right-click the client application and select Project Properties > JSP Tag Libraries. Select the Distributed Libraries folder and click Add. In the Choose Tag Libraries window, select the tag library Applications Core (ViewController) 11.1.1.0.0 and click OK.

    Figure 14-72 Select the Tag Library Applications Core (ViewController) 11.1.1.00

    Select tag library Applications Core.
  5. In the Project Properties window, select Libraries and Classpath and click the Add Library button. From the window that displays, select the Applications Core library and click OK.

    Figure 14-73 Add the Applications Core Library to the Project

    Add the Applications Core library to the project.
  6. In the Project Properties window, click the Add JAR/Directory button and browse for the file oracle.bpm.activityguide-ui_11.1.1.jar. The file is located under jdev_install/jdeveloper/soa/modules/oracle.bpm.activityguide-ui_11.1.1.jar.

    Click Select to add the JAR to the project classpath.

  7. Add Activity Guide runtime libraries or JAR files to the classpath. Use either shared libraries or JAR files; do not use both.

    1. Using shared libraries for Activity Guide runtime JAR files

      Add the shared library references oracle.soa.bpel and oracle.soa.workflow.wc to the weblogic-application.xml file.

      <library-ref>
         <library-name>oracle.soa.bpel</library-name>
      </library-ref>
      <library-ref>
         <library-name>oracle.soa.workflow.wc</library-name>
      </library-ref>
      
    2. Using JAR files for Activity Guide runtime

      Add the following JAR files to the classpath:

      FMW_home/AS11gR1SOA/soa/modules/oracle.soa.workflow_11.1.1/bpm-services.jar
      FMW_home/AS11gR1SOA/soa/modules/oracle.soa.bpel_11.1.1/orabpel-common.jar
      FMW_home/AS11gR1SOA/soa/modules/oracle.soa.bpel_11.1.1/orabpel.jar
      FMW_home/AS11gR1SOA/soa/modules/oracle.soa.fabric_11.1.1/bpm-infra.jar
      FMW_home/AS11gR1SOA/soa/modules/oracle.soa.fabric_11.1.1/fabric-runtime.jar
      FMW_home/oracle_common/modules/oracle.webservices_11.1.1/wsclient.jar
      FMW_home/oracle_common/modules/oracle.xdk_11.1.1/xml.jar
      
  8. Create a file called Config.jar using the wf_client_config.xml file and add it to the application classpath. The wf_client_config.xml file should include the host name and port of the WLS instance running the Activity Guide instances.

  9. Create a JSF page. Right-click the application name and click New. In the New Gallery, select JSF > JSF Page and click OK. Use UIShell as a page template and select the checkbox Create as XML Document (*.jspx).

    If a dialog box displays the message "Confirm Add Form Element," click No.

  10. Create Application menu metadata. See Section 14.3, "Implementing Application Menu Security.".

To add a task flow to the Oracle UI Shell client application:

  1. Open the menu metadata menu XML file created in "To develop an activity guide client application using Oracle UI Shell:".

  2. Right-click itemNode_<JSF page name> and select Insert inside itemNode_<JSF page name> > itemNode.

  3. In the Common Properties window, browse for the name of the JSF page and enter a unique ID for the itemNode using the standard format <pageID>_<taskFlowName>. For example: ItemNode_MainArea_TaskFlow.

  4. Click the Browse button to the right of the focusViewId field. In the Edit Property window that displays, select the focusViewId of the page under which you are registering the task flow. Click OK.

  5. In the Property Inspector, select the Applications tab and enter a label for the itemNode such as Main Taskflow.

  6. From the Project Navigator, select the menu metadata XML file. In the Structure view, select the task flow itemNode – Main Taskflow. In the Property Inspector, enter the following values under the Advanced section:

    • Task Type: defaultMain

    • Task Flow ID: Click the Browse button to display the Select Task Flow ID window and select the location of the task flow definition: /WEB-INF/oracle/bpel/activityguide/ui/taskflows/ag-humantask-task-flow.xml#ag-humantask-task-flow. This is the ID of the main area task flow.

    • Disclosed: Optionally, set this value to false. This property enables opening a new tab when clicking the relevant task link at run time. For tabs, the first defaultMain with disclosed=true is the one that will be in focus.

  7. Repeat Steps 1 through 6 for the regional task flow, naming the label and ID accordingly. Provide the following values for the regional task flow in step 6:

    • Task Type: defaultRegional

    • Task Flow ID: Click the Browse button to display the Select Task Flow ID window and select the location of the task flow definition: '/WEB-INF/oracle/bpel/activityguide/ui/taskflows/ag-tasktree-task-flow.xml#ag-tasktree-task-flow. This is the ID of the regional area task flow.

    • Disclosed: Set this value to true for the regional task flow. This property enables opening a new tab when clicking the relevant task link at run time.

  8. Create a file called activityguide.properties. See the table of Activity Guide properties, and the sample properties file, in the "Developing a Guided Business Process Client Application with Oracle ADF" section of Oracle Fusion Middleware Modeling and Implementation Guide for Oracle Business Process Management.

    If using identity propagation to secure the Activity Guide, the properties WorkflowAdminUser and WorkflowAdminPassword are not required.

  9. In the page definition of Oracle UI Shell JSF fragment page, navigate to pageTemplateBinding and set the Refresh property to ifNeeded.

  10. Open the file adfc-config.xml.

  11. Edit the file adfc-config.xml to include the location of the activity.properties file. This should be the absolute path to the activityguide.properties file.

    An example adfc-config.xml is shown in Example 14-80.

    Example 14-80 adfc-config.xml File with Reference to activityguide.properties File

    <managed-bean>
    <managed-bean-name>agProps</managed-bean-name>
    <managed-bean-class>
       oracle.bpel.activityguide.ui.beans.model.AGProperties
    </managed-bean-class>
    <managed-bean-scope>request</managed-bean-scope>
    <managed-property>
    <property-name>absAgPropsFileName</property-name>
    <property-class>java.lang.String</property-class>
    <value> <!---absolute path on your machine should be given here-->/activityguide.properties</value>
       <!-- For example:
       Windows: C:\AG\activityguide.properties
       Linux: /scratch/<user>/AG/activityguide.properties
       -->
    </managed-property>
    </managed-bean>
    
  12. To enable a task flow popup with summary information, add the property AGTasksPopupTaskFlowID to the activityguide.properties file.

    Use this parameter to display a task flow summary in dynamic regions. Enter the relevant task flow ID. If this parameter is not set, the value of OutputText is shown as the default task summary.

  13. Create a Workflow Service client configuration file. An example is shown in Example 14-81.

    Example 14-81 Workflow Services Client Configuration File

    <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
    <workflowServicesClientConfiguration xmlns="http://xmlns.oracle.com/bpel/services/client">
      <server default="true" name="default">
          <localClient>
              <participateInClientTransaction>false</participateInClientTransaction>
          </localClient>
          <remoteClient>
              t3://host:port
              <initialContextFactory>weblogic.jndi.WLInitialContextFactory</initialContextFactory>
              <participateInClientTransaction>false</participateInClientTransaction>
          </remoteClient>
          <soapClient>
              http://host:port
              <identityPropagation mode="dynamic" type="saml">
                  <policy-references>
                      <policy-reference enabled="true" category="security" uri="oracle/wss10_saml_token_client_policy"/>
                  </policy-references>
              </identityPropagation>
         </soapClient>
      </server>
    </workflowServicesClientConfiguration>
    
  14. Deploy the Acitivity Guide client application with Oracle UI Shell as described in "To deploy an Activity Guide client application with Oracle UI Shell to the integrated Oracle WebLogic Server:" or in "To deploy an Activity Guide client application with Oracle UI Shell to a standalone Oracle WebLogic Server:".

To secure the Activity Guide Oracle UI Shell client application:

Securing the Activity Guide client application ensures that only users with proper credentials can complete the tasks outlined in the Activity Guide. Security features include authentication, authorization, realm verification and policy enforcement.

Follow the instructions for securing a Web application as described in the "Enabling ADF Security in an Oracle Fusion Web Application" chapter of Oracle Fusion Middleware Fusion Developer's Guide for Oracle Application Development Framework.

To deploy an Activity Guide client application with Oracle UI Shell to the integrated Oracle WebLogic Server:

You can deploy an Activity Guide client application with Oracle UI Shell directly from JDeveloper or to the standalone Oracle WebLogic Server.

From the Application Navigator, right-click the JSF page created in "To develop an activity guide client application using Oracle UI Shell:" and select Run.

To deploy an Activity Guide client application with Oracle UI Shell to a standalone Oracle WebLogic Server:

  1. Create a connection to the standalone Oracle WebLogic Server.

  2. From the Application Navigator, right-click the project created in step 2 of "To develop an activity guide client application using Oracle UI Shell:"

  3. Select Project Properties.

    From the Project Properties dialog, select Deployment.

  4. Create a new WAR deployment profile.

  5. Right-click the project and select Deploy. Deploy the project to the standalone Oracle WebLogic Server connection created in step 1.

  6. Launch the client page from a browser.