Oracle® Fusion Applications Developer's Guide 11g Release 5 (11.1.5) Part Number E15524-10 |
|
|
PDF · Mobi · ePub |
This chapter describes the Fusion Middleware extensions for Oracle Applications base classes that extend the features of standard ADF Business Components classes.
The chapter includes the following sections:
Fusion Middleware extensions for Oracle Applications base classes provide additional features that are not part of the standard ADF Business Components core entity objects, view objects, and application modules.
The Fusion Middleware extensions support the following standard Oracle Applications features:
TL (translatable) table
WHO column
PL/SQL entity
FND services
Unique ID
Data security
Document sequencing
The base classes extend ADF Business Components Entity, EntityDef, ViewObject, ViewRow, and ApplicationModule implementation classes.
The base classes provided by Fusion Middleware extensions are the following:
OAApplicationModuleImpl
OAEntityImpl
OAEntityDefImpl
OAViewObjectImpl
OAViewRowImpl
OAViewCriteriaAdapter
They are found in oracle.apps.fnd.applcore.oaext.model.package
and extend the JBO classes with the same name (but without the OA prefix) in oracle.jbo.server.package
.
In Oracle JDeveloper, selecting the Oracle Fusion Applications Developer role automatically sets the Fusion Middleware extensions for Oracle Applications base classes as the default classes for ADF Business Components objects. The base classes become available when you add the Applications Core library. For more information, see Chapter 2, "Setting Up Your Development Environment."
Multi-language support (MLS) gives Oracle the ability to ship its products in multiple languages by setting standards and guidelines for translation.
In JDeveloper, multi-language entities are those that maintain one or more translated attributes and require the storage of all relevant translations of these attributes. Such entities have a base table that has attributes that are not translated and do not vary by language (such as codes and IDs) and a TL table that has, in addition to the base table primary key, the translatable attributes for that entity (such as Display Name, and Application Name). Figure 9-1 illustrates this concept.
For each row in the base table, there will be as many rows in the translation table as there are installed languages. The translation table's primary key is made up of the foreign key to the base table and a language column, which may be viewed as a foreign key to the FND_LANGUAGES table.
The translation table is fully populated. This means that rows for all installed languages are inserted even if the actual translations for these languages are not yet available. The logic, which maintains multi-language entities, is responsible for ensuring that the translation rows are inserted, updated, or deleted as required to meet the "fully populated" requirement. Translations, which have not been supplied, must be defaulted from one of the available translations. As updates occur to supply missing translations, the default values will be converted to true translations.
Since applications are run in a single language for any given user session, a convenient view is provided for the multi-language entities, which joins the base table and translation table and filters translations to the runtime language. This is the Multi-language View. This view uses the userenv ('LANG') expression to select the correct translation based on the session language, which usually comes from the NLS_LANG environment variable.
The following extensions support TL tables:
OAEntityImpl
OAViewRowImpl
As a developer, you can use multi-language extensions to deal with only one entity that contains both translatable and non-translatable attributes, instead of having to deal with two entities, one for the base table and one for the translation table.
Whenever an entity is created, the extensions ensure that the TL entities are also created for every installed language in the environment.
Whenever an insert is made into the base table or the table is updated, the same operations must also be performed on the corresponding TL table. Behind the scenes, the extensions override the appropriate ADF Business Components methods, such as create()
and setAttribute()
, to ensure that the TL table is populated correctly.
The extensions also enable you to work with only one ADF Business Components entity object at runtime for a multi-language database entity, and shield you from the two underlying tables (base and multi-language) that hold the data. You will see no inherent difference between a multi-language entity and a standard one. In addition, the extensions allow you to define an entity as multi-language in a JDeveloper design time environment, and provide any additional metadata for such that entity.
In addition, the following utility APIs are provided in OAEntityImpl
:
public boolean isTranslatable ()
- Returns true if this entity is a translatable entity.
public boolean isTranslated ()
- Returns true if there is at least one translated language other than the base language for this entity.
public String [] getTranslatedLanguages ()
- Returns an array of Language codes for which actual translations exist. The list always returns the base language as one of the translated languages. A record is considered translated if the LANGUAGE and SOURCE_LANG columns are equal.
The same set of APIs also will be provided on the AViewRowImpl
object, since it also would have the same characteristics of a row.
Creating a multi-language ADF Business Components entity object consists of four tasks:
Task 3, "Associate the _VL view and _TL table entity objects"
Task 4, "Create a view object that uses a translatable entity"
To create an entity object for translatable (_TL) tables, perform the following procedure.
Note:
This procedure does not apply to a _VL view. For information about creating an entity object for a _VL view, see Task 2, "Create an entity object for a base table".
Name the entity <Entity>TranslationEO.
For example, for a table named FND_ITEMS_DEMO_TL, you can name the entity ItemsDemoTranslationEO.
Include all of the table's attributes.
Make sure the attribute for the LANGUAGE
column is named Language, and the attribute for the SOURCE_LANG
column is named SourceLang.
If your TL table columns for LANGUAGE
and SOURCE_LANG
are named differently, it is important that you still name the attributes Language and SourceLang.
Identify the table's primary keys, including the LANGUAGE
column.
Verify that this extends OAEntityImpl
like any other entity object.
Add whatever validation logic you need for this entity and its attributes.
The translatable values are unlikely to need any special validation.
Overriding the default attribute behavior:
By default, all the attributes in the _TL table will be considered translatable if they are:
not a primary key attribute
not an entity accessor
one of the following types: VARCHAR, CHAR, FIXED_CHAR, LONGVARCHAR, CLOB
Note:
SourceLang and Language are special attributes and are handled by Oracle Fusion Middleware Extensions for Applications.
To create an entity object for a base table, perform the following procedure.
Name the entity object.
Use the regular entity object naming convention. For example, for the FND_ITEMS_DEMO table, the corresponding entity would be named ItemsDemoEO. The entity should be based on the _VL view.
Include all columns except the RowId
pseudo-column in the view.
Identify your primary keys as you normally would.
Set the entity-level Oracle Fusion Middleware Extensions for Applications schema-based ADF Business Components property named fnd:OA_BASE_TABLE with a value that names the true base table of your translatable entity.
For example, for the FND_ITEMS_DEMO_VL view, this value would be set to FND_ITEMS_DEMO_B.
You could use the entity Property Inspector to set this property, as shown in Figure 9-2.
Oracle Fusion Middleware Extensions for Applications automatically overrides the entity's doDML()
method to ensure that all inserts, updates, and deletes are actually performed on the base table identified by this property. All reads will be done against the _VL view.
To create the association between the _VL view and _TL table entity objects, perform the following procedure.
Follow the standard association object naming convention that describes the entity relationships. For example, ItemsToTranslation.
In the Structure window, choose the entity object. In this case, it is ItemsToTranslation.
In the Overview window, choose the Relationship option.
Designate the association as a Composition Association with a 1:* cardinality, as shown in Figure 9-3.
When you select Composition Association, be sure to uncheck Implement Cascade Delete and Cascade Update Key Attributes if they are selected.
Select the base entity as the source and the _TL entity as the destination.
Since the Applications Core OAEntityImpl
class overrides the remove()
method on the EntityImpl
class to handle Translation rows deletion, Cascade Delete is not required.
Configure Source Accessor and Destination Accessor, as shown in Figure 9-4.
Note:
Ensure that the Source Accessor has been created prior to performing Step 6.
When creating the view objects that will access your translatable tables, keep in mind the following:
Always use the base entity object created for the _VL view. For example, ItemsDemoEO.
Do not use the _Translation entity object ItemsDemoTranslationEO directly. For the purpose of any code that needs to access your translatable entity, you should treat the base entity object as the only entity object. Coordination between the base and Translation entities is handled automatically and the Translation entity should remain "invisible". Otherwise, you can treat your base entity object like any other entity object.
For a _TL table with no corresponding _B table:
There may be a rare case where you have a _TL table and _VL view and no _B table, because all of the attributes are translatable. If this occurs, do the following:
Define the base entity on the database view _VL.
Set the Applications Core schema-based property fnd:OA_BASE_TABLE to be the _VL view name.
Override doDML()
for the base entity to do nothing. This is going to be a virtual entity that does not have an underlying database table.
Create the translation entity object and the composite association between the base entity and the translation entity as you would in the regular scenario.
The Translation EO in this scenario alone must also include the non-translatable attributes because the base entity's doDML()
does nothing. If the translation entity does not include non-translatable attributes, you might get exceptions saying the attribute is not populated
Mark all the non-translatable columns in the _TL entity, i.e., non-string fields and non-primary keys, as explicitly translatable by setting OA Translatable to true
in the Applications section of the Property Inspector, as shown in Figure 9-5.
By default, only string fields (VARCHAR2 and its variants) are identified as translatable automatically by the parent. Primary key changes on the entity are also handled automatically by the framework. This means any numeric, date, or other data type attributes that are not primary key need to have the OA Translatable property set explicitly to true
.
There is a slight downside to this approach as non-translatable columns (like numbers and dates), technically, are being marked as translatable. However, this approach is required in order to ensure attributes set on the base entity are propagated to the TL entity; otherwise, you will get an "attribute not populated" exception. This is needed because the base entity is virtual and the doDML()
method on the base entity is empty.
The WHO feature reports information about who created or updated rows in Oracle Applications tables. Oracle Applications upgrade technology relies on WHO information to detect and preserve customizations. ADF Business Components provides the ability to track the creation of an entity or the changes made to one.
The OAEntityImpl
populates the WHO columns automatically. In addition to the standard history columns supported by ADF Business Components, the extension provides support for Last Update Login field.
All WHO columns are updated based on the current User Session. Table 9-1 lists the WHO columns and their descriptions.
Table 9-1 WHO Column Summary
Column Name | Type | Null? | Description |
---|---|---|---|
CREATED_BY |
VARCHAR2(64) |
NOT NULL |
Keeps track of which user created each row. |
CREATION_DATE |
DATE |
NOT NULL |
Stores the date on which each row was created. |
LAST_UPDATED_BY |
VARCHAR2(64) |
NOT NULL |
Keeps track of who last updated each row. |
LAST_UPDATE_DATE |
DATE |
NOT NULL |
Stores the date on which each row was last updated. |
LAST_UPDATE_LOGIN |
VARCHAR2(32) |
Stores the Session ID of the user who last updated the row. |
In order for Oracle Fusion Middleware Extensions for Applications to populate your WHO columns automatically, ensure that your WHO column attributes are of the appropriate History Column type by using the Entity Attribute Wizard, as shown in Figure 9-6.
In the example entity, the WHO column LastUpdateDate is identified as a modified on
History Column type.
Similarly, identify the following attributes as indicated:
LastUpdatedBy - modified by
CreationDate - created on
CreatedBy - created by
Ensure that the LAST_UPDATE_DATE and CREATION_DATE WHO columns have the Type as Timestamp (java.sql.Timestamp), as shown in Figure 9-7.
WHO column features provide the following design time and runtime support:
The extension supports the LAST_UPDATE_LOGIN column and ensures that the other columns are populated correctly.
The LAST_UPDATED_BY and CREATED_BY columns are populated with a value based on the user name, and not with the user GUID, a user ID, or a session ID. To obtain the value to populate these columns in PL/SQL, use FND_GLOBAL.WHO_USER_NAME. In Java, the CreatedBy and LastUpdatedBy attributes will normally be populated automatically with the correct value by the base classes, or you can also obtain the value from OAEntityImpl.getWhoUser()
.
History is provided for the Session ID of the user who last updated the row.
Proper shaping in the Oracle Fusion Applications Developer role to make this history available.
PL/SQL entities are those that depend on PL/SQL packages to handle their Data Manipulation Language (DML) operations (insert, delete, update, and lock). Since Oracle Applications has a large amount of their business logic in PL/SQL and a lot of teams still use it, they need a mechanism that will allow them to use their PL/SQL code when building ADF Business Components entities. The Fusion Middleware extensions provide the following:
A way to identify a PL/SQL entity using a custom property
TL table support and the ability to override the appropriate DML operation
In addition, the following APIs are provided in the OAEntityImpl
class to facilitate the insert, update, and delete DML operations in PL/SQL:
protected void insertRow ();
protected void updateRow ();
protected void deleteRow ();
The default implementations of these methods delegate to super.doDML (operation)
, which will result in SQL insert/update/delete being called for the entity.
A PL/SQL-based entity object provides an object representation of the data from a table or view and routes the DML operations to stored procedures in the database.
To identify an entity as a PL/SQL one, a custom attribute, OA_PLSQL_ENTITY
, must be set to Y
(Yes). This allows the framework to identify this entity as PL/SQL based.
To identify an entity as a PL/SQL one:
From the Applications window, choose an entity object.
In the Structure window, highlight the entity object.
From the Property Inspector tab, choose the Applications option.
Under PL/SQL, select Y
from the OA PLSQL Entity dropdown menu, as shown in Figure 9-8.
Override the following methods for its DML operations and provide JDBC calls when applicable:
void insertRow();
void updateRow();
void deleteRow();
Use the PL/SQL entity objects only if you have legacy PL/SQL code that maintains all your transactions and validations. If you are working on a new product and/or do not have a lot of PL/SQL legacy code, Applications Core recommends the use of Java entity objects over PL/SQL entity objects.
Call your PL/SQL insert, update, or delete procedure in your void insertRow();
, void updateRow();
, or void deleteRow();
method without calling super()
.
Create a callable statement to invoke your PL/SQL method.
Validate your attributes. You can do this in either of two places:
In your insertRow()
or updateRow()
methods: Perform your validation in Java in either of these two methods, or in PL/SQL stored procedures called from the methods.
In your validateEntity()
method: If validations are done in a separate stored procedure in PL/SQL, you can call that stored procedure in this method.
Fusion Middleware extensions for Oracle Applications provide the following services:
Profile
Lookup
Message
Language
Application
Taxonomy
Data Security
Attachments
Fusion Middleware extensions provide an easy way to access these services and to invoke them. Typically, the services are provided as application modules. An application module serves as a container for the various view objects and provides business-service-specific functionality.
The services listed above are provided as a service-specific application module. For example, Profile functionality is made available in ProfileService.
Access to these services is provided as a getFNDNestedService (String service)
method in the OAApplicationModuleImpl
class. The OAApplicationModuleImpl
extension is used to support access to the services.
See Section 9.5.1, "How to Use the Extension," for implementation information.
The code in Example 9-1 shows how to provide access to an FND service. In this case, it is ProfileService.
Example 9-1 Accessing an FND Service
ProfileService profileService = (ProfileService) myAM.getFNDNestedService (OAConstants.PROFILE_SERVICE); // now call profile specific methods on the ProfileService AM String appsServletAgent = profileService.getProfile ("APPS_SERVLET_AGENT");
OAConstants
exposes the various service names as a constant.
Note that the getFNDNestedService ()
is just a utility method that looks up the rootAM and checks to see if an instance of the requested service already exists in the rootAM as a nested AM. If one exists, it will return it; if it does not, it will instantiate a new AM for that service that will be nested inside the rootAM and return it.
In order to avoid primary key collision issues when synchronizing with disconnected clients, Oracle Applications standards require that an ADF Business Components entity object's primary key be populated with a Unique ID.
Fusion Middleware extensions support Unique ID by allowing an entity attribute to be populated with a globally unique value. The Fusion Unique ID Generator provided by ADF Business Components does this. The Unique ID can be used to populate an entity attribute of the BigDecimal
and Long
data types. The Unique IDs generated are of the BigDecimal
type and meet certain criteria for uniqueness across database instances.
Notes:
The database table column data type that corresponds to the entity attribute requiring a Unique ID must be large enough to hold the uniquely generated value. Typically, it should be of type NUMBER(18)
. NUMBER(15)
may not be sufficient to hold the uniquely generated values.
In addition, Oracle Applications coding standards require that the entity attribute populated with a Unique ID be of type Long
.
Fusion Middleware extensions provide both design time and runtime support for Unique ID.
At design time, Fusion Middleware extensions provide the ability to identify if an entity attribute needs a globally Unique ID. This is accomplished by setting Application Unique ID to true
in the entity attribute's Property Inspector section, as shown in Figure 9-9.
Based on the design time setting, the framework populates the entity attribute with a globally unique value at runtime. This is accomplished by setting the following transient expression on the entity attribute's definition:
oracle.jbo.server.uniqueid.UniqueIdHelper.getUniqueId(adf.object.unwrapObject());
Any custom view criteria adapter created by a product team will need to extend the OAViewCriteriaAdapter
class in order for Data Security to work correctly.
By setting custom ADF Business Components properties at runtime, the OAApplicationModuleImpl
class establishes the OAViewCriteriaAdapter
class as the standard view criteria adapter for the ADF Business Components container.
Product teams can do the following to create and use a custom view criteria adapter:
Extend OAViewCriteriaAdapter
and invoke super methods for use cases not handled by the custom view criteria adapter.
Set the custom view criteria adapter by invoking the setViewCriteriaAdapter()
method in the create()
method of the custom ViewObjectImpl
class.
Set the custom view criteria adapter on the ViewObject.
Document sequencing is a way to uniquely identify all business documents and business events belonging to a legal entity.
Document-sequence numbering has many country-specific requirements. It is a legal requirement in many EMEA, Asia Pacific, and Latin American countries. In the United States and the United Kingdom, it is used for internal control purposes and for financial-statement and other audits.
For more information about ADF Business Components integration of this feature provided by Fusion Middleware extensions, see Chapter 11, "Setting Up Document Sequences."