PK  Boa,mimetypeapplication/epub+zipPK BiTunesMetadata.plist@ artistName Oracle Corporation book-info cover-image-hash 728347767 cover-image-path OEBPS/dcommon/oracle-logo.jpg package-file-hash 935346923 publisher-unique-id E15524-10 unique-id 411813402 genre Oracle Documentation itemName Oracle® Fusion Applications Developer's Guide, 11g Release 5 (11.1.5) releaseDate year 2013 PK3eE@PK BMETA-INF/container.xml PKYuPK BOEBPS/flex_ext.htm Using Extensible Flexfields

23 Using Extensible Flexfields

This chapter discusses how to use extensible flexfields to enable customers to add additional attributes to application business objects in Oracle Fusion Applications.

This chapter includes the following sections:

23.1 Introduction to Extensible Flexfields

An extensible flexfield is similar to a descriptive flexfield in that it provides a customizable expansion space that implementors, such as Oracle Fusion Applications customers, can use to configure additional attributes (segments) without additional programming. As with descriptive flexfields, each segment is represented in the database as a single column. However, with extensible flexfields, the context values and context-sensitive segments are stored in an extension table.

Implementors can combine and arrange the segments into attribute groups that are tailored to a customer's specific needs. For example, they can group related segments so that they appear together on the page. The attribute groups are referred to as contexts. You can optionally set up an extensible flexfield to enable implementors to group contexts into categories.

To understand how implementors use contexts and categories to configure extensible flexfields to meet a customer's specific needs, see the "Using Flexfields for Custom Attributes" chapter in the Oracle Fusion Applications Extensibility Guide.

To learn more about flexfield basics and terms, including developer and implementor roles, segments, and contexts, see Chapter 21, "Getting Started with Flexfields." For more details about the differences between descriptive flexfields and extensible flexfields, see Section 23.1.2, "The Benefits of Extensible Flexfields."

23.1.1 Understanding Extensible Flexfields

Extensible flexfields include the following key artifacts:

  • Contexts (attribute groups)

  • Context-sensitive segments

  • Logical pages

  • Categories

  • Category hierarchies

  • Usages

23.1.1.1 About Contexts (Attribute Groups)

An extensible flexfield context is a data grouping mechanism that implementors can use to arrange segments into meaningful groups. Each context is a group of attributes that is displayed in its own subregion of the user interface (UI) page at runtime. Implementors create and configure the contexts. After creating a context, an implementor must associate the context with the categories for which that group of attributes is relevant. For example, a Parts flexfield might have a Fax category and an All-in-One Printers category. A Fax context would be associated with both categories, while a Copy context would be relevant only to the All-in-One Printers category. You can learn about categories in Section 23.1.1.4, "About Categories."

Figure 23-1 shows the UI page for the Positions business object. The Positions flexfield is embedded in the Additional Position Details region on the page. This region contains the Educational Requirements, Certification and License Requirements, and Travel contexts for the Positions flexfield.

Figure 23-2 and Figure 23-3 show UI pages for the Parts business object. The developer has enabled multiple categories for the Parts flexfield, so the page displays the category to which the part shown belongs. In Figure 23-2, the part belongs to the All-in-One Printers category, and in Figure 23-2, the part belongs to the Fax category. In these pages, the Parts flexfield is embedded in the Additional Information region. For the All-in-One Printers category in Figure 23-2, the Additional Information region contains the Copy, Fax, and Scan contexts for the Parts flexfield, while on the Parts page for the Fax category in Figure 23-3, the region contains just the Fax context.


Note:

A flexfield region is empty until the implementor configures the extensible flexfield that is embedded in it.


Extensible flexfields allow implementors to configure contexts as either single row or multiple row. That is, either one set of segments is stored for a business object instance, or multiple sets of segments are stored for the instance. For example, a job position requires only one set of educational requirements, but can require more than one certificate or license.

For single-row contexts, the segments appear as fields in a form. With multiple-row contexts, the segments appear as columns in a table, thus allowing end users to capture a list. In Figure 23-1, Educational Requirements and Travel are single-row contexts, so end users can specify only a single value for each context-sensitive segment, such as the percent of travel time required for the position. The Certification and License Requirements context is a multiple-row context, so end users can enter multiple rows, one for each certificate or license required for the position.

Figure 23-1 Position User Interface Page

Position user interface page

Figure 23-2 Parts User Interface Page for the All-in-One Printers Category

UI Page for All-in-One Printers Category

Figure 23-3 Parts User Interface Page for the Fax Category

Parts page for Fax category

23.1.1.2 Context-Sensitive Segments

With extensible flexfields, every segment is a member of a context (attribute group). That is, all segments are context-sensitive. Implementors define the contexts and their context-sensitive segments. Context-sensitive segments are the lowest-level data points that implementors can define for an extensible flexfield, and each segment is mapped to a column in an extension table. Just as with descriptive flexfields, the segments are rendered as ADF Faces rich client components, such as text box, text area, list of values (LOV) choice list, date picker, checkbox, and radio button group.

In Figure 23-1, the Educational Requirements context contains the High School, Bachelor, Master, J.D., M.D., and Ph.D. context-sensitive segments, and the Certification and License Requirements context contains the Type and Certificate/License context-sensitive segments.

23.1.1.3 About Logical Pages

Extensible flexfields enable implementors to define logical pages with which to group contexts for display purposes. Each page can contain one or more contexts along with their respective context-sensitive segments. There is no limit to the number of contexts on a logical page. The implementors associate the logical pages with categories on a flexfield usage basis. For information about usages, see Section 23.1.1.6, "About Usages (Data Levels)."

In the Parts UI page shown in Figure 23-2, an implementor has defined two logical pages for this category — Printers and All-in-One. The implementor defined the Printers logical page to contain all contexts related to the printing capabilities of the printer, and the All-in-One page to contain all contexts related to the other capabilities of the printer, such as the scanning, copying, and faxing capabilities

The Parts page that is shown in Figure 23-2 displays the list of logical pages for the category in the left-hand pane. End users view a logical page in the right-hand pane by selecting it from the list. In this figure, the end user has chosen to view the All-in-One logical page. The Printers logical page is shown in Figure 23-4.

Figure 23-4 Printers Logical Page in the Parts User Interface Page

Printers logical page in the parts UI

Logical pages have several layout options. For example, in Figure 23-1, the developers chose to hide the entire left-hand section because their customers will add attributes to a single page that is known at the time of development. However, in Figure 23-4, developers chose to display the list of logical pages in the left-hand pane. For more information about layout options, see Section 23.7, "Employing an Extensible Flexfield on a User Interface Page."

23.1.1.4 About Categories

Categories enable applications to dynamically display different sets of logical pages and contexts at runtime. In the simplest case, you create a single category for a flexfield, and the same extensible flexfield contexts and logical pages appear for every instance of the business object. In some cases, you might need the application to display different sets of logical pages and contexts depending on a runtime discriminator, such as an instance value. In these cases, you can create multiple categories for the flexfield, or you can provide application-specific logic that enables implementors to define their own categories.

The Positions flexfield in Figure 23-1 has a single category. The same flexfield segments appear in the Additional Position Details region regardless of which position is displayed. In this page, the developer has hidden the name of the category, because there is only one category.

In Figure 23-2 and Figure 23-3, the segments that the region displays depend on which category the part belongs to. In Figure 23-2, the part belongs to the All-in-One Printers category and the UI displays fields related to copying, faxing, and scanning. In Figure 23-3, the part belongs to the Fax category and the UI displays fields related to only faxing.

23.1.1.5 About Category Hierarchies

You can choose to support multiple categories for your flexfield. When you do so, the extensible flexfield respects any hierarchical relationship that is defined for the categories, whether created by developers or defined by implementors. Figure 23-5 shows an example of categories that are defined in a hierarchical fashion. In this example, the root category (the category that does not have parent categories) is Computers and Office. One of its child categories is Printers and Ink. The Printers and Ink category, in turn, has a Printers child category. The Printers category has two child categories — All-in-One Printers and Single Function Printers.

Figure 23-5 Example of a Category Hierarchy

Example of a category hierarchy

Each child category inherits the contexts and pages from its parent categories. For example, the Printers category contains the Print, Printer Functions, and Supported Operating Systems contexts. The All-in-One Printers category inherits these contexts from the Printers category. It also inherits all logical pages that are defined for its parent categories. Additional contexts can be assigned directly to the All-in-One-Printers category, such as Copy and Scan, which are relevant only to All-in-One printers.

23.1.1.6 About Usages (Data Levels)

When you create an extensible flexfield, you create one flexfield usage for each set of tables in the application that uses the flexfield. In the simplest case, you will have one flexfield usage. For example, in Figure 23-1, the Positions application requires a single Positions table with its associated extension tables to store the extensible flexfield values. Implementors simply associate their contexts with that one usage to make them available to the Positions application.

When you have several objects in the application that should be extended using the same extensible flexfield, you must create multiple usages for the flexfield. For example, in the case of an Items application, there might be different data levels, such as items and item revisions. In this case, you create one usage per data level. By defining separate usages for each set of tables, you enable your implementors to reuse the same extensible flexfield configuration for all data levels.

23.1.2 The Benefits of Extensible Flexfields

When deciding whether to use a descriptive flexfield or an extensible flexfield to extend a business object, consider the following features that you make available for implementors by using extensible flexfields:

  • Custom grouping: Extensible flexfields enable implementors to group segments into contexts (attribute groups), and each context is displayed in its own region on a page.

  • Multiple logical pages: When an implementor defines a large number of custom attributes, the implementor can choose to create several logical pages with which to display the attribute groupings. For example, Figure 23-2 and Figure 23-4 show different logical pages for the same part. In addition, the implementors can reuse these pages with different categories.

  • Hierarchical categories: Extensible flexfields can be configured to enable categories, which can be used to dynamically display different sets of logical pages and contexts based upon a runtime discriminator. The categories can be structured in a hierarchical manner and the children categories inherit all the contexts and logical pages that are configured for their parent categories.

  • Reusable attribute groups: When you enable multiple categories for an extensible flexfield, implementors can associate contexts with more than one category. When business object instances share common attributes, the implementors can put the common attributes in one context and reuse that context in all applicable categories, thus minimizing setup time. For example, in Figure 23-2 and Figure 23-3, the Fax context is associated with both the Fax category and the All-in-One Printers category.

  • Unlimited expansion space: While the number of segments that an implementor can define for a context is limited to the number of underlying flexfield extension columns, there is no limit to the number of contexts that an implementor can create for an extensible flexfield. Implementors can use the extension columns over and over in newly created contexts resulting in an unlimited number of custom attributes.

  • Custom lists: When implementors need to add custom lists to their business objects, they can create multiple-row contexts, which display the context's segments in a table, as shown in the Certification and License Requirements region in Figure 23-1.

  • Locale-specific values: You can optionally enable implementors to store different attribute values on a locale-by-locale basis. For example, an implementor could store and maintain the description of a part in English, Chinese, and French. The application displays and stores the value for the end user's locale.

    For more information, see the "Translating Flexfield and Value Set Configurations" section in the Oracle Fusion Applications Extensibility Guide.

  • Access control. Implementors can define who can view and edit the attributes in a context.

Another advantage of using extensible flexfields is that you can create your own custom modeler classes for adding application-specific logic for generating ADF Business Components and UI task flows, as described in Section 23.9, "Customizing the Extensible Flexfield Modelers."

23.1.3 Extensible Flexfield Structure and Content

Unlike descriptive flexfields, which are mapped to extension columns in a product table, extensible flexfields are mapped to extension columns in extension tables that are separate from the product table. You create the extension tables at design time.

How Extensible Flexfields Are Modeled in Oracle Application Development Framework

Extensible flexfields are modeled as a collection of Oracle Application Development Framework (ADF) polymorphic view rows, as described in the "Working with Polymorphic View Rows" section in the Oracle Fusion Middleware Fusion Developer's Guide for Oracle Application Development Framework (Oracle Fusion Applications Edition).

The category hierarchy translates into a hierarchy of view objects that are configured to support polymorphic view rows. The view objects have view links to associated context view objects. A CategoryCode attribute acts as the discriminator that determines which category view row type should be used. At application runtime, the category in the base category view object row determines what pages and contexts are displayed. Given a collection of polymorphic view rows, each row can be a different type depending upon the category. An application module that holds the category view object is generated for each category.


Note:

Because flexfield view objects are modeled as polymorphic view objects, you can use extensible flexfield view objects in the same manner that you use any other polymorphic view objects, and they will behave in the same way.


23.2 Overview of Integrating Extensible Flexfields in an Application

The process of developing an extensible flexfield and integrating it in an application comprises several different activities, such as creating the extension tables, creating business components, and adding the flexfield to the appropriate application pages. This section identifies the major tasks for incorporating an extensible flexfield and points to the sections that provide the details for completing the tasks.

Before you begin:

Before you begin developing an extensible flexfield, you must first complete the following tasks:

  1. Identify the business object and related product table for which you are implementing the extensible flexfield. For example, you might want to enable implementors to create custom attributes for the Parts business object, which corresponds to the FND_CRM_PARTS table.

  2. Decide if you want customers to be able to store translated values for one or more segments. For example, for a Parts flexfield, customers might want to store translations for the attributes in the Catalog Information context so they can print the catalog in different languages.

  3. Decide if you want to enable customers to store the information for a context at different levels (also referred to as flexfield usages). For example, implementors might choose to set up a context for a Parts flexfield that has both a part supplier level and a part level. The same context segments appear in both the supplier UI and the part UI, but the end user would enter different values. Take, for example, a lead-time segment. At the part level, the end user would supply the average lead time. At the supplier level, the end user would enter the actual lead time required for that supplier.

  4. Decide if you need more than one set of artifacts generated for a flexfield usage. For example, you might need both private user interfaces that are based on updatable (entity-based) view objects and public user interfaces that are based on read-only view objects. When you have more than one set of artifacts, you will need to define multiple groups at the entity-usage level for the flexfield usage, such as a Private group and a Public group, when you register the flexfield's business components.

  5. Determine whether you need to customize the generated model to add additional product-specific logic or customize the generated user interface, or both.

To complete the development tasks for an extensible flexfield:

  1. Create a base extension table for each flexfield usage. If you want to enable customers to store translations on a locale-by-locale basis, create a translation extension table and a view of the translation extension table for each usage as well.

    See Section 23.3, "Creating Extensible Flexfield Data Tables."

  2. Register the extension tables as secured objects to enable implementors to specify view and edit privileges for each context's attributes.

    See Section 23.4, "Registering Extension Tables as Secured Objects."

  3. Create the flexfield metadata. In this step, you use PL/SQL procedures to register the flexfield and its usages, create a default context data element, and register the flexfield data columns and root category.

    See Section 23.5, "Defining and Registering Extensible Flexfields."

  4. Create and configure business components to support the extensible flexfield. In this step, you create an entity object and a view object from the base extension table, and, if they exist, the translation extension table and view. You then create the base category view object from the product table entity object (the table for which the flexfield is an extension). If you want to enable search capabilities, you create a declarative SQL-based view object for searching over the product table that the flexfield extends. Last, you configure the flexfield usages' application modules to support flexfields and you register the flexfield's business components.

    See Section 23.6, "Defining and Registering Extensible Flexfield Business Components."

  5. Add the extensible flexfield to the appropriate UI pages.

    See Section 23.7, "Employing an Extensible Flexfield on a User Interface Page."

  6. Load any necessary application seed data, such as error messages and lookup values.

    See Section 23.8, "Loading Seed Data."

  7. Optionally, customize the generated model or the generated UI artifacts, or both.

    See Section 23.9, "Customizing the Extensible Flexfield Modelers" and Section 23.9.2, "How to Customize the Runtime User Interface Modeler for Extensible Flexfields."

  8. Test the flexfield.

    See Section 23.10, "Testing the Flexfield."

After you have completed the extensible flexfield development process and delivered your application, implementors can use the Manage Extensible Flexfields task flow to define contexts, categories, and pages, and to configure the segments for each extensible flexfield. These task flows determine how the flexfield's segments will be populated, organized, and made available to end users within the application. For information about planning and implementing flexfield configuration, such as defining attributes, labels, behavior, and associated value sets, see the "Using Flexfields for Custom Attributes" chapter in the Oracle Fusion Applications Extensibility Guide.


Note:

An extensible flexfield is not displayed at runtime unless at least one context and context-sensitive segment has been configured and associated with a category.


To make the Manage Extensible Flexfields task flow available to application implementors, register it with Oracle Fusion Functional Setup Manager. For more information, see Section 25.5, "Integrating Flexfield Task Flows into Oracle Fusion Functional Setup Manager."

23.3 Creating Extensible Flexfield Data Tables

Before you can define an extensible flexfield, you must create one set of dedicated database tables for each of the flexfield's usages. Each set must be composed of at least a base extension table. If you want to enable customers to store translated values for the segments, the set must include a translation extension table and a view of the translation extension table.

At runtime, as end users enter attribute values for each context, the context and its segment (attribute) values are stored as a row in the base extension table if the context is not translatable, or, if the context is translatable, as rows in the translation extension table (one row per installed language). The translation extension view returns the rows in the current user locale. When an implementor creates a translatable context, the implementor can add only VARCHAR2 segments to the context.

An extensible flexfield must have at least one set of tables, which defines the primary usage. The implementors will expose only the extension columns that they require.

You must use the Database Schema Deployment Framework tools to create the tables and columns. Using these tools ensures that the table and its columns are registered in the Oracle Fusion Middleware Extensions for Applications (Applications Core) data dictionary. For more information, see Chapter 56, "Using the Database Schema Deployment Framework."


Note:

The steps in this section assume that the product table that the flexfield is extending already exists.


23.3.1 How to Create a Base Extension Table

Each flexfield usage requires a base extension table. This table stores nontranslatable contexts and their segment values. The table name should have a suffix of _B to identify it as the base extension table.

Table 23-1 lists the columns that you must include in a base extension table. You can include additional columns, such as columns that are required by product teams or application standards. For space considerations, the table shows only the first and last attribute columns for each type.

Add as many attribute columns as you consider necessary. The attribute columns can be of type VARCHAR2, NUMBER, and TIMESTAMP. Do not set scale or precision for the NUMBER columns. There are no size requirements for the VARCHAR2 columns. To avoid compatibility and interoperability problems, name the columns ATTRIBUTE_type-and-number, such as ATTRIBUTE_CHAR1 for a VARCHAR2 column, ATTRIBUTE_NUMBER1 for a NUMBER column, and ATTRIBUTE_TIMESTAMP1 for a TIMESTAMP column.

For columns of type NUMBER, you can optionally add a column named ATTRIBUTE_NUMBERn_UOM to store the unit of measure.

The primary key of the base extension table must include the EFF_LINE_ID column, the CONTEXT_CODE column, the CATEGORY_CODE column, and the columns that match the primary key columns of the product table.

Table 23-1 Extensible Flexfield Base Extension Table (_B) Specification

ColumnTypeNullable?

EFF_LINE_ID

NUMBER(18)

No

Primary key columns of the product table for which this extensible flexfield is being defined.

Same as the column in the application.

No

CONTEXT_CODE

VARCHAR2(80)

No

CATEGORY_CODE

VARCHAR2(80)

No

CREATED_BY

VARCHAR2(64)

No

CREATION_DATE

TIMESTAMP(6)

No

LAST_UPDATED_BY

VARCHAR2(64)

No

LAST_UPDATE_DATE

TIMESTAMP(6)

No

LAST_UPDATE_LOGIN

VARCHAR2(32)

Yes

ATTRIBUTE_CHAR1

VARCHAR2(150)

Yes

...



ATTRIBUTE_CHAR40

VARCHAR2(150)

Yes

ATTRIBUTE_NUMBER1

NUMBER

Yes

ATTRIBUTE_NUMBER1_UOM

VARCHAR2(9)

Yes

....



ATTRIBUTE_NUMBER20

NUMBER

Yes

ATTRIBUTE_NUMBER20_UOM

VARCHAR2(9)

Yes

ATTRIBUTE_TIMESTAMP1

TIMESTAMP

Yes

...

TIMESTAMP

Yes

ATTRIBUTE_TIMESTAMP10

TIMESTAMP

Yes


23.3.2 How to Create a Translation Extension Table

If you plan to allow customers to store translations for some contexts on a locale-by-locale basis, then you must also create a translation extension table and a single table translation view from that table. The translation extension table and the translation extension view are not required. However, if you do not provide these tables, the customers cannot store translations for their extensible flexfields as described in the "Translating Custom Text" chapter in the Oracle Fusion Applications Extensibility Guide. For more information about multilanguage tables, see Section 9.2, "Using Multi-Language Support Features." For information about creating the view, see Section 23.3.3, "How to Create a Translation Extension View."

Note that unlike typical translation tables, the base extension table is completely separate from the translation extension table. All the segment values for a context go in either the base extension table or in the translation extension table. If a context is marked as translatable, all segment values are stored in the translation extension table, otherwise they are stored in the base extension table.

Table 23-2 lists the required translation extension table columns. The required columns are similar to those in the base extension table, except that the attribute columns must be of type VARCHAR2 and you must include the LANGUAGE and SOURCE_LANG columns. For space considerations, the table shows only the first and last attribute columns. You can include additional columns, such as columns that are required by product teams or application standards.

The translation table name should have a suffix of _TL to identify it as a translation table.

The primary key of the translation extension table must include the EFF_LINE_ID column, the CONTEXT_CODE column, the CATEGORY_CODE column, the LANGUAGE column, and the columns that match the primary key columns of the product table.

Developers typically create the same number of VARCHAR2 type attribute columns in the translation extension table as exist in the base extension table, but you are not required to do so. Create as many VARCHAR2 type attribute columns as you think are necessary for a translatable context. To avoid compatibility and interoperability problems, name the columns ATTRIBUTE_CHARnumber, such as ATTRIBUTE_CHAR1, ATTRIBUTE_CHAR2, and so on. When setting the size of the VARCHAR2 columns in an extension translation table, consider that the columns might need to contain multibyte characters.

Table 23-2 Extensible Flexfield Translation Extension Table (_TL) Specification

ColumnTypeNullable?

EFF_LINE_ID

NUMBER(18)

No

Primary key columns of the product table for which this extensible flexfield is being defined.

Same as the column in the application.

No

CONTEXT_CODE

VARCHAR2(80)

No

CATEGORY_CODE

VARCHAR2(80)

No

CREATED_BY

VARCHAR2(64)

No

CREATION_DATE

TIMESTAMP(6)

No

LAST_UPDATED_BY

VARCHAR2(64)

No

LAST_UPDATE_DATE

TIMESTAMP(6)

No

LAST_UPDATE_LOGIN

VARCHAR2(32)

Yes

SOURCE_LANG

VARCHAR2(4)

No

LANGUAGE

VARCHAR2(4)

No

ATTRIBUTE_CHAR1

VARCHAR2(1000)

Yes

...

VARCHAR2(1000)

Yes

ATTRIBUTE_CHAR40

VARCHAR2(1000)

Yes



Note:

To avoid compatibility and interoperability problems, format the column names as indicated.


23.3.3 How to Create a Translation Extension View

If you create a translation extension table, you must also create a view from the translation extension table. To create the view, use a view definition statement that follows the format shown in Example 23-1. The name of the translation extension view should have a suffix of _VL.

Example 23-1 Format for Translation Extension View Definition

select ROWID ROW_ID,
column list
from translation extension table
where LANGUAGE = userenv('LANG');

Example 23-2 shows a sample view definition.

Example 23-2 Sample Translation Extension View Definition

select
ROWID ROW_ID,
EFF_LINE_ID,
CONTEXT_CODE,
CATEGORY_CODE,
ATTRIBUTE_CHAR1,
...
ATTRIBUTE_CHAR40
from MYEFF_TL
where LANGUAGE = userenv('LANG');

23.4 Registering Extension Tables as Secured Objects

You must register an extensible flexfield's extension tables as database resources to enable implementors to specify and manage access privileges for context attributes as described in the "Task: Plan Extensible Flexfield Security" section in the Oracle Fusion Applications Extensibility Guide.

You can optionally preconfigure database resource actions and conditions (instance sets) that might be useful for the customers.


Note:

When an implementor uses Oracle Authorization Policy Manager to define security policies for an extensible flexfield, the implementor must manage the privileges for both the base extension table and the view of the translation extension table as described in the "Task: Plan Extensible Flexfield Security" section in the Oracle Fusion Applications Extensibility Guide. If your application has a separate user interface for managing privileges, this user interface must manage the base extension tables and the views of the translation extension tables for all usages as separate secured objects.


23.4.1 How to Register a Table as a Secured Object

You must register an extensible flexfield's base extension table as a secured object by creating a database resource for the table. If you create a translation extension table and view for an extensible flexfield, then you must register the view as a database resource as well. Use the Manage Database Security Policies task, which is accessed from the Setup and Maintenance work area of any Oracle Fusion Setup application, to create the database resources.

You can optionally create actions and conditions for the database resource. The preconfigured actions appear in the View Privileges and Edit Privileges dropdown lists for a context's usages in the Manage Extensible Flexfields task, as described in the "Configuring Extensible Flexfields" section in the Oracle Fusion Applications Extensibility Guide. Customers use these actions to restrict view and edit privileges.

For more information about database resources, actions, and conditions for extensible flexfields, see the "Task: Plan Extensible Flexfield Security" section in the Oracle Fusion Applications Extensibility Guide.

To create a database resource:

  1. In the Setup and Maintenance work area of any Oracle Fusion Setup application, go to the Manage Database Security Policies task.

  2. From the Search Results region, select Actions > Create.

  3. Create the database resource as described in the "Managing Oracle Fusion Applications Data Security Policies" chapter in the Oracle Fusion Middleware Oracle Authorization Policy Manager Administrator's Guide (Oracle Fusion Applications Edition).


    WARNING:

    When creating a database resource for the base extension table, then you must use the name of the table for the name of the database resource, such as ITEM_EFF_B. When creating a database resource for the view of the translation extension table, then you must use the name of the view for the name of the database resource, such as ITEM_EFF_VL. Otherwise, if an implementor creates actions for that database resource and sets the privileges for an extensible flexfield's context to those actions, the end users who have those privileges will get an oracle.jbo.JboException, such as Object is not registered with Data Security, when they access a page that contains the extensible flexfield context.


  4. Ensure that the EFF_LINE_ID column is included in the primary key.

  5. Optionally, create actions and conditions for the database resource as described in the "Task: Plan Extensible Flexfield Security" section in the Oracle Fusion Applications Extensibility Guide.

23.5 Defining and Registering Extensible Flexfields

After you create a set of dedicated tables for a flexfield's usage, use procedures from the FND_FLEX_DF_SETUP_APIS PL/SQL package to register the flexfield usage and define its metadata in seed tables.

The definition of an extensible flexfield usage includes the following information:

After the implementors configure the flexfield, the definition of an extensible flexfield also contains the following information:

23.5.1 How to Register Extensible Flexfields

Use the FND_FLEX_DF_SETUP_APIS PL/SQL API package to register new extensible flexfield usages and to add the specified flexfield metadata to the following global configuration metadata:

  • FND_DF_FLEXFIELDS_B, FND_DF_FLEXFIELDS_TL

    Add the extensible flexfield's code name to both tables.

  • FND_DF_FLEX_USAGES_B, FND_DF_FLEX_USAGES_TL

    Add the extensible flexfield usages.

  • FND_DF_FLEX_USAGES_TL

    Add the display names for the flexfield usages.

  • FND_DF_TABLE_USAGES

    For each usage, add the product table name for which the flexfield is implemented and set the table type to BASE. Also, add the usage's base extension table name with a type of EXTENSION, and add the usage translation extension table name with a type of EXTENSION_TL. Set the table usage code to the flexfield's usage code.

    If the consumers want to support interface loading of extensible flexfield data, add entries for the BASE_INTERFACE, EXTENSION_INTERFACE, and EXTENSION_INTERFACE_TL table types.

  • FND_DF_SEGMENTS_B

    Add one row for the extensible flexfield with CONTEXT_CODE set to "Context Data Element" and SEGMENT_CODE set to "Context Segment."

  • FND_FF_COLUMN_USAGES

    For each usage, add an entry for each context-specific column in the EXTENSION and EXTENSION_TL tables. For example, add entries for all the ATTRIBUTE_CHARn columns, for all the ATTRIBUTE_NUMBERn columns, and so on.

  • FND_EF_CATEGORIES_B

    An extensible flexfield requires at least one entry in this table. Add additional entries only if you are shipping your application with some categories already defined.


    Note:

    The CATEGORY_CODE and PARENT_CATEGORY_CODE values are used in the flexfield's element in the XML schema for web services. You can maximize the readability of the schema by naming the codes with a leading alphabetic character followed by alphanumeric characters. The use of spaces, underscores, multibyte characters, and leading numeric characters, which are all encoded in XML schemas, make the codes in the schema element difficult to read.


After you create the flexfield's business components, you must complete the registration process by adding entity details, as described in Section 23.5.1, "How to Register Extensible Flexfields." You must have at least one entity usage per base extension table. If you require parallel sets of extensible flexfield artifacts generated for different uses (for example, public view objects and private view objects), replicate the entity usage entries with a different group name. When the business components are generated for the flexfield, a separate set of components is generated for each group name.

For more information, see the package specification.

23.6 Defining and Registering Extensible Flexfield Business Components

To incorporate an extensible flexfield into your application, you must define and configure entity objects and view objects for each set of extension tables that is defined for each flexfield usage.

Figure 23-6 shows the extensible flexfield business components for a product table. In this example, the flexfield is not translatable. The developer creates an entity object and view object from the base extension table to support contexts.

If the flexfield is translatable, the developer would also create an entity object and view object from the translation extension table and the translation extension view.

When an implementor deploys flexfield configurations, the deployment process creates the extended context entity objects, context view objects, category view objects, and category-to-context view links. Note that in this example, the C2 context is a member of two categories.

Figure 23-6 Extensible Flexfield Business Components

Extensible flexfield business components

To define an extensible flexfield business component:

  1. Create and configure extensible flexfield entity objects from the base extension table. If a translation extension table exists for the flexfield, create and configure extensible flexfield entity objects from the translation extension table and the translation table view.

  2. Configure the EFF_LINE_ID attribute for each extensible flexfield entity object as a unique ID.

  3. Create and configure flexfield view objects to support contexts, categories, and, optionally, searching.

  4. For each extensible flexfield usage, configure its application module to support extensible field usage by adding a createDetailRowIfNotExist method.

  5. Register the flexfield business components.


Tip:

After completing these steps, you can regenerate the flexfield business components programmatically at runtime to update your extensible flexfield implementation without manual intervention.

For more information, see Section 25.4, "Regenerating Flexfield Business Components Programmatically."


23.6.1 How to Create and Configure Extensible Flexfield Entity Objects

For each extensible flexfield usage, you must create entity objects from the base extension table. If you created a translation extension table and a translation extension view for a usage, you must create entity objects for them as well.

For more information about creating entity objects, see the "Creating a Business Domain Layer Using Entity Objects" chapter in the Oracle Fusion Middleware Fusion Developer's Guide for Oracle Application Development Framework (Oracle Fusion Applications Edition).


Note:

The packages in which these entity objects are created must not fall under the packages allocated for runtime-generated business components (which are specified in the adf-config.xml file and the flexfield usage metadata).


Before you begin:

  1. Create one set of dedicated extension tables per usage, as described in Section 23.3.1, "How to Create a Base Extension Table."

  2. Register the flexfield's usages as described in Section 23.5.1, "How to Register Extensible Flexfields."

  3. Ensure that the Applications Core library has been added to the data model project, as described in Section 3.3, "Adding Necessary Libraries to Your Data Model Project."

  4. Verify that at least one customization class is included in the adf-config.xml file. This serves to ensure correct application behavior. It does not matter which customization class you include.

    For information about defining the customization layers, see the "Understanding Customization Layers" section in the Oracle Fusion Applications Extensibility Guide.

23.6.1.1 Creating and Configuring an Entity Object from the Base Extension Table

For each extensible flexfield usage, use the Create Entity Object wizard to create an entity object from the base extension table that is described in Table 23-1, but apply the changes described in the following procedure to support the extensible flexfield. For information about the Create Entity Object wizard, see the "How to Create Single Entity Objects Using the Create Entity Wizard" section in the Oracle Fusion Middleware Fusion Developer's Guide for Oracle Application Development Framework (Oracle Fusion Applications Edition).

To create and configure an entity object from the base extension table: 

  1. On the Attributes page of the wizard, include only the following columns as attributes in your new entity object:

    • EFF_LINE_ID

    • OBJECT_VERSION_NUMBER

    • Primary key columns of the product table

    • CONTEXT_CODE

    • CATEGORY_CODE

    • CREATED_BY

    • CREATION_DATE

    • LAST_UPDATED_BY

    • LAST_UPDATE_DATE

    • LAST_UPDATE_LOGIN

  2. On the Attribute Settings page, do the following:

    • Set the EFF_LINE_ID attribute to be a unique primary key.

    • Set the CONTEXT_CODE attribute to be a discriminator, with a default value of 0.

  3. On the Java page, confirm that the objectnameBEOImpl entity object class to be generated extends the oracle.apps.fnd.applcore.oaext.model.OAEntityImpl class.

  4. After creating the entity object, configure all of its attributes to be hidden.

    On the UI Hints tab of the Property Inspector for each attribute, set the Display Hint property to Hide.

23.6.1.2 Creating and Configuring an Entity Object from the Translation Extension Table

If you created a translation extension table for the flexfield usage, as described in Table 23-2, use the Create Entity Object wizard to create an entity object from the translation extension table, but apply the changes described in the following procedure to support the extensible flexfield.

For more information about creating entity objects, see the "Creating a Business Domain Layer Using Entity Objects" chapter in the Oracle Fusion Middleware Fusion Developer's Guide for Oracle Application Development Framework (Oracle Fusion Applications Edition).

To create and configure an entity object from the extensible flexfield translation extension table: 

  1. On the Attributes page of the wizard, include only the following columns as attributes in your new entity object:

    • EFF_LINE_ID

    • OBJECT_VERSION_NUMBER

    • Primary key columns of the product table

    • CONTEXT_CODE

    • CATEGORY_CODE

    • SOURCE_LANG

    • LANGUAGE

    • CREATED_BY

    • CREATION_DATE

    • LAST_UPDATED_BY

    • LAST_UPDATE_DATE

    • LAST_UPDATE_LOGIN

  2. On the Attribute Settings page, do the following:

    • Set the EFF_LINE_ID attribute to be a unique primary key.

    • Set the CONTEXT_CODE attribute to be a discriminator, with a default value of 0.

  3. On the Java page, confirm that the objectnameTlEOImpl entity object class to be generated extends the oracle.apps.fnd.applcore.oaext.model.OAEntityImpl class.

  4. After creating the entity object, configure all of its attributes to be hidden.

    On the UI Hints tab of the Property Inspector for each attribute, set the Display Hint property to Hide.

  5. Configure all of the non-key attributes that are of type String to be translatable.

    On the Applications tab of the Property Inspector for each non-key, String type attribute, set the OA Translatable property to True.

23.6.1.3 Creating and Configuring an Entity Object from the Translation Extension View

If you created a translation extension table and view for the flexfield usage, use the standard wizard to create an entity object from the translation extension view that is described in Section 23.3.3, "How to Create a Translation Extension View," but apply the changes described in the following procedure to support the extensible flexfield.

To create and configure an entity object from the extensible flexfield translation extension view: 

  1. On the Attributes page of the wizard, include only the following columns as attributes in your new entity object:

    • EFF_LINE_ID

    • Primary key columns of the product table

    • CONTEXT_CODE

    • CATEGORY_CODE

  2. On the Attribute Settings page, do the following:

    • Set the EFF_LINE_ID attribute to be a unique primary key.

    • Set the CONTEXT_CODE attribute to be a discriminator, with a default value of 0.

  3. On the Java page, confirm that the objectnameVlEOImpl entity object class to be generated extends the oracle.apps.fnd.applcore.oaext.model.OAEntityImpl class.

  4. After creating the entity object, configure all of its attributes to be hidden.

    On the UI Hints tab of the Property Inspector for each attribute, set the Display Hint property to Hide.

  5. On the Applications tab of the Property Inspector for the entity object General tab, set the OA Base Table property to the name of the view underlying this entity object.

23.6.2 How to Configure the EFF_LINE_ID Attribute as a Unique ID

After you create and configure entity objects from the base extension table, translation extension table, and view of the translation extension table as described in Section 23.6.1, "How to Create and Configure Extensible Flexfield Entity Objects," you must configure the EFF_LINE_ID attribute for each entity object as a unique ID.

The Unique ID Generator provides a way for your application to generate unique IDs for entity object attributes of type BigDecimal. The unique IDs generated are also of type BigDecimal, and meet certain required criteria for uniqueness across database instances.

To configure EFF_LINE_ID as a unique ID:

  1. Create a connection to the database that contains the Unique ID Generator table called S_ROW_ID.

  2. Configure a special default-value expression for EFF_LINE_ID that will invoke the Unique ID Generator when needed.

For more information, see Section 9.6, "Using Unique ID."

23.6.3 How to Create and Configure Extensible Flexfield View Objects

For each extensible flexfield usage, use the Create View Object wizard (not the Flexfield Business Components wizard) to create the following types of view objects:

  • To support contexts for the extensible flexfield, create one view object from the base extension table entity object and, if the flexfield has a translation extension table, one view object from the translation extension view entity object.


    Note:

    No view objects are required from the translation table entity object.


  • To support categories for the flexfield, create a view object from the product table entity object for which you are developing this extensible flexfield.

  • To support searching, create declarative SQL-based view objects.

For more information about creating view objects, see the "Defining SQL Queries Using View Objects" chapter in the Oracle Fusion Middleware Fusion Developer's Guide for Oracle Application Development Framework (Oracle Fusion Applications Edition). For more information about declarative SQL-based view objects, see the "How to Create SQL-Independent View Objects with Declarative SQL Mode" section in the Oracle Fusion Middleware Fusion Developer's Guide for Oracle Application Development Framework (Oracle Fusion Applications Edition).

Before you begin:

  1. Create and configure entity objects from the base extension table, translation extension table, and view as described in Section 23.6.1, "How to Create and Configure Extensible Flexfield Entity Objects."

  2. Configure the EFF_LINE_ID attribute as a unique ID as described in Section 23.6.2, "How to Configure the EFF_LINE_ID Attribute as a Unique ID."

23.6.3.1 Creating and Configuring Context View Objects

To support contexts for an extensible flexfield usage, the usage must have a view object from its base extension table entity object. If you created a translation extension table for the usage, you must also create a view object from the translation extension view entity object.

To create and configure context view objects: 

  1. Use the Create View Object wizard to create the view objects from the base extension table entity object and, if you created a translation extension table for the usage, from the translation extension view entity object.

  2. On the Java page for each view object, ensure that the view object classes to be generated extend base classes as follows:

    • vo_nameImpl extends EFFViewObjectImpl

    • vo_nameRowImpl extends EFFViewRowImpl

    • vo_nameDefImpl extends EFFViewDefImpl

    These base classes are in the oracle.apps.fnd.applcore.oaext.model package.

23.6.3.2 Creating and Configuring the Category View Object

To support categories for the flexfield, there must be a view object from the product table entity object for which you are developing the extensible flexfield.

To create and configure the category view object: 

  1. Use the Create View Object wizard to create a view object from the product table for which you are implementing the extensible flexfield in the usual manner. For example, in Figure 23-2, the product table is the Parts table that stores the base attributes for the Parts entity, such as Part Number, Description, and Unit Cost.

    This view object must include an attribute called CategoryCode, which is used to identify the category to which each row of data belongs. This attribute must be an entity-based attribute of type VARCHAR2 with a maximum of 80 characters.

    Set the CategoryCode attribute to be a discriminator, with a default value of 0.

    You must ensure that the correct category code is returned for this attribute at runtime.

  2. Implement the following interface on the Java tab of the view object definition:

    oracle.apps.fnd.applcore.oaext.model.EFFCategoryViewObjectInterface
     
    

    Create a method called queryCategoryRowByPrimaryKey that accepts up to five primary key values and returns the correct row of the product view object as demonstrated in Example 23-3.

    For this example, the view object has a view criterion defined, which is called getItemByKey, and has bind parameters defined for two primary key attributes, which are called OrganizationIdBind and InventoryItemIdBind.

    Example 23-3 Query Category Row Method

    public Row queryCategoryRowByPrimaryKey(
      String pk1, String pk2, String pk3, 
      String pk4, String pk5)
        {
            Long invId = new Long (pk1);
            Long orgId = new Long (pk2);
     
            setWhereClauseParams(null);
            applyViewCriteria(null);
     
            ViewCriteria vc = getViewCriteria("getItemByKey");
            setNamedWhereClauseParam("OrganizationIdBind", orgId);
            setNamedWhereClauseParam("InventoryItemIdBind", invId);
    
            applyViewCriteria(vc);
            executeQuery();
            Row r = null;
            if(hasNext())
            {
              r = next();
              setCurrentRow(r);
            }
            return r;
        }
     
    

    This method queries the correct category row based on up to five primary key values passed into the method.

23.6.3.3 Creating a Declarative SQL-Based View Object to Enable Searching

To enable searching, there must be a declarative SQL-based view object for searching over the product table for which you are implementing the extensible flexfield.

To create a declarative SQL-based view object to enable searching: 

  1. Create a declarative SQL-based view object as described in the "How to Create SQL-Independent View Objects with Declarative SQL Mode" section in the Oracle Fusion Middleware Fusion Developer's Guide for Oracle Application Development Framework (Oracle Fusion Applications Edition).

  2. On the Java page, confirm that the objectnameVOImpl view object class to be generated extends the following class:

    oracle.apps.fnd.applcore.oaext.model.EFFCategoryViewObjectImpl
     
    

    The EFFCategoryViewObjectImpl class adds the additional WHERE clause that provides security.

23.6.4 How to Configure an Extensible Flexfield Application Module

To enable UI pages that contain a flexfield usage to display the flexfield's segments, you must configure an application module to support that flexfield usage.

You can use the product application module, or you can use the Create Application Module wizard to create a new application module dedicated to your extensible flexfield.

To the application module's Java client interface, add a method called createDetailRowIfNotExist, as shown in Example 23-4.

Example 23-4 Java Source for createDetailRowIfNotExist Method

public void createDetailRowIfNotExist(
  String categoryAMInstName, String categoryViewUsageName, 
  String contextViewLinkAccName, String category_pk1, 
  String category_pk2, String category_pk3, 
  String category_pk4, String category_pk5)
{
  EffCategoryAMImpl effAM = (EffCategoryAMImpl) 
    findApplicationModule(categoryAMInstName);
  effAM.createDetailRowIfNotExist(
    categoryViewUsageName, contextViewLinkAccName, 
    category_pk1, category_pk2, category_pk3, 
    category_pk4, category_pk5);
}
 

When an implementor deploys a configured extensible flexfield, an application module instance is generated for each category that the implementor defined for the flexfield. For information about deploying flexfields, see the "Deploying Flexfield Configurations" section in the Oracle Fusion Applications Extensibility Guide.

23.6.5 How to Register Extensible Flexfield Business Components

After you configure business components to support an extensible flexfield usage, you must complete the flexfield registration process by providing the names of the flexfield usage's entity object and view object. If you created a translation extension table for the flexfield usage, you must also register the entity object from the translation extension table.

You use procedures from the FND_FLEX_DF_SETUP_APIS PL/SQL package to register the flexfield usage's entity details. For information about using the procedures, see the package specification.

To register extensible flexfield entity details:

Add the flexfield metadata to the FND_DF_ADFBC_USAGES table as specified by the package specification.

For each table defined in the FND_DF_TABLE_USAGES table, specify the name of the entity object and view object. For the translation extension table, also specify the name of the entity object from the translation extension table.

If the consumers who are incorporating the flexfield into the application want to generate a different set of artifacts for both private and public groups, create an additional set of rows with a different extensible flexfield group name.

Figure 23-7 shows example entries for a flexfield usage. As described in Section 23.5.1, "How to Register Extensible Flexfields," the FND_DF_TABLE_USAGES table contains rows for the product table (USGA_BASE), the usage base extension table (USGA_EFF_B), and the usage translation extension table (USGA_EFF_TL). The FND_DF_ADFBC_USAGES table contains two entries for each entry in the FND_DF_TABLE_USAGES table — one for the Private group and one for the Public group. Each row names the entity object and the view object. The rows for the translation extension table also name the entity object from the translation extension table. Note that not all columns are shown.


Note:

In this example, the Public group is necessary because the product that is using the flexfield usage requires a parallel set of extensible flexfield artifacts generated for public view objects.

If the consumers wanted to support interface loading of extensible flexfield data, you would also add entries for the BASE_INTERFACE, EXTENSION_INTERFACE, and EXTENSION_INTERFACE_TL table types.


Figure 23-7 Example Entity Detail Entries

Example entity table details

23.7 Employing an Extensible Flexfield on a User Interface Page

You can incorporate an extensible flexfield into an application with several UI variations:


Notes:

  • If there is only one usage and only one logical page, use a single task flow that presents a set of contexts associated with a specified logical page, which is identified before the UI page initializes. Do not display a list of usages or pages on the left-hand side of the task flow.

  • If the extensible flexfield will never have more than one usage and will never have more than one logical page, and if you do not need any features that are unique to extensible flexfields as discussed in Section 23.1.2, "The Benefits of Extensible Flexfields," consider using a descriptive flexfield instead.

  • Unless you know that the extensible flexfield will contain only a small amount of information, do not embed the flexfield in the middle of a region that has other content.


For more information about task flows, see the "Creating a Task Flow" section in the Oracle Fusion Middleware Fusion Developer's Guide for Oracle Application Development Framework (Oracle Fusion Applications Edition).


Note:

When it is not clear what type of data will be configured for the extensible flexfield, name the containing region, such as a page or a dialog, "Additional Information" or "Additional Information: Object Name" for view-only data, and "Edit Additional Information" or "Edit Additional Information: Object Name" for data that can be edited. If the containing region is a tab, name the tab "Additional Information" or "Edit Additional Information," as appropriate. This convention ensures consistency across Oracle Fusion applications.


23.7.1 How to Expose the Logical Pages and Contexts Associated with One Extensible Flexfield Usage

You can incorporate an extensible flexfield into the UI as a list of the logical pages for a single usage, combined with the contexts for the selected logical page, and integrated into a single task flow.

To expose the logical pages and contexts that are associated with one extensible flexfield usage:

  1. Create a task flow for the single extensible flexfield usage, which includes a page fragment with a splitter that contains the list of the usage's logical pages on the left, and the contexts associated with the selected logical page on the right.

  2. Add the task flow to the page.

  3. Render the page.

23.7.1.1 Creating a Task Flow for a Single Extensible Flexfield Usage

Create a task flow to be added to the page that will display the page lists and contexts.

Before you begin: 

Create and configure business components to support the extensible flexfield as described in Section 23.6, "Defining and Registering Extensible Flexfield Business Components."

To create a task flow for a single extensible flexfield usage: 

  1. Create a task flow.

  2. Add a view activity for a new page fragment and designate the activity as the default activity.

  3. Add an EffCategoryPagesBean managed bean with the class oracle.apps.fnd.applcore.flex.eff.runtime.EffCategoryPagesBean to the task flow. The scope should be pageFlow.

  4. Open the fragment and drag and drop a splitter control.

  5. On the first facet, drag and drop the EffCatPageListContainer seeded task flow from the ViewController FlexModeler-View library.

  6. Add the following parameters:

    • _eff_application_id: Provide the FND_EF_UI_PAGES_B.APPLICATION_ID value; for example 10010.

    • _eff_descriptive_flexfield_code: Provide the FND_EF_UI_PAGES_B.DESCRIPTIVE_FLEXFIELD_CODE value; for example EGO_ITEM_EFF.

    • _eff_category_code: Provide the FND_EF_UI_PAGES_B.CATEGORY_CODE value; for example ELECTRONICS.

    • _eff_usage_code: Provide the FND_EF_UI_PAGES_B.FLEXFIELD_USAGE_CODE value; for example, EGO_ITEM_DL.

    • _eff_containerBean: Provide #{pageFlowScope.EffCategoryPagesBean}.

  7. On the first facet, drag and drop the EffContextsPageContainer seeded task flow from the ViewController FlexModeler-View library.

  8. Add the following parameters:

    • _eff_application_id: Provide #{pageFlowScope._eff_application_id}.

    • _eff_descriptive_flexfield_code: Provide #{pageFlowScope._eff_descriptive_flexfield_code}.

    • _eff_category_code: Provide #{pageFlowScope._eff_category_code}.

    • _eff_usage_code: Provide #{pageFlowScope._eff_usage_code}.

    • _eff_page_code: Provide #{pageFlowScope._eff_page_code}.

    • _eff_containerBean: Provide #{pageFlowScope.EffCategoryPagesBean}.

    • _eff_category_pk1: (optional) Provide the value for the category's first primary key column, if applicable. For example, if the first primary key column is INVENTORY_ITEM_ID, and its value is 149, provide 149.

    • _eff_category_pk2 - (optional) Provide the value for the category's second primary key column, if applicable. For example, if the second primary key column is ORGANIZATION_ID, and its value is 204, provide 204.

    • _eff_category_pk3 through pk5: Provide the value for that primary key column, if applicable.

23.7.1.2 Adding the Task Flow to the UI Page

Add the task flow for the extensible flexfield usage to the UI page that will display the logical page lists and contexts.

Before you begin: 

Create the task flow for the extensible usage as described in Section 23.7.1.1, "Creating a Task Flow for a Single Extensible Flexfield Usage."

To add the task flow to the page: 

  1. Open the .jspx page that will display the logical page lists and contexts.

  2. Drag and drop the task flow onto the page.

23.7.1.3 Rendering the Page

Render the page to view the UI.

Before you begin: 

To render the page: 

  1. Open the Databindings.cpx file for the project that is consuming the generated extensible flexfield task flows and add the following EFFRuntimeAM data control:

    <BC4JDataControl      id="EFFRuntimeAMDataControl"
                          Package="oracle.apps.fnd.applcore.flex.eff.
                            runtime.applicationModule"
                          FactoryClass="oracle.adf.model.bc4j.
                            DataControlFactoryImpl"
                          SupportsTransactions="true" SupportsFindMode="true"
                          SupportsRangesize="true" SupportsResetState="true"
                          SupportsSortCollection="true" Configuration=
                            "EFFRuntimeAM"
                          syncMode="Immediate"
                          xmlns="http://xmlns.oracle.com/adfm/datacontrol"/>
    
  2. Complete the following steps to mark the flexfield usage's package directory as a flexfield model package:

    1. Create an inf subdirectory in the flexfield usage's package directory. For example, if the usage's package is oracle.apps.fnd.applcore.crmdemo.flex, then create the /oracle/apps/fnd/applcore/crmdemo/flex/inf subdirectory.

    2. To identify the package directory as a flexfield model package, create a file named FlexfieldPkgInf.xml in the package's inf subdirectory and add the following contents to the file:

      <?xml version="1.0" encoding="UTF-8" ?>
      <flexfield-inf/>
      

      Note:

      Ensure that the package directory contains only the automatically generated flexfield MDS files and the inf subdirectory with the FlexfieldPkgInf.xml file. When the application is deployed, the Ant script that is run by the deployment process will add the required namespaces for the identified package directory to the adf-config file, as shown in the following example:

      <namespace path="/persdef" metadata-store-usage="mdsRepos"/>
      <namespace path="/oracle/apps/scm/productCatalogManagement/items/protectedModel/itemRevisionEff"metadata-store-usage="mdsRepos"/>
      <namespace path="oracle/apps/scm/productCatalogManagement/"items/protectedModel/itemsEffmetadata-store-usage="mdsRepos"/>
      

  3. Complete the following steps to identify the flexfield user interface packages:

    1. Either create a web application archive (WAR) deployment profile in the project that is named FlexfieldViewController and that contains flexfield user interface packages, or reference the flexfield user interface packages through a library Java archive (JAR) file. Do not include this deployment profile in the application enterprise archive (EAR) file. This is only a marker profile.

    2. Find the flexfield user interface package directory under the ViewController/public_html directory and add an inf subdirectory to the flexfield user interface package directory.

    3. To identify the package directory as a flexfield user interface package, create a file named FlexfieldViewPkgInf.xml in the package's inf subdirectory and add the following contents to the file:

      <?xml version="1.0" encoding="UTF-8" ?>
      <flexfield-inf/>
      

      Note:

      The package directory will be added to the adf-config file and thus should contain only the automatically generated flexfield MDS files and the inf subdirectory with this file.

      Do not repeat these steps for the corresponding pageDefs packages under Application Sources. Those packages are added automatically when the flexfield is deployed.


  4. Add the following code to the Application tag at the top of the Databindings.cpx file so the application will find the page definitions for the generated UI artifacts:

    PageMapClass="oracle.jbo.uicli.mom.DynamicPageMapImpl"
                 BasePageDefPackageName="pageDefs"
    
  5. Deploy and run the application to render the page.

23.7.2 How to Expose the Complete Set of an Extensible Flexfield's Usages, Logical Pages, and Associated Contexts

To expose the complete set of usages, logical pages, and associated contexts, build a UI page that includes a splitter with two task flows: one containing the list of extensible flexfield usages and their associated logical pages on the left, and the other containing the contexts associated with the selected logical page on the right.

To build the UI page: 

  1. Create a task flow for the extensible flexfield usages and a task flow for the associated contexts.

  2. Create the left and right fragment pages.

  3. Use the task flows in the UI page.

23.7.2.1 Creating the Task Flows

The UI page requires two task flows: one containing the list of extensible flexfield usages and their associated logical pages, and the other containing the contexts associated with the selected logical page.

Before you begin: 

Create and configure business components to support the extensible flexfield as described in Section 23.6, "Defining and Registering Extensible Flexfield Business Components."

To create the two task flows: 

  1. Create a page-list task flow, for example, PageListTF.

  2. Add the following parameter to the task flow:

    • Name: ContainerBean

    • Class: oracle.apps.fnd.applcore.flex.eff.runtime.EffCategoryPagesBean

    • Value: #{pageFlowScope.ContainerBean}

  3. Create the context container task flow, for example, ContextPageTF.

  4. Add a parameter that is exactly the same as the one you added in Step 2 to the task flow.

23.7.2.2 Creating the Fragments

Create a left fragment for the list of flexfield usages and a right fragment for contexts.

Before you begin: 

Create the page-list task flow and context container task flow as described in Section 23.7.2.1, "Creating the Task Flows".

To create the fragments: 

  1. Create the left and right fragment pages PageListFrag.jsff and ContextPageFrag.jsff.

  2. Add the EffCatPageListContainer seeded task flow from the ViewController FlexModeler-View library to the page list fragment using the parameters listed in Section 23.7.1.1, "Creating a Task Flow for a Single Extensible Flexfield Usage," with the exception that the value for _eff_containerBean should be pageFlowScope.ContainerBean instead of pageFlowScope.EffCategoryPagesBean.

  3. Add the EffContextsPageContainer seeded task flow from the ViewController FlexModeler-View library to the context page fragment using the parameters described in Section 23.7.1.1, "Creating a Task Flow for a Single Extensible Flexfield Usage," with the exception that the value for _eff_containerBean should be pageFlowScope.ContainerBean instead of pageFlowScope.EffCategoryPagesBean.

  4. Drag and drop the page list fragment onto the page-list task flow.

  5. Drag and drop the context page fragment onto the context task flow.

23.7.2.3 Using the Task Flows in the Page

Use the task flows that you just created in Section 23.7.1.1, "Creating a Task Flow for a Single Extensible Flexfield Usage" to add the usage and context lists to the page.

Before you begin: 

  1. Create the page-list task flow and context container task flow as described in Section 23.7.2.1, "Creating the Task Flows."

  2. Create the left and right fragment pages PageListFrag.jsff and ContextPageFrag.jsff as described in Section 23.7.2.2, "Creating the Fragments."

To use the task flows in the page: 

  1. Open the page and add the splitter.

  2. Add the page-list and context page task flows to the left and right facets of the splitter.

  3. Enter the value of pageFlowScope.EffCategoryPagesBean for the ContainerBean parameter to the task flows.

  4. Follow the steps listed in Section 23.7.1.3, "Rendering the Page" to view the user interface.

23.7.3 How to Expose One Logical Page and Its Contexts

You can incorporate an extensible flexfield into an application as a single task flow that presents a set of contexts associated with a specified logical page, which will be identified before the UI page initializes.

To expose one logical page and its contexts, build a UI page that includes a splitter with a single task flow as a dynamic region on the right, and that contains the contexts associated with the selected logical page. This variation does not present an extensible flexfield usage or page-list task flow in the user interface.

23.7.4 How to Expose One Extensible Flexfield Context

Build an application page with a single task flow as a dynamic region on the right, and containing the context that was passed. This variation does not present an extensible flexfield usage or page-list task flow in the user interface.

Before you begin:

Create and configure business components to support the extensible flexfield as described in Section 23.6, "Defining and Registering Extensible Flexfield Business Components."

To expose the extensible flexfield context:

  1. Create a task flow for Pages List, for example, PageListTF.xml.

  2. Add a managed bean called EffCategoryPagesBean to this task flow. It should have a class of pageFlowScope.EffCategoryPagesBean and a scope of pageFlow.

  3. Create a fragment, for example PageListFrag.jsff, and drag and drop the EffCatPageListContainer task flow from the ViewController FlexModeler-View library on the fragment.

  4. Add the following parameters:

    • _eff_application_id: Provide #{pageFlowScope._eff_application_id}.

    • _eff_descriptive_flexfield_code: Provide #{pageFlowScope._eff_descriptive_flexfield_code}.

    • _eff_category_code: Provide #{pageFlowScope._eff_category_code}.

    • _eff_usage_code: Provide #{pageFlowScope._eff_usage_code}.

    • _eff_page_code: Provide #{pageFlowScope._eff_page_code}.

    • _eff_containerBean: Provide #{pageFlowScope.EffCategoryPagesBean}.

  5. Place the task flow on any page on which you want the page list to appear.

  6. Create a task flow, for example, ContextsTF.xml.

  7. Add an empty fragment to this task flow, for example, ContextsFrag.jsff.

  8. Access the page on which you would like your contexts to appear. This could possibly be the same page as in Step 5, but is likely the second facet of a splitter.

  9. Drag and drop ContextsTF.xml as a dynamic region onto this page at the correct location.

  10. When prompted for a backing bean, enter a new bean name, class, and package, for example, ContextsRenderingBean.java, and allow it to remain as a backing bean.

  11. Open the Java file and add the following code, replacing the value for taskFlowId with the appropriate string:

    public class ContextsRenderingBean {
      private String taskFlowId = 
    "/WEB-INF/oracle/apps/fnd/applcore/flex/eff/runtime/ui/test/flow/ContextsTF.xml#ContextsTF";
      private String newTaskFlowId =null;
      private boolean refreshRegion = false;
    
      public ContextsRenderingBean () {
      }
    
      public TaskFlowId getDynamicTaskFlowId() {
        return TaskFlowId.parse(taskFlowId);
      }
      public boolean getRefreshRegion() {
        refreshRegion = false;
        newTaskFlowId = (String) ADFContext.getCurrent().getSessionScope().
          get("_eff_context_tf_id");
    
        if (newTaskFlowId != null && taskFlowId.compareTo(newTaskFlowId) != 0 ) {
           taskFlowId = newTaskFlowId;
           refreshRegion = true;
        }
        return refreshRegion;
      }
    }
    
  12. Open the page definition for the launch page and scroll to the location of the dynamic region binding.

  13. Add the following refresh condition setting to the taskFlow tag:

    RefreshCondition="#{backingBeanScope.ContextsRenderingBean.refreshRegion}"
    

    This setting provides the callback and the conditions for the refresh of the contexts region.

  14. Follow the steps listed in Section 23.7.1.3, "Rendering the Page" to view the user interface.

    When you run the page and click the page link, the callback to refreshRegion will look up the ID for the contexts task flow and enable a refresh condition of the dynamic region.

23.8 Loading Seed Data

Any implementation of flexfields in Oracle Fusion Applications typically requires application seed data, which is the essential data that enables flexfields to work properly in applications. Flexfield seed data can be uploaded and extracted using Seed Data Loader.

After you complete the registration process described in Section 23.5.1, "How to Register Extensible Flexfields," your flexfield seed data consists of the information that you registered for your flexfield, such as the tables and columns reserved for your flexfield. For a customer flexfield, the seed data contains only this registration data.

If your flexfield is a developer flexfield, you also serve as the implementor. In addition to the registration data, your flexfield seed data might include contexts, segments, and value sets that you have defined for your flexfield. You can use the Oracle Fusion Middleware Extensions for Applications (Applications Core) Setup application, as described in Section 25.2, "Deploying Flexfields in a Standalone WebLogic Server Environment," to configure a flexfield. For information about how to define contexts, segments, and value sets, see the "Using Flexfields for Custom Attributes" chapter in the Oracle Fusion Applications Extensibility Guide.

For information about extracting and loading seed data, see Chapter 55, "Initializing Oracle Fusion Application Data Using the Seed Data Loader."

23.9 Customizing the Extensible Flexfield Modelers

You can customize the modelers that generate the extensible flexfield business component and UI artifacts to add additional product-specific logic. For example, you might want the modeler to set a specific JavaServer Pages (JSP) Expression Language (EL) expression on a generated segment's ReadOnly property.

23.9.1 How to Customize the Runtime Business Component Modeler for Extensible Flexfields

To extend the runtime business component modeler for extensible flexfields, override the EFFBCModelerFactory.getCustomEFFBCModeler method, shown in Example 23-5, in the custom runtime business component modeler factory for extensible flexfields.

Example 23-5 getCustomEFFBCModeler Method

/**
   * Implementing teams need to override this method and provide the
   * custom BC Modeler here (for example, PIMBCModeler).
   * @param namespace the name space
   * @param flexDef the flexfield def
   * @param entityUsage the entity usage
   * @param writer the modeler writer
   * @param conf the configuration
   * @param categoryDef the category def
   * @param categoryContextDef the category context def
   * @param categoryCode the category code
   * @param contextCode the context code
   * @param appShortName the application short name
   * @param flexCode the flexfield code
   * @param connUrl the connection url
   * @param isInterface the interface flag
   * @return the custom EFF BC Modeler instance.
   */
  protected EFFBCModeler getCustomEFFBCModeler(FlexfieldNamespace namespace,
                                            FlexfieldDef flexDef,
                                            FlexfieldEntityUsage entityUsage,
                                            BCModelerWriter writer,
                                            Map<BCModeler.Option, Object> conf,
                                            CategoryDef categoryDef,
                                            CategoryContextDef categoryContextDef,
                                            String categoryCode,
                                            String contextCode,
                                            String appShortName,
                                            String flexCode,
                                            String connUrl,
                                            boolean isInterface)
  {
    return new EFFBCModeler(namespace, flexDef, entityUsage, writer, conf,
                            categoryDef, categoryContextDef, categoryCode,
                            contextCode, appShortName, flexCode, connUrl,
                            isInterface);
  }

An example of the PIMBCModelerFactory.java override for this method is shown in Example 23-6.

Example 23-6 PIMBCModelerFactory.java Override

protected EFFBCModeler getCustomEFFBCModeler(FlexfieldNamespace namespace,
                                            FlexfieldDef flexDef,
                                            FlexfieldEntityUsage entityUsage,
                                            BCModelerWriter writer,
                                            Map<BCModeler.Option, Object> conf,
                                            CategoryDef categoryDef,
                                            CategoryContextDef categoryContextDef,
                                            String categoryCode,
                                            String contextCode,
                                            String appShortName,
                                            String flexCode,
                                            String connUrl,
                                            boolean isInterface)
  {
    return new PIMBCModeler(namespace, flexDef, entityUsage, writer, conf,
                            categoryDef, categoryContextDef, categoryCode,
                            contextCode, appShortName, flexCode, connUrl,
                            isInterface);
  }

23.9.2 How to Customize the Runtime User Interface Modeler for Extensible Flexfields

If the UI artifacts that are generated for an extensible flexfield business component do not fulfill application requirements, you can create wrapper implementation classes for the framework's customizer interfaces. These wrapper implementation classes enable some control over the XML code that the modeler generates for the UI artifacts just before it persists the generated task flows and JavaServer Faces (JSF) page fragments. The implementation classes are in the oracle.apps.fnd.applcore.flex.uimodeler.customizers package.

To customize an extensible flexfield business component's generated UI artifacts:

  1. Create wrapper classes for the default customizer implementation classes.

  2. Create a wrapper of the metadata provider implementation class.

  3. Register the metadata provider wrapper class in the metadata for the flexfield's business component.

23.9.2.1 Creating the Customizer Wrapper Class

Extend the default customizer implementation classes from the oracle.apps.fnd.applcore.flex.uimodeler.customizers package to customize the following UI artifacts:

  • Context JSF fragment

  • Segment components in the generated context task flow

  • Page links in the generated links task flow

  • Page task flow

  • Search task flow

23.9.2.1.1 How to Customize the Context JSF Page Fragment

To customize the JSF page fragment for a single row context, create a wrapper class for the SingleRowContextRegionCustomizerImpl implementation class and override the customizeGeneratedSingleRowContextFragment method.

To customize the JSF page fragment for a multiple row context, create a wrapper class for the MultiRowContextRegionCustomizerImpl implementation class and override the customizeGeneratedMultiRowContextFragment method.

23.9.2.1.2 How to Customize the Segment Components in the Generated Context Task Flow

To customize which segment components in the generated context task flow will be read-only for single and multirow contexts, create a wrapper class for the ContextComponentsCustomizerImpl implementation class and override the getAtributeComponentReadonlyELExpression method. This method returns the value of the readOnly property for a given segment component in the context task flow, as shown in Example 23-7.

Example 23-7 Sample getAtributeComponentReadonlyELExpression Method

public String getAtributeComponentReadonlyELExpression(
  Transaction tx, ViewDef contextViewDef) {
        String returnData = null;
        ViewDefImpl contextViewDefImpl = (ViewDefImpl) contextViewDef;
 
        if(contextViewDefImpl.getName().toUpperCase().indexOf("RESOLUTION") >0 ) {
             returnData = "#{pageFlowScope.EFF_PARAM5=='Y'}";
        }
         return returnData;
    }
23.9.2.1.3 How to Customize the Page Links in the Generated Links Task Flow

To customize which page links in a generated links task flow will be rendered, create a wrapper class for the PageListCustomizerImpl implementation class and override the getPageLinkRenderedProperty method. This method returns the value of the rendered property for a page link.

23.9.2.1.4 How to Customize the Page Task Flow

To customize which context task flows will be rendered in a page task flow, create a wrapper class for the ContainerPageCustomizerImpl implementation class and override the getContextTFRenderedELExpression method. This method returns the value of the region tag for a context task flow.

If implementors have defined a view privilege on a context, then the application checks if the context is present in either the base or translation extension table before verifying whether the end user has view privileges for the context. By default, the application uses the primary keys of the product table plus the context code and category code to search for a matching row in the extension tables. If your application uses a different method for associating extension table rows with product table rows, you must override the prepareSqlQueryForMatchingEffLineId method in the oracle.apps.fnd.applcore.flex.eff.runtime.EffCategoryPagesBean.java class to return the search query that is to be used to find a matching row. This method takes the security object, the context code, the category code, and the category row as input parameters and it returns the query in String form.

23.9.2.1.5 How to Customize the Search Task Flow

To customize the search task flow, create a wrapper class for the SearchRegionCustomizerImpl implementation class. Table 23-3 shows the ways in which you can customize the search task flow and the methods to override to perform the customizations.

Table 23-3 Methods to OverridePI to Customize the Search Task Flow

CustomizationMethod to OverrideNotes

Set the list of actions required in the search results table.

getResultTableActionMenu

Use the ResultsTableActionMenu inner class to define the menu properties and entries.

Set the managed bean for the generated task flow.

getSearchManagedBeanClass

The manage bean must extend oracle.apps.fnd.applcore.flex.eff.search.ui.bean.DefaultEffSearchManagedBean.

Alter properties in the product table component for search results.

getApplicationsTablePropertiesMap

This method returns a hashmap of name-value pairs of the properties to be set.

Alter properties in the ADF Table that is in the product table component for search results.

getADFTablePropertiesMap

This method returns a hashmap of name-value pairs of the properties to be set, as shown in Example 23-8.

Customize the query panel properties.

getQueryPanelPropertiesMap

This method returns a hashmap of name-value pairs of the properties.

Get a handle to the document object model (DOM) object of the generated search region and its pageDef.

customizeGeneratedSearchTaskflowRegion

Use DOM objects to customize generated artifacts only if there is no other way to perform for the customization.

Customize the readOnly property for a component in search results table column.

getResultsTableColumnComponentReadOnlyELExpression

This method returns a JSP EL expression.

Customize the properties on the search results table column for an attributeDef.

getResultsTableColumnPropertiesMap

This method returns a hashmap of name-value pairs of the properties.

Set the task flow data control scope to shared.

getSearchTaskFlowDataControlScope

The task flow can be generated with either a SHARED scope or an ISOLATED scope. The default is ISOLATED. Override this method to set the scope to SHARED.

Add custom toolbar components.

getAdditionalToolbarComponentDefinitions

Use the AdditionalToolbarComponentDefinition inner class to provide metadata for the required component. You can add components of type CHOICELIST, BUTTON, SPACER, and SEPARATOR.

Set the default search criteria on the search page as it is loaded.

getDefaultSearchCriteriaName

NA.

Customize the generated search task flow XML.

customizeGeneratedSearchTaskflow

This method returns a handle to the DOM object for the generated task flow XML. You should use DOM objects to customize generated artifacts only if there is no other way to perform the customization.


Example 23-8 Sample getADFTablePropertiesMap Method

public HashMap getADFTablePropertiesMap()
    {
        HashMap propertiesMap = new HashMap(10);
        propertiesMap.put("filterVisible","false");
        propertiesMap.put("columnStretching","column:description");
        propertiesMap.put("inlineStyle","width:100%;");
        return propertiesMap;
    }
23.9.2.1.6 How to Create a Metadata Provider Implementation Class

If you have created customizer wrapper classes for a flexfield business component, you must create a wrapper of the default UIModelerMetadataProviderImpl implementation class for that business component. This class is in the oracle.apps.fnd.applcore.flex.uimodeler package.

Override the appropriate methods in the following list to return the names of the custom wrapper classes. For example, if you created a custom wrapper class to customize the search task flow, you would override the getSearchRegionCustomizerClassName method, as shown in Example 23-9. Override only the methods that correspond to the classes for which you have created custom wrappers. In the case of a SearchRegionCustomizerImpl custom wrapper, the method that you override depends on whether the wrapper customizes the interface search UI or the regular search UI. If the wrapper customizes the interface search UI, override the getInterfaceSearchRegionCustomizer method. Otherwise, override the getSearchRegionCustomizerClassName method.

  • getContextComponentCustomizerClassName

  • getContainerPageCustomizerClassName

  • getPageListCustomizerClassName

  • getSearchRegionCustomizerClassName

  • getInterfaceSearchRegionCustomizer

  • getSingleRowContextRegionCustomizerClassName

  • getMultiRowContextRegionCustomizerClassName

Example 23-9 Sample getSearchRegionCustomizerClassName Method

public String getSearchRegionCustomizerClassName() {
        return "oracle.apps.myProduct.myApp.items.eff.ItemSearchRegionCustomizer";
    }
23.9.2.1.7 How to Register the Metadata Provider Class for the Business Component

For the user interface modeler to use your custom wrapper classes at runtime, you must register the metadata provider class. To register the class, set the ADFUI_MODELER column for the business component's row in the FND_DF_FLEXFIELDS_B table to the name of the UIMetadataProviderImpl implementation class that you created for the business component.

23.10 Testing the Flexfield

After implementing a flexfield, you can define seed or test value sets for the flexfield, and you can create a model that you can use to test it. For more information, see Section 25.1.2, "How to Test Flexfields."

23.11 Accessing Information About Extensible Flexfield Business Components

The consumers of an extensible flexfield might need to programmatically access an extensible flexfield, for instance, to further process the data that has been entered for an extensible flexfield, to add additional validation, or to perform change control. The oracle.apps.fnd.applcore.flex.runtime.util.common.ExtensibleFlexfieldUtil package provides methods for obtaining the handles to the artifacts that are generated in a customer's instance.

23.11.1 How to Access Information About Extensible Flexfield Business Components

Use the methods in oracle.apps.fnd.applcore.flex.runtime.util.common.ExtensibleFlexfieldUtil to get the names of the following Java business objects (JBOs) that are generated for an extensible flexfield:

  • Context entity object: Use getContextEoName, which is shown in Example 23-10.

  • Context view object: Use getContextVoName, which is shown in Example 23-11.

  • Context entity association between base and extension entity objects: Use getCategoryContextAssocName, which is shown in Example 23-12.

  • Context entity/view object attribute for a given segment code: Use getContextAttributeName, which is shown in Example 23-13.

  • Categories: Use the various methods shown in Example 23-14.

  • Search view object attributes: Use getSearchVoAttributeNames, which is shown in Example 23-15.

Example 23-10 Method to Get EFF Context Entity Object Name

/**
   * @param appId - application id
   * @param flexCode - flexfield code (e.g. EGO_ITEM_UDA)
   * @param flexUsageCode - flexfield usage code (e.g. EGO_ITEM_DL)
   * @param txn - DB transaction
   * @param contextCode - context code (e.g Voltage)
   * @param tableType - table type (e.g. EXTENSION)
   * @param effGroup - eff grouping entity name (public / private)
   * @return
   */
  public static String getContextEoName(Long appId, String flexCode,
                                        String flexUsageCode,
                                        DBTransaction txn,
                                        String contextCode,
                                        String tableType,
                                        String effGroup)

Example 23-11 Method to Get EFF Context View Object Name

/**
   * @param appId - application id
   * @param flexCode - flexfield code (e.g. EGO_ITEM_UDA)
   * @param flexUsageCode - flexfield usage code (e.g. EGO_ITEM_DL)
   * @param txn - DB transaction
   * @param contextCode - context code (e.g Voltage)
   * @param tableType - table type (e.g. EXTENSION)
   * @param effGroup - eff grouping entity name (public / private)
   * @return
   */
  public static String getContextVoName(Long appId, String flexCode,
                                        String flexUsageCode,
                                        DBTransaction txn,
                                        String contextCode,
                                        String tableType,
                                        String effGroup)

Example 23-12 Method to Get Name for EFF Context Entity Association Between Base and Extension Entity Objects

 /**
   * @param appId - application id
   * @param flexCode - flexfield code (e.g. EGO_ITEM_UDA)
   * @param flexUsageCode - flexfield usage code (e.g. EGO_ITEM_DL)
   * @param txn - DB transaction
   * @param contextCode - context code (e.g Voltage)
   * @param tableType - table type (e.g. EXTENSION)
   * @param effGroup - eff grouping entity name (public / private)
   * @return
   */
  public static String getCategoryContextAssocName(Long appId, String flexCode,
                                                   String flexUsageCode,
                                                   DBTransaction txn,
                                                   String contextCode,
                                                   String tableType,
                                                   String effGroup)

Example 23-13 Method to Get Attribute Name for EFF Context Entity/View Object Given Segment Code (FND_DF_SEGMENTS_VL.SEGMENT_CODE)

/**
   * Get the attribute name for the EFF context view
   * object / entity object given the segment code.
   * @param segmentCode - segment code for attribute name.
   * @return attribute name
   */
  public static String getContextAttributeName(String segmentCode)

Example 23-14 EFF Category Methods

public static String getCategoryAmNameForWebServices()
public static String getCategoryAmNameForDataEntry()
public static String getCategoryAmNameForInterfaceGeneric()
public static String getCategoryAmNameForInterfaceCategory()
public static String getCategoryAmNameForSearchGeneric()
public static String getCategoryAmNameForSearchCategory()
public static String getCategoryVoNameForDataEntry()
public static String getCategoryVoNameForWebServices()
public static String getCategoryVoNameForInterfaceGeneric()
public static String getCategoryVoNameForInterfaceCategory()
public static String getCategoryContextViewLinkNameForInterfaceGeneric()
public static String getCategoryContextViewLinkNameForInterfaceCategory()
public static String getCategoryContextViewLinkNameForSearchCategory()
public static String getCategoryContextViewLinkNameForSearchGeneric()
public static String getCategoryContextViewLinkNameForWebService()
public static String getCategoryContextViewLinkNameForDataEntry()
public static void useServiceProvider()
public static String getCategoryVoNameForSearchCategory()
public static String getCategoryVoNameForSearchGeneric()

Example 23-15 Method to Get Hash Map of View Object Attribute Names for EFF Search View Object

/**
   * Get a map of segment codes to search view object attribute names
   * @param flexUsageCode - flexfield usage code (e.g. EGO_ITEM_DL)
   * @param contextCode - context code (e.g Voltage)
   * @param segmentCodeList - segment codes for the map.
   * @return map of attribute names with key of segment codes
   */
  public static HashMap<String, String> getSearchVoAttributeNames( 
                                               String flexUsageCode,
                                               String contextCode,
                                               ArrayList<String> segmentCodeList)
PKbiIPIPK BOEBPS/uc_plsqlevent_soa.htmN> Initiating a SOA Composite from a PL/SQL Stored Procedure

33 Initiating a SOA Composite from a PL/SQL Stored Procedure

This chapter describes what a PL/SQL stored procedure needs to do to initiate a SOA composite application.

When to implement:.When a PL/SQL stored procedure needs to initiate a SOA composite application.

Design Pattern Summary: A PL/SQL stored procedure raises an event through the Event Delivery Network within the database. A mediator in the SOA composite application subscribes to the event and routes it as appropriate.

Involved components:

33.1 Introduction to the Recommended Design Pattern

Oracle Fusion applications may contain stored procedures that need to invoke a component within a SOA composite application, such as a BPEL process service component. A stored procedure can use the Event Delivery Network database API to publish an event whose payload is xmltype. An Oracle Mediator service component subscribes to the event by event name or by using a XPath expression on the event payload. The.edl file (event definition file) for the event can be supplied in the composite or deployed separately in a MAR (metadata archive). When the stored procedure publishes the event, the subscribed Oracle Mediator service component forwards the payload to the BPEL process service component.

This chapter explains how to implement the recommended approach.

33.2 Other Approaches

Instead of using an event to invoke an Oracle Mediator service component from a PL/SQL stored procedure, you could use one of the following implementations.


WARNING:

This approach is prohibited.


33.3 Example

The sample code for this use case can be downloaded from Oracle SOA Suite samples.

33.4 How to Invoke a SOA Composite Application Component Using PL/SQL

To invoke a SOA composite application component from a stored procedure, you must first create the event within the SOA composite application. The stored procedure must then raise the event and pass any required data via the EDN database API.

To invoke a SOA composite application component using PL/SQL:

  1. Create a SOA composite application with an Oracle Mediator component.

  2. Configure Oracle Mediator to subscribe to a new event (with a name of your choosing).

    The event filter can be by event name or using an XPath expression on the event payload and the EDL for the event can either be supplied in the composite.xml or deployed separately in a MAR.

  3. Create the SOA composite application component that will be invoked (for example, a BPEL process service component), and create a wire between the Oracle Mediator component reference and the component service.

  4. From a PL/SQL stored procedure, call the EDN-DB API method publish_event with the event namespace and the event payload as a CLOB type. An example is shown in Example 33-1.

    Example 33-1 Calling the publish_event Method

    DECLARE
      NAMESPACE VARCHAR2(200);
      LOCAL_NAME VARCHAR2(200);
      PAYLOAD CLOB;
    BEGIN
      NAMESPACE := 'http://xmlns.oracle.com/SubEventMediator/EventDefinition1';
      LOCAL_NAME := 'CustomerEvent';
      PAYLOAD := to_clob('<eb:business-event xmlns:eb=
       "http://oracle.com/fabric/businessEvent"
       xmlns:ob="http://xmlns.oracle.com/SubEventMediator/EventDefinition1">
       <eb:name>ob:CustomerEvent</eb:name><eb:content><CU:CustomerData
       xmlns:CU="http://xmlns.oracle.com/Esb/CustomerData"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
       <CustomerId>A22-9AXC2</CustomerId><CustomerName>
       Deserae International</CustomerName><Type>Gold</Type><Description>Accounting
       Outsourcing Partner</Description><Address>3228 Massilon Blvd</Address>
       <City>Juniper</City><State>Massachusetts</State><Zip>01854</Zip><Country>US
       </Country><Phone>877-555-9876</Phone><Status>Active</Status>
       <CreditRating>5</CreditRating><Discount>0</Discount><Terms>30n4</Terms>
       <EnrollDate>01/1/01</EnrollDate><LastOrderDate>05/05/05/</LastOrderDate>
       <Currency>USD</Currency><ContactName>Jan Forester</ContactName><ContactTitle>VP
       Finance</ContactTitle><ContactPhone>877-555-9000</ContactPhone><AccountRep>
       Geoff Seattle</AccountRep><CampaignRating>2</CampaignRating>
       <ReferedBy>Houston America Taxco</ReferedBy>
       </CU:CustomerData></eb:content></eb:business-event>');
     
      EDN_PUBLISH_EVENT( NAMESPACE => NAMESPACE, LOCAL_NAME => LOCAL_NAME, PAYLOAD => PAYLOAD);
    END;
    

33.5 Securing the Design Pattern

Secure Oracle Mediator by configuring the property runAsRoles=$publisher. For details on securing the Oracle Mediator, see Section 32.6, "Securing the Design Pattern."

When the database connection is established from the middle tier so as to invoke the PL/SQL stored procedure, a session is established with the appropriate identity. This identity is propagated through EDN back to the middle tier for the subscription. The subscription runs as the identity of the publisher.

To secure this pattern, follow the instructions described in Chapter 50, "Securing Web Services Use Cases."

33.6 Verifying the Deployment

Verifying the deployment involves the following:

33.6.1 Testing and Deploying the Use Case

Testing and deploying the use case involves the following main steps:

  1. Test your Oracle ADF application using various testing and debugging methods described in the chapter "Testing and Debugging ADF Components" of the Oracle Fusion Middleware Fusion Developer's Guide for Oracle Application Development Framework (Oracle Fusion Applications Edition). For information about testing the ADF Business Components service, see the chapter "Integrating Web Services Into a Fusion Web Application" in the Oracle Fusion Middleware Fusion Developer's Guide for Oracle Application Development Framework (Oracle Fusion Applications Edition).

  2. Deploy the SOA composite application to the standalone WLS where the SOA infrastructure has been installed. Because you created a published event from the SOA composite application to the ADF Business Components service, the ADF Business Components service need not to also be deployed to the SOA infrastructure.

  3. Test the deployed SOA composite service using Oracle Enterprise Manager Fusion Middleware Control Console. Every deployed service has its own test page, so you can quickly test that the service functions as you expect. For more information about using the Fusion Middleware Control Console to test deployed SOA composite applications, see the following chapter:

    "Automating Testing SOA Composite Applications" in the Oracle Fusion Middleware Developer's Guide for Oracle SOA Suite.

33.6.2 Verifying the SOA Composite Deployment Using Oracle Enterprise Manager Fusion Middleware Control Console

You can use Oracle Enterprise Manager Fusion Middleware Control Console to verify that the SOA composite was successfully deployed. In Oracle Enterprise Manager Fusion Middleware Control Console, you can select the SOA composite instance and display the result of the event.

Using Oracle Enterprise Manager Fusion Middleware Control Console, you can:

  • Verify the deployment of the SOA composite.

  • Test the SOA composite.

  • Verify the SOA composite test results.

To verify that the SOA composite was successfully deployed and the event was received:

  1. Using a web browser, access the Oracle Enterprise Manager Fusion Middleware Control Console using a URL such as the following:

    http://<host name>:<port number>/em
    
  2. From the list of applications, expand the PLSQLEvent composite.

  3. In the Last 5 Instances pane, click the most recent instance as shown in Figure 33-1.

    Figure 33-1 Finding the Latest PLSQLEvent Composite Instance

    Finding the latest PLSQL event composite instance.
  4. In the Flow Trace window that displays, click the Oracle Mediator component, as shown in Figure 33-2.

    Figure 33-2 The Flow Trace Window

    The Flow Trace window.

    A window displays, showing the event results, as shown in Figure 33-3.

    Figure 33-3 Displaying the Event

    Displaying event.

33.7 Troubleshooting the Use Case

Following are tips that may help resolve common issues that arise when developing or running this use case.

33.8 What You May Need to Know About Initiating a SOA Composite from a PL/SQL Stored Procedure

Before you implement these design patterns, be aware of the following:

33.9 Known Issues and Workarounds

Following are known issues:

PK;PS>N>PK BOEBPS/uc_async_dynamic.htm Implementing an Asynchronous Service Initiation with Dynamic UI Update

42 Implementing an Asynchronous Service Initiation with Dynamic UI Update

This chapter describes what to do when initiating asynchronous or long-running functionality from an Oracle ADF UI and, on completion, notifying users of the completion of that process by dynamically updating the UI. This provides a more dynamic experience for the end user and eliminates the need to constantly click a refresh button.


Notes:

  • To date, the only supported Oracle ADF UI components for Active Data Service (ADS) update are outputText and image.

  • This pattern is in the process of being re-written for conformance to Oracle WebLogic Server and Oracle Java Messaging Service (JMS) guidance and, in the interim, should be implemented with the understanding that a re-write is pending.


When to implement: When initiating asynchronous or long-running functionality from an Oracle ADF UI and, on completion, notifying users of the completion of that process by dynamically updating the UI. This provides a more dynamic experience for the end user and eliminates the need to constantly click a refresh button.

Design Pattern Summary: Oracle ADF UI registers an Active Data control subscriber on top of a JMS queue. The Oracle ADF UI then raises a business event either via the default CRUD operations on the entity or programmatically via Java. This event initiates a BPEL process that performs work and, when completed, invokes a synchronous ADF Business Components service method to trigger pushing the message on the JMS queue, which then causes the Active Data Service control to refresh the component or area of the component.

Involved components:

42.1 Introduction to the Recommended Design Pattern

Asynchronous services cannot be invoked from Java code in Oracle Fusion applications. When notification of completion of asynchronous, long-running functionality is required in a UI, business events can be used for asynchrony. In addition, ADS triggered over JMS will cause the UI update when the BPEL process completes and invokes the ADF Business Components service to signal its completion.

This approach is recommended because supported technology is used. The approach also supports dynamic page updates if the user navigates away and later returns.

42.2 Potential Approaches

Other than the Oracle ADF UI > Event > BPEL > ADF Business Components > ADS approach, following are the potential approaches:

42.3 Example

The following is an example that illustrates the design pattern.

In an order workbench, an end user selects an order and submits it to a scheduling system for fulfillment. The scheduling system services take several seconds to several minutes to acknowledge scheduling and when the user clicks the button to initiate the scheduling process, needs to be notified in the UI upon successful scheduling for fulfillment without the need to repeatedly refresh the page by hand.

In this implementation, entering the UI data and clicking Schedule programmatically raises a business event, initiates a BPEL process which goes through processing and approvals as needed, then finally invokes an order ADF Business Components service to complete the process and publish the JMS message to trigger the ADS UI update.

42.4 How to Implement an Asynchronous Service Initiation with Dynamic UI Update

To enable the UI for dynamic update via ADS, you must first create the ADS handler, which uses a common set of JMS Queue handlers to broker the updates coming from the call to ADF Business Components services.

The main steps are as follows, as shown in Figure 42-1:

  1. A business event is raised to initiate BPEL, which can perform work asynchronously.

  2. The BPEL process updates the database and submits Oracle Enterprise Scheduler jobs.

  3. At the end of the BPEL process, a web service is invoked to publish the message.

  4. The web service publishes the message to JMS.

  5. JMS delivers the message to the ActiveDataCollectionModel.

  6. The ActiveDataCollectionModel decodes the message and updates the UI.

Figure 42-1 Technology Flow Diagram (with Optional Oracle Enterprise Scheduler Job Submission)

Technology Flow Diagram

Prerequisites (for Prototyping Only)

Create the JMS queue in your development environment. Use the prototype common library to build this functionality into your application with minimal changes once the dependent functionality is consumed by the infrastructure.

For prototyping only, take the following steps to set up JMS using Oracle WebLogic Server Console:


Note:

This procedure assumes that the JMS Module does not already exist.


  1. In the Oracle WebLogic Server Console, navigate to Messaging > JMS Modules.

  2. Click New to create the JMS Module.

  3. Name the module "FusionAppsADSJMSModule" and click Next.

  4. In the Targets panel, choose the AdminServer target and click Next.

  5. Choose "Would you like to add resources to this JMS system module?" and click Finish.

  6. In the Summary of Resources table, click New.

  7. Choose Connection Factory and click Next.

  8. Name the connection factory FusionAppsADSJMSConnectionFactory, provide the JNDI name jms/Prototype/MyQueueConnFactory, and click Next.

  9. Click Finish.

  10. Verify the new connection factory in the Summary of Resources table and click New.

  11. Choose Queue and click Next.

  12. Name the queue FusionAppsADSJMSQueue, provide the JNDI name jms/Prototype/MyQueue and click Finish.

42.4.1 Writing the Active Data Handler

The classes shown in Example 42-1, Example 42-2, and Example 42-3 are common to every implementation of this pattern, and are responsible for handling JMS integration with ADS supported events.

Example 42-1 DemoDataChangeEntry.java

package ads.demo.common;

import java.io.Serializable;

public class DemoDataChangeEntry implements Serializable {
    public enum ChangeType
    {
        /**
         * Indicates the change is row value updates
         */
        UPDATE,

        /**
         * Indicates the change is a new row insertion
         */
        INSERT,

        /**
         * Indicates the change is a new row insertion before a row
         */
        INSERT_BEFORE,

        /**
         * Indicates the change is a new row insertion after a row
         */
        INSERT_AFTER,

        /**
         * Indicates the change is a new row insertion inside a parent
         */
        INSERT_INSIDE,

        /**
         * Indicates the change is row deletion
         */
        REMOVE,

        /**
         * Indicates the change is range refresh
         */
        REFRESH
    }
    public DemoDataChangeEntry() {
       super();
    }

    public DemoDataChangeEntry(Object[] pk, ChangeType type,
                             String[] attributes, Object[] values) {
         _pk = pk;
         _type = type;
         _attributes = attributes;
         _values = values;
    }
   
    private Object[] _pk;
    private ChangeType _type;
    private String[] _attributes;
    private Object[] _values;
 
    public Object[] getPk() {
        return _pk;
    }
 
    public ChangeType getType() {
        return _type;
    }
 
    public String[] getAttributes() {
        return _attributes;
    }
 
    public Object[] getValues() {
        return _values;
    }
 
    public void setPk(Object[] _pk) {
        this._pk = _pk;
    }
 
    public void setType(ChangeType _type) {
        this._type = _type;
    }

    public void setAttributes(String[] _attributes) {
        this._attributes = _attributes;
    }
 
    public void setValues(Object[] _values) {
        this._values = _values;
    }
}

Example 42-2 DemoDataUpdateEvent.java

package ads.demo.common;
 
import java.io.Serializable;
 
import java.util.List;
 
public class DemoDataUpdateEvent implements Serializable {
    public DemoDataUpdateEvent() {
    }
   
    public DemoDataUpdateEvent(List<DemoDataChangeEntry> entries) {
        _entries = entries;
    }
    private List<DemoDataChangeEntry> _entries;
 
    public List<DemoDataChangeEntry> getEntries() {
        return _entries;
    }
 
    public void setEntries(List<DemoDataChangeEntry> _entries) {
        this._entries = _entries;
    }
}

Example 42-3 JMSHelper.java

package ads.demo.common;
 
import java.util.Hashtable;
 
 
import javax.jms.JMSException;
import javax.jms.MessageListener;
import javax.jms.ObjectMessage;
import javax.jms.Queue;
import javax.jms.QueueConnection;
import javax.jms.QueueConnectionFactory;
 
import javax.jms.QueueReceiver;
import javax.jms.QueueSender;
import javax.jms.QueueSession;
 
import javax.jms.Session;
 
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
 
public final class JMSHelper {
    private  static JMSHelper _instance = new JMSHelper();
    public static JMSHelper getInstance() {
        return _instance;
    }
   
    public ObjectMessage createObjectMessage() throws JMSException {
            return qsession.createObjectMessage();
    }
   
    public void sendMessage(ObjectMessage message) throws JMSException {
            qsender.send(message);
    }
   
    public QueueReceiver createQueueReceiver(MessageListener listener, 
      String messageFilter) throws JMSException {
        QueueReceiver qreceiver = qsession.createReceiver(queue, messageFilter);
        qreceiver.setMessageListener(listener);
        return qreceiver;       
    }
   
    private JMSHelper() {
        try {
            init();
            } catch (Exception e) {
                e.printStackTrace();
            }
    }
       
    // Defines the JMS context factory.
    private final static String JMS_QUEUE_FACTORY=
     "jms/Prototype/MyQueueConnFactory";
 
    // Defines the queue.
    private final static String ADS_QUEUE="jms/Prototype/MyQueue";
 
    private QueueConnectionFactory qconFactory;
    private QueueConnection qcon;
    private QueueSession qsession;
    private QueueSender qsender;
    private Queue queue;
 
    /**
     * Creates all the necessary objects for sending
     * messages to a JMS queue.
     *
     * @param ctx JNDI initial context
     * @param queueName name of queue
     * @exception NamingException if operation cannot be performed
     * @exception JMSException if JMS fails to initialize due to internal error
     */
    private void init()
      throws NamingException, JMSException
    {
      InitialContext ctx = new InitialContext();
      qconFactory = (QueueConnectionFactory) ctx.lookup(JMS_QUEUE_FACTORY);
      qcon = qconFactory.createQueueConnection();
      qsession = qcon.createQueueSession(false, Session.AUTO_ACKNOWLEDGE);
      queue = (Queue) ctx.lookup(ADS_QUEUE);
      qsender = qsession.createSender(queue);
      qcon.start();
    }
 
    /**
     * Closes JMS objects.
     * @exception JMSException if JMS fails to close objects due to internal error
     */
    private void close() throws JMSException {
      qsender.close();
      qsession.close();
      qcon.close();
    }
 
}

To implement the Active Data Collection Model:

The Active Data Collection Model, driven by the ADS infrastructure, manages the messages coming from the queue and propagates them to the UI as Oracle ADF Rich Events. Implement the Active Data Collection Model by extending the CollectionModel class in the org.apache.myfaces.trinidad.model package and overriding the startActiveData, stopActiveData and onMessage methods. The class must implement ActiveDataModel and MessageListener as the onMessage method accepts JMS messages (which is a list of update events) and runs them through the active data listener.


Note:

Instead of implementing all the logic for CollectionModel, delegate to the collection model returned by the tree binding.


What you need to know before you begin:

  • The following methods must be implemented for ActiveDataModel:

    • getActiveDataPolicy() always returns ActiveDataPolicy.ACTIVE;

    • startActiveData(Collection<Object> rowKeys, int startChangeCount, ActiveDataListener listener) is where you create a queue receiver of the topic subscriber in JMS. If you are not using JMS, this is where you register yourself with the event source as listener.

    • stopActiveDate(Collection<Object> rowKeys, ActiveDataListener listener) removes the queue receiver of the topic subscriber in JMS.

    • getCurrentChangeCount(): ADS expects the events to arrive in order. Keep a counter in the JavaBean, so that the counter increments when a new event is pushed.

  • For ActiveDataCollectionModel to be the queue receiver or topic subscriber, ActiveDataCollectionModel must implement the MessageListener interface using the onMessage method. Do the following:

    1. Get the payload from the message. It should be DataUpdateEvent.

    2. Convert DataUpdateEvent to ActiveDataEvent. so that ADS can process the event.

    3. Deliver ActiveDataEvent to ADS.

Example 42-4 shows a collection model returned by a tree binding.

Example 42-4 Collection Model Returned by Tree Binding

package ads.demo.view;
import ads.demo.common.DemoDataChangeEntry;
import ads.demo.common.DemoDataUpdateEvent;
import ads.demo.common.JMSHelper;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageListener;
import javax.jms.ObjectMessage;
import javax.jms.QueueReceiver;
import oracle.adf.model.binding.DCBindingContainer;
import oracle.adf.model.binding.DCIteratorBinding;
import oracle.adf.share.ADFContext;
import oracle.adf.view.rich.event.ActiveDataEntry;
import oracle.adf.view.rich.event.ActiveDataListener;
import oracle.adf.view.rich.event.ActiveDataUpdateEvent;
import oracle.adf.view.rich.model.ActiveDataModel;
import oracle.adfinternal.view.faces.model.binding.FacesCtrlHierBinding;
import oracle.jbo.Key;
import org.apache.myfaces.trinidad.model.CollectionModel;
...

public class ActiveDataCollectionModel extends CollectionModel implements ActiveDataModel,
...
    public void startActiveData(Collection<Object> rowKeys,
                                int startChangeCount,
                                ActiveDataListener listener) {
        _listeners.add(listener);
        _currEventId = startChangeCount;
        if (_listeners.size() == 1) {
            // register as receiver for JMS Queue, listening to change event
            try {
                String messageFilter = "JMSCorrelationID = '" + getUuid() + "'";
                qreceiver = JMSHelper.getInstance().createQueueReceiver(this,
                            messageFilter);
            } catch (Exception e) {
                e.printStackTrace();
            }


        }
    }
    public void stopActiveData(Collection<Object> rowKeys,
                               ActiveDataListener listener) {
        _listeners.remove(listener);
        if (_listeners.isEmpty()) {
            // clean JMS
            try {
                qreceiver.close();
            } catch (JMSException e) {
                e.printStackTrace();
            }
        }
    }
    public int getCurrentChangeCount() {
        return _currEventId;
    }
    public void onMessage(Message message) {
        try {
            DemoDataUpdateEvent myEvent = null;
            if (message instanceof ObjectMessage) {
                myEvent =
                        (DemoDataUpdateEvent)((ObjectMessage)message).getObject();
                // Convert the event to ADS DataChangeEvent
            }
            List<ActiveDataEntry> dces = new ArrayList<ActiveDataEntry>(1);
            for (DemoDataChangeEntry entry : myEvent.getEntries()) {
                oracle.jbo.Key jboKey = new Key(entry.getPk());
                ActiveDataEntry.ChangeType newType = convertChangeType(entry.getType());
                Object[] path = new Object[] { Collections.singletonList(jboKey) };
                ActiveDataEntry dce =
                    new DemoActiveDataEntry(newType, path,
                                            new Object[0],
                                            entry.getAttributes(),
                                            entry.getValues());
                dces.add(dce);
            }
            _currEventId++;
            ActiveDataUpdateEvent event = new DemoActiveDataUpdateEvent(new Object(), _currEventId, 
                                              dces);
            _refreshControl = true;
           
            // Deliver event
            for (ActiveDataListener listener : _listeners) {
                try {
                    listener.dataChanged(event);
                } catch (Throwable e) {
                    e.printStackTrace();
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    private int _currEventId = 0;
    private final List<ActiveDataListener> _listeners =
        new LinkedList<ActiveDataListener>();
    private boolean _refreshControl = false;
    private String _treeBindingName;
    private String _iterBindingName;
    private ActiveDataEntry.ChangeType         convertChangeType(DemoDataChangeEntry.ChangeType
        type) {
        if (type == DemoDataChangeEntry.ChangeType.UPDATE) {
            return ActiveDataEntry.ChangeType.UPDATE;
        } else if (type == DemoDataChangeEntry.ChangeType.REFRESH) {
            return ActiveDataEntry.ChangeType.REFRESH;
        } else {
            return ActiveDataEntry.ChangeType.UPDATE;
        }
       
        // Return ActiveDataEntry.ChangeType.UPDATE;
    }
    private CollectionModel getModel() {
        CollectionModel cm =
            (CollectionModel)ADFContext.getCurrent().getRequestScope().get("collectionModel_" +
                                                                           this.hashCode());
        DCBindingContainer bindings =
            (DCBindingContainer)ADFContext.getCurrent().getRequestScope().get("bindings");
        if (_refreshControl) {
            DCIteratorBinding iterBinding =
                bindings.findIteratorBinding(_iterBindingName);
            iterBinding.executeQuery();
            _refreshControl = false;
        }
        if (cm == null) {
            FacesCtrlHierBinding hierBinding =
                (FacesCtrlHierBinding)bindings.findCtrlBinding(_treeBindingName);
            cm = hierBinding.getCollectionModel();
            ADFContext.getCurrent().getRequestScope().put("collectionModel_" +
                                                          this.hashCode(), cm);
        }
        return cm;
    }
...

There are two reasons for implementing the getModel() method this way:

  • It is necessary to delegate all collection model-related logic to the model returned by the tree binding. Inside the collection handler, you must get a handle to the collection model returned by the tree binding by looking up the binding container. As you reference the collection model often, store it somewhere for optimal performance. Make sure the managed JavaBean has a view scope while the binding container, tree binding or collection model has a request scope. You cannot store the collection model on the JavaBean. Instead, store the collection model in the request scope. When accessing the collection model, look it up first in the request scope. If the value is null—for example, at the beginning of the request—retrieve the value from the binding container.

  • When pushing the ActiveDataEvent through ADS, only the UI is updated with the new value. The binding layer is not aware that the underlying data source has changed. If the page is refreshed at this time, the UI displays the old data from the binding layer. A workaround is to keep a refreshBinding flag on the ActiveDataCollectionModel to indicate whether the binding requires refreshing. The flag is initially set to false. When an event is received, the flag is set to true. When getting the collection model, check for this flag first. If the flag is set to true, programmatically refresh the related binding before returning the collection model. Example 42-5 shows sample ActiveDataCollectionHandler code.

    Example 42-5 From the ActiveDataCollectionHandler Code

     private CollectionModel getModel() {
            CollectionModel cm =
                (CollectionModel)ADFContext.getCurrent().getRequestScope().get("collectionModel_" +
                                                                               this.hashCode());
            DCBindingContainer bindings =
                (DCBindingContainer)ADFContext.getCurrent().getRequestScope().get("bindings");
            if (_refreshControl) {
                DCIteratorBinding iterBinding =
                    bindings.findIteratorBinding(_iterBindingName);
                iterBinding.executeQuery();
                _refreshControl = false;
            }
            if (cm == null) {
                FacesCtrlHierBinding hierBinding =
                    (FacesCtrlHierBinding)bindings.findCtrlBinding(_treeBindingName);
                cm = hierBinding.getCollectionModel();
                ADFContext.getCurrent().getRequestScope().put("collectionModel_" +
                                                              this.hashCode(), cm);
                System.out.println("CollectionModel: " + cm.hashCode());
            }
            return cm;
        }
    

42.4.2 Building the Supporting Active Data Entry Classes

The ActiveDataCollectionHandler uses Oracle ADF Rich Events to propagate the data updates and UI refresh in response to JMS queue updates. You must implement these event classes and register them as events from the CollectionHandler.

To create the Active Data Entry implementation:

The class shown in Example 42-6 extends the Oracle ADF class oracle.adf.view.rich.event.ActiveDataEntry and implements several methods in that interface.

Example 42-6 Active Data Entry Class

package ads.demo.view;
 
import java.util.HashMap;
import java.util.Map;
 
import oracle.adf.view.rich.event.ActiveDataEntry;
 
public class DemoActiveDataEntry extends ActiveDataEntry {
    public DemoActiveDataEntry(ActiveDataEntry.ChangeType change,
                               Object[] path, Object[] insertKeyPath,
                               String[] names, Object[] values) {
        super();
 
        if (names != null) {
            for (int i = 0; i < names.length; i++) {
                String attribute = names[i];
                Object value = values[i];
                _valuesMap.put(attribute, value);
            }
        }
 
        _attributes = names;
        _values = values;
        _changeType = change;
        _path = path;
        _insertPath = insertKeyPath;
 
    }
 
    public ActiveDataEntry.ChangeType getChangeType() {
        return _changeType;
    }
 
    public Object[] getKeyPath() {
        return _path;
    }
 
    public Object[] getInsertKeyPath() {
        return _insertPath;
    }
 
    public String[] getAttributeNames() {
        return _attributes;
    }
 
    public Object getAttributeValue(String name)
    {
      return _valuesMap.get(name);
    }
 
    public Object getFormattedAttributeValue(String name)
    {
      return getAttributeValue(name);
    }
 
    private final Map<String, Object> _valuesMap =
        new HashMap<String, Object>();
    private String[] _attributes = null;
    private Object[] _values = null;
    private ChangeType _changeType = null;
    private Object[] _path = null;
    private Object[] _insertPath = null;
 
}

To implement the Active Data Update Event:

The Active Data update event takes a list of Active Data entry events and performs them at once. The class extends from oracle.adf.view.rich.event.ActiveDataUpdateEvent and implements several methods, as shown in Example 42-7.

Example 42-7 Active Data Update Event

package ads.demo.view;
 
import java.util.Collections;
import java.util.List;
 
import oracle.adf.view.rich.event.ActiveDataEntry;
import oracle.adf.view.rich.event.ActiveDataUpdateEvent;
 
public class DemoActiveDataUpdateEvent extends ActiveDataUpdateEvent {
    public DemoActiveDataUpdateEvent(Object object) {
        super(object);
    }
 
    public DemoActiveDataUpdateEvent(Object source, int eventId,
                               List<ActiveDataEntry> changeList)
    {
      super(source);
 
      _changeList = changeList;
      _eventId = eventId;
    }
 
    /**
    * Get the change list of this event
    *
    * @return the change list of this event
    */
    public List<ActiveDataEntry> getChangeList()
    {
      return _changeList;
    }
 
    /**
    * Get the event ID
    * Return the event ID
    */
    public int getEventId()
    {
      return _eventId;
    }
 
    public long getEventTime()
    {
      return System.currentTimeMillis();
    }
 
    public String toString()
    {
      return super.toString() + " eventId:" + _eventId + " changeList:" + _changeList;
    }
 
    private List<ActiveDataEntry> _changeList =  Collections.emptyList();
    private int _eventId = 0;
}

42.4.3 Registering the Active Data Collection Model with the Oracle ADF UI Page

In order to enable the active data feature and "hook" your collection model, you need to register the class as a managed JavaBean.

ADS requires UI components to have the same model across requests. Therefore, register the ActiveDataCollectionModel as a view scoped managed JavaBean. As long as you stay on the same page, the table is based on the same model.

To register your collection model as a managed JavaBean:

  1. Open adfc-config.xml.

  2. Add the managed JavaBean named adsBean and provide the package to your collection model class, as shown in Example 42-8.

Example 42-8 adsBean Managed JavaBean

<managed-bean>
  <managed-bean-name>adsBean</managed-bean-name>
  <managed-bean-class>ads.demo.view.ActiveDataCollectionModel</managed-bean-class>
  <managed-bean-scope>view</managed-bean-scope>
  <managed-property>
      <property-name>treeBindingName</property-name>
      <property-class>java.lang.String</property-class>
      <value>EmpView1</value>
  </managed-property>
  <managed-property>
      <property-name>iterBindingName</property-name>
      <property-class>java.lang.String</property-class>
      <value>EmpView1Iterator</value>
  </managed-property>
</managed-bean>

42.4.4 Registering the Component Managed JavaBean for Supporting Method Actions

To trigger the synchronous functionality of the use case pattern, raise a business event in response to the click of an Oracle ADF button. In order to support a response to the click of a button, create a managed JavaBean with which you can associate methods as the action for these buttons.

To build your Oracle ADF component managed JavaBean:

In the prototype use case, there is a table that contains a list of employees and their entity object attributes. Add two buttons at the top of the table in a panel collection toolbar which, when clicked, uses the selected employee to initiate an approval process. When completed, the approval process dynamically updates the table, as shown in Figure 42-2.

Figure 42-2 Dynamically Updated Table

Sample UI

The table component requires the managed JavaBean shown in Example 42-9.

Example 42-9 Table Component Managed JavaBean

package ads.demo.view;
 
import java.util.ArrayList;
 
import java.util.Collection;
 
import java.util.Map;
 
import javax.faces.application.FacesMessage;
import javax.faces.context.FacesContext;
import javax.faces.event.ActionEvent;
 
import oracle.adf.model.OperationBinding;
import oracle.adf.model.binding.DCBindingContainer;
import oracle.adf.share.ADFContext;
import oracle.adf.view.rich.component.rich.data.RichTable;
 
import oracle.jbo.Key;
 
import org.apache.myfaces.trinidad.model.RowKeySet;
 
public class TableHandlerBean {
    private RichTable _table;
 
    public TableHandlerBean() {
        super();
    }
 
    public void setTable(RichTable _table) {
        this._table = _table;
    }
 
    public RichTable getTable() {
        return _table;
    }
 
    public void handleRaise(ActionEvent event) {
        String correlationId =        ((ActiveDataCollectionModel)ADFContext.getCurrent().getViewScope().get("adsBean")).getUuid();
        RowKeySet selectedRowKeys = getTable().getSelectedRowKeys();
        ArrayList<String> selectedEmp = new ArrayList<String>(selectedRowKeys.size());
        for (Object rowKey : selectedRowKeys) {
            Key jboKey = ((Collection<Key>)rowKey).iterator().next();
            String rowKeyString = ((Integer)jboKey.getKeyValues()[0]).toString();
            selectedEmp.add(rowKeyString);
            // Publish event
            try {
                DCBindingContainer bindings =                (DCBindingContainer)ADFContext.getCurrent().getRequestScope().get("bindings");
                OperationBinding action =                (OperationBinding)bindings.findCtrlBinding("publishEvent");
                Map params = action.getParamsMap();
                params.put("correlationId", correlationId);
                params.put("key", rowKeyString);
                params.put("eventType", "payRaise");
                action.execute();
                // addConfirmationMessage();
            } catch ( Exception e ) {
                log.severe("ASM: Failed to raise commission event for key: " + rowKeyString);
            } // try
        }
 
        // Invoke BPEL from here.
    }
 
    public void handleCommission(ActionEvent event) {
        String correlationId =       ((ActiveDataCollectionModel)ADFContext.getCurrent().getViewScope().get("adsBean")).getUuid();
        RowKeySet selectedRowKeys = getTable().getSelectedRowKeys();
        ArrayList<String> selectedEmp = new ArrayList<String>(selectedRowKeys.size());
        for (Object rowKey : selectedRowKeys) {
            Key jboKey = ((Collection<Key>)rowKey).iterator().next();
            String rowKeyString = ((Integer)jboKey.getKeyValues()[0]).toString();
            selectedEmp.add(rowKeyString);
            // Publish event
            try {
                DCBindingContainer bindings =                (DCBindingContainer)ADFContext.getCurrent().getRequestScope().get("bindings");
                OperationBinding action =                (OperationBinding)bindings.findCtrlBinding("publishEvent");
                Map params = action.getParamsMap();
                params.put("correlationId", correlationId);
                params.put("key", rowKeyString);
                params.put("eventType", "payCommission");
                action.execute();
                // addConfirmationMessage();
            } catch ( Exception e ) {
                log.severe("ASM: Failed to raise commission event for key: " + rowKeyString);
            } // try
        }
        // Invoke BPEL from here.
 
 
    private void addConfirmationMessage() {
        FacesMessage msg = new FacesMessage("You request is submitted for approval.");
        FacesContext.getCurrentInstance().addMessage(null, msg);
    }
}

To register the component managed JavaBean:

As with the collection model, register the component managed JavaBean by adding an entry to adfc-config.xml, as shown in Example 42-10.

Example 42-10 adfc-config.xml Registration Code

<managed-bean>
    <managed-bean-name>tableBean</managed-bean-name>
    <managed-bean-class>ads.demo.view.TableHandlerBean</managed-bean-class>
    <managed-bean-scope>request</managed-bean-scope>
</managed-bean>

42.4.5 Referencing the Managed JavaBean in the Page UI

Modify the page component to reference the managed JavaBean from the earlier steps, as shown in Example 42-11.


Note:

You may notice that selectedRowKeys is not bound to any method. By default, it is bound to #{bindings.treeBinding.collectionModel.selectedRowKeys}. It will no longer work after using ActiveDataCollectionModel.


Example 42-11 Referencing the Managed JavaBean

<af:table value="#{viewScope.adsBean}" var="row"
  rows="#{bindings.EmpView1.rangeSize}"
  fetchSize="#{bindings.EmpView1.rangeSize}"
 
  rowBandingInterval="0"
 
  filterModel="#{bindings.EmpView1Query.queryDescriptor}"
 
  queryListener="#{bindings.EmpView1Query.processQuery}"
  filterVisible="true" varStatus="vs"
  selectionListener="#{bindings.EmpView1.collectionModel.makeCurrent}"
  rowSelection="multiple" id="t1" width="100%"
  binding="#{tableBean.table}">

42.4.6 Creating the Data Model and Adding Application Module Methods

The data model should exist before the page is built in order to simplify laying out the components required to display the data contained in that model. The application module needs additional methods to support incoming service methods and, optionally, the methods for raising the business event.

For more information about creating a data model with application modules, see the chapter "Implementing Business Services with Application Modules" in Oracle Fusion Middleware Fusion Developer's Guide for Oracle Application Development Framework (Oracle Fusion Applications Edition).

.

To extend the methods of your application module for the service interface:

Make sure to expose one or more application module methods in the application module service. This facilitates the callback from BPEL upon completion of the process, triggering the ADS UI update. These methods publish the message to the JMS queue following the message structure shown here.

The message payload should take the format of DataUpdateEvent, which comprises one or more DataChangeEntry items.

  • changeType: enum (UPDATE, REFRESH). Currently, there is no use case for INSERT.

  • key: Object[]

  • insertKey: Object[]

  • attributeNames: String[], a list of names of changed attributes

  • attributeValues: Object[], a list of new values for the changed attributes

In this pattern, payRaise and payCommision are supported for one or more selected employees. Use methods with simple string interfaces invoked by BPEL to complete the payRaise or payCommision event for each particular employee. Call the sendMessage method to publish the JMS message to notify ADS of the UI update. Sample BPEL methods are shown in Example 42-12.

Example 42-12 BPEL Methods

// Simplified interface method for service call per employee  
 
  public void performSingleRaise(String correlationId, String key) {
        ArrayList thelist = new ArrayList<String>();
        thelist.add(key);
        performRaise(correlationId, thelist);
    } //
 
 
  // List interface for call from UI and by Simplified Service Method
    public void performRaise(String correlationId, List<String> keyValues) {
        List<DemoDataChangeEntry> dces =
            new ArrayList<DemoDataChangeEntry>(keyValues.size());
        ViewObject empVO = getEmpView1();
        for (String keyVal : keyValues) {
            Key key = new Key(new Object[] { keyVal });
            Row row = empVO.findByKey(key, 1)[0];
            BigDecimal newSal = new
                BigDecimal(Math.round(((BigDecimal)row.getAttribute("Sal")).doubleValue()*(1+(new
                Random()).nextDouble()/10)));
            row.setAttribute("Sal", newSal);
            DemoDataChangeEntry dce =
                new DemoDataChangeEntry(new Object[] { new Integer(keyVal) },
                                        DemoDataChangeEntry.ChangeType.UPDATE,
                                        new String[] { "Sal" },
                                        new Object[] { newSal.toString() });
            dces.add(dce);
        }
        this.getDBTransaction().commit();
 
        DemoDataUpdateEvent event = new DemoDataUpdateEvent(dces);
        // Send a message
        sendMessage(correlationId, event);
    }
 
    // Simplified interface for Service method
 
    public void paySingleCommission(String correlationId, String key) {
        ArrayList<String> thelist = new ArrayList<String>();
        thelist.add(key);
        payCommission(correlationId, thelist);
    }
 
 
// List interface for calling from UI and by Simplified Service Method
 
public void payCommission(String correlationId, List<String> keyValues) {
        List<DemoDataChangeEntry> dces =
            new ArrayList<DemoDataChangeEntry>(keyValues.size());
        ViewObject empVO = getEmpView1();
        for (String keyVal : keyValues) {
            Key key = new Key(new Object[] { keyVal });
            Row row = empVO.findByKey(key, 1)[0];
 
            BigDecimal newComm = new BigDecimal((new Random()).nextInt(10000));
            row.setAttribute("Comm", newComm);
            DemoDataChangeEntry dce =
                new DemoDataChangeEntry(new Object[] { new Integer(keyVal) },
                                        DemoDataChangeEntry.ChangeType.REFRESH,
                                        new String[] { "Comm" },
                                        new Object[] { newComm.toString() });
            dces.add(dce);
        }
        this.getDBTransaction().commit();
 
        DemoDataUpdateEvent event = new DemoDataUpdateEvent(dces);
        // send message
        sendMessage(correlationId, event);
    }
 
 
// Private method to push ADS update to JMS queue
 
private void sendMessage(String correlationId, DemoDataUpdateEvent event) {
        try {
            JMSHelper helper = JMSHelper.getInstance();
            ObjectMessage message = helper.createObjectMessage();
            message.setObject(event);
            message.setJMSCorrelationID(correlationId);
            helper.sendMessage(message);
        } catch (JMSException e) {
            e.printStackTrace();
        } // try
    } // sendMessage
 

To define structure and compose event metadata:

The code that programmatically creates business event payloads and raises them through the business event APIs should be deliberately built around the namespace and event attributes defined in the appropriate EDL and XSD files.

For this pattern, a single event is used that supports multiple event types through an attribute value such as payRaise and payComission. However, support for additional event types only requires adding the UI facet, the programmatic method to raise that new event type and a conditional branch in BPEL. If the pattern requires completely separate event definitions, the code becomes more complex, the number of managed metadata source files increases, and the composite becomes more complex as well.

While this is a simpler approach, it is not as flexible from an integration perspective. Define your event types such that they support your current use case and potentially support additional integration in the future. Example 42-13 shows a simplified event definition, while Example 42-14 shows an event schema definition.

Example 42-13 Simplified Event Definition

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<definitions xmlns="http://schemas.oracle.com/events/edl"
             targetNamespace="http://xmlns.oracle.com/apps/ta/adsdemo/events/edl">
  <schema-import namespace="http://xmlns.oracle.com/apps/ta/adsdemo/events/schema"
             location="xsd/ADSDemoEventSchema.xsd"/>
  <event-definition name="ADSDemoEvent">
    <content xmlns:ns0="http://xmlns.oracle.com/apps/ta/adsdemo/events/schema"
             element="ns0:ADSDemoEventElement"/>
  </event-definition>
</definitions>

Example 42-14 Event Schema Definition

<?xml version="1.0" encoding="UTF-8" ?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
            xmlns="http://xmlns.oracle.com/apps/ta/adsdemo/events/schema"
            targetNamespace="http://xmlns.oracle.com/apps/ta/adsdemo/events/schema"
                   attributeFormDefault="unqualified"
            elementFormDefault="qualified">
  <xsd:element name="ADSDemoEventElement" type="ADSDemoEventElementType"/>
  <xsd:complexType name="ADSDemoEventElementType">
      <xsd:sequence>
        <xsd:element name="correlationId" type="xsd:long"/>
        <xsd:element name="key" type="xsd:long"/>
        <xsd:element name="eventType" type="xsd:string"/>
      </xsd:sequence>
</xsd:complexType>
 
</xsd:schema>

To extend the application module with publishEvent and supporting methods:

In the page bindings, add the method publishEvent that binds to the application module method of the same name. Use this binding in the handleRaise and handleCommission methods of the TableHandlerBean to publish the event for each employee to be updated.

For more information about extending the application module with the publishEvent method, see Section 32.5.1, "Using the Java Event API to Publish Events."


Note:

It is critical that the event name and namespace are consistent throughout the code and metadata definitions in the subscribing SOA composite.


42.4.7 Creating a SOA Composite that Subscribes to the Published Event

The creation of a SOA composite that subscribes to an event is covered in Section 32, "Initiating a SOA Composite from an Oracle ADF Web Application." A sample pattern composite is shown in Figure 42-3.

Figure 42-3 Pattern Composite

Prototype Composite

42.4.8 Constructing a BPEL Process to Perform Asynchronous Work

The creation of a BPEL process and human task activities is described in other sections. For more information, see Chapter 38, "Managing Tasks from an Oracle ADF Application."

A sample BPEL process is shown in Figure 42-4.

Figure 42-4 BPEL Flow

BPEL Flow

42.4.9 Invoking the ADF Business Components Service

Invoking an ADF Business Components service from a BPEL process is covered in another section. For more information, see Chapter 34, "Orchestrating ADF Business Components Services."

42.5 Securing the Design Pattern

The process of securing this design pattern is the same as that of securing an Oracle ADF UI application.

For more information, see Chapter 50, "Securing Web Services Use Cases."

42.6 Verifying the Deployment

Do the following to test functionality:

  1. Turn on the EDN-DB-LOG page by navigating to http://host:port/soa-infra/events/edn-db-log and ensure it reads "Log is Enabled." If it is not, click Enable.

  2. Open the UI page and interact with the UI components that you designed to trigger the event.

    The event should immediately display in the EDN-DB-LOG page.

  3. Check for the event payload shown in Example 42-15.

    Example 42-15 Event Payload

    Enqueing event: http://xmlns.oracle.com/apps/ta/adsdemo/events/edl::ADSDemoEvent from J
    Body: <business-event xmlns:ns="http://xmlns.oracle.com/apps/ta/adsdemo/events/edl" xmlns="http://oracle.com/fabric/businessEvent">
       <name>ns:ADSDemoEvent</name>
       <id>494ae921-4667-4a42-8190-5a5aaa428f7e</id>
       <content>
          <ADSDemoEventElement xmlns="http://xmlns.oracle.com/apps/ta/adsdemo/events/schema">
             <correlationId>3926ed2d-e023-4f05-85f9-bdf0b57099ae</correlationId>
             <key>7499</key>
             <eventType>payRaise</eventType>
          </ADSDemoEventElement>
       </content>
    </business-event>
     
    Subject name:
    Enqueing complete
     
    Starting EDN Agent for Event from Queue
    Dequeued event: http://xmlns.oracle.com/apps/ta/adsdemo/events/edl::ADSDemoEvent
    Subject name:
    Body: <business-event xmlns:ns="http://xmlns.oracle.com/apps/ta/adsdemo/events/edl" xmlns="http://oracle.com/fabric/businessEvent">
       <name>ns:ADSDemoEvent</name>
       <id>494ae921-4667-4a42-8190-5a5aaa428f7e</id>
       <content>
          <ADSDemoEventElement xmlns="http://xmlns.oracle.com/apps/ta/adsdemo/events/schema">
             <correlationId>3926ed2d-e023-4f05-85f9-bdf0b57099ae</correlationId>
             <key>7499</key>
             <eventType>payRaise</eventType>
          </ADSDemoEventElement>
       </content>
    </business-event>
    
  4. Check the console ($DOMAIN_HOME/as.log) or soa-diagnostic logs ($DOMAIN_HOME/servers/<serverName>logs/<serverName>.log) to see any Mediator activity that results from your event.

     INFO: MediatorServiceEngine received an event = {http://xmlns.oracle.com/apps/ta/adsdemo/events/edl}ADSDemoEvent
    Apr 17, 2009 1:57:26 PM oracle.tip.mediator.common.persistence.MediatorPersistor persistCallback
    INFO: No call back info set in incoming message
    Apr 17, 2009 1:57:26 PM oracle.tip.mediator.common.persistence.MediatorPersistor persistCallback
    INFO: Message properties :{id=041ecfcf-8b73-4055-b5c0-0b89af04f425, tracking.compositeInstanceId=50003, tracking.ecid=0000I2pqzVCBLA5xrOI7SY19uEYF00004g:47979}
    Apr 17, 2009 1:57:26 PM oracle.tip.mediator.dispatch.InitialMessageDispatcher dispatch
    INFO: Executing Routing Service..
    Apr 17, 2009 1:57:26 PM oracle.tip.mediator.dispatch.InitialMessageDispatcher processCases
    INFO: Unfiltered case list size :1
    Apr 17, 2009 1:57:26 PM oracle.tip.mediator.monitor.MediatorActivityMonitor createMediatorCaseInstance
    INFO: Creating case instance with name :ADEDemoProcess.adedemoprocess_client.process
    Apr 17, 2009 1:57:26 PM oracle.tip.mediator.dispatch.InitialMessageDispatcher processCase
    INFO: Immediate case {ADEDemoProcess.adedemoprocess_client.process} with case id :{5B52B4A02B9211DEAF64D3EF6E2FB21D} will be executed
    Apr 17, 2009 1:57:26 PM oracle.tip.mediator.service.filter.FilterFactory createFilterHandler
    INFO: No Condition defined
    
  5. Check Oracle Enterprise Manager at http://host:port/em for an instance of your SOA composite, and check for errors.

  6. If your process has no errors and is expecting a response from the human workflow notification, do the following:

    1. Navigate to the worklist at http://host:port/integration/worklistapp.

    2. Log in as the assigned approver.

    3. Approve or reject the notification per your design requirements.

At this point, the BPEL process should complete and invoke the ADF Business Components service to trigger the ADS push. The UI should promptly update. Check the Oracle ADF UI runtime console and diagnostic logs for stack traces and log messages.

42.7 Troubleshooting the Use Case

For the Oracle ADF UI functionality, use Fusion Middleware Control, Oracle Fusion Applications Logger, and server diagnostic logs for information about what is failing.

For the events functionality, use the Event Delivery Network database log page at http://host:port/soa-infra/events/edn-db-log.

For the SOA functionality, use the Oracle Enterprise Manager console for diagnostics and Oracle Fusion Applications Logger sensor variables for logging.

For the ADF Business Components service functionality, use BPEL fault handling and logging via Oracle Fusion Applications Logger sensor variables as well as the console, Oracle Fusion Applications Logger and server diagnostic logs for more detailed error messages.

42.8 What You May Need to Know About Initiating an Asynchronous Service with Dynamic UI Update

42.9 Known Issues and Workarounds

Known issues are as follows:

PKO!PK BOEBPS/uc_soa_plsqlservice.htm$W Accessing a PL/SQL Service from a SOA Composite

36 Accessing a PL/SQL Service from a SOA Composite

This chapter describes what a SOA composite application needs to do to access logic implemented as PL/SQL in the database.

When to implement: A SOA composite application needs to access logic implemented as PL/SQL in the database.

Design Pattern Summary: The SOA composite application accesses an ADF Business Components service, which in turn accesses the PL/SQL stored procedure.

Involved components:

36.1 Introduction to the Recommended Design Pattern

Oracle Fusion applications may contain stored procedures in the database that a SOA composite application needs to access. The stored procedure must be wrapped by an ADF Business Components service; the BPEL process then accesses the ADF Business Components service.

36.2 Other Approaches

Instead of accessing the stored procedure through an ADF Business Components service, you could use a SOA database binding component. However, this is not allowed because the SOA database binding component does not handle data changes or database schema changes gracefully. In addition, a PL/SQL stored procedure definition cannot be considered a service contract, as there is often some needed extrapolation.

Another alternative is to create a Web service directly on top of PL/SQL. This is not allowed because of security issues in the PL/SQL Web service.

36.3 Example

The sample code for this use case can be downloaded from Oracle SOA Suite samples.

36.4 How to Invoke a PL/SQL Stored Procedure from a SOA Composite Application

Instead of directly accessing the stored procedure, you create a business component that accesses the procedure, you then publish the business component as a SOAP service. The SOA composite application component accesses the ADF Business Components service, which in turn invokes the stored procedure.

To invoke a PL/SQL stored procedure from a SOA composite application:

  1. Create a business component, including an application module, as documented in the section "Part II: Building Your Business Services" of the Oracle Fusion Middleware Fusion Developer's Guide for Oracle Application Development Framework (Oracle Fusion Applications Edition).

  2. Write a method in your application module that accesses the PL/SQL stored procedure. For step-by-step instructions, see the section "Invoking Stored Procedures and Functions" in the chapter "Advanced Business Components Techniques" of theOracle Fusion Middleware Fusion Developer's Guide for Oracle Application Development Framework (Oracle Fusion Applications Edition)

  3. Generate the service interface for the business component, as described in "Integrating Web Services Into a Fusion Web Application" in Oracle Fusion Middleware Fusion Developer's Guide for Oracle Application Development Framework (Oracle Fusion Applications Edition).

  4. Invoke it through a SOAP binding, as described in Chapter 34, "Orchestrating ADF Business Components Services."

36.5 Securing the Design Pattern

You secure this design pattern in the same way you secure a pattern with an ADF Business Components service invoked from a SOA composite application. For details, see Section 34.5, "Securing the Design Pattern."

Identity propagation is enabled using Application User Sessions. When the application module initializes, an Application User Session is created with the user who is currently logged in (assuming no such Application User Session yet exists). The Application User Session is pushed to the database, making it accessible from PL/SQL.

For information about accessing the Application User Session, see Section 47, "Implementing Application User Sessions."

For information about securing the design pattern, see Section 50, "Securing Web Services Use Cases."

36.6 Verifying the Deployment

To properly verify this design pattern, test your business component, then deploy and test the SOA composite application.

To verify this design pattern:

  1. Test your Oracle ADF application using various testing and debugging methods described in the chapter "Testing and Debugging ADF Components" of the Oracle Fusion Middleware Fusion Developer's Guide for Oracle Application Development Framework (Oracle Fusion Applications Edition). For information about testing the ADF Business Components service, see the chapter "Integrating Web Services Into a Fusion Web Application" in the Oracle Fusion Middleware Fusion Developer's Guide for Oracle Application Development Framework (Oracle Fusion Applications Edition).

  2. Deploy the SOA composite application to the standalone WLS where the SOA infrastructure has been installed. Because you created a published event from the SOA composite application to the ADF Business Components service, the ADF Business Components service need not to also be deployed to the SOA infrastructure.

  3. Test the deployed SOA composite service using Oracle Enterprise Manager Fusion Middleware Control Console. Every deployed service has its own test page, so you can quickly test that the service functions as you expect. For more information about using the Fusion Middleware Control Console to test deployed SOA composite applications, see the following chapter:

    "Automating Testing SOA Composite Applications" in the Oracle Fusion Middleware Developer's Guide for Oracle SOA Suite.

PK $$PK BOEBPS/bs_validation.htmp Defining Defaulting and Derivation Logic

6 Defining Defaulting and Derivation Logic

This chapter describes how to define your defaulting and derivation logic, how to use Groovy (a Java-like scripting language), and how to use Oracle Application Development Framework (Oracle ADF) validators and convertor hints instead of using messages.

This chapter includes the following sections:

6.1 Understanding Entity Object Defaulting and Derivation Logic

Defaulting logic means assigning attribute values when a row or entity object is first created or refreshed. (The logic is not re-applied when the entity object is changed.) Defaulting is achieved either declaratively in the default field of the attribute or programmatically by adding code to the EOImpl.

Derivation logic means assigning attribute values when some other attributes have changed. Derivation is achieved either declaratively in the default field of the transient attribute or by using a validator, or programmatically by adding code to the EOImpl.

Figure 6-1, illustrates what you need to consider when determining whether to implement defaulting or derivation logic.

Figure 6-1 Defaulting and Derivation — Decision Tree

Defaulting and Derivation - Decision Tree

When implementing defaulting or derivation logic, you should also consider the following factors:

6.2 Using Groovy Scripting Language

ADF Business Components now provide integrated support for Groovy (a Java-like scripting language), which is dynamically compiled and evaluated at run-time. Because it is dynamically compiled, Groovy script can be stored inline in the XML and is eligible for customization. Groovy also supports object access via dot-separated notation, which means you can now use syntax such as empno instead of getAttribute(EMPNO).

You can embed Groovy script into various declarative areas, including:

6.2.1 Keywords and Available Names

As with the original Script implementation, the current object is passed into the script as "this" object. Therefore, to refer to any attribute inside the current object simply use the attribute name. For example, in an attribute or validator expression for an entity, to refer to an attribute named Ename, the script may say return Ename.

There is one top-level reserved name, adf, which is used to get to objects that the framework makes available to the Groovy script. Currently, these objects are:

  • ADFContext (adf.context)

  • Object on which the expression is being applied (adf.object)

  • Error handler that lets the validator generate exceptions or warnings (adf.error)

All other names come from the context in which the script is applied:

  • Variable - gets the Variable, structureDef in which it is contained via getStructureDef method on VariableImpl.

  • Transient Attribute - gets the Entity or ViewRow as its context so that all attributes in the entity are accessible by name. Any method on the entity may be invoked by directly calling the entity method as if you were writing a method in the entity subclass.


    Tip:

    Only public methods on the entity are available to call.


    You also need to call the method using the "object" keyword, such as adf.object.createUnqualifiedRowSet(). The "object" keyword is equivalent to the "this" keyword in Java. Without it, in transient expressions, the method is assumed to exist on the script object itself, which it does not.

  • Validator - gets the Validator context JboValidatorContext merged with the Entity on which the validator is applied. This is done so that you can use:

    • newValue and oldValue to get to the values being validated

    • sourceRow to get to the Entity or ViewRow on which the validator is applied

    • All attribute names in the Entity or ViewRow as top-level names

6.2.2 Scripting Logic

Groovy scripting logic is similar to Expression Language (EL) because you can use a "." separated path to get to a value inside an object. Note that if a Java object implements Map, only the map lookup is performed instead of the bean style property lookup. However, for Maps that extend JboAbstractMap you get the same EL behavior, which is map first followed by bean lookup. This is due to the implementation of get in JboAbstractMap.

Consider the following information:

  • All Java methods, language constructs, and Groovy language constructs are available in the script.

  • Aggregates are implemented by calling sum(expr), count(expr), or avg(expr) on a RowSet object where expr can be any Groovy expression that returns a numeric value or number domain.

  • The defaultRowSet reserved keyword has been removed. The method EntityImpl.createUnqualifiedRowSet() replaces EntityImpl.getDefaultRowSet() and can be accessed like any other public method in EntityImpl.

  • Use the return keyword as you would in Java to return a value. That is, unless it is a single-line expression where the return is assumed to be the result of the expression itself. For example, "Sal + Comm" or "Sal > 0".

  • Do not use {} to surround the entire script because Groovy interprets { to be the beginning of a Closure object.

  • Any object that implements oracle.jbo.Row, oracle.jbo.RowSet, or oracle.jbo.ExprValueSupplier is wrapped into a Groovy Expando object. This is to extend the properties available for those objects to beyond the bean properties and also as a way to avoid introspection for most used names.

6.2.3 Groovy Expression Examples

The following are some examples of Groovy.

6.2.3.1 Querying Based on the Current Locale

Instead of using the following SQL to achieve this:

SELECT C.ISO_COUNTRY_CODE
,C.COUNTRY_NAME
FROM COUNTRY_CODES C
WHERE LANGUAGE = SYS_CONTEXT('USERENV', 'LANG')
ORDER BY C.COUNTRY_NAME

Create a bind variable and base its default value on the adf.context.locale.language expression:

6.2.3.2 Error Message Tokens

To get the attribute new value and label:

Example of using Groovy to get attr new value label.

The above example uses the following two Groovy expressions:

newValue  // This works because an attribute level validator has been created.
source.hints.ProductId.label

and

source.structureDef.name+" of type "+sourceFullName

6.2.3.3 Expression Validators

Example 6-1 is an example of an Object graph, custom error, and a warning:

Example 6-1 Object Graph, Custom Error, and a Warning

if (EmpSal >= 5000)
{
  // If EmpSal is greater than a property value set on the custom
  // properties on the root AM
  // raise a custom exception else raise a custom warning
  if (EmpSal >= source.DBTransaction.rootApplicationModule.propertiesMap.salHigh)
  {
    adf.error.raise("ExcGreaterThanApplicationLimit");
  }
  else
  {
    adf.error.warn("WarnGreaterThan5000");
  }
}
else if (EmpSal <= 1000)
  {
    adf.error.raise("ExcTooLow");
  }
return true;

Example 6-2 is an example of how to average a collection.

Example 6-2 Averaging a Collection

attribute Number EmpSal : SAL
{
  expressionValidator(expression = 
    "newValue <= source.createUnqualifiedRowSet().avg(\"EmpSal\") * 1.2");
}

Example 6-3 is an example of a built-in or custom method call on the sourceObject of this validator (sourcObject being the Entity on which this validator is being run). isAttributeChanged(String) is a public method on the EntityImpl:

Example 6-3 Built-in or Custom method Call

if (source.isAttributeChanged("EmpSal") || source.isAttributeChanged("EmpComm"))
           {
              return true;
           }
           return false;

Example 6-4 is an example of getting to oldValue / newValue of an attribute on which this validator is applied:

Example 6-4 Getting to Old Value and New Value of an Attribute

return (oldValue == null || newValue < olValue * 1.2);

Example 6-5 is an example of accessing the Entity state relative to the database and relative to the last post operation.

Use adf.object.entityState or adf.object.postState.

To get the old value of an attribute (this works in the context of a transient Entity Object attribute):

Example 6-5 Getting the Old Value of a Transient Entity Object Attribute

index = object.getStructureDef().getAttributeIndexOf("Salary");
return object.getAttribute(index, oracle.jbo.server.EntityImpl.ORIGINAL_VERSION);

Example 6-6 is an example of the WHILE construct as well as calling an accessor (Emp):

Example 6-6 While Construct and Calling an Accessor

emps = Emp;
boolean alreadyfound = false;
emps.reset();
while (emps.hasNext())
{
  if (emps.next().Job == "CLERK")
  {
    if (alreadyfound)
    {
      adfError.raise("alreadyfound");
    }
    alreadyfound = true;
  }
}
return true;

6.2.3.4 Attribute Defaulting and Calculation

Example 6-7, Example 6-8, and Example 6-9 are examples of a simple transient attribute, how to sum or count a collection, and how to create a complex calculation of a bind variable value.

Example 6-7 Simple Transient Attribute

attribute transient Integer YearSal
{
  transientexpression = "EmpSal * 12";
}

Example 6-8 Sum or Count a Collection

attribute transient Integer TotalSal
{
  transientexpression = "object.createUnqualifiedRowSet().sum(\"EmpSal\")";
}
attribute transient Integer TotalCount
{
  transientexpression = "object.createUnqualifiedRowSet().count(\"EmpSal\")";
}

Example 6-9 Complex Calculation of a Bind Variable Value

query EmpView
{
  entity Emp EmpUsage \*;
  where "SAL > :avgSal"
  orderby "1"
  bindingstyle "OracleName"

variables
  {
    Double avgSal
    kind (where)
    {
      transientexpression
      {
        totSal = 0;
        empCount =0;
        fullVO = structureDef.getApplicationModule().createViewObject("_AvgSal", 
          testp.kava.VO7.si33mt.EmpAllView");
        empCount = 0;
        while (fullVO.hasNext())
        {
          row = fullVO.next();
          sal = row.EmpSal; totalSal = totSal + sal; empCount = empCount + 1;
        }
        fullVO.remove();
        if (empCount > 0)
        {
          return (int)(totalSal / empCount);
        }
        else
        {
          return 0;
        }
      }
    }
  }
}

Example 6-10 is of an entity-attribute XML fragment where a transient expression is used to provide a default value for that attribute. This expression is evaluated before the protected create method of the entity is called. Example 6-11 is an example of an attribute defaulting with a transient attribute calculation expression.

Example 6-10 Attribute Value Defaulting

<Attribute
      Name="EmpComm"
      ColumnName="COMM"
      Type="oracle.jbo.domain.Number"
      ColumnType="NUMBER"
      SQLType="NUMERIC"
      TableName="EMP" >
<TransientExpression><![CDATA[

      if (EmpSal == null)
      {
        return null;
      }
      if (EmpDeptNum == null)
      {
        return 0;
      }
      if (EmpDeptNum > 40)
      {
        retune 500;
      }

]]></TransientExpression>

Example 6-11 Attribute Defaulting with a Transient Attribute Calculation Expression

<ViewAttribute
    Name="Total"
    IsUpdateable="false"
    AttrLoad="Each"
    IsSelected="false"
    IsPersistent="false"
    PrecisionRule="false"
    Type="java.lang.String"
    ColumnType="VARCHAR2"
    AliasName="View_ATTR"
    SQLType="VARCHAR">
<TransientExpression>
<![CDATA[
          if (Sal != null && Comm != null)
          {
          return Sal + Comm;
        }
        else
        {
          return Sal;
        }
        ]]>
</TransientExpression>

6.2.4 Defining Expressions at Design Time

An expression for an attribute can be defined using either the Attribute Editor (see Figure 6-2) or the Expression Editor (see Figure 6-3).

Figure 6-2 Entity Object — Attribute Editor

Entity Object - Attribute Editor

If you want to define a string literal instead of a Groovy expression, select Literal as the Value Type and enter the value as "My Literal Value".

Figure 6-3 Entity Object — Expression Editor

Entity Object - Expression Editor

To access the Expression Editor, click the Edit button located next to the Value text box.


Note:

Recalculate Expression is used to determine whether or not the expression needs to be recalculated as changes are made during run-time. The Recalculate option is hidden for persistent attributes. This is because Persistent attribute values are always updateable by the user and therefore, the expression of the attribute should only act as a default expression so recalculation is not necessary. For non-persistent attributes, the user can choose to always recalculate, never recalculate, or decide if recalculation is needed based on the evaluation of the recalculate expression.


6.3 Using Oracle ADF Validators and Convertor Hints

In some situations, you should consider using Oracle ADF validators or converter hints instead of using messages.


Caution:

Oracle ADF validators and converter hints can only be used with messages stored in the Strings resource bundles. They cannot be used for messages stored in the Message Dictionary.


To ensure that the user has supplied the correct sort of value or a value in a valid range, input fields can be validated using an Oracle ADF validator. Values may be converted by a converter, for example to convert a string of input characters into a value of some other type such as a date or color.

To validate or convert an input value, you add the input component to the page and then add a validator or converter to that field. Each validator and converter has some messages associated with it:

For an individual component, you can explain the error to a user in terms relating to that specific input component by overriding the hints or by adding or overriding a detailed error message.

How to override an Oracle ADF validator or converter message with new text

You may not see any messages when you follow these steps to select the Application Messages resource bundle:

  1. In JDeveloper, select the af validator tag in the UI page.

  2. Open the Property Inspector.

  3. Select the message attribute.

  4. Select the text resource.

  5. Select the Application Messages resource bundle.

In this case, you may need to override the default message from the validator. To do so, follow the procedure in "Displaying Hints and Error Messages for Validation and Conversion" in the Oracle Fusion Middleware Web User Interface Developer's Guide for Oracle Application Development Framework (Oracle Fusion Applications Edition).

PKTCH!ppPK BOEBPS/cover.htmO Cover

Oracle Corporation

PK[pTOPK BOEBPS/ext_customize.htm Creating Customizable Applications

61 Creating Customizable Applications

Oracle Metadata Services (MDS) framework allows you to create customizable Oracle Fusion applications. This chapter describes how to configure your application at design time so that it can be customized by end users.

This chapter includes the following sections:

61.1 Introduction to Creating Customizable Applications

With the customization features provided by Oracle Metadata Services (MDS), both developers and customers can customize Oracle Fusion applications. Customizing an application involves taking a generalized application and making modifications to suit the needs of a particular group, such as a specific industry or site.

When an application is customizable, an end user can customize a user interface page at runtime in one of four ways:

Some customizations, such as changes to the model or to task flow roles, must be done from Oracle JDeveloper, as described in the "Using JDeveloper for Customizations" chapter in the Oracle Fusion Applications Extensibility Guide. Customizations made from JDeveloper are referred to as design-time customizations. Design-time customizations that are created and shipped with Oracle Fusion Applications are known as seeded customizations.


Note:

End users with the correct permissions can also customize some menus, such as the Navigator menu. For more information, see the "Customizing the Navigator Menu" chapter in the Oracle Fusion Applications Extensibility Guide.


For more information about customization, see the "Customizing and Extending Oracle Fusion Applications" chapter in the Oracle Fusion Applications Extensibility Guide.

A customized application contains a base application and one or more layers of customized metadata content. The customized metadata objects are stored in an MDS repository and, when a customized application is launched, the customized content is retrieved and applied over the base content. For more information, see the "Customizing Applications with MDS" chapter in the Oracle Fusion Middleware Fusion Developer's Guide for Oracle Application Development Framework (Oracle Fusion Applications Edition) and the "Managing the Metadata Repository" chapter in the Oracle Fusion Applications Administrator's Guide.


Note:

When you run your page in JDeveloper, all customizations created at runtime are, by default, written to a simulated MDS repository directory, which is stored at a temporary location in your system directory. The simulated MDS repository that is configured for the application reflects the metadata information that is contained in the Metadata Archive (MAR).

For more information, see Section 52.2.1, "How to Deploy an Application with Metadata to Integrated WebLogic Server."


To enable runtime customizations of an application, you first prepare the application for customizations, then you enable the runtime customization of pages and components.

61.2 Preparing an Application for Customizations

To enable an application for customization, you must complete the following steps in your JDeveloper application workspace in the order shown.

  1. Set project properties to enable user and seeded customizations.

  2. Configure the persistence change manager parameter to use the composer change manger.

  3. Enable end-user translations of customized strings.

  4. Add Oracle WebCenter Portal — Composer technology scope to your project. This technology scope contains the components that are used for Page Composer customization.

  5. (Optional) Enable user customization of the user interface (UI) shell template.

  6. (Optional) Create an IDE connection to your database (in addition to the application connection) to enable access to layer values that are populated from a database call.

After you complete these steps, you can enable runtime customization for the application's web pages and task flows as described in Section 61.3, "Enabling Runtime Customization of Pages and Components."

61.2.1 How to Set Project Properties to Enable User and Seeded Customizations

To enable user customizations, you must configure the view project to persist the customized metadata objects to a MDS repository so that the objects are available across sessions. You must also enable seeded customizations so that the page fragments and JSPX pages that you create will be configured to allow customizations.


Note:

ADF components (such as controller, model, and business components objects) must have a unique identifier so that they can be customized. ADF components that are generated by JDeveloper are created with identifiers by default, with the exception of fragments and pages in your user interface projects. To cause JDeveloper to generate identifiers for components on pages that you create in your user interface projects, you must explicitly specify this at the project level by enabling seeded customizations.


To set project properties for your view project:

  1. In the Application Navigator in JDeveloper, right-click your view project and choose Project Properties.

  2. In the Project Properties dialog, select ADF View to display the ADF View settings.

  3. Select Enable User Customizations and select Across Sessions Using MDS, as shown in Figure 61-1.

  4. Select Enable Seeded Customizations.

    Figure 61-1 Project Properties — ADF View

    Project Properties - ADF View
  5. Click OK.

61.2.2 How to Configure the Persistence Change Manager

You must configure the persistence change manager in order for the following runtime behavior to occur:

  • The Persist and Don't Persist attributes that you set for components at design time will govern which implicit changes that the end users make at runtime will be persisted during the session as well as across sessions.

  • The changes that end users make in the design view of Page Composer will be stored in the MDS repository.

When you enabled user customizations across sessions by completing the procedure in Section 61.2.1, "How to Set Project Properties to Enable User and Seeded Customizations," the IDE added the CHANGE_PERSISTENCE context parameter to the view project's web.xml file, and set the parameter to use the filtered persistence change manager. You must modify this parameter to use the composer change manager, and you must add the composer filter and its mapping.

Before you begin:

Modify your view project's properties to enable user customizations across sessions as described in Section 61.2.1, "How to Set Project Properties to Enable User and Seeded Customizations."

To configure the persistence change manager:

  1. In the Application Navigator, expand the WEB-INF node for your view project and double-click web.xml.

  2. In the source editor, change the org.apache.myfaces.trinidad.CHANGE_PERSISTENCE context parameter value to oracle.adf.view.page.editor.change.ComposerChangeManager, as shown in the following code.

    <context-param>
      <param-name>org.apache.myfaces.trinidad.CHANGE_PERSISTENCE</param-name>
      <param-value>
        oracle.adf.view.page.editor.change.ComposerChangeManager
      </param-value>
    </context-param>
    
  3. Add the filter and filter-mapping elements for the WebCenterComposerFilter class as shown in bold in Example 61-1.


    Note:

    Filters must be configured in the following order.

    1. JpsFilter

    2. ApplSessionFilter

    3. WebCenterComposerFilter

    4. ADFBindingFilter


    Example 61-1 composerFilter and Mappings in web.xml

    ....
      <!-- composerFilter goes here -->
      <filter>
        <filter-name>composerFilter</filter-name>
        <filter-class>
          oracle.adf.view.page.editor.webapp.WebCenterComposerFilter
        </filter-class>
      </filter>
      <filter>
        <filter-name>adfBindings</filter-name>
        <filter-class>oracle.adf.model.servlet.ADFBindingFilter</filter-class>
      </filter>
    .....
    
      <!-- composerFilter mapping goes here -->
      <filter-mapping>
        <filter-name>composerFilter</filter-name>
        <servlet-name>Faces Servlet</servlet-name>
        <dispatcher>FORWARD</dispatcher>
        <dispatcher>REQUEST</dispatcher>
      </filter-mapping>
      <filter-mapping>
        <filter-name>adfBindings</filter-name>
        <servlet-name>Faces Servlet</servlet-name>
        <dispatcher>FORWARD</dispatcher>
        <dispatcher>REQUEST</dispatcher>
      </filter-mapping>
    ....
    
  4. Enable sessions for the JSPX pages and task flows that you create in your view project as described in Section 47.2.1, "How to Configure Your Project to Use Application User Sessions."

    This step, among other modifications, adds the Applications Core and Web Service Data Control libraries to your project, which you need to complete the tasks to prepare your application for customization.

61.2.3 How to Enable Translations of Customized Strings

You must configure your application to enable end users to provide translated values for customized strings at runtime, as described in the "Translating Custom Text" chapter in the Oracle Fusion Applications Extensibility Guide.

The resource string editor enables the runtime editing of strings. The changes made using the resource string editor are saved into an application override bundle, which can be translated and imported back into the application.

For more information about configuring the runtime resource string editor, see the "Configuring Runtime Resource String Editing" section in the Oracle Fusion Middleware Developer's Guide for Oracle WebCenter Portal.


Note:

This procedure only enables resource string editing if the changes are customizations and not user personalizations, as user personalizations do not need to be translated.


To set up runtime resource string editing for customizations:

  1. In the Application Navigator in JDeveloper, right-click the application and select Application Properties.

  2. In the Application Properties dialog, select Resource Bundles.

  3. Click Add.

  4. Type the following string in the File Name field in the Select Resource Bundle dialog.

    oracle.adf.view.page.editor.resource.ComposerOverrideBundle.xlf
    
  5. Click Open.

  6. Select the Overridden check box.

  7. Click OK to save your changes.

  8. Open the adf-config.xml file, which is located in the Application Resources > Descriptors > ADF META_INF folder.

  9. Add the resource-string-editor element shown in Example 61-2 to the page-editor-config section to enable resource string editing.

    Example 61-2 Configuration to Turn On Resource Editor

    <pe:page-editor-config>
      ...
      <resource-string-editor>
        <enabled>
          #{GlobalAreaBackingBean.tipLayerNonUser}
        </enabled>
      </resource-string-editor>
    </pe:page-editor-config>
    

61.2.4 How to Add Composer Technology Scope to Your Project

You must add the Oracle WebCenter Portal — Composer technology scope in order to access the technologies for consuming Page Composer components and enabling runtime customization.

To add Composer technology scope: 

  1. Right-click your view project and select Project Properties.

  2. Select Technology Scope.

  3. Add the Oracle WebCenter Portal Composer technology scope to your project and click OK.

61.2.5 How to Enable the User Customization of the UI Shell Template

You can configure the UI Shell template so that it can be customizable out-of-the-box. This functionality enables customers to use Page Composer to customize UI Shell pages, as described in the "Customizing Existing Pages" chapter in the Oracle Fusion Applications Extensibility Guide.

To enable users to customize the UI shell template, you add a link or button to the page fragment from which you want end users to launch the UI Shell template for editing. You then configure the link (or button) to enable end users to modify the template.

To enable the user customization of the UI Shell Template:

  1. From JDeveloper, open the JSF page fragment (.jsff) from where the UI Shell can be edited.

  2. In the Application Navigator, expand the Data Controls hierarchy to locate and expand the FndUIShellController.

  3. Drag and drop the customizeUIShellTemplate operation onto the page, and choose Create > Method > ADF Button or choose Create > Method > ADF Link.

  4. In the Edit Action Binding dialog, provide a comma delimited list of fully packaged qualified customization classes for the custClass parameter, as shown in Example 61-3.

    Example 61-3 Sample custClass List

    oracle.apps.fnd.applcore.customization.GlobalCC,oracle.apps.fnd.applcore.customization.SiteCC
    

    Each of the customization classes supplied in the list must be valid and configured in the adf-config.xml file, as shown in Figure 61-2.

    Figure 61-2 adf-config.xml — Customization Classes

    adf-config.xml - Customization Classes

    If any of the classes cannot be instantiated, or if they are not pre-configured in the adf-config.xml file, an exception is thrown at runtime.

    The last customization class specified is the tip customization layer and the modifications to the UI Shell is written to this layer. In Example 61-3, the customization of the UI Shell takes place in SiteCC. The purpose of the earlier customization in the list is to view the UI Shell with any other customizations applied.

    For information about customization layers, see the "Understanding Customization Layers" section in the Oracle Fusion Applications Extensibility Guide.

  5. Click OK.

  6. Open the page definition file for the page fragment.

  7. In the editor window, click the Source tab.

  8. Add the <methodAction> element shown in Example 61-4 to the <bindings> element. The id attribute must be set to custNavigate, which is the key to the customizeUIShellTemplate operation that you dropped on the page in Step 3.

    Example 61-4 custNavigate methodAction Binding

      <bindings>
        <methodAction id="custNavigate" RequiresUpdateModel="true"
                      Action="invokeMethod" MethodName="navigate"
                      IsViewObjectMethod="false" DataControl="FndUIShellController"
                      InstanceName="FndUIShellController.dataProvider"
                      ReturnName=
    "FndUIShellController.methodResults.navigate_FndUIShellController_dataProvider_navigate_result">
          <NamedData NDName="viewId" NDValue="TemplateCustomizationUIShell"
                     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"
      NDType="oracle.apps.fnd.applcore.patterns.uishell.ui.bean.FndMethodParameters"/>
        </methodAction>
      </bindings>
    
  9. Add the view permission for oracle_apps_fnd_applcore_template_customization_TemplateCustomizationUIShellPageDef (the customization page) for each role for which you want to enable the view action as described in Section 61.3.4, "How to Authorize the Runtime Customization of Pages and Task Flows." To access oracle_apps_fnd_applcore_template_customization_TemplateCustomizationUIShellPageDef in the Resource Grants navigation tab, select Web Page from the Resource Type dropdown list and select Show web pages imported from ADF libraries.

61.2.6 How to Create a Database Connection at the IDE Level

In addition to the application level connection to your application database, you might also need to create an Integrated Development Environment (IDE) connection.

The IDE connection is required when implementing design-time customizations from JDeveloper, as described in the "Using JDeveloper for Customizations" chapter in the Oracle Fusion Applications Extensibility Guide.

To create a database connection at the IDE level

  1. From the Database Navigator, right-click the ApplicationDB node under your application's node and choose Properties.

  2. Make a note of the settings and click Cancel.

  3. Right-click IDE Connections and choose New Connection.

  4. Enter the settings that you noted in Step 2.

  5. Click Test Connection to ensure the settings are correct.

  6. Click OK.

    The database connection appears under the IDE Connections node.

61.3 Enabling Runtime Customization of Pages and Components

Once you have completed the non-optional procedures described in Section 61.2, "Preparing an Application for Customizations," you can enable pages, task flows, and components for runtime customization.

To enable an application's pages, task flows, and components for runtime customization:

  1. Enable runtime customization of web pages.

  2. Enable end-user personalization for the desired pages.

  3. (Optional) Restrict customizations of specific page fragments and components. (By default, customization is allowed for pages, page fragments, and the components on a page.)

  4. Authorize runtime customization of pages and task flows.

  5. (Optional) Enable and disable persistence of attributes for implicit runtime customizations.

As shown in Figure 61-3, the settings that you make by following the procedures in this section affect whether an end user can customize an object under the following scenarios.

To determine whether customization is allowed, the application looks at the component's Customization Allowed property to see if it has an explicit value. If there is no explicit value, the application looks at the parent object and continues up the tree, ending at the JSF page fragment (.jsff root), until it finds an explicit value. For example, if Customization Allowed is not set for a component, but is set to true for the page fragment, then customization is allowed for the component. However, if Customization Allowed is false for the component, the application disallows customization of that object, even if the page fragment's Customization ABllowed property is set to true. Conversely, if the page fragment's Customization Allowed property is set to false, but a component's property is set to true, the end user can customize the component.

By default the Customization Allowed property for the page (.jspx) root is true. Therefore, you must explicitly set Customization Allowed to false at some level, such as for a component, region, fragment (.jsff), or page (.jspx), to disallow customization for that object and its children objects.


Note:

You can optionally use the Customization Allowed By property to permit customizations only for certain roles.


Figure 61-3 Runtime Effects of Customization Settings

Runtime effects of customization settings

61.3.1 How to Enable Pages for Runtime Customization

Perform the following steps to enable runtime customization of a web page using Page Composer:

  1. Ensure that the customizable pages have page definition files.

  2. Make pages runtime editable by adding Page Composer components to the pages.

  3. If you are enabling the runtime addition of content, set up a resource catalog.

  4. (Optional) Set up a default catalog definition file to facilitate testing.

61.3.1.1 Ensuring Customizable Pages Have Page Definitions

Page definition files define the binding objects that populate data the data in UI components at runtime. A page definition is required for runtime customizations that add additional components such as task flows and portlets. Page definition files can be found under Projects > View Controller > Application Sources > oracle.apps.view. If a required page definition file does not exist, complete the following steps to create one.

To create a page definition file for a JSPX page: 

  1. In the Application Navigator, right-click the JSPX page and choose Go to Page Definition.

  2. If the page does not have a page definition, a Confirm Create New Page Definition dialog appears. Click Yes to create the page.

61.3.1.2 Making a JSPX Document Editable at Runtime

To make a JSPX document editable at runtime, you add Composer components to the page at design time. You use the Panel Customizable component to define an area of the page onto which users can add components at runtime. You use the Layout Customizable component to enable users to lay out its child components in several predefined ways, such as two-column or three-column.

The Layout Customizable and Panel Customizable components are from the Oracle WebCenter Portal — Composer technology scope, which you added when you completed the steps in Section 61.2.4, "How to Add Composer Technology Scope to Your Project," and which are available from the Composer page in the Component Palette.

For more information about the Panel Customizable and Layout Customizable components, see the "Composer Components" section in the Oracle Fusion Middleware Developer's Guide for Oracle WebCenter Portal.

61.3.1.3 Setting Up a Resource Catalog

If you have a Panel Customizable component on your page to enable the runtime addition of content, you must set up a resource catalog to list the available content.

To learn how to create a custom resource catalog, see the "Creating and Managing Resource Catalogs" chapter in the Oracle Fusion Middleware Developer's Guide for Oracle WebCenter Portal.

61.3.1.4 Using the Default Catalog Definition File for Testing

A considerable amount of work is involved in setting up a resource catalog. If you want to test runtime customizations before you finish setting up your catalog, you can use the default catalog definition file.

To use the default catalog for testing: 

  1. Create the application_root/ViewController/src/oracle/adf/rc/metadata directory structure.

  2. Copy the Oracle WebCenter Portal default catalog definition file default-catalog.xml to the newly created application_root/ViewController/src/oracle/adf/rc/metadata directory.


Caution:

The Oracle WebCenter Portal default catalog should only be used for testing purposes. You must create your own catalog for production purposes.


61.3.2 How to Enable End-User Personalizations for a Page

Control whether an end user can personalize a page by setting the page's isPersonalizableInComposer property.


Note:

You must enable personalizations for all your dashboards. However, workareas should have personalizations enabled only if absolutely required.


To enable end-user personalizations: 

  1. In the Application Navigator, select the .jspx page.

  2. In the Structure window, select the af:pageTemplate component.

  3. In the Property Inspector, select true from the isPersonalizableInComposer dropdown list.

61.3.3 How to Restrict Customization of a Page, Page Fragment, or Component

Customization is enabled for pages, page fragments, and components by default. However, there might be situations where you want to prevent customization for some objects.

You can specify at the page, page fragment, or component level whether customizations for a component are permitted at runtime and who is permitted to customize that component.

Before you begin:

Review the introduction to Section 61.3, "Enabling Runtime Customization of Pages and Components" to understand how the application uses the value of the Customization Allowed property to determine whether an object can be customized.

To restrict customization of a page, page fragment, or component:

  1. In the Application Navigator, select the page or fragment for which you want to edit customization properties.

  2. If you are restricting the customization of a component, select the component in the Structure window.

  3. If the Property Inspector is not open, choose Property Inspector from the View menu.

  4. In the Property Inspector, expand Customization.

  5. Set the appropriate customization attribute.

    • To disable runtime customization, set Customization Allowed to false.

    • To restrict customization to specific sets of users and layers, set Customization Allowed By to a space-separated list of the security roles for which you wish to permit customization.

For more information about these attributes, see the "Extended Metadata Properties" section in the Oracle Fusion Middleware Fusion Developer's Guide for Oracle Application Development Framework (Oracle Fusion Applications Edition).

For information about customization layers, see the "Understanding Customization Layers" section in the Oracle Fusion Applications Extensibility Guide.

61.3.4 How to Authorize the Runtime Customization of Pages and Task Flows

As illustrated in Figure 61-3 a user can edit customizable components in a user interface page at runtime only if they have permission to edit the page and permission to edit the task flow that contains the component. For example, an end user can only customize components in a task flow using Page Composer if that user has permission to customize the task flow. You use the jazn-data.xml file to define which roles can edit the page or task flow.

Before you begin:

Enable the desired pages for editing in Page Composer as described in Section 61.3, "Enabling Runtime Customization of Pages and Components."

To authorize pages and task flows for runtime customizations:

  1. In the Application Resources panel, expand Descriptors, expand META-INF nodes, and then double-click jazn-data.xml.


    Tip:

    If the jazn-data.xml file does not exist, you can create it by right-clicking the META-INF node, selecting New Oracle Deployment Descriptor, selecting jazn-data.xml, and then clicking Finish.


  2. In the overview editor, click the Resource Grants navigation tab, as shown in Figure 61-4.

    Figure 61-4 Resource Grants Tab in jazn-data.xml Overview

    Resource Grants Tab in jazn-data.xml Overview
  3. Select Web Page from the Resource Type dropdown list.

    You use the Web Page resource type for both web pages and page fragments.

  4. Set the Source Project to ViewController.

  5. For each Page Composer enabled web page, select the Customize action for each role for which you want to enable page customization.

    You must also authorize customization for the task flows, as described in the following two steps.

  6. Select Task Flow from the Resource Type dropdown list.

  7. For each task flow, select the Customize action for each role for which you want to enable customization of the components in the task flow.

  8. If you want the task lists that are exposed in your pages to be customizable for your application, select the entry for TaskList in the Resources list, and, for each role for which you want to enable task list customization, select the customize and grant actions.

For more information, see the "Implementing Task Flow Security" section in the Oracle Fusion Middleware Developer's Guide for Oracle WebCenter Portal.

61.3.5 How to Persist Implicit Runtime Customizations

Certain ADF Faces components have attributes that can be saved during a user session. For example, if a user expands a panel box component, the box will be expanded when the user returns to the page. This type of change is referred to as implicit runtime customization. For information about which component properties can be persisted, see the "Allowing User Customizations at Runtime" chapter in the Oracle Fusion Middleware Fusion Developer's Guide for Oracle Application Development Framework (Oracle Fusion Applications Edition).

In Section 61.2.1, "How to Set Project Properties to Enable User and Seeded Customizations," you configured the application to persist implicit runtime customizations across sessions as well as within sessions.

The attributes that can be persisted are set in the tag library, but you can override these settings. For example, you might not want the end users to change column widths, but you want all other default attribute changes for columns to be persisted. You set and unset these values in the Overview Editor for the adf-config.xml file, as described in the "Configuring User Customizations" section in the Oracle Fusion Middleware Fusion Developer's Guide for Oracle Application Development Framework (Oracle Fusion Applications Edition). You can also override these settings for specific components, as described in the "Controlling User Customizations in Individual JSF Pages" section in the Oracle Fusion Middleware Fusion Developer's Guide for Oracle Application Development Framework (Oracle Fusion Applications Edition).

PK2PK BOEBPS/whatsnew.htmt What's New in This Guide

What's New in This Guide

The following topics introduce the new and changed features of the Oracle Fusion Applications Developer's Guide 11g Release 5 (11.1.5) and other significant changes that are described in this guide, and provides pointers to additional information.

New and Changed Features for 11g Release 5 (11.1.5)

The Oracle Fusion Applications Developer's Guide Release 5 (11.1.5) includes the following new and changed features for this document.

PKNҷPK BOEBPS/ui_localize.htm Working with Localization Formatting

20 Working with Localization Formatting

This chapter describes the Oracle Fusion Applications standards and guidelines for working with localization formatting.

20.1 Introduction to Localization Formatting

When developing applications for international users, it is often necessary to format the display of certain location-dependent data. In the context of Oracle JDeveloper and Oracle Application Development Framework, localization requires implementing formatting patterns so as to properly display the data according to local standards.

Currency, dates, numbers and time zones are localized using Oracle ADF Faces components that bind to the attribute to be localized. In some cases, Groovy or Expression Language methods are used to localize a particular UI component.

20.2 Formatting Currency

Currency values may be formatted differently, depending on the currency code associated with the value. Each currency code is associated with formatting such as precision and currency symbols.

You can format currency using the default formatting behavior, or by overriding the default formatting. Alternatively, you can format currency on the fly using partial page rendering.

Currency fields are represented by java.lang.BigDecimal in entity objects and view objects.

A currency field should always be formatted according to the currency code chosen in the context UI of the transaction.

For example, if the user selects JPY as the currency code from the context UI, then the currency value should be formatted according to the Japanese Yen standard.

There are two implementations to format numerical values according to the corresponding currency code.

Currency codes are stored in the FND_Currencies table located in the Oracle Fusion Middleware Extensions for Applications schema. The currency code determines the format mask for the currency field, including:

Precision: Determines the use and number of decimal digits, comma placement, and so on.

Currency symbol: Displays the standard symbol for the currency.

The Expression Language function fnd:currencyPattern() determines formatting for the currency field using the default precision associated with the currency code. No currency symbol or code is displayed in the user interface. The Expression Language function fnd:currencyPatternWithPrecisionAndSymbol() determines formatting for the currency field using an extra parameter for precision. It also uses the currency code to show a currency symbol/code in the user interface. User preferences for grouping and decimal separators are used to format the value in both these functions.

20.2.1 How to Format Currency

To format currency, you must first set the view object custom attribute to type currency and then select the currency code to be used in formatting the currency field. You can specify the currency code by entering its value explicitly, or by writing a Groovy expression in the transient attribute.

Before you begin:

Create an entity object and a view object.

20.2.1.1 Formatting Currency Values

To format currency values, use the fnd:currencyPattern() function to obtain the format pattern of different currency codes. Therefore, a currency field, whether it is used in inputText or outputText, should be formatted with code similar to that shown here.

<af:convertNumber type="currency" currencyCode="#{bindingToAmountCurrencyCode}"
 pattern="#{fnd:currencyPattern(bindingToAmountCurrencyCode)}" />

Here, bindingToAmountCurrencyCode should be replaced with the actual name of the field that allows users to select a currency code.

If <af:convertNumber type="currency" pattern="#{applCorePrefs.numberFormatPattern}"/> is found, then the currency field will be formatted as a number. This is incorrect.

If the field requires displaying currency numbers combined with a currency code or currency symbol, the Expression Language function fnd:currencyPatternWithPrecisionAndSymbol() should be used to get the format pattern.

In Example 20-2, the Amount field is formatted according to the currency code set in the af:convertNumber tag.

Example 20-2 The af:convertNumber Tag Currency Code Determines Amount Format

<af:outputText value="#{node.Amount}" id="ot28">
        <af:convertNumber type="currency" currencyCode="#{bindings.CurrencyCode.attributeValue}" pattern="#{fnd:currencyPattern(bindings.CurrencyCode.attributeValue)}"/>
</af:outputText>

In Example 20-3, the grouping separator and decimal separator are taken from the user's number preferences, and the number of precision digits is set to 2. Also, the symbol shown corresponds to the currency code set in the af:convertNumber tag.

Example 20-3 Number Preferences Determine Grouping and Decimal Separators

<af:outputText value="#{node.Amount}" id="ot28">
        <af:convertNumber type="currency" currencyCode="#{bindings.CurrencyCode.attributeValue}" pattern="#{fnd:currencyPatternWithPrecisionAndSymbol(bindings.CurrencyCode.attributeValue,2,'symbol'}"/>
</af:outputText>

The fields Ordered, Total Tax, and Total in Figure 20-1 show how currency values are formatted in Oracle Fusion Applications.

Figure 20-1 Showing How Currency Values Are Formatted

Showing How Currency Values Are Formatted

20.2.1.2 What Happens When You Format Currency

When dragging and dropping the view object onto a JSF page, Applications Core generates relevant bindings to the Oracle ADF Faces Number Converter attached to the user interface component.

Example 20-4 shows bindings to the Number Converter.

Example 20-4 Bindings to the Number Converter

<af:outputText label="Amount" value="#{bindingToOrderTotal}">
<af:convertNumber 
 pattern="#{applCorePrefs.numberFormatPattern}" />
<af:outputText>

As the developer, you should change the generated code according to either the fnd:currencyPattern() Expression Language function or the fnd:currencyPatternWithPrecisionAndSymbol() Expression Language function as shown in Example 20-5.

Example 20-5 Changing the Generated Code

<af:outputText label="Amount" value="#{bindingToOrderTotal}">
<af:convertNumber type="currency"
 currencyCode="#{bindingToAmountCurrencyCode}"
 pattern="#{fnd:currencyPattern(bindingToAmountCurrencyCode)}" />
<af:outputText>

The bindings indicate that the Expression Language method fnd:currencyPattern() is to be used to return the currency code for the value of the attribute.

20.2.1.3 What Happens at Runtime: How Currency Is Formatted

At runtime, Applications Core Technology evaluates the bindings generated during design time to generate the correct currency format mask for the value. The fnd:currencyPattern() and fnd:currencyPatternWithPrecisionAndSymbol() Expression Language methods return the format mask for a given currency code, accounting for currency precision, currency symbol, and so on.

20.3 Formatting Numbers

All numerical values need to be formatted correctly when they are presented to a user in Oracle Fusion Applications. Users expect that they can enter numerical values based on their formatting preferences, which include such things as options to change the grouping and the decimal separators. Number formatting preferences also let users choose the number format mask that will be used to display the number. For instance, a user might choose that the grouping separator has to be shown once every three digits with a maximum of three decimal digits (#,##0.###). An example is a value of 1234.5 in the database that might have to be displayed as 1 234,500 or 1,234.500 or 1.234,500.

20.3.1 How to Format Numbers

Before you begin:

Create an entity object and a view object with number fields, including any of these attribute types:

java.math.BigDecimal, java.lang.Integer, or java.lang.Long.

The number one thousand two hundred and thirty four point five six can display in any of the following formats:

  • 1,234.56

  • 1'234.56

  • 1'234,56

  • 1.234,56

  • 1234.56 (ISO standard)

  • 1234,56

  • 1 234.56

  • 1 234,56

View objects and entity objects can be formatted so as to display date and number data in accordance with local standards. The ISO standard is typically used when it is not desirable to use local standards.

20.3.1.1 Formatting Decimal Numbers

Decimal output fields should be formatted according to the user's number formatting preferences. Use the <af:convertNumber pattern... entry to retrieve the number formatting pattern from the applCorePrefs bean, as shown in Example 20-6.

Example 20-6 Formatting Decimal Output Fields

<af:outputText value="#{bindings.FromValue.inputValue}" id="ot19">
<af:convertNumber pattern="#{applCorePrefs.numberFormatPattern}"/>
</af:outputText>

Input decimal fields should be formatted according to the user's number preferences. In Example 20-7, use the <af:convertNumber pattern... entry to retrieve the number formatting pattern from the applCorePrefs bean.

Example 20-7 Formatting Input Decimal Fields

<af:inputText value="#{row.bindings.FromValue.inputValue}"
    label="#{bindings.PerformanceThreshold21.hints.FromValue.label}"
    required="#{bindings.PerformanceThreshold21.hints.FromValue.mandatory}"
    columns="#{bindings.PerformanceThreshold21.hints.FromValue.displayWidth}"                                              maximumLength="#{bindings.PerformanceThreshold21.hints.FromValue.precision}"
    shortDesc="#{bindings.PerformanceThreshold21.hints.FromValue.tooltip}"
    id="inputText9"
    autoSubmit="true">
    <af:convertNumber pattern="#{applCorePrefs.numberFormatPattern}"/>
</af:inputText>

The Threshold Start field in Figure 20-2 is an example of a number field that is formatted according to the user's number formatting preferences.

Figure 20-2 Example of a Formatted Number Field

Example of a Formatted Number Field

When a decimal number is to be shown as a part of a larger string object on the user interface, the fnd:formatNumber and fnd:formatNumber2 Expression Language functions provided in the applCore library should be used to format such numbers. When either of these functions is used, the user's number formatting preferences are implemented according to applCorePrefs.numberFormatPattern.

The syntaxes of the two Expression Language functions are:

  • fnd:formatNumber(java.lang.Number decimalValueToBeFormatted)

  • fnd:formatNumber2(java.lang.Number decimalValueToBeFormatted, int maximumNumberOfFractionDigits)

Example 20-8 shows how to use these two functions for decimal number formatting.

Example 20-8 Decimal Number Formatting

<af:image id="img65"
     source="/images/upgreenplus_status.png"
     shortDesc="#{af:formatNamed(prcponnegotiationsuiBundle3['AltTxt.IncreasedbyVALUE.FavorablyIncreasedbyVALUE'], VALUE', fnd:formatNumber(bindings.ActiveResponsesChangeAmt.inputValue))}"
     visible="#{bindings.ActiveResponsesChange.inputValue == 'INCREASE'}"/>

As shown in Example 20-8, the variable ActiveResponsesChangeAmt will be formatted according to the user's number preferences according to applCorePrefs.numberFormatPattern. This formatted number is then concatenated to the externalized string FavorablyIncreasedbyVALUE and displayed to the user.

The fnd:formatNumber2 function has the advantage of explicitly specifying the maximum number of fraction digits in the formatted number, as shown in Example 20-9.

Example 20-9 Using the fnd:formatNumber2 Function

<af:showDetailItem text="#{PjbWorkareaGenBundle['Header.SubmittedValues']} (#{fnd:formatNumber2(pageFlowScope.InvoiceWorkareaBean.invoiceValueRowNum[1],2)})"
       id="tabSubmitted"
       disclosureListener="#{InvoiceListBean.changeStatusTab}"
       partialTriggers="AT1:_ATp:menuSubmit AT1:_ATp:btnSubmit AT2:_ATp:menuApprove AT2:_ATp:menuReject AT2:_ATp:menuRelease AT2:_ATp:menuReturntoDraft cl1"
       stretchChildren="first"
       disclosedTransient="true"
       disclosed="#{pageFlowScope.pageFocus == '2'}">

Here, the text attribute of the af:showDetailItem tag includes a number that must be formatted before being displayed. Therefore, the fnd:formatNumber2 Expression Language function has been used to format the number to be added to the SubmittedValues string. Here, the second parameter has been set to 2 and indicates that a maximum of two fractional digits can be shown in the decimal number. So, for example, after formatting, the number 1234.56789 that is retrieved from the database will be displayed as SubmittedValues: 1,234.57.

20.3.1.2 Formatting Integer Numbers

Integer output fields should be formatted according to the user's number formatting preferences without any decimal precision digits. For instance, the number 12345.00 stored in the database might have to be shown as 12,345 or 12.345 or 12 345 for a certain user. Notice that there is no decimal separator or any precision digits shown in these numbers. As shown in Example 20-10, use the <af:convertNumber pattern... entry to retrieve the number formatting pattern from the applCorePrefs bean.

Example 20-10 Formatting Integer Numbers

<af:outputText value="#{bindings.integerQuantity.inputValue}" id="ot19">
<af:convertNumber pattern="#{applCorePrefs.integerFormatPattern}"/>
</af:outputText>

Input integer fields should be formatted according to the user's number preferences without showing any decimal precision digits. As shown in Example 20-11, use the <af:convertNumber pattern... entry to retrieve the number formatting pattern from the applCorePrefs bean.

Example 20-11 Formatting Input Integer Fields

<af:inputText value="#{bindings.Point1.inputValue}"
        label="#{bindings.Point1.hints.label}"
        required="#{bindings.Point1.hints.mandatory}"
        columns="#{bindings.Point1.hints.displayWidth}"
        maximumLength="#{bindings.Point1.hints.precision}"
        shortDesc="#{bindings.Point1.hints.tooltip}"
        inlineStyle="width:100%; border-color:InactiveBorder; border-width:thin;"
        id="inputText5">
    <f:validator binding="#{bindings.Point1.validator}"/>
    <af:validateLongRange minimum="0"/>
    <af:convertNumber pattern="#{applCorePrefs.integerFormatPattern}"/> 
 </af:inputText>

In Figure 20-3, Point 1 is an example of an input integer field that is formatted according to the user's number preferences without showing the decimal separator or any precision digits.

Figure 20-3 Example of a Formatted Integer Field

Example of a Formatted Integer Field

When an integer number is to be shown as a part of a larger string object on the user interface, the fnd:formatNumber2 function provided in the applCore library should be used to format such numbers. When this function is used with the maximum number of precision digits set to 0, the user's number formatting preferences are used from applCorePrefs.numberFormatPattern with no precision digits.

The syntax of the fnd:formatNumber2 function is as follows:

fnd:formatNumber2(java.lang.Number integerValueToBeFormatted, int maximumNumberOfFractionDigits)
 

The fnd:formatNumber2 function can be used to format integer numbers by explicitly specifying the maximum number of fraction digits as 0 in the formatted number. Example 20-12 shows how to use the fnd:formatNumber2 function for integer number formatting.

Example 20-12 Formatting Integers Using fnd:formatNumber2

<af:showDetailItem text="#{PjbWorkareaGenBundle['Header.SubmittedInvoices']} (#{fnd:formatNumber2(pageFlowScope.InvoiceWorkareaBean.invoiceValueRowNum[1],0)})"
       id="tabSubmitted"
       disclosureListener="#{InvoiceListBean.changeStatusTab}"
       partialTriggers="AT1:_ATp:menuSubmit AT1:_ATp:btnSubmit AT2:_ATp:menuApprove AT2:_ATp:menuReject AT2:_ATp:menuRelease AT2:_ATp:menuReturntoDraft cl1"
       stretchChildren="first"
       disclosedTransient="true"
       disclosed="#{pageFlowScope.pageFocus == '2'}">

Here, the text attribute of the af:showDetailItem tag includes a number that must be formatted before being displayed. The fnd:formatNumber2 function is used to format the integer to be added to the SubmittedInvoices string. The second parameter has been set to 0 and indicates that no fractional digits can be shown in the formatted number. For example, after formatting, the number 1234 that is retrieved from the database will be displayed as SubmittedInvoices: 1,234.

20.3.1.3 Formatting ID Numbers

An ID field is a number field that uniquely identifies an object. Typical examples of ID fields include TransactionID, Sequence Number, and Item Number. Such ID output fields should be formatted without using the user's number formatting preferences. That is, ID output fields should not display decimal precision digits or grouping separators. For example, a student's admission number should be displayed as 14567 instead of 14,567.00. The <af:convertNumber pattern... entry in Example 20-13 retrieves the number formatting pattern from the applCorePrefs bean.

Example 20-13 Formatting ID Numbers

<af:column headerText="#{bindings.Deliveries.hints.SalesOrderLine.label} id="c9" >
<af:outputText value="#{row.bindings.SalesOrderLine.inputValue}"                            
label="#{bindings.Deliveries.hints.SalesOrderLine.label}" id="outputText3">
       <af:convertNumber pattern="#{applCorePrefs.numericCodeFormatPattern}"/>
 </af:outputText>
</af:column>

Note:

ID fields always should be aligned to the left. As a developer, you must not hardcode the align attribute of the column attribute of an af:table, or the contentStyle attribute of the af:outputText tag displaying an ID field. By default, Oracle ADF supports start alignment that is appropriate for ID fields.


The field Sales Order Line in Figure 20-4 corresponds to the output ID field shown in the above sample code.

Figure 20-4 Sample Output ID Field

Example Output ID Field

Input integer fields should be formatted according to the user's number preferences without showing any decimal precision digits or grouping separators. The <af:convertNumber pattern entry in Example 20-14 indicates that the number formatting pattern is being retrieved from the applCorePrefs bean.

Example 20-14 Formatting Input Integer Fields

<af:inputText value="#{bindings.SequenceNumber.inputValue}"
         label="#{bindings.SequenceNumber.hints.label}"
         required="#{bindings.SequenceNumber.hints.mandatory}"
         columns="#{bindings.SequenceNumber.hints.displayWidth}"
         id="inputText1"
         partialTriggers="asgStat"
         helpTopicId="InvCoreSetup_755E15370133C364E040D30A688161D5V000"
         contentStyle="text-align:start"
         autoSubmit="true">
     <f:validator binding="#{bindings.SequenceNumber.validator}"/>
     <af:convertNumber pattern="#{applCorePrefs.numericCodeFormatPattern}"/>
 </af:inputText>

The field Sequence in Figure 20-5 corresponds to the input ID field shown in the above sample code.

Figure 20-5 Example Input ID Field

Example Input ID Field

The fnd:formatNumber() and fnd:formatNumber2() functions must not be used for ID fields appearing in strings, because they introduce a grouping separator in number fields, which should not be displayed in ID fields. In such cases, output ID fields should be treated as normal text fields.

20.3.1.4 How to Format Numbers in Hyperlinks

In Oracle Fusion Applications, hyperlinks are represented by af:commandLink and af:goLink. All numbers found in the labels of hyperlinks in the user interface must be formatted according to the user's number preferences. The number might either have to be formatted according to numberFormatPattern if the number value is decimal in nature, integerFormatPattern if the number value is integer only, and need not be formatted at all if the value corresponds to an ID value. Code to format numbers in hyperlinks is shown in Example 20-15.

Example 20-15 Formatting Numbers in Hyperlinks

<af:commandLink id="outputText6" text="" 
                partialSubmit="true" immediate="true" 
                action="#{LocalAreaHandlerBean.showInventory}">
<af:outputText value="#{row.InvPendingCount}" id="ot1">
        <af:convertNumber type="number" pattern="#{applCorePrefs.integerFormatPattern}"/>
</af:outputText>
</af:commandLink>

Because af:convertNumber is not a valid child tag of af:commandLink, the best way to format a number on a link is by making the text attribute of the af:commandLink tag empty and then adding an af:outputText tag as a child tag that displays the formatted numerical value. In this case, the number is an integer (java.lang.Integer), so the pattern applCorePrefs.integerFormatPattern has been used. In cases of decimal numbers (java.math.bigDecimal), applCorePrefs.numberFormatPattern has to be used, while in cases of ID fields (java.lang.Long), af:convertNumber can be removed and the field can be honored as plain text. The parent hyperlink tag can be either af:commandLink or af:goLink.

Similarly, numbers that are found on links represented by the af:goLink tag in Oracle Application Development Framework (Oracle ADF) should be formatted according to the user's number formatting preferences using the Preferences bean. The procedure to be followed is very similar to that of the af:commandLink tag. Sample code for number formatting in af:golink is shown in Example 20-16.

Example 20-16 Formatting a Number in af:goLink

<af:goLink text="" id="gl1"  destination="#{row.children[0].FileUrl}">
          <af:outputText id="id1" value="#{bindings.fromValue.inputValue}">
                <af:convertNumber type="number" pattern="#{applCorePrefs.numberFormatPattern}"/>
           </af:outputText>
 </af:goLink>

Again, af:goLink cannot have an af:convertNumber as its child tag, so the text attribute of the goLink tag should be made empty and af:outputText should be added as a child tag of af:goLink. The af:convertNumber then can be added as a subtag of the outputText tag. The pattern attribute can be changed for this af:convertNumber tag, according to whether the number is decimal or an integer. If the number represents an ID field, no number formatting is needed.

Another way of formatting the text in af:commandLink and af:goLink is by using the Expression Language functions fnd:formatNumber and fnd:formatNumber2 in their text attributes. Sample code to format a number in a commandLink using the fnd:formatNumber2 Expression Language function is shown in Example 20-17.

Example 20-17 Formatting a Number in a commandLink

<af:commandLink id="outputText6" text="#{fnd:formatNumber2(row.InvPendingCount,0)}" 
                partialSubmit="true" immediate="true" 
                action="#{LocalAreaHandlerBean.showInventory}">
</af:commandLink>

Here, the second parameter has been set to 0 so that no precision digits are shown. This is the same as using pattern="#{applCorePrefs.integerFormatPattern}" as used in Example 20-15. The only added feature in this example is that there is no need to add a child af:outputText tag for number formatting.

Similarly, af:goLink can also be formatted using the fnd:formatNumber and fnd:formatNumber2 Expression Language functions. An example of formatting the af:goLink shown in Example 20-16 using the fnd:formatNumber function is shown in Example 20-18:

Example 20-18 Formatting af:goLink Using fnd:formatNumber

<af:goLink text="#{fnd:formatNumber(bindings.fromValue.inputValue)}" id="gl1"  destination="#{row.children[0].FileUrl}"/>

Here, the fnd:formatNumber Expression Language function has been used to format the value in the af:goLink. This is the same as using pattern="#{applCorePrefs.numberFormatPattern}" as shown in Example 20-16.

20.3.1.5 How to Format Percentage Values

A percentage value maps to java.math.BigDecimal in entity object and view object files and NUMBER(n, m) (where m!=0) in underlying database columns.

Such percentage values in output fields must be displayed in a locale-sensitive format. For example, 75.68% in en_US (Language: English Territory: United States) should be displayed as 75,68 % (there is a space between the number and the percentage sign) in the fr_FR (Language: French Territory: France) locale.

The number and percentage sign of a percentage value should always be displayed in a user preferred format in Oracle Fusion applications. Sample code that can display percentage values is shown in Example 20-19.

Example 20-19 Displaying Percentage Values

<af:outputText value="#{row.PercentComplete != null ? (row.PercentComplete * 0.01):  row.PercentComplete}"
                   id="outputText5">
     <af:convertNumber minFractionDigits="2" maxFractionDigits="2" 
                   type="percent"/>
     <af:showPopupBehavior triggerType="click"
                   popupId=":::progressTrendPopup"
                   alignId="rowHeadCol"/>
 </af:outputText>

Here, maxFractionDigits can be determined by the underlying database column type using this formula:

maxFractionDigits = The scale of database Column Data Type - 2

For example, if the database column data type is NUMBER(8,4), maxFractionDigits can be "2". If "The scale of database Column Data Type - 2" <=0, attribute maxFractionDigits should not be added to the convertNumber tag.

This formula arises from the fact that a percentage value like 1% usually is stored in the database column as 0.01. Hence, the maximum number of fraction digits in the percentage value to be displayed on the user interface will always be 2 less than the scale of the database column.

In Oracle Fusion applications, you must not hardcode the % sign in the value attribute of the outputText tag, because this makes the percentage values locale-insensitive.

The Percent of Project Work Complete field in Figure 20-6 corresponds to the output percentage field shown in Example 20-19.

Figure 20-6 Results of Output Percentage Field

Results of Output Percentage Field

A percentage value in an input field generally is formatted exactly like the output percentage field. Sample code to format input percentage fields is shown in Example 20-20.

Example 20-20 Formatting Input Percentage Fields

<af:inputText value="#{bindings.PercentQuantity.inputValue}"
        label="#{bindings.PercentQuantity.hints.label}"
        autoSubmit="true"
        id="inputText10"
        <f:validator binding="#{bindings.PercentQuantity.validator}"/>
        <af:convertNumber type="percent" minFractionDigits="2" maxFractionDigits="2"/>
</af:inputText>

20.3.2 What Happens When You Format Numbers

All number formatting patterns default to the formats described in Section 20.3.1, "How to Format Numbers."

When dragging and dropping a view object containing an attribute of type java.math.BigDecimal or java.lang.Integer, or java.lang.Long, Applications Core generates code that binds to the numberFormatPattern property in the applCorePrefs managed bean as shown in Example 20-21.

Example 20-21 Bindings to the numberFormatPattern Property

<af:convertNumber pattern="#{applCorePrefs.numberFormatPattern}"/> 

20.3.3 What Happens at Runtime: How Numbers Are Formatted

At runtime, the bindings generated at design time are executed. Numbers are displayed according to user preferences for number formatting patterns, such as 1,234.567.

20.4 Formatting Date and Timestamp Values

All date values must be formatted correctly when they are presented to a user. Users expect to input values according to their date formatting preferences. For instance, a value of 13 August, 2011 in the database might have to be displayed as 08/13/2011 or 2011.8.13. A similar example of a date-time value is a value of 26 July 2011, 2:00:00 PM might have to be displayed as 14:00 07/26/2011 or 2011.7.26 02:00:00 PM.

20.4.1 How to Format Dates and Timestamp Values

Before you begin:

Create an entity object and a view object with date fields, including either of these attribute types: java.sql.Date or java.sql.Timestamp.

20.4.1.1 Formatting Dates

Dates without time values (called dates) are mapped to java.sql.Date in the entity object/view object layer. These fields should be formatted according to the user's date formatting preferences.

The <af:convertDateTime pattern... entry in the sample code retrieves the date formatting pattern from the applCorePrefs bean.

<af:column sortProperty="OrderDate" filterable="true" 
sortable="true"headerText="#{bindings.NlsOrders1.hints.OrderDate.label}" id="c1">
<f:facet name="filter">
<af:inputDate value="#{vs.filterCriteria.OrderDate}" 
                       id="id8" >
                        <af:convertDateTime pattern="#{applCorePrefs.dateFormatPattern}"/>
                </af:inputDate>
</f:facet>
<af:inputDate value="#{row.bindings.OrderDate.inputValue}"
label="#{bindings.NlsOrders1.hints.OrderDate.label}"                                required="#{bindings.NlsOrders1.hints.OrderDate.mandatory}"                                shortDesc="#{bindings.NlsOrders1.hints.OrderDate.tooltip}"
                        id="id1">
<f:validator binding="#{row.bindings.OrderDate.validator}"/>
<af:convertDateTime pattern="#{applCorePrefs.dateFormatPattern}"/>
</af:inputDate>
</af:column>
 

Both the filter for the date and the date field should be formatted according to the user's date formatting preferences. If this is not done, the dates will not be displayed according to the user's preferences.

The values for the Due Date field in Figure 20-7 are examples of how a date value is formatted according to the user's preferences in Oracle Fusion Applications.

Figure 20-7 Example of a Formatted Date Value

Example of a Formatted Date Value

20.4.1.2 Formatting Current Dates

Applications often show the current date on the user interface. They are mapped to the java.sql.Date data type in the entity object/view object layer. Correctly identifying the date requires the use of particular APIs.

A server date is calculated by truncating the time portion of the current time from the system clock. However, it may not be appropriate to display the server date to end users if they are not located in the server time zone. For example, when creating an order, the order form may display with the order date filled out for the end user with the current date. In this case, the order date must be the end user's local date rather than the server date. A server in the US may be serving an end user in China, whose local date may be one day ahead due to time zone differences. It is necessary to adjust the server date to the end user's local date.

This sample shows how to adjust the server date to the local date in the Java bean.

public Date getCurrentLocalDate() {
    // Get the current date and time.
    long date = new java.util.Date().getTime();
    // Get the user preferred time zone from the ApplCore PreferencesBean.
    TimeZone uptz = TimeZone.getTimeZone(pb.getUPTZ());
    // Get the server time zone.
    TimeZone crtz = TimeZone.getDefault();
    // Calculate the time zone offset difference and return an adjusted date.
    int uptzoff = uptz.getOffset(date);
    int crtzoff = crtz.getOffset(date);
    int diff = uptzoff - crtzoff;

return new Date(date+diff);

}
 

This sample shows how to display the current date in the JSF page.

<af:inputDate binding="#{localDateBean.currentLocalDate}"
           value="#{bindings.StartDate.inputValue}"
             label="#{bindings.StartDate.hints.label}(Type: java.sql.Date)"
             required="#{bindings.StartDate.hints.mandatory}"
             shortDesc="#{bindings.StartDate.hints.tooltip}"
             id="id1">
     <af:convertDateTime pattern="#{applCorePrefs.dateFormatPattern}"/>
</af:inputDate>
 

This workaround can be used only if there is no middleware tier validation for the date field. For example, if the middleware tier validation has a condition that the date field's value cannot be more than the middleware tier's system time, the conversion with the above method will generate a validation error. In such cases, you would need the ATG enhancement to convert the server time zone date to the user's preferred time zone.

The Required Date field in Figure 20-8 should default to the user's preferred time-zone rather than the server time-zone.

Figure 20-8 Example of a Field to Default to User's Time

Example of a Field to Default to User’s Time

20.4.1.3 Formatting Timestamp Values

Dates with time values (called datetimes) are mapped to java.sql.Timestamp in the entity object/view object layer. Format these fields according to the user's date and time formatting preferences.

All datetime fields must have at least one of these three patterns in the af:convertDateTime tag to be formatted according to the user's date and time preferences.

  • Pattern 1

    pattern="#{applCorePrefs.UPTZPattern}"
    

    applCorePrefs.UPTZPattern returns a pattern by combining the selection of the Date Format and the Time Format in User Preferences. For example, if a user selects M.d.yyyy (4.28.2010) from the Date Format list, and HH.mm (00.55) from the Time Format list, applCorePrefs.UPTZPattern returns a pattern M.dd.yyyy HH:mm. Therefore, applCorePrefs.UPTZPattern may return a pattern with or without Seconds, depending on the selection in User Preferences.

  • Pattern 2

    This pattern is applicable if it always needs to display the Seconds part of a datetime value.

    pattern="#{applCorePrefs.DateFormatPattern} #{applCorePrefs.timeFormatPatternWithSeconds}"
    

    Note that there is a single space between the two Expression Language expressions.

  • Pattern 3

    pattern="#{applCorePrefs.DateFormatPattern} #{applCorePrefs.timeFormatPatternWithoutSeconds}"
    

    Note that there is a single space between the two Expression Language expressions.

    This pattern is applicable if it does not need to display the Seconds part of a date-time value.

Both the filter for the date-time and the date-time field should be formatted according to the user's date and time formatting preferences, as shown in this sample code. If this is not done, these fields will not be processed according to the user's preferences.

<af:column sortProperty="LastUpdateDate" filterable="true" 
sortable="true"
headerText="#{bindings.NlsOrders1.hints.LastUpdateDate.label}"
        id="c1">
<f:facet name="filter">
<af:inputDate value="#{vs.filterCriteria.LastUpdateDate}" 
                       id="id8" >
                        <af:convertDateTime pattern="#{applCorePrefs.UPTZPattern}"/>
                </af:inputDate>
</f:facet>
<af:inputDate value="#{row.bindings.LastUpdateDate.inputValue}"
label="#{bindings.NlsOrders1.hints.LastUpdateDate.label}"                                required="#{bindings.NlsOrders1.hints.LastUpdateDate.mandatory}"                                shortDesc="#{bindings.NlsOrders1.hints.LastUpdateDate.tooltip}"
                       id="id1">
<f:validator binding="#{row.bindings.LastUpdateDate.validator}"/>
<af:convertDateTime pattern="#{applCorePrefs.UPTZPattern}"/>
</af:inputDate>
</af:column> 
 

The Last Saved field at the top right of Figure 20-9 is an example of how a date-time is formatted according to the user's preferences in Oracle Fusion Applications.

Figure 20-9 Example of a Formatted Date and Time

Example of a Formatted Date and Time

20.4.2 What Happens When You Format Dates and Timestamps

When dragging and dropping a view object containing an attribute of type java.sql.Date or java.sql.Timestamp , Applications Core generates code that binds to the dateFormatPattern (date fields) or UPTZPattern (timestamp fields) property in the applCorePrefs managed bean.

This sample shows bindings to the dateFormatPattern property. The pattern according to which the date value is formatted is picked up from the Preferences bean in applCore, which in turn accesses these values from the LDAP server configured with users' roles and policies.

<af:panelLabelAndMessage label="#{bindings.OrderDate.hints.label}"
                                 id="plam1">
          <af:outputText value="#{bindings.OrderDate.inputValue}" id="ot1">
            <af:convertDateTime pattern="#{applCorePrefs.dateFormatPattern}"/>
          </af:outputText>
        </af:panelLabelAndMessage>
 

This type of code is generated for both date and timestamp fields. For date fields, you should add the type="date" attribute, whereas for timestamp fields, you should add the type="both" attribute, and make the pattern attribute equal to one of the three patterns discussed above.

20.4.3 What Happens at Runtime: How Dates and Timestamps Are Formatted

At runtime, the bindings generated at design time are executed. Dates and Timestamps are displayed according to user preferences for date and time formatting patterns (for example, 01/01/10 and 01/01/10 01:05:00).

20.4.4 Standards and Guidelines for Formatting Dates and Timestamps

The following standards and guidelines apply to formatting dates and timestamps.

  • All date-only fields must be represented only by java.sql.Date data types.

  • When a value bound to a field is date-only of type java.sql.Date, do not set the time zone to af:convertDateTime.

20.5 Formatting Time Zones

Date values with time (called datetime values) are mapped to java.sql.TimeStamp in the entity object and view object layer. In Oracle Fusion Applications, datetime values can be calculated according to one of these time zones:

The business logic of the application decides which time zone to use to calculate the date-time value.

20.5.1 How to Format Time Zones

The different types of tags required to implement either the User Preferred Time Zone or Legal Entity Time Zone are shown in this section.

Before you begin:

Create an entity object and a view object with date fields, and include the java.sql.Timestamp attribute type. Note that the middle-tier time zone and the database time zone always must match. If they do not match, the conversions will be invalid.

Using the Server Reporting Time Zone

Use this code sample if the date-time value is to be calculated according to the Server Reporting Time Zone:

<af:outputText value="#{bindings.StartDate.inputValue}" ... >
                        <af:convertDateTime type="both" pattern="#{applCorePrefs.UPTZPattern}" />
</af:outputText>

This is to say that nothing needs to be explicitly added into the automatically generated af:convertDateTime tag.

Using the User Preferred Time Zone

Use this code sample to calculate the date-time value according to the User Preferred Time Zone:

<af:outputText value="#{bindings.StartDate.inputValue}" ... >
                        <af:convertDateTime type="both" pattern="#{applCorePrefs.UPTZPattern}" timeZone="#{applCorePrefs.UPTZ}" />
</af:outputText>

Converting a Timestamp to the Legal Entity Time Zone

Follow this method to convert a timestamp value to the Legal Entity Time Zone:

Retrieve the Legal Entity time zone. Each legal entity has a LETZ. Determining a LETZ starts with a legal entity's address that is used to look up a specific location and a unique time zone attribute. This time zone is the LETZ for the legal entity.

Related tables in the database are:

FND_TIMEZONES_B and FND_TIMEZONES_TL, tables to record time zone related information.

XLE_REGISTRATIONS, a table of Legal Entity data.

HZ_LOCATIONS, table to store geographical locations.

Use this PL/SQL API to obtain the Legal Entity Time Zone code. This API is found in the package XLE_LE_TIMEZONE_GRP and is to be called in the following way:

Get_Le_Tz_Code(?,?)

The ? indicates an input parameter.

This is sample code for using the Get_Le_Tz_Code(?,?) API:

l_timezone_code = XLE_LE_TIMEZONE_GRP.Get_Le_Tz_Code('BUSINESS_UNIT_ID', p_ou_id);
l_timezone_code = XLE_LE_TIMEZONE_GRP.Get_Le_Tz_Code ('INVENTORY_ORG_ID', p_inv_org_id);
l_timezone_code = XLE_LE_TIMEZONE_GRP.Get_Le_Tz_Code ('LEGAL_ENTITY_ID', p_le_id);

To retrieve the current date and time in the Legal Entity Time Zone, use this PL/SQL API to calculate the current date and time in the Legal Entity Time Zone. This is particularly useful while creating or saving a transaction, when the legal entity date and time is to be displayed. This API is found in the XLE_LE_TIMEZONE_GRP package and is to be called in the following way:

Get_Le_Sysdate_Time(?,?)

The ? indicates an input parameter.

This is sample code using this API to determine the current date and time in the LETZ:

l_sysdate = XLE_LE_TIMEZONE_GRP .Get_Le_SysDate_Time('BUSINESS_UNIT_ID', p_ou_id);
l_sysdate = XLE_LE_TIMEZONE_GRP .Get_Le_SysDate_Time ('INVENTORY_ORG_ID', p_inv_org_id);
l_sysdate = XLE_LE_TIMEZONE_GRP .Get_Le_SysDate_Time ('LEGAL_ENTITY_ID', p_le_id);

This function will invoke the API (Get_DefaultLegalEntity) when the input parameter passed is the Business Unit or the Inventory Organization.

To convert the server date and time into the LETZ, use this PL/SQL API. This is useful while retrieving an already saved transaction and showing the already saved timestamp in the LETZ. This API is found in the XLE_LE_TIMEZONE_GRP package and is to be called in the following way:

Get_Le_Day_Time(?,?,?)
 

The ? indicates an input parameter.

Sample code using this API to convert a given date and time from the server time zone to the LETZ:

l_le_day_time = XLE_LE_TIMEZONE_GRP . Get_Le_Day_Time ('BUSINESS_UNIT_ID', p_ou_id, p_trxn_date);
l_le_day_time = XLE_LE_TIMEZONE_GRP . Get_Le_Day_Time ('INVENTORY_ORG_ID', p_inv_org_id. p_trxn_date);
l_le_day_time = XLE_LE_TIMEZONE_GRP . Get_Le_Day_Time ('LEGAL_ENTITY_ID', p_le_id, p_trxn_date);
 

Here the p_trxn_date is the transaction date and time value in the server time zone.

To convert the legal entity date and time into the server time zone, use this PL/SQL API. This API is found in the XLE_LE_TIMEZONE_GRP package and is to be called in the following way:

Get_Server_Day_Time(?,?,?)
 

The ? indicates an input parameter.

This API will be for reverse LETZ conversion. Calling applications can pass in the Legal Entity Date Time and the Business Unit/Inventory Organization/Legal Entity ID to convert the Legal Entity datetime to the Server datetime.

Sample code using this API to convert the LETZ timestamp value to server time zone:

l_Server_Date := XLE_LE_TIMEZONE_GRP .Get_Server_Day_Time ('INVENTORY_ORG_ID', p_inv_org_id, p_Le_Date);
l_Server_Date := XLE_LE_TIMEZONE_GRP .Get_Server_Day_Time ('BUSINESS_UNIT_ID', p_ou_id, p_Le_Date);
l_Server_Date := XLE_LE_TIMEZONE_GRP. Get_Server_Day_Time ('LEGAL_ENTITY_ID', p_inv_org_id, p_Le_Date);
 

These PL/SQL APIs must be called in the Java entity object implementation classes for time zone conversion. The JSF code corresponding to the date field need not be changed.

Here is a sample of a JSF date field in the server time zone and its corresponding conversion into the LETZ. The code in the JSF page corresponding to a date field is shown in Example 20-22:

Example 20-22 Converting a Date Field into the LETZ

<af:inputDate value="#{bindings.InvoiceDate.inputValue}"
            label="#{bindings.InvoiceDate.hints.label}"
            required="#{bindings.InvoiceDate.hints.mandatory}"
            shortDesc="#{bindings.InvoiceDate.hints.tooltip}"
            showRequired="true" autoSubmit="true"
          valueChangeListener="#{pageFlowScope.invoiceActionsBean.invoiceDateValueChangeListener}"
            columns="#{bindings.InvoiceDate.hints.displayWidth}"
            disabled="#{pageFlowScope.matchPopupVisible}"
            id="id2">
        <f:validator binding="#{bindings.InvoiceDate.validator}"/>
        <af:convertDateTime pattern="#{applCorePrefs.dateFormatPattern}"/>
</af:inputDate>
 

As shown, you do not need to change the date field's snippet in the JSF page, or add a time zone attribute in the af:convertDateTime tag for this field.

The calculation of LETZ date values should be triggered when changing the value for the Business Unit field in the user interface. The value change should invoke a method that can calculate values according to the LETZ in the EOImpl class. In this case, this method is the setOrgID() method, shown in Example 20-23.

Example 20-23 Using the setOrgID() Method

public void setOrgID(Long orgID)
{
        ...
        //To convert the current timestamp to the LETZ, we call another method getLEDateTime 
this.setInvoiceDate(this.getLEDateTime(orgID, this.getDBTransaction()));
}
//This method calls the PL/SQL API to get the current date and time in the LETZ
public Date getLEDateTime(Long orgId, DBTransaction dbTransaction)
{
          // 1. Define the PL/SQL block for the statement to invoke
  String stmt = "begin ? := XLE_LE_TIMEZONE_GRP.Get_Le_Sysdate_Time(?,?);  end;";
  // 2. Create the CallableStatement for the PL/SQL block
  st = (OracleCallableStatement)dbTransaction.createCallableStatement(stmt, 0);
  // 3. Register the positions and types of the OUT parameters
  st.registerOutParameter(1, Types.DATE);
  // 4. Set the bind values of the IN parameters
  st.setObject(2,"BUSINESS_UNIT_ID");
  st.setObject(3,orgId);
  //5. Execute Query
  st.executeUpdate();
 return  st.getDate(1);
}
 

In Figure 20-10, the field Receipt Date is an example of how a date-time or a timestamp field in Oracle Fusion Applications is calculated according to the user's preferred time zone rather than the server time zone.

Figure 20-10 Converting to User Preferred Time Zone

Converting to User Preferred Time Zone

In Figure 20-11, the Business Unit field determines the LETZ according to which the date fields Date and Terms Date on the right of the screenshot are converted in Oracle Fusion Applications. Thus, the fields Date and Terms Date change according to the Business Unit field in the Create Invoice transaction.

Figure 20-11 Converting to Legal Entity Time Zone

Converting to Legal Entity Time Zone

20.5.2 How to Format Invariant Time Zone Values

Some date-time values are not associated with a specific time zone. For example, an application may execute a job at 9 AM local time in every location across different time zones. Such values are called invariant or floating times. To print an invariant time zone value, use the default time zone such that no specific time zone is applied to the value.

When printing a date-time value for a specific time zone derived from an invariant time zone value, you may need to adjust the formatting so as to neutralize the effect of time zone conversion. This is because the server default time zone is applied implicitly.

20.5.3 What Happens When You Format Time Zones

When you drag and drop a timestamp field onto the JSF page, Applications Core generates these tags:

<af:outputText label="orderDateTime" value="#{bindingToOrderDateTime}"><af:convertDateTime pattern="#{applCorePrefs.dateFormatPattern}"/>  <af:outputText>

You need to change the tags depending on whether the field is to be calculated according to the UPTZ or the server time zone (invariant timestamp values), for example Default : Server Time Zone.

This should be used only for invariant timestamp values. Invariant timestamp values are timestamps in which varying Timezone will not make a difference to the business logic of the application.

<af:outputText label="orderDateTime" value="#{bindingToOrderDateTime}"><af:convertDateTime pattern="#{applCorePrefs.UPTZPattern}"/>  <af:outputText> 

This is an example of a User Preferred Time Zone.

<af:outputText label="orderDateTime" value="#{bindingToOrderDateTime}"><af:convertDateTime timeZone="#{applCorePrefs.UPTZ}" pattern="#{applCorePrefs.UPTZPattern}"/><af:outputText>

At design time, Applications Core uses the Date-Time Sensitive custom property to generate bindings to the time zone attribute on the Oracle ADF Faces Date Time Converter. The attribute is bound to the applCorePrefs managed bean.

20.5.4 What Happens at Runtime: How Time Zones Are Formatted

At runtime, the Applications Core managed bean applCorePrefs, implemented by oracle.apps.fnd.applecore.common.PreferencesBean and registered with the faces-config.xml file, retrieves the relevant formatting masks from Applications Session.

By default, date-time data may display as shown in Example 20-24.

Example 20-24 Date Time Data Format

1/1/2009 12:34 AM        for the pattern "M/d/yyyy hh:mm a"

20.5.5 Standards and Guidelines

The following standards and guidelines apply to formatting time zones:

  • All date time fields must be represented only by java.sql.Timestamp data types (used by default in time zone view object attributes).

  • The database and middle-tier Timezone must always be the same in Oracle Fusion Applications.

20.6 Formatting Numbers, Currency and Dates Using Localization Expression Language Functions

Expression Language functions provide an alternative to the formatting procedures described in Section 20.2, "Formatting Currency,", Section 20.3, "Formatting Numbers" and Section 20.5, "Formatting Time Zones."

20.6.1 How to Format Numbers, Currency and Dates Using Expression Language Functions

Oracle ADF Faces Expression Language functions of the type af:formatNamed and af:format only support String objects as parameters. Consequently, other object types such as Date and BigDecimal must be converted to the String object type.

For example, when binding the date object dateValue as shown in Example 20-25, the dateValue object must be converted to a String object by calling the toString() method.

Example 20-25 Binding a Date Object

af:formatNamed(bundle.NOTE_MESSAGE, 'BIRTHDAY', dateValue)

However, the toString() method does not support Oracle Fusion Applications user preferences. Oracle Fusion Applications thus require the use of Expression Language format functions to convert the following data objects to String objects:

  • Number and currency objects:

    • java.math.BigDecimal

    • java.lang.Integer

    • java.lang.Long

  • Date and DateTime (Timestamp) objects:

    • java.sql.Date

    • java.sql.Timestamp

You can format numbers, currency and dates using Expression Language functions.

20.6.1.1 Formatting Numbers Using Expression Language Functions

Use the following Expression Language functions to format numbers.

The number Expression Language formatting function is shown in Example 20-26.

Example 20-26 formatNumber(java.lang.Number value) Function

fnd:formatNumber(java.lang.Number value)

Returns the formatted number value using the user preferences for the number format mask, grouping separator and decimal separator.

This function produces the tag shown in Example 20-27.

Example 20-27 Tag Produced by the Function fnd:formatNumber(java.lang.Number value)

<af:convertNumber pattern="#{applCorePrefs.numberFormatPattern}"/>

An additional Expression Language formatting function for numbers is shown in Example 20-28.

Example 20-28 formatNumber2(java.lang.Number value, int maxFractionDigit) Function

fnd:formatNumber2(java.lang.Number value, int maxFractionDigit)

Returns the formatted number value using the user preferences for the number format mask, grouping separator and decimal separator.

Overrides the scale—the number of digits following the decimal point—of the user preferred number format pattern using the value assigned to maxFractionDigit.

This function produces the tag shown in Example 20-29.

Example 20-29 Tag Produced by the Function fnd:formatNumber2(java.lang.Number value, int maxFractionDigit)

<af:convertNumber pattern="#{applCorePrefs.numberFormatPattern}"
            maxFractionDigits="your scale here"/>

20.6.1.2 Formatting Currency Using Expression Language Functions

Use the Expression Language function shown in Example 20-30 to format currency.

Example 20-30 fnd:formatCurrency(java.lang.Number currencyAmount, java.lang.String currencyCode) Function

fnd:formatCurrency(java.lang.Number currencyAmount,
             java.lang.String currencyCode)

Returns the formatted currency amount value in numeric form along with the relevant currency code. Applications Core uses the currency code as defined in FND_CURRENCIES to format the currencyAmount value, rather than the number format mask preference. User preferences for grouping and decimal separators are used to format the value.

This function produces the tag shown in Example 20-31.

Example 20-31 Tag Produced by the Function fnd:formatCurrency(java.lang.Number currencyAmount, java.lang.String currencyCode)

 <af:convertNumber type="currency"
      currencyCode="#{bindings.quantityCurrencyCode.inputValue}"
      pattern="#{fnd:currencyPattern(bindings.quantityCurrencyCode.inputValue)}"/>

20.6.1.3 Formatting Dates Using Expression Language Functions

Use the Expression Language function shown in Example 20-32 to format dates.

Example 20-32 fnd:formatDate(java.util.Date dateValue) Function

fnd:formatDate(java.util.Date dateValue)

Returns the formatted date value based on the user preferred date format mask.

This function produces the tag shown in Example 20-33.

Example 20-33 Tag Produced by the Function fnd:formatDate(java.util.Date dateValue)

<af:convertDateTime pattern="#{applCorePrefs.dateFormatPattern}"/>

Use the Expression Language function shown in Example 20-34 to format date time values.

Example 20-34 fnd:formatDateTime(java.util.Date dateTimeValue) Function

fnd:formatDateTime(java.util.Date dateTimeValue)

Returns the formatted date time value using the user preferences for the date and time format masks and time zone.

This function produces the following tag as shown in Example 20-35.

Example 20-35 Tag Produced by the Function fnd:formatDateTime(java.util.Date dateTimeValue)

<af:convertDateTime type="both" timeZone="#{applCorePrefs.UPTZ}"
              pattern="#{applCorePrefs.UPTZPattern}"/>

Use the Expression Language function shown in Example 20-36 to format date time values with user formatting masks and the user-specified time zone.

Example 20-36 fnd:formatDateTimeTZ(java.util.Date dateTimeValue, java.util.TimeZone timeZone) Function

fnd:formatDateTimeTZ(java.util.Date dateTimeValue,
                         java.util.TimeZone timeZone)

Returns the formatted date time value using the user preferences for date and time format masks and the user-specified time zone.

This function produces the tag shown in Example 20-37.

Example 20-37 Tag Produced by the Function fnd:formatDate(java.util.Date dateTimeValue, java.util.TimeZone timeZone)

<af:convertDateTime type="both" timeZone="<your timezone>"
              pattern="#{applCorePrefs.UPTZPattern}"/>

20.6.2 What Happens When You Format Numbers, Currency and Dates Using Expression Language Functions

Applications Core formats the value as defined by the Expression Language function and produces the tags described in this section.

For example, the date formatting Expression Language function produces a tag such as the one shown in Example 20-38.

Example 20-38 Tag Produced by Expression Language Date Formatting Function

<af:convertDateTime pattern="#{applCorePrefs.dateFormatPattern}"/>

20.6.3 What Happens at Runtime: How Currency, Dates and Numbers and Time Zones are Formatted Using Expression Language Functions

For more information about what happens at runtime when you format numbers, currency and dates using Expression Language functions, see Section 20.2, Section 20.3 and Section 20.5.

20.7 Implementing Bi-directional Support

Oracle Fusion applications should be enabled to provide bi-directional support. Examples of bi-directional languages are Arabic (Middle East and North Africa) and Hebrew (Israel). These scripts are generally written from right to left. The entire UI must also render from right to left. That is, if you took a standard English UI and placed a mirror next to your computer screen, the image in the mirror is exactly what is expected of speakers of bi-directional languages. Some rules come into play, such as how to correctly render English text or numerals embedded in a bi-directional script, but this generally is handled by underlying technologies (in this case, Oracle ADF). An example of this is that the text, which translates to United Arab Emirates: Bi-directional example one.
for a user with English locale needs to be displayed as: Bi-directional support example two.
for a user with Arabic Locale.

20.7.1 How to Implement Bi-directional Support

Before you begin, create an entity and a view object from ADF Business Components. Drag and drop some of the attributes from the view object into a JSF page.

20.7.1.1 Making Panels and Columns Provide Bi-directional Support

UI Components such as af:panelGroupLayout and af:column have an align or an halign attribute that allows developers to align a particular component in one direction. A typical example of this is a number field that is always aligned to the right by Oracle Fusion Applications standards. Now, if a UI component (a non-number field) is hardcode-aligned to the left or right in the JSF page, the implication in the Arabic locale is that the UI component does not switch to its corresponding mirror image position. As a result, there are discrepancies in the user interface in the Arabic locale.

To correct this situation, you must not hardcode a UI component (non-number field) to the left or right. You should always use the start or end values for the halign and align attributes to make them bi-directional compatible, as shown in Example 20-39.

Example 20-39 Making align Attributes Bi-directional

<af:panelGroupLayout id="pgl5" layout="horizontal" halign="end"> 
    <af:commandButton  text="#{ResourcesGenBundle['Action.Advanced.AdvancedSearch']}" 
        actionListener="#{ItemRelationshipRegionalSearchBean.onAdvancedButtonClick}"    id="cb4"/> 
            <af:spacer width="8" height="10" id="s7"/> 
            <af:image source="/images/seperator_img.png" id="i2" shortDesc=""/> 
            <af:spacer width="8" height="10" id="s8"/> 
            <af:commandButton textAndAccessKey="#{ResourcesGenBundle['Action.Search1']}" id="cb5" 
                actionListener="#{ItemRelationshipRegionalSearchBean.onRegionalAreaSearchClick} "/> 
            <af:spacer width="5" height="10" id="s9"/> 
            <af:commandButton text="#{ResourcesGenBundle['Action.Reset']}" id="cb6" 
                   actionListener="#{ItemRelationshipRegionalSearchBean.onResetBtnClick}"/> 
            <af:spacer width="5" height="10" id="s10"/> 
         </af:panelGroupLayout>

Here, the halign attribute for the panel group has been set to end, which means that this component will be bi-directional compatible and will switch to its mirror image position in the Arabic locale.

In the English locale shown in Figure 20-12, the panel containing the three buttons Advanced, Search and Reset is aligned to the right.

Figure 20-12 Showing Right-aligned Buttons for English Locale

Showing Right-aligned Buttons for English Locale

Therefore, the expected behavior is that, in the Arabic locale shown in Figure 20-13, the panel, with the buttons' text in Arabic, is aligned to the left.

Figure 20-13 Showing Left-aligned Buttons for Arabic Locale

Showing Left-aligned Buttons for Arabic Locale

20.7.1.2 Making Images Provide Bi-directional Support

In Oracle Fusion applications, all UI components should provide bi-directional support. This means that, in bi-directional locales such as Arabic and Hebrew, UI components should be shown from right-to-left instead of left-to-right. This also includes images that are shown on the UI to give a pictorial representation of an instruction to the end user. If an image is directional (unsymmetrical), it should be flipped and shown as its corresponding mirror image from right-to-left. However, if an image is non-directional (symmetrical) it need not be flipped since its mirror image is the image itself. To make an image bi-directional, you have to use the function fnd:bidiImage(<Image-Path>), shown in Example 20-40, that is provided as a part of the ApplCore library.

Example 20-40 Using fnd:bidiImage to Provide Bi-directional Support for an Image

<af:commandImageLink icon="#{fnd:bidiImage('search_ena.png')}" action="search" />

In bi-directional locales, instead of displaying the image search_ena.png directly, the fnd:bidiImage suffixes an _rtl just before the start of the extension to the parameter file-name given to it (in this case, the image icon search_ena.png becomes search_rtl_ena.png), and then displays the image search_rtl_ena.png on the JSF page. Now, if the latter image has been stored as a mirror image of the former, bi-directionality is ensured for the image.

Figure 20-14 shows how the search image next to the Search by Year option appears in an English locale.

Figure 20-14 Showing Command Image Link in English Locale

Showing Command Image Link in English Locale

Figure 20-15 shows how the command image link supports bi-directional behavior in an Arabic locale.

Figure 20-15 Showing Command Image Link in Arabic Locale

Showing Command Image Link in Arabic Locale

20.8 Supporting Mnemonic Keys

A mnemonic key, also called a soft key, is a shorthand name for a key, command, or menu option. Mnemonic keys are used in Oracle Fusion applications to activate the buttons in a page. This is made possible by using a <Modifier>+<Access Key>.

Note that modifiers are browser-specific. Internet Explorer, Safari and Google Chrome use the Alt key; Firefox uses Alt+Shift.

The Access Key is defined in the source code by the developer.

In Oracle Fusion applications, the access key for a particular button needs to be externalized so that the keys for different locales are different. Do not hardcode the accessKey or the textAndAccessKey attribute provided as a child attribute of the af:commandButton tag. Hard-coding these keys would cause mnemonic key issues. For example, if an English letter is hardcoded as an access key in the JSF layer, an Arabic user may not be able to use this key because there are no English letters on his keyboard. Instead the accessKey and textAccessKey attributes should be externalized using either the applCoreBundle or any resource bundle defined in an Oracle Fusion application's project.

20.8.1 How to Implement Mnemonic Key Support

Before you begin, create an entity object and a view object from ADF Business Components. Drag and drop some of the attributes from the view object into a JSF page. Create a panel group and add a command button to it.

There are two attributes provided by Oracle ADF for mnemonic keys for buttons: accessKey and textAndAccessKey. The attribute accessKey takes as a value just the access key to be typed by the user, whereas the attribute textAndAccessKey takes as a value the text to be displayed on the button and the short-hand key to be typed by the user. You must make sure that the accessKey and textAndAccessKey attributes are never hard-coded. Both should be externalized and read from resource bundles. In the case of the textAndAccessKey attribute, the value of the access key usually is preceded by an ampersand (&) in the resource bundle. In case the ampersand sign is not present in the bundle, the first letter of the text is treated as the access key.

How to use the textAndAccessKey attribute using the applCoreBundle is shown in Example 20-41.

Example 20-41 Using the textAndAccessKey Attribute Using the applCoreBundle

f:facet name="actionButtonBar">
     <af:panelGroupLayout layout="horizontal"
                id="panelGroupLayout11"
                styleClass="AFStretchWidth">
       <af:commandButton id="commandButton2"
                textAndAccessKey="#{applCoreBundle.SAVE}"
                actionListener="#{bindings.Commit.execute}"/>

How to use the textAndAccessKey attribute using the resource bundles is shown in Example 20-42.

Example 20-42 Using the textAndAccessKey Attribute Using Resource Bundles

<af:commandButton id="commandButton2"
           textAndAccessKey="#{TemporaryBundle.SAVE}"
           actionListener="#{bindings.Commit.execute}"/>

Here, the resource bundle TemporaryBundle must be defined in the JSF page containing the af:commandButton tag. Also, the textAndAccessKey has been externalized and is read from the applCore bundle and the resource bundle , as shown in the examples, which is the correct way to define mnemonic keys. The values for this particular id SAVE in the resource bundles are "Save" in the English locale, "\uC800\uC7A5(&S)" in the Korean locale (S is the access key) and "\u062D\u0641&\u0638" (\u0638 is the access key) in the Arabic locale.

Example 20-43 shows how to externalize the accessKey attribute using the applCoreBundle.

Example 20-43 Externalizing the accessKey Attribute Using the applCoreBundle

<af:commandToolbarButton text="#{applCoreBundle.SAVE_AND_CLOSE_SHORT_DESC}"
           id="ctb1"
           actionListener="#{BillingCycleBean.saveAndClose}"
           accessKey="#{applCoreBundle.ACCESSKEY}">

Example 20-44 shows how to externalize the accessKey attribute using a resource bundle.

Example 20-44 Externalizing the accessKey Attribute Using a Resource Bundle

<af:commandToolbarButton text="#{TemporaryBundle.SAVE_AND_CLOSE_SHORT_DESC}"
                  id="ctb1"
                  actionListener="#{BillingCycleBean.saveAndClose}"
                  accessKey="#{TemporaryBundle.ACCESSKEY}">

Here, the accessKey attribute has been externalized and is read from the applCore bundle and the resource bundle as shown in the examples. Note that the TemporaryBundle has to be defined as the viewControllerBundle in the JSF page containing the command button. The values for this particular resource ID ACCESSKEY are "S" in the English locale, ""\uC800" in the Korean locale and "\u0638" in the Arabic locale, as defined in the resource bundle.


Notes:

  • When a textAndAccessKey attribute has a value with more than one "&", the letter following the first "&" is chosen as the access key.

  • When an accessKey attribute has more than one letter, the first letter is chosen as the access key.


In Figure 20-16, the buttons on the top right are examples of buttons with soft keys that must not be hardcoded, so that they can be different for different locales.

Figure 20-16 Example of Buttons with Soft Keys

Example of Buttons with Soft Keys

20.9 Implementing Localization Formatting in ADF Desktop Integration

With ADF Desktop Integration technology, users can browse, edit and upload data through a Microsoft Excel spreadsheet. Localization formatting differs from to ADF Faces pages:

In ADF Faces pages, number and date/time values are formatted based on the format patterns selected in the Oracle Fusion application's Preference UI. Number separators are extracted from the application's number format patterns.

20.9.1 How to Format Numbers

Number separators in ADF Desktop Integration spreadsheets vary according to the client OS locale. Number formatting is decided by the style defined in Excel spreadsheet. For example, when opening an ADF Desktop Integration spreadsheet with French Windows XP and Excel, number 1000.5 (One thousand point 5) displays as 1 000,5. It is displayed as 1.000,5 in German Windows XP and Excel. Assuming one fractional digit is specified in the style.

To achieve this, developers need to specify correct styles for numbers at design time.

For more details about Excel styles, refer to the Oracle Fusion Middleware Desktop Integration Developer's Guide for Oracle Application Development Framework.

20.9.1.1 Formatting Numbers

Before you begin, create a workable ADF Desktop Integration spreadsheet and have the attributes in place. Related attributes are of types: java.math.BigDecimal, java.lang.Integer, or java.lang.Long.

Define styles for each type of cells and configure the cell appearance using the Oracle Fusion Applications UI standard.

Decimal Number Formatting

Follow these steps to modify the existing style for formatting decimal numbers and apply the style to the cell containing a decimal number value.

  • In Excel, select Home > Cell Styles.

  • Right-click the style name and select Modify from the context menu, as shown in Figure 20-17.

    Figure 20-17 Selecting Modify Menu Option

    Selecting Modify Menu Option
  • On the Style dialog, shown in Figure 20-18, click Format.

    Figure 20-18 Selecting Format on the Style Dialog

    Selecting Format on the Style Dialog
  • Select the Number tab and select the Number category. Specify the number of decimal places and the format of negative numbers according to your business logic. If you want to see grouping separator in the number values, make sure that Use 1000 Separator is checked, as shown in Figure 20-19.

    Figure 20-19 Selecting the Use 1000 Separator

    Selecting the Use 1000 Separator
  • Click OK and save the Excel file.

Integer Formatting

Integer formatting is the same as decimal formatting except no fractional digit should display. This can be done by specifying 0 for Decimal places when modifying the style.

ID Formatting

An ID value is a sequence of digits, such as an Invoice Number, Service Request ID, or Bank Account. Displaying ID values should not vary based on a user's preference or client OS locale. That is, ID values should be printed as text instead of numbers.

In Oracle Fusion applications, the length of an ID value typically is 13 or 18. By default, Excel formats such long numbers with Scientific Notation format, which is not desired for Oracle Fusion applications. For instance, an Invoice Number 1234567890123 (13 digits) is displayed as 1.23457E+12. It is not a valid Invoice Number when it is printed out.

To avoid the default formatting of Excel in such cases, developers need to customize the styles for ID values.

  • In Excel, select Home > Cell Styles

  • Right-click the style name and select Modify from the context menu.

  • Click Format.

  • Select the Number tab and select the Text category.

  • Click OK. In the Style dialog, Figure 20-20 shows that @ is defined as the Number style.

    Figure 20-20 Selecting the Number Style

    Selecting the Number Style
  • Click OK and save the file.

    As a result, Figure 20-21 shows that an ID value is displayed as text without any number formatting.

    Figure 20-21 Displaying ID Value as Text

    Displaying ID Value as Text

20.9.1.2 What Happens When You Format Numbers

When dragging and dropping a binding to generate the components in an ADF Desktop Integration spreadsheet, the framework generates default styles for those values based on the Java type of the values. However, these styles may not be correct for formatting number values. Therefore, you may need to refine the styles according to business logic.

20.9.1.3 What Happens at Runtime: How Numbers Are Formatted

At runtime, ADF Desktop Integration will pass the style specified in the ADF Desktop Integration unpublished spreadsheet (known as the design time file) to the published spreadsheet during the publication process. When a user opens the published spreadsheet, Excel formats the numbers according to the combination of styles and client OS locale.

20.9.2 How to Format Currency Values

Grouping and decimal separators of currency values vary based on the client OS locale, while the number of fraction digits is controlled by the style defined in the Excel spreadsheet.

You should not display currency symbols or currency codes with currency numbers in the same cell. Instead, you need to display currency symbols or currency codes in a separate cell.

20.9.2.1 Formatting Currency Values

Before you begin, create a workable ADF Desktop Integration spreadsheet and have the attributes in place. The related attribute is of type java.math.BigDecimal.

Define styles for each type of cells and configure the cell appearance using the Oracle Fusion Applications UI standard.

Follow these steps to modify an existing style for formatting currency values and apply it to the corresponding cells.

  • In Excel, select Home > Cell Styles, right-click the style name and select Modify from the context menu.

  • Click Format.

  • Select the Number tab and select the Currency category. Specify the number of Decimal places and the format of negative numbers according to your business logic.

  • In Oracle Fusion applications, you should display the currency symbol in a separate cell. Make sure None is selected for Symbol, as shown in Figure 20-22.

    Figure 20-22 Selecting None as the Currency Symbol

    Selecting None as the Currency Symbol
  • Click OK and save the file.

20.9.2.2 What Happens When You Format Currencies

When dragging and dropping a binding to generate the components in an ADF Desktop Integration spreadsheet, the framework generates default styles for those values based on the Java type of the values. However, these styles may not be correct for formatting number values. Therefore, you may need to refine the styles according to business logic.

20.9.2.3 What Happens at Runtime: How Currency Values Are Formatted

At runtime, ADF Desktop Integration will pass the style specified in the unpublished spreadsheet (the design time file) to the published spreadsheet during the publication process. When a user opens the published spreadsheet, Excel formats the numbers according to the combination of styles and the client OS locale.

The currency code should be displayed in a cell other than the cell containing the Currency Value. The currency code in this cell should be printed as text.

20.9.3 How to Format Dates and Timestamp Values

The format of date and timestamp values in ADF Desktop Integration spreadsheets varies according to the client OS locale.

For example, when opening an ADF Desktop Integration spreadsheet with French Windows XP and Excel, the date May 25th, 2011 is displayed as 25/05/2011. It displays as 2011-05-25 in Korean Windows XP and Excel.

To achieve this, developers need to specify correct styles for date and timestamp values at design time.

For more details about Excel styles, refer to the Oracle Fusion Middleware Desktop Integration Developer's Guide for Oracle Application Development Framework.

20.9.3.1 Formatting Date and Timestamp Values

Before you begin, create a workable ADF Desktop Integration spreadsheet and have the attributes in place. Related attributes are of types: java.sql.Date or java.sql.Timestamp.

Define styles for each type of cell and configure the cell appearance using Oracle Fusion Applications UI standards.

Formatting the Date

Follow these steps to modify an existing style for formatting dates and apply it to the correspondent cells.

  • In Excel, select Home > Cell Styles

  • Right-click the style name and select Modify from the context menu.

  • Click Format.

  • Select the Number tab and select the Date category. Set the value of Locale (location) to your Windows OS locale. For example, if you are using English Windows XP, this Locale should be set to English (U.S.).

  • Select a type beginning with an asterisk (*), as shown in Figure 20-23. There are two such Types: one is short date format, and the other is long date format. Choose one according to your business requirement.

    Figure 20-23 Selecting the Date Type

    Selecting the Date Type

    Note that date formats display date and time serial numbers as date values. Date formats that begin with an asterisk (*) respond to changes in regional date and time settings that are specified for the operating system. Formats without an asterisk are not affected by operating system settings.

  • Click OK and save the file.

Formatting the Timestamp

Follow these steps to define a style for formatting the timestamp and apply it to the corresponding cells.

  • In Excel, select Home > Cell Styles.

  • Right-click the style name and select Modify from the context menu.

  • Click Format.

  • Select the Number tab and select the Time category. Set the value of Locale (location) to your Windows OS locale. For example, if you are using English Windows XP, this Locale should be set to English (U.S.).

  • Select the type beginning with an asterisk (*), as shown in Figure 20-24.

    Figure 20-24 Selecting the Time Type

    Selecting the Time Type
  • Click OK and save the file.

Note: With current ADF Desktop Integration support, it is impossible to display both the date and the time part of a timestamp value in a single cell if you want to see its format varying according to client OS locale.

Workaround

To display the date and time, formatted according to the client OS locale, you can use two cells: One for displaying the date part and another for displaying the time part of the timestamp. Then format each of these cells separately as described for date and time format.

20.9.3.2 What Happens When You Format the Date and Timestamp

When dragging and dropping a binding to generate the components in an ADF Desktop Integration spreadsheet, the framework generates default styles for those values based on the Java type of the values. However, these styles may not be correct for formatting number values. Therefore, you may need to refine the styles according to business logic.

20.9.3.3 What Happens at Runtime: How Date and Timestamp Are Formatted

At runtime, ADF Desktop Integration will pass the style specified in the unpublished spreadsheet (the design time file) to the published spreadsheet during the publication process. When a user opens the published spreadsheet, Excel formats the date or timestamp values according to the combination of styles and the client OS locale.

For timestamp values, time zone conversion also happens at runtime. See Section 20.9.3.4, "Honoring Time Zones" for more details.

20.9.3.4 Honoring Time Zones

There are two time zones involved in time zone conversion for timestamp values in ADF Desktop Integration spreadsheets. One is the time zone of the Oracle Fusion Applications server, called the server time zone. The other is the time zone of the client system on which the ADF Desktop Integration spreadsheet is open, which is called the client time zone.

At runtime, conversion between server time zone and client time zone happens automatically for timestamp values in ADF Desktop Integration spreadsheets.

For example, if the server time zone is (GMT-8:00) Pacific Time (US & Canada) and the client time zone is (GMT+8:00) Beijing, Chongqing, Hong Kong, Urumqi, the timestamp value in the database 2011-05-22 20:00:00 is converted to 2011-05-23 12:00:00 at runtime and displayed as 2011-05-23 or 12:00:00 in the ADF Desktop Integration spreadsheet, depending on the format style defined for the corresponding cells.

20.10 Implementing Localization Formatting in Oracle BI Publisher Reports

Oracle BI Publisher can pass Oracle Fusion applications Preferences Number Format, Date Format and Time Format to Oracle BI Publisher reports using function format-date, format-number or format-currency, if Oracle BI Publisher is running in Oracle BI Publisher and Oracle Fusion applications integration mode.


Note:

To modify RTF templates, Oracle BI Publisher Template Builder for Word should be installed on Microsoft Word 2003, 2007 or higher version. After it is installed, there is a Oracle BI Publisher menu in the Word menu bar.


20.10.1 How to Format Numbers in a Oracle BI Publisher Report

To format numbers in an RTF template with an Oracle Fusion application user-preferred number format pattern, Oracle's format-number function must be used with 'XDODEFNUM' used as a format mask, for example:

<?format-number:fieldName; 'XDODEFNUM'?>

For details about the format-number function, see "Number, Date and Currency Formatting" in the Oracle Fusion Middleware Report Designer's Guide for Oracle Business Intelligence Publisher.

Follow these steps to format numbers with the Oracle Fusion application user-preferred number format pattern:

  • Open your RTF template file with Word.

  • Select BI Publisher > Sample XML and select a sample XML file that contains sample data for the number fields to be formatted in the RTF template.

  • Double-click the number field to be modified (such as ORDER_TOTAL). In the Oracle BI Publisher Properties dialog, select the Properties tab and make sure that Regular Text is selected for Type.

  • Select the Advanced tab and enter format code, as shown in Figure 20-25.

    Figure 20-25 Entering a Number Format Code

    Entering a Number Format Code
  • Click OK and save the RTF template file.

Follow these steps to format a number value in graphs in Oracle BI Publisher reports

  • To set format masks for graphs, an Oracle Fusion application Oracle BI Publisher report designer needs to change the RTF template graph code manually.

  • Edit the graph and change the graph definition code in the Advanced tab of the Graph dialog in the template builder.

  • Use an XSLT format such as:

    <xsl:value-of select="xdoxslt:xdo_format_number($_XDOXSLTCTX,current-group()/SGT_NUMBER,'XDODEFNUM')" />

    to format a currency value on the graph.

At runtime, XDODEFNUM is replaced with the number format pattern selected in the Oracle Fusion application Preferences UI. Consequently, the number is formatted with the Oracle Fusion application number format pattern. For example, if a user selects -1'234,567 as the Number Format in the Preferences UI, as shown in Figure 20-26, the number 1000.8888 (one thousand point eight eight eight eight) will be displayed as 1'000,889 in the Oracle BI Publisher report.

Figure 20-26 Selecting a Number Format in the Preferences UI

Selecting a Number Format in the Preferences UI

When using XDODEFNUM as the format mask in format-number, the format of the number is fully controlled by the Oracle Fusion application Number Format, including grouping separator, decimal separator, number of fractional digit, and form of negative numbers.

In the Oracle BI Publisher and Oracle Fusion application integration environment, if format-number is used to format a number, whether or not XDODEFNUM is used as the format mask, the grouping separator and decimal separator are always derived from the Oracle Fusion application Number Format.

Therefore, an integer could be formatted as:

<?format-number:fieldName; '999G999'?>

In this case, if the Number Format is -1'234,567, the integer 10000 is displayed as 10'000 in the Oracle BI Publisher report.

If you do not wish to display a number with fractional digits or grouping separators (such as PO numbers, Bank Accounts, or Invoice Numbers), enter <?fieldName?> in step 4 of [To format numbers]. In such cases, the Number Format has no effect on the field; it always is displayed as text.

20.10.2 How to Format Currency Values in Oracle BI Publisher

Currency fields in RTF templates can be formatted with the format-currency function:

<?format-currency:Amount_Field;CurrencyCode;displaySymbolOrNot?>

where

  • Amount_Field takes the tag name of the XML element that holds the amount value in your data.

  • CurrencyCode can be set to a static value or it can be set dynamically. If the value will be static for the report, enter the ISO three-letter currency code in single-quotes, such as 'USD'.

To set the value dynamically, enter the tag name of the XML element that holds the ISO currency code. Note that an element containing the currency code must be present in the data.

  • At runtime, the Amount_Field will be formatted according to the format you set up for the currency code in the report properties.

  • displaySymbolOrNot takes as a value either 'true' or 'false' in single quotes. When set to 'true', the currency symbol will be displayed in the report based on the value for CurrencyCode. If you do not wish the currency symbol to be displayed, you can either enter 'false' or simply omit the parameter.

For details about the format-currency function, see "Number, Date and Currency Formatting" in the Oracle Fusion Middleware Report Designer's Guide for Oracle Business Intelligence Publisher.

To use the format-currency function, the currency values in your data source must be in a raw format, with no formatting applied (for example: 1000.00). If the value has been formatted for European countries (for example: 1.000,00), the format will not work.

To format your currency values with the currency code passed dynamically from a particular business flow, you must have the currency code defined in your data source.

In the Oracle Fusion application and Oracle BI Publisher integration environment, Currency is passed to Oracle BI Publisher through XDODEFCC. For example, if US Dollar is selected for Currency in Preferences, as shown in Figure 20-27, at runtime, XDODEFCC is replaced with USD.

Figure 20-27 Selecting a Currency in Oracle Fusion Application Preferences

Selecting a Currency in application Preferences

Therefore, to format a currency value with the Currency selected in Oracle Fusion application Preferences, you can use:

<?format-currency:Amount_Field; 'XDODEFCC'?>

or

<?format-currency:Amount_Field; 'XDODEFCC';'true'?>

To format currency values with the currency code selected in a particular business flow instead of the Currency code selected in Oracle Fusion application Preferences, you can use:

<?format-currency:Amount_Field; CurrencyCode_Field?>

or

<?format-currency:Amount_Field; CurrencyCode_Field;'true'?>

where CurrencyCode_Field is the tag name of the XML element that holds the currency code selected in the business flow. At runtime, CurrencyCode_Field is replaced with a currency code, such as USD, JPY, or EUR.

Note: Whether the currency code is set to a static value, such as XDODEFCC, or a dynamic value passed from a particular business flow, the grouping separator and decimal separator in currency values are always derived from the Number Format selected in Oracle Fusion application Preferences. The parameter currency code in the format-currency function controls the number of fraction digits and the placement of the grouping separator in the output.

Example

Assume that <?format-currency:Amount_Field; CurrencyCode_Field?> is applied in the RTF template for a currency field.

In the report properties, if the format mask for USD is 9G999D99, for JPY it is 9G999 and for INR it is 9G99G99G999D99, and if a user has set the Number Format as -1,234.567 in Preferences (uses comma (,) as the grouping separator and dot (.) as decimal separator), the currency value of 1234567.89 will display as shown here, depending on the currency passed to CurrencyCode Field at runtime.

  • If 'USD' is passed to CurrencyCode_Field at runtime, the value displayed is 1,234,567.89.

  • If 'JPY' is passed to CurrencyCode_Field at runtime, the value displayed is 1,234,568.

  • If 'INR' is passed to CurrencyCode_Field at runtime, the value displayed is 12,34,567.89.

If a European user changes the Number Format to -1'234,567 in Preferences (uses the apostrophe (') as the grouping separator and comma (,) as the decimal separator), the currency value of 1234567.89 will display as:

  • If 'USD' is passed to CurrencyCode_Field at runtime, the value displayed is 1'234'567,89.

  • If 'JPY' is passed to CurrencyCode_Field at runtime, the value displayed is 1'234'568.

  • If 'INR' is passed to CurrencyCode_Field at runtime, the value displayed is 12'34'567,89.

Follow these steps to format a currency field in the Oracle BI Publisher RTF template.

  • Open the RTF template file with Word.

  • Expand BI Publisher > Sample XML and select a sample XML file that contains sample data for the number fields to be formatted in the RTF template.

  • Double-click the currency field to be modified (for instance ORDER_TOTAL). In the Oracle BI Publisher Properties dialog, click the Properties tab and make sure Type is set to Regular Text.

  • Click the Advanced tab and enter format code, as shown in Figure 20-28.

    Figure 20-28 Entering Currency Code in Oracle BI Publisher Properties

    Entering Currency Code in BI Publisher Properties
  • Click OK and save the RTF template file.

Follow these steps to format a currency value in graphs in Oracle BI Publisher reports

  • To set format masks for graphs, an Oracle Fusion application Oracle BI Publisher report designer needs to change the RTF template graph code manually.

  • Edit the graph and change the graph definition code in the Advanced tab of the Graph dialog in template builder.

  • Use an XSLT format, such as <xsl:value-of select="xdoxslt:xdo_format_currency($_XDOXSLTCTX,current-group()/SGT_CURRENCY,'XDODEFCC')" /> to format a currency value on the graph.

20.10.3 How to Format Dates and Timestamps in Oracle BI Publisher

In the Oracle BI Publisher RTF template, a date or timestamp can be formatted as:

<?format-date:date_string; 'ABSTRACT_FORMAT_MASK';'TIMEZONE'?>

where:

  • ABSTRACT_FORMAT_MASK can be any date format pattern supported by Oracle BI Publisher, such as YYYY-MM-DD or DD/MM/YYYY.

  • TIMEZONE is optional. It can be any valid time zone ID, such as PST or UTC. If it is not specified, the Oracle BI Publisher report time zone is applied implicitly.

For details about the format-date function, see "Number, Date and Currency Formatting" in the Oracle Fusion Middleware Report Designer's Guide for Oracle Business Intelligence Publisher.

To use the format-date function, the date from the data source must be in canonical format, which is YYYY-MM-DDThh:mm:ss+HH:MMwhere:

  • YYYY is the year

  • MM is the month

  • DD is the day

  • T is the separator between the date and time component

  • hh is the hour in 24-hour format

  • mm is the minutes

  • ss is the seconds

  • +HH:MM is the time zone offset from Universal Time (UTC), or Greenwich Mean Time

For example: 2011-05-26T09:30:10-07:00.

The data after the T is optional, therefore 2011-05-26 is a valid date.


Note:

If the time component and time zone offset are not included in the XML source date, Oracle BI Publisher assumes it represents 12:00 AM UTC (that is, YYYY-MM-DDT00:00:00-00:00).


In the Oracle BI Publisher and Oracle Fusion application integration environment, XDODEFDATE is used to pass the Oracle Fusion application date format pattern to Oracle BI Publisher, and XDODEFTIME can pass the Oracle Fusion application time format pattern to Oracle BI Publisher reports.

Consider that "yyyy-MM-dd (2011-05-27)" is selected for the Date Format, and "a hh:mm:ss (AM 12:49:13)" is selected for the Time Format in Oracle Fusion application Preferences, as shown in Figure 20-29:

Figure 20-29 Selecting Date and Time Format in Oracle Fusion Application Preferences

Selecting Date and Time Format in applications Preferences

At runtime, XDODEFDATE is replaced with "yyyy-MM-dd" and XDODEFTIME is replaced with "a hh:mm:ss".

Therefore, to format date or timestamp values in Oracle BI Publisher reports with the Date Format or Time Format selected in Oracle Fusion application Preferences, the format-date function can be used:

  • To display date only values

    <?format-date:Date_Only_Field; 'XDODEFDATE'?>

    Only the date is displayed, such as 2011-05-27.

  • To display time only values

    <?format-date:Time_Only_Field; 'XDODEFTIME'?>

    Only the time is displayed, such as AM 12:49:13.

  • To display datetime values

    <?format-date:Datetime_Field; 'XDODEFDATE XDODEFTIME'?>

    Both date and time are displayed, such as 2011-05-27 AM 12:49:13.

  • To display System Date (sysdate)

    <?format-date:xdoxslt:sysdate_as_xsdformat();' XDODEFDATE XDODEFTIME '?>

    A sample output: 2011-05-27 AM 12:49:13.

With these codes, the format of date or timestamp values varies according to the Date Format or the Time Format chosen in Oracle Fusion application Preferences.

Follow these steps to format date or timestamp values in the RTF template.

  • Open the RTF template file in Microsoft Word.

  • Choose BI Publisher > Sample XML, and choose a sample XML file that contains sample data for the number fields to be formatted in RTF template.

  • Double-click the date or timestamp field to be modified, such as ORDER_DATE. In the BI Publisher Properties dialog, click the Properties tab and make sure that Type is set to Regular Text.

  • Click the Advanced tab and enter format code, as shown in Figure 20-30.

    Figure 20-30 Entering Date Format Code in Oracle BI Publisher Properties

    Entering Date Format Code in BI Publisher Properties
  • Click OK and save the file.

Follow these steps to format date or timestamp values in graphs in Oracle BI Publisher reports.

  • To set format masks for graphs, an Oracle Fusion application Oracle BI Publisher report designer needs to change the RTF template graph code manually.

  • Edit the graph and change the graph definition code in the Advanced tab of the Graph dialog in template builder.

  • Use an XSLT format such as <xsl:value-of select="xdoxslt:xdo_format_date($_XDOXSLTCTX,current-group()/SGT_DATE,'XDODEFDATE XDODEFTIME')" /> to format a date-time value on the graph.

If you do not wish to format date or timestamps according to the Oracle Fusion application Date or Time format, you can use Oracle abstract format masks, such as:

  • <?format-date:ORDER_DATE;'SHORT'?>

  • <?format-date:ORDER_DATE;'LONG'?>

  • <?format-date:xdoxslt:sysdate_as_xsdformat();'MEDIUM'?>

For more abstract format masks, see "Oracle Abstract Format Masks" in "Number, Date, and Currency Formatting" in the Oracle Fusion Middleware Report Designer's Guide for Oracle Business Intelligence Publisher.

With using abstract format masks, date and timestamp values are formatted according to the default format of the Oracle Fusion application user's locale.

20.10.4 How to Honor Time Zones in Oracle BI Publisher

In Oracle BI Publisher and Oracle Fusion application integration environment, the Time Zone selected in Oracle Fusion application Preferences is passed to the Oracle BI Publisher server and overrides the Oracle BI Publisher report time zone automatically. As a result, if the TIMEZONE parameter is not specified in the format-date function, a date/time field in the Oracle BI Publisher report is formatted with the time zone selected in Oracle Fusion application Preferences. That is, time zone conversion happens between the Oracle BI Publisher server time zone and the Oracle Fusion application Preferences time zone.

If you do not wish to format a date-time field with the Oracle Fusion application Preferences Time Zone, you must explicitly specify a time zone ID in the format-date function:

<?format-date:Datetime_Field; 'XDODEFDATE XDODEFTIME', 'timezone'?>

where timezone is a static value, such as PST, UTC, or IST.


Note:

There is no parameter that passes the Oracle Fusion application Corporation Time Zone (CRTZ) or Legal Entity Time Zone (LETZ) to the Oracle BI Publisher server. Therefore, you cannot format a date/time value with CRTZ or LETZ dynamically by using a parameter to pass CRTZ or LETZ to Oracle BI Publisher reports. Instead, you have to hard-code the time zone ID within the format-date function.


20.11 Implementing Localization Formatting in ADF Data Visualization Components

All numerical-based values need to be formatted correctly when they are presented to a user in Oracle Fusion applications graphs. For instance, a value of 1234.5 in the database might need to be displayed as 1 234,500 or 1,234.500 or 1.234,5. The user can change the number of digits found after the decimal digit, grouping separator, and decimal separator.

20.11.1 How to Format Numbers on a Graph

Before you begin, create an entity object and a view object with number fields, including any of the following attribute types: java.math.BigDecimal, java.lang.Integer, or java.lang.Long. Drag and drop the entity and create a data visualization component such as a pie graph, bar graph or a line graph.

Numerical values on all parts of the graph need to be formatted according to the user's number formatting preferences in Oracle Fusion applications. Developers need to add the tag <af:convertNumber> to all the tags in the graph where numerical values are displayed.

The ADF Data Visualization area graph supports number formatting on its Y1 and Y2 axis tick labels, and for marker text that appears on the data points. Users can customize the number formatting by adding <af:convertNumber> to the <dvt:y1TickLabel>, <dvt:y2TickLabel>, <dvt:y1Format>, and <dvt:y2Format> tags. Example 20-45 shows how to configure these tags.

Example 20-45 Area Graph Y1 Axis Number Formatting

<dvt:y1TickLabel>
<af:convertNumber pattern="#{applCorePrefs.numberFormatPattern}"/>
</dvt:y1TickLabel>
 
<dvt:markerText><dvt:y1Format>
<af:convertNumber pattern="#{applCorePrefs.numberFormatPattern}"/>
</dvt:y1Format></dvt:markerText>

In Figure 20-31, numbers such as 20,000 and 40,000 on the Y axis and numbers such as 12,003.67 on the tooltip are examples of numbers on an area graph that should be formatted according to the user's number preferences in graphs in Oracle Fusion applications.

Figure 20-31 Showing Number Formatting on an Area Graph

Showing Number Formatting on an Area Graph

Note: For integer fields, use pattern="#{applCorePrefs.integerFormatPattern}" just like integer formatting in ADF Faces.

Generally, an attribute on an ordinal axis (O1 axis and X1 axis) of a graph in ADF Data Visualization is considered to be text, irrespective of its data type in the model or view layer. A developer can add af:convertNumber to such a view attribute by first adding dvt:attributeFormat to it, and only then will the resultant values on the x-axis and o-axis be formatted according to the user's number preferences. The name="size" entry refers to the categorical attribute (attribute on the ordinal/x axis). To format the integers, use pattern="#{applCorePrefs.integerFormatPattern}", as shown in Example 20-46.

Example 20-46 Area Graph O Axis Formatting

<dvt:attributeFormat id="af1"  name="size">
<af:convertNumber pattern="#{applCorePrefs.numberFormatPattern}"/>
 </dvt:attributeFormat>

In Figure 20-32, numbers such as 2234 and 1014 are examples of numbers on the O axis of an area graph that should be formatted according to the user's number preferences.

Figure 20-32 Numbers to Format Using User's Preferences

Numbers to Format Using User’s Preferences

Other Types of Graphs

Example 20-46 just gives an example of number formatting in area graphs. Table 20-1 presents the tags in which af:convertNumber can be added for number formatting in other types of graphs, such as bar graphs and pie charts, and the graphs in which dvt:attributeFormat can be used to format text attributes on the ordinal axis.

Table 20-1 Using af:convertNumber for Number Formatting and dvt:attributeFormat for Text Formatting

Graph TypeParent Tags for af:convertNumberIs dvt:attributeFormat Needed for Number Formatting?

Bar Graph

<dvt:y1TickLabel>, <dvt:y2TickLabel>, <dvt:y1Format>, and <dvt:y2Format>

Yes (for O1 axis)

Bar Horizontal

<dvt:y1TickLabel>, <dvt:y2TickLabel> ,<dvt:y1Format>, and <dvt:y2Format>

Yes (for O1 axis)

Bubble Graph

<dvt:x1TickLabel>, <dvt:y1TickLabel>, <dvt:y2TickLabel>, <dvt:x1Format>, <dvt:y1Format>, <dvt:y2Format> and <dvt:zFormat>

Yes (but not for O1 axis, for X1 axis)

Combination graph

<dvt:y1TickLabel>, <dvt:y2TickLabel>, <dvt:y1Format>, and <dvt:y2Format>

Yes (for O1 axis)

Funnel Graph

<dvt:sliceLabel>

Yes (for funnel section values)

Line Graph

<dvt:y1TickLabel>, <dvt:y2TickLabel>, <dvt:y1Format>, and <dvt:y2Format>

Yes (for O1 axis)

Pareto Graph

<dvt:y1TickLabel>, <dvt:y2TickLabel>, and <dvt:y1Format>

Yes (for O1 axis)

Pie Graph

<dvt:sliceLabel>

Yes (for slice values)

Pie Bar Charts

<dvt:y1TickLabel>, <dvt:sliceLabel> and <dvt:y1format>

Yes (for slice values)

Gantt Chart

<af:column>

Yes (for O1 axis)

Gauge

<dvt:metricLabel> and <dvt:tickLabel>

Yes (for O1 axis)

ADF Pivot Table

<af:inputText> or <af:outputText> whose parent tag is <dvt:dataCell>

<af:inputText> or <af:outputText> whose parent tag is <dvt:headerCell>



20.11.2 Standards and Guidelines for Formatting Numbers in Graphs

  • dvt:numberFormat has been deprecated and all Oracle Fusion applications developers should use only af:convertNumber to format numbers on graphs.

  • Before adding an af:convertNumber tag to a graph, make sure that the autoPrecision attribute of the parent tag (for example dvt:MarkerText) is set to off. If autoPrecision is set to on, ADF Data Visualization does not follow the converter correctly, and formats numbers automatically, which will be incorrect in Oracle Fusion applications, as the number will not honor user preferences.

  • Set scaling="none" before adding the af:convertNumber tag to a graph. Otherwise ADF Data Visualization will not follow the converter correctly.

20.11.3 How to Format Currency Values in ADF Data Visualization

Currency fields are represented by java.lang.BigDecimal in entity objects and view objects.

A currency field should always be formatted according to the currency code chosen in the context UI of the transaction.

For example, if the user selects "JPY" as the currency code from the context UI, the currency value should be formatted according to the Japanese Yen standard, whereas if USD is chosen as the currency code, the currency value should be formatted according to the American Dollar standard.

Oracle Applications Technology (ATG) provides two implementations to format numerical values according to the corresponding currency code:

  • fnd:currencyPattern(bindingToAmountCurrencyCode) : This function formats the numerical value according to the currency code input as a parameter (for example, if "USD" is the input parameter, the value is formatted as #,##0.00)

  • fnd:currencyPatternWithPrecisionAndSymbol(bindingToAmountCurrencyCode, bindingToAttrNamePrecision, bindingToAttrNameCurrencySymbol): This function formats the numerical value according to the currency code input as the first parameter; the second parameter indicates the number of decimal digits in the formatted value; the third parameter determines whether the formatted string shows the symbol for the currency code, the currency code itself or nothing after the numerical value. (The third parameter can be symbol, code or none.)

20.11.3.1 Formatting Currency Values on a Graph

Before you begin, create an entity object and a view object with number fields, including any of the following attribute types: java.math.BigDecimal, which is a currency value. Drag and drop the entity and create an ADF Data Visualization component, such as a pie graph, bar graph, or a line graph.

Numbers on the Y and O axis can be formatted as currency and can be displayed with the currency symbol, as shown in Example 20-47.

Example 20-47 Area Graph Y1 Axis Currency Value Formatting

<dvt:y1TickLabel>
       <af:convertNumber  pattern="#{ fnd:currencyPattern(YourCurrencyCode)}"/>
</dvt:y1TickLabel>
<dvt:markerText><dvt:y1Format>
<af:convertNumber pattern="#{ fnd:currencyPattern(YourCurrencyCode) }/>
</dvt:y1Format></dvt:markerText>

In Figure 20-33, number values such as 40,000.00 and 80,000.00 on the Y axis, and 13,344.22 on the tooltip, are examples of number fields in an area graph that should be formatted according to the currency code for these values. Numbers on the O1 axis should also be formatted according to the currency code. (In this case, for USD, the format is #,##0.00.)

Figure 20-33 Numbers to Format According to Currency Code

Numbers to Format According to Currency Code

Other Types of Graphs

Example 20-47 gives an example of currency formatting in area graphs. Table 20-2 presents the tags in which af:convertNumber can be added for currency formatting in other types of graphs, and the graphs in which dvt:attributeFormat can be used to format text attributes on the ordinal axis.

Table 20-2 Using af:convertNumber for Currency Formatting and dvt:attributeFormat for Text Formatting

Graph TypeTags in which af:convertNumber Can Be Added for Currency FormattingCan dvt:attributeFormat Be Added for Currency Formatting of Attributes on the Ordinal Axis?

Bar Graph

<dvt:y1TickLabel>, <dvt:y2TickLabel>, <dvt:y1Format>, and <dvt:y2Format>

Yes

Bar Horizontal

<dvt:y1TickLabel>, <dvt:y2TickLabel>, <dvt:y1Format>, and <dvt:y2Format>

Yes

Bubble Graph

<dvt:x1TickLabel>, <dvt:y1TickLabel>, <dvt:y2TickLabel>,<dvt:x1Format>, <dvt:y1Format>, <dvt:y2Format> and <dvt:zFormat>

Yes (but not for O1 axis, for X1 axis)

Combination Graph

<dvt:y1TickLabel>, <dvt:y2TickLabel>, <dvt:y1Format>, and <dvt:y2Format>

Yes

Funnel Graph

<dvt:sliceLabel>

Yes (for funnel section values)

Line Graph

<dvt:y1TickLabel>, <dvt:y2TickLabel>, <dvt:y1Format>, and <dvt:y2Format>

Yes

Pareto Graph

<dvt:y1TickLabel>, <dvt:y2TickLabel>,and <dvt:y1Format>

Yes

Pie Graph

<dvt:sliceLabel>

Yes (for slice values)

Pie Bar Charts

<dvt:y1TickLabel>, <dvt:sliceLabel> and <dvt:y1format>

Yes (for slice values)

Gantt Chart

<af:column>

No

Gauge

<dvt:metricLabel> and <dvt:tickLabel>

No

ADF Pivot Table

<af:inputText>/<af:outputText> whose parent tag is <dvt:dataCell>

<af:inputText>/<af:outputText> whose parent tag is <dvt:headerCell>



20.11.3.2 Standards and Guidelines for Formatting Currency Values in Graphs

  • Before adding an af:convertNumber tag to a graph, make sure that the autoPrecision attribute of the parent tag (such as dvt:MarkerText) is set to off. If autoPrecision is set to on, ADF Data Visualization does not follow the converter correctly, and instead formats numbers automatically, which will be incorrect in Oracle Fusion applications, as the number will not honor user preferences.

  • Set scaling="none" before adding the af:convertNumber tag to a graph. Otherwise, ADF Data Visualization will not follow the converter correctly.

20.11.4 How to Format Dates and Timestamp Values in ADF Data Visualization

All date values on a graph need to be formatted correctly when they are presented to a user. Users expect that they can input values according to their date formatting preferences. For instance, a value of 13th August, 2011 in the database might have to be displayed as 08/13/2011 for a certain user. A similar example of a date-time value is that a value of 26th July 2011, 2:00:00 PM might have to be displayed as 14:00 07/26/2011.

20.11.4.1 Formatting Dates and Timestamp Values on a Graph

Before you begin, create an entity object and a view object with date or timestamp fields, including any of these attribute types: java.sql.Date or java.sql.Timestamp. Drag and drop the entity and create an ADF Data Visualization component, such as a pie graph, a bar graph or a line graph.

A graph typically uses categorical attributes, such as product, geography or year, on an ordinal axis (x axis or dvt:o1Axis) and for the marker tooltips. For the dvt:o1 axis, the data is considered as text no matter what its type in the underlying layers. Therefore, any number or date on the dvt:o1 axis does not honor any formatting.

A user can add af:convertNumber/af:convertDateTime by first adding dvt:attributeFormat to it, and the resultant values on the x-axis will be formatted, as shown in Example 20-48. Also, with this code, wherever the ordinal axis values are used in the user interface, they will appear with the proper formatting.

Example 20-48 Date Formatting on the O1 Axis

<dvt:attributeFormat id="af1" name="OrderDate">
            <af:convertDateTime type="date" pattern="#{applCorePrefs.dateFormatPattern}"/>
 </dvt:attributeFormat>

Notes:

  • If there is a single categorical Date attribute being displayed on the O1Axis, the graph displays a TimeAxis instead of the typical O1 / Ordinal Axis. The TimeAxis will show dates in a hierarchical format instead of as a single label on an O1 Axis, for example June 27, 2001. To show a single label on the O1 Axis, the TimeAxis should be turned off (timeAxisType="TAT_OFF") and a <dvt:attributeFormat> should be used to specify the date format.

  • The Area graph displays a time axis when dates (object type java.util.Date) are specified for the column labels. Several timeXXX attributes are defined on the graph tag to customize the time axis. The child tag timeAxisDateFormat controls the format in which the time axis labels are displayed.

    <dvt:timeAxisDateFormat dayFormat="DAY_OF_MONTH"
             monthFormat="MONTH_LONG"
             quarterFormat="NONE" yearFormat="YEAR_LONG"
             timeFormat="HOUR_MINUTE_SECOND"/>
    

Example 20-49 shows timestamp formatting on the O1 axis.

Example 20-49 Timestamp Formatting on the O1 Axis

<dvt:attributeFormat id="af1" name="LastUpdateDate">
            <af:convertDateTime type="both" pattern="#{applCorePrefs.UPTZPattern}"/>
 </dvt:attributeFormat>

This is the same as the case of ADF Faces, in which the UPTZPattern is used to format timestamp values and dateFormatPattern is used to format date values.

In Figure 20-34, dates such as 2/1/2015 on the O1 axis and 8/9/2009 on the tooltip are examples of date fields on an area graph that should be formatted according to the user's date formatting preferences.

Figure 20-34 Dates to Format Using User Preferences

Dates to Format Using User Preferences

Other Types of Graphs

Example 20-49 just gives an example of date and date-time formatting in area graphs. Table 20-3 shows the tags in which af:convertDateTime can be added for date and timestamp formatting in the other types of graphs.

Table 20-3 Using af:convertDateTime for Date and Timestamp Formatting

Graph TypeIs dvt:attributeFormat Required?

Bar Graph

Yes

Bar Horizontal

Yes

Bubble Graph

Yes

Combination Graph

Yes

Funnel Graph

Yes (for funnel section values

Line Graph

Yes

Pareto Graph

Yes

Pie Graph

Yes

Pie Bar Charts

Yes

Gantt Chart

No (Add af:convertDateTime as a child tag of af:column)

Gauge

N/A

ADF Pivot Table

<af:inputText>/<af:outputText> whose parent tag is <dvt:dataCell><af:inputText>/<af:outputText> whose parent tag is <dvt:headerCell>


20.12 Configuring National Language Support Attributes

In Oracle Fusion Applications, National Language Support (NLS) refers to the ability to run an application instance in any single supported language, including specific regional or territorial number and date formats. Typically, in order to support a given language, only the customer-facing components of the software (user interface, lookup tables, online documentation, and so on) are translated. Translations are delivered via NLS patches.

20.12.1 Session National Language Support Attributes

Oracle Fusion Applications manage NLS attributes at the session level. At runtime, these attributes are initialized based on the user's profile, and are applied when needed by Applications Core. For example, the session date format mask is initialized based on the user's preferred date format mask. The date format mask is automatically applied when date is rendered and parsed. As such, it is unnecessary to manually specify NLS attributes in design time.

In certain situations, however, you may need to access the NLS attributes for the purposes of data formatting or parsing your code. To do so, use the managed bean ApplCorePrefs.

Table 20-4 lists the Oracle Fusion Applications session NLS attributes, the profile used to set each attribute and the possible values for session attributes.

Table 20-4 Session NLS Attributes

Session AttributeProfileValuesComments

LANGUAGE

FND_LANGUAGE

select DESCRIPTION, LANGUAGE_TAG from FND_LANGUAGES_B where INSTALLED_FLAG in ('I', 'B');

Primary attribute used to represent the current language. Corresponds to the LANGUAGE_TAG column in FND_LANGUAGES.

Looks up the corresponding NLS_LANGUAGE and alters the session in the database. Valid examples are es, es-US, fr.


NLS_LANG


Represents the two letter language code, which is derived using the LANGUAGE attributes. This value is derived rather than explicitly set.


NLS_LANGUAGE


Represents the NLS language, which is derived from the LANGUAGE attribute. This value is derived rather than explicitly set.


NLS_SORT

FND_NLS_SORT

select MEANING, LOOKUP_CODE

from FND_LOOKUPS

where LOOKUP_TYPE = 'NLS_SORT'

and ENABLED_FLAG = 'Y'

and SYSDATE

between START_DATE_ACTIVE and nvl(END_DATE_ACTIVE, SYSDATE+1);

Setting this attribute results in an altered session in the database for the NLS_SORT database attribute.

DATE_FORMAT

FND_DATE_FORMAT

select MEANING, LOOKUP_CODE

from FND_LOOKUPS

where LOOKUP_TYPE = 'DATE_FORMAT'

and ENABLED_FLAG = 'Y' and SYSDATE between START_DATE_ACTIVE and nvl(END_DATE_ACTIVE, SYSDATE+1);


TIME_FORMAT

FND_TIME_FORMAT

select MEANING, LOOKUP_CODE

from FND_LOOKUPS

where LOOKUP_TYPE = 'TIME_FORMAT'

and ENABLED_FLAG = 'Y'

and SYSDATE between START_DATE_ACTIVE and nvl(END_DATE_ACTIVE, SYSDATE+1);


GROUPING_SEPARATOR

FND_GROUPING_SEPARATOR

select MEANING, LOOKUP_CODE

from FND_LOOKUPS

where LOOKUP_TYPE = 'GROUPING_SEPARATOR'

and ENABLED_FLAG = 'Y'

and SYSDATE between START_DATE_ACTIVE and nvl(END_DATE_ACTIVE, SYSDATE+1);


DECIMAL_SEPARATOR

FND_DECIMAL_SEPARATOR

select MEANING, LOOKUP_CODE

from FND_LOOKUPS

where LOOKUP_TYPE = 'DECIMAL_SEPARATOR'

and ENABLED_FLAG = 'Y'

and SYSDATE between START_DATE_ACTIVE and nvl(END_DATE_ACTIVE, SYSDATE+1);


CURRENCY

FND_CURRENCY

select NAME, CURRENCY_CODE

from FND_CURRENCIES_VL

where ENABLED_FLAG = 'Y'

and SYSDATE between START_DATE_ACTIVE and nvl(END_DATE_ACTIVE, SYSDATE+1);

This attribute specifies the preferred currency code. It has no corresponding database attribute.

TERRITORY

FND_TERRITORY

select TERRITORY_SHORT_NAME, TERRITORY_CODE from FND_TERRITORIES_VL where ENABLED_FLAG = 'Y';

This attribute specifies the preferred territory. This attribute differs from the database attribute NLS_TERRITORY, as Oracle Fusion Applications supports more territories than the database. The database attribute is permanently set to the value AMERICAN.

TIMEZONE

FND_TIMEZONE

select TIMEZONE_CODE, NAME from FND_TIMEZONES_VL where ENABLED_FLAG = 'Y';

This attribute specifies the preferred time zone value.

CLIENT_ENCODING

FND_CLIENT_ENCODING

select MEANING, LOOKUP_CODE

from FND_LOOKUPS

where LOOKUP_TYPE = 'CLIENT_ENCODING'

and ENABLED_FLAG = 'Y'

and SYSDATE between START_DATE_ACTIVE and nvl(END_DATE_ACTIVE, SYSDATE+1);



Table 20-5 lists language and territory values used with NLS attributes.

Table 20-5 Language and Territory Values

LANGUAGE_TAGLANGUAGE_CODELANGUAGE_IDNLS_LANGUAGENLS_TERRITORYISO_LANGUAGEISO_TERRITORYNLS_CODESETISO_LANGUAGE_3

ar

AR

8

ARABIC

UNITED ARAB EMIRATES

ar

AE

AR8ISO8859P6

ara

bg

BG

101

BULGARIAN

BULGARIA

bg

BG

CL8ISO8859P5

bul

ca

CA

102

CATALAN

CATALONIA

ca

CT

WE8ISO8859P1

cat

cs

CS

30

CZECH

CZECH REPUBLIC

cs

CZ

EE8ISO8859P2

ces

de

D

4

GERMAN

GERMANY

de

DE

WE8ISO8859P1

deu

da

DK

5

DANISH

DENMARK

da

DK

WE8ISO8859P1

dan

es

E

11

SPANISH

SPAIN

es

ES

WE8ISO8859P1

spa

eg

EG

118

EGYPTIAN

EGYPT

eg

EG

AR8ISO8859P6

egy

el

EL

104

GREEK

GREECE

el

GR

EL8ISO8859P7

ell

es-US

ESA

29

LATIN AMERICAN SPANISH

AMERICA

es

US

WE8ISO8859P1

spa

fr

F

2

FRENCH

FRANCE

fr

FR

WE8ISO8859P1

fra

fr-CA

FRC

3

CANADIAN FRENCH

CANADA

fr

CA

WE8ISO8859P1

fra

en-GB

GB

1

ENGLISH

UNITED KINGDOM

en

GB

WE8ISO8859P1

eng

hr

HR

103

CROATIAN

CROATIA

hr

HR

EE8ISO8859P2

hrv

hu

HU

28

HUNGARIAN

HUNGARY

hu

HU

EE8ISO8859P2

hun

it

I

108

ITALIAN

ITALY

it

IT

WE8ISO8859P1

ita

is

IS

106

ICELANDIC

ICELAND

is

IS

WE8ISO8859P1

isl

he

IW

107

HEBREW

ISRAEL

he

IL

IW8ISO8859P8

heb

ja

JA

15

JAPANESE

JAPAN

ja

JP

JA16EUC

jpn

ko

KO

16

KOREAN

KOREA

ko

KR

KO16KSC5601

kor

lt

LT

109

LITHUANIAN

LITHUANIA

lt

LT

NEE8ISO8859P4

lit

no

N

10

NORWEGIAN

NORWAY

no

NO

WE8ISO8859P1

nor

nl

NL

6

DUTCH

THE NETHERLANDS

nl

NL

WE8ISO8859P1

nld

pl

PL

110

POLISH

POLAND

pl

PL

EE8ISO8859P2

pol

pt

PT

18

PORTUGUESE

PORTUGAL

pt

PT

WE8ISO8859P1

por

pt-BR

PTB

26

BRAZILIAN PORTUGUESE

BRAZIL

t

BR

WE8ISO8859P1

por

ro

RO

111

ROMANIAN

ROMANIA

ro

RO

EE8ISO8859P2

ron

ru

RU

112

RUSSIAN

RUSSIA

ru

RU

CL8ISO8859P5

rus

sv

S

13

SWEDISH

SWEDEN

sv

SE

WE8ISO8859P1

swe

fi

SF

7

FINNISH

FINLAND

fi

FI

WE8ISO8859P1

fin

sk

SK

113

SLOVAK

SLOVAKIA

sk

SK

EE8ISO8859P2

slk

sl

SL

114

SLOVENIAN

SLOVENIA

sl

SI

EE8ISO8859P2

slv

th

TH

115

THAI

THAILAND

th

TH

TH8TISASCII

tha

tr

TR

116

TURKISH

TURKEY

tr

TR

WE8ISO8859P9

tur

en

US

0

AMERICAN

AMERICA

en

US

US7ASCII

eng

zh-CN

ZHS

14

SIMPLIFIED CHINESE

CHINA

zh

CN

ZHS16CGB231280

zho

zh-TW

ZHT

117

TRADITIONAL CHINESE

TAIWAN

zh

TW

ZHT16BIG5

zho

sq

SQ

67

ALBANIAN

ALBANIA

sq

AL

EE8ISO8859P2

sqi

vi

VN

43

VIETNAMESE

VIETNAM

vi

VN

VN8MSWIN1258

vie

id

IN

46

INDONESIAN

INDONESIA

id

ID

WE8ISO8859P1

ind


20.12.2 Database Session Attributes

Oracle Fusion Applications does not use most of the database session NLS parameters. Instead, these are set to constant values such that typically, the user's preferred values are not reflected. This is true for most parameters except the following: NLS_LANGUAGE which is set to view link view access, and NLS_SORT, which is set to use the database linguistic sorting functionality.

The parameters TO_NUMBER, TO_DATE, TO_TIMESTAMP and TO_CHAR are used to format and parse SQL or PL/SQL statements. These parameters are based on constant values, the canonical format. The parameter FND_DATE for PL/SQL packages also works with the canonical format. Formatting and parsing should be done at the presentation, rather than the model layer.

Oracle Fusion Applications session management controls database session parameters. As such, the database NLS session parameter values must not be altered.

Table 20-6 lists the following:

  • Database attribute: The database NLS session parameter name.

  • Associated session attribute: The Oracle Fusion Applications NLS session attribute name related to the database attribute name, if one exists. If the attributes are indeed related, configuring a value for the Oracle Fusion Applications NLS session attribute results in an ALTER SESSION in the database layer.

  • Default value: The default value of the attribute. This value is configured both in the database and init.ora as the database default.

  • Alter Session: Indicates whether an ALTER SESSION is created in the database. When an ALTER SESSION initiates at session creation or attachment, execute NLS_LANGUAGE and NLS_TERRITORY first, as these may affect other attributes.

    • Create: An ALTER SESSION is created once, when the connection is first created.

    • Update: The ALTER SESSION updates when the session attaches, or whenever an associated attribute value changes mid-session.

    • Never: An ALTER SESSION is not created, and the default database value is unchanged.

Table 20-6 Localization Database Attributes

Database AttributeDefault ValueAlter SessionComments

NLS_CALENDAR

None

Never

This attribute need not be set as the default value is GREGORIAN. Accept the default value.

NLS_COMP

None

Never

This attribute need not be set as the default value is BINARY. Accept the default value.

NLS_CURRENCY

None

Never

Accept the default value.

NLS_DATE_FORMAT

YYYY-MM-DD

Create

Fixed value.

NLS_DATE_LANGUAGE

NUMERIC DATE LANGUAGE

Create

Fixed value. Does not require an attribute or profile.

NLS_ISO_CURRENCY

None

Never

Accept the default value.

NLS_LANGUAGE

None

Update

The value of this attribute is based on the LANGUAGE session attribute. See the LANGUAGE attribute in Table 20-4.

NLS_TERRITORY

AMERICA

Create

The value of this attribute is fixed. See the TERRITORY attribute in Table 20-4.

NLS_LENGTH_SEMANTICS

CHAR

Create

Fixed value. Does not require an attribute or profile.

NLS_NCHAR_CONV_EXCP

None

Never

Accept the default value. This parameter is not used.

NLS_NUMERIC_CHARACTERS

,.

Create

Fixed value. Choose group and decimal separators independently.

NLS_SORT

None

Update

In order to enable linguistic sorting, the NLS_SORT session attribute is used to set the value for this database attribute. See the NLS_SORT session attribute in Table 20-4.

NLS_TIME_FORMAT

HH24:MI:SS.FF

Create

Fixed value. Does not require an attribute or profile.

NLS_TIME_TZ_FORMAT

HH24:MI:SS.FF TZR

Create

Fixed value. Does not require an attribute or profile.

NLS_TIMESTAMP_FORMAT

YYYY-MM-DD HH24:MI:SS.FF

Create

Fixed value. Does not require an attribute or profile.

NLS_TIMESTAMP_TZ_FORMAT

YYYY-MM-DD HH24:MI:SS.FF TZR

Create

Fixed value. Does not require an attribute or profile.

NLS_DUAL_CURRENCY

None

Never

Accept the default value.



Note:

As the language attributes tracked on the session reflect Java values, you cannot use them for formatting on the PL/SQL layer.


20.13 Standards and Guidelines for Localization Formatting

The following standards and guidelines apply to localization formatting:

PKuMfc4 PK BOEBPS/ecsf_gs.htm Getting Started with Oracle Enterprise Crawl and Search Framework

26 Getting Started with Oracle Enterprise Crawl and Search Framework

This chapter provides an introduction to Oracle Enterprise Crawl and Search Framework (ECSF). It also describes how to set up ECSF.

This chapter includes the following sections:

26.1 Introduction to Using Oracle Enterprise Crawl and Search Framework

Oracle Enterprise Crawl and Search Framework (ECSF) is an Oracle Fusion Middleware search framework that enables you to quickly expose application context information on various business objects to enable full-text transactional search.

For more information, see the "Managing Search with Oracle Enterprise Crawl and Search Framework" chapter in the Oracle Fusion Applications Administrator's Guide.

26.1.1 ECSF Architecture

The ECSF framework abstracts an underlying search engine and provides a common set of application programming interfaces (APIs) for developing search functionalities. ECSF serves as an integration layer between the search engine and the Oracle Fusion applications. Figure 26-1 illustrates the architecture of the ECSF framework.

Figure 26-1 Enterprise Crawl and Search Framework Architecture

ECSF components and external dependencies

ECSF includes the following high-level components:

  • Searchable Object Manager

  • Search Designer

  • Semantic Engine

  • Fusion Applications Control

  • ECSF Command Line Administration Utility

  • Security Services

  • Data Services

  • Query Service

ECSF integrates with the Oracle Secure Enterprise Search (Oracle SES) engine to support application search. Oracle SES provides capabilities for crawling and indexing the metadata and objects exposed by ECSF. The Security Plug-in and Crawler Plug-in are modules on Oracle SES that interface with ECSF.

26.1.1.1 Searchable Object Manager

Searchable Object Manager, serving as a metadata manager, manages searchable objects and provides the runtime interface for accessing these objects. At runtime, the Searchable Object Manager loads the searchable objects from persistent storage, validates the searchable object definitions, and provides the searchable objects to the Crawlable Factory component of the Data Service.

The Searchable Object Manager is also responsible for the life cycle management of searchable objects, which administrators can deploy, customize, and enable or disable via the Fusion Applications Control or the ECSF Command Line Administration Utility.

26.1.1.2 Search Designer

The Search Designer is a page in Oracle JDeveloper 11g that provides the interface for defining the metadata that describes the business objects to be indexed. You can also use this design interface to specify the security mechanism used to protect the data, as well as define the searchable object search characteristics, which include Advanced Search, Faceted Navigation, and Actionable Results.

26.1.1.3 Semantic Engine

The Semantic Engine leverages the semantic information of searchable object definitions to create context around the search. It achieves this by interpreting the searchable object definitions with relation to the runtime user information during both crawl and query time. Runtime user information may include the following:

  • Facets

  • Actionable results

  • Security

  • Personalization

  • Internationalization

  • Data structure mapping

  • Tagging, commenting, rates

  • Results clustering

  • Context filtering

  • Custom weighting

26.1.1.4 Fusion Applications Control

The Fusion Applications Control is an Oracle Enterprise Manager extension that provides a user interface for registering searchable objects in the ECSF schema in the Oracle Fusion Applications database, as well as for administering the runtime parameters of ECSF, the target search engine, and the configuration of parameters.

26.1.1.5 ECSF Command Line Administration Utility

The ECSF Command Line Administration Utility is a standalone command line interface that provides a user interface for registering searchable objects in the ECSF schema in the Oracle Fusion Applications database. You can also use this tool for configuring and administering ECSF without external dependencies on Oracle Enterprise Manager.

26.1.1.6 Security Service

The Security Service is the runtime server component responsible for providing security information to SES. During query time, this service retrieves the security keys of the user performing the search and passes them to Oracle SES, where they are used to filter the query results.

The Security Service server component is also invoked during crawl time to add security information (access control lists) to data before inserting or creating indexes on the search engine (Oracle SES). An access control list (ACL) is a list that identifies the users who can access the associated object and that specifies the user's access rights to that object. The ACL values generated by the Security Service during crawl time should match the corresponding keys generated during query time.


Note:

In ECSF, the generic term ACL (access control list) is used to describe how Oracle SES and ECSF pass security information and perform security checks by using the information described in the ACL.


The Security Service component is implemented as a security engine with a plug-in interface. The security plug-in determines the format of the ACL keys. For all custom security models, a new Security Plug-in must be implemented. Security Service uses Oracle Platform Security for Java to authenticate users and call the Security Plug-in to retrieve security values for a given searchable object.

For more information about security for ECSF, see Chapter 28, "Configuring ECSF Security."

26.1.1.7 Data Service

Data Service is the primary data interface, based on a proprietary Really Simple Syndication (RSS) feed format, between ECSF and the search engine. In addition to supporting the flow of metadata between ECSF and the search engine, Data Service supports attachments, batching, and error handling.

Data Service authenticates each Oracle SES crawl request by using Oracle Platform Security for Java to validate the user credentials and permissions for crawling the data source.

The Crawlable Factory component, part of Data Service, determines how searchable objects are broken down and manages the construction of RSS feeds to the search engine.

26.1.1.8 Query Service

The Query Service provides a search interface for the applications UI and handles all search requests. This service performs query rewrite, parameter substitution, and other preprocessing operations before invoking the underlying configured search engine.

Search results are also serviced via this service. Hooks are provided to preprocess and postprocess data, which facilitates the capability to filter search results.

26.1.1.9 Oracle SES Search Engine

Oracle SES enables a secure, uniform search across multiple enterprise repositories. ECSF integrates with Oracle SES technology to provide full-text search functionality in Oracle Fusion Applications.

For more information about Oracle SES, see Oracle Secure Enterprise Search Administrator's Guide.


Note:

The application server space is demarcated to identify that ECSF runs in a separate application server, outside the search engine. It is recommended, for performance reasons, that each search engine instance runs on separate hardware.


26.1.1.10 Security Plug-in

Oracle SES provides an API for writing security plug-ins (or connectors) in Java. With this API, you can create a security plug-in to meet your requirements. ECSF Security Service interfaces with this security plug-in. The Security Plug-in invokes the Security Service to retrieve keys, to which the user has access, for filtering the results that are delivered to the ECSF query service. A proxy user must be set up on the search engine in order to invoke the Security Service. The proxy user must have security privileges for the Oracle Fusion applications. For more information about security for ECSF, see Chapter 28, "Configuring ECSF Security."

26.1.1.11 Crawler Plug-in

The Crawler Plug-in is a search engine (Oracle SES) module that implements the modified RSS feed format between ECSF and Oracle SES. This component deserializes the data sent from ECSF, via the Data Service component, and interfaces with the Oracle SES components that creates the indexes.

26.2 Setting Up and Running ECSF Command Line Administration Utility

You can use the ECSF Command Line Administration Utility to quickly test and manage the searchable objects without having to use Oracle Enterprise Manager Fusion Applications Control.


Note:

Administrators should use Fusion Applications Control to manage the life cycle of searchable objects in the production environment.


Before you can run the utility, you must complete the following setup requirements:

  1. Make the searchable objects accessible to the ECSF Command Line Admin Utility.

  2. Set the class path to make sure it contains the required Oracle classes. ECSF provides a set of scripts that you can use to set the class path.

  3. Connect to the database by performing one of the following tasks:

    • Provide the connection information in the script so that the ECSF Command Line Administration Utility automatically connects to the specified database during startup.

    • Manually connect to the database after you start the ECSF Command Line Administration Utility.

  4. Provide the path of the JPS Config file.

  5. Create ECSF query proxy users. In order to perform commands that connect to the Oracle SES server (for example, deploy, start schedule, etc.), the engine instance must be set up correctly so that its parameters have the required information. For more information, see the "Managing Search with Oracle Enterprise Crawl and Search Framework" chapter in the Oracle Fusion Applications Administrator's Guide.

  6. (Optional) Configure the log settings.

  7. (Optional) Set the startup parameter to support taking input from a text file.

After you have set up the ECSF Command Line Administration Utility, you can run the utility by any of the following ways:

Enter a username and password when prompted.


Note:

If you enter an invalid username and password, you can either reconnect manually by using the connect command, or exit the ECSF Command Line Administration Utility (type exit or press Ctrl-C) and try again.

When you update passwords in the Lightweight Directory Access Protocol (LDAP) credential store from the ECSF Command Line Administration Utility, the jps-config-jse.xml file must contain the same LDAP information as the jps-config.xml file. Java Platform Security (JPS) does not propagate the changes from jps-config.xml to jps-config-jse.xml automatically.


All commands, responses, and error messages in the ECSF Command Line Administration Utility are logged.

To exit the ECSF Command Line Administration Utility, enter the exit command at the prompt.

26.2.1 How to Make Searchable Objects Accessible to the ECSF Command Line Administration Utility

Make the searchable objects accessible to the ECSF Command Line Administration Utility by adding the ADF library JAR file containing the view object and entity object definitions to its class path.

The ECSF Command Line Administration Utility needs the path of the JAR file containing the searchable objects. These metadata objects are validated during register and unregister operations.

You can find the unpacked EAR files containing the searchable object JAR files for the search applications in the following locations:

  • /net/mount1/appbase/fusionapps/applications/fscm/deploy/EarFscmSearch.ear/APP-INF/lib/searchable_object_jar_file

  • /net/mount1/appbase/fusionapps/applications/crm/deploy/EarCrmSearch.ear/APP-INF/lib/searchable_object_jar_file

  • /net/mount1/appbase/fusionapps/applications/hcm/deploy/EarHcmSearch.ear/APP-INF/lib/searchable_object_jar_file

To add the ADF library JAR file containing the view object and entity object definitions to the class path for the ECSF Command Line Administration Utility, you must first create the ADF library. For information, see the "Adding ADF Library Components into Projects" section in Oracle Fusion Middleware Fusion Developer's Guide for Oracle Application Development Framework (Oracle Fusion Applications Edition).

The application JAR file, which contains the searchable objects that are defined in your application, is written to the deploy directory of the project.

In order to deploy or undeploy a searchable object, a JAR file containing the searchable object must be specified in the class path of the ECSF Command Line Administration Utility. For information, see Section 26.2.2, "How to Set the Class Path."

If you are deploying searchable objects from multiple applications, you must create a JAR file for each of those applications in order to add the searchable objects to the class path.

26.2.2 How to Set the Class Path

In order for the ECSF Command Line Administration Utility to run, the class path must contain the required Oracle classes. Modify and run scripts to set the class path, as well as optional connection information, and run the ECSF Command Line Administration Utility.


Note:

If you receive a java.lang.ClassNotFoundException exception, then add the JAR file containing that class to ADMIN_CP in the script.


The ECSF Command Line Administration Utility references the class path to obtain the location of Oracle Library home, Java home, Oracle WebLogic Server home, and the JAR files needed for the ECSF Command Line Administration Utility operations.

26.2.2.1 Setting the Class Path in Windows

Modify and run the runCmdLineAdmin.bat script to set the class path in a Windows environment.

To set the class path in Windows:

  1. In a text editor, open the runCmdLineAdmin.bat script from MW_HOME/Oracle_atgpf1/ecsf/modules/oracle.ecsf_11.1.1/admin.

  2. Specify the Oracle Library home directory path by locating the line set ORACLE_LIBRARY_HOME=SET_ORACLE_LIBRARY_HOME and replace SET_ORACLE_LIBRARY_HOME with the ATGPF shiphome directory, for example, set ORACLE_LIBRARY_HOME=C:\mw_home\oracle_common.

  3. Specify the ATGPF Library home directory path by locating the line set ATGPF_LIBRARY_HOME=SET_ATGPF_LIBRARY_HOME and replace SET_ATGPF_LIBRARY_HOME with the ATGPF shiphome directory, for example, set ATGPF_LIBRARY_HOME=C:\mw_home\Oracle_atgpf1.

    Specify the ATGPF Library home directory path by locating the line set ATGPF_LIBRARY_HOME=SET_ATGPF_LIBRARY_HOME and replace SET_ATGPF_LIBRARY_HOME with the ATGPF Library directory, for example, set ATGPF_LIBRARY_HOME=c:\fmwtools_view\fmwtools\mw_home\jdeveloper.

  4. Specify the Oracle WebLogic Server home directory path:

    1. Locate the following line: set WLS_HOME=SET_WLS_HOME

    2. Replace SET_WLS_HOME with the Oracle WebLogic Server home directory path, for example, set WLS_HOME= C:/MW_HOME/wlserver_10.3

  5. Specify the Java home directory path:

    • Locate the following line: set JAVA_HOME=SET_JAVA_HOME

    • Replace SET_JAVA_HOME with the Java home directory path (where the Java executable should be located), for example, set JAVA_HOME=C:\Java\jdk\bin.

    The version of Java used must match the version required by the Oracle build.

  6. Specify the directory path of the application JAR file:

  7. Save the script file.

26.2.2.2 Setting the Class Path in Linux

Modify and run the runCmdLineAdmin.sh script to set the class path in a Linux environment.

To set the class path in Linux:

  1. In a text editor, open the runCmdLineAdmin.sh script from MW_HOME/Oracle_atgpf1/ecsf/modules/oracle.ecsf_11.1.1/admin.

  2. Specify the Oracle Library home directory path by locating the line export ORACLE_LIBRARY_HOME=SET_ORACLE_LIBRARY_HOME and replace SET_ORACLE_LIBRARY_HOME with the ATGPF shiphome directory, for example, export ORACLE_LIBRARY_HOME="/scratch/mw_home/Oracle_atgpf1".

    Specify the Oracle Library home directory path by locating the line export ORACLE_LIBRARY_HOME=SET_ORACLE_LIBRARY_HOME and replace SET_ORACLE_LIBRARY_HOME with the Oracle Common Library directory, for example, export ORACLE_LIBRARY_HOME="/scratch/login/view_storage/login_fmwtools_view/fmwtools/mw_home/oracle_common".

  3. Specify the ATGPF Library home directory path by locating the line export ATGPF_LIBRARY_HOME=SET_ATGPF_LIBRARY_HOME and replace SET_ATGPF_LIBRARY_HOME with the ATGPF shiphome directory, for example, set ATGPF_LIBRARY_HOME="/scratch/fmwtools/mw_home/Oracle_atgpf1".

  4. Specify the Java home directory path:

    • Locate the following line: export JAVA_HOME="set_java_home"

    • Replace set_java_home with the Java home directory path (where the Java executable should be located), for example, export JAVA_HOME="/Java/jdk/bin".

    The version of Java used must match the version required by the Oracle build.

  5. Specify the directory path of the application JAR file:

  6. Save the script file.

  7. Run the script.

26.2.3 How to Set the Connection Information

The ECSF Command Line Administration Utility requires an Oracle Fusion Applications database, to which it can either be directly connected or connected through a remote MBean. In order to use the ECSF Command Line Administration Utility, you must supply the connection information.

Set the connection information in the runCmdLineAdmin script so that the ECSF Command Line Administration Utility automatically connects to the specified database or MBean server during startup. If you do not include the connection information in the script, then you must manually create the connection to the Oracle Fusion Applications database after you start the ECSF Command Line Administration Utility. For information, see Section 26.2.4, "How to Manually Connect to the Oracle Fusion Applications Database."

The information for connecting to the database or MBean server is saved in the runCmdLineAdmin script for the ECSF Command Line Administration Utility to use for connecting to the Oracle Fusion Applications database at startup. You are prompted to enter a password after you start the ECSF Command Line Administration Utility.

26.2.3.1 Setting the Connection Information in Windows

Modify the runCmdLineAdmin.bat script to set the connection information in a Windows environment.

To set the connection information in Windows:

  1. Open the runCmdLineAdmin.bat script, located in JDEV_INSTALL/ecsf, in a text editor.

  2. Locate set CONNECT_INFO= and specify the database or MBean server, using one of the following formats:

    • connect to mbeanserver hostname port

    • Using SID:

      connect to database hostname port SID

      For example,

      set CONNECT_INFO=connect to database fusionhost123 1566 fh123.

    • Using service name:

      connect to database service hostname port servicename

      For example,

      set CONNECT_INFO=connect to database service fusionhost123 5521 myservice

    • Using database descriptor:

      connect to database descriptor 'descriptor'

      The descriptor argument must be enclosed in quotation marks and can contain either the SID or service name. For example:

      • Using SID:

        set CONNECT_INFO=connect to database descriptor '(DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=fusionhost123)(PORT=5521))(CONNECT_DATA=(SID=dbmsdb2)))'

      • Using service name:

        set CONNECT_INFO=connect to database descriptor '(DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=fusionhost123)(PORT=5521))(CONNECT_DATA=(SERVICE NAME=myservice)))'

  3. Save the script file.

26.2.3.2 Setting the Connection Information in Linux

Modify and run the runCmdLineAdmin.sh script to set the connection information in a Linux environment.

To set the connection information in Linux:

  1. Open the runCmdLineAdmin.sh script, located in ORACLE_HOME/jdeveloper/ecsf, in a text editor.

  2. Locate export CONNECT_INFO="" and specify the database or MBean server, using one of the following formats:

    • connect to mbeanserver hostname port

    • Using SID:

      connect to database hostname port SID

      For example,

      set CONNECT_INFO=connect to database fusionhost123 1566 fh123
      
    • Using service name:

      connect to database service hostname port servicename

      For example,

      set CONNECT_INFO=connect to database service fusionhost123 5521 myservice
      
    • Using database descriptor:

      connect to database descriptor 'descriptor'

      The descriptor argument must be enclosed in quotation marks and can contain either the SID or service name. For exDSample:

      • Using SID:

        set CONNECT_INFO=connect to database descriptor '(DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=fusionhost123)(PORT=5521))(CONNECT_DATA=(SID=dbmsdb2)))'
        
      • Using service name:

        set CONNECT_INFO=connect to database descriptor '(DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=fusionhost123)(PORT=5521))(CONNECT_DATA=(SERVICE NAME=myservice)))'
        
  3. Save the script file.

26.2.4 How to Manually Connect to the Oracle Fusion Applications Database

The ECSF Command Line Administration Utility requires an Oracle Fusion Applications database, to which it can either be directly connected or connected through a remote MBean, for command execution. In order to use the ECSF Command Line Administration Utility, you must supply the connection information.

You can supply connection information either before or after starting the ECSF Command Line Administration Utility. Supplying the connection information before startup allows the ECSF Command Line Administration Utility to automatically connect to the specified database or MBean server during startup. For information, see Section 26.2.3, "How to Set the Connection Information."

If you choose not to supply the connection information before startup, you must manually create the connection to the Oracle Fusion Applications database after you start the ECSF Command Line Administration Utility.

To create the connection to the Oracle Fusion Applications database:

To create a connection to the Oracle Fusion Applications database directly, enter one of the following commands at the ECSF Command Line Administration prompt, then press Enter:

  • connect to database

    The ECSF Command Line Administration Utility prompts you for the host name, port, and SID.

  • connect to database service

    The ECSF Command Line Administration Utility prompts you for the host name, port, and service name.

  • connect to database descriptor

    The ECSF Command Line Administration Utility prompts you for the descriptor.

    The descriptor argument must be enclosed in quotation marks and can contain either the SID or service name. For example:

    • Using SID:

      '(DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=fusionhost123)(PORT=5521))(CONNECT_DATA=(SID=dbmsdb2)))'
      
    • Using service name:

      '(DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=fusionhost123)(PORT=5521))(CONNECT_DATA=(SERVICE NAME=myservice)))'
      
  • connect to database hostname port SID

    You can directly pass the required values as arguments into the command.

  • connect to database service hostname port servicename

    You can directly pass the required values as arguments into the command.

  • connect to database descriptor 'descriptor'

    You can directly pass the required value as an argument into the command. The descriptor argument must be enclosed in quotation marks and can contain either the SID or service name. For example:

    • Using SID:

      '(DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=fusionhost123)(PORT=5521))(CONNECT_DATA=(SID=dbmsdb2)))'
      
    • Using service name:

      '(DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=fusionhost123)(PORT=5521))(CONNECT_DATA=(SERVICE NAME=myservice)))'
      

To create a connection to the Oracle Fusion Applications database through a remote MBean, enter one of the following commands at the ECSF Command Line Administration prompt, then press Enter:

  • connect to mbeanserver

    The ECSF Command Line Administration Utility prompts you for the required values.

  • connect to mbeanserver hostname port

    You can directly pass the required values as arguments into the command.

The ECSF Command Line Administration Utility prompts you to enter a username and password.

26.2.5 How to Provide the Path of the JPS Config File

The JPS Config file (jps-config-jse.xml) contains the credential store information needed for running the ECSF Command Line Administration scripts. You must provide the path of the JPS Config file by modifying the ECSF Command Line Administration scripts.

To set the JPS Config file path:

  1. Open the runCmdLineAdmin.bat (Windows) or runCmdLineAdmin.sh (Linux) script, located in ORACLE_HOME/jdeveloper/ecsf, in a text editor.

  2. Set the JPS_CONFIG parameter to point to the location of jps-config-jse.xml (usually at DOMAIN_HOME/config/fmwconfig/jps-config-jse.xml).

  3. Save.

26.2.6 How to Configure the Log Settings

The scripts for the ECSF Command Line Administration Utility point to the logging configuration file (ecsfcla-logging.xml), where you can configure log settings, such as log level and log file location. The ecsfcla-logging.xml file is located in the same directory as the ECSF Command Line Administration scripts (JDEV_INSTALL/ecsf/). To configure log settings, modify the property values in ecsfcla-logging.xml and save the file.

The location of ecsfcla-logging.xml can be changed by modifying the ODL_CONFIG parameter in the ECSF Command Line Administration scripts.

All commands, responses, and error messages in the ECSF Command Line Administration Utility are logged. The generated log files follow the format ecsfCmdLineAdminLog*.txt, and its default location is JDEV_INSTALL/ecsf/log/.

26.2.7 How to Automate the ECSF Command Line Administration Utility

You can set the ECSF Command Line Administration Utility to automatically execute a defined sequence of commands when you run the utility. To automate the ECSF Command Line Administration Utility in this way, you must configure the startup script to take inputs from a text file that you create.

The input file must contain one command per line. Any values that are not passed in with a command and are typically prompted for (for example, username and password) must occupy their own lines in the file. You must include a connect command since this is not passed in during the automated startup, and you must also include the exit command as the last command in the file in order to exit the ECSF Command Line Administration Utility. Example 26-1 illustrates a sample list of commands for an input file.

Example 26-1 Sample Input File

connect to database fusionhost123 1566 fh123
fusion
fusion
manage instance 1
set param "SES_ADMIN_SERVICE"="http://example.com:7777/search/api/admin/AdminService"
set param "SES_ADMIN_USERNAME" = "eqsys"
exit

You must know all of the object IDs when you create the input file. Using the input file, you cannot create a new object and then manage it in one automation.

To configure the startup script to automatically run the commands you defined in the input file, you must modify the startup script to include the AUTOMATE command in the STARTUP_PARAMS parameter.

To set the JPS Config file path:

  1. Open the runCmdLineAdmin.bat (Windows) or runCmdLineAdmin.sh (Linux) script, located in ORACLE_HOME/jdeveloper/ecsf, in a text editor.

  2. Set the STARTUP_PARAMS parameter to AUTOMATE and point to the location of input file. For example,

    STARTUP_PARAMS="AUTOMATE /scratch/commands.txt"

    where commands.txt is the input filename.

  3. Save.

    The output of the ECSF Command Line Administration Utility is displayed on the screen (or can be redirected), and errors are logged in the log file as usual. If the input file cannot be found, the ECSF Command Line Administration Utility runs in its usual mode and waits for the user to input a command through the prompt.

26.3 Setting Up Oracle Enterprise Manager and Discovering ECSF

While the ECSF Command Line Administration Utility can be used to quickly test and manage the searchable objects, Oracle Enterprise Manager Fusion Applications Control should be used to manage the life cycle of searchable objects in the production environment.

The ECSF runtime application needs to register its MBean to WebLogic's Domain Runtime MBean server, and the Oracle Enterprise Manager Fusion Applications Control needs to invoke all ECSF runtime operations through the MBean.

To access the Fusion Applications Control, you must install and configure Oracle Enterprise Manager (EM) to work with ECSF. You do not need to set up Oracle Enterprise Manager if you plan to use the ECSF Command Line Administration Utility to administer search.

To set up Oracle Enterprise Manager for ECSF, you must perform the following tasks:

  1. Register the ECSF runtime application MBean.

  2. Install Oracle Enterprise Manager.

  3. Discover ECSF in Oracle Enterprise Manager.

  4. Add users to the Administrators group.

Multiple developers can share one single Oracle Enterprise Manager application with the Fusion Applications Control.

26.3.1 How to Register the ECSF Runtime MBean to the Integrated WebLogic Server

The ECSF runtime application registers an MBean (oracle.ecsf.mbean.SearchRuntimeAdminMXBean) in WebLogic's Domain Runtime MBean server through a listener class (oracle.ecsf.mbean.RegisterMbeanContextListener). All ECSF runtime operations are invoked through the MBean.

To register the MBean:

  1. Add the MBean listener to web.xml.

  2. Create the application enterprise archive (EAR) file.

  3. Configure the data sources.

  4. Deploy the ECSF application.

  5. Start the Oracle WebLogic Server instance.

Registering the ECSF runtime MBean to the Integrated WebLogic Server makes the MBean available to remote clients such as Fusion Applications Control in Oracle Enterprise Manager.

26.3.1.1 Adding the MBean listener to web.xml

Add the MBean listener by modifying web.xml to include oracle.ecsf.mbean.RegisterMbeanContextListener.

To add the MBean listener:

  1. In the view-controller project in the Application Navigator, expand Web Content, then expand WEB-INF, and open web.xml.

  2. Add the following <listener> element in web.xml:

    <listener>

    <listener-class>oracle.ecsf.mbean.RegisterMbeanContextListener</listener-class>

    </listener>

  3. Save.

26.3.1.2 Creating the Application EAR File for Deployment

Create the application EAR file to be deployed. Right-click the application name and navigate to Deploy > ECSF application deployment profile > to EAR file. When the deployment is complete, you can find the generated EAR file in the JDeveloper log message window.

26.3.1.3 Configuring Data Sources in Oracle WebLogic Server

You must configure data sources in Oracle WebLogic Server for MBean integration. For information, see Oracle Fusion Middleware Configuring Server Environments for Oracle WebLogic Server.

Search for a data source with the JNDI name SearchDBDS. If any exist, make sure to look at the connection and validate that SearchDBDS is pointing to the correct database. If SearchDBDS is not listed, you must create a data source with jdbc/SearchDBDS as the JNDI name and with the connection information to the database against which the Fusion web application is running.

26.3.1.4 Deploying the ECSF Application Using the EAR File

Make the MBean available by deploying the EAR file you created to Integrated WebLogic Server. For information, see Oracle Fusion Middleware Configuring Server Environments for Oracle WebLogic Server.

Make sure that the EAR file is deployed and the application status is active in the final step.

26.3.1.5 Starting the Oracle WebLogic Server Instance

When the MBean is available after you deploy the enterprise archive (EAR) file, you can start the Oracle WebLogic Server instance by selecting Start Server Instance from the Run menu.

26.3.2 How to Install Oracle Enterprise Manager

You must install Oracle Enterprise Manager in order to access the Fusion Applications Control. Installing Enteprise Manager allows you to then enable it to discover the ECSF custom application target in Oracle WebLogic Server.

26.3.3 How to Discover ECSF in Oracle Enterprise Manager

In order to use Fusion Applications Control in Oracle Enterprise Manager, you must first enable Oracle Enterprise Manager to discover the ECSF custom application target in Oracle WebLogic Server. When you discover ECSF in Oracle Enterprise Manager, you enable Oracle Enterprise Manager to detect and display the Fusion Applications Control. You only need to discover the ECSF custom application target in Oracle WebLogic Server once. Once it is discovered, you can directly launch EM with the following URL:

http://your machine name:port/em

To discover ECSF in Oracle Enterprise Manager:

  1. Invoke the target discovery page in Oracle WebLogic Server with the following URL:

    http://your machine name:port/em/faces/as/discovery/addWeblogic

  2. Complete the following fields and click Submit:

    • Host (the name of the machine that hosts Oracle WebLogic Server)

    • Port (the Oracle WebLogic Server runtime port number, for example, 7101)

    • Username (for example, weblogic)

    • Password (for example, weblogic)


    Note:

    You can discover multiple Oracle WebLogic Servers by specifying a value for Farm Name Prefix (for example, Farm).


  3. Click Farm_DefaultDomain.

  4. At the Oracle Enterprise Manager login page (http://your machine name:port/em), log in with the following credentials:

    • Username: weblogic

    • Password: weblogic

  5. To start Fusion Applications Control, navigate to Farm_DefaultDomain > Fusion Middleware > Enterprise Crawl and Search Framework and click EcsfRuntimeApp.


Note:

You only need to discover the ECSF custom application target in Oracle WebLogic Server once. Once it is discovered, you can directly launch EM with the following URL:

http://your machine name:port/em


26.3.4 How to Add Users to the Administrators Group

In order to access the ECSF pages in Fusion Applications Control, users must be created and added to the Operator group and above on Oracle WebLogic Server. For information, see Oracle Fusion Middleware Securing Oracle WebLogic Server.

PK9yRNDPK BOEBPS/bs_messages.htm Defining and Using Message Dictionary Messages

7 Defining and Using Message Dictionary Messages

This chapter provides a detailed overview of Message Dictionary messages and discusses how to use them in Oracle Fusion Applications.

This chapter contains the following sections:

7.1 Introduction to Message Dictionary Messages

The Message Dictionary stores translatable Error and Warning messages for Oracle Fusion Applications. These types of messages provide information about business rule errors, such as missing or incorrect data, and how to resolve them, warn about the consequences of intended actions, inform about the status of an application, pages, or business objects, and indicate that processes and actions are performing or are completed.

All other messages can be stored in resource bundles, with the exception of strings and messages that need to be accessed by C or PL/SQL programs (resource bundles only can be accessed by Java programs). These exceptions can be stored in the Message Dictionary as Informational and UI String messages. Resource bundles also can be used to store job output or log file messages for Oracle Enterprise Scheduler (ESS) Java programs and test output messages for Java Diagnostic Testing Framework tests.

The Error, Warning, Information, and UI String message types are described in detail in Section 7.2, "Understanding Message Types."


Note:

Because the messages are stored in Application Object Library FND_MESSAGE_% tables, these types of messages are sometimes referred to as FND messages.


By using the messages in the Message Dictionary, you can define standard messages that you can use in all your applications, provide consistency for messages within and across all your applications, define flexible messages, and change or translate the text of your messages without regenerating or recompiling your application code.


Note:

Non-message strings, such as labels, report headings, and message fragments are typically stored in Oracle Application Development Framework (ADF) resource bundles. However, because Oracle ADF resource bundles only can be accessed by Java programs, you can store these types of strings in the Message Dictionary if C or PL/SQL programs need to access them.


Message Dictionary messages are composed of several message components, which enable you to author different messages for different audiences, such as the end user or help desk personnel, and for different conditions, such as when an action must be performed before the user can continue. For more information, see Section 7.3.4, "About Message Components."

Messages can be displayed to the UI and written to logs and incidents. Incidents are collections of information about system errors for which end users might require assistance from help desk personnel. An incident contains information about the state of the system at the time the problem occurred. Help desk personnel can use incidents to supply internal support personnel or Oracle support personnel with information about problems that need to be resolved.

You can set up a Message Dictionary message such that an incident and an associated log entry are created automatically. This is referred to as implicit incident creation.

For information on to how to generate incidents and log entries from Message Dictionary messages, see Section 7.5, "Understanding Incidents and Diagnostic Logs with Message Dictionary." For information about how incidents and log entries can be used, see the "Managing Oracle Fusion Applications Log Files and Diagnostic Tests" chapter and the "Introduction to Troubleshooting Using Incidents, Logs, QuickTrace, and Diagnostic Tests" chapter in the Oracle Fusion Applications Administrator's Guide.

Use the Manage Messages task in the application's Setup and Maintenance work area to create and maintain Message Dictionary messages. For more information, see the Oracle Fusion Applications Common Implementation Guide.

Oracle Fusion applications provide some common messages in the Message Dictionary with message names that begin with FND_CMN_. Do not modify or replace these messages.

7.2 Understanding Message Types

All messages must have a message type. The message type indicates which message components are applicable, determines whether implicit logging and incident creation occurs, and determines the logging level if the message is logged. For information about message components, see Section 7.3.4, "About Message Components." For information about logging and incident creation, see Section 7.5, "Understanding Incidents and Diagnostic Logs with Message Dictionary." For information about the standard log settings and about logging profile options see the "Default System Log Settings" section in the Oracle Fusion Applications Administrator's Guide.

The valid values for message types are fixed and therefore cannot be customized.

Error Messages

Use the Error message type for messages that alert the user to data inaccuracies when completing a field, submitting or saving a page, navigating from the page, or when an application or unknown failure occurs. An error message requires attention or correction before the user can continue with their task.

Warning Messages

Use the Warning message type for messages that inform users about an application condition or a situation that might require their decision before they can continue. Warning messages describe the reason for the warning and potential consequence of the selected or intended action by users. The warning requires the attention of users, and a standard question might be posed with the warning, or the warning can take the form of a statement.

Information Messages

The Information message type is intended for the following types of strings:

You can choose to use the Information message type in one of two ways:

UI String Messages

Use the UI String message type for non-error and non-warning strings that need to be stored in the Message Dictionary but are not complete messages, such as prompts, titles, or translated fragments. For example, "Upload Process Parameters." Note that UI String messages are processed exactly as Information messages.

7.3 Understanding Message Content

Messages must have unique message names. Although message numbers are not required, you should use them for error messages in order to make it easier for users to identify the precise error in logs, and to enable users to find more information about the error in various help sources, including those in different languages.

Translation Notes are not required, but can be used to store notes about context and use of the message. Translation notes can also be used to provide information to help translators understand how the message is used and thus provide a more accurate translation.

Different combinations of information are provided depending on the nature of the message and the intended audience, such as end user or help desk personnel. This is accomplished using message components.

Tokens are also an important part of messages. Tokens are the programmatic parts of message text that allow the substitution of other text or values into the message at run time. They are used as a way include variable information in the same message. In Oracle Fusion Applications, tokens are used for dates, numbers, and specific types of text.

7.3.1 About Message Names

Every message must have a unique name. You should include a unique prefix that makes it easier to find your custom messages and that helps to avoid name conflicts with non-custom messages. Names that begin with FND_CMN_ are reserved for Oracle Fusion Applications common messages.

7.3.2 About Message Numbers

A unique and persistent message number can be included with each message. The message range 10,000,000 to 10,999,999 has been allocated for customers' own messages.

When displayed, the number takes the format of (Application Shortname-Number). For example:

Descriptive flexfields do not support unit of measure enabled segments. (FND-2774)

If the message does not have a message number, the formatted number is not displayed.

7.3.3 About Translation Notes

A translation note (message context) is a descriptive note to developers, translators, and message customizers describing where and how the message is used. The note is not translated and cannot contain tokens. It is never displayed to end users or help desk personnel. The maximum size of this field is 4000 characters.

7.3.4 About Message Components

Message components enable you to define messages for different audiences and address additional information needs. All messages require a value for the Message Text component, the other components are optional.

Both help desk personnel and end users see the message text and cause components. For the other components, you can use the Message Mode profile option, which has a code of FND_MESSAGE_MODE, to configure whether the end user or help desk personnel (or both) see each type of component. For example, you can set the profile option to enable a particular user to see the Message Admin Detail component. You use the Manage Administrator Profile Values task in the Oracle Fusion Applications Setup and Maintenance work area to set the Message Mode profile option to Administrator or User at the Site, Product, and User levels.


Note:

Incidents contain all message components. For more information about incidents, see Section 7.5, "Understanding Incidents and Diagnostic Logs with Message Dictionary."


Message Text

Message text is required. This is a brief statement of the operation attempted and the problem that occurred as a result, or information that the user needs to know. The text is included in log and incident creation messages. The content in this field is customizable and the text can contain tokens. The maximum field size for messages stored in the Message Dictionary is 240 characters.

If the entire message, after tokens have been substituted, exceeds the 240 character limit, the message text is truncated. To allow room for expansion in other languages, the US version of any translated column should be no more than 70% of the maximum possible length. (For example, 240 character short text becomes 160 characters in US).


Caution:

Tokens are just values substituted into the message at runtime. Tokens must come from a translated source unless it is a number, seed data, technical information, or a name that is not translated. Extreme care must be taken with tokens when substituting translatable data. You must make sure that it makes sense at run-time

For more information, see Section 7.3.5, "About Tokens."


The text appears in bold at the top of the message window region. In addition, the message text is the only message component displayed in limited real estate UIs, such as pagers and phones. Therefore, the message text should be clear enough to be understood alone when used in this context.This is a required field for all message types.

Message User Detail

This is a more detailed explanation of the problem identified in the short message and its audience is the end user. This field includes the details that are appropriate and meaningful to the end user and should outline exactly what caused the error to occur. For example, in the case of an incident creation error message, this field can be used to provide the user with information about the type of error. The content in this field is customizable and the text can contain numerous tokens. The maximum field size is 4000 characters.

The text appears in normal letters just below the short message. This field is optional.

Message Admin Detail

Message Admin Detail text provides a detailed explanation of the problem identified in the short message. This information is never seen by the end user. This field is for technical details that are not meaningful to an end user. The content in this field is customizable and the text can contain numerous tokens. The maximum field size is 4000 characters.

Although this component is optional, it should be used for errors that require help desk processing, and should contain information to assist the help desk personnel to resolve the issue, such as the technical background.

Message Cause

The message cause text provides for the end user a concise explanation of why the error occurred. It lists reasons for the failure such as a prerequisite that is not met, incorrect inputs, an anticipated but incorrect action, and so on. The content in this field is customizable and the text can contain numerous tokens. The maximum field size is 4000 characters.

The word Cause (in bold) is prefixed automatically to the beginning of the cause text. This text appears below the user detail, if available. This component is optional and is only applicable for messages of type Error and Warning. The components Cause and User Action are mutually required, meaning if you enter one you must enter both.

Message User Action

This component is for messages that state the action that the user must perform in order to continue and complete the task. This is intended for and seen by the end user. The content in this field is customizable and the text can contain tokens. The maximum field size is 4000 characters.

The word Action (in bold) is prefixed automatically to the beginning of the action text. This text appears below the cause text. This component is optional and is only applicable for messages of type Error and Warning.

Message Admin Action

Message Admin Action messages state the action that must be performed in order to resolve the error condition. This should contain the information that the help desk personnel requires to resolve the error. The content in this component is customizable and the text can contain tokens. The maximum field size is 4000 characters.

The word Action: (in bold) is prefixed automatically to the beginning of the action text. This text appears below the cause text and is only applicable for messages of type Error and Warning. This component is only enabled if Cause and User Action are entered. If this is NULL and User Action information is available, then the User Action information is displayed.

7.3.5 About Tokens

Tokens are identified in the message text by their use of curly brackets and all uppercase letters. The token values are supplied at runtime by the code that raises the message. For example, the following token {MATURITY_DATE} is replaced by a date when the user receives the error message on their screen:

"Enter an effective date that is the same as or later than {MATURITY_DATE}".

Becomes:

"Enter an effective date that is the same as or later than 25-APR-2010".

7.4 About Grouping Messages by Category and Severity

You can group messages by category and by severity. These groups are used to define logging and incident policies. Otherwise, category and severity have no affect. Category and severity values do not appear in logging entries, incidents, or the UI.

7.5 Understanding Incidents and Diagnostic Logs with Message Dictionary

Incidents are collections of information about system errors for which the customer might require assistance from help desk personnel. An incident contains information about the state of the system at the time the problem occurred. Help desk personnel can monitor and respond to incidents and send them to Oracle if further assistance is necessary. For more information about how customers use incidents, see the "Managing Oracle Fusion Applications Log Files and Diagnostic Tests" chapter and the "Introduction to Troubleshooting Using Incidents, Logs, QuickTrace, and Diagnostic Tests" appendix in the Oracle Fusion Applications Administrator's Guide.

Implicit incident creation and logging occurs when the Message Dictionary message is retrieved in PL/SQL and C code, or when it is formatted in Java code, and the message has the following settings:


Note:

Implicit incident creation occurs when logging is enabled. Implicit logging only occurs if the SEVERE log level is enabled.


Use the Message Dictionary APIs to retrieve a Message Dictionary message. The PL/SQL methods are in the FND_MESSAGE package and the Java methods are in the messageService package. For C code, use the methods in the fddutl package.

For more information about the Message Dictionary APIs, see the "Message Dictionary" chapter in the Oracle E-Business Suite Developer's Guide. You can download this soft-copy documentation as a PDF file from the Oracle Technology Network at http://www.oracle.com/technetwork/indexes/documentation/

For Java code, implicit incident creation and logging occurs for qualifying messages when the appropriate formatting methods are called from the MessageServiceAMImpl class and the MessageServiceAM interface, such as the getUserXML(), formatMap(), formatUserTextMap(), or formatAdminTextMap() methods. See the MessageServiceAM and MessageServiceImpl Javadoc for information about which methods to call for implicit logging. Implicit incident creation and logging also occur when exceptions are created using the ApplcoreException classes.

When implicit logging and incident creation occurs, additional information is appended to the message, as follows:

To learn more about the information that is included with incidents and associated log entries, see the "How the Diagnostic Framework Works" section in the Oracle Fusion Middleware Administrator's Guide.

7.6 Using Message Dictionary Messages in Oracle ADF Java Code

You can use messages in the Message Dictionary in Java code to raise exceptions using Oracle Fusion Middleware Extensions for Applications exception classes. You can also retrieve the message text programmatically.

7.6.1 How to Raise Exceptions Using Oracle Fusion Middleware Extensions for Applications Exception Classes

Exceptions from messages in the Message Dictionary should be raised using wrapper classes that are provided in the oracle.apps.fnd.applcore.message package. Wrappers that are provided correspond to the most commonly used Oracle ADF exception classes. See Table 7-1.

Table 7-1 Oracle ADF Exception Classes vs. Message Dictionary Classes

Exception ClassMessage Dictionary Class

JboException

oracle.apps.fnd.applcore.messages.ApplcoreException

RowValException

oracle.apps.fnd.applcore.messages.ApplcoreRowValException

AttrValException

oracle.apps.fnd.applcore.messages.ApplcoreAttrValException


In each of these classes, the message name is expected to be passed in the format: APP_NAME:::MESSAGE_NAME (application short name, followed by exactly 3 colons, followed by the message name). For example: "FND:::FND_CMN_POSITIVE".

Message tokens passed to most Message Dictionary Java APIs are expected to be supplied as Map<String, Object> or as an array of alternating String/Object pairs. With either style, the String is the name of the message token and the following Object is an object representing the value of that token. The type of the Object is expected to match the type of the token as shown in Table 7-2.

Table 7-2 Message Tokens and Data Types

Token TypeToken Value Object Type

TEXT

java.lang.String

NUMBER

java.math.BigDecimal

DATE

java.sql.Timestamp


Exceptions that are raised using JboException or one of its subclasses with a severity level of SEVERITY_ERROR, which is the default, or any java.lang.RuntimeException, are treated as system errors, and the following occurs:

  • The error message is replaced with a generic message, such as "An application error occurred. Your help desk was informed"

  • An incident is created for the system error

  • A stack trace is written to the log file for the system error

If you do not want the JboException to be treated as a system error, do one of the following:

  • Convert the exception type to ApplcoreException

  • Set the severity level to other than SEVERITY_ERROR, such as SEVERITY_RECOVERABLE_ERROR.


Tip:

If you need to see the original error message, you can run the application with the -DAFERROR_MODE=debug parameter, as described in Section 7.9, "Diagnosing Generic System Error Messages."


You should use the wrappers wherever possible. However, it is possible to also use native Oracle ADF exceptions directly if there isn't a wrapper that exactly suits your needs. If you do this, you must specify the FndMapResourceBundle resource bundle class, and format tokens correctly.

Example 7-1 shows sample code that raises an ApplcoreException exception. Example 7-2 shows an example of raising ApplcoreRowValException exception. Use of the ApplcoreAttrValException exception is shown in Example 7-3. Example 7-4 illustrates how to throw a native JBOException.

To display more than one application error message, such as a series of validation error messages, bundle the exceptions and throw the bundled exceptions, as shown in Example 7-5. The exceptions in the bundle must be only application error exceptions, such as ApplcoreException, JboException with SEVERITY_RECOVERABLE_ERROR, or ValidationException. If you include any system error exceptions in the bundle, such as NullPointerException, the bundle is processed as a system error. For example, if you include a RuntimeException exception in the bundle, you cannot display the bundled exception error messages in a popup dialog, because it will be processed as a system error.

Example 7-1 ApplcoreException

import oracle.apps.fnd.applcore.messages.ApplcoreException;

// Construct and populate HashMap with token values
Map<String, Object> tokens = new HashMap<String, Object>();
tokens.put("TEXT_TOKEN", "text token value");
tokens.put("NUMBER_TOKEN", new BigDecimal(10));
Calendar cal = Calendar.getInstance();
cal.set(1999, Calendar.DECEMBER, 31, 0, 0, 0);
tokens.put("DATE_TOKEN", new Timestamp(cal.getTimeInMillis()));
 
throw new ApplcoreException("MYAPP:::MY_MESSAGE_NAME", tokens);

Example 7-2 ApplcoreRowValException

import oracle.apps.fnd.applcore.messages.ApplcoreRowValException;
 
// Construct and populate HashMap with token values
Map<String, Object> tokens = new HashMap<String, Object>();
tokens.put("TEXT_TOKEN", "text token value");
tokens.put("NUMBER_TOKEN", new BigDecimal(10));
Calendar cal = Calendar.getInstance();
cal.set(1999, Calendar.DECEMBER, 31, 0, 0, 0);
tokens.put("DATE_TOKEN", new Timestamp(cal.getTimeInMillis()));
 
Key key = new Key(new Object[] { "Primary Key" });
 
ApplcoreRowValException ex = new ApplcoreRowValException("MYAPP:::MY_MESSAGE_NAME", "MyEODefName",key, tokens);

Example 7-3 ApplcoreAttrValException

import oracle.apps.fnd.applcore.messages.ApplcoreAttrValException;
 
// Construct and populate HashMap with token values
Map<String, Object> tokens = new HashMap<String, Object>();
tokens.put("TEXT_TOKEN", "text token value");
tokens.put("NUMBER_TOKEN", new BigDecimal(10));
Calendar cal = Calendar.getInstance();
cal.set(1999, Calendar.DECEMBER, 31, 0, 0, 0);
tokens.put("DATE_TOKEN", new Timestamp(cal.getTimeInMillis()));
 
ApplcoreAttrValException ex = new ApplcoreAttrValException("MYAPP:::MY_MESSAGE_NAME",
                                "MyEODefName","AttrName", "AttrValue", tokens);

Example 7-4 Native JBOException

import oracle.apps.fnd.applcore.messages.ApplcoreException;

// Construct and populate HashMap with token values
Map<String, Object> tokens = new HashMap<String, Object>();
tokens.put("TEXT_TOKEN", "text token value");
tokens.put("NUMBER_TOKEN", new BigDecimal(10));
Calendar cal = Calendar.getInstance();
cal.set(1999, Calendar.DECEMBER, 31, 0, 0, 0);
tokens.put("DATE_TOKEN", new Timestamp(cal.getTimeInMillis()));

JboException ex = new JboException(FndMessagesUtil.getFndMapResourceBundleDef(),
                                   "MYAPP:::MY_MESSAGE_NAME", null);
ex.setErrorParametersMap(tokens);
throw ex;

Example 7-5 Throwing Bundled Exceptions

ApplcoreException error1 =
     new ApplcoreException("PON:::PON_NEG_REQ_TOTAL_WEIGHT_ERROR");
 ApplcoreException error2 =
     new ApplcoreException("PON:::PON_KNOCKOUT_CRITERIA_ERROR");
 
 ApplcoreException[] details = {error1, error2};
 ValidationException errorBundle = new ValidationException("");
 errorBundle.setExceptions(details);
 throw errorBundle;

7.6.2 How to Retrieve Message Text Programmatically

You can use static methods in the oracle.apps.fnd.applcore.messages.Message class to retrieve translated, token substituted message text without raising exceptions. APIs are provided to retrieve the fully formatted text of the user message, the administrator message, or to retrieve the parts of the message (short message, cause, action, and so on) individually, as shown in Example 7-6.

Example 7-6 Retrieving Messages

// Construct and populate HashMap with token values
Map<String, Object> tokens = new HashMap<String, Object>();
tokens.put("TEXT_TOKEN", "text token value");
tokens.put("NUMBER_TOKEN", new BigDecimal(10));
Calendar cal = Calendar.getInstance();
cal.set(1999, Calendar.DECEMBER, 31, 0, 0, 0);
tokens.put("DATE_TOKEN", new Timestamp(cal.getTimeInMillis()));
 
// Get the token substituted message short text. 
String shortText = Message.getShortText("MYAPP", "MY_MESSAGE", tokens);
 
// Get the token substituted full user message, in plain text format. 
String userText = Message.getUserText("MYAPP", "MY_MESSAGE", tokens);
 
// Get the token substituted full user message, in HTML format. 
String userHTML = Message.getUserHTML("MYAPP", "MY_MESSAGE", tokens);
 
// Get the token substituted full admin message, in plain text format. 
String adminText = Message.getAdminText("MYAPP", "MY_MESSAGE", tokens);
 
// Get the token substituted full admin message, in HTML format. 
String adminHTML = Message.getAdminHTML("MYAPP", "MY_MESSAGE", tokens);

7.7 Associating Message Dictionary Messages with Oracle ADF Validation Rules

The easiest way to create and manage validation rules is through declarative validation rules. Declarative validation rules are defined using the overview editor for the entity object, and once created, are stored in the entity object's XML file. These are known as declarative validation rules on entity objects.

For information about defining validation rules on entity objects, see the "Defining Validation and Business Rules Declaratively" chapter in the Oracle Fusion Middleware Fusion Developer's Guide for Oracle Application Development Framework (Oracle Fusion Applications Edition).

Oracle ADF provides built-in declarative validation rules that satisfy many of your needs. You can also base validation on a Groovy expression, as described in Section 6.2, "Using Groovy Scripting Language".

When you add a validation rule, you supply an appropriate error message. You can also define how validation is triggered and set the severity level.

These messages can contain named message tokens for retrieving and displaying context sensitive values.


Tip:

When raising exceptions with the ADF Business Components validation rules, the tokens must be formatted as {TOKEN_NAME} and not (TOKEN_NAME).


7.7.1 How to Associate Error Messages with Oracle ADF Entity Object Validation Rules

To associate an error message with your validation rule:

  1. Go to the Failure Handling tab of your declarative validation rule when you have finished defining your rule. In the Validation Failure Severity field, Select Error.

  2. Click Select Message to open the Select Text Resource dialog. Choose Application Messages from the Resource Picker dropdown list.

  3. Use the Search area to filter your search results. For example, enter fnd_view in the search text area to filter your results to messages whose key begins with FND_VIEW.


    Note:

    You can search for messages only by the message key. All other types of searches have been disabled. Also notice from the results that message keys are prepended with the application short name.


  4. Select the required error message from the list of results. The Select Text Resource dialog closes and the selected error message displays in the Failure Message Text area on the Failure Handling tab.


    Note:

    If the selected message contains tokens, a row for each token is added into the Error Message Expressions table.


  5. If your message contains tokens, bind them to Groovy expressions to retrieve context sensitive values. Groovy script is a Java-like scripting language. For more information about Groovy script, see Section 6.2, "Using Groovy Scripting Language".

    A validation rule's error message can contain embedded expressions that are resolved by the server at runtime. To access this feature, simply enter a named token delimited by curly braces (for example, {TOKEN_NAME} or {ERRORPARAM}) in the error message text where you want the result of the Groovy expression to appear.

    The Token Message Expressions table at the bottom of the dialog displays a row that allows you to enter a Groovy expression for the token. Figure 7-2 shows the failure message for a validation rule in the PaymentOptionEO entity object that contains message tokens.

    Figure 7-2 Using Message Tokens in a Failure Message

    Using Message Tokens in a Failure Message

Declarative validation is different from programmatic validation, which is stored in an entity object's Java file. For more information about programmatic validation, see the "Implementing Validation and Business Rules Programmatically" chapter in the Oracle Fusion Middleware Fusion Developer's Guide for Oracle Application Development Framework (Oracle Fusion Applications Edition).

7.8 Raising Error Messages Programmatically in PL/SQL

Because they make calls to the database, both PL/SQL and C code require that the message is stored in the Message Dictionary. PL/SQL and C code cannot reference Java-based resource bundles. You can use PL/SQL to:

7.8.1 How to Raise Exceptions Programmatically in PL/SQL

There are three packages that you can use to handle errors in PL/SQL using messages in the Message Dictionary:

  • FND_MESSAGE: This package includes basic APIs to set messages on the error stack, set tokens, retrieve token substituted message text, and so on.

  • APP_EXCEPTION: This package includes utilities to raise SQL exceptions with messages in the Message Dictionary as the exception text.

  • FND_MSG_PUB: This package includes utilities to set messages on the error stack. In Oracle Fusion Applications, the error stack also exists natively in the FND_MESSAGE package; this package is primarily used for backward compatibility with existing code. PL/SQL code that in EBS was primarily called from Framework usually uses this method.

For more information about these packages, see the package headers.

7.8.2 How to Raise Errors in PL/SQL

The FND_MESSAGE PL/SQL package allows you to set one message and its tokens, as shown in Example 7-7. It also allows you to set multiple messages in the stack by explicitly pushing the current message onto the stack, as shown in Example 7-8. When you need to retrieve the message from the stack, an explicit pop() is required, as shown in Example 7-9.

Example 7-7 Getting Message and its Tokens

-- setting INVALID_USER as the current message
fnd_message.set.name('FND', 'INVALID_USER');
-- setting token value for NAME
fnd_message.set_token('NAME', '<USER>');
..........
-- get the current translated and token substituted message
-- then clear the message
msg := fnd_message.get;

Example 7-8 Receiving a Message Record and Clearing Message

-- setting INVALID_USER as the current message
fnd_message.set_name('FND', 'INVALID_USER');
-- setting token value for NAME
fnd_message.set_token('NAME', 'TESTUSER');
.......
-- receive a message record which contains everything about the
-- current message. The record contains message number, message category
-- message severity and translated and token substituted message text,
-- translated and token subsituted user message, user action, ...
-- Getting message record for current message will NOT clear the message
msg_rec := fnd_message.get_message_record;
-- clear the message
fnd_message.clear;

Example 7-9 Retrieving message from the Stack

-- setting INVALID_USER as the current message
fnd_message.set_name('FND', 'INVALID_USER');
-- setting value for token NAME for INVALID_USER message
fnd_message.set_token('NAME', 'TESTUSER');
-- saving the current message onto stack
fnd_message.push;
-- setting LOGIN_FAILED as the current message
fnd_message.set_name('FND', 'LOGIN_FAILED');
-- saving the current message onto stack
fnd_message.push;
.......
-- poping one message out of stack and set it as the current message
fnd_message.pop;
-- get the translated and token subsituted LOGIN_FAILED message
-- then clear the current message
msg := fnd_message.get;
-- poping one message out of stack and set it as the current message
fnd_message.pop;
-- get the translated and token subsituted INVALID_USER message
-- then clear the message
msg := fnd_message.get;

7.8.3 How to Retrieve Errors when PL/SQL is Called from Java

You can use the OAExceptionUtil.CheckErrors() API to check for error messages after calling PL/SQL from Java. The CheckErrors() API looks for errors on both the new FND_MESSAGE and FND_MSG_PUB stacks, raises a bundled exception for each error found on both stacks, and then clears both PL/SQL error stacks.

Where the call to OAExceptionUtil.CheckErrors() depends on which style of error handling your PL/SQL code uses:

  • If your PL/SQL code uses FND_MESSAGE with FND_MSG_PUB, then errors will be left on the PL/SQL error stack without raising any exceptions. The call to OAExceptionUtil should go immediately after the PL/SQL call.

  • If your PL/SQL code uses APP_EXCEPTION.RAISE_EXCEPTION, or FND_MESSAGE.RAISE, then errors will cause SQL exceptions to be raised. The call to OAExceptionUtil.CheckErrors() should be in a SQLException catch block.

  • If you do not know what style of error handling your PL/SQL code uses, or there could be a mixture of both, then you should include calls to OAExceptionUtils.CheckError() in both places, as shown in Example 7-10.

    Example 7-10 Calls to OAExceptionUtils.CheckError() — Unknown Error Handling Style

    import oracle.apps.fnd.applcore.common.OAExceptionUtils;
      ...
    
      try
      {
        // Create and execute a plsql statement
        String mystmt = "BEGIN MY_PLSQL_PACKAGE.MY_PROCEDURE(); END;";
    
        DBTransaction txn = getDBTransaction();
        CallableStatement mystmt = txn.createCallableStatement(mystmt, 1);
    
        myStmt.executeUpdate();
    
        // Check for errors left on message stack without raising exception
        OAExceptionUtils.checkErrors(txn);
      }
      catch(SQLException sqlE)
      {
        // Check for FND Messages exception.
        // FND Messages exception always has error code -20001.
        if (sqlE.getErrorCode() == 20001)
        {
          OAExceptionUtils.checkErrors(txn);
        }
        else
          // Not a FND Messages exception, re-raise.
          throw sqlE;
      }
    

7.9 Diagnosing Generic System Error Messages

If you see an error message similar to one the following messages, it is because a system error was raised and the original error message was replaced with a generic message:

An application error occured. Your help desk was informed.

An application error occurred. See the incident log for more information.

When you receive these types of errors, you can look at the log file entry to find the original error message.


Note:

When generic errors are raised, you will see oracle.apps.fnd.applcore.messages.ExceptionHandlerUtil class information at the top of the call stack. This is the code that is replaced the unhandled exception with the generic error and should not be mistaken for the original error from the Message Dictionary.


You can also set one of the following debug options to allow you to see the error more directly, without having to view the log file entry:

For information about finding the cause of an error and its corrective action and for information about viewing and managing log files, see the "Managing Log Files and Diagnostic Data" chapter and the "Introduction to Troubleshooting Using Incidents, Logs, QuickTrace, and Diagnostic Tests" appendix in the Oracle Fusion Middleware Administrator's Guide.

7.10 Formatting Message Dictionary Messages for Display in Oracle ADF Applications

When raising an exception or attribute validation error by retrieving a message from the Message Dictionary using a resource bundle interface, the exception message returns in XML format.

You can convert XML formatted messages to HTML or plain text for display in Oracle ADF applications, as shown in Figure 7-3.

Figure 7-3 Error Message Example

Error Message Example

This can be done in one of two ways:

7.10.1 How to Programmatically Convert XML Messages

When directly handling Oracle Fusion Applications resource bundle exceptions in Java code, you can convert XML messages to HTML or plain text using utility APIs. The utility APIs are found in oracle.apps.fnd.applcore.messages.model.util.Util.

Sample code is shown in Example 7-11.

Example 7-11 Converting XML Messages to HTML or Plain Text

Exception ex =
      new ApplcoreException("FND:::MY_TEST_MESSAGE");
 
    // Retrieve the HTML short message
    String htmlShort = Util.formatHTMLMessage(ex);
 
    // Retrieve the HTML message details.
    String htmlDetails = (Util.formatHTMLDetailMessage(ex)).getHTMLText();
 
    // Retrieve the plain text messge details
    String textDetails = (Util.formatHTMLDetailMessage(ex)).getText();
 
     // Retrieve the full plain text message
    String textMsg = Util.formatTextMessage(ex);

7.10.2 How to Convert XML Messages by Configuring the Error Format Handler

You can convert XML messages to HTML or plain text by configuring the error format handler in the DataBindings.cpx file.

To convert XML messages to HTML by configuring the error format handler:

  1. Under the user interface project, open the DataBindings.cpx file.


    Tip:

    JDeveloper names the user interface project ViewController by default.


  2. In the Property Inspector, set the ErrorHandlerClass field to the value shown in Example 7-12 and Figure 7-4.

    Example 7-12 The Value of the ErrorHandlerClass Field

    oracle.apps.fnd.applcore.messages.MessageFormatHandler
    

    Figure 7-4 Setting the Value of the ErrorHandlerClass Field in the Property Inspector

    Property Inspector - Setting the ErrorHandlerClass

7.11 Integrating Messages Task Flows into Oracle Fusion Functional Setup Manager

Every Oracle Fusion application registers task flows with a product called Oracle Fusion Functional Setup Manager. These task flows are available from the application's Setup and Maintenance work area and enable customers and implementers to set up and configure business processes and products. For more information, see the Oracle Fusion Applications Common Implementation Guide.

Function Security controls your privileges to a specific task flow, and users who do not have the required privilege cannot view the task flow. For more information about how to implement function security privileges and roles, see Chapter 49, "Implementing Function Security."

Table 7-3 lists the task flows and their parameters.

Table 7-3 Messages Task Flows and Parameters

Task Flow NameTask Flow XMLParameters PassedBehaviorComments

Manage Messages

/WEB-INF/oracle/apps/fnd/applcore/messages/ui/flow/ManageMessagesTF.xml#ManageMessagesTF

mode='search' [moduleType] [moduleKey]

mode='edit' messageName applicationId [pageTitle]

Search mode launches the search page, with optional parameters to restrict to a particular module.

Edit mode launches the edit page for a particular message. The messageName and applicationId parameters are mandatory as they specify the message to edit.

NA.


PK{"PK BOEBPS/bs_gs.htmp\ Getting Started with Business Services

4 Getting Started with Business Services

This chapter provides an overview of ADF Business Components, validators, list of values (LOVs), and data types. It also discusses migrating PL/SQL to Java, batch processing, and extensibility and reusability. Also included is an overview of services.

This chapter includes the following sections:

4.1 Introduction to Implementing Business Logic

The core business logic is implemented in one or more business components that are provided in ADF Business Components. Entity objects, view objects, and application modules are the key business components that are discussed in this section.

4.1.1 About Entity Objects

An entity object represents a row in a database table. It encapsulates the business logic and database storage details of your business entities. It simplifies modifying its data by handling Data Manipulation Language (DML) operations automatically. There are two general classifications of business logic that are placed on the entity object:

  • Standard business and validation logic

  • Specialized business functions

4.1.1.1 Standard Business and Validation Logic

An entity has a life cycle; customized business rules can be added to an entity object at various places to be executed in different phases of its life cycle.

The entity object should contain all logic that is invoked during entity object life cycle events. This comprises logic for create, initDefaults, all validation (including attribute validation, entity validation and cross entity validation), DML, and so on. In other words, the entity object encapsulates the rules that ensure the entity object is created and remains in a valid state.


Note:

All logic existing in one entity object Java class not required. It's valid for the entity object to call utility classes for code modularity purposes.


If a business rule can be defined declaratively, you should always use the declarative approach. For example, if an attribute has a constant default value, then you should specify it in the Entity Object wizard rather than coding it. You should also first consider using declarative validators for your validation logic, which is explained in Section 4.2, "Understanding Validators".

The life cycle of an entity object begins with being created as a new entity object or fetched from the database as an unmodified entity object. The entity object can then be modified or removed. Only new, modified, or removed entity objects are in the transaction pending change list and are posted to the database when the transaction is committed.

For more information about the key events in the entity objects life cycle and where you can add entity object business logic programmatically, see the Introduction to Programmatic Business Rules section in the "Implementing Validation and Business Rules Programmatically" chapter in the Oracle Fusion Middleware Fusion Developer's Guide for Oracle Application Development Framework (Oracle Fusion Applications Edition).

4.1.1.2 Specialized Business Functions

The entity object is the core business object that is used to encapsulate task-level business logic. It is shared by both user interfaces (UIs) and services. Core business functions and tasks should be placed on the entity object as custom methods for maximum reusability. Corresponding methods on the view object and application modules should delegate to these functions on the entity object. Examples of business functions are approvePurchaseOrder and hireApplicant. Internally, these custom methods can be implemented using Java or may invoke legacy PL/SQL.

Custom business functions that are not invoked during entity object life cycle events should be placed in either the entity object or model application module. Generally these are the custom business functions that are required by the UI and Service application module.

4.1.2 About View Objects

A view object represents a SQL query and also collaborates with entity objects to consistently validate and save the changes when end users modify data in the UI. The relationships between view objects are captured using view links. View objects are used to present your business data for the specific needs of a given application scenario or task, and generally don't contain business logic.

However, view objects may have additional attributes that do not exist in the underlying entity objects, which are used to store some calculated values. Usually you define different view objects for supporting services and UIs:

  • Service view object: Represents an outfacing business object and contains only the attributes in the business object. For example, it contains the foreign key ID attribute such as SupplierID, but it does not contain foreign key reference attributes such as SupplierName.

  • UI view object: This view object may contain addition UI flags and calculated attributes that are used for a particular UI. In addition, the UI view object may join to other tables for additional foreign key attribute references.


Note:

A service view object must be versioned to support service versioning. However, there is no versioning requirement for an internal UI view object.


4.1.3 About Application Modules

An application module encapsulates an active data model and the business functions for a logical unit of work related to an end-user task. The active data model is defined as a collection of view object instances.

The methods on the application module are used to encapsulate task-level business logic, although these methods should delegate to the methods on entity objects whenever possible. If you have an option to put your business logic either on an entity object or an application module, then you should always put it on the entity object. This is because the entity object owns the business object and also for better reusability. The task-level validations that span multiple related parent-child entities, such as purchase order header and lines, should be put on the parent entity. It is also important that the entity object should not trust the incoming data and always perform all validations.

Application modules can be used to support UIs or define services. Usually you want to have two separate application modules for the two different purposes because:

  • UI application modules may contain additional view objects and context values that are only required for a particular UI, but not needed by a business service.

  • Application modules that define public services are versioned, but internal UI application modules are not.

UI application modules and service application modules share the underlying entity objects as shown in Figure 4-1. A UI application module can also call a service.

Figure 4-1 UI Application Module and Service Application Module

UI App Module and Service App Module

4.2 Understanding Validators

In Fusion, you should use validators to implement the validation logic. Validators are added declaratively, which provides visibility and personalizability to customers as well as the benefit of being easy to use and maintain. Validation view objects can be attached to entity objects declaratively as view accessors, which can then be used in declarative validators.

For more information about how to use validators and Groovy (a Java-like scripting language), see Chapter 6, "Defining Defaulting and Derivation Logic."

4.3 Understanding List of Values (LOV)

List of Values (LOV) is the mechanism to specify a list of valid values for an attribute in a view object. There are basically two parts involved when a LOV is defined: the base object and the LOV object. The base object is a view object, which contains the attribute whose list of valid values need to be defined, such as a PurchaseOrder view object containing a BuyerId attribute. The LOV object is a normal view object that contains the list of valid values, such as a Buyer view object containing all the valid buyers. You should use the view object design time wizard to add a List Value on the BuyerId attribute to associate with the Buyer view object.

In Fusion, the LOV metadata is defined on the server using ADF Business Components, and this drives and defaults the UI controls to automatically render the LOV bound items accordingly when you define a page, such as LOV and poplist controls.

It's important to define the LOV and entity validators to share the same view object instance to avoid redundant database round-trips for validation. To achieve this, the LOV view object should be added as a view accessor in the entity object, and the view accessor should be used to define entity level validators. The same view accessor is available at the view object level and should be used to define the LOV. When the user picks up a row from LOV on the UI, the row is placed on the LOV view object cache. The entity object validation then hits the cache instead of going against the database. A LOV/validation view object can also be defined as a global data source that is shared among all the users.

For more information, see the "Sharing Application Module View Instances" chapter, in the Oracle Fusion Middleware Fusion Developer's Guide for Oracle Application Development Framework (Oracle Fusion Applications Edition).

4.4 Understanding Batch Processing

Depending on the use case, different approaches should be considered to achieve the best performance.

For the use case of complicated bulk processing, such as very high volume or multiple step processing, then a combination of multiple techniques needs to be considered. For example, ADF Business Components, C, PL/SQL, SOA, Oracle Enterprise Scheduler (ESS), and so on.

For the other use cases, such as integration with third- parties or data migration, if the data volume is low to medium, then ADF Business Components service should be used. Internally, a combination of interface table and PL/SQL can be used to handle large amount of data, complicated processing, and validation logic. The inbound data is loaded into an interface table through a service and then the PL/SQL API is executed to process the data


Note:

You should still provide services for all objects, and double code the high performance alternatives when necessary.


4.5 Understanding Extensibility and Reusability

Fusion web applications are extensible applications, which can be tailored to fit the business practices specific to a customer, locale or an industry. Adaptation through Business Editor enables you to extend Oracle applications declaratively, which satisfies most of the extensibility requirements. You can also use the programmatic extensibility feature to address additional use cases.

4.6 Understanding Services

A service is a set of operations defined by an interface that can be used by other components. In Fusion, applications use both ADF Business Components services and SOA services. ADF Business Components services should be created to manage business objects and SOA services are for orchestration and business processes.

In Fusion, you make your data and business logic available via UIs and services. For more information about services, see Chapter 5, "Developing Services."

4.7 Using the Declarative Approach

When building your model objects, you should use the declarative approach whenever possible. For example, when defining your view objects, use declarative SQL mode whenever possible, base your view objects on entity objects, and utilize view criteria.

4.7.1 How to Define View Objects Using the Declarative Approach

When you define your view objects, use declarative SQL mode wherever possible. The next option is to use normal SQL mode.

When building your view objects, use declarative SQL mode wherever possible. Reasons for not using declarative SQL include:

  • You have a complicated query and the WHERE clause cannot be implemented using view criteria.

  • Your query includes derived attributes that cannot be implemented as calculated attributes based on a SQL expression.

If you are unable to use declarative SQL mode, you should try and use normal SQL mode, which gives you full control over the WHERE clause. Only use expert mode if other modes do not work. However, you should still base the view object on an entity object when the query supports it.

Non-expert mode view objects are metadata based and more declarative instead of SQL based. The declarative approach gives you benefits such as:

  • Increased development productivity:

    • Proven experience from PeopleSoft and Siebel.

    • Removes the requirement for you to tune each view object.

  • Easier to perform dependency and impact analysis.

  • Can be extended more robustly.

Declarative SQL mode is recommended because it is an even more declarative approach to defining the view object than normal mode.

  • The runtime query optimization feature is enabled only when you use declarative SQL mode. ADF Business Components makes runtime changes to the SQL based on usage such as column pruning to improve performance.

  • Declarative SQL optimization means you can consider creating view objects that can be reused in multiple UIs without impacting runtime performance.

For more information about how to set the SQL mode, see the Working with View Objects in Declarative SQL Mode section of the "Defining SQL Queries Using View Objects" chapter in the Oracle Fusion Middleware Fusion Developer's Guide for Oracle Application Development Framework (Oracle Fusion Applications Edition).

4.7.1.1 Using Entity Object Based View Objects

All view objects (including read-only view objects) should be based on entity objects unless:

  • Entity object based view objects are not supported for the SQL statement you are using, for example:

    • Union

    • Select Distinct

    • Group By

  • Your data doesn't come from the database. For example, the data comes from external files.

Even if you have to use expert mode view object, you should still base your view object on top of entity objects because:

  • The attributes from the entity object are still declaratively defined so that you can partially benefit from the declarative approach.

  • Multiple view objects based on the same entity object can automatically see updates made by any one of them.

  • Updated reference information is reflected when foreign key attribute values are changed.

  • Metadata, (UI hints, associations, and other attributes), are automatically propagated up to the view objects from entity objects.

  • New row management, such as view link consistency, only works with an entity object-based view object.

  • findByKey doesn't work for view objects with no entity usage unless you turn on the key management at the view object level (and this will add significant resources and CPU time). The findByKey method is a frequently invoked by any operation that involves setting the current row, such as clicking a row on an ADF Faces rich client table:

    • findByKey does not find the matching view row in the view object cache if the key management is not enabled.

    • findByKey adds the row fetched from the database into view object cache even if the view object already has the same row in cache if the key management is not enabled.

  • Updatable view objects must be based on entity objects so that view objects can coordinate with the underlying entity objects to perform DML.

4.7.1.2 Utilizing View Criteria

Instead of directly setting the WHERE clause, use declarative named view criteria whenever possible. Named criteria can be re-used in the UI and in the service interface. Also, it supports customization better and is required for declarative SQL mode.

In parallel, always use named bind parameters. Define the named bind parameters during design time if possible. Otherwise, add the named bind parameters programmatically. Named bind parameters are much easier to understand and manage than the indexed bind parameters so therefore, the code is easier to develop and maintain. If the same bind parameter appear multiple times in the WHERE clause, you only need to bind it once.

PK]]u\p\PK BOEBPS/sec_portlets.htm8ǀ Securing End-to-End Portlet Applications

51 Securing End-to-End Portlet Applications

This chapter describes how to authenticate and authorize portlet services, as well as configure key and credential stores. The process of securing portlet services is similar to that of securing web services.

51.1 Introduction to Securing End-to-End Portlet Applications

In Oracle Fusion Applications, portlets are WSRP portlets, therefore, web services. Oracle Web Services Manager (WSM) policies secure portlets, in the same way that they secure ordinary web services.

Oracle Web Services Manager implements web service security, and allows for run time enforcement and declarative policy attachment within Oracle Fusion Middleware.

Oracle Fusion applications make use of an Oracle WSM feature called global policy attachment (GPA). In GPA, policies are not attached locally, but specified at a global level. At runtime, components inherit the global policy and Oracle WSM enforces it.

For each portlet, these four ports require Oracle WSM policies:

Only the WSRP_v2_Markup_Service markup port requires an authentication policy. By default, no policy should be locally attached to the markup port; this port will inherit the policy from GPA.

However, if the WSRP_v2_Markup_Service port has unique requirements not fulfilled by GPA, then a locally attached policy will be necessary. Additionally, if the locally attached policy specifies message protection or SSL, the necessary key store setup must be in place.

The three non-markup ports are anonymous and therefore you will need to locally attach a "no behavior" policy (defined by oracle/no_authentication_service_policy) in order to override GPA.

The requirements for the client counterparts for each of these ports is exactly the same. Clients of the WSRP_v2_Markup_Service port inherit GPA, and clients of the three non-markup ports propagate an anonymous token defined by the oracle/no_authentication_client_policy policy.

Table 51-1 summarizes the policies attached to the portlet service and the client.

Table 51-1 Recommended Oracle Web Services Manager Policies for Oracle Fusion Portlets

PortService Side PolicyClient Side Policy

WSRP_v2_Markup_Service

No local policy. Inherits from GPA, which by default is oracle/wss_saml_or_username_token_service_policy.

No local policy. Inherits from GPA, which by default is oracle/wss_saml_or_username_token_client_policy.

WSRP_v2_PortletManagement_Service

Local anonymous policy:

oracle/no_authentication_service_policy

Local anonymous policy:

oracle/no_authentication_client_policy

WSRP_v2_Registration_Service

Local anonymous policy:

oracle/no_authentication_service_policy

Local anonymous policy:

oracle/no_authentication_client_policy

WSRP_v2_ServiceDescription_Service

Local anonymous policy:

oracle/no_authentication_service_policy

Local anonymous policy:

oracle/no_authentication_client_policy


To override GPA and secure end-to-end portlet applications with a locally attached policy:

51.2 Securing the Portlet Service

Securing the portlet service with a locally attached policy that overrides GPA involves the following main steps:

51.2.1 How to Authenticate the Service

Authenticating the service is necessary only in two cases:

  • When applying the "no behavior" policy to the anonymous ports.

  • When GPA is being overridden for the WSRP_v2_Markup_Service port.

When a policy is attached locally, Oracle ADF must authenticate the portlet service against an Oracle Web Services Manager policy, such as wss10_saml_token_with_message_protection_service_policy. In addition, it is necessary to configure security for the Oracle Fusion web application EAR file.

Authenticating the services involves the following main steps:

  • Attach the policy (for example, wss10_saml_token_with_message_protection_service_policy) to the provider. You can do this in one of the following ways:

    • Use Oracle Enterprise Manager.

    • Alternatively, manually update oracle-webservices.xml. This is a packaging artifact, meaning it is not available in Oracle JDeveloper during design time. To edit the file, deploy your application to an EAR file. Extract the oracle-webservices.xml file, update it and repackage it into the EAR file.

To edit the oracle-webservices.xml file when overriding GPA:

Open the oracle-webservices.xml file, find port-component name="WSRP_v2_Markup_Service" and add the code shown in Example 51-1.

Example 51-1 Edit the oracle-webservices.xml File

<port-component name="WSRP_v2_Markup_Service" style="document" bindingQName="{urn:oasis:names:tc:wsrp:v2:bind}WSRP_v2_Markup_Binding_SOAP" enabled="true" schemaValidateInput="false">
   <policy-references>
      <policy-reference enabled="true" uri="oracle/wss10_saml_token_with_message_protection_
         service_policy" category="security"/>
      </policy-references>
   <operations>
      <operation name="performBlockingInteraction" inputName="performBlockingInteraction"
         outputName="performBlockingInteractionResponse"
         input="{urn:oasis:names:tc:wsrp:v2:types}performBlockingInteraction" use="literal"/>
      <operation name="releaseSessions" inputName="releaseSessions"
         outputName="releaseSessionsResponse"
         input="{urn:oasis:names:tc:wsrp:v2:types}releaseSessions" use="literal"/>
      <operation name="getMarkup" inputName="getMarkup" outputName="getMarkupResponse"
         input="{urn:oasis:names:tc:wsrp:v2:types}getMarkup" use="literal"/>
      <operation name="handleEvents" inputName="handleEvents" outputName="handleEventsResponse"
         input="{urn:oasis:names:tc:wsrp:v2:types}handleEvents" use="literal"/>
      <operation name="initCookie" inputName="initCookie" outputName="initCookieResponse"
         input="{urn:oasis:names:tc:wsrp:v2:types}initCookie" use="literal"/>
      <operation name="getResource" inputName="getResource" outputName="getResourceResponse"
         input="{urn:oasis:names:tc:wsrp:v2:types}getResource" use="literal"/>
   </operations>
   <!-- start:deployment time generated info -->
   <deployment>
     <tie-class-name>oasis.names.tc.wsrp.v2.bind.runtime.WSRP_v2_Markup_Binding_SOAP_
        Tie</tie-class-name>
     <service-qname namespaceURI="urn:oasis:names:tc:wsrp:v2:wsdl" localpart="WSRP_v2_Service"/>
     <soap-version>soap1.1</soap-version>
   </deployment>
   <!-- end:deployment time generated info   -->
     <servlet-link>WSRP_v2_Markup_Service</servlet-link>
</port-component>

51.2.2 How to Configure the Key Store and Credential Store

By default, a globally attached policy profile specifies (authentication [AuthN]) and there is no need to use Oracle Enterprise Manager to configure a key store or a credential store. You only need to perform this task when a policy has a message protection or a SSL profile.

The key store contains the signing and encryption keys used to encrypt and decrypt messages. The key store itself and all the keys are password protected. The keys are also referred to using aliases, which are stored, along with their corresponding passwords, in the credential store. When accessing the key store, query the credential store first for the necessary aliases and passwords.

You can verify the creation of the key store and credential store as follows.

To verify the creation of the key store and credential store:

  1. Open $DOMAIN_HOME/config/fmwconfig/jps-config.xml.

  2. Verify the existence of the entry shown in Example 51-2. This code should be configured out of the box.

    Example 51-2 Verify the credstore and keystore serviceInstance Elements

    <serviceInstance location="./" provider="credstoressp" name="credstore">
                <description>File Based Credential Store Service Instance</description>
    </serviceInstance>
    
    <serviceInstance name="keystore" provider="keystore.provider" location="./default-keystore.jks">
                <description>Default JPS Keystore Service</description>
                <property name="keystore.type" value="JKS"/>
                <property name="keystore.csf.map" value="oracle.wsm.security"/>
                <property name="keystore.pass.csf.key" value="keystore-csf-key"/>
                <property name="keystore.sig.csf.key" value="sign-csf-key"/>
                <property name="keystore.enc.csf.key" value="enc-csf-key"/>
    </serviceInstance>
    
  3. Make sure the default context references the key store and credential store service instances as shown in Example 51-3.

    Example 51-3 Default Context References to the Credential Store and Key Store

    <jpsContext name="default">
                <serviceInstanceRef ref="credstore"/>
                <serviceInstanceRef ref="policystore.xml"/>
                <serviceInstanceRef ref="audit"/>
                <serviceInstanceRef ref="idstore.ldap"/>
                <serviceInstanceRef ref="keystore"/>
    </jpsContext>
    

    Note:

    There is no need to restart your domain if this configuration is already in place.


51.2.3 How to Authorize the Service

Oracle ADF Security is responsible for authorizing portlets, that is, Oracle ADF Security decides whether a portlet is available to a given user by checking it against the Oracle Platform Security Services (OPSS) policy store. Portlets are just one way of exposing local task flows to remote applications. A component called a portlet bridge is responsible for bridging between portlets and task flows. A portlet bridge enables exposing a task flow as a portlet.

Once you create an entitlement grant for the desired task flow in jazn-data.xml, you must create a resource grant for the portlet bridge component to the authenticated role, as shown in Example 51-4.

Example 51-4 Resource Grant to the Authenticated Role

<jazn-policy>
    <grant>
       <grantee>
           <principals>
               <principal>
                    <class>oracle.security.jps.internal.core.principals.
                           JpsAuthenticatedRoleImpl</class>
                    <name>authenticated-role</name>
                </principal>
           </principals>
        </grantee>
        <permissions>
              <permission>
                  <class>oracle.adf.controller.security.TaskFlowPermission</class>
                  <name>/WEB-INF/adfp-portlet-bridge-container.xml
                        #adfp-portlet-bridge-container</name>
                  <actions>view</actions>
              </permission>
        </permissions>
    </grant>
...
</jazn-policy>

Example 51-5 shows an entitlement grant enabling access to the task flow.

Example 51-5 Entitlement-Based Policy Definition in the jazn-data.xml File

<?xml version="1.0" ?>
<jazn-data>
  <policy-store>
    <applications>
      <application>
        <name>MyApp</name>
                
        <app-roles>
        <app-role>
          <name>AppRole</name>
          <display-name>AppRole display name</display-name>
          <description>AppRole description</description>
          <guid>F5494E409CFB11DEBFEBC11296284F58</guid>
          <class>oracle.security.jps.service.policystore.ApplicationRole</class>
        </app-role>
      </app-roles>
                
      <!-- resource-specific OPSS permission class definition -->
      <resource-types>
        <resource-type>
          <name>TaskFlowResourceType</name>
          <display-name>Task Flow</display-name>
          <description>Task Flow resource type</description>
          <matcher-class>oracle.adf.controller.security.
                                    TaskFlowPermission</matcher-class>
          <actions-delimiter>,</actions-delimiter>
          <actions>view,customize,grant,personalize</actions>
        </resource-type>
      </resource-types>
                
      <resources>
        <resource>
         <name>/WEB-INF/my-task-flow.xml#my-task-flow</name>
          <display-name>my-task-flow</display-name>
          <description>/WEB-INF/my-task-flow</description>
          <type-name-ref>TaskFlowResourceType</type-name-ref>
        </resource>
      </resources>
                
      <!-- entitlement definition -->
      <permission-sets>
        <permission-set>
          <name>MyPortletEntitlement</name>
          <member-resources>
            <member-resource>
              <resource-name>/WEB-INF/my-task-flow.xml#
                                           my-task-flow</type-name-ref>
              <type-name-ref>TaskFlowResourceType</type-name-ref>
              <display-name>my-task-flow</resource-name>
              <actions>view</actions>
            </member-resource>
          </member-resources>
        </permission-set>
      </permission-sets>
                
      <!-- Oracle function security policies -->
      <jazn-policy>
        <!-- function security policy is a grantee and permission set -->
        <grant>
          <!-- application role is the recipient of the privileges -->
          <grantee>
            <principals>
              <principal>
                <class>
                   oracle.security.jps.service.policystore.ApplicationRole
                </class>
                <name>AppRole</name>
              </principal>
            </principals>
          </grantee>

          <!-- entitlement granted to an application role -->
          <permission-set-refs>
            <permission-set-ref>
              <name>MyPortletEntitlement</name>
            </permission-set-ref>
          </permission-set-refs>
        </grant>
      </jazn-policy>
    </application>
  </applications>
 </policy-store>
</jazn-data>

Note when the Oracle Fusion application needs to provide anonymous access to a portlet, the bridge wrapper task flow needs a grant to the anonymous-role, and the markup port needs a no_authentication policy, or it can use GPA, but needs to specify a Default User in the producer registration, using a valid guest user account, as described in Section 51.3, "Securing the Portlet Client."

51.3 Securing the Portlet Client

Securing the portlet client is necessary only when applying the "no behavior" policy to the anonymous ports.

Securing a portlet consumer, or client, means enabling identity propagation. You can enable identity propagation while registering the portlet producer in Oracle JDeveloper. When registering the portlet producer, make sure you select following values in the WSRP Portlet Producer Registration wizard.

In the Configure Security Attributes window, select the following:

Within the portlet consumer domain, make sure the key store and credential store are the same ones used by the portlet producer or service. The key store and credential store are located at $DOMAIN_HOME/config/fmwconfig. For more information, see the section about verifying the creation of the key store and credential store under Section 51.2.2, "How to Configure the Key Store and Credential Store."

51.4 Registering the Key Store and Writing to the Credential Store

By default, globally attached policy profile specifies (authentication [AuthN]) and there is no need to use Oracle Enterprise Manager to register a key store or create a credential store. You only need to perform this task when a policy profile offers message protection or SSL.

However, if you need to configure another key store for your domain, use Oracle Enterprise Manager to register the key store and write to the credential store.

51.4.1 How to Register the Key Store and Write to the Credential Store

To register the key store and write to the credential store:

  1. In Oracle Enterprise Manager, expand your domain. Select WebLogic Domain > WebLogic Domain Name.

  2. In the right-hand pane, click the WebLogic Domain menu at the top of the page and select Security > Credentials.

  3. If there is no map called oracle.wsm.security, create one. If the map exists, skip this step. Figure 51-1 displays the Create Map window.

    Figure 51-1 Create a Map If None Exists

    Create a map if none exists.
    • Click the Create Map button.

    • For the Map Name, enter oracle.wsm.security.

      Do not create any keys. Keys are created when configuring the domain's service provider.

  4. In the right-hand pane, click the WebLogic Domain menu at the top of the page and select Security > Security Provider Configuration.

  5. In the Service Provider Configuration page, under the Key Store section, click the Configure button. The Service Provider Configuration page is shown in Figure 51-2.

    Figure 51-2 Click the Configure Button

    Click the Configure button.
  6. If the Keystore Path displays ./default-keystore.jks, follow the instructions here. Otherwise, skip this step.

    Uncheck the Configure KeyStore Management box and click OK. This displays the window shown in Figure 51-2.

    Under the Keystore section, click Configure again and enter the following information. The file producer.jks is assumed to be located under the directory path $DOMAIN_HOME/config/fmwconfig which contains a certificate alias called producer. Figure 51-3 displays the Keystore Configuration page.

    Figure 51-3 Configure the Keystore

    Configure the keystore.
    • Keystore Path: Enter the path of the keystore, in this case ./producer.jks.

    • Password/Confirm Password: Enter the required password, then confirm the password.

    Signature Key

    • Key Alias: Enter the name of the signature key.

    • Signature Password/Confirm Password: Enter the required password, then confirm the password.

    Encryption Key

    • Crypt Alias: Enter the name of the encryption key.

    • Crypt Password/Confirm Password: Enter the required password, then confirm the password.

  7. Restart your domain.

51.4.2 What Happens When You Register the Key Store and Write to the Credential Store

Entering this information enables the creation of keystore-csf-key, sign-csf-key and enc-csf-key in the credential store of the domain. You can verify that the keys have been created by viewing the credential store page of the domain in Oracle Enterprise Manager.

51.5 Maintaining Application Session Context Across Web Service Requests

When the user invokes a function defined by a web service, the current application session context must be propagated across web service requests. The application session context contains important information that is stored for the duration of the user's HTTP session. This includes information that defines a context for the application, such as its language preferences, date, and number formatting.

In order for application session context propagation to occur, you need to register the ApplSessionContext class with the context interceptor infrastructure. Then when a SOAP request is generated by the invoked web service, the request calls out to the infrastructure and adds the application session context onto the SOAP payload.

To register the ApplSessionContext class, you must add the oracle.applcore.config library to the weblogic-application.xml file for projects on both ends of the web service request. In order for propagation to work, both the portlet consumer and the portlet producer must have this library.

Before you begin:

It may be helpful to have an understanding of application user sessions. For more information, see Chapter 47, "Implementing Application User Sessions."

You will need to complete this task:

Configure your project to use application user sessions. For more information, see Section 47.2, "Configuring Your Project to Use Application User Sessions."

To add the Oracle Applications Core (Config) JDev library to the classpath:

  1. In the Application Resources panel of the Application Navigator, double-click the weblogic-application.xml file of the project that defines the portlet producer.

  2. In the source editor for the file, add the following lines alongside the other <library-ref> tags:

    <library-ref>
      <library-name>
        oracle.applcore.config
      </library-name>
    </library-ref>
    

    The order of the <library-ref> tags is not important; however, all <library-ref> tags must be grouped together.

  3. Repeat this change in the project that defines the portlet consumer.

    In order for propagation to work, both the portlet consumer and the portlet producer must have the oracle.applcore.config library.

PK?B8PK BOEBPS/prt_ecsf.htm Using Oracle Enterprise Crawl and Search Framework

Part V

Using Oracle Enterprise Crawl and Search Framework

This part of the Developer's Guide provides information about the Oracle Enterprise Crawl and Search Framework (ECSF). Oracle Enterprise Crawl and Search Framework (ECSF) is an Oracle Fusion Middleware search framework that enables you to quickly expose application context information on various business objects to enable full-text transactional search.

The Getting Started with Oracle Enterprise Crawl and Search Framework chapter discusses how to set up ECSF.

The Creating Searchable Objects chapter discusses how to create sets of data that make view objects available for full text search.

The Configuring ECSF Security chapter discusses how to configure security for ECSF.

The Validating and Testing Search Metadata chapter discusses how to validate and test the search metadata.

The Deploying and Crawling Searchable Objects chapter discusses how to deploy the sets of data to the ECSF application and verify the crawl.

The Advanced Topics for ECSF chapter discusses the additional functionality that ECSF offers to enhance the search experience.

This part contains the following chapters:

PK"  PK BOEBPS/adv_xdf.htm Using the Database Schema Deployment Framework

56 Using the Database Schema Deployment Framework

This chapter discusses database modeling and database schema deployment in Oracle Fusion Middleware.

When designing an application to interact with the database, you will need to understand the database schema and be able to modify the schema as needed. This chapter contains information regarding database modeling and database schema deployment in Oracle Fusion Middleware. Developers should not use SQL DDL scripts for deployment and source control of database objects, because they tend to be error-prone and do not serve as a single accurate source. Instead, developers should use the JDeveloper offline database schema object files in SXML persistence mode.


Note:

Prior to SXML migration, these were referred to as XDF (extension) files.


This chapter includes the following sections:

56.1 Introduction to Using the Database Schema Deployment Framework

The Oracle Fusion Schema Deployment framework includes JDeveloper plugins that handle applications-specific metadata, data modeling standards for applications database modeling, and deployment of database schema objects to a target application database. The database schema deployment component can be invoked standalone outside of JDeveloper, such as from the command line, build scripts, or a patching tool.

56.2 Implementing Applications Data Modeling and Deployment JDeveloper Extensions (Data Modeling Extensions)

Oracle uses source-controlled schema metadata files produced from JDeveloper. The Offline Database is a way to persist database object definitions in a JDeveloper project using SXML files, rather than accessing the database directly. It provides an abstract layer that can be used to access a store of database object definitions. Therefore, it is possible to create, edit, delete and manipulate aspects of a database schema offline and access database objects in a database through JDeveloper's connections.

All schema modeling can be done through JDeveloper. The XDF extension provides developers with a set of tools to do the data physical modeling, such as create, edit, deploy, and import the schema objects used in applications. The extension also provides Application Data Modeling Standard validation, modification, and template object plugins in JDeveloper to help users to follow the Data Model standards.

Developers will use XDF extensions for their database modeling development.

Information covered here includes:

56.2.1 How to Use the Offline Database

JDeveloper provides the tools you need to create and edit database objects, such as tables and constraints, outside the context of a database, using the offline Database model. You can create new tables and views, and generate the information to a database, or you can import database objects from a database schema, make the changes you want, and generate the changes back to the same database schema, to a new database schema, or to a file that you can run against a database at a later date.

56.2.2 How to Create an Offline Database

Follow these directions to create an offline database.

To create an offline database:

  1. In the Application navigator within JDeveloper, locate the project you want to work in.

  2. Select File > New to display the New Gallery.

  3. From the New Gallery, select Database Tier > Offline Database Objects > Offline Database, as shown in Figure 56-1.

    Figure 56-1 Creating a New Offline Database

    Creating a New Offline Database
  4. In the Create Offline Database dialog, enter a name for the offline database, as shown in Figure 56-2. For more information at any time, press F1 or click Help from within the Create Offline Database dialog.

    Figure 56-2 Naming the New Offline Database

    Naming the New Offline Database

The following types of objects are modeled using offline database objects.

  • Table

  • Trigger

  • View

  • Materialized View

  • Materialized View Log

  • Sequence

  • Synonym

JDeveloper offline database objects do not support these objects. However, SXML persistence files for these object types can be imported using the applxdf extension.

  • Queue

  • Queue tables

  • Policy

56.2.3 How to Deploy an Offline Database in XML Persistence Format

See Section 56.2.9.1, "Deploying in SXML Persistence Format."

56.2.4 How to Validate Application Data Model Standards

A Framework plug-in on the JDeveloper database object editor provides warnings and errors to enforce Data Modeling standards and XDF deployment requirements.

Additional Validations for Schema Object Deployment

To better service the Schema Deployment on Application Data Model, these validations have been added on some User Defined Property (UDP) and other object properties in the plugin.

  • Table Owner (UDP)

    For a table object, if the User Property Table Owner is not defined, an error will be displayed.

  • Short Name (UDP)

    All schema objects:

    • If the length of the object name is greater than the length standard and if the short name is null or empty, display a warning.

      If the short name is not null or empty, check if the length of the short name is greater than the length standard. If it is, display a warning message.

    • If the length of the object name is not greater than the length standard and if the short name is null or empty, automatically set the short name to be the same as the object name.

      If the short name is not null or empty, check if the length of the short name is greater than the length standard. If it is, display a warning message.

      The name length standard for a Table is 24; for all others, it is 27.

  • Adxml (UDP)

    The UDP adxml is set automatically for these schema object types:

    Table.TYPE
       View.TYPE
       Synonym.TYPE
    Sequence.TYPE
    MaterializedViewLog.TYPE
    MaterializedView.TYPE
    Trigger.TYPE
    

    The content of the UDP adxml will be determined by the current value of the UDP adxml and the UDP useExistingAdxml.

  • AdxmlFK (UDP)

    For table type only, automatically set the UDP adxmlFk according to the values of the UDP adxmlFk and useExistingAdxml.

  • AdxmlDeferredIndexes (UDP)

    For table and MaterializedView.type only, automatically set the UDP adxmlDeferredIndexes according to the current value of this UDP and the value of UDP useExistingAdxml.

  • Active Constraint or Index's Columns Checking

    Check the status of a column to which an active constraint or index refers. If its value is obsolete, an error message be displayed and block the work flow.

  • Index for Unique Constraint

    Check if an index of unique constraint exists. If not, add one automatically.

  • Constraint Deployment Violation Checking

    If a constraint is defined as disabled, but its UDP isLogical is set to N, a warning message will be displayed, because this case will cause a deployment error.

  • Dependencies/Risk

    This feature uses JDeveloper's Offline database APIs and therefore has a dependency on all the offline database JAR files. The risk for this feature is some enforcement of standards may fire wrongly due to potential bugs preventing developers from modeling their objects as needed.

56.2.5 Application User Defined Properties

JDeveloper provides a large number of User Defined Properties (UDP). Their mapping with the tables in the dictionary are detailed in:

56.2.5.1 User Defined Properties for Tables

Table 56-1 shows the User Defined Properties that are defined for the tables.

Table 56-1 User Defined Properties for Tables

UDPDisplay NameValues in JDeveloperDefinition in FND_TABLES

isFlashbackAllowed

This property indicates whether flashback of the table is allowed. This UDP is mandatory.

Is Flashback Allowed

Y: Flashback of the table is allowed. That is, you can use Flashback Query to examine the state of a table at a previous time, or use the FLASHBACK TABLE statement to restore an earlier state of a table in the event of human or application error.

N (default): Flashback of the table is not allowed.

FLASHBACK_ALLOWED

isLogical

The value of this UDP indicates whether the deployment program will create an editioning view for this table or not. This UDP is required.

Editioning View

Y (default): The deployment program will create an editioning view for this table.

N: The deployment program will not create an editioning view for this table.

LOGICAL

VARCHAR2(1) Not Null

runTwice

Run Deployment Twice

Y: Specifies that the table needs to be deployed twice and the appropriate patching metadata will be stamped in the file. This is typically used when a product team adds or modifies a column as a not-null column to a existing table, and does not want to use a RBMS default value. The column will be populated with an upgrade script having a more complex logic. The column needs to exist in the target database before the upgrade script is run. Also, the upgrade script cannot enforce the not-null constraint since it is against the standards to have DDL in scripts. Setting this UDP to Y will accommodate this.N (default).

N/A

shortName

The short name of the table is used by the Zero Downtime programs to uniquely identify the table. The maximum length of this UDP is 24 characters.

Table Short Name

N/A

The value of this UDP is defaulted to the table name when the length of the table name is less than 24 characters. When the length of the table name is greater than 24 characters, this UDP is required.

SHORT_NAME

VARCHAR2(30) Null

objectOwner

This UDP stores the Short Name of the application that the table belongs to.

This UDP is required.

Table Owner

N/A

APPLICATION_SHORT_NAME

VARCHAR2(10)

tsClassification

This UDP stores the Tablespace Classification for this table. This value is used to derive the tablespace for the table but it is not equivalent to the tablespace. This UDP is mandatory.

Tablespace Classification

TRANSACTION TABLES (default)

REFERENCE

INTERFACE

SUMMARY

NOLOGGING

TRANSACTION_INDEXES

ARCHIVE

TOOLS

MEDIA

N/A

mlsSupportModel

The value of this UDP indicates the language data model for the table.

This UDP is required.

MLS Support Model

Not MLS (default): The table is not an MLS table.

Fully Synched: For Standard MLS (pair of _B and _TL tables) or Single MLS (single _TL) tables. A record will exist in the _TL table for each licensed language in the instance. The _TL table must have LANGUAGE and SOURCE_LANG columns.

Partially Synched: For Partially Synchronized MLS tables. These tables have a LANGUAGE column but do not have a SOURCE_LANG column. A record may or may not exist in the table for the licensed languages in the instance.

Single Language: For Single Language tables. These tables do not have either a LANGUAGE or a SOURCE_LANG column. The language of the data in the translatable columns in the table is considered to be the language classified as the default or base language of the instance.

MLS_SUPPORT_MODEL

VARCHAR2(30)

status

The value of this UDP indicates the status of the table. This UDP is required.

Status

Active (default): The table is active.

Obsolete: The table is obsolete and can be deleted from the database.

STATUS

VARCHAR2(30)

extensionOfTable

This UDP stores the name of the base table that is extended by this table.

Extension of Table

N/A

EXTENSION_OF_TABLE

VARCHAR2(30)

deployTo

The value of this UDP indicates the deployment mode of the table for the Oracle Fusion Disconnected Mobile Framework.

This UDP is required.

Deploy To

Server DB Only (default): The table is deployed on the server database but not on the mobile database.

All: The table is deployed both on the server database and on the mobile database.

Mobile DB Only: The table is deployed on the mobile database but not on the server database.

DEPLOY_TO

VARCHAR2(30)

conflictResolution

The value of this UDP indicates how the Oracle Fusion Disconnected Mobile Framework should resolve the conflicts about duplicate rows.

This UDP is required.

Conflict Resolution

Duplicate (default): A new duplicate record is added and the conflict will be handled during the next synchronization. This value should be used for non-intersection tables.

Merge: The records are merged. This value should be used for intersection tables.

CONFLICT_RESOLUTION

VARCHAR2(30)

sharedObject

The value of this UDP indicates whether the table is accessed by external products.

Shared Object

Y: The table can be accessed directly by external products, other than the owning product.

N (default): The table cannot be accessed directly by external products.

SHARED_OBJECT

VARCHAR2(30)

adxml

The value of this UDP is patch metadata used by the patching tool.

ADXML

N/A

N/A

axdmlFk

The value of this UDP is patch metadata used by the foreign key portion of the patching tool.

ADXML for Foreign Keys

N/A

N/A

adxmlDeferredIndexes

The value of this UDP is patch metadata used by the deferred indexes portion of the patching tool.

ADXML for Deferred Indexes

N/A

N/A

useExistingAdxml

This UDP is mandatory.

Use Existing ADXML

Y: Generate ADXML comment using the existing ADXML value from the ADXML UDP

N (default): Regenerate the ADXML comment and update the ADXML UDP.

N/A

isSelectAllowed

This property indicates whether the select on the table is allowed. This is mandatory.

Is Select Allowed

Y (default)N

SELECT_ALLOWED

VARCHAR2(1) Not Null

isUpdateAllowed

This property indicates whether update on the table is allowed. This property is mandatory.

Is Update Allowed

Y (default)N

UPDATE_ALLOWED

VARCHAR2(1) Not Null

isInsertAllowed

This property indicates whether the insert on the table is allowed. This property is mandatory.

Is Insert Allowed

Y

N (default)

INSERT_ALLOWED

VARCHAR2(1) Not Null

isDeleteAllowed

This property indicates whether delete on the table is allowed. This property is mandatory.

Is Delete Allowed

Y (default)N

DELETE_ALLOWED

VARCHAR2(1) Not Null

isTruncateAllowed

This property indicates whether truncate on the table is allowed. This property is mandatory.

Is Truncate Allowed

Y

N (default)

TRUNCATE_ALLOWED

VARCHAR2(1) Not Null

maintainPartition

Indicates whether partitions can be maintained on the table. This property is mandatory.

Maintain Partition

Y

N (default)

MAINTAIN_PARTITION

VARCHAR2(1) Not Null

exchangePartition

Indicates whether it is possible to exchange partitions on the table. This property is mandatory.

Exchange Partition

Y

N (default)

EXCHANGE_PARTITION

VARCHAR2(1) Not Null

maintainIndex

This property indicates whether it is possible to maintain indexes on the table. This property is mandatory.

Maintain Index

Y

N (default)

MAINTAIN_INDEX

VARCHAR2(1) Not Null


56.2.5.2 User Defined Properties for Columns

Table 56-2 shows the User Defined Properties that are defined for columns.

Table 56-2 User Defined Properties for Columns

UDPDisplay NameValues in JDeveloperDefinition in FND_COLUMNS

shortName

The short name of the column is used by the Zero Downtime programs to uniquely identify the column within the table.

The value of this UDP is defaulted to the column name when the length of the column name is less than 27 characters. When the length of the column name is greater than 27 characters, this UDP is required.

Column Short Name

N/A

SHORT_NAME

VARCHAR2(27) Null

translateFlag

The value of this UDP indicates whether the column is translatable or not.

This UDP is required.

Translate

Y: The column is translatable.

N (default): The column is not translatable.

TRANSLATE_FLAG

VARCHAR2(1) Not Null

status

The value of this UDP indicates the status of the column.

This UDP is required.

Status

Active (default): The column is active.

Obsolete: The column is obsolete and can be deleted from the database.

STATUS

VARCHAR2(30)

customDefaultValue

Custom Default Value

N/A

N/A

denormPath

The value of this UDP indicates the name of the column that stores the data that should be copied to this column as per the Oracle Fusion Disconnected Mobile Framework.

Denormalization Path

N/A

N/A

routingMode

The value of this UDP indicates how this column will be handled during the synchronization between the server and the client database as per the Oracle Fusion Disconnected Mobile Framework.

Routing Mode

Normal (default): The contents of this column must be routed to the destination database.

Do Not Route: The contents of this column must not be routed to the destination database.

ROUTING_MODE

VARCHAR2(30)

histogram

The value of this UDP indicates if the column is a candidate for histogram.

This UDP is required.

Histogram

Y (default): This column is a candidate for histogram.

N: This column is not a candidate for histogram.

N/A

histogramSize

The value of this UDP indicates the number of buckets to be used when the column is defined as a candidate for histograms.

Histogram Size


N/A

versionColumn

The value of this UDP indicates the name of the version column used by the Oracle Fusion Disconnected Mobile Framework during synchronization of LOB columns.

Disconnected Mobile Version Column Name

N/A

VERSION_COLUMN

VARCHAR2(30 CHAR)


56.2.5.3 User Defined Properties for Indexes

Table 56-3 shows the User Defined Properties that are defined for the indexes.

Table 56-3 User Defined Properties for Indexes

UDPDisplay NameValues in JDeveloperDefinition in FND_INDEXES

shortName

The short name of the index is used by the Zero Down Time patching programs to uniquely identify the index.

The value of this UDP is defaulted to the index name when the length of the index name is less than 28 characters. When the length of the index name is greater than 28 characters, the developer must enter a value that uniquely identifies the index.

Index Short Name

N/A

SHORT_NAME

VARCHAR2(30) Null

deferred

The value of this UDP indicates whether the creation of the index will be deferred during deployment.

This UDP is required.

Index Deferred (Y/N)

N (default): The creation of the index will not be deferred.

Y: The creation of the index will be deferred.

N/A

status

The value of this UDP indicates the status of the index.

This UDP is required.

Status

Active (default): The index is active.

Obsolete: The index is obsolete and can be deleted from the database.

STATUS

VARCHAR2(30)

deployTo

The value of this UDP indicates the deployment mode of the index for the Oracle Fusion Disconnected Mobile Framework.

This UDP is required.

Deploy To

Server DB Only (default): The index is deployed on the server database but not on the mobile database.

All: The index is deployed both on the server database and on the mobile database.

Mobile DB Only: The index is deployed on the mobile database but not on the server database.

DEPLOY_TO

VARCHAR2(30)


56.2.5.4 User Defined Properties for Constraints

Table 56-4 shows the User Defined Properties that are defined for the constraints.

Table 56-4 User Defined Properties for Constraints

UDPDisplay NameValues in JDeveloperDefinition in FND_PRIMARY_KEYS or FND_FOREIGN_KEYS

isLogical

Logical Constraint

Y (default)N

LOGICAL

VARCHAR2(1)

shortName

The short name of the constraint is used by the Zero Down Time patching programs to uniquely identify the constraint.

The value of this UDP is defaulted to the constraint name when the length of the constraint name is less than 28 characters. When the length of the constraint name is greater than 28 characters, the developer must enter a value that uniquely identifies the constraint.

Constraint Short Name


SHORT_NAME

VARCHAR(30)

conDefer

The value of this UDP indicates whether the creation of the constraint will be deferred during deployment.

This UDP is required.

Defer Constraint

N (default): The creation of the constraint will not be deferred.

Y: The creation of the constraint will be deferred.

N/A

status

The value of this UDP indicates the status of the constraint.

This UDP is required.

Status

Active (default): The constraint is active.

Obsolete: The constraint is obsolete and can be deleted from the database.

N/A


56.2.5.5 User Defined Properties for Views

Table 56-5 shows the User Defined Properties that are defined for the views.

Table 56-5 User Defined Properties for Views

UDPDisplay NameValues in JDeveloperDefinition in FND_VIEWS

adxml

The value of this UDP is patch metadata used by the patching tool.

ADXML

N/A

N/A

isFlashbackAllowed

This property indicates whether flashback of the view is allowed. This UDP is mandatory.

Is Flashback Allowed

Y: Flashback of the view is allowed. That is, you can use Flashback Query to examine the state of a view at a previous time.

N (default): Flashback of the view is not allowed.

FLASHBACK_ALLOWED

useExistingAdxml

Use Existing ADXML

Y: Generate ADXML comment using existing ADXML value from ADXML UDP.

N (default): Regenerate ADXML comment and update ADXML UDP.

N/A

status

The value of this UDP indicates the status of the view.

This UDP is required.

Status

Active (default): The view is active.

Obsolete: The view is obsolete and can be deleted from the database.

STATUS

VARCHAR2(30)

isSelectAllowed

This property indicates whether the select on the table is allowed. This is mandatory.

Is Select Allowed

Y (default)N

SELECT_ALLOWED

VARCHAR2(1) Not Null

isUpdateAllowed

This property indicates whether update on the table is allowed. This property is mandatory.

Is Update Allowed

Y (default)N

UPDATE_ALLOWED

VARCHAR2(1) Not Null

isInsertAllowed

This property indicates whether the insert on the table is allowed. This property is mandatory.

Is Insert Allowed

Y

N (default)

INSERT_ALLOWED

VARCHAR2(1) Not Null

isDeleteAllowed

This property indicates whether delete on the table is allowed. This property is mandatory.

Is Delete Allowed

Y (default)N

DELETE_ALLOWED

VARCHAR2(1) Not Null


56.2.5.6 User Defined Properties for Sequence

Table 56-6 shows the User Defined Properties that are defined for Sequence.

Table 56-6 User Defined Properties for Sequence

UDPDisplay NameValues in JDeveloperDefinition in FND_SEQUENCES

objectOwner

Sequence Owner

N/A

N/A

status

The value of this UDP indicates the status of the sequence. This UDP is required.

Status

Active (default): The sequence is active.

Obsolete: The sequence is obsolete and can be deleted from the database.

STATUS

VARCHAR2(30) Null

adxml

The value of this UDP is patch metadata used by the patching tool.

ADXML

N/A

N/A

useExistingAdxml

Use Existing ADXML

Y: Generate ADXML comment using existing ADXML value from ADXML UDP.

N (default): Regenerate ADXML comment and update ADXML UDP.

N/A

isSelectAllowed

This property indicates whether select on the table is allowed.

This UDP is mandatory.

Is Select Allowed

Y (default)N

SELECT_ALLOWED

VARCHAR2(1) Not Null

resetSequence

This property indicates if the sequence can be reset to a specific value.

This UDP is mandatory.

Reset Sequence

Y

N (default)

RESET_SEQUENCE

VARCHAR2(1) Not Null


56.2.5.7 User Defined Properties for Materialized View

Table 56-7 shows the User Defined Properties that are defined for the Materialized View.

Table 56-7 User Defined Properties for Materialized View

UDPDisplay NameValues in JDeveloperDefinition in FND_MVIEWS

objectOwner

Short Name of the application to which this materialized view belongs.

Mview Owner

N/A

N/A

shortName

Materialized view short name. Max Length is 24.

Materialized View Short Name

N/A

SHORT_NAME

VARCHAR2(30)

status

The value of this UDP indicates the status of the materialized view.

Status

Active (default): The materialized view is active.

Obsolete: The materialized view is obsolete and can be deleted from the database.

STATUS

VARCHAR2(30)

adxml

The value of this UDP is patch metadata used by the patching tool.

ADXML


N/A

tsClassification

Tablespace Classification

TRANSACTION_TABLES

REFERENCE

INTERFACE

SUMMARY (default)

ARCHIVE

TOOLS

MEDIA

N/A

useExistingAdxml

This UDP is mandatory.

Use Existing ADXML

Y: Generate ADXML comment using existing ADXML value from ADXML UDP.

N (default): Regenerate ADXML comment and update ADXML UDP.

N/A

isSelectAllowed

This property indicates whether select on the table is allowed.

This UDP is mandatory.

Is Select Allowed

Y (default)N

SELECT_ALLOWED

VARCHAR2(1) Not Null

adxmlDeferredIndexes

The value of this UDP is patch metadata used by the deferred indexes portion of the patching tool.

ADXML for Deferred Indexes

N/A

N/A


56.2.5.8 User Defined Properties for Materialized View Log

Table 56-8 shows the User Defined Properties that are defined for the Materialized View Log.

Table 56-8 User Defined Properties for Materialized View Log

UDPDisplay NameValues in JDeveloper

status

The value of this UDP indicates the status of the materialized view log. This UDP is required.

Status

Active (default): The materialized view log is active.

Obsolete: The materialized view log is obsolete and can be deleted from the database.

objectOwner

Materialized view log owner.

MV Log Owner

N/A

adxml

The value of this UDP is patch metadata used by the patching tool.

ADXML


useExistingAdxml

This UDP is mandatory.

Y

N (default)

Y: Generate ADXML comment using existing ADXML value from ADXML UDP.

N (default): Regenerate ADXML comment and update ADXML UDP.


56.2.5.9 User Defined Properties for Trigger

Table 56-9 shows the User Defined Properties that are defined for Trigger.

Table 56-9 User Defined Properties for Trigger

UDPDisplay NameValues in JDeveloper

status

The value of this UDP indicates the status of the trigger. This UDP is required.

Status

Active (default): The trigger is active.

Obsolete: The trigger is obsolete and can be deleted from the database.

objectOwner

Trigger Owner

N/A

adxml

The value of this UDP is patch metadata used by the patching tool.

ADXML


useExistingAdxml

This UDP is mandatory.

Use Existing ADXML

Y: Generate ADXML comment using existing ADXML value from ADXML UDP.

N (default): Regenerate ADXML comment and update ADXML UDP.


56.2.6 How to Create an Offline Database Object

To create new offline database objects from within JDeveloper, in the Application Navigator:

  • Right-click the offline Database or schema.

  • Select New Database Object.

  • Select any Offline database object definition that you wish to create.

You also can create an offline database object definition by importing an existing definition from an online database schema.

56.2.7 How to Edit an Offline Database Object

To edit an offline database object:

  • In the Application Navigator, expand the workspace, project, and schema.

  • Right-click the offline database object that you wish to edit and choose Properties. Or double-click the offline database object.

    The Edit offline database object dialog opens. For more information at any time, press F1 or click Help from within the Edit dialog.

  • In the Edit dialog, select an information category on the left and change the values in the panel on the right. Any items that are grayed out cannot be selected or changed.

56.2.8 How to Import an Offline Database Object

Database objects from a database schema can be imported to an offline database project in JDeveloper. JDeveloper extensions will also handle the additional Oracle Fusion metadata, if available in the target database. The additional metadata will be copied to an offline database object as user-defined properties. For objects not supported by JDeveloper, such as Policy and Advanced queue tables, import of object definitions from the database will be provided. Implementation of unsupported object import process APIs depends on functionality provided by the Metadata team (dbms_metadata).

Using the Import Offline Database Object Wizard

Object definitions can be generated to the Offline Database by right-clicking an Offline Database Source and selecting the Reverse Engineer Fusion Applications Objects option, extended to invoke the relevant import API, as shown in Figure 56-3.

Figure 56-3 Starting the Import Database Object Wizard

mport Database Object Wizard
  1. The target database connection name can be selected from the list of all defined database connections, or a new connection can be created in the Specify Source dialog, shown in Figure 56-4.

    Figure 56-4 Specifying the Source

    Specify source dialog
  2. Select the Project and Offline database to which the objects from the target database need to be imported, as shown in Figure 56-5.

    Figure 56-5 Specifying the Target

    Specify Target Dialog

    Filters can be applied to select the objects that are displayed as available for import. When there are a large number of objects in the schema, you should apply filters.

    In the Object Picker, shown in Figure 56-6, you can:

    • Enter characters in the Name Filter to filter the list of available objects by name. The Name Filter is case sensitive.

    • When there are a large number of objects, you can turn off Auto-Query and click Query once you have entered the filter you want to use.

    • Select the object types you want to view.

    Figure 56-6 Picking an Object

    Object Picker
  3. Click Next to display the summary information.

  4. Click Finish to import the selected objects to the specified offline database.

56.2.9 How to Deploy the Offline Database Objects

Once an offline database object is created, it can be deployed to a target database using the deployment extension provided in JDeveloper.

56.2.9.1 Deploying in SXML Persistence Format

As part of the Oracle Middleware Extensions for Applications (Applications Core) labels, the applxdf extensions for the JDeveloper offline database include a deployment program that operates on JDeveloper offline database objects in SXML format. It checks for and compares the object definitions in SXML format with the object definitions in the target database, and then executes the necessary create/alter DDL to deploy the objects. This deployment program is available in two forms:

  • Deployment wizard extension that can be invoked from within JDeveloper.

  • Standalone deployment program that can be invoked from the command line.

56.2.9.1.1 How to Use the Database Object Deployment Wizard in JDeveloper

To start the deployment wizard in JDeveloper, you need to choose APPS: Deploy DB Object from the context menu on the offline object definition in the Application Navigator.

This can be used to deploy an offline database to a target online database. These options are available for deployment:

  • Deploying a single database object file. Only one item is selected, as shown in Figure 56-7.

    Figure 56-7 Deploying a Single Database Object File

    Deploying a Single DB Object File
  • Deploying multiple database object files (Bulk Deployment). Several items are selected, as shown in Figure 56-8.

    Figure 56-8 Deploying Multiple Database Object Files

    Deploying Multiple DB Object Files
  • Deploying offline schema object (and thereby deploying the entire designed data model), as shown in Figure 56-9.

    Figure 56-9 Deploying Offline Schema Object

    Deploying Offline Schema Object

The Generate Fusion Applications Objects wizard will prompt for the following information:

  • Database Connection: The target database connection name can be selected from the list of all defined database connections, or a new connection can be created, as shown in Figure 56-10.

    Figure 56-10 Selecting a Database Connection

    Selecting a Database Connection
  • Deployment Parameters. Figure 56-11 shows how the dialog appears for single database deployment parameters.

    Figure 56-11 Single Database Object Deployment Parameters

    Single DB Object Deployment Parameters

    Figure 56-12 shows how the Deployment Parameters dialog appears for multiple database deployment parameters.

    Figure 56-12 Multiple Database Object Deployment Parameters

    Multi DB Object Deployment Parameters
    • Owner User: Oracle schema name in which the object exists or should be created.

    • Log File Path: Specify a logfile name if it has to be written to a log file. By default, the log will be displayed in the JDeveloper log window.

      For Single Database Object deployment, this is optional. For bulk Database Object and schema deployment, it is mandatory to provide a directory for saving log files.

    • Log File Format: The format of the log file. Permitted values are text (the default) or xml.

    • Debug Level: The Debug level controls the level of detail to be captured in the log. Debug Level=3 will show the most information. Permitted values are 0 (the default), 1, 2 or 3.

    • Db Object Mode: A single database object can be deployed independently in table and in tablefk mode.

      In case of bulk and schema deployment, the database objects first will be deployed in table mode and then tablefk mode, by default.

      This is standard for bulk and schema deployment; therefore, the Db Object Mode is not displayed on the wizard.

    • Stand Alone: If this option is selected, the XDF comparison utility will execute in a standalone mode. This mode does not have any applications dependencies and it creates database objects without applications standards for physical attributes such as TABLESPACE/STORAGE; the database defaults are used.

    • Change Database: This option indicates whether the deployment should just report or execute the necessary Alter DDLs, based on comparison of the offline Database object definition against target database. If unchecked, the deployment will report on the differences but will not actually apply the changes to the database.

    • Force Mode: If this option is selected, any additional column, index or constraints that are present in a target database, but not in the current object file, will be dropped.

56.2.9.1.2 How to Use the Database Object Deployment Command Line Interface

Use this command and parameters shown in Example 56-1 to deploy a database object from the command line.

Example 56-1 Sample Database Object Deployment Using the CLI

java oracle.apps.fnd.applxdf.comp.XdfSchemaDeploy <owner_un={schemaId}> <apps_un={appId}> <jdbc_protocol={jdbc driver type}> <jdbc_db_addr={jdbc tns info}> <xdf_file_name={xdf file name}> <xdf_mode={xdf mode}> [xdf_xsl_dir={xsl file directory}] [standalone={y|n}] [changedb={y|n}] [logfileformat={text|xml}] [logfile={log file path and name}] [debuglevel={0|1|2|3}] [from_jdev={y|n}]*

Mandatory Arguments

  • owner_un: Oracle schema name in which the object exists or should be created.

  • apps_un: Oracle schema name of the current APPS schema.

Note that in the consolidated fusion schema model, owner_un will be the same as apps_un. These parameters are maintained for cases where they could be different.

  • jdbc_protocol: The JDBC protocol (thin or oci8).

  • jdbc_db_addr: JDBC tns information, either formatted as a Net8 connect string enclosed in double quotes, or as hostname:port:oracle_sid.

  • xdf_mode: The object type information - table, qtable, mview, mviewlog, sequence, type, trigger, view, policy, bootstrap.

  • xdf_file_name: The XDF file name, which contains the object definition. It is not mandatory if the xdf_mode is bootstrap.

Password Arguments

The command line deployment tool will prompt to get the database password from the user in an interactive mode. The password cannot be a parameter, because it is against Security guidelines. If you have a script in which you are invoking schema deployment, you can pipe the password in the script, such as:

$JDEV_JAVA_HOME/bin/java oracle.apps.fnd.applxdf.comp.XdfSchemaDeploy owner_un=$FUSION_SCH apps_un=$FUSION_SCH  jdbc_protocol=thin jdbc_db_addr=$JDBC_ADDR changedb=y logfileformat=text xdf_file_name=$xdfFile xdf_mode=$xdf_mode  logfile=$logfile  <<!  $FUSION_PASS

Optional Parameters

  • xdf_xsl_dir: The XSL directory, which contains all the XSL files required for XSLT transformation. This parameter is optional and is automatically determined in most cases if the JAR file format of deploying Java class files is being used. This parameter is maintained for flexibility, in case the format for deploying Java files becomes similar to what existed in previous versions.

  • standalone: This option is used to execute the XDF comparison utility in a standalone mode. Permitted values are y, Y, n or N. The default value is n. Standalone=y does not have any applications dependency. This mode creates database objects without applications standards for physical attributes such as TABLESPACE/STORAGE and uses the database defaults. It also does not update applications metadata.

  • changeDb: The default is "y." If changedb is specified as "n," the SQL statements generated by the XDF comparison utility are not executed but are displayed on the standard output or a log file.

  • logfileformat: The format of the log file. Permitted values are text or xml. If logfileformat is not set, the default is text.

  • logfile: The output of the comparison utility is written to standard out. Specify a logfile name if it has to be written to a log file. If logfile is not set, the outputs will be displayed on the screen.

  • debuglevel: Debug levels determine how much information is to be shown in the log. Debuglevel=3 will show the most information. Permitted values are 0, 1, 2 or 3. The default value is 0.

  • from_jdev: This parameter is set to "y" when the XDF comparison utility is called from JDeveloper. The default value is "n."

  • force_mode: The force deployment mode introduces an additional input parameter that when specified will drop any additional column, index or constraints that are present in a target database. The applications metadata stored for the object is also updated to be in sync with the new definition.

  • index_category: Values are small, large, and both. If the table is partitioned, the index is always created. If the table is not partitioned, there is no index creation if one of these conditions is true:

    • index_category=small and unused dbms block size greater than parallel_index_threshold

    • index_category=large and unused dbms block size less than parallel_index_threshold

  • parallel_index_threshold: Parallel index threshold, default is 0.

  • no_error: This option is used when you add a not-null column to an existing table with data, or change a null column to a not-null column. XdfSchemaDeploy results in FAILURE without this option. XdfSchemaDeploy results in WARNING if you have no_error=y. Default value is "n."

  • idxnolog: Pass idxnolog=y to add a NOLOGGING clause in the Index creation to improve the performance of creation. The default value is "n."

56.2.9.2 Setting the CLASSPATH Variable

The XdfSchemaDeploy tool requires JDK 1.6, the standard Oracle JDBC driver, the XML parser, and the applxdf JAR file.

Set the CLASSPATH environment variable to contain these JAR files:

  • ojdl.jar (Only DROP8 Build 3)

  • ojdl2.jar (Only DROP8 Build 3)

  • xmlparserv2.jar

  • ojdbc6.jar

  • orai18n.jar

  • oracle.apps.fnd.applxdf.jar

    Example 56-2 shows the set of commands to set the CLASSPATH.

    Example 56-2 Example of Setting CLASSPATH

    setenv CLASSPATH $ADE_VIEW_ROOT/fmwtools/BUILD_HOME/oracle_common/modules/oracle.nlsrtl_11.1.0/orai18n.jar:
    $ADE_VIEW_ROOT/fmwtools/BUILD_HOME/oracle_common/modules/oracle.xdk_11.1.0/xmlparserv2.jar:
    $ADE_VIEW_ROOT/fmwtools/BUILD_HOME/wlserver_10.3/server/ext/jdbc/oracle/11g/ojdbc6.jar:
    $ADE_VIEW_ROOT/fmwtools/BUILD_HOME/oracle_common/modules/oracle.odl_11.1.1/ojdl.jar:
    $ADE_VIEW_ROOT/fmwtools/BUILD_HOME/oracle_common/modules/oracle.odl_11.1.1/ojdl2.jar:
    $MW_HOME/jdeveloper/jdev/extensions/oracle.apps.fnd.applxdf.jar
    

The JDeveloper installation directory could potentially change with newer versions of JDeveloper being available. Check the JDeveloper installation directory to make sure that it exists. You could also use the XML parser and JDBC driver that comes with the database. Note that so far XDF has been tested with the same JAR files with which it has been compiled. It should not be a problem setting the CLASSPATH with a higher version of these JAR files and testing them. If you encounter any issues, try using 11g JDBC and xmlparsers.

56.2.9.3 Using Bootstrap Mode

Bootstrap mode for XDF Schema deployment is available using the parameter xdf_mode=bootstrap. XDF currently depends on several database components, such as pl/sql and tables, for it to work completely in all modes. The bootstrap mode can be used to make sure that the XDF database dependencies are set up correctly and to avoid any manual steps to get XDF working on a particular database.

In bootstrap mode, the mandatory parameter xdf_file_name becomes optional and only the remaining mandatory parameters are applicable.

To run XDF in bootstrap mode, use the command shown in Example 56-3.

Example 56-3 Sample of Running XDF in Bootstrap Mode

$JDEV_JAVA_HOME/bin/java oracle.apps.fnd.applxdf.comp.XdfSchemaDeploy owner_un=fusion apps_un=fusion jdbc_protocol=thin jdbc_db_addr={jdbc tns info}  xdf_file_name="dummy" xdf_mode=bootstrap runtime_schema=<runtime schema name>

56.2.9.4 Deployment FAQ

Examining these frequently-asked questions about deployment will help you prevent and fix problems.

To add a not-null column to an existing table with data, or change a null column to a not-null column:

There are two options to add a not-null column to an existing table with data, or change a null column to a not-null column.

  • Option 1

    • Adding a not null column to an existing table with data

      Product teams can specify an RDBMS default value for the column which will be used by the databases to successfully alter the table to add the not-null column.

    • Modifying a null column to not-null in a table with data

      Product teams can specify an RDBMS default value for the column. This default value will be used by schema deployment utility to update the existing null rows with that value before changing the column to not null.

  • Option 2

    If a product team does not want to use a RDBMS default value, it can add or modify a column as a not-null column to an existing table by using a script having a more complex logic. The column needs to exist in the target database before the script is run. The script cannot enforce the not-null constraint because it is against the standards to have DDL in scripts.

    To use a script to populate the column, the UDP named runTwice must be set to Yes. This UDP will be used by XDF to ensure that the required patch metadata is present in XDF to run it twice in a patch. In the first run, the script will not error out if it is not able to enforce the not-null constraint, but it will error out in the second run if it still is not able to enforce the not-null constraint.

    If the user does not set this UDP, the default behavior of the deployment utility is to error out if it is not able to enforce the not-null constraint while adding or modifying the column.

To remove a table, column or view:

See Section 56.2.9.5.3, "How to Use fnd_cleanup_pkg and fnd_drop_obsolete_objects."

To rename a table, column or view:

Deployment does not support renaming a table, column or view. The workaround that can be used is to make the object obsolete and introduce a new renamed object. The development team must separately handle data migration and update information in the Automatic Diagnostic Repository (ADR), if required.

To implement a non-additive change to the data type of a column, such as varchar2 to number:

Developers can create a script that runs before deployment of the object to rename or drop the column, based on whether or not data needs to be preserved or migrated. Once the deployment successfully adds the column with the correct data type, another script may be needed to make sure that data is migrated and that the renamed column is dropped. This is applicable only if the initial script renames the column.

To add or change the unique constraints or indexes on a populated table:

If the populated table does not meet the criteria for creating unique constraint or unique index, to remove the invalid data create a script to clean the table before deploying a unique index or constraint.

56.2.9.5 Cleaning Database Objects

To maintain efficiency, database objects should be cleaned of no-longer-used data. As part of that process, it is important to keep the FND data dictionary synchronized with existing objects (it can be table, sequence or view) in the database. The XDF team provides packages to make this process easier.

56.2.9.5.1 Making a Database Object Obsolete

Use this information to correctly make a database object obsolete. It is applicable after the release of the initial version of the product to customers.

Modeling database schema for new releases or upgrades to new releases may involve making certain database objects or certain attributes of the database object, such as Columns, obsolete. Doing this may make a significant effect to existing customizations or extensions currently implemented on the system. Making obsolete database objects that contain data, such as Tables, requires particularly close analysis for potential effects. Development teams should take the necessary steps to review and understand the implications of such updates in these areas.

Making obsolete certain database objects or certain attributes of a database object may require those objects to be dropped as part of clean up. Considering any existing customization or extensions to such objects, the act of making obsolete and dropping the object should be kept separate. Dropping the obsolete database objects or columns should be an optional step that is invoked at the demand of customers. The Patching (AD) utilities will provide such an option as a post-patching step.

Follow these steps to make obsolete a database object or attribute.

  1. Set Status User Defined Property for the specific database objects or attributes to Obsolete. This can be done using User Defined Properties for Applications specific metadata that is part of the offline database model.

  2. Status User Defined Property will be captured in the Applications/XDF data dictionary as part of deploying XDF to the database.

These steps ensure that:

  • If the table does not already exist in the database, the Applications schema deployment utilities (XDF) will create the table without columns marked as obsolete.

  • If the column does not already exist in the table, the Applications schema deployment utilities (XDF) will not add the column to the table.

  • If the column already exists in the table, the Applications schema deployment utilities (XDF) will remove any NOT NULL, PK/FK constraints on the column.

  • Any indexes that comprise only the obsolete columns could be dropped. In other cases, the development team owning the obsolete objects will be expected to update the definition of any affected indexes.

56.2.9.5.2 How to Use the Force Mode Option in Schema Deployment

During the initial development of the product before release, product teams may not want to mark the object as obsolete and may prefer directly dropping the object; that is, removing the definition from the offline database file. To support this, the force_mode=y parameter can be passed to the schema deployment tool. The additional input parameter which, when specified, will drop any additional column, index or constraints that are present in a target database and not present in the offline object file definition. The XDF dictionary metadata stored for the object is also updated to be synchronized with the new definition. Note that this option, in certain cases, will not change the definition of the table to exactly match the definition in the file. For example, if the database does not allow some changes, such as changing of certain column datatype, or changing an unpartitioned table to a partitioned table, force mode will not override the database.

Force mode only handles the removal of column, index and constraints, and synchronizing the corresponding definition in the XDF dictionary. If the primary object, such as a table, sequence or view, is dropped, the fnd_cleanup_pkg needs to be used to synchronize the XDF dictionary.

56.2.9.5.3 How to Use fnd_cleanup_pkg and fnd_drop_obsolete_objects

Use fnd_cleanup_pkg and fnd_drop_obsolete_objects to clean a database.

Using fnd_cleanup_pkg

Procedure fndcleawHnup(name): Remove table, sequence, or view with name that is in fnd_tables, fnd_views or fnd_sequences tables, but not in the database. All the required XDF dictionary tables will be updated when fnd_tables, fnd_views, or fnd_sequences is updated.

name: Optional. This can be a table name, a view name or a sequence name. If a name is provided, the procedure will clean only the named object and related components. If it is not defined, the fndcleanup procedure removes all table, view, or sequences that are in fnd_tables, fnd_views, or fnd_sequence tables, but that do not exist in the database.

Procedure clean_fndcons(tbname): Remove the tbname table's Primary Key (PK), Unique Keys (UKs), and Foreign Keys (FKs) that are not in the database from the fnd constraint dictionary tables. The tbname parameter is optional. If it is not specified, then all tables' PK, UKs, and FKs that are not in the database will be removed from the fnd constraint tables.

Procedure TableFndCleanUp(tbname, deleteType, delname): Remove the specified deleteType with the specified delname on the specified tbname table from related fnd tables. The delname parameter is optional. If it is not specified, all table properties on that deleteType will be removed from the specified table. The deleteType includes column, index, pkuk, and fk.

Examples

  • Remove all table, view, or sequence information in fnd_tables, fnd_views, or fnd_sequences tables, but not in the database. All the required XDF dictionary tables will be updated when fnd_tables, fnd_views, or fnd_sequences is updated.

    execute fnd_cleanup_pkg.fndcleanup

  • Remove table1 from the fnd_tables table if table1 is not in the database. All required XDF dictionary tables will be updated when fnd_tables is updated.

    execute fnd_cleanup_pkg.fndcleanup('table1')

  • Remove view1 from the fnd_views table if view1 is not in the database.

    execute fnd_cleanup_pkg.fndcleanup('view1')

  • Remove all table names LIKE HZ% in fnd_tables or fnd_views tables that do not exist in the database.

    execute fnd_cleanup_pkg.fndcleanup('HZ%')

  • Remove table XF1's PK, UKs, and FKs that are not in the database, from the fnd constraint dictionary tables.

    exec fnd_cleanup_pkg.clean_fndcons('XF1');

  • Remove a Foreign Key named XF2_T1_FK on table XF2 from the fnd constraint dictionary tables. XF2_T1_FK may or may not be in the database.

    exec fnd_cleanup_pkg.tablefndcleanup('XF2', 'fk', 'XF2_T1_FK');

fnd_drop_obsolete_objects

Procedure drop_object(objectname): Drop obsolete objectname from the database. This procedure is used to delete obsolete views, tables and columns that are marked as Obsolete in the table.

Examples

  • Drop Table table1 from the database if it is marked as obsolete. If table1 is not obsolete, drop any columns in table1 that are obsolete.

    execute fnd_drop_obsolete_objects.drop_object(table1)

  • Drop View view1 from the database if it is marked as obsolete.

    execute fnd_drop_obsolete_objects.drop_object(view1)

  • Verify all tables and views with name like 'HZ_%" for dropping tables and views, or drop columns if the tables are not obsolete.

    execute fnd_drop_obsolete_objects.drop_object('HZ_%')

56.2.9.5.4 Frequently Asked Questions

Use this information when dropping an object in the database.

  • How do I make an object obsolete?

    1. Select the object in JDeveloper.

    2. Right-click and select Properties > User Properties.

    3. Change the Status to Obsolete.

  • What happens when you deploy an obsolete object or an object that has obsolete columns or indexes?

    Only the FND dictionary is updated. Objects in the database are not dropped.

  • How do I remove an object from the database and keep the FND data dictionary synchronized?

    There are three ways this can be done. SQL scripts can be used to achieve the same outcome.

    • If the object is not a primary object and is a column, index or constraint that is being dropped:

      • Use JDeveloper to remove the definition of these secondary objects from the offline database file definition.

      • Use the force_mode optional parameter to deploy the object to the target database.

    • If the object is a primary object, such as a table, sequence or view:

      • Drop the object obj from sqlplus.

      • Execute this command from sqlplus:

        execute fnd_cleanup_pkg.fndcleanup(' obj')

    • Change the object obj status UDP to Obsolete from JDeveloper. Deploy the object to the database either by command line (XdfSchemaDeploy) or use Generate Fusion Applications Objects from JDeveloper.

      • Execute this command from sqlplus:

        execute fnd_drop_obsolete_objects.drop_object(' obj')

      • Execute this command from sqlplus:

        execute fnd_cleanup_pkg.fndcleanup(' obj')

  • How do I clean up the FND data dictionary if many objects are no longer in the database?

    Execute this command from sqlplus or use a SQL script.

    execute fnd_cleanup_pkg.fndcleanup

  • How do I clean up the FND data dictionary if I had deleted columns and indexes from table, but did not cleanup from the FND data dictionary.

    Execute this command from sqlplus or use a SQL script.

    execute fnd_cleanup_pkg.fndcleanup

  • How do I remove obsolete columns/indexes in objects from FND data?

    Execute this command from sqlplus.

    execute fnd_cleanup_pkg.fndcleanup

  • How do I remove all table/view/sequence name LIKE HZ% in fnd_tables/fnd_views/fnd_sequences tables that do not exist in the database?

    Execute this command from sqlplus.

    execute fnd_cleanup_pkg.fndcleanup('HZ%')

  • How do I drop table/view/sequence name xyz in fnd_tables/fnd_views/fnd_sequences tables from the database if it is marked as obsolete?

    Execute this command from sqlplus.

    execute fnd_drop_obsolete_objects.drop_object('xyz')

  • How do I drop table/view/sequence name LIKE HZ% in fnd_tables/fnd_views/fnd_sequences tables from the database if it is marked as obsolete?

    Execute this command from sqlplus.

    execute fnd_drop_obsolete_objects.drop_object('HZ%')

56.3 Using Schema Separation to Provide Grants

The application runtime schema could be different from the database object owning schema for security reasons. To support this model as part of schema deployment, there is a mechanism to granularly provide grants on various database objects. These are granted to a set of fixed roles which are eventually available to runtime schema.

Privilege will be granted on the database object to the role based on privilege User defined properties defined for the object. Table 56-10, Table 56-11, Table 56-12, and Table 56-13 present the user defined properties that will be defined for each object type.

Table 56-10 Table Object Type Properties

UDP NameDescriptionValues

Insert Allowed

Grant Insert Privilege on the table to the required role

Y/N Default Y

Update Allowed

Grant Update Privilege on the table to the required role

Y/N Default Y

Delete Allowed

Grant Delete Privilege on the table to the required role

Y/N Default Y

Select Allowed

Grant Select Privilege on the table to the required role

Y/N Default Y

Truncate Allowed

The value of this UDP indicates whether a TRUNCATE statement is allowed on the table

Y/N Default Y

Maintain Partition

The value of this UDP indicates whether partitions can be maintained on the table. The ADM_DDL program when handling requests for dynamic DDL operations uses this information.

Y/N Default Y

Exchange Partitions

The value of this UDP indicates whether it is possible to exchange partitions on the table. The ADM_DDL program when handling requests for dynamic DDL operations uses this information.

Y/N Default Y

Maintain Index

The value of this UDP indicates whether it is possible to maintain indexes on the table. The ADM_DDL program when handling requests for dynamic DDL operations uses this information.

Y/N Default Y


Table 56-11 View Object Type Properties

UDP NameDescriptionValues

Insert Allowed

Grant Insert Privilege on the view to the required role

Y/N Default Y

Update Allowed

Grant Update Privilege on the view to the required role

Y/N Default Y

Delete Allowed

Grant Delete Privilege on the view to the required role

Y/N Default Y

Select Allowed

Grant Select Privilege on the view to the required role

Y/N Default Y


Table 56-12 Sequence Object Type Properties

UDP NameDescriptionValues

Select Allowed

Grant Select Privilege on the sequence to the required role

Y/N Default Y

Reset Sequence

The value of this UDP indicates if the sequence can be reset to a specific value. The ADM_DDL program when handling requests for dynamic DDL operations uses this information.

Y/N Default Y


Table 56-13 Materialized Views Object Type Properties

UDP NameDescriptionValues

Select Allowed

Grant Select Privilege on the materialized view to the required role

Y/N Default Y


PK}MHwPK BOEBPS/sec_gs.htm Getting Started with Security

46 Getting Started with Security

This chapter describes the components that developers use to secure Oracle Fusion applications and web services by enforcing authentication and authorization.

This chapter includes the following sections:

46.1 Introduction to Securing Oracle Fusion Applications

Oracle Fusion Applications security consists of two main components, namely authentication and authorization. Authentication establishes the identity of the user. Authorization ensures that users only have access to resources to which they have been granted access.

When developing an Oracle Fusion application, it is necessary to ensure that authentication and authorization polices are properly enforced throughout the application. The implementation details may vary depending on the technology used in the application.

For complete details about the Oracle Fusion security approach, including concepts and best practices, see the Oracle Fusion Applications Security Guide.

Additionally, for information about security and extending Oracle Fusion applications, see the Oracle Fusion Applications Extensibility Guide.

46.1.1 Architecture

Oracle Fusion applications are built on top of a fixed set of internal and third-party technologies. This set of technologies defines what may be used to develop, build, package, and run all Oracle Fusion applications. Each technology and component may have its own specific requirements for security implementation.

Figure 46-1 depicts the components in the Oracle Fusion Applications security approach.

Figure 46-1 Oracle Fusion Security Architecture

Oracle Fusion Applications Security architecture

The Oracle Fusion Applications key technologies and features include:

Some of the technologies have an additional layer of security on top of the main security technologies.

46.1.1.1 Oracle Platform Security Services (OPSS) Security Framework

OPSS security framework provides security to Oracle Fusion Middleware, including Oracle WebLogic Server, Oracle SOA Suite applications, Oracle WebCenter Portal, Oracle ADF applications, and Oracle Entitlements Server. OPSS is designed to be portable to third-party application servers. Developers can therefore use OPSS as the single security framework for both Oracle and third-party environments, thus decreasing application development, administration, and maintenance costs.

OPSS comprises Oracle WebLogic Server security and Oracle Fusion Middleware security. Figure 46-2 illustrates the layered architecture that combines these two security frameworks.

Figure 46-2 Oracle Platform Security Services Architecture

OPSS architecture

Figure 46-2 depicts the various security components as layers. The uppermost layer includes the Oracle WebLogic Server and the Java applications running on the server; under it, is the layer consisting of APIs for Authentication, Authorization, Credential Store Framework, User and Role, and identity virtualization; the bottom layer includes the Security Service Provider Interface (SSPI) layer and the service providers. The bottom layer interacts with security data repositories, such as LDAP and database servers.

In addition to the list of providers shown in Figure 46-2, other providers include the role mapping and audit providers.

For more information about OPSS, see the "Understanding Security Concepts" part in the Oracle Fusion Middleware Application Security Guide.

The Security Service Provider Interface (SSPI) layer is accessed through OPSS APIs and provides Java EE container security in permission-based (JACC) mode and in resource-based (non-JACC) mode. It also provides resource-based authorization for the environment, thus allowing customers to choose their security model.

46.1.1.2 Oracle Web Services Manager

Oracle Web Services Manager (Oracle WSM) provides a policy framework to consistently secure Web services. Application developers attach policies using JDeveloper to the clients and services. Authentication and authorization are enforced on the services by Oracle WSM based on the policies attached to the service. The policies determine how the client and service communicate. For the predefined policies the naming convention indicates the behavior of the policy.

For example, given a policy called:

oracle/wss11_saml_token_with_message_protection_client_policy

  • oracle is the path of the policy,

  • ws11 indicates the Web services standard,

  • saml_token is the authentication token,

  • with_message_protection indicates whether message protection is enabled,

  • client_policy indicates the type of policy, server or client.

For more information about Oracle WSM, see Oracle Fusion Middleware Security and Administrator's Guide for Web Services.

How Policies are Executed

When a request is made from a service consumer (also known as a client) to a service provider (also known as a Web service), the request is intercepted by one or more policy interceptors. These interceptors execute policies that are attached to the client and to the Web service. There are five types of interceptors (reliable messaging, management, WS-Addressing, security, and MTOM) that together form a policy interceptor chain. Each interceptor executes policies of the same type. The security interceptor intercepts and executes security policies, the MTOM interceptor intercepts and executes MTOM policies, and so on.

Policies attached to a client or Web service are executed in a specific order via the Policy Interceptor Pipeline, as shown in Figure 46-3.

Figure 46-3 Policy Interceptors Acting on Messages Between a Client and Web Service

Policy interceptor pipeline.

When the interceptor encounters a policy that deals with authentication or authorization, it delegates the task to OPSS. If the authentication using OPSS is successful, a security subject with the identity is established. Similarly, processing continues only if the authorization using OPSS for the established identity is successful.

46.1.1.3 Oracle ADF Security

Oracle ADF security framework is the provider of authentication and authorization services to Oracle Fusion Applications. Oracle ADF security is built on top of OPSS architecture, and provides declarative, permissions-based protection for ADF bounded task flows and top-level web pages that use ADF bindings.

Oracle ADF security and Oracle JDeveloper provide the tools to interact with the file-based identity and policy store, as well as the architecture to enforce the security definitions on the secured resources.

For more information about ADF Security, see the "Enabling ADF Security in a Fusion Web Application" chapter in the Oracle Fusion Middleware Fusion Developer's Guide for Oracle Application Development Framework (Oracle Fusion Applications Edition).

46.1.1.4 Application User Sessions

Application user sessions allow applications to store the security and application context for Oracle Fusion Applications. Session attributes contain common information such as the current user and the user's associated roles, current language, date and number formatting, as well as application-specific attributes.

A session is created after the security subject has been established. In the context of Oracle ADF, a session is created using a filter, while a context is created in Oracle SOA Suite using an interceptor. When a session is created, information about the user's associated roles are stored in the session.

Oracle Fusion Data Security relies on the security context in the session when deciding whether a user is allowed to access particular data. If the session is not established, the user cannot access any secured data.

Application user sessions are associated with pillars and, ideally, there should be only one session per pillar. In the case of web services, if the client and server are on the same pillar then they share the same session. Subsequently, session context is specific to a particular pillar. That is, everything running on that same pillar should see the same context.

For details about application user sessions, see Chapter 47, "Implementing Application User Sessions."

46.1.1.5 Oracle Fusion Data Security

Oracle Fusion Data Security implementation is a solution specifically for Oracle Fusion Applications. The security definitions for who can access what data are stored in the Oracle Fusion Data Security model in the Oracle Fusion Applications schema. Developers create these definitions through SQL scripts, APIs or UIs. The definitions are then extracted and version controlled as seed data.

Oracle Fusion Data Security definitions are enforced either declaratively or programmatically in their application. In the context of an Oracle Fusion application, developers can do the following:

  • Declaratively enforce security on the entity object level,

  • Declaratively enforce security on the view object level through view criteria,

  • Programmatically apply security view criteria,

  • Programmatically call APIs to check whether a user is authorized to access data or obtain a predicate used to retrieve the data the user is authorized to access.

The data security implementation relies on the security context defined in the application user session. Even if OPSS authenticates the user and the security subject is established, the user cannot access any data unless the application user session is established.

For details about Oracle Fusion Data Security, see Chapter 48, "Implementing Oracle Fusion Data Security."

46.1.1.6 Oracle Virtual Private Database

Oracle Virtual Private Database (VPD) enables controlling access to data on the database level using security policies associated with database objects. Use VPD when securing Personally Identifiable Information (PII) on the database level, for example.

For more information about VPD, see the "Using Oracle Virtual Private Database to Control Data Access" chapter in the Oracle Database Security Guide.

46.1.1.7 Oracle Data Integrator

Oracle Data Integrator (ODI) is used to move and transform data among systems using specific features for authentication and authorization. Authentication is based on Oracle Platform Security Services (OPSS). Following authentication, processing specific to ODI occurs in which OPSS principals are mapped to definitions stored in ODI to determine identity access rights. The security definitions controlling authorization decisions are stored in an ODI master repository.

For more information about ODI, see the "Understanding Oracle Data Integrator" part in the Oracle Fusion Middleware Developer's Guide for Oracle Data Integrator.

46.1.2 Authentication

Oracle Fusion applications reside in containers that automatically handle authentication. The container intercepts all requests entering the system, and ensures that users are properly authenticated and the security context propagated.

Invoking the ADF Security wizard when developing an application configures the application to enforce security at runtime.

When a request is received with no subject defined, Oracle Platform Security Services creates a subject containing the anonymous user principal and the anonymous role role principal. Oracle Platform Security Services is configured by the JPSFilter. With this security subject, unauthenticated users can access public resources. When accessing secure resources, the adfAuthentication servlet forces users to authenticate. The security configuration determines the login module to be used for authentication.

By default, Oracle WebLogic Server is the authenticator used when developing applications with Oracle ADF. Different configurations can also be used, such as an Oracle Single Sign-On solution.

46.1.2.1 Oracle Identity Management Repository

Oracle Identity Management Repository stores users, enterprise roles and their relationships. During development the identities exist in two places; the jazn-data.xml file in Oracle JDeveloper and the embedded LDAP of JDeveloper's Integrated WebLogic Server. In staging environments, these definitions reside in LDAP on standalone Oracle WebLogic Server.

46.1.2.1.1 Users

Test users created during development within Oracle JDeveloper enable testing applications in development. These test users are not migrated with the completed application. Rather, they are for testing purposes only. Enterprise users are added by a system administrator who defines users/groups in the enterprise identity store.

46.1.2.1.2 Roles

Users are not assigned permissions directly, rather access is assigned to roles. Roles group particular permissions required to accomplish a task; instead of assigning individual permissions, roles match users with the permissions required to complete their particular task.

There are two main types of roles, enterprise and application. Oracle Identity Management Repository contains enterprise roles that are available across applications. These are created as groups in LDAP, making them available across applications. Application roles are stored in the application-specific policy store.

Functional roles include job, duty, data, abstract and privilege roles. Role are enforced by a role hierarchy. In Oracle Identity Management Repository, these logical roles are translated into technical Oracle Platform Security Services roles.

46.1.2.1.3 Segregation of Duties

Segregation of Duties (SOD) ensures that no single individual has control over two or more phases of a business transaction or operation. The goal of segregation of duties is to prevent information misuse such that the same user cannot both create and approve transactions.

Oracle Applications Access Controls Governor (AACG) is used to manage, remediate and enforce user access policies. AACG ensures effective segregation of duties at the implementation site.

46.1.2.1.4 File-Based Identity Store

The data in the file-based identity store (jazn-data.xml file) is used when authenticating within Oracle JDeveloper running Integrated WebLogic Server. The identity data in the jazn-data.xml file should not be synchronized with the identities in the LDAP staging server. By default, the deployment configuration disables data synchronization between the jazn-data.xml file and the LDAP server. This setting should not be modified.

46.1.2.1.5 File-Based Policy Store

The data in the file-based security policy store (jazn-data.xml file) is used when authorizing within Oracle JDeveloper running Integrated WebLogic Server. Changes to the security policies in the jazn-data.xml file must be migrated to the LDAP staging server by a security administrator. By default, the deployment configuration disables data synchronization between the jazn-data.xml file and the LDAP server. This setting should not be modified.

46.1.2.1.6 ODI

ODI has its own concept of identities such as ODI role and stores in the ODI schema. For authentication, OPSS is used and the OPSS principals are mapped to the ODI identities.

46.1.2.2 Identity Propagation

Identity propagation is a fundamental requirement for securing Oracle Fusion Applications. It provides that the same user identity is visible across different processes and technologies boundaries. While there some cases where the identity is implicitly propagated, in several scenarios explicit configuration is required.

Web Services and SOA

In the case of Web services and SOA applications, you can propagate identities by attaching Oracle Web Services Manager policies to the client and service. When a client sends a request to a service, a policy interceptor intercepts the request. On the client side, the policy interceptor packages the identity to be transported according to the policy attached to the client. On the service side, the interceptor processes the request based on the policy and delegates authentication to Oracle Platform Security Services. If the authentication succeeds, a security subject with the identity is established.

Remote Method Invocation (RMI)

The executing user is automatically propagated when using RMI. If a different identity than the executing user needs to be propagated, it has to be explicitly passed through Java Naming and Directory Interface (JNDI) context.

Oracle WebCenter Portal

Oracle Fusion applications deploy Web Services for Remote Portlets (WSRP). As web services, they rely on Oracle Web Services Manager for Identity Propagation.

Oracle Data Integrator (ODI)

In a OPSS-enabled environment (Oracle Platform Security Services), ODI authentication happens in two phases.

Figure 46-4 depicts the first phase is OPSS authentication, during which time a subject is created using the OPSS framework. The second phase is the ODI authentication itself, which is based on the previously created subject. ODI lists the ODI roles having one or more OPSS principals of the subject as members. Users will need to choose one ODI role from here. ODI will then create an ODI security token based on this role. This ODI security token contains an ODI role and the list of principals associated with the current OPSS subject.

Figure 46-4 ODI Authentication

ODI authentication architecture

Audit Identity

When switching to the application identity, in order to preserve the submitting identity for auditing purposes, you must propagate the identity to be audited.

Auditing is based on who columns, which are populated with session data. When the session is established, it is initialized using the current identity. The session APIs expose a method to manipulate the identity to be used for auditing. This method allows teams to control which identity is stored as the audit identity. Example 46-1 illustrates the syntax of this method.

Example 46-1 Controlling which Identity Is Stored as the Audit Identity

ApplSession.setHistoryOverrideUserName()

The session is not propagated, rather only the identity is propagated. As the session is initialized using the identity, any application specific values are lost. To prevent this, you must pass the audit identity and override the audit identity on the session.

It is recommended for the service provider to add an extra parameter to the service so as to store the original user ID (historyOverrideUserName, of type String). In order to invoke the service, the service method consumer must fill in the original user ID as part of the payload. Within the service, the value passed is populated on the session as shown in Example 46-2.

Example 46-2 Storing the Original Identity

ApplSession session = ApplSessionUtil.getSession();
if (session != null)    
session.setHistoryOverrideUserName(historyOverrideUserName);

46.1.2.3 Application User Session Propagation

Application user sessions are associated with pillars and, ideally, there should be only one session per pillar. In the case of web services, if the client and server are on the same pillar then they share the same session. Subsequently, session context is specific to a particular pillar. That is, everything running on that same pillar should see the same context.

46.1.3 Authorization

Authorization ensures that users only have access to the resources to which they have been granted access. Authorization decisions are based on policies stored in a policy store. There are two main types of policy stores: OPSS application security repository and Oracle Fusion Data Security repository. The OPSS repository contains the security definitions that control access to applications. The Oracle Fusion Data Security repository contains the security definitions controlling data access.

46.1.3.1 OPSS Application Security Repository

The enterprise security administrator exports the OPSS application security repository to the jazn-data.xml file policy store. The security definitions in these repositories control access to application functions. The policies defined in the jazn-data.xml file are used during development. For testing and implementation, the file-based policy store content is migrated into LDAP.

Policy Store Content

Enterprise security administrators are responsible for managing application security policies. Oracle Fusion Applications developers can add new application security policies, but must not modify existing application security policies.

Roles

The jazn-data.xml file identity store contains the application roles specific to a given application. These roles are not visible outside the application. The policies are created against an application role. Permissions are grouped into a permission sets for administrative purposes. And permission sets are granted to the application roles. Developers must not allowed to modify role hierarchy or remove privileges defined by the permission sets granted to existing application roles.

Design Time

During development, you can interact with the jazn-data.xml file policy store using the tools and user interfaces provided in Oracle JDeveloper.

For more information, see the "Enabling ADF Security in a Fusion Web Application" chapter in Oracle Fusion Middleware Fusion Developer's Guide for Oracle Application Development Framework (Oracle Fusion Applications Edition).

Runtime

When Oracle ADF security is enabled in an application, the Web container uses the policies in OPSS application policy store for authorization. Oracle ADF security enforcement logic checks whether the user, represented by the JAAS subject, has the correct permissions to access the resource.

The subjec3?t contains the user's principals, which include a user principal with the user's name and list of role principals, as well as enterprise roles and application roles obtained from the policy and identity stores. The principal is created to represent all of the user's memberships in application roles defined in the policy store. In turn, each application role may have multiple granted permissions in OPSS application policy store.

At runtime, the page context determines whether the current user has view permissions for the page being accessed. If the page includes an activity of a bounded task flow, the task flow controller determines the permissions. If the page is a top-level page with an associated page definition file, the Oracle ADF model determines the permissions for the page.

The OPSS service provider interface checks whether the subject includes the roles with the relevant permissions required to access the page. If the user is authorized to access the page, then the task flow is initiated. If the user is not authorized, ADF Controller throws an exception and passes control to an exception handler specified by the task flow configuration.

It is also possible to include an API that checks whether the current user has access to a resource.

Developer created additions to the policy store must be migrated to LDAP by a security administrator.

46.1.3.2 Oracle Fusion Data Security Repository

Oracle Fusion Data Security repository is used to control access to data.

Policy Store Content

Enterprise security administrators are responsible for managing data security policies. Oracle Fusion Applications developers can add new data security policies, but must not modify existing data security policies.

For more information about Oracle Fusion Data Security, see Chapter 48, "Implementing Oracle Fusion Data Security."

Design Time

During development, developers can interact with the Oracle Fusion Data Security repository through the Oracle Authorization Policy Manager.

Runtime

Data security relies on session information for the user identity. When a user session is created at runtime, the user information for that session and the flattened list of roles for the user are propagated to the database. This information is used to identify the user and the user's access level based on the policies in Oracle Fusion Data Security repository.

Data security is not automatically enforced, rather developers must enforce data security either declaratively on the entity object or view object, or programmatically, using API calls.

46.2 Authentication Techniques and Best Practices

There are some cases in which you must implement authentication from an external source or using a different identity. You can implement authentication using APIs, Expression Language or a non-browser based login.

46.2.1 APIs

You can implement authentication by using user and role APIs. For more information, see the "Developing with the User and Role API" chapter in the Oracle Fusion Middleware Application Security Guide.

You can use the security subject APIs to run an application under an identity different from the current user.

46.2.2 Expression Language

You can use Expression Language to access security context information. Some useful expressions are as follows:

  • securityContext.userName

  • securityContext.authenticated

  • securityContext.userInRole

  • securityContext.userInAllRoles

  • securityContext.userGrantedPermission

  • securityContext.userGrantedResource

  • securityContext.taskflowViewable

  • securityContext.regionViewable

Note that decisions about user's access rights should not rely on the user's role information since role definitions may be changed. Instead access should be based on available permissions.

For more information, see the "Enabling ADF Security in a Fusion Web Application" chapter in the Oracle Fusion Middleware Fusion Developer's Guide for Oracle Application Development Framework (Oracle Fusion Applications Edition).

46.2.3 Non-browser Based Login

For information about using non-browser based security, see the "Securing Your Integrated Excel Workbook" chapter in the Oracle Fusion Middleware Desktop Integration Developer's Guide for Oracle Application Development Framework.

46.3 Authorization Techniques and Best Practices

Authorization is implemented using function security policies that control access to application functions. At the most fundamental level, authorization is based on standard JAAS (Java Authentication and Authorization Services) permissions and OPSS permission sets (also called entitlements) which may be granted to secure specific application artifacts. Oracle ADF defines the JAAS permissions needed to secure certain Oracle ADF application artifacts, including ADF bounded task flows and, in the case of top-level web pages, ADF page definitions files.

46.3.1 Function Security

Security is automatically enforced on all ADF bounded task flows and top-level web pages that use ADF bindings and are not contained in a bounded task flow.

Security is not automatically enforced on web service methods. You can use API calls to define permissions in the policy store and enforce security based on these permissions.

Implementing function security requires the following main steps:

  1. Consult a security administrator to export all predefined function security policies of the application that you are customizing into a jazn-data.xml file.

  2. Copy the exported jazn-data.xml file into the application workspace.

  3. Create an entitlement to group one or more ADF resources and their corresponding actions to entitle end users to access the resource.

  4. Grant the entitlement to a custom duty role that was added to the Oracle Fusion application policy store.

  5. Enable ADF Security for the application by running the Configure ADF Security wizard.

After running the ADF Security wizard, any web page associated with a bounded ADF task flow will be protected. Therefore before running the application and testing security, developers must first create security policies that grant end users access.

For more information, see Chapter 49, "Implementing Function Security."

46.3.1.1 Resource Entitlements and Permissions

In general, the JAAS permission determines the allowed operations that the end user may perform on the application resource. However, from the standpoint of Oracle Fusion Applications, end users typically need to interact with multiple resources to complete the duties designated by their provisioned roles. To simplify the task of creating function security policies, developers work with entitlement grants (defined as OPSS permission sets) to grant privileges for a variety of securable resources, including ADF task flows, web services, and SOA work flows to a role.

Developers use the Oracle JDeveloper to create the entitlements (with one or more resource-action pairs) and then grant one or more entitlements to the desired application roles (the grantee).

For details about creating entitlement-based security policies, see Chapter 49, "Implementing Function Security."

Task flow, page definition, and web service resource permissions are tightly coupled with code artifacts. These permissions are assumed to be associated with concrete code artifacts. In some circumstances, permissions are required, but no code artifacts exist with which the permissions could be associated. For example, suppose the same page is used to view and update tasks. The same code artifact is used for both actions such that one cannot control access to both view and update tasks separately. Resource permissions enable creating abstract permissions which can be referred to with API calls.

For details about resource permissions and using APIs, see the "Understanding Security Concepts" part in the Oracle Fusion Middleware Application Security Guide.

46.3.1.2 Expression Language

You can use Expression Language to access security context information. Following are some useful expressions:

  • securityContext.taskflowViewable

  • securityContext.regionViewable

  • securityContext.userGrantedPermission

For more information, see the "Enabling ADF Security in a Fusion Web Application" chapter in the Oracle Fusion Middleware Fusion Developer's Guide for Oracle Application Development Framework (Oracle Fusion Applications Edition).

46.3.2 Data Security

Implementing data security requires the following main steps:

  1. Use Oracle Authorization Policy Manager to create security definitions based on the Oracle Fusion Data Security model. This step is common, regardless of the technology being used.

  2. Refer to these security definitions from the code artifacts. This step varies depending on the technology used, as well as the functional requirements of the application.

For more information about implementing Oracle Fusion Data Security, see Chapter 48, "Implementing Oracle Fusion Data Security."

For more information about using Oracle Authorization Policy Manager, see the Oracle Fusion Middleware Oracle Authorization Policy Manager Administrator's Guide (Oracle Fusion Applications Edition).

46.3.2.1 APIs and Expression Language

For information about using APIs and Expression Language to secure data, see Chapter 48, "Implementing Oracle Fusion Data Security."

46.3.2.2 Oracle Virtual Private Database

Oracle Virtual Private Database (VPD) enables creating security policies to control database access at the row and column level. Access is controlled at the database level. VPD adds a dynamic WHERE clause to a SQL statement issued against an object to which an VPD security policy has been applied.

VPD can be useful for enforcing security when a development team must enforce security at the database level. Using VPD affects performance. As such, make sure to evaluate your performance requirements prior to implementing the VPD solution.

For more information regarding VPD implementation, see the "Using Oracle Virtual Private Database to Control Data Access" chapter in the Oracle Database Security Guide.

46.3.2.3 Personally Identifiable Information

PII (Personally Identifiable Information) is any information that can be used to uniquely identify a person. This information is considered sensitive and must be protected from misuse for the purposes of legal regulation, financial liability and personal reputation. For example, only authorized users should be allowed access to the social security numbers of people stored in a system. PII authorization is only implemented on data identified by the PII working group in the data privacy Oracle Fusion uptake document.

PII authorization is implemented using one or more of the following technologies:

  • Encryption and decryption APIs

  • Oracle Fusion Data Security

  • Row level Oracle Virtual Private Database

The security requirements for the PII attribute determine the technologies to be used.

46.3.2.4 Data Role Templates

Installations of Oracle Fusion Applications may require a large number of roles that must be provisioned. For data security purposes, it is often necessary to create the roles as the data security rules are not known at design time.

For more information regarding data role templates, see the "Data Security" chapter in the Oracle Fusion Applications Security Guide.

PK =3PK BOEBPS/ui_impl_uishell_addl.htm Implementing Additional Functions in the UI Shell

15 Implementing Additional Functions in the UI Shell

This chapter discusses additional functions, such as the Navigate API and how to implement the Home Page UI, that are included in the UI Shell page template used to build web pages.

This chapter includes the following sections:

For more information about the features, see:

15.1 Introducing the Navigate API

You can create a link in the task flow to open a different UI Shell page. Because navigation can occur across different web applications, a single consistent API performs browser redirect. See Table 15-1. This API is exposed as the FndUIShellController.navigate Data Control method.


Note:

When opening 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.


15.1.1 How to Use the Navigate API Data Control Method

Drag and drop the Data Control method on page fragments to create links to start navigation.

  1. Expand the Data Controls and select the navigate item, as shown in Figure 15-1.

    Figure 15-1 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 15-2 is displayed so you can choose one of the options.

    Figure 15-2 Selecting a Navigate Option from the Applications Context Menu

    Selecting a Nav Option from the Applications Context Menu

You can specify a task flow to load on the target page. Page level parameters also can be specified.

Table 15-1 Navigate API Parameters

Navigate API ParameterAttribute Name

viewId

navigateViewId

webApp

Attribute used to look up the host and port of the associated Workarea or Dashboard from the Oracle Fusion Applications Functional Core (ASK) deployment tables. These tables are populated at deployment time through Oracle Fusion Functional Setup Manager tasks.

You need to pass the deployed module name to the webApp parameter.

requestContextPath

Obsolete. Replaced by webApp.

pageParametersList

navigateParamsList

navTaskFlowId

Equates to the openMainTask taskFlowId parameter.

This is the 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

navTaskKeyList

Equates to the openMainTask keyList parameter.

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

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

The navTaskKeyList parameter has been implemented for the following FndUIShellController data control methods:

  • openMainTask

  • discloseRegionalTask

  • collapseRegionalTask

  • navigate

  • openSubTask

In dynamic tabs mode, when looking for a match of an 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 navTaskKeyList values, such that the existing task flow will be picked only if its navTaskKeyList values match the ones specified in the navTaskKeyList 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 reuse a tab only if you pass in a null keyList.

navTaskParametersList

You 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

Equates to the openMainTask label parameter.

Note: When passing parameters, do not leave the navTaskLabel 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 13.2.3.4, "Supporting No-Tab Work Areas"), 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.


Certain parameters, summarized in Table 15-2, can be passed using the Navigate API's argument list.

Table 15-2 Parameters Passed Using Navigate API Arguments

Parameter NamePassed UsingDescription

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 13.2.3.4, "Supporting No-Tab Work Areas"), 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 15-1.

Example 15-1 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 must 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 open.

  • viewId determines the view activity within the target web application.

pageParametersList defines custom URL parameters that you 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 15-2 shows how to set up these two parameters.

Example 15-2 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 does not need to 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 Oracle Fusion Applications Functional Core (ASK) deployment tables. These tables are populated at deployment time through Functional Setup Manager 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.


15.1.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, you 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 runtime 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 you are trying to open.

15.2 Warning of Pending Changes in the UI Shell

When there are pending changes in the UI Shell Main Area, and the user is leaving the page, or is refreshing the tab or task flow, 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 Oracle Application Development Framework. But, from the search results page, drilling down to a sub flow and making the flow dirty marks the sub flow as a candidate for warn about changes.

15.2.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 15-3.

    Example 15-3 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 15-4.

    Example 15-4 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 15-5 to their main page fragment's pageDef whose taskflow is attached to the tab in MainArea.

    Example 15-5 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 15-5 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.

15.2.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 15-6.

Example 15-6 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>

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

15.3.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 Java EE web applications. A given home page can be hosted on any one of these distinct Java EE web applications. A tab click on a given home page therefore must 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.

15.3.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 13.5, "Working with the Global Menu Model."

  7. When running a home page JSPX, the page should look similar to Figure 15-3.

Figure 15-3 Home Page Example

Home Page example

15.3.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 15-7.

    Example 15-7 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 15-8, 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 15-8 Example Use of getURLForCurrentTask

    public java.lang.String getURLForCurrentTask( )
    throws  java.io.IOException
    

15.4 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 15-4.

Figure 15-4 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.

15.4.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 15-9, has been added to adfc-config.xml for viewScope Hashmap.

Example 15-9 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 the Oracle Fusion Middleware Fusion Developer's Guide for Oracle Application Development Framework (Oracle Fusion Applications Edition).

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.

15.4.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 the Oracle Fusion Middleware Fusion Developer's Guide for Oracle Application Development Framework (Oracle Fusion Applications Edition).

Example 15-10 shows a sample entry in adfc-config.xml for such a view activity.

Example 15-10 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 15-11 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 15-11 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 Area and Main Area, can access this in pageFlowScope (of a Main Area or Regional Area container task flow owned by Applications Core) for the appropriate input parameters through the menu model and openMainTask API.

Example 15-12 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 15-12 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.

15.5 Implementing the Third-Party Component Area

The Third-Party Component Area, shown in Figure 15-5, 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 15-5 Third Party Component Area Facet Containing A CTI

Third Party Facet Containing a CTI

15.5.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 reference 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 13-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.

15.6 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 15-6 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 15-7 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 15-8 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 is displayed, select the Applications Core library and click OK.

    Figure 15-9 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 13.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 is displayed, 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 15-13.

    Example 15-13 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 15-14.

    Example 15-14 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" chapt:(er of the Oracle Fusion Middleware Fusion Developer's Guide for Oracle Application Development Framework (Oracle Fusion Applications Edition).

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.

15.7 Troubleshooting UI Shell Issues

This section presents the more-common problems, with their solutions, that may be experienced by Oracle Fusion applications developers. Also see the Oracle Fusion Applications Administrator's Troubleshooting Guide and "Troubleshooting Customizations" in the Oracle Fusion Applications Extensibility Guide.

15.7.1 ApplSession Is Not Created

Problem

When ApplSession is not created, these problems occur:

  • User Language settings are not set.

  • Data security policies are not applied.

  • Webservice requests are run as anonymous users instead of named users.

Solution

To resolve this problem:

  • Check that the JpsFilter section is correct in web.xml: Applcore Session code depends on the JPS subject. The entry must appear exactly as shown in Example 15-15.

  • Check that the ApplSessionFilter section is correct in web.xml: ApplSession must be configured immediately after JpsFilter. The entry must appear exactly as shown in Example 15-15.

    Example 15-15 ApplSessionFilter and JpsFilter Configuration in web.xml

    <filter-mapping>
        <filter-name>JpsFilter</filter-name>
        <url-pattern>/*</url-pattern>
        <dispatcher>FORWARD</dispatcher>
        <dispatcher>REQUEST</dispatcher>
        <dispatcher>INCLUDE</dispatcher>
    </filter-mapping>
    <filter-mapping>
        <filter-name>ApplSessionFilter</filter-name>
        <servlet-name>Faces Servlet</servlet-name>
        <dispatcher>FORWARD</dispatcher>
        <dispatcher>REQUEST</dispatcher>
    </filter-mapping>
    
  • If the issue is with the ApplSession not being created over a web service request using SOA, check how the ApplSession context interceptor is configured.

    ApplSession information is preserved over SOA/Web Service requests through the use of context interceptors that fire when requests are sent and received. The ApplSessionContext interceptor, in particular, will handle propagating all session attributes from the caller to the web service, and will even attempt to reuse the same session ID if running against the same database. To enable the context interceptor, the weblogic-application.xml on both the caller and the called should include the oracle.applcore.config shared library:

    <library-ref>
        <library-name>
          oracle.applcore.config
        </library-name>
      </library-ref>
    

    If the context interceptor has not been enabled, the prepareSession() of the root application module call should still be able to create the session as the right user, so long as the Subject has been established correctly in the Oracle Web Services Manager layer. But in that case, no other session attributes will be propagated, and the session cannot be reused.

  • Obtain the session ID from the cookie. The cookie is located in the browser's cookies folder.

    The session cookie is obtained so that subsequent queries can be run to verify the session's existence and obtain additional info about the session. Note that it is the session cookie that is stored in the browser cookie location, not the session ID. They represent the same session, but the actual session ID is internal.

    Cookie name: ORA_FND_SESSION_<db_instance_name>

    The session cookie value will appear similar to: DEFAULT_PILLAR:wvlu8CUiH4FYjySCPQtwaEphBOyiUTZwexYd1fYXh5VwV9i9koUL8L3Qhm0bNrZ8:1282160020177

    To retrieve the actual session id, run this SQL statement: select session_id from fnd_sessions where session_cookie=value_obtained_from_cookie_value.

    Note: The value_obtained_from_cookie_value is the alpha-numeric string between the two colons. In the example, it is wvlu8CUiH4FYjySCPQtwaEphBOyiUTZwexYd1fYXh5VwV9i9koUL8L3Qhm0bNrZ8. This value will always be different.

15.7.2 Navigator Shows a Little White Box

Problem

Clicking the Navigator in the global area shows a little white box.

This is an issue that developers would see.

Solution when in a production environment

  • Make sure that you are signed in as a user that has access to some pages in the Navigator menu. You can type the full URL of the page directly into the browser and see if the user can access it.

  • Make sure there is a valid connection to the LDAP server. This is needed to check the policies of each entry in the Navigator menu.

  • Use Enterprise Manager to make sure the Applications are registered in the topology tables.

  • Make sure the Applications Core Setup application is deployed. (From JDeveloper, run .../atgpf/applcore/applications/FndSetup/FndSetup.jws.) This contains the Navigator menu file and usually is deployed to the Oracle Fusion Applications Global domain.

  • Check that the menus are in MDS. Check for entries with the path oracle/apps/menu.

Solution when in a development environment

  • You usually should run without menu security. The first thing to check is if you have started your web server with this parameter to turn off security checking:

    -DAPPLCORE_TEST_SECURED_MENU=N

  • Then check steps 3 through 5 in the solution for a production environment.

15.7.3 Navigator Shows Unfiltered Entries

Problem

The Navigator menu is showing all entries, rather than being filtered by what the user has access to, and the Welcome page has all tabs exposed.

Solution

This is caused by menu security being turned off. This should happen only in development environments.

Because menu security is on by default, check that the web server was not started with -DAPPLCORE_TEST_SECURED_MENU=N.

15.7.4 Other Navigation Issues

Problem

Customizers and developers may encounter a URL that is not working.

Solution

Make sure the URL does not end with ".jspx."

Problem

A message such as "webApp <value> not defined" is displayed. This means the application is not listed in the topology tables.

Solution

Check that the application is registered.

PKՏI(:(PK BOEBPS/flex_key.htm Using Key Flexfields

24 Using Key Flexfields

This chapter discusses how to use key flexfields in Oracle Fusion applications to access data that is presented by different customers using different combinations of fields, and to customize the presentation of that information to customers in a way that is most appropriate for them. This chapter also discusses how to take advantage of key flexfield secondary usages, code-combination filters, and other advanced features.

This chapter includes the following sections:

24.1 Introduction to Key Flexfields

A key flexfield is a key that is composed of segments, in which one or more segments may have a meaning. The key, or code, uniquely identifies an object such as an account, an asset, a part, or a job, that implementors can configure to validate any way they wish. The definition of a key flexfield provides a list of possible combinations of key flexfield segment values, known as code combinations. Each type of code combination is called a structure. Each structure is identified by a string that is called the structure code. Much like the context values in descriptive flexfields, a key flexfield structure code indicates how database columns are organized to store the code combinations.

24.1.1 Benefits of Key Flexfields

Key flexfields provide a way for Oracle Fusion applications to represent objects such as accounting codes, part numbers, or job descriptions, which combine multiple fields (or segments) into a single object of concatenated segments.

Most customers use codes made up of meaningful segments to identify various business objects. For example, a customer might have a part number "PAD-NR-YEL-8 1/2x14" indicating a notepad, narrow-ruled, yellow, and 14 inches by 8 1/2. Key flexfields enable developers of Oracle Fusion applications to provide customers with flexible code data structures that implementors can set up however they like using key flexfield segments. Key flexfields enable an implementor to customize Oracle Fusion applications to show a customer's codes any way they want them. For example, a different customer might have a different code for the same notepad, such as "8x14-PD-Y-NR", and the implementor can easily customize Oracle Fusion applications to meet that different need. Key flexfields let developers satisfy different customers without having to reprogram the applications.

You can use key flexfields in many applications. For example, you could use a Part flexfield in an inventory application to uniquely identify parts. Your Part flexfield could contain such segments as product class, product code, size, color and packaging code. You could define valid values for the color segment, for example, to range from 01 to 10, where 01 means red, 02 means blue, and so on. You could even specify cross-validation rules to describe valid combinations of segment values. For example, products with a specific product code may be available only in certain colors.

24.1.2 How Key Flexfields Are Modeled in Oracle Application Development Framework

Flexfields are modeled as a collection of Oracle Application Development Framework (Oracle ADF) polymorphic view rows, as described in the "Working with Polymorphic View Rows" section in the Oracle Fusion Middleware Fusion Developer's Guide for Oracle Application Development Framework (Oracle Fusion Applications Edition).

In a polymorphic collection, each view row can have its own set of attributes, and all rows have at least one common attribute, the discriminator. The discriminator determines which view row type should be used. Given a collection of polymorphic view rows, each row can be a different type. When a polymorphic collection of rows is created, Oracle ADF selects the correctly-typed view definition for the row to be added based on the value of the discriminator attribute.

Key flexfield segments are exposed as view row attributes in the order that they are defined in the flexfield's metadata. The code combination ID (CCID) and structure instance number (SIN) segments are exposed as attributes in the base view object of the polymorphic collection. Every code combination structure is modeled as an extended view object of the base view object. That is, an extended view object is created for every structure instance number. These extended view objects, which are referred to as subtype view objects, expose the key flexfield segments as subtype-specific view attributes. The structure instance number is exposed as the discriminator attribute of the polymorphic view rows. For more information about code combination IDs and structure instance numbers, see Section 24.2.1.1, "Creating the Combinations Table."

You use the Create Entity Objects wizard to generate the base view object that is based on the key flexfield definition, then create a view link to connect the reference view object (the view object for the database table that the key flexfield extends) and the base view object. You can then use the base view object to add the flexfield to a user interface page. For more information about the generation of base and subtype view objects, see Section 24.2.4, "How to Create Key Flexfield Business Components."

Because flexfield view objects are modeled as polymorphic view objects, you can use key flexfield view objects in the same manner that you use any other polymorphic view objects, and they will behave in the same way. This includes support for flexfields in ADF Desktop Integration. For more information, see the Oracle Fusion Middleware Desktop Integration Developer's Guide for Oracle Application Development Framework.

24.1.3 Secondary Usage Feature

A key flexfield configuration can be shared with other product tables through the secondary usage feature. To share a key flexfield configuration with another product table, you include one or all of the primary usage segment columns in that product table. The product table that contains the shared segment columns is referred to as a secondary table. When you work with a primary usage you are working in reference mode. When you work with a secondary usage, you are working in secondary mode.


Note:

Secondary usage is sometimes referred to as a partial usage.


There are two types of secondary usages:

  • All-segment secondary usage: In this mode, the secondary table has columns for all of the key flexfield segments.

  • Single-segment secondary usage: In this mode, the secondary table has only one key flexfield segment column.

24.1.4 Participant Roles

As mentioned in Section 21.2, "Participant Roles," this guide uses the owner and implementor roles to clarify and group flexfield development activities.

The flexfield owner is the developer (or development team) who determines that a particular flexfield is needed or would be useful within a particular Oracle Fusion application, and makes a flexfield available. The owner then incorporates the flexfield into an application. With key flexfields, the owner can be either a producer or a consumer, or can assume both roles.

The producer is the developer who determines that a particular key flexfield is needed or would be useful within a particular application, and makes it available. The producer's product owns the combinations table, which supports that flexfield by storing the key flexfield values.

A consumer incorporates a key flexfield into the application, which is typically different from the producer's application. The consumer typically stores a code combination ID (CCID), which identifies a row in the combinations table, in a product table, and works with the structural and seed data and the business components that have been configured by the key flexfield producer.

An implementor configures a flexfield on behalf of the customer by specifying the structure of the flexfield and specifying the prompt, length, and data type of each flexfield segment.

For more information about owners, producers, consumers, and implementors see Section 21.2, "Participant Roles." For information about the combinations table, see Section 24.2.1.1, "Creating the Combinations Table."

24.1.5 Completing the Key Flexfield Development Process

Before you start to incorporate key flexfields into your application, you must determine whether you should complete the producer portion or the consumer portion of the key flexfield development process.

To incorporate key flexfield secondary usages into your application, see Section 24.6, "Completing the Development Tasks for Key Flexfields in Secondary Mode."

To employ key flexfield code-combination filters in your application, see Section 24.7, "Working with Code-Combination Filters for Key Flexfields."

Figure 24-1 provides an overview of producer and consumer roles as they apply to the creation and configuration of the necessary key flexfield business components and associated artifacts. Section 24.1.5.3, "Understanding the Key Flexfield Producer Development Tasks" and Section 24.1.5.4, "Understanding the Key Flexfield Consumer Development Tasks" define the producer phases and summarize the steps for creating the components and artifacts shown in Figure 24-1.

Figure 24-1 Key Flexfield Development Roles, Business Components and Supporting Artifacts

Roles, Business Components and Supporting Artifacts

24.1.5.1 Maintenance Mode and Dynamic Combination Insertion

By default, key flexfield user interface elements do not allow new code combination values entered into the application user interface to be saved. However, you might want to enable the entry of new code combinations in either of the following ways:

  • A code-combination maintenance page enables application implementors and administrators to manage key flexfield code combinations, including the ability to enter new code combinations and update existing code combinations for a flexfield. This is called working in maintenance mode.

  • You can enable end users to enter values on an application page that constitute ad-hoc new code combinations, even if the users are not authorized to perform maintenance tasks directly. This is known as dynamic combination insertion.

    For example, when entering a transaction, an Oracle General Ledger user can enter a new expense account code combination for an account that does not yet exist. Your application creates the new account by inserting the new combination into the combinations table in the background.


    Note:

    If you configure the key flexfield for dynamic combination insertion, you must build a maintenance model and a maintenance application module as described in Section 24.2.4.1, "Building a Writable Maintenance Model," and use the setup APIs to register the maintenance application module in the flexfield metadata. For information about the setup APIs, see Section 24.2.1.5, "Registering and Defining Key Flexfields Using the Setup APIs."


The key flexfield producer builds the appropriate models to support maintenance mode and dynamic combination insertion.

24.1.5.2 Cross-Validation Rules and Custom Validation

When you decide to support maintenance mode or dynamic combination insertion for a key flexfield, you can also implement advanced validation capability for the new code combinations that are entered.

Cross-Validation Rules

Cross-validation rules apply a pair of filters to new code combinations that are proposed for a key flexfield by implementors.

At registration time, you must enable the key flexfield for cross-validation. Then you create a maintenance user interface that administrators of your application can subsequently use to define each cross-validation rule as a pair of code-combination filters: one to establish the condition for evaluating the rule, and the other to specify which code combinations are valid under that condition.

Custom Validation Callouts

There are two PL/SQL custom validation callout procedures that can be defined for a given key flexfield: one for application development use, and one reserved for customers. These callouts can be used to enforce any custom validation logic that you want to apply to new code combinations beyond what has been defined for cross-validation rules.

You define custom validation logic with a standard signature for the customer callout. You then register your callout with the key flexfield. The custom validation callout will automatically be called before any new combination is inserted using dynamic insertion in C and PL/SQL.

24.1.5.3 Understanding the Key Flexfield Producer Development Tasks

If you have determined that a particular key flexfield is needed within an application, and there are not yet columns in the product table to support it, you must define the necessary metadata and provide the appropriate business components so that flexfield consumers can make use of your flexfield.

To complete the producer development tasks:

  1. Develop the key flexfield.

    See Section 24.2.1, "How to Develop Key Flexfields."

    Optionally, you can also do the following at registration time:

  2. Create and configure the key flexfield business components.

    As shown in Figure 24-1, the producer activities occur in two phases. The first phase produces a writable maintenance model, and the second phase produces a read-only reference model:

    • In producer phase 1, you create an updatable entity object for your combinations table and a master view object that is based on the updatable entity object. Next, using the updatable entity object, you create key flexfield business components for a maintenance model and define a view link between the master view object and the key flexfield view objects. Then you create the maintenance application module.

    • In producer phase 2, you optionally configure the maintenance application module to accept dynamic combination insertion calls, and implement the appropriate Java class in the user interface to invoke dynamic insertion. You create a read-only reference entity object for your combinations table, and using this entity object, create key flexfield business components for a reference model.

    See Section 24.2.4, "How to Create Key Flexfield Business Components."


    Tip:

    After completing this task, you can regenerate the flexfield business components programmatically at runtime to update your key flexfield implementation without manual intervention. For more information, see Section 25.4, "Regenerating Flexfield Business Components Programmatically."


  3. Optionally, share your key flexfield business components with other developers using an ADF library.

    For more information, see Section 24.2.5, "How to Share Key Flexfield Business Components."

  4. Optionally, build a user interface for key flexfield maintenance.

    For more information, see Section 24.2.6, "How to Build a Key Flexfield Maintenance User Interface."

  5. Optionally, implement key flexfield advanced features such as code combination constraints or API access to segment labels, or access flexfields from an Excel worksheet using ADF Desktop Integration.

    For more information, see Section 24.5, "Using Key Flexfield Advanced Features in Reference Mode."

  6. Optionally, define, implement, and invoke key flexfield code-combination filters.

    For more information, see Section 24.7, "Working with Code-Combination Filters for Key Flexfields."

24.1.5.4 Understanding the Key Flexfield Consumer Development Tasks

You can incorporate a producer's key flexfields in your own application. For example, you might have an expenses table that references an account key flexfield in the Oracle General Ledger application.

If your product table already has a foreign-key reference to the key flexfield's combinations table, and the flexfield producer who owns that metadata has provided you with the appropriate business components, you can proceed to incorporate the flexfield into your application. You should have already created an entity object and view object for the product table, which is referred to as the reference table.

To complete the consumer development tasks:

  1. As shown in Figure 24-1, create a view link between the view object for the reference table and the polymorphic view objects for the key flexfield's reference model.

    See Section 24.3.1, "How to Create Key Flexfield View Links."

  2. Nest the key flexfield application module instance in the product application module.

    See Section 24.3.2, "How to Nest an Instance of the Key Flexfield Application Module in the Product Application Module."

  3. Add a key flexfield view object instance to the product application module.

    See Section 24.3.3, "How to Add an Instance of a Key Flexfield View Object to the Product Application Module."

  4. Add your key flexfield to an application page.

    See Section 24.4, "Employing Key Flexfield UI Components on a Page."

  5. Configure the key flexfield user interface components.

    See Section 24.4.3, "How to Configure Key Flexfield UI Components."

After completing these tasks, you can define seed or test value sets for the flexfield, and you can create a model that you can use to test the flexfield. For more information, see Section 25.1.2, "How to Test Flexfields."

After you have completed the key flexfield development process and delivered your application, implementors can use the Manage Key Flexfields task flow to define and configure the structures, structure instances, segments, and segment instances for each key flexfield. This will determine how the flexfield's segments will be populated, organized, and made available to end users within the application.

To make the Manage Key Flexfields task flow available to application implementors and administrators, you register it with Oracle Fusion Functional Setup Manager. For more information, see Section 25.5, "Integrating Flexfield Task Flows into Oracle Fusion Functional Setup Manager."

24.2 Completing the Producer Tasks for Key Flexfields

To prepare key flexfields for modeling in Oracle JDeveloper, you must ensure that columns for the flexfields you require are defined in your application database. You also might need to define more advanced features such as key flexfield secondary usages, code-combination filters, or the enabling of cross-validation rules and custom validation callout procedures. All of these features require you to modify your application database.


Note:

To incorporate a key flexfield secondary usage into your application, you must have already defined and registered the key flexfield primary usage on which it is based. See Section 24.2.1.5, "Registering and Defining Key Flexfields Using the Setup APIs," then continue to Section 24.6, "Completing the Development Tasks for Key Flexfields in Secondary Mode."

To employ key flexfield code-combination filters in your application, see Section 24.7, "Working with Code-Combination Filters for Key Flexfields."


The product table and its key flexfield columns must be registered in the Oracle Fusion Middleware Extensions for Applications (Applications Core) data dictionary before a flexfield can be defined on it. For more information, see Chapter 56, "Using the Database Schema Deployment Framework."

Any implementation of flexfields in Oracle Fusion applications typically requires application seed data, which is the essential data to enable flexfields to work properly in applications. Flexfield seed data can be uploaded and extracted using the seed data loader.

After you complete the registration process described in Section 24.2.1, "How to Develop Key Flexfields," your flexfield seed data consists of the information that you registered for your flexfield, such as the tables and columns reserved for your flexfield.

For information about extracting and loading seed data, see Chapter 55, "Initializing Oracle Fusion Application Data Using the Seed Data Loader."

24.2.1 How to Develop Key Flexfields

Key flexfields enable you to represent objects such as accounting codes, part numbers, or job descriptions, that combine multiple columns (or segments) into a single object of concatenated segments.

To develop a key flexfield:

  1. Create a combinations table that includes the key flexfield segments.

  2. Create foreign key columns to associate a product table with the combinations table. The product table is referred to as the reference table.

  3. Optionally, include the key flexfield segments in product tables for secondary usages.

  4. Optionally, create filter columns for defining which key flexfields the user can filter.

  5. Enable the use of flexfield combinations on application pages.

  6. Register and define the key flexfield.

  7. Optionally enable the multiple structure and data set features.

  8. Optionally reuse one or all key flexfield segments in a product table.

  9. Register the entity details for each usage.

24.2.1.1 Creating the Combinations Table

Each key flexfield must have one corresponding table known as the combinations table.


Note:

The product table and its key flexfield columns must be registered in the Applications Core data dictionary before a flexfield can be defined on it. For more information, see Chapter 56, "Using the Database Schema Deployment Framework."


The combinations table must have a code combination ID (CCID) column (type NUMBER) that identifies each data row.

The combinations table can have an optional structure instance number (SIN) column (type NUMBER) with generated values that identify different validation sources for a given structure. These generated values are unique within a given flexfield. Multiple SIN values exist for a key flexfield if you elect to define the flexfield with multiple alternate structure instances.

A given structure (arrangement of segments) can have several structure instances. The structure instances share the same arrangement of segments, but use different value sets to validate the segments (for example, one group of value sets for the United States. and another for France). Each structure instance is identified by a SIN.

The combinations table might also have a data set number (DSN) column (type NUMBER), but only if you have elected to data set-enable your key flexfield code combinations. A DSN column enables you to tag sets of combination codes with your own numeric IDs. For example, you can use it to stripe (partition) the data into subsets by ORGANIZATION_ID. ADF Business Components supports the DSN by including it as part of the table's primary key. Your SQL code can then select code combinations from this table using a more qualified primary key.


Note:

Data sets are used by specific application-development teams. If your team does not use data sets, you can ignore the references to DSNs in this guide.

A DSN is not the same thing as a set ID. Set ID partitioning is not supported by flexfields. For information about set IDs, see Chapter 8, "Managing Reference Data with SetIDs."


The table's primary key is composed of a combination of the CCID, SIN, and DSN columns depending on the conditions listed in Table 24-1.

Table 24-1 Primary Key Configuration

ColumnInclude in the Primary Key

CCID

Always

SIN

When the flexfield is multiple structure-enabled or is multiple structure instance-enabled

DSN

When the flexfield is DSN-enabled


The combinations table must include the columns listed in Table 24-2. These columns indicate whether a combination is enabled and active. The column names and data types must match exactly.

Table 24-2 Required Combinations Table Columns

ColumnData TypeDescription

ENABLED_FLAG

VARCHAR2(1) NOT NULL

A Y value indicates that the combination is enabled. Any other value indicates that the combination is not enabled.

START_DATE_ACTIVE

DATE

If a date is specified and the current validation date is earlier than the specified date, the combination is not active. There must not be a default database value for this column.

END_DATE_ACTIVE

DATE

If a date is specified and the current validation date is later than the specified date, the combination has expired. There must not be a default database value for this column.


Include one column for each flexfield segment that you or your customers might wish to customize. You need at least as many columns as the maximum number of segments an end user would ever want in a single key flexfield structure. The columns must be of type VARCHAR2 or NUMBER. If the type is VARCHAR2, the length must be at least 30 characters.


Tip:

There are no constraints on how to name the segment columns. However, these columns are typically named using the patterns SEGMENTn_VARCHAR2 and SEGMENTn_NUMBER. This convention makes it easy to identify the key flexfield segments. It also makes it easier to name the columns for secondary usages of the key flexfield.


If the key flexfield defines value attributes, you must include one derived value attribute column of type VARCHAR2 for each value attribute. For more information about value attributes, see Section 24.2.2, "How to Implement Key Flexfield Segment Labels."


Note:

The combinations table may contain other columns than those described here. If the key flexfield is dynamic insert-enabled, these other columns should either allow null values or they should have default database values.


24.2.1.2 Creating Foreign Key Columns to Enable the Use of Flexfield Combinations on Application Pages

To permit the use of flexfield code combinations on different application pages, you must include foreign key references to your combinations table's primary key configuration, as shown in Table 24-1, in other product tables. That way, you can display or enter valid combinations using forms that are not based on your combinations table. When you build an application that uses key flexfields, you include foreign key references in the product tables wherever you reference the flexfield. The product tables that contain the foreign key references are referred to as reference tables.


Note:

Pages whose underlying entity objects contain a foreign key reference to the combinations table are referred to as code-combination reference pages, while pages whose underlying entity objects use the combinations table itself are referred to as code-combination maintenance pages.


24.2.1.3 Including Segment Columns in Secondary Tables

You can reuse a key flexfield definition over a product table by including some or all of the key flexfield's segment columns in the product table. The product table that contains the redefined segment columns is referred to as a secondary table. If a SIN or DSN is used, the secondary table must either include those columns or a column from which the SIN or DSN can be derived.

24.2.1.4 Creating Filter Columns

You can use the key flexfield code-combination filter feature to represent a subset of combinations. For each filter that you want to include in the application user interface, you define a dedicated column of type XMLType. You can define the column in an existing reference table or you can create one or more dedicated tables just to store filter columns.

For more information, see Section 24.7, "Working with Code-Combination Filters for Key Flexfields."

24.2.1.5 Registering and Defining Key Flexfields Using the Setup APIs

Before you can use a key flexfield in an application, you must first define and register the flexfield using procedures from the FND_FLEX_KF_SETUP_APIS PL/SQL package. This package also has procedures for updating, deleting, and querying flexfield definitions.

The definition of a key flexfield includes the following information:

  • The code, name, and description of the flexfield.

  • The primary usage code (also referred to as the master usage code). This code is typically the same code as the flexfield.

  • The name of the combinations database table.

  • The names of the database table columns to be used as flexfield segments.

  • The name of the CCID column.

  • The names of the SIN and DSN columns, if they exist.

Before you begin: 

Create the combinations table as described in Section 24.2.1.1, "Creating the Combinations Table."

To learn how to generate documentation about using the procedures in the following steps, see Section 24.2.1.6, "What You May Need to Know About the Key Flexfield Setup API."

To register and define a key flexfield: 

  1. Run the fnd_flex_kf_setup_apis.create_flexfield(...) procedure to register the key flexfield and its primary usage.

  2. Run the fnd_flex_kf_setup_apis.create_segment_column_usage(...) procedure for each segment column to register the segment columns.

  3. (Optionally) Register the entity details as described in Section 24.2.1.9, "Registering Entity Details Using the Setup APIs." This step must be completed before you can generate the flexfield usage's business components.

24.2.1.6 What You May Need to Know About the Key Flexfield Setup API

In the key flexfield development process, you use the FND_FLEX_KF_SETUP_APIS PL/SQL package to manage flexfield registration data.

You can learn about the FND_FLEX_KF_SETUP_APIS PL/SQL package by running the following command, which produces package documentation and usage examples to the <db_name>_<user_name>_FND_FLEX_KF_SETUP_APIS_<date>.plsqldoc file.

sqlplus <fusion_user>/<fusion_pwd>@<fusion_db> \
@/ORACLE/fusionapps/atgpf/applcore/db/sql/flex/fnd_flex_pkg_doc.sql \ 
FND_FLEX_KF_SETUP_APIS 

24.2.1.7 Enabling Multiple Structure, Multiple Structure Instance, and Data Set Features

To enable the multiple structure, multiple structure instance, or data set features for a registered key flexfield, you must run the enable_feature(...) procedure from the FND_FLEX_KF_SETUP_APIS PL/SQL package. To enable the multiple structure feature or multiple structure instance feature, you provide the SIN column name. To enable the data set feature, you provide the DSN column name.

To learn how to generate documentation about using the enable_feature(...) procedure, see Section 24.2.1.6, "What You May Need to Know About the Key Flexfield Setup API."

24.2.1.8 Reusing Key Flexfield Segments in Another Table

Key flexfield secondary usage enables you to capture the values of a key flexfield's segments in a product table. You can capture all of the flexfield's segments, or just one.

For information about reusing a key flexfield's segments, see Section 24.6, "Completing the Development Tasks for Key Flexfields in Secondary Mode."

24.2.1.9 Registering Entity Details Using the Setup APIs

When you build the flexfield business components and create flexfield-specific application module instances, the flexfield modeler requires the following information about the flexfield usage:

  • The full class name of the entity object. For the primary usage, this is the entity object that was defined for the combinations table. For a secondary usage, this is the entity object that was defined for the secondary table.

  • A prefix from which to derive the names of generated objects.

  • The package in which to place the generated business components. Each usage can have its own package name.

You register entity details using the create_adfbc_usage(...) procedure from the FND_FLEX_KF_SETUP_APIS PL/SQL package.

Before you begin: 

  1. Register the usage as described in Section 24.2.1.5, "Registering and Defining Key Flexfields Using the Setup APIs."

  2. Ensure that the entity object for the usage's table exists.

To learn how to generate documentation about using the create_adfbc_usage(...) procedure, see Section 24.2.1.6, "What You May Need to Know About the Key Flexfield Setup API."

To register the entity details using the registration application: 

  • Run the fnd_flex_kf_setup_apis.create_adfbc_usage(...) procedure to register the entity object, package name, and object name prefix for the flexfield usage.

24.2.2 How to Implement Key Flexfield Segment Labels

A segment label identifies the purpose of a particular segment in a key flexfield.

Usually an application needs some method of identifying a particular segment for some application purpose such as security or computations. However, because a key flexfield can be customized so that segments appear in any order with any prompts, the application needs a mechanism other than the segment name or order to use for segment identification. Segment labels serve this purpose.

You can think of a segment label as an identification tag for a segment. It identifies a segment that application implementors and administrators should include when customizing the key flexfield. By defining segment labels when you define your key flexfield, you ensure that implementors customize the flexfield to include the segments that your application needs.

For example, the Oracle General Ledger application needs to be able to identify which segment in the Accounting flexfield contains the primary balance information and which segment contains natural account information. Because you can customize the Accounting flexfield so segments appear in any order with any prompts, Oracle General Ledger needs a segment label to internally specify the correct segment for each purpose. When you define your Accounting flexfield, you must specify which segment labels apply to which segments.

You ensure that the implementor or administrator will define these key segments by defining two segment labels, GL_BALANCING and GL_ACCOUNT. When customizing your accounting flexfield, the implementor ties the GL_BALANCING and GL_ACCOUNT segment labels to particular key segments. As the developer, you need not know which key segment becomes the natural account or primary balance segment, because the key flexfield takes care of returning natural account and primary balance information to your application at runtime.

Oracle General Ledger also uses key flexfields that have segment labels identifying the cost center segment (FA_COST_CTR), management segment (GL_MANAGEMENT), and intercompany segment (GL_INTERCOMPANY). Other applications, such as Human Resources, use segment labels as well. Human Resources uses segment labels to control who has access to confidential information in its flexfield segments.

When you use segment labels with a key flexfield, you might also need to define value attributes in which you qualify a value by applying a value attribute to it when the value set is used with a segment that has a segment label.


Note:

For information about retrieving segment label information, see Section 24.5.2, "How to Access Segment Labels Using the Java API."


24.2.2.1 Defining Key Flexfield Segment Labels

You should define and register segment labels if you want to ensure that the application implementor or administrator customizes your key flexfield to include the segments that your application needs. For example, Oracle General Ledger defines account and balancing segment labels in the Accounting flexfield to ensure that implementors define the account and balancing segments.

When you register a key flexfield, you can define segment labels for it.

Segment labels can be unique, required, or global. You specify a segment label as unique if you want the implementor to tie it to at most one segment of the flexfield. You specify a segment label as required if you want the implementor to tie it to at least one segment. You specify a segment label as global if you want it to apply to all segments. Any key flexfield segment can have any number of segment labels applied.

Table 24-3 shows the results of setting these flags on a segment label in various combinations.

Table 24-3 Segment Label Flag Combinations

Global FlagRequired FlagUnique FlagResult
N
N
N

0+ (Zero or more segments)

N
N
Y

0,1 (Zero or one segment)

N
Y
N

1+ (One or more segments)

N
Y
Y

1 (Exactly one segment)

Y
-
-

ALL (All segments; global flag overrides the other flags.)


For example, in the Oracle General Ledger Accounting flexfield, the Account segment label is required and unique because Oracle General Ledger requires one and only one account segment.

You create segment labels using the create_segment_label(...) procedure from the FND_FLEX_KF_SETUP_APIS PL/SQL package.

Before you begin: 

Define the key flexfield as described in Section 24.2.1.5, "Registering and Defining Key Flexfields Using the Setup APIs."

To learn how to generate documentation about using the create_segment_label(...)procedure, see Section 24.2.1.6, "What You May Need to Know About the Key Flexfield Setup API."

To define key flexfield segment labels: 

  • Run the fnd_flex_kf_setup_apis.create_segment_label(...) procedure to register the label and label code for the key flexfield.

24.2.2.2 Using Value Attributes

When you use segment labels with a key flexfield, you might also need to define value attributes.

Every value in a value set has accompanying properties that provide supplemental information about the value, such as a description, an internal code, and start and end dates. In addition to these standard properties, you can further qualify a value by applying a value attribute to it when the value set is used with a segment that has a segment label. There are three types of value attributes:

  • Flexfield value attributes: The FND_VS_VALUES_B table contains 20 available value attribute columns, called FLEX_VALUE_ATTRIBUTE1 through FLEX_VALUE_ATTRIBUTE20, which are globally defined across all Oracle Fusion applications.

  • Custom value attributes: The FND_VS_VALUES_B table also contains 10 additional value attribute columns, called CUSTOM_VALUE_ATTRIBUTE1 through CUSTOM_VALUE_ATTRIBUTE10. Customers cannot modify or reassign the standard value attribute columns, but they can use these custom columns for their own implementations of value attributes.

  • SUMMARY_FLAG: This is a predefined system value attribute, for use with the GL# key flexfield only.

Create value attributes using a procedure from the FND_FLEX_KF_SETUP_APIS PL/SQL package.

Before you begin: 

  1. Define the key flexfield as described in Section 24.2.1.5, "Registering and Defining Key Flexfields Using the Setup APIs."

  2. Define the segment label as described in Section 24.2.2.1, "Defining Key Flexf