You are on page 1of 605

Contents

6 .......................... ................................ ................................ My Simple Introduction


7 ......................... ................................ ................................ What is OA Framework?
9 ................... ................................ Personalization, Extension & Customization in OAF
11 .......................................... ................................ Install OA Framework jDeveloper
11 ..................................... ................................ ................................ OAF Overview
12 .................. ................................ ................................ Oracle OAF MDS Repository
16 ................................... ................................ What the hell is JVM, Session, Cache ?
03 ..................... ................................ ................................ Oracle OAF Profile Option
01 ......................................... Naming Standards of Commonly Used OAF Components
03 ............... ................................ OAF Directory Structure - Location of Files on Server
07 ........................ ................................ ................................ Items in OA Framework
33 .................... ................................ ................................ Regions in OA Framework
32 ......................................... ................................ Bound Values in OA framework - I
36 ........................................ ................................ Bound Values in OA framework - II
34 ...................................... ................................ Some JDeveloper Concepts and Tips
23 ...................................... ................................ Restoring JDeveloper Stander Setup
21 ............................ Starting a new module/applciation?? Follow the following steps!!
23 ...................... ................................ ................................ OAF Hello World Tutorial
43 .................. ................................ ................................ Create Data Entry OAF Page
49 ............................. ................................ Page Creation in OAF - Supplier - Site Page
112 .............................. Entity Level Validation for StartDate and End Date comparison
116 ................. ................................ Create and Update on one click in OA Framework
106 .......................................... ................................ Create and Update Page in OAF
132 ............... ................................ ................................ Update records in OAF Page
123 ................... ................................ ................................ Row.STATUS_INITIALIZED
122 ........................... ................................ Create ViewObject (VO) Dynamically
126 ..................... ................................ ................................ Concept of Nested AM.
124 ................ ................................ ................................ Delete Records in OAF Page
166 .............................. ................................ ................................ OAF Sample Code
171 ...................................... OAException Message and Dialog Page in OA Framework
170 .............................. ................................ ................................ For High Volumes
172 ...................................... ................................ Set Active Subtab in SubTabLayout
176 ................................ ................................ Checkbox validation using VO attribute

1
www.AppsLead.com
174 ......................... ................................ Get and set the values using Session in OAF
Determine the transaction state that is, whether changes have been made to view
179 .................................... ................................ ................................ objects or not
143 ................. Scrolling Table: Table with horizontal Scrollbars and vertical scrollbars
140 ........................... ................................ OA Framework – Few code common using
143 ..................... ................................ Blocking User on submit Action in a OAF page
146 ..................... ................................ ................................ Create OAF Search Page
191 ....................... ................................ Simple Search Page in OAF with filter by code
196 ..................... ................................ Search Page Using Auto Customization Criteria
132 ............. ................................ Create Auto Customization Criteria OAF Search Page
111 ..................... ................................ How to fetch a bean in Advanced Search Panel
Setting Query Dynamically in View Object. (Why in some cases even after using
111 .................................... ................................ setQuery(), VO picks default query.)
110 ......................................... Manual Search Page with validations in OA Framework
Copying Data from One Table to Another Table in OAF and ADF Using RowsetIterator
116 ....................... ................................ ................................ ................................
117 ................... ................................ Clear/ Reset Result Table of Search page in OAF
103 .......................... ................................ Add Attribute to View Object Pragmatically
101 ............... ................................ Implement Master Detail Relationship in OAF Page
130 .................... ................................ Set Default Value for messageTextInput in OAF
136 ....................... Setting the default selected date for an OAMessageDateFieldBean
137 ................................... ................................ Implement PopList in OA Framework
123 ................ ................................ ................................ Uncommitted data warning
121 ................... ................................ ................................ Get Current Row in Table
121 ......................... ................................ ................................ Filtering Rows in OAF
120 ........................... ................................ Implement External LOV in OA Framework
127 ....................... ................................ ................................ Dependent LOV in OAF
161 ....................... ................................ Implement Dependent LOV in OA Framework
177 .............................. ................................ ................................ PPR-- An insight !
179 ..................................... ................................ Partial Page Rendering in OAF Page
142 .................................... ................................ PPR (Partial Page Rendering) in OAF
191 ................... ................................ ................................ Programmatic PPR in OAF
191 ..................................... ................................ Partial Page Rendering in OAF Page
030 ...................... Adding programmatic fire Action to UIX beans which dont support it
032 ............................ ................................ Programmatically Add Region to OA Page
036 .............. ................................ ................................ Implement Train in OAF Page

1
www.AppsLead.com
011 .................... ................................ ................................ Execute sql script in OAF
010 .............................. ................................ Execute PL/SQL Function from OAF Page
017 ...................................... Execute parameterized PL SQL procedure from OAF page
010 ...................... ................................ Oracle D2K to OA Framework Transformation
016 ............. ................................ ................................ Call D2K Form from OAF Page
003 .............. ................................ ................................ Call OAF Page from D2K form
003 ................................... ................................ Get Host Name and URL of OAF Page
004 ....................................... OAF Page to Upload Files into Server from local Machine
032 ................................. Import Data from Excel sheet to DB Table through OAF page
026 ...................................... ................................ Improving Performance of a HGrid
027 ................................. ................................ How to display HTML in content (OAF)
024 ............ ................................ ................................ EO based VO Extension in OAF
073 Hiding an item conditionally through SPEL in OAF ( VO Extension + Personalization )
073 ................. ................................ Entity Object Extension in Oracle Application R12
073 ......................... https://blogs.oracle.com/manojmadhusoodanan/tags/eo_extension
071 ........................ Hide "Privacy Link" and "Copy right information" from dialog page!
070 ....................................... ................................ ................................ SPEL in OAF
073 ............ ................................ ................................ Entity Object Based on PL/SQL
073 ............ ................................ ................................ Entity Object Extension in OAF
040 .................................. ................................ Application Module Extension in OAF
091 ................ ................................ ................................ Controller Extension in OAF
333 ......................... ................................ Another way to Controller Extension in OAF
332 .................. ................................ ................................ Key Flex Fields, KFF in OAF
313 ............................... ................................ Descriptive Flexfield Creation in OA Framework
310 ............................ Adding Descriptive Flex Field (DFF) through OAF Personalization
312 .................. ................................ Creating Descriptive Flex Field (DFF) Bean in OAF
312 ............................. ................................ Creating Key Flex Field (KFF) Bean in OAF
312 ............ ................................ Important Adding OAF Bean Through Personalization
312 ...................... Invoking OAF through form personalization (Zoom to Another Page)
312 .................... ................................ Embeding OAF Region in Workflow Notification
312 .......................................... Embedding Custom Region Inside Standard OAF Pages
312 ............................ ................................ Passing Parameters, encryption, encoding
317 ........................................ ................................ Get List all Paramaters for a Page
314 .................... ................................ Creation Of the Anonymous page Introduction
303 ........ Deploying OAF Personalizations Using the Import/Export Command Line Tools

0
www.AppsLead.com
331 ....................................... Implementing a simple watch in a OA Framework Page
330 .................................. ................................ Implementing Shuttle Region in OAF
337 ........... ................................ ................................ Gruoping Radio Buttons in OAF
334 ....................... ................................ ................................ Creating Graph in OAF
321 .......................... ................................ Steps to add JSP page to Oracle Application
321 ........... ................................ ................................ Calling JSP Page from OAF Page
322 ............................ ................................ Dependent Dynamic message choicelists
324 ............. ................................ MOAC(Multi Org Access Control) in OA Framework
363 ......................... ................................ Export Button Functionality Programatically
Giving download option to user for a file at a particular location on Application Server
360 ....................... ................................ ................................ ................................
370 ................ ................................ PopUp Window Using PopupBean Programetically
373 ....................................... ................................ Opening a POP UP window in OAF
372 ......................... Dynamically changing multiselect to single select in Table in OAF
376 ...................... ................................ Attaching AutoSubmit Property to a OA page.
343 .......................... ................................ Adding Custom Html code to the OAF Page
341 .................... ................................ Customizing Standard LOV using OAF Extension
341 ..................................... ................................ Download BLOB File from Database
340 .............. ................................ ................................ Create Items Programetically
343 ............................... Color The Item Based on Employee Position in Advanced table
347 .............................. ................................ Dynamic Color change in OA Framework
216 ............. ................................ ................................ Java date manipulation Notes
217 ................ ................................ ................................ Number Formatting in OAF
214 ......................................... ................................ Changing the Total Label in OAF
219 ............... ................................ ................................ Record History on OAF Page
211 ...................................... OAException Message and Dialog Page in OA Framework
210 ................................ ................................ How to make an OAF Page Read Only?
207 .......................... ................................ ................................ Make Page Readonly
204 ................................. ................................ Embedding ADF Region into OAF Page
231 .................................. ................................ Raise Multiple Error Messages in OAF
231 ............................ ................................ ................................ Few Useful threads
230 .......................................... Using Oracle AOL Profile Options to Configure Logging
230 ...................................... ................................ How to Generate SQL Trace In OAF
232 ............................... ................................ How to Check Debug Log on OAF Pages
234 ............... ................................ Debugging OA Framework - 7 Different Techniques
221 ........................................ Custom Logging in Java Layer in Oracle Applications R12
3
www.AppsLead.com
222 ......................... ................................ ................................ Logging in OAF Pages
222 ....................... Where is the debug message stored, once the logging is turned on?
222 ................................ ................................ ................................ Trace OAF Pages
227 ..................... ................................ ................................ Using Logging to Screen
229 ........................ ................................ ................................ Purging Log Messages
261 ............ ................................ Open Workflow status monitor diagram page in OAF
261 ............... ................................ ................................ JavaScript In OA Framework
266 .............. ................................ ................................ Alert Using JavaScript in OAF
267 .................. ................................ Invoking Web Service from OA Framework Pages
273 ........................ ................................ ................................ Clearing Profile Cache
271 ....................... ................................ ................................ Bounce Apache Server
271 .......................................... OAF Related Migrations from one Instance to Another
271 ............... ................................ ................................ Migration of Personalization
276 ............................... ................................ ................................ Deploy OAF page
243 ............................. ................................ Register OAF page in Oracle Applications
249 ...................................... Moving setup from one instance to another in oracle R12
291 ........ Deploying OAF Personalizations Using the Import/Export Command Line Tools
293 ....................................... Migrating Personalization from one instance to another.
292 ........................ ................................ How to deploy JAR file into R12 server in OA
297 .................................... ................................ OA Framework Interview Questions
299 ............. ................................ ................................ OA Framework Best Practices
633 .......................................... ................................ ................................ Best Blog
633 ..................... http://apps2fusion.com/apps/oa-framework/oa-framework-training
632 ............... ................................ ................................ ................................ Video

2
www.AppsLead.com
My Simple Introduction

In fact I have to say my article is nothing but compilation of information from


OAF Developer's guide , googling , metalink, blogs and lastly my
knowledge....[You must be facs on the last point.... even I am :)]

Mostafa El-Rouby

6
www.AppsLead.com
What is OA Framework?
Before starting about OA Framework, let's try to understand the word

'Framework':

As more and more applications are being developed, new technologies are also evolving at the same time.
If we look at our web application from scratch, even state is not maintained for our pages. For example, I want to
create a search form. When I click on search/submit button, the criteria fields will not retain their values
automatically. Also we use javascript for validations and lots of other things for similar basic functionalities.

Now, the solution to these problems is that lots of frameworks are there in which such common functionalities
are already done (pre-written) for us.
So whether it is Sun or Oracle or Microsoft, the main motive behind creating frameworks is that the attention of
developers should only be towards developing the application i.e. the business rule (such as what tax should be
deducted from an invoice) and get rid of all other things like 'request.getParameter' or 'making input fields inside
an HTML file'. Because these things are not contributing to that part of software development which is directly
related to users. By doing this we are not implementing any business rule. The aim here is to do these tasks ASAP
so that developers can only concentrate on implementing the business application.

One more things I want to put here is: difference between API & Framework:

API is a library. At times we instantiate objects of library code and call their functions.

Framework on the other side is like that there is already some blocks of code written and we have to fit our own
code somewhere inside those blocks.

So to fit our code what we do is that sometimes we make our classes to inherit from other classes, implement
the methods what framework specifies. This is what happens in most of the frameworks.

For example we want to make our application on MVC architecture. So for that we can use Structs (a framework
which provides built in support for MVC). However this doesn't provide much support for UI.

JSF is also a framework which provide us a complete model of visual components, provides event handling tech
for web-apps and lots of other services.

Now, I think it’s easy to define Oracle Application Framework :)

Oracle Application Framework


==========================
OAF - Framework developed by Oracle for building and launching web pages within Oracle E-Business Suite (EBS).
Below is a sample web page of Oracle EBS:

7
www.AppsLead.com
All pages within EBS are almost similar in look and feel. Based on this fact, below is some common functionality
which is already provided by this framework so that we can mainly concentrate on implementing business logic:

Built in support for MVC architecture.

Inbuilt support for Apps specific features like flexfields, menus etc..

Provide classes for all standard components seen on pages like text fields, buttons, tables etc..

Support for connection pooling and session management.

Built in protection against web hacking.

Personalization - We can change look and feel, layout or visibility of contents on the standard pages delivered by
Oracle. However the main thing here is that OAF allows somewhat skilled functional user to apply these changes.

Almost every implementation of EBS has to make some changes to some of these pages. OAF has mechanism to
implement these changes in such a way that the changes are not wiped out even after patches delivered by
Oracle are applied.

Since OAF is used only for creating EBS pages, copyright links and global links are provided by this framework by
default.

4
www.AppsLead.com
Personalization, Extension & Customization in OAF
While dealing with Oracle EBS html based pages, we can modify or create completely new page using any of the
below methods:

Personalization
======================

Personalization is the process of making changes to the User Interface (UI) from within an Oracle E-Business Suite
Page.
Using 'Personalize Page' link or from 'Functional Administrator' responsibility, we can perform personalization.
'Personalize Page' link shows all the regions and items used in the page in hierarchical form for example as shown
below:

From here, we can modify/personalize almost any items/region using 'Personalize' icon. We can modify
properties such as Prompt, Rendering of item, making fields Required and others as shown below:

9
www.AppsLead.com
All the personalizations get stored in MDS (i.e. JDR_% tables) by creating a new document ID for the page. Thus
any patch will modify the original document ID (standard one) and unlike forms these personalizations will not
get removed.

Extenion
======================
There are not many things we can do using personalization such as changing the logic or control settings of the
page. For these modifications we use extension. It is the process of making changes to the programmatic
elements of an E-Business Suite form/page. It is possible to extend OA Framework-based pages either using
controller extension or AM extension or by performing VO substitutions.

Controller extension

Oracle does not recommend to extend controller objects associated with regions in seeded EBS product pages.
One reason is that controller code is subject to change at any time, and Oracle cannot guarantee that extended
controller code will work after the updates.
However, we extend controller code quite regularly. For example, we need to create a web beans
programmatically on the fly in the controller code instead of declaratively, which is not possible through
personalization.
To extend a controller, first we create a new class file that extends the original controller’s Java class. Next, using
personalization, we personalize the region to which the original controller is attached. Once in the
personalization screen for the region, replace the existing controller with the newly created extended controller.
If in the extended CO class we override processRequest(), then OA Framework will invoke the overridden method
in the custom class. OA Framework will not execute the method in the original controller class unless
super.processRequest() is called in the extended class.

View Object Extension


Sometimes there is requirement to display additional information on screens that display data fetched from view
objects. To do this, we need to do three things:

 First, we need to create an additional field on the page using personalization.

13
www.AppsLead.com
 Then, create a new view object. This new view object extends the existing view object, which is why it
inherits all the features and columns of the existing view object. This is referred to as view object
extension.
 Later we create a substitution in JDeveloper; the substitution contains the directive to replace the
existing view object with the new view object at runtime.

Entity Object Extension


We extend entity objects to add extra validation to some fields/records. We can also extend entity objects to
assign default values to the attributes. Steps for extending the entity object are similar to those for extending
view objects.

Application Module Extension


In AM, Oracle seeded code initiates PL/SQL JDBC calls. Sometimes, there is a need to enhance that PL/SQL call by
some additional PL/SQL calls. In such cases, we can extend the Application Module. Steps for extending the AM
are similar to those of extending a view object and entity object.
For example an Application Module has following methods:

public String method1(parameters) {....}


public boolean method2(parameters) {....}
public String method3(parameters) {....

Lets say we need to raise some business event if method2 returns false. So, we will code the extended
Application Module as shown below:

public boolean method2(parameters) {

if !(super.method2(parameters)) {
// business logic comes here

Customization
======================
Customization is the process of creating new OAF pages. While Oracle does provide tools to do this (i.e.,
JDeveloper 10g with OA Extension), this is the only and least supported option.

Install OA Framework jDeveloper


JDeveloper Setup for OA Framework

1) Download JDeveloper for OA Framework


==========================

Login to oracle apps and open any HTML form.

Click on 'About this Page' --> 'Technology Components' tab.

Note the OA Framework version as shown below:

11
www.AppsLead.com
Go to Metalink Note 416708.1 and download the right JDeveloper patch. (for example, for 12.1.3, JDeveloper
patch 9879989 is used). The correct version has BC4J, MDS and FND libraries matching with libraries deployed on
the server.

Suppose downloaded file is p9879989_R12_GENERIC.zip. So extract this file to D:\JDEV\1213. This will create 3
directories: jdevbin, jdevdoc and jdevhome.

2) JDEV_USER_HOME Environment Variable


==========================
Create a new user variable named JDEV_USER_HOME, and a variable value that points to <install
directory>\jdevhome\jdev
e.g., D:\JDEV\1213\jdevhome\jdev.

3) Obtain FND .dbc file


==========================
Login to unix box and go to $FND_SECURE directory and locate the latest .dbc file. It contains information
required to establish a DB connection to Oracle apps. Copy this file to <JDEV_USER_HOME>\dbc_files\secure.

4) Starting JDev and connecting to oracle database


==========================

Start Jdeveloper from jdevbin\jdev\bin\jdevW.exe. Also create desktop shortcut for the same.

Expand the connection node in system navigator, right-click on the Database node and select New Connection. It
is a 4 steps process in which we have to provide DB details such as connection name, apps username &
password, host name, JDBC port and service name. After entering all the details test the connection.

5) Running a page for testing:

==========================

Open <JDEV_USER_HOME>\myprojects\toolbox.jws to configure the tutorial project. Right click on Tutorial


project --> Project Properties --> Runtime Connection.

When running a page from JDeveloper, we are not provided with list of responsibilities or asked to enter FND
username and password. Running a page form JDev is simply right-click a page and Run. So details of FND
username, password and responsibility are entered in project properties. As shown below, enter a valid FND
username and password and that user must have access to the mentioned responsibility. Also browse to .dbc file
we saved in step3:

11
www.AppsLead.com
Expand tutorial project and run HelloWorldPG.xml as shown below:

10
www.AppsLead.com
Another Basic Installation Steps -

1. Download JDeveloper 10.1.3.3.0. Available Oracle patch is p8431482_R12_GENERIC.zip

Unzip the patch p8431482_R12_GENERIC.zip i.e. in D:\

2. Specify the path of jdev in following location

My Computer>Properties>Advanced>Environment Variables as given below screen shot

3. Download dbc file of Oracle application instance from $FND_TOP/secure

13
www.AppsLead.com
( it is like a tnsnames.ora file having connection detail )

Place the file at location D:\p8431482_R12_GENERIC\jdevhome\jdev\dbc_files\secure

4. Open JDeveloper and set database connection goto Connection Navigator > Database and create a new
connection

12
www.AppsLead.com
Note Give user name and password do not give any role and do not check Deploy Password checkbox

Note Give Host Name, JDBC port, and SID. Keep driver as thin.

16
www.AppsLead.com
Now JDeveloper is ready to use

5. Create a sample workspace and project to know setting during creation of project

1. Goto Application Navigator right click > New > General > Workspace Configured for Oracle Applications

2. Give workspace name

3. Give project name and Default package

17
www.AppsLead.com
Note Default package is

<3rd party identifier>.oracle.apps.<application_short_name>.<component>.

[<subcomponent>]

Example: mycompany.oracle.apps.po.requisition.webui

4. Give database connection detail

14
www.AppsLead.com
5. Give your dbc file location, application username, application password, application short name, and
responsibility key

i.e. Application short key and responsibility key is nothing but assigned responsibility detail to the application
user for example if application user has System Administrator responsibility then Application short name will be
“SYSADMIN” and responsibility key will be “SYSTEM_ADMINISTRATOR”. These values are required to compile and
run the page because page required context during run time so it will login the application with given username
and password and it will take context from assigned responsibility

19
www.AppsLead.com
6. Click Next. Creation of Workspace and project has finished

13
www.AppsLead.com
OAF Overview
Share on facebook Share on twitter Share on email Share on print More Sharing Services 1

This post will explains some terminologies that is used in Oracle Application Framework (OAF).

Entity Object - business component entity objects maps to database table or view that allow DML operations and
that used to cache data result set and perform validation before post changes to database.

Association Object - business component association objects implement the relationships between different
entity objects and can mapped to database referential integrity constraint or non existing referential integrity
constraint and this case constrain will be validated in OAF but not in database.

View Object - business component view objects are used to display data in UI pages and it can be based on
1- Entity Object or many entity objects and this case it supports DML operations.
2- SQL queries : that's doesn't support DML operations
3- Static : Programmer create structure of view object attributes and can add static data also.
4- Programmatic : Programmer write code at runtime to get dynamic data of view object.

View Link - Establishes a master/detail relationship between different view objects and can be in more depth
master/detail/detail/....

Validation View Object - A view object created exclusively for the purpose of performing light-weight SQL
validation on behalf of entity objects or their experts.

Application Module - An application module is a container for related BC4J objects. The AM is connected to the
database, and is responsible for the commit and rollback of a transaction.

Validation Application Module - An application module created exclusively for the purpose of grouping and
providing transaction context to related validation view objects. Typically, a standalone entity object or the top-
level entity object in a composition would have an associated validation application module.

Root Application Module - Each pageLayout region in an OA Framework application is associated with a "root"
application module which groups related services and establishes the transaction context.

This transaction context can be shared by multiple pages if they all reference the same root application module,
and instruct the framework to retain this application module (not return it to the pool) when navigating from
page to page within the transaction task.

Entity Expert - A special singleton class registered with an entity object (EO) that performs operations on behalf
of the EO.

Controller - The controller is the java code in charge of loading a page when we call it. It is also in charge of
handling an event on a page, like a click on a button, or the call of a List Of Values.

Attribute Set - Bundles of region or item properties that can be reused either as is or with modifications. For
example, all buttons sharing the same attribute set would have the same label and Alt text.

Another OA Framework Architecture

OA Framework is based on MVC (Model-View-Controller) architecture. However to reduce the complexity, each
layer is futher sub divided into multiple layers.

Below figure shows sub division of these 3 layers:

11
www.AppsLead.com
View (Pages in OAF)

==========================
While developing pages in OAF, these are stored in XML format (due to declarative nature of development
method). However to access an OAF page from front end, these page definitions must be loaded in Oracle
database i.e. MDS.

Metadata Service (MDS) is a repository used for rendering of an OAF page. It is implemented as a group of
database tables that stores the structure and properties of the page components. The tables that belong to the
MDS repository begin with JDR% : JDR_PATHS, JDR_ COMPONENTS, JDR_ATTRIBUTES_TRANS, and
JDR_ATTRIBUTES. (For standard pages delivered by Oracle, page definition XML files are stored
in $<PRODUCT>_TOP/mds directory. However these are only for reference purpose and are not used at runtime).

A page consists of regions and items. At runtime, both regions and items are instantiated as JavaBeans within the
application server.
As page definition is stored in the database tables, OA Framework caches the page structure into the
memory cache on middle-tier. When any given page or region is accessed for the very first time, its definition
gets loaded in the MDS cache. Subsequently, each successive access to that page happens from the memory,
hence reducing the performance overhead of querying the page definitions from database tables.

Controller in OAF
==========================
A controller in OA Framework is a Java class that is attached to a region. Its function is to handle user actions.
Controllers in OA Framework are based on the OAController interface, which defines three methods that can be
implemented in the controllers that implement the OA Framework controller:

processRequest() method:
PR method is called by OAF just before a region gets displayed.
One page can have multiple regions, and each region may have a controller attached to it. If a page has multiple
regions and controllers, controller against the outermost region will be the first to be called.

processFormData() method:

When a user submits the page, the PFD method in the controller class is invoked. The purpose of this method is
to transfer the values from the fields on the screen into the cache.

processFormRequest() method:

Finally if everything is fine till this point, then PFR method of the controller class is called. Usually we issue a
commit via processFormRequest() after all the validations. If there are multiple controller classes at different

11
www.AppsLead.com
levels, then processFormRequest() against each of the controllers is called for each nested region within that
page.

Also, instances of OAPageContext class and OAWebBean class are also passed as parameter to all these 3
methods. OAPageContext is used to get parameter values from the page and OAWebBean can be used to get
handle of any of the bean within the page.

Model (BC4J)

==========================
Model part in OAF is implemented using "Business Components for Java - BC4J". BC4J is collection of application
module (AM), view object (VO) and entity object (EO).

Application Module (AM):

An AM is container for server side objects, which are view objects, entity objects, view links, and entity
associations.

Every OAF page accessed through Oracle apps must have an Application Module attached to its top-level region
which is root AM. This top-level region is of the pageLayout region type and serves as a container for other
regions and page components. The Root AM holds a BC4J transaction object that helps in JDBC operations.
AMs can also be attached at lower-level regions within the

page. In such cases, AMs become nested AMs. The nested AMs reference the Root AM’s transaction object.

View Object (VO):

The purpose of a VO is to query data from database. A view object can either be a SQL Statement or it can be
based on entity objects. If a region is read only, then its view object can be based directly on a SQL
Statement. However, if the region allows a user to make changes to the data, then its VO should be based on
entity objects. For example, view objects used by LOVs are not based on entity objects.

Entity Object (EO):

Entity objects are responsible for doing inserts, updates, and deletes to database tables. Each instance of an
entity object represents a single row in the database table.

However, inserts, updates, and deletes can be done from anywhere. This is possible because any layer can
request a JDBC connection via the AM. But this is not a recommended approach.

==========================

For better understanding, lets take an example of a page where user first queries the data, then modify the
records and finally save/submit the changes.

Querying the data


VO based on an EO, which is based on a database table. The query is executed on that table. Data returned from
SQL query is stored in entity object cache.

Modifying the data


The data changes only happen in the browser. The fields on the screen may be mapped to view object attributes,

10
www.AppsLead.com
but the view object or the entity object is not affected until the page gets submitted to the server.

Submitting the form

 Fields in the screen are mapped to VO attributes. At this stage, PFD method of the controller is called. It
transfers the values from the screen fields to the VO cache. As VO is based on EO, changes are further
transferred into the EO cache.
 At the time when the cache is populated, the setAttribute method is called for each column. Within the
setAttribute method, VO then calls the corresponding set(Attribute Name) method in the underlying
EO. This executes the column-level validation in the entity object. Once all the attribute values have
been set, OAF calls the validateRow() method for each VO row the user modified. This executes any
row-level view object validation. Finally, within the validateRow() method, the view object calls
validateEntity() for validating data in underlying entity objects.
 Once the cache has been populated and validated by PFD, the processFormRequest() method gets
called. Inside this method, we can issue a commit or rollback through the AM. When a commit takes
place, the data changes are transferred from the cache to the database table.

13
www.AppsLead.com
Oracle OAF MDS Repository
MDS repository stores all pages and regions used in OAF pages and contain personalization and extensions.

All MDS data stores in the following 4 tables.


1. JDR_PATHS: Stores the path of the documents, OA Framework pages and their parent child relationship.
2. JDR_COMPONENTS: Stores components on documents and OA Framework pages.
3. JDR_ATTRIBUTES: Stores attributes of components on documents and OA Framework pages.
4. JDR_ATTRIBUTES_TRANS: Stores translated attribute values of document components or OA framework
pages.

JDR_UTILS PL/SQL package supports the MDS repository and can be used to query and maintain the repository.

12
www.AppsLead.com
What the hell is JVM, Session, Cache ?
From quite some days, I find threads on OAF Forums, where people could not understand the basic terminology
of J2EE like session,JVM , Oracle user session, cache etc. I think these terms are not new for people from Java
background, but for people who come from pl/sql background or not from Java background, these terms might
look like hammers.I remember one thread where I and Tapash were replying somebody asked whats' the
difference between ICX session and http session, I wanted to reply, but I thought, replying there would make
thread too long, i guess that thread already crossed 4 pages and replying there may not reach to all target
audience.

So, lets start with basic terminalogy:

About JVM
At the heart of the Java platform lies the Java Virtual Machine, or JVM. Most programming languages compile
source code directly into machine code, suitable for execution on a particular microprocessor architecture. The
difference with Java is that it uses bytecode - a special type of machine code.
Java bytecode executes on a special type of microprocessor. Strangely enough, there wasn't a hardware
implementation of this microprocessor available when Java was first released. Instead, the processor
architecture is emulated by what is known as a "virtual machine". This virtual machine is an emulation of a real
Java processor - a machine within a machine (Figure One). The only difference is that the virtual machine isn't
running on a CPU - it is being emulated on the CPU of the host machine.

The Java Virtual Machine is responsible for interpreting Java bytecode, and translating this into actions or
operating system calls. For example, a request to establish a socket connection to a remote machine will involve
an operating system call. Different operating systems handle sockets in different ways - but the programmer
doesn't need to worry about such details. It is the responsibility of the JVM to handle these translations, so that
the operating system and CPU architecture on which Java software is running is completely irrelevant to the
developer.

16
www.AppsLead.com
The Java Virtual Machine forms part of a large system, the Java Runtime Environment (JRE). Each operating
system and CPU architecture requires a different JRE. The JRE comprises a set of base classes, which are an
implementation of the base Java API, as well as a JVM. The portability of Java comes from implementations on a
variety of CPUs and architectures. Without an available JRE for a given environment, it is impossible to run Java
software.

Differences between JVM implementations


Though implementations of Java Virtual Machines are designed to be compatible, no two JVMs are exactly alike.
For example, garbage collection algorithms vary between one JVM and another, so it becomes impossible to
know exactly when memory will be reclaimed. The thread scheduling algorithms are different between one JVM
and another (based in part on the underlying operating system), so that it is impossible to accurately predict
when one thread will be executed over another.
Initially, this is a cause for concern from programmers new to the Java language. However, it actually has very
little practical bearing on Java development. Such predictions are often dangerous to make, as thread scheduling
and memory usage will vary between different hardware environments anyway. The power of Java comes from
not being specific about the operating system and CPU architecture - to do so reduces the portability of software.

Summary

The Java Virtual Machine provides a platform-independent way of executing code, by abstracting the differences
between operating systems and CPU architectures. Java Runtime Environments are available for a wide variety of
hardware and software combinations, making Java a very portable language. Programmers can concentrate on
writing software, without having to be concerned with how or where it will run. The idea of virtual machines is
nothing new, but Java is the most widely used virtual machine used today. Thanks to the JVM, the dream of
Write Once-Run Anywhere (WORA) software has become a reality.

JVM Cache and Its impelemetation in Oracle Apps:

Qestions like what is cache? How is it related to JVM? How is caching implementated in Oracle Apps?Instead of
me explaining this.

HTTP SESSION

HttpSession is nothing but a java interface.The servlet container uses this interface to create a session between
an HTTP client and an HTTP server.
17
www.AppsLead.com
The session persists for a specified time period, across more than one connection or page request from the user.
A session usually corresponds to one user,
who may visit a site many times. The server can maintain a session in many ways such as using cookies or
rewriting URLs.
This interface allows servlets to View and manipulate information about a session, such as the session identifier,
creation time, and last accessed time
Bind objects to sessions, allowing user information to persist across multiple user connections.

ICX Session or Oracle Applications User Session


(Is it same as HTTP session/servelet session ?)

A http session or a servelet session usually corresponds to an application login/logout cycle, but that is not
strictly true in the case of OA Framework applications.I tell u y ? When the user logs in to an OA Framework
application, the OA Framework creates an AOL/J oracle.apps.fnd.common.WebAppsContext object and a
browser session-based cookie that together keep track of key Oracle Applications context information like the
current responsibility, organization id and various user attributes such as user name, user id,
employee id and so on.
The cookie contains an encrypted key identifier for a session row stored in the Applications database.Specifically,
this is the servlet session ID which, in its decrypted form, serves as the primary key in the
ICX_SESSIONS table.(to get an idea do run Select * from ICX_SESSIONS , to get an exact idea of what information
is stored in the table)
The WebAppsContext retrieves this key value after each request and uses it to query the current session state.
The Oracle Applications user session or ICX SESSION is associated and not dependent with a servlet session,
because , it has its own life cycle and time-out characteristics. Generally, the Oracle Applications user session has
a longer life span than the servlet session. The servlet session should time-out sooner.

User session is dependent on following profiles:

a)ICX: Limit Time :Determines the maximum Oracle Applications user session length( in
hours.

b)ICX:Session Timeout: Maximum idle time for the Oracle Applications user session
(specified in minutes).

While servelet session timeout is purely dependent on setting in Apache Jserv session timeout setting.

An Oracle Applications user session might be associated with multiple http servlet sessions. For example, the
servlet session times out
while the user takes a phone call in the middle of creating an OA Framework expense report, then resumes work
before the Oracle Applications user session
times out.If the Oracle Applications user session times out, aslong as the user does not close the browser window
(so the browser session-based cookie isn't lost) and no one deletes the corresponding session row in the
ICX_SESSIONS table, the user can resume her transaction at the point where he stopped working
after being prompted to log back in.
Although the best practice as per Oracle standards is to sync ICX_SESSION and servelet session,till passivation
feature is implenented in Oracle Apps. Passivation is still not supported in 11i and 12i.

This is straight from metalink “The ICX: Session Timeout option sets the the maximum number of minutes to wait
before invalidating an idle ICX Session. The default value is null. The web server session timeout value, or more
appropriately the Apache Jserv Session value is used to specify the number of milliseconds to wait before
invalidating an unused session. The default value is 1800000 or 30 minutes.
We recommend that you set the ICX: Session Timeout and the Apache Jserv Session to be the same. It's better to
be consistent and let the ICX session and the Apache Jserv (middle tier) session expire at the same time. If the ICX
session expires before the Jserv session, the user will be presented with a login page even though the Jserv session
is still active. If the user logs back in before the Jserv session expires, they will see the old state of their middle-tier
transaction. This can be confusing, since from the point of view of the user there is no distinction between the ICX
session and the Jserv session.

14
www.AppsLead.com
We also recommend that you do not set the Apache Jserv Session timeout to be any higher than 30 minutes.
Longer idle sessions will drain the JVM resources and can also cause out of memory errors.
The session timeout for the webserver is specified via the following directive in the /Jserv/etc/zone.properties file.
session. timeout=1800000”

I think by now you must be crystal in ur understanding of basic key terms in J2EE.I would like to stress on one
thing... JVM cache is shared across servelet/http sessions , and is purely dependent on first login, it can be
removed progrmatically by invalidating the cache or by bouncing the apache server.

19
www.AppsLead.com
Oracle OAF Profile Option
Share on facebook Share on twitter Share on email Share on print More Sharing Services 1

Oracle OAF has some important profile options which is useful in extension or personalization.
I will list it below and write breif about every profile option.

1- FND_Diagnostics
Setting this profile option to YES, will add anew link "Diagnostics" at top right on page, that allow developer to
trace logs.

To add log when coding use the following code in Controller or Application Module
In Controller write this code:-
pageContext.writeDiagnostics(this, "Phrase will be added to logs", 1);

In Application Module write this code


getOADBTransaction().writeDiagnostics(this, "Phrase will be added to logs", 1);

2- Personalize Self-Service Defn


Set this profile to Yes to allow personalization.

3- FND: Personalization Region Link Enabled :


Set this profile to Yes show "Personalize Region" links above each region in a page.

4- Disable Self-Service Personal


Yes will disable all personalization at any level.

5- FND: Personalization Document Root Path


Set this profile option to a directory at application server machine which will contain import/export
personalization files.

03
www.AppsLead.com
Naming Standards of Commonly Used OAF Components
1] Naming Standards for a Custom Package:

If you want to create new pages, business logic, or whole applications and deploy your code with existing Oracle
E-Business Suite applications, you must define a new application and use its short name for any related package
and seed data definitions. For example, if you want to create a new, custom Procurement application, you might
create a product with the short name XXPO (the “XX” prefix ensures that your selected product short name
never conflicts with any future Oracle E-Business Suite product names).

Any objects that you create — either by extending (subclassing) existing Oracle E-Business Suite objects or by
creating new objects from scratch — must be added to a package that starts with your company’s identifier:

<myCompanyName>.oracle.apps….

 If you are creating new objects from scratch, you should put them in a package that also includes your
custom application short name as follows:

<myCompanyName>.oracle.apps.<customProductShortName>….

For example, assuming your company is called ABC Corporation and your custom product short code is XXPO,
any new classes and OA Components that you create should be added to the following package:

abc.oracle.apps.xxpo….

 If you are extending existing Oracle-Business Suite objects, you may add your files to a package that
corresponds directly to the original Oracle package (in this case, you don’t need to add your files to a
package including a custom application short code).

2] Naming Standards for a Page (File Extension: .xml):

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

<Object><Function>PG or <Object>PG

Examples:

 SuppliersPG.xml (Supplier update)


 SupplierCreatePG.xml (differentiated only if update and create are separate tasks)
 SupplierViewPG.xml (view supplier info)
 SupplierSearchPG.xml (search for supplier)
 SupplierHomePG.xml (Supplier home page)

3] Naming Standards for a Region (File Extension: .xml):

The region name should convey the object it presents (an employee, a supplier, an item, a purchase order, an
applicant, and so on), and the function being performed or the structure (search, promote, hire, approve, view,
table, HGrid, Tree and so on).

<Object><Function-Structure>RN or <Object>RN

Examples:
01
www.AppsLead.com
 SupplierDetailsRN.xml
 PoApproveRN.xml
 CustomerContactsRN.xml
 ItemTypeHGridRN.xml

4] Naming Standards for an Entity Object (File Extension: .xml, .java):

The EO should be named for the objects stored in its underlying entity. For example, the entity
FWK_TBX_PO_HEADERS stores purchase order headers, so the associated EO name is PurchaseOrderHeaderEO.

<EntityName>EO

Examples:

 EmployeeEO.xml
 EmployeeEOImpl.java
 SupplierEO.xml
 SupplierEOImpl.java
 SupplierSiteEO.xml
 SupplierSiteEOImpl.java
 PurchaseOrderHeaderEO.xml
 PurchaseOrderHeaderEOImpl.java
 PurchaseOrderLineEO.xml
 PurchaseOrderLineEOImpl.java

5] Naming Standards for an Entity Association Object (File Extension: .xml):

The AO name should convey the relationship between a parent and its child entities.

<Parent>To<Child>AO

Examples:

 PoHeaderToLinesAO.xml
 SupplierToSitesAO.xml
 EmployeeToContactsAO.xml

6] Naming Standards for a View Object (File Extension: .xml, .java):

The VO name should convey the nature of the query. VO names are always plural as they model a collection of
rows.

<DescriptiveName>VO

Examples:

 AllEmployeesVO.xml
 AllEmployeesVOImpl.java
 AllEmployeesVORowImpl.java
 NewCustomersVO.xml
 NewCustomersVOImpl.java
 NewCustomersVORowImpl.java

7] Naming Standards for a View Link (File Extension: .xml):

01
www.AppsLead.com
The VL name should convey the relationship between the master and detail VOs.

<Master>To<Detail>VL

Examples:

 EmployeeToDepartmenstVL.xml
 PoHeaderToLinesVL.xml
 ItemToApprovedSuppliersVL.xml

8] Naming Standards for an Application Module (File Extension: .xml, .java):

The AM name should convey the purpose of the UI module it services.

<ModuleName>AM

Examples:

 EmployeesAM.xml
 EmployeesAM.java (optional interface)
 EmployeesAMImpl.java
 ItemCatalogAM.xml
 ItemCatalogAMImpl.java
 PoSummaryAM.xml
 PoSummaryAMImpl.java
 ApprovedSupplierListAM.xml
 ApprovedSupplierListAMImpl.java

00
www.AppsLead.com
OAF Directory Structure - Location of Files on Server
All the standard OAF components delivered by Oracle fall under:
$JAVA_TOP/oracle/apps/... directory.

Similarly, any of our custom OAF application should go under:


$JAVA_TOP/xxcust/oracle/apps...
(xxcust is short name for our custom application).

While running our application from JDeveloper, there is no $JAVA_TOP. So equivalent directory for $JAVA_TOP
is <JDEV_USER_HOME>/myclasses.

when we create our pages, all java and xml files get created in <JDEV_USER_HOME>/myprojects folder.
However on compiling the project corresponding class files and xml files get generated under

<JDEV_USER_HOME>/myclasses.

Right after oracle/apps, there is short name of an application that is registered within EBS (like icx, fnd, po, etc).

Now all we have to do is to create package structure for all components:


1) Entity objects: package name should end with .schema.server
2) Application module: package name should end with .server
3) View objects: package name should end with .server
4) View objects (for LOVs): package name should end with .lov.server
5) Page definitions & controllers: package name should end with .webui

UIX (User Interface XML) Framework


Oracle EBS uses:

 UIX for UI Components (i.e. View part)


 BC4J for business components (i.e. Model part)

03
www.AppsLead.com
 And what OAF does is the programmatic binding among all these.

UIX framework is J2EE-based framework for building web applications and is based on MVC design pattern.
The main focus of UIX is the user presentation layer of an application. UIX is platform independent as it is
implemented in the Java programming language. UIX development can be declarative, using uiXML, an XML
language for creating UIX pages.

UIX includes a set of UI components and classes for rendering them:

UI Components: These are implemented as Java Beans. They include page layouts and simple UI objects that map
to standard HTML controls, such as buttons, forms, and checkboxes. There are other complex components, such
as trees, hide-show controls, LOV etc.

Renderers: These are Java classes for rendering the UI components to target clients/devices. For example,
components are rendered as HTML for use in web browsers or as WML for use in mobile devices.

Classes for UIX Components are in the oracle.cabo.ui package.

uiXML: This is an XML language for programming UIX applications. uiXML provides a declarative way of creating
web applications programmatically using UIX Java APIs. The pages, events, and any other items defined with
uiXML elements are all transformed into Java objects behind the scenes. Below is an example of a uiXML element
(button):

1<button destination="http://www.abc.com/index" disabled="false" text="goBtn">

2</button>

uiXML documents are written in a text format, where document represents page or a region.
Classes supporting uiXML are located in oracle.cabo.ui.xml and oracle.cabo.servlet.xml packages.

Pages in UIX
===================
On the browser, "page" is just collection of HTML elements. However, while in developing phase, concept of
"page" can be more complex, depending upon the declarative way used to create the page and renderers used.

A UIX page consists of a hierarchical set of components known as UI nodes. Some nodes define visible
components, such as buttons, images, text fields, while others organize the layout and appearance of other
nodes.
Nodes can have parents and children, and multiple nodes together form a tree-like structure used to represent a
page's logical structure.

For example, left part below figure shows a logical hierarchy of UI nodes and right part shows the same hierarchy
rendered as an HTML page.

02
www.AppsLead.com
Now in UIX, there is a java class for each UI nodes. These classes implement the UINode interface in the
oracle.cabo.ui package. The UINode interface contains methods for the characteristics of nodes, such as:

1public int getIndexedChildCount(RenderingContext context);

2public UINode getIndexedChild(RenderingContext context, int childIndex);

3public Enumeration getAttributeNames(RenderingContext context);

4public Object getAttributeValue(RenderingContext context, AttributeKey attrKey);

06
www.AppsLead.com
Items in OA Framework
Items are the components to which user interacts directly. For example if a user wants to enter some data on a
page, he will perform this through some text field which is an item. This text item might be inside some region.
Similarly for performing different actions on a page, different items are there.

OA Framework offers a large set of UI components that make the building of applications easier. These consists
of simple componenets (like buttons, fields) and complex components (like tables, hierarchical grids etc..)

Below are some of the items provided by OAF:

MessageStyledText

If we want to display the text but that should not be editable, then we can use MessageStyledText.

Bean: oracle.apps.fnd.framework.webui.beans.message.OAMessageStyledTextBean

MessageTextInput

It is a simple text field where users can enter data.

Bean: oracle.apps.fnd.framework.webui.beans.message.OAMessageTextInputBean

MessageLovInput

Instead of entering data manually, this item provides users a list of values

and users can select any value from that. This will open a popup window where user can search/select values
from the list.

Bean: oracle.apps.fnd.framework.webui.beans.message.OAMessageLovInputBean

MessageChoice

This item also provides a list of values but in a drop down manner. This is mainly used when the list of valid
values is very small in number.

Bean: oracle.apps.fnd.framework.webui.beans.message.OAMessageChoiceBean

MessageDownload

This item enables user to download a file from the server to a local machine. It appears as a linked text. When we
select this link, a small window opens in browser through which we can open/save that file.
07
www.AppsLead.com
Bean: oracle.apps.fnd.framework.webui.beans.message.OAMessageDownloadBean

MessageFileUpload

Using file upload item, we can easily upload a file from local/client machine to the server. It appears as an input
field, followed by a browse button.

Bean: oracle.apps.fnd.framework.webui.beans.message.OAMessageFileUploadBean

MessageRadioGroup

This item can have many radio buttons but we can select only one at a time. This is mainly used when we want to
select a single choice from a list of choices.

Bean: oracle.apps.fnd.framework.webui.beans.message.OAMessageRadioGroupBean

MessageCheckBox

As radio button is used for only single selection, message check box on the other hand is used for multiple
selection.

Bean: oracle.apps.fnd.framework.webui.beans.message.OAMessageCheckBoxBean

Button and SubmitButton

Submit button (also known as action button) submits the page when selected by a user. i.e. HTTP POST will be
performed.
Bean: oracle.apps.fnd.framework.webui.beans.form.OASubmitButtonBean

Simple button (also known as navigation button) acts simply as a link and is only used for navigation purpose. On
selecting this, HTTP GET will be performed. Bean: oracle.apps.fnd.framework.webui.beans.nav.OAButtonBean

Link

This bean is simply used to navigate from one page to another. This item creates a HTML link tag to redirect to
some other page.

Bean: oracle.apps.fnd.framework.webui.beans.nav.OALinkBean

FormValue

This item is used when we want to store some information or save that to DB but do not want to display on the
screen. We can think of it as hidden fields used in simple HTML tags.

04
www.AppsLead.com
Bean: oracle.apps.fnd.framework.webui.beans.form.OAFormValueBean

Spacer

This bean is used to add spaces between items/regions. It has properties for height and width. So we can have
horizontal or vertical spacing as per our requirement.

Bean: oracle.apps.fnd.framework.webui.beans.layout.OASpacerBean

Flex

By using flex item, we can create both KFF and DFF in OA framework.

Bean: oracle.apps.fnd.framework.webui.beans.OADescriptiveFlexBean
Bean: oracle.apps.fnd.framework.webui.beans.OAKeyFlexBean

UrlInclude

If we want to embed HTML content from external source, we can use UrlInclude bean. It has a property for 'URL
source' where we can specify the complete URL path for that HTML content.

Bean: oracle.apps.fnd.framework.webui.beans.include.OAUrlIncludeBean

Tip

Tips are used for providing hints to users. We can associate tips with lots of items by using a property: 'Tip Type'.
For that we have to create a message in application message dictionary.
However, OAF provides a separate item for tip. We can either type the tip text directly in the text property or we
can define a message in application message dictionary and then attach with the tip bean.

Bean: oracle.apps.fnd.framework.webui.beans.OATipBean

09
www.AppsLead.com
Regions in OA Framework
The view part in OAF consists of pages which in turn contains regions and items.

Regions act as containers for different items and there can be multiple regions inside one region. These are
mainly used to organize the contents of pages.

In OAF, every item and region is a java bean.

OA Framework offers lots of regions which helps in building the application easier. I am just providing a brief
description of some of these regions:

PageLayout Region

By default this is the top most region for any OAF page. We can create any number of regions/items as children
of this region. It provides some common functionalities to all pages like footer (privacy & copyright links), root
AM, window title, title, function name etc..

Bean: oracle.apps.fnd.framework.webui.beans.layout.OAPageLayoutBean

DefaultSingleColumn Region

This region is used for holding items in single column. Suppose we added 4 items inside this region, then all these
item appear in one single column as shown below:

Bean: oracle.apps.fnd.framework.webui.beans.layout.OADefaultSingleColumnBean

DefaultDoubleColumn Region

OAF DefaultDoubleColumn region is used to hold items in two columns. Prompt of items will be right justified
and the input fields will be left justified.
For example as shown below, six items are added under this region which appears in two columns (3 items in
each):

33
www.AppsLead.com
Bean: oracle.apps.fnd.framework.webui.beans.layout.OADefaultDoubleColumnBean

MessageComponentLayout Region

It serves the multiple column display of components in an OAF page and also satisfies the standard UI guidelines.
messageComponentLayout region set Rows =x and columns =y in property inspector. Now this is used instead of
DefaultSingleColumn and DefaultDoubleColumn.

TableLayout, RowLayout, CellFormat Region

We can create our items using messageComponentLayout region by setting number of rows and columns.
However if that doesn't satisfy our requirement, then we can use tableLayout region and can place the items
manually as we want. It provides 2 regions (rowLayout & cellFormat) using which we can have different number
of columns for each row. All together, these 3 regions work as follows:

 TableLayout can contain multiple rowLayout, each corresponding to a row.


 RowLayout contains multiple cellFormat, each corresponding to a column.
 Finally, inside cellFormat region, we can add different items.

Query Bean Region

When we want to perform a search on a page, instead of creating different items for criteria fields and serch
button, we can use query region. It provides built in functionality such as search panel ,advanced search panel
and Views Panel as shown below:

Bean: oracle.apps.fnd.framework.webui.beans.layout.OAQueryBean

HideShow Region

31
www.AppsLead.com
Using this region, we can show or hide regions or items which are inside this region. Also we can set default as
hidden or shown on page load.

Bean: oracle.apps.fnd.framework.webui.beans.layout.OADefaultHideShowBean

PageButtonBar Region

If we want to show some items at pagelayout level, we can use pageButtonBar region as direct child of
pageLayout region. Items under this region will be displayed at bottom as well as at top of the page.

Bean: oracle.apps.fnd.framework.webui.beans.nav.OAPageButtonBarBean

Table Region

Table region is used to display data in tabular form. It also supports other functionalities such as single/multiple
selection, sorting..

Bean: oracle.apps.fnd.framework.webui.beans.table.OATableBean

AdvancedTable Region
31
www.AppsLead.com
Advanced table extends the functionality of simple table region. It provides declarative support for these
functionalities for which we to write code if using simple table region. Advanced table has many rich features,
some of which can be like a table can now have an instruction text and even a tip, also table can have a
navigation bar, selection column, add rows button, control bar, recalculate and many more.

Bean: oracle.apps.fnd.framework.webui.beans.table.OAAdvancedTableBean

ContentContainer Region

This region has some special properties which differentiates it from other regions. It can have different
background color which can be set using shade property. It can have border all around so that it can be easily
identified as separate region as shown below:

Bean: oracle.apps.fnd.framework.webui.beans.layout.OAContentContainerBean

FlowLayout Region

When we want to associate an item (mainly a button) with table or advanced table, we can create a flowLayout
region. This is much easier than using tableLayout/rowLayout/cellFormat regions for performing this task.

Bean: oracle.apps.fnd.framework.webui.beans.layout.OAFlowLayoutBean

Switcher Region

30
www.AppsLead.com
Switcher region is used to dynamically switch between the items displyed in a region. It is similar to CASE
statement used in programming languages. For example, using this we can show an item on one condition and
hide/disable the same on another condition.

Bean: oracle.apps.fnd.framework.webui.beans.OASwitcherBean

Train Region

Suppose we have a scenario where to complete one transaction we have to navigate multiple pages such as
step1, step2...

Here we can use train region which provides built in functionality for showing different stages of transaction and
highlight active page.

Bean: oracle.apps.fnd.framework.webui.beans.nav.OATrainBean

hGrid Region

This region is used when we want to display information in hierarchial structure.

Bean: oracle.apps.fnd.framework.webui.beans.table.OAHGridBean

33
www.AppsLead.com
Bound Values in OA framework - I
A web bean in OAF(UIX) consists of

 Indexed Children
 Named Children
 Attributes.

Attributes can be specified at design time in which case it will be a simple name/value pair and value of that
attribute will be static. Attribute value can also be determined during run time. If the attribute value has to be
determined runtime it must be bound to a data source. When OAF(UIX) is building/rendering these UI nodes it
establishes a context called rendering context. And to acheive this runtime behavior we get the data source from
this rendering context.

Lets convert the above statement in English Language to Java language

RenderingContext - Interface representing the context when OAF(UIX) builds(renders) the UI nodes.
BoundValue - Is a simple interface with a single method getValue(RenderingContext context). It is left to the
implementation of getValue() method to achieve the run time behavior based on rendering context object.

So OAWebBean (MutableUINode to be precise) have a method to set attribute value.

public void setAttributeValue(AttributeKey attrKey,Object value)

Value can be any implementation of BoundValue interface if it must be determined at runtime.

And at run time, when OAF(UIX) uses getAttributeValue(RenderingContext context, AttributeKey key), a typical
code might look like

if ((value instanceof BoundValue))


{
return ((BoundValue)value).getValue(context);
}

Generally the parameters that determine the run time value will be passed to the constructor of BoundValue
implementing object. For example DataBoundValue is a implementation of BoundValue which reads value based
on DataObject in the context. DataObject is very simple interface to extract arbitarily structured data.

So one of the construtor of that Class is

public DataBoundValue(
Object select
)

where the parameter, select, is used to get the DataObject from RenderingContext.

And getValue() method implementation will be simple

return context.getCurrentDataObject().selectValue(context, select);

32
www.AppsLead.com
Bound Values in OA framework - II
Lets take a closer look at the interface DataObject.

From javadoc

The DataObject interface provides an extremely simple API for retrieving arbitrarily structured data. All "queries"
are based simply on a selection string. It is entirely up to an implementation of this interface to define the syntax
for these strings.

It has only one method.

public java.lang.Object selectValue(RenderingContext context, java.lang.Object select)

OA Framework creates a named DataObject for each data source and then caches the DataObject on
oracle.cabo.ui.RenderingContext. A data source is identified by the view usage name set on the web bean. OA
Framework then gets the value from the DataObject using the view attribute on the bean as a lookup key.

OAWebBean.getValue() >> delegates to OADataBoundValue.getValue(RenderingContext context) and passes


rendering context as parameter >> which lookups DataObject from
renderingcontext based on view usage name setup in the web bean and calls that DataObject.selectValue () with
view attribute name as lookup key.

For a table bean OA fraemwork creates DataList which is a list of DataObject.


ReneringContext.getCurrentDataObject() will return the DataObject for the current processing
row.

So code in OADataBoundValue.getValue(RenderingContext context) will look like

DataObject dataobject = renderingcontext.getCurrentDataObject();


if(dataobject == null) {
// will return view usage name
String s = ((OAWebBeanData)mOAWebBean).getDataObjectName();
if(s != null) {
// first parameter is name space URI
dataobject = renderingcontext.getDataObject(
"oracle.apps.fnd.framework",
s);
}
}
// gets view attribute name
String s1 = ((OAWebBeanDataAttribute)mOAWebBean).getDataAttributeName();
if(s1 != null && !s1.equals(""))
return dataobject.selectValue(renderingcontext, s);

Most of the above things are just good to know kind of information. So lets take a look at this in OAF developer
perspective on how to use this.

Typical use cases are


(a) To programaticaly bind a web bean property like "Rendered" or "Prompt" etc to a view object
(b) To programaticaly set fire action event parameters.

STEP 1: Find out whether the web bean takes BoundValue as parameter for the property/attribute.
STEP 2: Find the right BoundValue implementation to pass it to the web bean. For example for the USE CASE (a)
we will use OADataBoundValueViewObject and for USE CASE (b) we will use OADataBoundValueFireActionURL.
STEP 3: Determine the parameters required to be passed to the BooundValue constructor.
STEP 4: Create the corresponding BoundValue object and pass it to the setAttribute() method.

36
www.AppsLead.com
Example 1: (Based on USE CASE a: To set prompt of web bean to a view object)

OAMessageStyledTextBean mTextBean =
(OAMessageStyledTextBean)webBean.findChildRecursive("TextID");
OADataBoundValueViewObject promptBV =
new OADataBoundValueViewObject(mTextBean, "VoAttribute");
mTextBean.setAttributeValue(
oracle.cabo.ui.UIConstants.PROMPT_ATTR, promptBV);

Example 2: (Based on USE CASE b: To set fire action event programaticaly )

OAMessageStyledTextBean b =
(OAMessageStyledTextBean)createWebBean(
pageContext,
MESSAGE_STYLED_TEXT_BEAN,
"NUMBER",
"TextID");
b.setViewUsageName("ViewusageName");
b.setViewAttributeName("ViewAttributeName");
Hashtable params = new Hashtable(1);
OADataBoundValueFireActionURL fireEventBV = new
OADataBoundValueFireActionURL(webBean,"{$ViewAttributeName}");
params.put("FireEventParameter",fireEventBV);
b.setFireActionForSubmit("fireEvent",null,
params,false,false);

37
www.AppsLead.com
Some JDeveloper Concepts and Tips
File Type: jpr jpx jws

JPR - JDeveloper Project File

jws - JDeveloper Workspace File

JPX - The.jpx Information File contains configuration that JDeveloper uses in the Design time to allow you to

Create the Data Model project.

make vs rebuild

"Make" JDeveloper should detect that the java file doesn't need recompiling and skip it.

"Rebuild" JDeveloper should recompile everything whether or not it needs it.


Embedded OC4J Server

Oracle Application Server Containers for J2EE (OC4J) is a program that allows J2EE applications to run on the

Oracle Application Server. OC4J offers a lightweight, easy to use, high performance J2EE environment. The J2EE

facilities provided by OC4J include an Enterprise JavaBeans (EJB ) container, a Java Servlet container, and a

JavaServer Pages Translator and runtime (ojsp).

By Default, your Server-Side Java applications run in a Version of OC4J that is Embedded in JDeveloper. Use this

Server to Debug, test, and optimize your J2EE applications locally, prior to Deploying them to a target Application

Server. OC4J: How to set Java Embedded OC4J option in Project Properties-> Run/Debug-> Launch Setting

Include and Exclude

If the Project is very much inside the file, JDev often very slow, then you can use the Project Properties -> Project

Content, and to set up the project through Include and Exclude show what, do not show anything. Once set, the

file will load much faster speed significantly.

34
www.AppsLead.com
39
www.AppsLead.com
Restoring JDeveloper Stander Setup

Some times in Jdeveloper by chance we change the default winodowing layout like
(structure window,Log window etc) it will be difficult to again get the Initial Layout in that
case just search for the following windowinglayout.xml file delete it and just close
the Jdeveloper and Reopen it will Re-Arrange
as Defualt

23
www.AppsLead.com
Starting a new module/applciation?? Follow the following steps!!
Developers often fall in a dilemma where to start and how to start, when asked to develop an OAF
application/module from scratch. Here are few guidelines which can make the developer’s work easier and help
to build it faster.

Note : : Following are generic steps for starting an application. They may slightly vary as per the requirement.

Ø Database design should precede development

i) Tables must be ready

ii) Queries for all List of Values must be ready

iii) Queries for Common VOs must be ready

Ø Decide the required package structure, module wise, for all the modules in your application. See to it that
the package is distributed to the lowest level possible to increase modularity and also ease the migration process.
It also overcomes the integration issues by reducing the dependency.

Ø Create all the necessary EOs related to the tables that are required for the application. There should be only
one EO per table and it should be reused for several VOs.

Ø Create Association Objects (AOs) ,if any, to establish relation between EOs.

Ø If you have any entity validations, create Entity Experts for all your EOs

Ø Create all the common LOV VOs in the LOV server package.

Ø Create one application module for containing all the LOV VOs

Ø Create LOV regions based on LOV VOs and attach respective COs to the regions if required.

Ø Create all the common VOs for your application.

Ø Create View Links (VLs) ,if any, to establish relation between different VOs.

Ø Create Application Module (The Application Module must be reused across pages. Create one application
module per Application/Module based on the complexity. If the module is too complex, you may divide it into
segments(set of pages) and create one Application Module per segment(s)). And attach all the VOs to the
Application Module

Finally, create PG files and COs and attach the corresponding Applciation Module to the pages.

Using Code Templates in JDeveloper


While coding in JDev, we often use code templates. For example, for writing 'System.out.println();', we can write
'sop' then press ctrl+Enter.
We can also create our own code templates and then when required, instead of writing the complete code, we
can simply use custom shortcuts for our code.

Here I have shown how to create and use these custom code templates.

Mostly we face a requirement to navigate from one page to another on button click and also passing some
parameters along with that. Below are steps for creating template for this:

21
www.AppsLead.com
1) Go to 'Tools --> Preferences...'

2) On Preferences window, expand 'Code Editor --> Code Templates'.

3) Click on Add, enter shortcut and description. In the code tab, write the code which you want on that shortcut
as shown below:

21
www.AppsLead.com
4) Also, if we want to import some classes for that code, we can write those in 'Imports' tab.

5) Now we only need to write this shortcut 'navOnBtn' then press ctrl+Enter. This will automatically replace that
shortcut name with the complete code.

20
www.AppsLead.com
OAF Hello World Tutorial

1. Create a New OA Workspace and Empty OA Project

File> New > General> Workspace Configured for Oracle Applications

23
www.AppsLead.com
22
www.AppsLead.com
26
www.AppsLead.com
2. Set Run Options in OA Project Setting

Select Your Project in the Navigator and choose Project Properties

Select Oracle Applications > Run Options

Select OADeveloperMode and OADiagnostic, and move them to selected Options List

27
www.AppsLead.com
3. Create Application Module AM

24
www.AppsLead.com
29
www.AppsLead.com
63
www.AppsLead.com
61
www.AppsLead.com
4. Create a OA components Page

61
www.AppsLead.com
60
www.AppsLead.com
5. Modify the Page Layout (Top-level) Region

63
www.AppsLead.com
Attribute Property

ID PageLayoutRN

Region Style pageLayout

Form Property True

Auto Footer True

Window Title Hello World Window Title

Title Hello World Page Header

AM Definition prajkumar.oracle.apps.ak.hello.server.HelloAM

62
www.AppsLead.com
6. Create the Second Region (Main Content Region)

66
www.AppsLead.com
Attribute Property

ID MainRN

Region Style messageComponentLayout

7. Create the first Item (Empty Field)

MainRN > New > messageTextInput

67
www.AppsLead.com
Attribute Property

ID HelloName

Style Property messageTextInput

Prompt Name

Length 20

Maximum Length 50

64
www.AppsLead.com
8. Create a container Region for Go-Button

MainRN > messageLayout

69
www.AppsLead.com
Attribute Property

ID ButtonLayout

73
www.AppsLead.com
9. Create a Second Item (Go Button)

Select ButtonLayout > New > Item

71
www.AppsLead.com
Attribute Property

ID Go

Item Style submitButton

Attribute /oracle/apps/fnd/attributesets/Buttons/Go

71
www.AppsLead.com
70
www.AppsLead.com
10. Save Your Work

11. Run Your Page UI is ready

73
www.AppsLead.com
12. Add a Controller

MainRN > Set New Controller

72
www.AppsLead.com
13. Edit Your Controller

Add Following OA Exception as a last line in import section

import oracle.apps.fnd.framework.OAException;

Add Following Code in processFormRequest

public void processFormRequest(OAPageContext pageContext, OAWebBean webBean)

super.processFormRequest(pageContext, webBean);

if (pageContext.getParameter("Go") != null)

String userContent = pageContext.getParameter("HelloName");

String message = "Hello, " + userContent + "!";

throw new OAException(message, OAException.INFORMATION);

76
www.AppsLead.com
14. Build Your Controller

77
www.AppsLead.com
15. Test Your Work Your Hello World Page is Ready

74
www.AppsLead.com
79
www.AppsLead.com
Create Data Entry OAF Page

1. Create a New Workspace and Project

Right click Workspaces and click create new OAworkspace and name it as PRajkumarInsert. Automatically a new
OA Project is also created. Name the project as InsertDemo and package as
prajkumar.oracle.apps.fnd.insertdemo

2. Create a New Application Module (AM)

Right Click on InsertDemo > New > ADF Business Components > Application Module

Name -- InsertAM

Package -- prajkumar.oracle.apps.fnd.insertdemo.server

3. Enable Passivation for the Root UI Application Module (AM)

Right Click on InsertAM > Edit InsertAM > Custom Properties >

Name – RETENTION_LEVEL

Value – MANAGE_STATE

Click add > Apply > OK

4. Create Test Table in which we will insert data (For Testing Purpose)

CREATE TABLE xx_insert_demo


( -- ---------------------
-- Data Columns
-- ---------------------
column1 VARCHAR2(100),
column2 VARCHAR2(100),
-- ---------------------
-- Who Columns
-- ---------------------
last_update_date DATE NOT NULL,
last_updated_by NUMBER NOT NULL,
creation_date DATE NOT NULL,
created_by NUMBER NOT NULL,
last_update_login NUMBER
);

5. Create a New Entity Object (EO)

Right click on InsertDemo > New > ADF Business Components > Entity Object

Name – InsertEO

Package -- prajkumar.oracle.apps.fnd.insertdemo.schema.server
43
www.AppsLead.com
Database Objects -- XX_INSERT_DEMO

Note – By default ROWID will be the primary key if we will not make any column to be primary key.

Check the Accessors, Create Method, Validation Method and Remove Method

6. Create a New View Object (VO)

Right click on InsertDemo > New > ADF Business Components > View Object

Name -- InsertVO

Package -- prajkumar.oracle.apps.fnd.insertdemo.server

In Step2 in Entity Page select InsertEO and shuttle them to selected list

In Step3 in Attributes Window select columns Column1, Column2 and shuttle them to selected list

In Java page deselect Generate Java file for View Object Class: InsertVOImpl and Select Generate Java File for
View Row Class: InsertVORowImpl

7. Add Your View Object to Root UI Application Module

Right click on InsertAM > Edit InsertAM > Data Model >

Select InsertVO in Available View Objects list and shuttle to Data Model list

8. Create a New Page

Right click on InsertDemo > New > Web Tier > OA Components > Page

Name -- InsertPG

Package -- prajkumar.oracle.apps.fnd.insertdemo.webui

9. Select the InsertPG and go to the strcuture pane where a default region has been created

10. Select region1 and set the following properties:

ID -- PageLayoutRN

Region Style -- PageLayout

AM Definition -- prajkumar.oracle.apps.fnd.insertdemo.server.InsertAM

Window Title -- Date Entry Page Window

Title -- Data Entry Page

Auto Footer -- True

41
www.AppsLead.com
11. Right click PageLayoutRN > New > Region

ID -- MainRN

Region Style -- defaultSingleColumn

12. Create Text Input Items

Right click on MainRN > New > Item

Set following properties for New Item

ID -- COLUMN1

Item Style -- messageTextInput

Maximum Length -- 100

Length -- 20

Prompt -- Column1

View Instance -- InsertVO1

View Attribute -- Column1

Again Right click on MainRN > New > Item

Set following properties for New Item

ID -- COLUMN2

Item Style -- messageTextInput

Maximum Length -- 100

Length -- 20

Prompt -- Column2

View Instance -- InsertVO1

View Attribute – Column2

13. Add Apply and Cancel Buttons

Right click on PageLayoutRN > New > Region

ID -- PageButtons

Region Style -- pageButtonBar

Right click on PageButtons > New > Item

ID -- Cancel

Item Style -- submitButton

41
www.AppsLead.com
Attribute Set -- /oracle/apps/fnd/attributesets/Buttons/Cancel

Disable Server Side Validation -- True

Prompt -- Cancel

Warm About Changes -- False

Additional Text – Select to cancel this transaction.

Right click on PageButtons > New > Item

ID -- Apply

Item Style -- submitButton

Attribute Set -- /oracle/apps/fnd/attributesets/Buttons/Apply

Prompt -- Apply

Additional Text – Select to save this transaction.

14. Implement Row Initialization (Create a View Object Row)

Add createRecord method to your InsertAMImpl class

import oracle.jbo.Row;
import oracle.apps.fnd.framework.OAViewObject;
...

public void createRecord()


{
OAViewObject vo = (OAViewObject)getInsertVO1();

if (!vo.isPreparedForExecution())
{
vo.executeQuery();
}

Row row = vo.createRow();


vo.insertRow(row);
row.setNewRowState(Row.STATUS_INITIALIZED);
}

15. Create Controller for Page

PageLayoutRN > Set New Controller >

Package Name: prajkumar.oracle.apps.fnd.insertdemo.webui

Class Name: InsertCO

16. Add Create Page Initialization to your Controller


40
www.AppsLead.com
Add following code to your processRequest()

import oracle.apps.fnd.framework.OAApplicationModule;
...

public void processRequest(OAPageContext pageContext,OAWebBean webBean)


{
super.processRequest(pageContext, webBean);

if (!pageContext.isFormSubmission())
{
OAApplicationModule am = pageContext.getApplicationModule(webBean);
am.invokeMethod("createRecord", null);
}
}

17. Add below method in InsertAMImpl Class to handle Apply Button action

import oracle.jbo.Transaction;
...

public void apply()


{
getTransaction().commit();
}

18. Add below Logic in InsertCO to handle Apply Button

Add following code to your processFormRequest()

import oracle.jbo.domain.Number;
import oracle.apps.fnd.common.MessageToken;
import oracle.apps.fnd.framework.OAException;
import oracle.apps.fnd.framework.OAViewObject;
import oracle.apps.fnd.framework.webui.OAWebBeanConstants;
...

public void processFormRequest(OAPageContext pageContext, OAWebBean webBean)

{super.processFormRequest(pageContext, webBean);
OAApplicationModule am = pageContext.getApplicationModule(webBean);

// Pressing the "Apply" button means the transaction should be


// validated and committed.

if (pageContext.getParameter("Apply") != null)
{
OAViewObject vo = (OAViewObject)am.findViewObject("InsertVO1");

43
www.AppsLead.com
String column1 = (String)vo.getCurrentRow().getAttribute("Column1");
String column2 = (String)vo.getCurrentRow().getAttribute("Column2");

am.invokeMethod("apply");

// Create a FND Message with name "TEST_CREATE_CONFIRM" with two


// tokens
MessageToken[] tokens = { new MessageToken("COLUMN1", column1),
new MessageToken("COLUMN2", column2)
};

OAException confirmMessage = new OAException( "FND",


"TEST_CREATE_CONFIRM", tokens,
OAException.CONFIRMATION, null);

pageContext.putDialogMessage(confirmMessage);
pageContext.forwardImmediately(
"OA.jsp?page=/prajkumar/oracle/apps/fnd/insertdemo/webui/InsertPG",
null, OAWebBeanConstants.KEEP_MENU_CONTEXT,
null,
null,
true, // retain AM
OAWebBeanConstants.ADD_BREAD_CRUMB_NO);

42
www.AppsLead.com
19. Congratulations you have successfully created data insert page. Run InsertPG page to test Your Work

46
www.AppsLead.com
47
www.AppsLead.com
Ca

44
www.AppsLead.com
Page Creation in OAF - Supplier - Site Page

49
www.AppsLead.com
93
www.AppsLead.com
91
www.AppsLead.com
91
www.AppsLead.com
90
www.AppsLead.com
93
www.AppsLead.com
92
www.AppsLead.com
96
www.AppsLead.com
97
www.AppsLead.com
94
www.AppsLead.com
99
www.AppsLead.com
133
www.AppsLead.com
131
www.AppsLead.com
131
www.AppsLead.com
130
www.AppsLead.com
133
www.AppsLead.com
132
www.AppsLead.com
136
www.AppsLead.com
137
www.AppsLead.com
134
www.AppsLead.com
139
www.AppsLead.com
113
www.AppsLead.com
111
www.AppsLead.com
111
www.AppsLead.com
110
www.AppsLead.com
113
www.AppsLead.com
112
www.AppsLead.com
116
www.AppsLead.com
117
www.AppsLead.com
114
www.AppsLead.com
119
www.AppsLead.com
113
www.AppsLead.com
Code in Controller
==============

1 public void processRequest(OAPageContext pageContext, OAWebBean webBean)

2 {

3 super.processRequest(pageContext, webBean);

4 OAApplicationModule am=pageContext.getApplicationModule(webBean);

6 am.invokeMethod("CreateSupplierRow");

8 }

10

11 public void processFormRequest(OAPageContext pageContext, OAWebBean webBean)

12 {

13 super.processFormRequest(pageContext, webBean);

14 OAApplicationModule am=pageContext.getApplicationModule(webBean);

15

16 String event =pageContext.getParameter(OAWebBeanConstants.EVENT_PARAM);

111
www.AppsLead.com
17 String source =pageContext.getParameter(OAWebBeanConstants.SOURCE_PARAM);

18

19

20 if(pageContext.getParameter("Apply")!=null)

21 {

22 am.invokeMethod("SaveData");

23

24

25 //These five lines are to display the confirmation message..

26 String supId =pageContext.getParameter("SuppNumber");

27 String supName =pageContext.getParameter("SuppName");

28

29 MessageToken[] tokens = {new MessageToken("SUPID",supId),new MessageToken("SNAME",supName)};

30

31 OAException msg = new OAException("PO","SUPPLIER_SAVED_MSG",tokens,OAException.CONFIRMATION,null);

32 throw msg;

33 }

34

35 if(ADD_ROWS_EVENT.equals(event))

36 {

37 am.invokeMethod("CreateSitesRow");

38 }

39

40 }

41

42 }

Code in the AM
==============

?
1 public void CreateSupplierRow()

2 {

3 SuppliersEOVOImpl vo=getSuppliersEOVO1();

5 Row row=vo.createRow();

111
www.AppsLead.com
6

7 if(!vo.isPreparedForExecution())

8 {

9 vo.setMaxFetchSize(0);

10 }

11 vo.insertRow(row);

12

13 //we need to import import oracle.jbo.domain.Number

14 //Setting the sequence value to the Supplier ID attribute(field)

15 Number seq =getOADBTransaction().getSequenceValue("fwk_tbx_suppliers_s");

16

17 row.setAttribute("SupplierId",seq);

18

19 row.setNewRowState(Row.STATUS_INITIALIZED);

20

21 }

22

23

24 public void CreateSitesRow()

25 {

26 SitesEOVOImpl vo=getSitesEOVO1();

27

28 SuppliersEOVOImpl vo1=getSuppliersEOVO1();

29

30 Row siterow=vo.createRow();

31 if(!vo.isPreparedForExecution())

32 {

33 vo.setMaxFetchSize(0);

34 }

35 int count =vo.getRowCount();

36 vo.insertRowAtRangeIndex(count,siterow);

37

38

39 //Setting the sequence values in SupplierID,SuppliersiteID Attributes(fields).

110
www.AppsLead.com
40 Number seq =getOADBTransaction().getSequenceValue("fwk_tbx_supplier_sites_s");

41 String mSupId =vo1.getCurrentRow().getAttribute("SupplierId").toString();

42

43 siterow.setAttribute("SupplierId",mSupId); //Setting the sequence value in SupplierID attribute

44 siterow.setAttribute("SupplierSiteId",seq); //Setting the sequence value in SupplierSiteId Attribute

45 siterow.setAttribute("SerialNum",count+1); //Setting the sequence value in SerialNum Transient Attribute.

46

47

48

49 siterow.setNewRowState(Row.STATUS_INITIALIZED);

50

51

52

53 }

54 //Written by Shashi..

55 public void SaveData()

56 {

57 this.getTransaction().commit();

58 }

59

60 }

113
www.AppsLead.com
Entity Level Validation for StartDate and End Date comparison
Entity Level Validation for StartDate and End Date comparison

In EOImpl.java

protected void validateEntity()


{
super.validateEntity();
Date sdate=getStartdate();
Date Edate=getEnddate();
if(sdate.dateValue().getTime()>Edate.dateValue().getTime())
{
throw new OAAttrValException(OAException.TYP_ENTITY_OBJECT,
getEntityDef().getFullName(), // EO name
getPrimaryKey(), // EO PK
"Enddate", // Attribute Name
Edate, // Attribute Value
"AK", // Message product short name
"FWK_TBX_T_END_DATE_PAST"); // Message name

}
}

112
www.AppsLead.com
Create and Update on one click in OA Framework

We will try to implement Search Page with one text item as ID. Based on ID control will go to second page.
Second page contain three text rows. ID will be displayed on second page as Styled Text in all three rows

If match will be found based on ID then search result will come. If not found then empty rows will come. Based
on that new data can be inserted there and existing data can be updated directly with one button click ‘Apply’

1. Create a New Workspace and Project

Right click Workspaces and click create new OAworkspace.

File Name – PrajkumarSearch

Project Name -- SearchDemo

package -- prajkumar.oracle.apps.fnd.searchdemo

2. Create a New Application Module (AM)

Right Click on SearchDemo > New > ADF Business Components > Application Module

Name -- SearchAM

Package -- prajkumar.oracle.apps.fnd.searchdemo.server

3. Enable Passivation for the Root UI Application Module (AM)

Right Click on SearchAM > Edit SearchAM > Custom Properties >

Name – RETENTION_LEVEL

Value – MANAGE_STATE

Click add > Apply > OK

4. Create Test Table and insert data some data in it (For Testing Purpose)

CREATE TABLE xx_create_upd_demo


( -- ---------------------
-- Data Columns
-- ----------------------
column1 VARCHAR2(100),
column2 VARCHAR2(100),
column3 VARCHAR2(100),
column4 NUMBER,
-- ---------------------
-- Who Columns
-- ---------------------
last_update_date DATE NOT NULL,
last_updated_by NUMBER NOT NULL,
creation_date DATE NOT NULL,
created_by NUMBER NOT NULL,

116
www.AppsLead.com
last_update_login NUMBER
);

5. Create a New Entity Object (EO)

Right click on SearchDemo > New > ADF Business Components > Entity Object

Name – SearchEO

Package -- prajkumar.oracle.apps.fnd.searchdemo.schema.server

Database Objects -- xx_create_upd_demo

Note – By default ROWID will be the primary key if we will not make any column to be primary key.

Check the Accessors, Create Method, Validation Method and Remove Method

6. Create a New View Object (VO)

Right click on SearchDemo > New > ADF Business Components > View Object

Name -- SearchVO

Package -- prajkumar.oracle.apps.fnd.searchdemo.server

In Step2 in Entity Page select SearchEO and shuttle them to selected list

In Step3 in Attributes Window select columns Column1, Column2, Column3, Column4 and shuttle them to
selected list

In Java page select Generate Java File for View Object Class: SearchVOImpl and Generate Java File for View Row
Class: SearchVORowImpl

7. Add Your View Object to Root UI Application Module

Select Right click on SearchAM > Application Modules > Data Model >

Select SearchVO and shuttle to Data Model list

8. Create a New Page

Right click on SearchDemo > New > Web Tier > OA Components > Page

Name -- SearchPG

Package -- prajkumar.oracle.apps.fnd.searchdemo.webui

9. Select the SearchPG and go to the strcuture pane where a default region has been created

10. Select region1 and set the following properties:

117
www.AppsLead.com
ID – PageLayoutRN

Scope -- Public

Region Style -- PageLayout

AM Definition -- prajkumar.oracle.apps.fnd.searchdemo.server.SearchAM

Window Title –Page Window

Title – Page Header

Auto Footer – True

11. Create the Second Region (Main Content Region)

ID – MainRN

Region Style -- messageComponentLayout

Auto Footer – True

12. Create the first Item (Empty Field)

MainRN > New > messageTextInput

Set Following properties for new item

ID – MyId

Style Property – messageTextInput

Prompt – Id

Data Type – Number

Length – 20

Maximum Length – 100

13. Create a container Region for Go-Button

MainRN > messageLayout

Set ID -- ButtonLayout

14. Create a Item (Go Button)

Select ButtonLayout > New > Item

ID – Go

Item Style – submitButton

Attribute -- /oracle/apps/fnd/attributesets/Buttons/Go

114
www.AppsLead.com
15. Create a New Second Page

Right click on SearchDemo > New > Web Tier > OA Components > Page

Name -- CreateUpdPG

Package -- prajkumar.oracle.apps.fnd.searchdemo.webui

16. Select the CreateUpdPG and go to the strcuture pane where a default region has been created

17. Select region1 and set the following properties:

ID – PageLayoutRN

Scope -- Public

Region Style -- PageLayout

AM Definition -- prajkumar.oracle.apps.fnd.searchdemo.server.SearchAM

Window Title –Page Window

Title – Page Header

Auto Footer – True

18. Create the Second Region (Main Content Region)

ID – MainRN

Region Style -- table

Auto Footer – True

Records Displayed – 3

19. Create the first Item (Empty Field)

MainRN > New > item

Set Following properties for new item

ID – Column1

Style Property – messageTextInput

Prompt – Column1

Data Type – VARCHAR2

Length – 20

Maximum Length – 100

View Instance -- SearchVO1

View Attribute -- Column1

119
www.AppsLead.com
Create Second Item

MainRN > New > item

Set Following properties for new item

ID – Column2

Style Property – messageTextInput

Prompt – Column2

Data Type – VARCHAR2

Length – 20

Maximum Length – 100

View Instance -- SearchVO1

View Attribute -- Column2

Create Third Item

MainRN > New > item

Set Following properties for new item

ID – Column3

Style Property – messageTextInput

Prompt – Column3

Data Type – VARCHAR2

Length – 20

Maximum Length – 100

View Instance -- SearchVO1

View Attribute -- Column3

Create Fourth Item

MainRN > New > item

Set Following properties for new item

ID – Column4

Style Property – messageStyledText

Prompt – Column4

Data Type – NUMBER

View Instance -- SearchVO1

103
www.AppsLead.com
View Attribute -- Column4

20. Add Controller for Page SearchPG Select PageLayoutRN right click Set New Controller

Package Name -- prajkumar.oracle.apps.fnd.searchdemo.webui

Class Name -- SearchCO

Add Following code in that controller

import com.sun.java.util.collections.HashMap;

import oracle.apps.fnd.framework.webui.OAWebBeanConstants;

public void processFormRequest(OAPageContext pageContext, OAWebBean webBean)


{
super.processFormRequest(pageContext, webBean);

if (pageContext.getParameter("Go") != null)
{
String userContent = pageContext.getParameter("MyId");
HashMap hmap = new HashMap();
hmap.put("MyId", userContent);

pageContext.setForwardURL(
"OA.jsp?page=/prajkumar/oracle/apps/fnd/searchdemo/webui/CreateUpdPG",
null,
OAWebBeanConstants.KEEP_MENU_CONTEXT,
null,
hmap,
true,
OAWebBeanConstants.ADD_BREAD_CRUMB_NO,
OAWebBeanConstants.IGNORE_MESSAGES);
}
}

21. Add Return Link to come back to SearchPG from CreateUpdPG

Select CreateUpdPG in Structure Panel Select PageLayoutRN > New > returnNavigation

ID – ReturnLink

Destination URI – OA.jsp?page=/prajkumar/oracle/apps/fnd/searchdemo/webui/SearchPG&retainAM=Y

Text – Return to SearchPG

22. Add pageButtonBar region to implement Apply Button

101
www.AppsLead.com
Right click on PageLayout > New > Region

Set following properties for new region

ID -- ButtonBar

Region Style – pageButtonBar

Select ButtonBar right click > New > Item

Select newly created item and set following properties –

ID – Apply

Item Style – submitButton

Attribute Set -- /oracle/apps/fnd/attributesets/Buttons/Apply

23. Add Controller for Page CreateUpdPG Select PageLayoutRN right click Set New Controller

Package Name -- prajkumar.oracle.apps.fnd.searchdemo.webui

Class Name -- CreateUpdCO

Add Following code in that controller

import java.io.Serializable;
import oracle.apps.fnd.framework.OAApplicationModule;
import oracle.apps.fnd.framework.webui.OAWebBeanConstants;

public void processRequest(OAPageContext pageContext, OAWebBean webBean)


{ super.processRequest(pageContext, webBean);

OAApplicationModule am = pageContext.getApplicationModule(webBean);

String val = pageContext.getParameter("MyId");

Serializable[] params = { val };


am.invokeMethod("createRow", params);
}

public void processFormRequest(OAPageContext pageContext, OAWebBean webBean)


{ super.processFormRequest(pageContext, webBean);

OAApplicationModule am = pageContext.getApplicationModule(webBean);

if (pageContext.getParameter("Apply") != null)
{ am.getTransaction().commit();
pageContext.setForwardURL(
"OA.jsp?page=/prajkumar/oracle/apps/fnd/searchdemo/webui/SearchPG",
null,
OAWebBeanConstants.KEEP_MENU_CONTEXT,
null,
null,
101
www.AppsLead.com
true,
OAWebBeanConstants.ADD_BREAD_CRUMB_NO,
OAWebBeanConstants.IGNORE_MESSAGES);
}
}

24. Add Following code in SearchAMImpl.java

import oracle.apps.fnd.framework.server.OAApplicationModuleImpl;
import oracle.jbo.Row;

public void createRow(String Val)


{
SearchVOImpl vo = getSearchVO1();
vo.initQuery(Val);

int rowCount = vo.getRowCount();


if ( rowCount < 3 )
{
for(int i = 3; i != rowCount ; rowCount++)
{
Row studrow = vo.createRow();
vo.last();
vo.next();

vo.insertRow(studrow);
vo.setCurrentRow(studrow);
vo.getCurrentRow().setAttribute("Column4",Val);
studrow.setNewRowState(Row.STATUS_INITIALIZED);
}
}
}

25. Add Following code in SearchVOImpl.java

import oracle.jbo.domain.Number;
import oracle.apps.fnd.framework.OAException;
import oracle.apps.fnd.framework.server.OAViewObjectImpl;

public void initQuery(String Val)


{
if ((Val != null) && (!("".equals(Val.trim()))))
{
// Do the following conversion for type consistency.
Number Val2 = null;

try

100
www.AppsLead.com
{
Val2 = new Number(Val);
}
catch(Exception e)
{
throw new OAException("AK", "FWK_TBX_INVALID_EMP_NUMBER");
}

setWhereClause("Column4 = :1");
setWhereClauseParams(null); // Always reset
setWhereClauseParam(0, Val2);
executeQuery();
}
}

26. Congratulation you have successfully finished. Run Your SearcgPG page and Test Your Work

103
www.AppsLead.com
C

102
www.AppsLead.com
Create and Update Page in OAF
Here are the steps for creating 'Employee create update' page. I have modified the search page created in
previous post.

1) Create a new Entity Object (EO):


===================

Right click on 'emprec' package and create a new entity object (This will open a wizard having 5 steps).

Step 1
Package: xxcus.oracle.apps.fnd.emprec.schema.server
Name: XxEmployeeEO
Schema Object (in Database Object): EMPLOYEE
Click Next.

Step 2
Keeps default (all attributes selected). Click Next.

Step 3
If there is any primary key in DB table, then keep all defaults else select a primary key (like empno). Click
Next.

Step 4
Keep defaults and click on Next.

Step 5
Keep 'Generate Default View Object' uncheked and click on Finish.

2) Create a new View Object (VO) based on EO created in (1):


====================
Right click --> New View Object (This will open a wizard having 7 steps).

Step 1
Package: xxcus.oracle.apps.fnd.emprec.server
Name: XxEmployeeVO
Choose the radio button 'Updatable access through Entity Objects'. Click Next.

Step 2
Select the xxcus.oracle.apps.fnd.emprec.schema.server.XxEmployeeEO from 'Available' list and shuttle it to
'Selected' list. Click Next.

Step 3
Move all the columns except WHO columns (lastUpdateLogin, createdBy...) to 'Selected' list from 'Available'
list attributes.
Click Next.

Keep defaults for step 4, 5 & 6.

Step 7
Select check boxes for 'Generate Java File' for both 'View Object Class' and 'View Row Class'. Click Finish.

Double Click on XxEmployeeAM and shuttle XxEmployeeVO from 'Available view objects' to 'Data Model'.
(now there are two VO instances in AM :XxEmployeeSearchVO1 & XxEmployeeVO1).

3) Edit Employee Search Page (XxEmployeeSearchPG):


====================

106
www.AppsLead.com
(This includes adding a 'create button' at top & 'update' icon on every row in search result. Modified page will
appear as below:).

Step 1
Right click on pageLayoutRN and add a new region. Set properties as below:
Region Style: pageButtonBar
ID: pageBtnBarRN

Right click on pageBtnBarRN region and add a new item:


Item Style: submitButton
ID: createBtn
Prompt: Create Employee

Step 2
Right click on XxEmployeeSearchVO1 table region and add an item. Set the below properties:
Item Style: Image
ID: updateImg
Prompt: Update

107
www.AppsLead.com
Image URI: updateicon_enabled.gif
Action Type: fireAction
Event: updateEvent
Parameters: it will open a new window. Add a parameter as below:
Name: p_empNum value: ${oa.XxEmployeeSearchVO1.Empno}

4) Create a new Update Create page:


====================
(Here user can either create a new employee or can update existing one. The page will appear as shown below: ).

Right click emprec --> New --> Web Tier --> OA Components --> select 'Page' item. Click OK. (This will open a
popup window)
We are creating Employee Create Update Page, so specify the details of page as below:
Name: XxEmployeeCreateUpdatePG
Package: xxcus.oracle.apps.fnd.emprec.webui

Create a new region under pageLayout of type 'header'

Create another region under the header region using wizard


(This will open a wizard window having 4 steps):

 Select 'XxEmployeeAM' from Application Module drop down and select 'XxEmployeeVO1' in available
view usages. Click Next.
 Choose region style as 'defaultSingleColumn' from drop down. Click Next.
 Shuttle all the fields from available to selected attributes. Click Next.
 Change the style to messageStyledText for Empno and messageTextInput for other remaining rows.
Also modify the prompt to make it more user friendly (like empName to Employee Name).
 Click Next and finish.

Right click on pageLayoutRN and add a new region

Set properties as below:


Region Style: pageButtonBar
ID: pageBtnBarRN

Right click on pageBtnBarRN region and add 2 new items of type submitButton:
Item Style: submitButton
ID: saveBtn; ID: cancelBtn
104
www.AppsLead.com
prompt: Save; prompt: Cancel

Now change the properties for each field from property inspector as shown below:

pageLayout: ID: pageLayoutRN


AM Definition: xxcus.oracle.apps.fnd.emprec.server.XxEmployeeAM
Window Title: Employee Create Update Page
Title: Employee Create Update

header: ID: empCreateRN

5) Create a new controller for Update Create page:


====================
Step 1
Select XxEmployeeCreateUpdatePG in navigator tab. Declarative form of page will be visible in structure tab.

Step 2
Right click on pageLayout region --> set new controller (This will open a popup window). Enter the below details:
package Name: xxcus.oracle.apps.fnd.emprec.webui
Class Name: XxEmployeeCreateUpdateCO

The declarative page structure in jDev will be similar to as shown below:

109
www.AppsLead.com
6) Code for Performing Create & Update Operation
====================

 Catch the 'create button' or 'Update' event in PFR method of XxEmployeeSearchCO (controller of
XxEmployeeSearchPG page) and navigate to 'Employee Create Update Page'
(XxEmployeeCreateUpdatePG). We also pass a token (in the form of HashMap) to indicate whether it is
a create or update operation.

1 // XxEmployeeSearchCO :: PFR
2 if (pageContext.getParameter("createBtn") != null) {

3 HashMap hm = new HashMap(); //com.sun.java.util.collections.HashMap;


4 hm.put("event", "create");
5 pageContext.forwardImmediately("OA.jsp?page=/xxcus/oracle/apps/

6 fnd/emprec/webui/XxEmployeeCreateUpdatePG",

7 null, (byte)0, null, hm, false, null);

8 }

133
www.AppsLead.com
9

10if ("updateEvent".equals(pageContext.getParameter(EVENT_PARAM))) {

11 String p_empNum = pageContext.getParameter("p_empNum");

12 HashMap hm = new HashMap();

13 hm.put("event", "update");

14 hm.put("empNum", p_empNum);

15pageContext.forwardImmediately("OA.jsp?page=/xxcus/oracle/apps/

16fnd/emprec/webui/XxEmployeeCreateUpdatePG",

17null, (byte)0, null, hm, false, null);

18}

 Once navigated to create page, we have to initialize the XxEmployeeVO1, so data entered by user in
the fields can be mapped to its attributes. And in case of 'update', populate the records for the
employee. We write this code in PR method of XxEmployeeCreateUpdateCO (controller
of XxEmployeeCreateUpdatePG page). First we check if it is create or update event and will call a
method from AM accordingly:

1 // XxEmployeeCreateUpdateCO :: PR method
2 public void processRequest(OAPageContext pageContext, OAWebBean webBean) {

3 super.processRequest(pageContext, webBean);
4 am = pageContext.getRootApplicationModule();
5

6 if ("create".equals(pageContext.getParameter("event"))) {
7 am.invokeMethod("initCreateEmp");
8 }
9

10 if ("update".equals(pageContext.getParameter("event"))) {

11 String empNum = pageContext.getParameter("empNum");


12 Serializable[] param = { empNum };
13 am.invokeMethod("initUpdateEmp", param);
14 }

15}

Write below methods in XxEmployeeAMImpl.java file:

1
// XxEmployeeAMImpl ::
2
public void initCreateEmp() {
3
try {
4

131
www.AppsLead.com
5 XxEmployeeVOImpl empCreateVO = getXxEmployeeVO1();

6 empCreateVO.setMaxFetchSize(0);

7 XxEmployeeVORowImpl row = (XxEmployeeVORowImpl)empCreateVO.createRow();

9 // here we are setting the employee number using a DB Sequence

10 Number empNum = getOADBTransaction().getSequenceValue("EMPLOYEE_NUMBER_S");

11 row.setEmpno(empNum);

12 empCreateVO.insertRow(row);

13 row.setNewRowState(Row.STATUS_INITIALIZED);

14 } catch () {

15 e.printStackTrace();

16 }

17}

18

19public void initUpdateEmp(String empNum) {

20 try {

21 XxEmployeeVOImpl employeeVO = getXxEmployeeVO1();

22 employeeVO.setWhereClause(null);

23 employeeVO.setWhereClauseParams(null);

24 employeeVO.setWhereClause("EMPNO = :1");

25 employeeVO.setWhereClauseParam(0, empNum);

26 employeeVO.setMaxFetchSize(-1);

27 employeeVO.executeQuery();

28 } catch (Exception e) {

29 e.printStackTrace();

30 }

Finally, user can click on 'Save' button to commit the data or 'Cancel' to return back to search page.

 We will catch the 'save' or 'cancel' button click in PFR method of XxEmployeeCreateUpdateCO and call
a method from AM accordingly:

1 // XxEmployeeCreateUpdateCO :: PFR method

2 public void processFormRequest(OAPageContext pageContext,

3 OAWebBean webBean) {

131
www.AppsLead.com
4 super.processFormRequest(pageContext, webBean);

6 OAApplicationModule am = pageContext.getRootApplicationModule();

8 if (pageContext.getParameter("cancelBtn") != null) {

9 pageContext.forwardImmediately("OA.jsp?page=/xxcus/oracle/apps

10 /fnd/emprec/webui/XxEmployeeSearchPG", null, (byte)0, null, null, false, null);

11 }

12

13 if (pageContext.getParameter("saveBtn") != null) {

14

15 /*Here we are performing commit operation

16 and returning back to search page.

17 Also we are fetching the updated/created

18 emp num so we can display a message on search page*/

19

20 String savedEmp = am.invokeMethod("commit").toString();

21 HashMap hm = new HashMap();

22 hm.put("updated", "Y");

23 hm.put("empUpdated", savedEmp);

24 pageContext.forwardImmediately("OA.jsp?page=/xxcus/oracle/apps

25 /fnd/emprec/webui/XxEmployeeSearchPG", null, (byte)0, null, hm, false, null);

26 }

27}

Below is 'commit' method created in AMImpl class:

1
public String commit() {
2
try {
3
XxEmployeeVOImpl employeeVO = getXxEmployeeVO1();
4
XxEmployeeVORowImpl row = (XxEmployeeVORowImpl)employeeVO.first();
5
String savedEmp = row.getEmpno().toString();
6
getOADBTransaction().commit();
7
return savedEmp;
8
} catch (Exception e) {
9

130
www.AppsLead.com
10 e.printStackTrace();

11 }

Below is code to display successful message on search page:

1 // XxEmployeeSearchCO :: PR method

2 public void processRequest(OAPageContext pageContext, OAWebBean webBean) {

3 super.processRequest(pageContext, webBean);

5 if ("Y".equals(pageContext.getParameter("updated"))) {

6 String updatedEmp = pageContext.getParameter("empUpdated");

7 throw new OAException("Employee Number " + updatedEmp +

8 " has been saved successfully.",

9 OAException.CONFIRMATION);

10 }

11

12}

Message will be displayed after saving the data as shown below:

133
www.AppsLead.com
Update records in OAF Page

1. Create a Search Page to Create a page please go through the following link

https://blogs.oracle.com/prajkumar/entry/create_oaf_search_page

2. Implement Update Action in SearchPG

Right click on ResultTable in SearchPG > New > Item

Set following properties for New Item

Attribute Property

ID UpdateAction

Item Style image

Image URI updateicon_enabled.gif

Atribute Set /oracle/apps/fnd/attributesets/Buttons/Update

Prompt Update

Additional Text Update record

Height 24

Width 24

Action Type fireAction

Event update

Submit True

Parameters Name – PColumn1


Value -- ${oa.SearchVO1.Column1}
Name – PColumn2
Value -- ${oa.SearchVO1.Column2}

3. Create a Update Page

Right click on SearchDemo > New > Web Tier > OA Components > Page

Name – UpdatePG

Package – prajkumar.oracle.apps.fnd.searchdemo.webui

132
www.AppsLead.com
4. Select the UpdatePG and go to the strcuture pane where a default region has been created

5. Select region1 and set the following properties:

Attribute Property

ID PageLayoutRN

Region Style PageLayout

AM Definition prajkumar.oracle.apps.fnd.searchdemo.server.SearchAM

Window Title Update Page Window

Title Update Page

Auto Footer True

6. Create the Second Region (Main Content Region)

Select PageLayoutRN right click > New > Region

ID – MainRN

Region Style – messageComponentLayout

7. Create first Item (Empty Field)

MainRN > New > messageTextInput

Attribute Property

ID Column1

Style Property messageTextInput

Prompt Column1

Data Type VARCHAR2

Length 20

Maximum Length 100

View Instance SearchVO1

136
www.AppsLead.com
View Attribute Column1

8. Create second Item (Empty Field)

MainRN > New > messageTextInput

Attribute Property

ID Column2

Style Property messageTextInput

Prompt Column2

Data Type VARCHAR2

Length 20

Maximum Length 100

View Instance SearchVO1

View Attribute Column2

9. Create a container Region for Apply and Cancel Button in UpdatePG

Select MainRN of UpdatePG

MainRN > messageLayout

Attribute Property

Region ButtonLayout

10. Create Apply Button

Select ButtonLayout > New > Item

Attribute Property

ID Apply

Item Style submitButton

137
www.AppsLead.com
Attribute /oracle/apps/fnd/attributesets/Buttons/Apply

11. Create Cancel Button

Select ButtonLayout > New > Item

Attribute Property

ID Cancel

Item Style submitButton

Attribute /oracle/apps/fnd/attributesets/Buttons/Cancel

12. Add Page Controller for SearchPG

Right Click on PageLayoutRN of SearchPG > Set New Controller

Name – SearchCO

Package -- prajkumar.oracle.apps.fnd.searchdemo.webui

Add Following code in Search Page controller SearchCO

import oracle.apps.fnd.framework.webui.OAPageContext;
import oracle.apps.fnd.framework.webui.beans.OAWebBean;
import oracle.apps.fnd.framework.webui.OAWebBeanConstants;
import oracle.apps.fnd.framework.webui.beans.layout.OAQueryBean;

public void processRequest(OAPageContext pageContext, OAWebBean webBean)


{
super.processRequest(pageContext, webBean);

OAQueryBean queryBean = (OAQueryBean)webBean.findChildRecursive("QueryRN");


queryBean.clearSearchPersistenceCache(pageContext);
}

public void processFormRequest(OAPageContext pageContext, OAWebBean webBean)


{
super.processFormRequest(pageContext, webBean);

if ("update".equals(pageContext.getParameter(EVENT_PARAM)))
{
pageContext.setForwardURL("OA.jsp?page=/prajkumar/oracle/apps/fnd/searchdemo/webui/UpdatePG",
null,
OAWebBeanConstants.KEEP_MENU_CONTEXT,
null,
134
www.AppsLead.com
null,
true,
OAWebBeanConstants.ADD_BREAD_CRUMB_NO,
OAWebBeanConstants.IGNORE_MESSAGES);
}
}

13. Add Page Controller for UpdatePG

Right Click on PageLayoutRN of UpdatePG > Set New Controller

Name – UpdateCO

Package -- prajkumar.oracle.apps.fnd.searchdemo.webui

Add Following code in Update Page controller UpdateCO

import oracle.apps.fnd.framework.webui.OAPageContext;
import oracle.apps.fnd.framework.webui.beans.OAWebBean;
import oracle.apps.fnd.framework.webui.OAWebBeanConstants;
import oracle.apps.fnd.framework.OAApplicationModule;
import java.io.Serializable;

public void processRequest(OAPageContext pageContext, OAWebBean webBean)


{
super.processRequest(pageContext, webBean);
OAApplicationModule am = pageContext.getApplicationModule(webBean);

String Column1 = pageContext.getParameter("PColumn1");


String Column2 = pageContext.getParameter("PColumn2");
Serializable[] params = { Column1, Column2 };
am.invokeMethod("updateRow", params);
}

public void processFormRequest(OAPageContext pageContext, OAWebBean webBean)


{
super.processFormRequest(pageContext, webBean);
OAApplicationModule am = pageContext.getApplicationModule(webBean);

if (pageContext.getParameter("Apply") != null)
{
am.invokeMethod("apply");
pageContext.forwardImmediately("OA.jsp?page=/prajkumar/oracle/apps/fnd/searchdemo/webui/SearchPG",
null,
OAWebBeanConstants.KEEP_MENU_CONTEXT,
null,
null,
false, // retain AM
OAWebBeanConstants.ADD_BREAD_CRUMB_NO);
}
else if (pageContext.getParameter("Cancel") != null)
{
139
www.AppsLead.com
am.invokeMethod("rollback");
pageContext.forwardImmediately("OA.jsp?page=/prajkumar/oracle/apps/fnd/searchdemo/webui/SearchPG",
null,
OAWebBeanConstants.KEEP_MENU_CONTEXT,
null,
null,
false, // retain AM
OAWebBeanConstants.ADD_BREAD_CRUMB_NO);
}
}

14. Add following Code in SearchAMImpl

import oracle.apps.fnd.framework.server.OAApplicationModuleImpl;
import oracle.apps.fnd.framework.server.OAViewObjectImpl;

public void updateRow(String Column1, String Column2)


{
SearchVOImpl vo = (SearchVOImpl)getSearchVO1();
vo.initQuery(Column1, Column2);
}

public void apply()


{
getTransaction().commit();
}

public void rollback()


{
getTransaction().rollback();
}

15. Add following Code in SearchVOImpl

import oracle.apps.fnd.framework.server.OAViewObjectImpl;

public void initQuery(String Column1, String Column2)


{
if ((Column1 != null) && (!("".equals(Column1.trim()))))
{
setWhereClause("column1 = :1 AND column2 = :2");
setWhereClauseParams(null); // Always reset
setWhereClauseParam(0, Column1);
setWhereClauseParam(1, Column2);
executeQuery();
}
}

123
www.AppsLead.com
16. Congratulation you have successfully finished. Run Your Search page and Test Your Work

121
www.AppsLead.com
121
www.AppsLead.com
120
www.AppsLead.com
Row.STATUS_INITIALIZED

We were experiencing a very strange problem with an OA page. The page is used to update multiple rows from a
transient VO using a table region. Following were the symptoms.

 Sometimes after save, the old value used to reappear.


 Sometimes after save, value from different row gets updated to current row.
 It was not happening for all kind of data.

Finally (by sheer luck) we found that it was because the way we preparing the VO for update.

Old Code
Row row = vo.createRow();
row.setAttribute(0,"value1");
row.setAttribute(1,"value2");
row.setNewRowState(row.STATUS_INITIALIZED);
vo.insertRow(row);

It seems we accidentally were using STATUS_INTITIALIZED instead of STATUS_NEW. What a bummer?

I am not sure where or when we should be using STATUS_INTITIALIZED though but found out that it should never
be used while preparing row for insert or update. Below is from the javadoc of oracle.jbo.Row.

STATUS_INITIALIZED

static Indicates that the row is newly created and no setAttribute has been called on it yet.
byte

STATUS_NEW
static
byte

Indicates that the Row is newly created and this Row's consistuent entities have been added to the
transaction.

123
www.AppsLead.com
Create ViewObject (VO) Dynamically

In ProcessRequest
import oracle.apps.fnd.framework.server.OAViewDef
import oracle.apps.fnd.framework.OAViewObject

AdminRegAMImpl am=(AdminRegAMImpl)pageContext.getApplicationModule(webBean);
if(am!=null)
{
OAViewDef viewdef=(OAViewDef)am.getOADBTransaction().createViewDef();
viewdef.setSql("select ename from scott.emp");
OAViewObject vo=(OAViewObject)am.createViewObject("SampleVO1",viewdef);
//SampleVO1 is ViewObject Name

122
www.AppsLead.com
Concept of Nested AM.

Hi All,
Writing a theoretical article after a long time. What inspired me to write.... hmm... lot of questioning developers
:) . Ok, my target with this article is to make an OA Framework developer understand what is nested AM? and
how can u find a nested AM instance from master/root AM instance? What we should know about it while
developing extensions or new pages.

What is a Nested AM?


--------------------------------------
An application module may be a root application module or a nested application module. A root application
module is not contained in another applicatin module. It provides transaction context for all objects contained in
it. It may optionally contain nested application modules. A root application module is created through JNDI calls.

A nested application module is contained in another application module. The containing application module is
referred to as the parent application module. If one traverses this containership ancestry, one will eventually find
the root application module (which does not have a parent application module). A nested application module
uses the transaction context provided by the root application module. Thus, data modifications performed in
application modules parented by one root application module will commit or rollback together.

Transaction
-----------------------------
Associated with the root application module is the Transaction object, which provides this transaction context.
From any (root or nested) application module, the user can retrieve the transaction object through a call to
getOADBTransaction(). In reality, getOADBTransaction() first locates the root application module and then
returns the transaction object from it.

The transaction object manages connection to database and entity caches. Thus, changes made through one
view object are visible to other view objects as long as these view objects all parented by the one root
application module. In contrast, if two view objects are parented by two separate root application modules, then
changes made through the view object will not be seen by the second view object until the changes are
committed to database through the first root application module and the second VO executes query (to retrieve
the most up-to-date data from database).

Creating Application Module


--------------------------------------------------------------------
A root application module is created by:

Finding the application module home through JNDI.


Calling create() on the application module home.
Here is a sample code to create a root application module:

java.util.Hashtable env = new java.util.Hashtable();

// Add environment entries into env...

javax.naming.Context ic = new InitialContext(env);

// 'defName' is the JNDI name for the application module


// definition from which the root application module is to
// be created
String defName = ...;

oracle.jbo.ApplicationModuleHome home = ic.lookup(defName);


oracle.jbo.ApplicationModule am = home.create();

One creates a nested application module by calling createApplicationModule on the parent Application module.

How nested AM concept works in OAF :


---------------------------------------------------------------------------
Now to associate a nested application module with a region,

126
www.AppsLead.com
specify either of the following properties:
1) AM Instance -- The application module instance name as specified in the application module's data
model. For example, PoSummaryAM1.
2) AM Definition -- The fully qualified name of the application module instance. For example,
oracle.apps.fnd.framework.toolbox.tutorial.server.PoSummaryAM.

If you specify the AM Instance property, OA Framework attempts to find and return the AM instance with the
given name. It searches the application module associated with the parent web bean.
If you specify the AM Definition property, OA Framework assigns a generated AM instance name to the nested
region. This name is comprised of the following values:
a) Region code of the associated nested region (if the region was originally created in AK)
b) Nested region application ID
c) Nested region ID
d) AM definition name.

OA Framework checks to see if the nested AM with the system-generated name has been already created
under the application module of the parent web bean. If the instance is not found, OA Framework creates and
uses a nested AM with the system-generated name. Otherwise, it reuses the pre-existing AM with the system
generated
name.

When specifying both the AM Instance and AM Definition properties


if a matching AM instance is found, OA Framework compares its definition with the AM Definition property
value. If there is a mismatch, OA Framework throws an exception.
If a matching AM instance is not found, OA Framework creates and returns a nested application module
instance with the given AM instance name and the definition.

Code for finding nested AM instance in root AM :


-----------------------------------------------------------------------------------
Hence, whenever you are trying to find an nested AM instance linked to a OA region under pagelayout region,
please check the am defination and am instance property of that region, because only then you would be able to
have a idea of name of nested AM instance. It can be system generated AM instance or name given by developer
for AM instance.So, you need to confirm this from the three cases mentioned in the previous article.For
debugging purposes, you can get the list if Application modules in root AM and print there names ,too :

String[] nestedAMNames = parentAM.getApplicationModuleNames();

// If you want to retrieve all currently loaded nested Application Modules


ApplicationModule[] nestedAMs = new ApplicationModule[nestedAMNames.length];

for (int i = 0; i < nestedAMNames.length; i++)


{
nestedAM[i] = parentAM.findApplicationModule(nestedAMNames[i]);
}

Otherwise for finding nested AM instance by :


ApplicationModule nestedAM = parentAM.findApplicationModule("MyNestedAM");

This concept is really helpful while doing extensions in OAF, as you may have to find a nested AM in a CO of
particular OAF region.You can always find root AM of the page in any controller using
pagecontext.getRootApplicationModule().

127
www.AppsLead.com
Delete Records in OAF Page

1. Create a Search Page to Create a page please go through the following link

https://blogs.oracle.com/prajkumar/entry/create_oaf_search_page

2. Implement a Delete in your SearchEOImpl Class

public void remove()


{ super.remove();
} // end remove()

3. Create a Delete Image

Select ResultsTable right click > New > Item

Set following properties for New Item

ID – DeleteAction

Item Style – image

Image URI – deleteicon_enabled.gif

Atribute Set -- /oracle/apps/fnd/attributesets/Buttons/Delete

Prompt -- Delete

Additional Text – Delete record action enabled

Height – 24

Width – 24

Action Type – fireAction

Event – delete

Submit – True

Select Parameter Properties define parameter name as Column1 and whose value is

${oa.SearchVO1.Column1}

Select Parameter Properties define parameter name as Column2 and whose value is

${oa.SearchVO1.Column2}

Select OK button to create your request parameters

4. Add Page Controller

Add a New Contoller for SearchPG

Name – SearchCO

Package -- prajkumar.oracle.apps.fnd.searchdemo.webui

124
www.AppsLead.com
Implement Delete Action

5. Add deleteRecord() method to SearchAMImpl

import oracle.apps.fnd.framework.OAViewObject;
import oracle.apps.fnd.framework.server.OAApplicationModuleImpl;
import oracle.jbo.domain.Number;
import oracle.apps.fnd.framework.server.OAViewObjectImpl;
import oracle.jbo.RowSetIterator;
...

public void deleteRecord(String Column1)


{ OAViewObject vo = (OAViewObject)getSearchVO1();
SearchVORowImpl row = null;

int fetchedRowCount = vo.getFetchedRowCount();

RowSetIterator deleteIter = vo.createRowSetIterator("deleteIter");


if (fetchedRowCount > 0)
{ deleteIter.setRangeStart(0);
deleteIter.setRangeSize(fetchedRowCount);
for (int i = 0; i < fetchedRowCount; i++)
{
row = (SearchVORowImpl)deleteIter.getRowAtRangeIndex(i);
row.remove();
getTransaction().commit();
break;
}
}
deleteIter.closeRowSetIterator();
} // end deleteRecord

Note – Create Standard FND Messages DELETE_RECORD_WARN and DELETE_CONFIRM

129
www.AppsLead.com
163
www.AppsLead.com
6. Add DeleteSelection Handler Code to SearchCO.processFormRequest()

import com.sun.java.util.collections.HashMap;
import oracle.apps.fnd.framework.webui.OADialogPage;
import oracle.apps.fnd.framework.webui.OAWebBeanConstants;
import oracle.apps.fnd.common.MessageToken;
import oracle.apps.fnd.framework.OAException;
import oracle.apps.fnd.framework.webui.OAWebBeanConstants;
import oracle.apps.fnd.framework.OARow;
import oracle.apps.fnd.framework.OAApplicationModule;
...

OAApplicationModule am = pageContext.getApplicationModule(webBean);
OAViewObject vo =(OAViewObject)am.findViewObject("SearchVO1");

String rowRef =
pageContext.getParameter(OAWebBeanConstants.EVENT_SOURCE_ROW_REFERENCE);

OARow row = (OARow)am.findRowByRef(rowRef);

if ("delete".equals(pageContext.getParameter(EVENT_PARAM)))
{

161
www.AppsLead.com
String Column1 = (String)row.getAttribute("Column1");
String Column2 = (String)row.getAttribute("Column2");

String Column3 = pageContext.getParameter("Column1");


String Column4 = pageContext.getParameter("Column2");

MessageToken[] tokens = { new MessageToken("COLUMN1", Column1),


new MessageToken("COLUMN2", Column2)};

OAException mainMessage = new OAException("FND",


"DELETE_RECORD_WARN", tokens);

OADialogPage dialogPage = new OADialogPage(OAException.WARNING,


mainMessage, null, "", "");

String yes = pageContext.getMessage("AK", "FWK_TBX_T_YES", null);


String no = pageContext.getMessage("AK", "FWK_TBX_T_NO", null);

dialogPage.setOkButtonItemName("DeleteYesButton");

dialogPage.setOkButtonToPost(true);
dialogPage.setNoButtonToPost(true);
dialogPage.setPostToCallingPage(true);

dialogPage.setOkButtonLabel(yes);
dialogPage.setNoButtonLabel(no);

java.util.Hashtable formParams = new java.util.Hashtable(1);


formParams.put("Column1", Column3);
formParams.put("Column2", Column4);
dialogPage.setFormParameters(formParams);

pageContext.redirectToDialogPage(dialogPage);
}

7. Add Delete Confirmation Handler Code to SearchCO.processFormRequest()

import java.io.Serializable;
import oracle.apps.fnd.framework.OAApplicationModule;
...

else if (pageContext.getParameter("DeleteYesButton") != null)


{
String Column1 = (String)row.getAttribute("Column1");
String Column2 = (String)row.getAttribute("Column2");
Serializable[] parameters = { Column1 };

OAApplicationModule am =
pageContext.getApplicationModule(webBean);

am.invokeMethod("deleteRecord", parameters);

OAException message = new OAException("FND",


"DELETE_CONFIRM", null,
OAException.CONFIRMATION, null);
161
www.AppsLead.com
pageContext.putDialogMessage(message);
}

8. Congratulation you have successfully finished. Run Your page and Test Your Work

160
www.AppsLead.com
163
www.AppsLead.com
162
www.AppsLead.com
OAF Sample Code
Get the VO from the AM

OAViewObject objAssessmentVO = (OAViewObject) yourAM.findViewObject ("yourVO");

MtlLotNumbersVOImpl vo = (MtlLotNumbersVOImpl) findViewObject ("MtlLotNumbersVO1");

MtlLotNumbersVORowImpl VOI = (MtlLotNumbersVORowImpl) (vo.getCurrentRow ());

mLotDetailValuesHT.put ("StatusId", voi.getStatusId ());

First get the AM where your VO is attached, then get the VO from that AM.Get the RootAM and get all the VOs
under that AM, using

writeLog (pageContext, "Room AM" + pageContext.getRootApplicationModule ());

String [] rootViewNames = pageContext.getRootApplicationModule () getViewObjectNames ();.

writeLog (pageContext, "Length of the VOs from Rootm AM" + rootViewNames.length);

for (int J = 0; J <rootViewNames.length; J + +)

pageContext.writeDiagnostics (this, J + "Value" + rootViewNames [J]);

If your VO is Not Available in that AM, and get the nested AM Then Check for your VO Inside that AM,

Use the below code to get the AM if your AM is Not root AM,

Public OAApplicationModule getRequestedAM (OAPageContext pageContext, String requestedAMName)

writeLog (pageContext, "Requested AM called to Check the AM" + requestedAMName);

amname String = "";

String objectivesAMName = requestedAMName ;/ / "ObjectivesAM";

String nestedAMArray [] = pageContext.getRootApplicationModule () getApplicationModuleNames ();.

pageContext.writeDiagnostics (this, "Root AM =>" + pageContext. getRootApplicationModule () getName () +

"Child AMs =>" + nestedAMArray.length, 1);.

OAApplicationModule currentAM = null;

currentAM = (OAApplicationModule) pageContext.getRootApplicationModule ();

for (int i = 0; i <nestedAMArray.length ; i + +)

166
www.AppsLead.com
amname = nestedAMArray;

pageContext.writeDiagnostics (this, "Nested AM Name =>" + amname + "and amName.indexOf

(objectivesAMName)" + amName.indexOf (objectivesAMName), 1);

currentAM = (OAApplicationModule) pageContext .. getRootApplicationModule () findApplicationModule

(amname);

/ / Get the View Names

String [] viewNames = currentAM.getViewObjectNames ();

for (int i = 0; i <viewNames.length; i + +)

writeLog (pageContext, i + " Value "+ viewNames);

(! (amName.indexOf (objectivesAMName) == -1) if)

pageContext.writeDiagnostics (this, "Found My Nested AM to Handle" + amname, 1);

break;

return currentAM ;

Getting & Setting Value, Capturing the value from VO and setting Explictiy in EO

Import oracle.apps.fnd.framework.OAViewObject;

Import oracle.apps.fnd.framework.OARow;

Public void processFormRequest (OAPageContext pageContext, OAWebBean webBean)

super.processFormRequest (pageContext, webBean);

OAApplicationModule am = pageContext.getApplicationModule (webBean );

OAViewObject oaviewobject1 = (OAViewObject) am.findViewObject ("NewEmployeeVO1");

if (oaviewobject1 = null)!

System.out.println ("Inside");

167
www.AppsLead.com
oaviewobject1.reset (); / / New line Added

oaviewobject1.next (); / / new line Added

OARow row = (OARow) oaviewobject1.getCurrentRow ();

String fullName = (String) row.getAttribute ("FullName");

OAViewObject Vo1 = (OAViewObject) am.findViewObject ("EmployeeEOVO1");

vo1.reset ();

if (Vo1 = null!)

do

if (vo1.hasNext ()!)

break;

vo1.next ();

EmployeeEOVORowImpl lcerl = (EmployeeEOVORowImpl) vo1.getCurrentRow ();

lcerl.setFullName (fullName );

} while (true);

vo.initQuery

MtlLotNumbersVOImpl lotVO = this.getMtlLotNumbersVO1 ();

lotVO.initQuery (- Organization, inventoryItemId, lotNumber);

MtlLotNumbersVORowImpl row1 = (MtlLotNumbersVORowImpl) lotVO.first ();

Simple queries

Increase in VOimpl in method:

Import oracle.jbo.domain.Number;

Import oracle.apps.fnd.framework.OAException;

...

Public void InitQuery (String employeeNumber)

164
www.AppsLead.com
{

if ((employeeNumber = null) &&!

((! . "" Equals (employeeNumber.trim ()))))

. / / Do the following conversion for type consistency

Number empnum = null;

TRY

empnum = new Number (employeeNumber);

Catch (Exception e)

throw new OAException ("AK", "FWK_TBX_INVALID_EMP_NUMBER");

setWhereClause ("EMPLOYEE_ID =: 1");

setWhereClauseParams (null); / / Always RESET

setWhereClauseParam (0, empnum);

executeQuery ();

} / / End InitQuery ()

in AM establishment method, called VO query

Import oracle.apps.fnd.framework.OAException;

Import oracle.apps.fnd.common.MessageToken;

...

/ *************** ************************************************** ******

* Initializes the Detail Employee Query.

******************************* **********************************************

*/

169
www.AppsLead.com
Public void initDetails (String employeeNumber)

EmpfullVOImpl vo = getEmpfullVO1 ();

if (vo == null)

MessageToken [] = {new MessageToken errTokens ("OBJECT_NAME", "EmployeeFullVO1")};

throw new OAException ("AK", "FWK_TBX_OBJECT_NOT_FOUND ", errTokens);

vo.initQuery (employeeNumber);

} / / End initDetails ()

when the page is called, CO execute the following code, the front of the function calls and execution (before the

call, the incoming parameter variables .. This can not be Forget)

Public void processRequest (OAPageContext pageContext, OAWebBean webBean)

super.processRequest (pageContext, webBean);

/ / Get the employeeNumber parameter from the URL

String employeeNumber = pageContext.getParameter ("employeeNumber");

/ / Now we want to initialize Our Single Query for the Employee

/ / with all of its details.

OAApplicationModule am = pageContext.getApplicationModule (webBean);

Serializable

173
www.AppsLead.com
OAException Message and Dialog Page in OA Framework

You can use OAException (or any of its subclasses) to display a message on an OA Framework page and the OA
Framework automatically displays an error message at the top of the current page.
You can display the following standard kinds of messages at the top of a page:

 Error
 Warning
 Confirmation
 Information
You can explicitly display a message box of any type using the following code in your controller.

OAException message = new OAException("You cannot create a new change order when a Draft version
1
already exits.",OAException.ERROR);

2 pageContext.putDialogMessage(message);

Here you need to construct an oracle.apps.fnd.framework.OAException object and set the kind of message you
want (other options are OAException.WARNING, OAException.INFORMATION and OAException.CONFIRMATION).
Then you can simply identify this exception for display when the page renders by calling the
OAPageContext.putDialogMessage() method.

If — after you call putDialogMessage() in your processFormRequest() method — you want to forward to the
current page or another page and display the message at the top of the new target page, you need to call the
appropriate oracle.apps.fnd.framework.webui.OAPageContext forwardImmediately*() method. The OA
Framework immediately stops processing the page and issues a forward before displaying the messages.

You can register or throw multiple exceptions; the OA Framework combines them into a single message box
using the following rules:

 Since an error is more important than a warning, the message box is titled “Error” if both errors and warnings
exist.
 Confirmations and errors cannot be shown together. In this case, the OA Framework simply ignores the
confirmation message(s).
 You can, however, show confirmations with warnings. The message box is titled “Confirmation,” and it
contains both types of messages.

Show the Exception Message on a Dialog Page

You can display an exception as a message in a dialog page using the APIs in the
oracle.apps.fnd.framework.webui.OADialogPage class and oracle.apps.fnd.framework.webui.OAPageContext
interface.

171
www.AppsLead.com
The OADialogPage class holds properties for the generic dialog page. To create a dialog page object, first use the
constructors to instantiate the basic properties, then use the setter methods provided in the class to set
additional properties.

To navigate (redirect) to a dialog page, use the OAPageContext.redirectToDialogPage methods. The


OAPageContext interface contains the context and state information specific for a client request.

// To Diaplay the Exception on a Dialog page

OAException message = new OAException("You cannot create a new change order when a Draft version already
exits.");

OADialogPage dialogPage = new OADialogPage(OAException.ERROR, message, null,"",null);

dialogPage.setOkButtonToPost(true);

dialogPage.setOkButtonLabel("Ok");

dialogPage.setPostToCallingPage(true);

java.util.Hashtable formParams = new java.util.Hashtable(1);

dialogPage.setFormParameters(formParams);

pageContext.redirectToDialogPage(dialogPage);

If you want 1 buttons (Say Cancel and Ok), then put “” instead of null in the OADialogPage dialogPage = new
OADialogPage line.

171
www.AppsLead.com
For High Volumes
For high load, high volume scenarios, you can log middle-tier messages to a local file, which is faster than logging
to a remote database.

Cursor Focus on OA page


Initial Cursor Focus is a highly under rated requirement in OA framework and mostly it is put on the back burner
during design/coding. And there is no clear documentation for this feature and may be OA dev guide avoided it
because we need to use Java Script for it; which is considered sacrilegious in OAF. We designed and deployed
around 50 pages to production and realized the importance of cursor focus only when the users started whining
about it. Hey, but they had a valid case, some times they open a page and scans a lot number immediately. But if
the focus was on URL browser field, it will take them to different page. And worse, some users started
complaining about carpal tunnel symptoms due to excessive usage of mouse. So when we started fixing the
pages for initial cursor focus we found ourselves in a difficult situation for some pages like the one which have
tab region or one with table region.

Simple messageText field.


Initial cursor focus on single row region is simple and straightforward.

String id = "myId"; // ID of the field


OABodyBean bB = (OABodyBean)pageContext.getRootWebBean();
bB.setInitialFocusId(id);

Tab region
We need to find the current active tab and then focus on the field for that tab.

OABodyBean bB = (OABodyBean)pageContext.getRootWebBean();
OASubTabLayoutBean tBean = (OASubTabLayoutBean)webBean.findIndexedChildRecursive("tabRegionId");
if(tBean != null)
{
int tabIndex = tBean.getSelectedIndex(pageContext);
if(tabIndex == 0)
bB.setInitialFocusId("id1");
else if (tabIndex == 1)
bB.setInitialFocusId("id2");

Table region
This is tricky and there is no direct OA supported way of doing this. OA framework (UIX) suffixes N: to the table
field id while creating the final HTML page. Based on this fact following javascript function will do the trick.

// id is ID of your bean
// rowIndex is the row number you want to focus.
function setTableFocus(id,rowIndex)
{
for (i = 0; i< 100 ; i++)
{
var bean = document.getElementById('N' + i+ ':' + id + ':' + rowIndex);
if(bean != null)
{
bean.focus();
break;
}
}
}

OABodyBean bB = (OABodyBean)pageContext.getRootWebBean();

170
www.AppsLead.com
pageContext.putJavaScriptFunction("focusTag",);
bB.setOnLoad("setTableFocus('" + id + "'," + 1 + ")"); // focus on first row.

173
www.AppsLead.com
Set Active Subtab in SubTabLayout

In Process Request

OASubTabLayoutBean subTabLayout = (OASubTabLayoutBean)webBean.findChildRecursive("region2");/*Region2


subtablayoutname*/
subTabLayout.setSelectedIndex(pageContext,"DeptVO1");/*DeptVO1 is Region Name Under subtablayout*/
subTabLayout.setUnvalidated(Boolean.TRUE);

172
www.AppsLead.com
Checkbox validation using VO attribute
I got a requirement for customization of a page where I need to create a check box. I need to do a Partial page
Rendering using the Check box. That is, to enable and disable an LOV bean according to the event triggered in the
check box.

I found that the Check box was already available in the seeded page and was not rendered. So I Personalized it to
make it rendered.

I wrote the following code to do that Assignment.

PR

OAMessageLovInputBean locationBean =
(OAMessageLovInputBean)webBean.findIndexedChildRecursive("LocationCodeLov");

OAMessageCheckBoxBean cbbean =
(OAMessageCheckBoxBean)webBean.findChildRecursive("WorkAtHome");

oracle.cabo.ui.action.FireAction FireActionA = new oracle.cabo.ui.action.FireAction();

FireActionA.setEvent("Event");

FireActionA.setUnvalidated(true);

cbbean.setPrimaryClientAction(FireActionA);

OAApplicationModule am = pageContext.getApplicationModule(webBean);

OAViewObject pVO = (OAViewObject)am.findViewObject("LocationVO");

OARow poRow = (OARow)pVO.getCurrentRow();

String WorkAtHome = (String)poRow.getAttribute("WorkAtHome");

if("Y".equals(WorkAtHome))

locationBean.setReadOnly(true);

else

locationBean.setReadOnly(false);

176
www.AppsLead.com
PFR

if("Event".equals(pageContext.getParameter(EVENT_PARAM)))

pageContext.setForwardURLToCurrentPage(null,

true,

OAWebBeanConstants.ADD_BREAD_CRUMB_NO,

OAWebBeanConstants.IGNORE_MESSAGES);

Note about Check box:

When a check box is created without the checked and unchecked value, it will be defaulted with ‘on’
when checked and ‘null’ when unchecked. But, when it stored to DB or we set the values while creating a check
box will be usually stored as ‘Y’ for checked and ‘N’ for unchecked.

177
www.AppsLead.com
Get and set the values using Session in OAF

I faced a issue in OAF customization where the value is not getting retained when the page returns a error. Yes ,
when an action returns an error the code wont process further. The page wont load once again to retain the
value.

I spend lots of time in clearing this issue. At last I manually stored the selected value in session and got
it when I needed it.

I need the value to be retrieve when the button clicked. So I set the value in the Process Form Request.

I got the value in PR and set it back when the page loaded once again.

Set the value with this:

pageContext.putSessionValue("RetainEffDate",dateFieldBean.getText(pageContext).toString());
pageContext.putSessionValue("PossibleDate",convertedDateString.toString());

Give a name for the session and store the string value along with it.

Get the Session value where you need it with this :

dateFieldBean.setText(pageContext.getSessionValue("RetainEffDate").toString());

In this I am setting the Session value to a DateField bean.


pageContext.getSessionValue("RetainEffDate").toString() will return the stored session value.

174
www.AppsLead.com
Determine the transaction state that is, whether changes have been made to view objects or not

Use the following methods:

ApplicationModule.getTransaction().isDirty() - This method tells you whether the transaction contains any
changes in the view objects. This works for transactions made by entity object-based view objects only.

OAViewObject.isDirty() - This method tells you whether a particular view object contains changes or not. This
works for both entity object-based view objects and view objects based on OAPlsqlViewObjectImpl. For view
objects based on OAPlsqlViewObjectImpl, you can also use OAPlsqlViewObjectImpl.getState() method

179
www.AppsLead.com
Scrolling Table: Table with horizontal Scrollbars and vertical scrollbars

Hi All,
I hope this is quite an interesting reading for most developers and they will try to put this feature in OAF
tables.This is a very essential requirement in any of the custom OAF pages, where you show data in OATableBean
and table has lot of columns, so, user has to scroll the entire page from scroll bar which is automatically rendered
by browser if table width is more than page width.This is very painful for user as everytime, he scrolls the scroll-
bar to see extra table columns,entire page is scrolled and he has to scroll back to the page to see other
data.Similary, if you are displaying more than 10-20 rows in the table , user needs to scroll the entire page to see
all the rendered rows of table.

In order to lessen the pain of the user and to have better UI design, we will render scroll bars both horizontal and
vertical just surrounding the table
as , shown in the image below :

So, now lets focus how can we bring these scroll bars. In that case you can use the DIV tag to do the job for
you.Put 2 RawText Bean(named DivStart, DivEnd), before and after the Table Bean in the JRAD page as shown in
the image below IN JDEVELOPER:

You can use following API in process request :


public void processRequest(OAPageContext pageContext, OAWebBean webBean)
{
super.processRequest(pageContext, webBean);
//SEE ALL PARAMETER values you need to pass in the java comments of the method
addScrollBarsToTable(pageContext, webBean,"DivStart","DivEnd",true,"400",true,"400");
.
.
}

/**
* @param pageContext the current OA page context.
* @param webBean the web bean corresponding to the region.Pass the webBean of pagelayout.
* @param preRawTextBean is name of the Rawtext bean just above the table bean.
* @param postRawTextBean is name of the Rawtext bean just below the table bean.
* @param horizontal_scroll is boolean value if horizontal scrollbar is required/not required.
* @param width is the minimum width of table beyond which horizontal scrollbar is displayed.i.e
* if width is greater than this horizontal scrollbar is displayed.If this is passed as null, defalt value
* is considered which is 400.
* @param vertical_scroll is boolean value if vertical scrollbar is required/not required.
* @param height is the minimum height of table beyond which horizontal scrollbar is displayed .i.e
* if width is greater than this horizontal scrollbar is displayed.If this is passed as null, defalt value
* is considered which is 400.

143
www.AppsLead.com
*/
public void addScrollBarsToTable(OAPageContext pageContext,
OAWebBean webBean,
String preRawTextBean,
String postRawTextBean,
boolean horizontal_scroll, String width,
boolean vertical_scroll, String height)
{
String l_height = "400";
String l_width = "400";
pageContext.putMetaTag("toHeight",
"<style type=\"text/css\">.toHeight {height:24px; color:black;}</style>");

OARawTextBean startDIVTagRawBean =
(OARawTextBean) webBean.findChildRecursive(preRawTextBean);
if (startDIVTagRawBean == null)
{
throw new OAException("Not able to retrieve raw text bean just above the table bean. Please verify the id of pre
raw text bean.");
}

OARawTextBean endDIVTagRawBean =
(OARawTextBean) webBean.findChildRecursive(postRawTextBean);
if (endDIVTagRawBean == null)
{
throw new OAException("Not able to retrieve raw text bean just below the table bean. Please verify the id of
post raw text bean.");
}

if (!((height == null) || ("".equals(height))))


{
try
{
Integer.parseInt(height);
l_height = height;
}
catch (Exception e)
{
throw new OAException("Height should be an integer value.");
}
}

if (!((width == null) || ("".equals(width))))


{
try
{
Integer.parseInt(width);
l_width = width;
}
catch (Exception e)
{
throw new OAException("Width should be an integer value.");
}
}

String divtext = "";


if ((horizontal_scroll) && (vertical_scroll))
{
divtext =
"<DIV style='width:" + l_width + ";height:" + l_height + ";overflow:auto;padding-bottom:20px;border:0'>";
}
else if (horizontal_scroll)
141
www.AppsLead.com
{
divtext =
"<DIV style='width:" + l_width + ";overflow-x:auto;padding-bottom:20px;border:0'>";
}
else if (vertical_scroll)
{
divtext =
"<DIV style='height:" + l_height + ";overflow-y:auto;padding-bottom:20px;border:0'>";
}
else
{
throw new OAException("Both vertical and horizintal scrollbars are passed as false,hence, no scrollbars will be
rendered.");
}
startDIVTagRawBean.setText(divtext);
endDIVTagRawBean.setText("</DIV>");
}
Please Note : Height and Width passed in addScrollBarsToTable API are the minimum
height and width of the table respectively which will be displayed on the page. Hence if this display resolution
is available on page the scrollbars will not be displayed or corresponding one scrollbar or both scrollbars will
be displayed.If you are not able see both scrollbars, even if you pass true for both in this method, try to put
less resolution like 150 and 150 etc.

141
www.AppsLead.com
OA Framework – Few code common using

Code for Disabling Global Buttons (in process request)

OAPageLayoutBean page =
(OAPageLayoutBean)pageContext.getPageLayoutBean(); page.prepareForRendering(pageContext);
OAGlobalButtonBarBean buttons = (OAGlobalButtonBarBean)page.getGlobalButtons();
buttons.setRendered(false);

Code for Setting Initial Focus on a field (in process request)

import oracle.apps.fnd.framework.webui.beans.OABodyBean;

OABodyBean oabean = (OABodyBean)pageContext.getRootWebBean();
oabean.setInitialFocusId(“ProjectType1″);

Code for Handling enter key press after entering a value in the text box.

(in process request)

OAMessageLovInputBean messagelovinputbean =
(OAMessageLovInputBean)webBean.findIndexedChildRecursive(“SelectVersion“);
// SelectVersion is the id of the lov item in the page if(messagelovinputbeanPerson != null) {
Hashtable params = new Hashtable();
params.put(“Go“, “true”);
//Go is the name of the button, whose action should happen after enter key press
messagelovinputbeanPerson.setAttributeValue(OAWebBeanConstants.ON_KEY_PRESS_ATTR,new
OABoundValueEnterOnKeyPress(pageContext,”DefaultFormName”,params,true,true)); }

Code for releasing lock on a database transaction (in AMImpl)

OADBTransaction oadbTransaction = getOADBTransaction();


oadbTransaction.setLockingMode(oadbTransaction.LOCK_NONE);

Code for wrapping text in read-only text area (in Process Request)

textBean.setWrap(SOFT_WRAP);

Handling Browser Back Button

(In Process Request)

if (!pageContext.isBackNavigationFired(false)) {
TransactionUnitHelper.startTransactionUnit(pageContext, “xxxxxxxxxxTxn”);
// All your processRequest logic should be inside this IF loop.
} else {
if (!TransactionUnitHelper.isTransactionUnitInProgress(pageContext, “xxxxxxxxxxxTxn”, true)) {
OADialogPage dialogPage = new OADialogPage(STATE_LOSS_ERROR);
pageContext.redirectToDialogPage(dialogPage);
}
}
(In Process Form Request, before redirecting to a different page or before form submission)
TransactionUnitHelper.endTransactionUnit(pageContext, “xxxxxxxxxxxxxxxTxn”);

140
www.AppsLead.com
Blocking User on submit Action in a OAF page

This is one of the most frequently required feature in OAF page, in certain conditions. Basically our requirement
is to block user from pressing a button twice, i.e.,if a button is pressed for the first time,till the time request
processing is going on for the first request on server either the button should be disabled on page or an hourglass
should be shown on the page, so that user should not be able to press it again to start another request, before
this request's response has been received from server. This is very essential feature where

1) You are lets say creating a account.


2) Doing a transaction.
3) Generating a report.
4) Doing a transaction which takes significant amount of time which can make user impatient and press the
button again.

The standard solution for this provided by OAF is setBlockOnEverySubmit API.Whenever a submit action takes
place on a page, subsequent submits can be blocked.
When using a blocking on submit technique, when the submit action takes place, the cursor becomes busy and
prevents any other submit action until the current submit event has been handled.
The block on submit behavior is not enabled by default on a page. However, For Partial Page Refresh (PPR) events
alone, it is enabled by default.
To implement the block on submit behavior on a specfic page, add the following code to the processRequest() of
that page CO:

import oracle.apps.fnd.framework.webui.beans.OABodyBean;

public void processRequest(OAPageContext pageContext, OAWebBean webBean)


{
super.processRequest(pageContext, webBean);
OAWebBean body = pageContext.getRootWebBean();
if (body instanceof OABodyBean)
{
((OABodyBean)body).setBlockOnEverySubmit(true);
}
...
...
}

But there are exceptions to this API functionality, what if my page has multiple buttons and I want this nature
only on press of one of the button.Situations like this the standard solution is using OAProcessing page(See dev
guide for OAProcessing page implementation, its explained well!), which is typically used in long running
processed.But what if user is not ready to leave the page at all and asks you to block the navigation somehow?
What if you are mobile browser, where OAProcessing page does not work fine. Situations like this can be taken
care through javascript.
I must repeat again, use this javascript solution only when your requirement is not fulfilled by standard
setBlockOnEverySubmit API provided by framework.Ok here are the steps for the javascript solution, which will
block the action by making the button disabled as soon as it is pressed and releasing it as soon as your action is
finished :

1) Add a button bean , instead of submit button bean. Lets say its id is "item1" in property inspector. Set
destination uri property in property inspector as :
javascript:document.getElementById('item1').disabled=true;submitForm('DefaultFormName',0,{'XXX':'Y'});

2) In process form request, you can catch the event as :

public void processFormRequest(OAPageContext pageContext,


OAWebBean webBean)
{
super.processFormRequest(pageContext, webBean);

.// the js button click event


// don't use pageContext.getParameter() API to get parameter values
// in R12 because its doing validation on JS paremeters.

143
www.AppsLead.com
// so,instead of getting parameter value from pagecontext
//getting directly from http request.
if(pageContext.getRenderingContext()
.getServletRequest().getParameter("XXX")!=null)
{
// ur button event logic in process form request
......

//remove this parameter from http request


pageContext.removeParameter("XXX");
}
}

142
www.AppsLead.com
Create OAF Search Page

1. Create a New Workspace and Project

Right click Workspaces and click create new OAworkspace and name it as PRajkumarSearch. Automatically a new
OA Project is also created. Name the project as SearchDemo and package as
prajkumar.oracle.apps.fnd.searchdemo

2. Create a New Application Module (AM)

Right Click on SearchDemo > New > ADF Business Components > Application Module

Name -- SearchAM

Package -- prajkumar.oracle.apps.fnd.searchdemo.server

3. Enable Passivation for the Root UI Application Module (AM)

Right Click on SearchAM > Edit SearchAM > Custom Properties >

Name – RETENTION_LEVEL

Value – MANAGE_STATE

Click add > Apply > OK

4. Create Test Table and insert data some data in it (For Testing Purpose)

CREATE TABLE xx_search_demo


( -- --------------------
-- Data Columns
-- --------------------
column1 VARCHAR2(100),
column2 VARCHAR2(100),
-- --------------------
-- Who Columns
-- --------------------
last_update_date DATE NOT NULL,
last_updated_by NUMBER NOT NULL,
creation_date DATE NOT NULL,
created_by NUMBER NOT NULL,
last_update_login NUMBER
);

INSERT INTO xx_search_demo VALUES (‘val1’, ’val1’, SYSDATE, 3, SYSDATE, 3, 3);


INSERT INTO xx_search_demo VALUES (‘val1’, ’val1’, SYSDATE, 3, SYSDATE, 3, 3);
INSERT INTO xx_search_demo VALUES (‘val0’, ’val3’, SYSDATE, 3, SYSDATE, 3, 3);
INSERT INTO xx_search_demo VALUES (‘val2’, ’val6’, SYSDATE, 0, SYSDATE, 0, 0);

Now we have 4 records in our custom table

5. Create a New Entity Object (EO)


146
www.AppsLead.com
Right click on SearchDemo > New > ADF Business Components > Entity Object

Name – SearchEO

Package -- prajkumar.oracle.apps.fnd.searchdemo.schema.server

Database Objects -- XX_SEARCH_DEMO

Note – By default ROWID will be the primary key if we will not make any column to be primary key Check the
Accessors, Create Method, Validation Method and Remove Method

6. Create a New View Object (VO)

Right click on SearchDemo > New > ADF Business Components > View Object

Name -- SearchVO

Package -- prajkumar.oracle.apps.fnd.searchdemo.server

In Step2 in Entity Page select SearchEO and shuttle them to selected list

In Step3 in Attributes Window select columns Column1, Column2 and shuttle them to selected list

In Java page Select Generate Java file for View Object Class: SearchVOImpl and Generate Java File for View Row
Class: SearchVORowImpl

7. Add Your View Object to Root UI Application Module

Select Right click on SearchAM > Edit SearchAM > Data Model >

Select SearchVO and shuttle to Data Model list

8. Create a New Page

Right click on SearchDemo > New > Web Tier > OA Components > Page

Name -- SearchPG

Package -- prajkumar.oracle.apps.fnd.searchdemo.webui

9. Select the SearchPG and go to the strcuture pane where a default region has been created

10. Select region1 and set the following properties:

ID -- PageLayoutRN

Region Style -- PageLayout

AM Definition -- prajkumar.oracle.apps.fnd.searchdemo.server.SearchAM

Window Title -- Search Page Window

Title -- Search Page


147
www.AppsLead.com
Auto Footer -- True

11. Add a Query Bean to Your Page

Right click on PageLayoutRN > New > Region

Select new region region1 and set following properties

ID – QueryRN

Region Style – query

Construction Mode – resultBasedSearch

Include Simple Panel – True

Include Views Panel – True

Include Advanced Panel – True

12. Add a Result Data Table to your QueryRN

Select QueryRN right click > New > Region using Wizard

In BC4J Objects page, Select your SearchAM and then select your SearchVO1

Note – DO NOT select Use this as Application Module Definition for this region checkbox

In Region Properties page, set Region ID value to ResultsTable and Region Style to table

In view Attributes page, select attributes from Available View Attributes list and shuttle them to

Selected View Atributes list:

Column1

Column2

In Region Items Page, you can set ID, Style and Attributes Set. Currently we are going to set only Style
as messageStyledText

13. Set and verify Your Results Table Region Properties

ID – ResultsTable

Region Style – table

AM – Please Donot put any AM

Rendered – True

Records Displayed – 10

Width – 100%

144
www.AppsLead.com
User Personalization – True

14. Set or Verify Column1 Item Properties

Search Allowed -- True

Sort Allowed – ascending

Initial Sort Seqence – first

Selective Search Criteria – True

User Personalization – True

15. Set or Verify Column2 Item Properties

Search Allowed – True

Sort Allowed -- ascending

Selective Search Criteria – True

User Personalization – True

16. Congratulation you have successfully finished Search page. Run Your SearchPG page and Test Your Work

149
www.AppsLead.com
193
www.AppsLead.com
Simple Search Page in OAF with filter by code

Here is a simple search page where user can perform search operation on the basis of employee number and
employee name on employee table.

1) Create a new OA workspace (xxcus) and a new project under this (xxcus).

2) Create a new OA page:

Right click on project (xxcus) --> New --> Web Tier --> OA Components --> select 'Page' item. Click OK. (This will
open a popup window)
We are creating a employee search page, so specify the details of page as below:
Name: XxEmployeeSearchPG

Package: xxcus.oracle.apps.fnd.emprec.webui

3) Create a new view object (VO):

Right click --> New View Object (This will open a wizard having 7 steps).

Step 1
Package: xxcus.oracle.apps.fnd.emprec.server
Name: XxEmployeeSearchVO
Choose the radio button 'Read-only Access' (as we are not performing any DML operation). Click Next.

Step 2
Enter the below query in 'Query Statement':

SELECT empno, ename, job, mgr, hiredate, sal, deptno FROM employee

Keep defaults for step3, 4, 5, 6

Step 7
Select check boxes for 'Generate Java File' for both 'View Object Class' and 'View Row Class'. Click Finish.

4) Create a new Application Module (AM):

Step 1
Package: xxcus.oracle.apps.fnd.emprec.server
Name: XxEmployeeAM. Click Next.

Step 2
Here we will add an instance of the VO created in (3). Select XxEmployeeSearchVO from 'Available View Objects'
and shuttle it to 'Data Model' using > button.

Keep defaults for all other steps (3, 4). Click Finish.

5) Create a new Controller class :

Step 1
Select XxEmployeeSearchPG in navigator tab. Declarative form of page will be visible in structure tab.

Step 2
Right click on pageLayout region --> set new controller (This will open a popup window). Enter the below details:
package Name: xxcus.oracle.apps.fnd.emprec.webui
Class Name: XxEmployeeSearchCO

191
www.AppsLead.com
Creating the Page Layout & Setting its Properties
==========================
Page will appear as below:

1) Create a new region under pageLayout of type defaultSingleColumn.


2) Create 3 items under defaultSingleColumn region (messageTextInput, messageTextInput, submitButton).

3) Create another item under pageLayout of type 'spacer'.

Now change the properties for each field from property inspector as shown below:

pageLayout:

ID: pageLayoutRN

AM Definition: xxcus.oracle.apps.fnd.emprec.server.XxEmployeeAM

Window Title: Employee Search Page

Title: Employee Search

defaultSingleColumn: ID: singleColRN

191
www.AppsLead.com
messageTextInput (for emp number):
ID: empNum
Prompt: Employee Number

messageTextInput (for emp name):


ID: EmpName
Prompt: Employee Name

submitButton: ID: goBtn, Prompt: Go

spacer: ID: spcr, Height: 20

4) Again create a region under pageLayout. However this time, choose 'Region Using Wizard'.

Step 1
select 'XxEmployeeAM' from Application Module drop down and select 'XxEmployeeSearchVO1' in available view
usages. Click Next.

Step 2
choose region style as 'table' from drop down. Click Next.

Step 3
shuttle all the fields from available to selected attributes. Click Next.

Step 4
Change the style to messageStyledText for each row. Also modify the prompt to make it more user friendly (like
empName to Employee Name).

The declarative page structure in jDev will be similar to as shown below:

190
www.AppsLead.com
Code for Performing the Search Operation
==========================

 User will enter search criteria (emp num or name) and click on 'Go' button.
 We catch this button press in PFR method of controller.
 Get the criteria fields and pass those to AM where we define a method to perform search.

Write the below code in PFR method of controller:

1 public void processFormRequest(OAPageContext pageContext,

2 OAWebBean webBean) {

3 super.processFormRequest(pageContext, webBean);

5 OAApplicationModule am = pageContext.getRootApplicationModule();

7 if (pageContext.getParameter("goBtn") != null) {

193
www.AppsLead.com
9 if ((!("".equals(pageContext.getParameter("empNum").trim()))) ||

10 (!("".equals(pageContext.getParameter("EmpName").trim())))) {

11 String empNum = pageContext.getParameter("empNum");

12 String empName = pageContext.getParameter("EmpName");

13 if (("".equals(pageContext.getParameter("empNum").trim()))) {

14 empNum = null;

15 }

16

17 Serializable[] param = { empNum, empName };

18 am.invokeMethod("searchEmployee", param);

19 } else {

20 throw new OAException("Please Enter Search Criteria.",

21 OAException.ERROR);

22 }

23 }

24 }

Below is code for searchEmployee method in XxEmployeeAMImpl.java :

1 public void searchEmployee(String empNum, String empName) {

2 try {

3 XxEmployeeSearchVOImpl vo = getXxEmployeeSearchVO1();

4 vo.setMaxFetchSize(-1);

5 vo.setWhereClause(null);

6 vo.setWhereClauseParams(null);

7 vo.setWhereClause("EMPNO = nvl(" + empNum + ",EMPNO)" +

8 "AND UPPER(ENAME) like UPPER('%" + empName + "%')");

9 System.out.println("search query - " + vo.getQuery());

10 vo.executeQuery();

11

12 } catch(Exception e) {

13 e.printStackTrace();

14 }

15 }

192
www.AppsLead.com
Search Page Using Auto Customization Criteria

196
www.AppsLead.com
197
www.AppsLead.com
194
www.AppsLead.com
199
www.AppsLead.com
133
www.AppsLead.com
131
www.AppsLead.com
131
www.AppsLead.com
130
www.AppsLead.com
133
www.AppsLead.com
Create Auto Customization Criteria OAF Search Page

1. Create a New Workspace and Project

Right click Workspaces and click create new OAworkspace and name it as PRajkumarCustSearch. Automatically a
new OA Project will also be created. Name the project as CustSearchDemo and package as
prajkumar.oracle.apps.fnd.custsearchdemo

2. Create a New Application Module (AM)

Right Click on CustSearchDemo > New > ADF Business Components > Application Module

Name -- CustSearchAM

Package -- prajkumar.oracle.apps.fnd.custsearchdemo.server

3. Enable Passivation for the Root UI Application Module (AM)

Right Click on CustSearchAM > Edit SearchAM > Custom Properties >

Name – RETENTION_LEVEL

Value – MANAGE_STATE

Click add > Apply > OK

4. Create Test Table and insert data some data in it (For Testing Purpose)

CREATE TABLE xx_custsearch_demo


( -- ---------------------
-- Data Columns
-- ---------------------
column1 VARCHAR2(100),
column2 VARCHAR2(100),
column3 VARCHAR2(100),
column4 VARCHAR2(100),
-- ---------------------
-- Who Columns
-- ---------------------
last_update_date DATE NOT NULL,
last_updated_by NUMBER NOT NULL,
creation_date DATE NOT NULL,
created_by NUMBER NOT NULL,
last_update_login NUMBER
);

INSERT INTO xx_custsearch_demo VALUES('v1','v2','v3','v4',SYSDATE,0,SYSDATE,0,0);


INSERT INTO xx_custsearch_demo VALUES('v1','v3','v4','v5',SYSDATE,0,SYSDATE,0,0);

132
www.AppsLead.com
INSERT INTO xx_custsearch_demo VALUES('v2','v3','v4','v5',SYSDATE,0,SYSDATE,0,0);
INSERT INTO xx_custsearch_demo VALUES('v3','v4','v5','v6',SYSDATE,0,SYSDATE,0,0);

Now we have 4 records in our custom table

5. Create a New Entity Object (EO)

Right click on SearchDemo > New > ADF Business Components > Entity Object

Name – CustSearchEO

Package -- prajkumar.oracle.apps.fnd.custsearchdemo.schema.server

Database Objects -- XX_CUSTSEARCH_DEMO

Note – By default ROWID will be the primary key if we will not make any column to be primary key

Check the Accessors, Create Method, Validation Method and Remove Method

6. Create a New View Object (VO)

Right click on CustSearchDemo > New > ADF Business Components > View Object

Name -- CustSearchVO

Package -- prajkumar.oracle.apps.fnd.custsearchdemo.server

In Step2 in Entity Page select CustSearchEO and shuttle them to selected list

In Step3 in Attributes Window select columns Column1, Column2, Column3, Column4, and shuttle them to
selected list

In Java page deselect Generate Java file for View Object Class: CustSearchVOImpl and Select Generate Java File
for View Row Class: CustSearchVORowImpl

7. Add Your View Object to Root UI Application Module

Select Right click on CustSearchAM > Application Modules > Data Model

Select CustSearchVO and shuttle to Data Model list

8. Create a New Page

Right click on CustSearchDemo > New > Web Tier > OA Components > Page

Name -- CustSearchPG

136
www.AppsLead.com
Package -- prajkumar.oracle.apps.fnd.custsearchdemo.webui

9. Select the CustSearchPG and go to the strcuture pane where a default region has been created

10. Select region1 and set the following properties:

ID -- PageLayoutRN

Region Style -- PageLayout

AM Definition -- prajkumar.oracle.apps.fnd.custsearchdemo.server.CustSearchAM

Window Title – AutoCustomize Search Page Window

Title – AutoCustomization Search Page

Auto Footer -- True

11. Add a Query Bean to Your Page

Right click on PageLayoutRN > New > Region

Select new region region1 and set following properties

ID – QueryRN

Region Style – query

Construction Mode – autoCustomizationCriteria

Include Simple Panel – False

Include Views Panel – False

Include Advanced Panel – False

12. Create a New Region of style table

Right Click on QueryRN > New > Region Using Wizard

Application Module – prajkumar.oracle.apps.fnd.custsearchdemo.server.CustSearchAM

Available View Usages – CustSearchVO1

In Step2 in Region Properties set following properties

Region ID – CustSearchTable

Region Style – Table

In Step3 in View Attributes shuttle all the items (Column1, Column1, Column0, Column3) available in “Available
View Attributes” to Selected View Attributes:

137
www.AppsLead.com
In Step3 in Region Items page set style to “messageStyledText” for all items

13. Select CustSearchTable in Structure Panel and set property Width to 100%

14. Include Simple Search Panel

Right Click on QueryRN > New > simpleSearchPanel

Automatically region2 (header Region) and region1 (MessageComponentLayout Region) created

Set Following Properties for region2

Id – SimpleSearchHeader

Text -- Simple Search

15. Now right click on message Component Layout Region (SimpleSearchMappings) and create two message
text input beans and set the below properties to each

Message TextInputBean1

Id – SearchColumn1

Search Allowed – True

Data Type – VARCHAR2

Maximum Length –

CSS Class – OraFieldText

Prompt – Column1

Message TextInputBean2

Id – SearchColumn2

Search Allowed -- True

Data Type – VARCHAR2

Maximum Length – 100

CSS Class – OraFieldText

Prompt – Column2

16. Now Right Click on query Components and create simple Search Mappings. Then automatically
SimpleSearchMappings and QueryCriteriaMap1 created

134
www.AppsLead.com
17. Now select the QueryCriteriaMap1 and set the below properties

Id – SearchColumn1Map

Search Item – SearchColumn1

Result Item – Column1

18. Now again right click on simpleSearchMappings -> New -> queryCriteriaMap, and then set the below
properties

Id – SearchColumn2Map

Search Item – SearchColumn2

Result Item – Column2

19. Congratulation you have successfully finished Auto Customization Search page. Run Your CustSearchPG
page and Test Your Work

139
www.AppsLead.com
113
www.AppsLead.com
How to fetch a bean in Advanced Search Panel

Normally, when we want to get handle of any bean in the page , we use webBean.findChildRecursive(“<id of
bean>”) method. But to get handle of a criteria bean in advanced search panel, this will not work.

Example, lets say we have a advanced search panel and the first criteria Row has a message text input field with
id Emp.

Now if we write webBean.findChildRecursive(“Emp”), it returns null. This is because, the framework dynamically
allocates a different id of the form “Value_n” for each criteria row created in the page.

Sample code:

OAAdvancedSearchBean advBean =
(OAAdvancedSearchBean)webBean.findChildRecursive(“AdvancedSearchBean”);
OAMessageTextInputBean empNum = (OAMessageTextInputBean)advBean.findChildRecursive(“Value_x”);
empNum.setValue(pageContext,”110″);

where x stands for xth criteria row in the advanced search panel. i.e if empNum is the first criteria row in your
page, then give Value_0 as id.

111
www.AppsLead.com
Setting Query Dynamically in View Object. (Why in some cases even
after using setQuery(), VO picks default query.)
Couple of time while making view object in OAF pages, you have conditions where instead of where clause or
order by clause, you need to change the entire source of sql query of View Object.
There can be n number of such scenarios, for example you are using a querybean in a search page, and in a
certain condition, you have to change your query, your VO is attached to a LOV and in certain condition you need
the query to change in order to optimize the VO sql query etc. Following points always keep in mind while using
setQuery():

1) The new query you want to set in the view object should have same column name and types as the original VO
query.

2)As per OAF coding standards all coding related to setting where clause, order by clause or setQuery should be
written in ViewObjectImpl class, so in such case, you should generate ViewObjectImpl class.

3)Most Important :Always call vo.setFullSqlMode(FULLSQL_MODE_AUGMENTATION) before calling setquery()


on the view object.This ensures that the order by or the WHERE clause, that is generated by OA Framework, can
be correctly
appended to your VO. The behavior with FULLSQL_MODE_AUGMENTATION is as follows:

a) The new query that you have programmatically set takes effect when you call setQuery and execute the query.
b) If you call setWhereClause or if a customer personalizes the criteria for your query region, BC4J augments the
whereClause on the programmatic query that you set.

For example:
select * from (your programmatic query set through setQuery)
where (your programmatic where clause set through setWhereClause)
order by (your programmatic order set through setOrderBy)
The same query is changed as follows if a customer adds a criteria using personalization:
select * from (your programmatic query set through setQuery)
where (your programmatic where clause set through setWhereClause) AND
(additional personalization where clause)
order by (your programmatic order set through setOrderBy)_

Warning: If you do not set FULLSQL_MODE_AUGMENTATION, the whereClause and/or the


orderBy, which was set programmatically, will not augment on the new query that you set using setQuery. It
will instead augment on your design time VO query.

Due to timing issues, always use the controller on the query region/LOV region while using setQuery().

111
www.AppsLead.com
Manual Search Page with validations in OA Framework

110
www.AppsLead.com
113
www.AppsLead.com
112
www.AppsLead.com
116
www.AppsLead.com
117
www.AppsLead.com
114
www.AppsLead.com
119
www.AppsLead.com
113
www.AppsLead.com
111
www.AppsLead.com
111
www.AppsLead.com
110
www.AppsLead.com
VO Query:

?
1 SELECT fs.supplier_id, fs.NAME, fs.on_hold_flag, fs.start_date, fs.end_date,

2 fst.supplier_site_id, fst.site_name, fst.carrier_code,

3 fst.purchasing_site_flag, fst.address_id

4 FROM fwk_tbx_suppliers fs, fwk_tbx_supplier_sites fst

5 WHERE fs.supplier_id = fst.supplier_id

6 AND fs.supplier_id LIKE NVL (:1, fs.supplier_id)

7 AND fs.NAME LIKE NVL (:2, fs.NAME)

8 AND NVL (fs.on_hold_flag, 'N') LIKE NVL (:3, NVL (fs.on_hold_flag, 'N'))

Code in CO:

?
1 public void processFormRequest(OAPageContext pageContext, OAWebBean webBean)

2 {

113
www.AppsLead.com
3 super.processFormRequest(pageContext, webBean);

5 xxManualSearchPageAMImpl am =
(xxManualSearchPageAMImpl)pageContext.getApplicationModule(webBean);
6

7
if(pageContext.getParameter("Search")!=null)
8
{
9
String Sup_ID = pageContext.getParameter("SupplierID");
10
String Sup_Name = pageContext.getParameter("SupplierName");
11
String HFlag = pageContext.getParameter("onHoldFlag");
12
String Start_Date = pageContext.getParameter("StartDate");
13

14
am.xxinitQuery(Sup_ID,Sup_Name,HFlag,Start_Date);
15
}
16

17
if(pageContext.getParameter("Clear")!=null)
18
{
19
pageContext.setForwardURLToCurrentPage(null,false,null,OAWebBeanConstants.IGNORE_MESSAGES);
20
}
21

22
}

Code in AM Impl:

?
1 public void xxinitQuery(String Sup_ID,String Sup_Name,String onHoldFlag,String SDate)

2 {

3 xxManualSearchPageVOImpl vo = getxxManualSearchPageVO1();

5 vo.xxGetSuppData(Sup_ID,Sup_Name,onHoldFlag,SDate);

6 }

Code in VO Impl:

112
www.AppsLead.com
Copying Data from One Table to Another Table in OAF and ADF
Using RowsetIterator

Requirement:Copy FirstName,LastName,EmployeeId to Sample Table(Custom)

Step1:Create Sample Table wihch Having Fileds Like FirstName and Last Name and EmployeeId
Step 2:Create New View Object For this Sample Table.

Add Below Code in AM Impl

public void Rowcount()


{
ViewObjectImpl vo = getEmployeesVO1();
RowSetIterator rs = vo.createRowSetIterator("xxx");
while (rs.hasNext())
{

int rowcount=vo.getRowCount();
Row row=rs.next();
ViewObjectImpl newvo=getSampleVO1();
Row row1=newvo.createRow();
newvo.insertRow(row1);
row1.setAttribute("EmployeeId", row.getAttribute("EmployeeId"));
row1.setAttribute("FirstName", row.getAttribute("FirstName"));
row1.setAttribute("LastName", row.getAttribute("LastName"));

getDBTransaction().commit();
}
}

116
www.AppsLead.com
Clear/ Reset Result Table of Search page in OAF

Normally problem faced by developers after creating Search Page is how to Clear/ Reset Result Table when
developer open search page first time or after search when developer redirecting back to same search page
from any other page (say delete page or update page)

Add following Code in your Search page Controller where you have constructed your Query Region

import oracle.apps.fnd.framework.webui.beans.layout.OAQueryBean;
...

public void processRequest(OAPageContext pageContext, OAWebBean webBean)


{
super.processRequest(pageContext, webBean);

OAQueryBean queryBean = (OAQueryBean)webBean.findChildRecursive("QueryRN");


// Here QueryRN is your Query Region Name as shown in following snap shot

queryBean.clearSearchPersistenceCache(pageContext);
}

Note –

After add this code, no need to worry about state of Application Module (AM). This code will clean up result table
automatically every time when you will open Search page first time and when you are redirecting back to search
page. But still as per good coding standard while redirecting back to search page always keep AM state to FALSE

117
www.AppsLead.com
OUTPUT IS BELOW .

114
www.AppsLead.com
119
www.AppsLead.com
Add Attribute to View Object Pragmatically

You can add transient attribute to view object progmatically at run time.
You can use this transient attribute to store any temporary data for every row in view object or create generic
solution in your custom framework for general purpose.

I will check existence of attribute XXAttr, If it is not exist I will add it to view object

public void processRequest(OAPageContext pageContext, OAWebBean webBean) {


super.processRequest(pageContext, webBean);

OAApplicationModule am = pageContext.getApplicationModule(webBean);
OAViewObject vo = (OAViewObject)am.findViewObject("ViewObjectName");

if (vo != null) {
try {
String transientAttr =
vo.findAttributeDef("XXAttr").toString();
} catch (Exception e) {
vo.addDynamicAttribute("XXAttr");
}
}
}

103
www.AppsLead.com
Implement Master Detail Relationship in OAF Page

Let us try to implement Master Detail Relationship in advanceedTable. We will create two tables master table
and child table. Both have relationship with each other with Column1

(Note - Column1 is a primary key in both tables)

1. Create a New OA Workspace and Empty OA Project

File> New > General> Workspace Configured for Oracle Applications

File Name -- MasterDetailProj

Project Name – MasterDetailDemo

Default Package -- prajkumar.oracle.apps.fnd.masterdetaildemo

2. Create Application Module AM

MasterDetailDemo right click > New > ADF Business Components > Application Module

Name -- MasterdetailDemoAM

Package -- prajkumar.oracle.apps.fnd.masterdetaildemo.server

Check Generate JavaFile(s)

3. We need two tables one table will be act as Master table and second table will be act as Child or detail table.
Lets Create two tables

-- Master Table

CREATE TABLE master_table_demo


( -- ---------------------
-- Data Columns
-- ---------------------
Column1 VARCHAR2(100),
Column2 VARCHAR2(100),
-- ----------------------
-- Who Columns
-- ----------------------
last_update_date DATE NOT NULL,
last_updated_by NUMBER NOT NULL,
creation_date DATE NOT NULL,
created_by NUMBER NOT NULL,
last_update_login NUMBER
);

-- Detail Table

101
www.AppsLead.com
CREATE TABLE detail_table_demo
( -- ---------------------
-- Data Columns
-- ---------------------
Column1 VARCHAR2(100),
Column2 VARCHAR2(100),
-- ----------------------
-- Who Columns
-- ----------------------
last_update_date DATE NOT NULL,
last_updated_by NUMBER NOT NULL,
creation_date DATE NOT NULL,
created_by NUMBER NOT NULL,
last_update_login NUMBER
);

Note – Consider Master Table is Linked to Detail Table with Column1

4. Lets put some data in the tables

-- Insert Data into Master Table

INSERT INTO master_table_demo VALUES ( ‘VAL1’, ‘VAL1’, SYSDATE, 3, SYSDATE, 3, 3);

INSERT INTO master_table_demo VALUES ( ‘VAL0’, ‘VAL3’, SYSDATE, 3, SYSDATE, 3, 3);

-- Insert Data into Detail Table

INSERT INTO detail_table_demo VALUES ( ‘VAL1’, ‘VAL6’, SYSDATE, 3, SYSDATE, 3, 3);

INSERT INTO detail_table_demo VALUES ( ‘VAL0’, ‘VAL4’, SYSDATE, 3, SYSDATE, 0, 0);

5. Create a New Entity Object (EO) for Master Table

Right click on MasterDetailDemo > New > ADF Business Components > Entity Object

Name – MasterEO

Package -- prajkumar.oracle.apps.fnd.masterdetaildemo.schema.server

Database Objects -- master_table_demo

Note -- Make Column1 as a primary key

101
www.AppsLead.com
Check the Accessors, Create Method, Validation Method and Remove Method

6. Create a New Entity Object (EO) for Detail Table

Right click on MasterDetailDemo > New > ADF Business Components > Entity Object

Name – DetailEO

Package -- prajkumar.oracle.apps.fnd.masterdetaildemo.schema.server

Database Objects -- detail_table_demo

Note -- Make Column1 as a primary key

100
www.AppsLead.com
Check the Accessors, Create Method, Validation Method and Remove Method

Note – Column1 in both tables is common Column to make parent child relationship

7. Lets Create View Object for Master Table

Right click on MasterDetailDemo > New > ADF Business Components > View Object

Name -- MasterVO

Package -- prajkumar.oracle.apps.fnd.masterdetaildemo.server

In Step2 in Entity Page select MasterEO and shuttle them to selected list

Create transient item by clicking on New

Name – DetailFlag

Type -- Boolean

103
www.AppsLead.com
In Step3 in Attributes Window select columns Column1, Column2, DetailFlag and shuttle them to selected list

In Java page deselect Generate Java file for View Object Class: MasterVOImpl

8. Lets Create View Object for Detail Table

Right click on MasterDetailDemo > New > ADF Business Components > View Object

Name -- DetailVO

Package -- prajkumar.oracle.apps.fnd.masterdetaildemo.server

In Step2 in Entity Page select DetailEO and shuttle them to selected list

In Step3 in Attributes Window select columns Column1, Column2 and shuttle them to selected list

In Java page deselect Generate Java file for View Object Class: DetailVOImpl

9. Create View Link Add Your View Object to Root UI Application Module

Right click on MasterDetailDemo > New > ADF Business Components > View Link

Name – MasterdetailDemoVL

Package -- prajkumar.oracle.apps.fnd.masterdetaildemo.server

102
www.AppsLead.com
10. Add Your View Object to Root UI Application Module

Right click on MasterdetailDemoAM > Application Modules > Data Model >

Select MasterVO, DetailVO via ViewLink, DetailVO and shuttle to Data Model list

106
www.AppsLead.com
11. Create a New Page

Right click on MasterdetailDemo > New > Web Tier > OA Components > Page

Name -- MasterdetailDemoPG

Package -- prajkumar.oracle.apps.fnd.masterdetaildemo.webui

12. Select MasterdetailDemoPG and go to the strcuture pane where a default region has been created

13. Select region1 and set the following properties:

ID -- PageLayoutRN

Region Style -- PageLayout

AM Definition -- prajkumar.oracle.apps.fnd.masterdetaildemo.server.MasterdetailDemoAM

Window Title – Master Detail Demo Page Window

Title – Master Detail Demo Page Header

Auto Footer – True


107
www.AppsLead.com
14. Add a New Region MainRN

Select PageLayoutRN right click > New > Region

ID -- MainRN

Region Style – header

15. Create a Master Table Region

Select MainRN > New > Region

ID – MainTableRN

Region Style -- advancedTable

View Instance -- MasterVO1

Detail View Attribute – DetailFlag

Child View Attribute -- Column1

View Link Instance -- MasterdetailDemoVL1

Width – 100%

Rendered – True

16. Create Columns and their items for MainTableRN

Create Column1

Select MainTableRN > New > column

Select column1 > New > Item

ID – item1

Item Style – messageStyledText

View Attribute – Column1

Create Column2

Select MainTableRN > New > column

Select column2 > New > Item

ID – item2

Item Style – messageStyledText

View Attribute – Column2

17. Create a Detail Region

104
www.AppsLead.com
Select MainTableRN > New > detail

A new Region will be get created under detail set following properties for that region

ID – DetailRN

Region Style – header

18. Create a DetailTable Region

Select DetailRN > New > Region

For New region set following Properties

ID – DetailTableRN

Region Style – advancedTable

View Instance -- DetailVO2

View Link Instance -- MasterdetailDemoVL1

Width – 100%

Rendered – True

19. Create Columns and their items for DetailTableRN

Create Column3

Select DetailTableRN > New > column

Select column3 > New > Item

ID – item3

Item Style – messageStyledText

View Instance – DetailVO2

View Attribute – Column1

Create Column4

Select DetailTableRN > New > column

Select column4 > New > Item

ID – item4

Item Style – messageStyledText

View Instance – DetailVO2

View Attribute – Column2

20. Add Controller for Page MasterdetailDemoPG Select PageLayoutRN right click Set New Controller

109
www.AppsLead.com
Package Name -- prajkumar.oracle.apps.fnd.masterdetaildemo.webui

Class Name -- MasterdetailDemoCO

Set Following Code in CO

import oracle.apps.fnd.framework.webui.OAPageContext;
import oracle.apps.fnd.framework.webui.beans.OAWebBean;
import prajkumar.oracle.apps.fnd.masterdetaildemo.server.MasterdetailDemoAMImpl;

...

public void processRequest(OAPageContext pageContext, OAWebBean webBean)


{
super.processRequest(pageContext, webBean);

MasterdetailDemoAMImpl AM =
(MasterdetailDemoAMImpl)pageContext.getApplicationModule(webBean);

pageContext.writeDiagnostics(this, "Calling Method", 1);

AM.MasterDetails(pageContext,webBean);
}

21. Add Following Code in your AMImpl Class (MasterdetailDemoAMImpl.java)

import oracle.apps.fnd.framework.webui.OAPageContext;
import oracle.apps.fnd.framework.webui.beans.OAWebBean;

...

public void MasterDetails(OAPageContext pageContext,OAWebBean webBean)


{
MasterVOImpl pvo = getMasterVO1();
pvo.executeQuery();
}

22. Final Structure pane will look like following picture

133
www.AppsLead.com
23. Congratulation you have successfully finished. Run Your MasterdetailDemoPG page and Test Your Work

131
www.AppsLead.com
131
www.AppsLead.com
Set Default Value for messageTextInput in OAF

1. Create a New OA Workspace and Empty OA Project

File > New > General > Workspace Configured for Oracle Applications

File Name – PrajkumarSetDefaultValDemo

Automatically a new OA Project will also be created

Project Name -- SetDefaultProj

Default Package -- prajkumar.oracle.apps.fnd.setdefaultproj

2. Create Application Module AM

Right Click on SetDefaultProj > New > ADF Business Components > Application Module

Name -- SetDefaultAM

Package -- prajkumar.oracle.apps.fnd.setdefaultproj.server

Check Application Module Class: SetDefaultAMImpl Generate JavaFile(s)

3. Create a OA components Page

Right click on SetDefaultProj > New > Web Tier > OA Components > Page

Name -- SetDefaultPG

Package -- prajkumar.oracle.apps.fnd.setdefaultproj.webui

4. Select SetDefaultPG and go to the strcuture pane where a default region has been created

5. Select region1 and set the following properties:

Attribute Property

ID PageLayoutRN

Region Style pageLayout

Form Property True

Auto Footer True

Window Title Set Default Value Window Title

130
www.AppsLead.com
Title Set Default Value Header

AM Definition prajkumar.oracle.apps.fnd.setdefaultproj.SetDefaultAM

6. Create the Second Region

Right click on PageLayoutRN > New > Region

Attribute Property

ID MainRN

Region Style messageComponentLayout

7. Create messageTextInput

MainRN > New > messageTextInput

Attribute Property

ID MyTextitemId

Style Property messageTextInput

Length 20

Maximum Length 50

8. Save Your Work

9. Add a Controller

MainRN > Set New Controller

Package Name -- prajkumar.oracle.apps.fnd.setdefaultvaldemo.webui

Class Name -- SetDefaultValCO

10. Edit Your Controller

Add Following Code in processRequest

133
www.AppsLead.com
import oracle.apps.fnd.framework.webui.beans.message.OAMessageTextInputBean;

public void processRequest(OAPageContext pageContext, OAWebBean webBean)


{
super.processRequest(pageContext, webBean);

String myValue = "My Default Value";


OAMessageTextInputBean textBean =
(OAMessageTextInputBean)webBean.findChildRecursive("MyTextitemId");

textBean.setValue(pageContext, myValue);
}

11. Test Your Work

132
www.AppsLead.com
Setting the default selected date for an OAMessageDateFieldBean

I have seen couple of threads in recent past on OA Forums about setting default value in
OAMessageDateFieldBean, so, did a little R n D :) on OAMessageDateFieldBean.

OAMessageDateFieldBean in framework, u will find its nothing but a onClick js event is called on the imageicon
attached with messagetextinput bean(in case the type is Date) and OAInlineDatePickerBean is opened in a
modal js window.

Setting deafult date in the OAMessageDateFieldBean, also sets the OAInlineDatePickerBean , as it takes the
default value from OAMessageDateFieldBean.
So, here is code for setting/getting value both in both in OAMessageDateFieldBean and OAInlineDatePickerBean :
import java.sql.Date;
import java.text.SimpleDateFormat;
java.sql.Timestamp;

//defining format of date


SimpleDateFormat f = new SimpleDateFormat("mm/dd/yyyy");
//define date as string
String dateString = "06/30/1984";
//defining new java.sql.date
Date sqlDate=new Date(f.parse(dateString).getTime());

OAMessageDateFieldBean dateField = (OAMessageDateFieldBean)webBean.findIndexedChildRecursive();


dateField.setValue(pageContext,sqlDate);

//getting oracle.jbo.domain.Date object from OAMessageDateFieldBean


//in process form request
Timestamp ts = (Timestamp)dateField.getValue(pageContext);
System.out.println(ts.getTime());
java.sql.Date select = new java.sql.Date(ts.getTime());
oracle.jbo.domain.Date sd=new oracle.jbo.domain.Date(select);

//You can also set min Value and Max value in OAMessageDateFieldBean which
//will also be set in OAInlineDatePickerBean
//Here is code
dateField.setMinValue(minDate);
dateField.setMaxValue(maxValue);

136
www.AppsLead.com
Implement PopList in OA Framework

1. Create a New Workspace and Project

File> New > General> Workspace Configured for Oracle Applications

File Name -- PopListDemo

Project Name – PopListDemo

Default Package -- prajkumar.oracle.apps.fnd.poplistdemo

2. Create a New Application Module (AM)

Right Click on PopListDemo > New > ADF Business Components > Application Module

Name -- poplistdemoAM

Package -- prajkumar.oracle.apps.fnd.poplistdemo.server

3. Create a New View Object (VO)

Right click on PopListDemo > New > ADF Business Components > View Object

Name -- poplistdemoVO

Package -- prajkumar.oracle.apps.fnd.poplistdemo.server

Note - The VO is not based on any EO so click next and go to the query section and paste the query

SELECT 'poplist_item1' poplist_items


FROM DUAL
UNION
SELECT 'poplist_item2'
FROM DUAL
UNION
SELECT 'poplist_item3'
FROM DUAL

4. Create a New Page

Right click on PopListDemo > New > Web Tier > OA Components > Page

Name -- poplistdemoPG

Package -- prajkumar.oracle.apps.fnd.poplistdemo.webui

5. Select the poplistdemoPG and go to the strcuture pane where a default region has been created

6. Select region1 and set the following properties:

ID -- PageLayoutRN

AM Definition -- prajkumar.oracle.apps.fnd.poplistdemo.server.poplistdemoAM

Window Title -- PopList Demo Window

Title – PopList Demo Header

137
www.AppsLead.com
7. Right click PageLayoutRN and click new Region

ID -- MainRN

Region Style – messageComponentLayout

8. Verify Your VO attribute name

Select poplistdemoVO right click > Edit poplistdemoVO > Attributes >

Verify the Name it should be “poplist_items” if it is not then edit it and enter name “poplist_items”

9. Create the first Item (Empty Field)

MainRN > New > messageChoice

Set following properties for new item

ID – MyPopList

Required -- Yes

Picklist View Definition -- prajkumar.oracle.apps.fnd.poplistdemo.server.poplistdemoVO

Picklist Display Attribute – poplist_items (Name of Attribute in Your VO)

Picklist Value Attribute -- poplist_items

CSS Class – OraFieldText

Prompt – My PopList

10. Congratulation you have successfully finished. Run Your page and Test Your Work

134
www.AppsLead.com
Category: Oracle
Tags: implement_poplist_in_oa_framework

139
www.AppsLead.com
Uncommitted data warning

Share on facebook Share on twitter Share on email Share on print More Sharing Services 0

If you are working entry data page and some feilds has been changed and you moved to another page, data still
in cache but not posted or commited.

So to show warning of unsaved data before moving to another page you can do this by setting "Uncommitted
data warning" property of af:document to "true". Then whenever user change data and move out of current
page or close the browser, it will display a warning of unsaved data

123
www.AppsLead.com
Get Current Row in Table

Share on facebook Share on twitter Share on email Share on print More Sharing Services 1

Sometimes you want to get current row in table. To apply this you can use the following code in controller and
write it inside processFormRequest method.

public void processFormRequest(OAPageContext pageContext,


OAWebBean webBean) {
super.processFormRequest(pageContext, webBean);
//Get application Module
OAApplicationModule am = pageContext.getApplicationModule(webBean);

//Get Row Refrence


String rowReference =
pageContext.getParameter(EVENT_SOURCE_ROW_REFERENCE);

//Get current Row using Row Reference


OARow currRow = (OARow)am.findRowByRef(rowReference);

//Get attribute value from current row


String attrValue = (String)currRow.getAttribute("AttrName");
}

121
www.AppsLead.com
Filtering Rows in OAF

Some times if we have a check box in the table region and we need to some operation only
for the checked rows then we need to filter the Rows of vo with that Check Box attribute

Here is a sample code for the same

OAViewObject vo = (OAViewObject) getxxxVO1();


xxxVORowImpl row = null;

Row[] rows = vo.getFilteredRows("select","Y");


//where select is the Vo attribute given for the check box in table region
for (int i=0;i
row = (xxxVORowImpl)rows[i];
//using row.set and get attributes perform logic as show below
savelogic(row.getSupplierName,row.getSupplierId);
}

121
www.AppsLead.com
Implement External LOV in OA Framework

1. Create a New Workspace and Project

Right click Workspaces and click create new OAworkspace and name it as PRajkumarLovDemo. Automatically a
new OA Project is also created. Name the project as LovDemo and package as
prajkumar.oracle.apps.fnd.lovdemo

2. Create a New Application Module (AM)

Right Click on LovDemo > New > ADF Business Components > Application Module

Name -- LovAM

Package -- prajkumar.oracle.apps.fnd.lovdemo.server

3. Create a New View Object (VO)

Right click on LovDemo > New > ADF Business Components > View Object

Name -- LovVO

Package -- prajkumar.oracle.apps.fnd.lovdemo.server

Note - The VO is not based on any EO so click next and go to the query section and paste the query

SELECT employee_number, full_name

FROM per_all_people_f

WHERE SYSDATE BETWEEN effective_start_date AND effective_end_date

4. Add View Object to Root UI Application Module

5. Create a New Page

Right click on LovDemo > New > Web Tier > OA Components > Page

Name -- LovPG

Package -- prajkumar.oracle.apps.fnd.lovdemo.webui

6. Select the LovPG and go to the strcuture pane where a default region has been created

7. Select region1 and set the following properties:

ID -- PageLayoutRN

AM Definition -- prajkumar.oracle.apps.fnd.lovdemo.server.LovAM

120
www.AppsLead.com
Window Title -- List of values Demo Window

Title – List of values Demo

8. Right click PageLayoutRN and click new Region

ID -- MainRN

Region Style – messageComponentLayout

Note - Style is given as messageComponentlayout because we are going to create only message components that
is messageLovInput item in that region

9. Create a New Region

Right click on LovDemo > New > Web Tier > OA Components > Region

Name -- EmployeeLovRN

Package -- prajkumar.oracle.apps.fnd.lovdemo.webui

Region Style -- listOfValues

Scope -- Public

Note - The property Scope is the key property which makes the LOV region public and makes it usable in multiple
pages

10. Select EmployeeLovRN. Right click on EmployeeLovRN in Structure pane and click table using wizard. In the
wizard choose the prajkumar.oracle.apps.fnd.lovdemo.server.LovAM and select the LovVO1. Click Next

Region Id -- LovRN

Region style -- table

11. Shuttle the two attributes to the right side.That is EmployeeNumber and FullName

12. Click next, check the mapping and then finish

13. Select the field FullName and set the following properties:

Search Allowed -- True

Selective Search Criteria – True

Note - The first property lets users search on these values in the LOV, and the second property ensures that the
users specify search criteria for at least one of these values to avoid a blind query

123
www.AppsLead.com
Attaching External LOV to Page:

14. Click on LovPG and right click the MainRN and click new messageLovInput

External Lov -- /prajkumar/oracle/apps/fnd/lovdemo/webui/EmployeeLovRN

Lov Region Item -- FullName

Return Item -- item1

Criteria Item -- item1

Prompt -- Employee Name

15. Congratulation you have successfully finished. Run Your page and Test Your Work

122
www.AppsLead.com
126
www.AppsLead.com
Dependent LOV in OAF

Concept of dependent LOV is that, we select a value from one LOV field and based on that value, another LOV
field will show filtered results.

Here, I have used two LOVs: one for PO Headers and another for PO Lines.
So first, user will select a PO Header Id from LOV1.
As we are making these dependent, so LOV2 will show only those PO Lines that are related to PO header Id
selected.

1) Create a new OA page:


==========================
Right click on project (xxcus) --> New --> Web Tier --> OA Components --> select 'Page' item. Click OK. (This will
open a popup window)
We are creating Dependent LOV page, so specify the details of page as below:
Name: XxDemoDependentLovPG
Package: xxcus.oracle.apps.fnd.dpndntlov.webui

2) Create two new view objects (VO):


==========================

First for PO Headers

Right click (dpndntlov) --> New View Object (This will open a wizard having 7 steps).

Step 1
Package: xxcus.oracle.apps.fnd.dpndntlov.lov.server
Name: XxPoHeaderLovVO
Choose the radio button 'Read-only Access' (as we are not performing any DML operation). Click Next.

Step 2
Enter the below query in 'Query Statement':
select PO_HEADER_ID from po_headers_all where rownum <50

As there is no need to generate VOImpl/VORowImpl, keep defaults for step3, 4, 5, 6 & 7 and click Finish. Save All.

Second for PO Lines

Right click --> New View Object

Step 1
Package: xxcus.oracle.apps.fnd.dpndntlov.lov.server
Name: XxPoLinesLovVO
Choose the radio button 'Read-only Access'. Click Next.

Step 2
Enter the below query in 'Query Statement':
select PO_HEADER_ID, PO_LINE_ID from po_lines_all

Keep defaults for step3, 4, 5, 6 & 7 and click Finish. Save All.

3) Create a new Application Module (AM):


==========================
Step 1
Package: xxcus.oracle.apps.fnd.dpndntlov.server
Name: XxDemoDependentLovAM. Click Next.

Step 2

127
www.AppsLead.com
Here we will add an instance of the VOs created in (2).
Select XxPoHeaderLovVO & XxPoLinesLovVO from 'Available View Objects' and shuttle it to 'Data Model'
using ">" button.

Keep defaults for all other steps (3, 4). Click Finish.

4) Creating the Page Layout & Setting its Properties:


==========================
Page will appear as below :

1) Create a new region under pageLayout of type defaultSingleColumn.


2) Create 2 items under defaultSingleColumn region (messageLovInput, messageLovInput).

Now change the properties for each field from property inspector as shown below:

pageLayout:
ID: pageLayoutRN
AM Definition: xxcus.oracle.apps.fnd.dpndntlov.server.XxDemoDependentLovAM
Window Title: Dependent LOV Demo Page
Title: Dependent LOV Demo

defaultSingleColumn:
ID: singleColRN; Text: PO Lines Dependent on PO Header

messageLovInput (for PO Header):


ID: poHearderLov
Prompt: PO Header ID

messageLovInput (for PO Lines):


ID: poLineLov
Prompt: PO Line ID

Creating LOV regions:

Expand poHearderLov LOV, right click on region1 and create a new region using wizard.

Step 1
select 'XxDemoDependentLovAM' from Application Module drop down and select 'XxPoHeaderLovVO1' in
available view usages. Click Next.

Step 2
choose region style as 'table' from drop down. Click Next.

Step 3
124
www.AppsLead.com
Shuttle all the fields from available to selected attributes. Click Next.
Also modify the prompt to make it more user friendly (like PO Header ID).

This will create an item 'PoHeaderId' under 'XxPoHeaderLovVO1' table region.


Set search allowed property to TRUE for the item created.
lovMap1:
LOV region item: PoHeaderId
Return item: poHearderLov
Criteria item: poHearderLov

Similarly, create LOV region for poLineLov choosing XxDemoDependentLovAM as AM and XxPoLinesLovVO1 as
view object.
Modify the prompt to PO Lines ID.

This will create 2 items 'PoHeaderId1' & 'PoLineId' under 'XxPoLinesLovVO1' table region.
Set search allowed property of 'PoLineId' to TRUE.

lovMap2:
LOV region item: PoLineId
Return item: poLineLov
Criteria item: poLineLov

Here, in lovMap3, we are making this dependent on first LOV by setting criteria item as value of first LOV field.
lovMap3:
LOV region item:PoHeaderId1
Criteria item: poHearderLov

The declarative page structure in jDev will be similar to as shown below:

129
www.AppsLead.com
Now select a value (PO Header Id) from LOV1 such as 4 (as shown in above screenshot).

Perform a search on PO Line ID LOV. This will show only those lines whose header Id is 4.

Below is screenshot for the same:

163
www.AppsLead.com
161
www.AppsLead.com
Implement Dependent LOV in OA Framework

Let us try to create a Dependent LOV. In this exercise first Lov Input is “Employee Name” based on Employee
Name Second Lov Input will give “Dependent Name”

1. Create a New Workspace and Project

Right click Workspaces and click create new OAworkspace and name it as PRajkumarDependentLovDemo.

Automatically a new OA Project will be created. Name the project as DependentLovDemo and package as
prajkumar.oracle.apps.fnd.dependentlovdemo

Note -- Check Run Option Property for Project.

Right Click on DependentLovDemo > Oracle Applications > Run Options. Check OADeveloperMode should not be
inSelected Options if it is there in Selected Options list then shuttle it back to Available Options

2. Create a New Application Module (AM)

Right Click on DependentLovDemo > New > ADF Business Components > Application Module

161
www.AppsLead.com
Name -- DependentLovAM

Package -- prajkumar.oracle.apps.fnd.dependentlovdemo.server

3. Create a New View Object (VO)

Right click on DependentLovDemo > New > ADF Business Components > View Object

Name – DependentLovVO1

Package -- prajkumar.oracle.apps.fnd.dependentlovdemo.server

Note - The VO is not based on any EO so click next and go to the query section and paste the query

SELECT person_id, full_name


FROM per_all_people_f
WHERE SYSDATE BETWEEN effective_start_date AND effective_end_date

4. Create a New View Object for Second Lov (VO)

Right click on DependentLovDemo > New > ADF Business Components > View Object

Name – DependentLovVO2

Package -- prajkumar.oracle.apps.fnd.dependentlovdemo.server

Note - The VO is not based on any EO so click next and go to the query section and paste the query

SELECT pcr.person_id, papf.full_name


FROM per_contact_relationships pcr,
per_all_people_f papf
WHERE papf.person_id = pcr.contact_person_id
AND SYSDATE BETWEEN pcr.date_start AND NVL(pcr.date_end,SYSDATE)
AND SYSDATE BETWEEN papf.effective_start_date AND papf.effective_end_date

5. Add Your View Objects to Root UI Application Module

Select Right click on DependentLovAM > Edit DependentLovAM > Data Model >

Select DependentLovVO1 and DependentLovVO2 and shuttle to Data Model list

160
www.AppsLead.com
Create First LOV Region for VO DependentLovVO1

6. Create First LOV Region

Right click on DependentLovDemo > New > Web Tier > OA Components > Region

Name -- FirstLovRN

Package -- prajkumar.oracle.apps.fnd.dependentlovdemo.webui

Region Style -- listOfValues

Scope -- Public

Note - The property Scope is the key property which makes the LOV region public and makes it usable in multiple
pages

7. Right click on FirstLovRN and click table using wizard. In the wizard choose the
prajkumar.oracle.apps.fnd.dependentlovdemo.server.DependentLovAM and select DependentLovVO1_1. Click
Next

163
www.AppsLead.com
Region Id – FirstLovRN

Region style – table

162
www.AppsLead.com
8. Shuttle the two attributes to the right side.That is PersonId and FullName

166
www.AppsLead.com
9. Set Region Item properties as below –

ID Prompt Style Datatype

PersonId_LOV PersonId formValue NUMBER

FullName_LOV FullName messageStyledText VARCHAR2

10. Click Next and Finish

11. Select PersonId_LOV and Set Following Properties –

Attribute Property

Search Allowed False

Selective Search Criteria False

12. Select FullName_LOV and Set Following Properties –

167
www.AppsLead.com
Attribute Property

Search Allowed True

Selective Search Criteria False

Now Same way Create Second LOV Region for VO DependentLovVO2

13. Create Second LOV Region

Right click on DependentLovDemo > New > Web Tier > OA Components > Region

Name -- SecondLovRN

Package -- prajkumar.oracle.apps.fnd.dependentlovdemo.webui

Region Style -- listOfValues

Scope -- Public

Note - The property Scope is the key property which makes the LOV region public and makes it usable in multiple
pages

14. Right click on SecondLovRN and click table using wizard. In the wizard choose the
prajkumar.oracle.apps.fnd.dependentlovdemo.server.DependentLovAM and select DependentLovVO2_1. Click
Next

164
www.AppsLead.com
Region Id – SecondLovRN

Region style – table

169
www.AppsLead.com
15. Shuttle the two attributes to the right side.That is PersonId and FullName

16. Set Region Item properties as below –

ID Prompt Style Datatype

Second_PersonId_LOV PersonId messageStyledText NUMBER

Second_FullName_LOV FullName messageStyledText VARCHAR2

173
www.AppsLead.com
17. Click Next and Finish

18. Select Second_PersonId_LOV and Set Following Properties –

Attribute Property

Search Allowed False

Selective Search Criteria True

19. Select Second_FullName_LOV and Set Following Properties –

Attribute Property

Search Allowed True

Selective Search Criteria False

20. Create a New Page

171
www.AppsLead.com
Right click on DependentLovDemo > New > Web Tier > OA Components > Page

Attribute Property

Name DependentLovPG

Package prajkumar.oracle.apps.fnd.dependentlovdemo.webui

21. Select the DependentLovPG and go to the strcuture pane where a default region has been created

22. Select region1 and set the following properties:

Attribute Property

ID PageLayoutRN

AM Definition prajkumar.oracle.apps.fnd.dependentlovdemo.server.DependentLovAM

Window Title Dependent List of values Demo Window

Title Dependent List of values Demo

23. Right click PageLayoutRN and click new Region

Attribute Property

ID MainRN

Region Style messageComponentLayout

24. Create a New item to store Return result of First LOV and to give Search Criteria to second LOV

Select PageLayoutRN > New > Item

Set following Properties for New Item –

Attribute Property

ID ParentPersonId

Item Style formValue

171
www.AppsLead.com
Data Type Number

Build First LOV on Page:

25. Right click the MainRN and click new messageLovInput

Set Following Properties for Newly Created messageLovInput

Attribute Property

ID Employee_Name

External Lov /prajkumar/oracle/apps/fnd/dependentlovdemo/webui/FirstLovRN

Search Allowed False

Selective Search Criteria True

Prompt Employee Name

Select LovMap1 and set following properties --

Attribute Property

Lov Region Item FullName_LOV

Return Item Employee_Name

Criteria Item Employee_Name

Create LovMap2 and set following properties for that --

Select Employee_Name > lovMappings right click New > lovMap

Set following properties for lovMap2 --

Attribute Property

Lov Region Item PersonId_LOV

Return Item ParentPersonId

170
www.AppsLead.com
Build Second LOV on Page:

26. Right click the MainRN and click new messageLovInput

Set Following Properties for Newly Created messageLovInput

Attribute Property

ID Dependent_Name

External Lov /prajkumar/oracle/apps/fnd/dependentlovdemo/webui/SecondLovRN

Search Allowed True

Selective Search True


Criteria

Prompt Dependent Name

Select LovMap3 and set following properties --

Attribute Property

Lov Region Item Second_FullName_LOV

Return Item Dependent_Name

Programmatic Query True

Create LovMap4 and set following properties for that --

Select Dependent_Name > lovMappings right click New > lovMap

Set following properties for lovMap4 --

Attribute Property

Lov Region Item Second_PersonId_LOV

Criteria Item ParentPersonId

Required True

27. Congratulation you have successfully finished. Run Your page and Test Your Work
173
www.AppsLead.com
172
www.AppsLead.com
176
www.AppsLead.com
PPR-- An insight !

PPR or Partial Page Rendering is one of the most attractive feature put up by Oracle in 11.5.10 release of Oracle
Apps, or OA Famework.
Although most of OAF developer community use this feature, i think very few would have idea, how excatly it
works in UIX.PPR uses Ajax kind of design and hence very attractive to use, because it can put dynamic features
in various UIX beans, without the use of any client side script like javascript, which is otherwise a integral part of
any web application. PPR events are very fast as they refresh only a particular region or protion of page and no
the entire page.

Developers that want to add such behaviors to their web pages are often faced with a difficult decision. All of
these actions can be implemented using a very simple solution: by refreshing the entire page in response to the
user interaction. However easy, this solution is not always desirable. The full page refresh can be slow, giving the
user the impression that the application is unresponsive. Another option is to implement such actions using
JavaScript (or other client-side scripting technologies). This results in faster response times, at the expense of
more complex, less portable code. JavaScript may be a good choice for simple actions, such as updating an
image. However, for more complicated actions, such as scrolling through data in a table, writing custom
JavaScript code can be a very challenging undertaking.

Oracle UIX provides another solution which avoids some of the drawbacks of the full page refresh and custom
JavaScript solutions: partial page rendering (or PPR for short). The UIX partial page rendering functionality
provides the ability to re-render a limited portion of a page. As in the full page render solution, PPR sends a
request back to the application on the middle-tier to fetch the new contents. However, when PPR is used to
update the page, only the modified contents are sent back to the browser. UIX automatically merges the new
contents back into the web page. The end result is that the page is updated without custom JavaScript code, and
without the loss of context that typically occurs with a full page refresh.

How Partial Page Rendering Works


The partial page rendering process breaks down into three main areas: the partial page event, the partial page
rendering pass, and the partial page replacement.

The partial page event is the request that the browser sends to the application to request new contents. Partial
page events are very similar to their full page event equivalents. For example, when the user navigates to a new
record set in a table bean, a goto event with a value event parameter is sent to the application regardless of
whether the event is a partial or full page event. There are two important differences between partial and full
page events. First, partial page events specify partial page rendering-specific event parameters which are not
present on the full page event equivalents. For example, partial page events may include an event parameter
which identifies the set of nodes that should be re-rendered (referred to as "partial targets"). The second
difference between partial page events an full page events is how the events are sent.

Unlike full page events, partial page events must be sent in a way which does not force the browser to reload the
current page. To implement this capability, UIX partial page rendering uses a hidden inline frame (iframe) as a
communication channel between the browser and the web application running on the middle-tier. Partial page
events are sent by forcing a navigation in the hidden iframe, which in turn causes a request to be sent to the
application on the middle-tier. Since the iframe is hidden, the process of sending a partial page event and
rendering partial page contents can take place behind the scenes, without discarding the contents of the current
page.

When the partial page event is received by the application, the application responds by determining the set of
partial targets to render and performing the partial page rendering pass. The partial page rendering pass is
similar to a full page rendering pass. In both cases, the UINode tree is traversed by calling render() on each node
in the tree. However, in the partial page rendering case, only the contents generated by the partial targets are
actually sent back to the browser. All other contents are dropped. So, although the scope of a partial page
rendering pass and full page rendering pass are similar in the number of UINodes that are rendered, the partial
page response is generally much smaller, since only the modified contents are sent back to the browser.

The final part of the PPR process is the partial page replacement. When the browser receives the partial page
response, the new contents for each partial target node are copied from the hidden iframe into the main
browser window, replacing the existing contents for each target node. So, for example, in the table navigation
case, rather than replacing the entire page, just the contents of the table itself are replaced. The browser reflows
in response to the modifications, displaying the new contents to the user without fully re-rendering the entire
page.

177
www.AppsLead.com
To recap, the sequence of steps which occur during a partial page render are:

The initial page is rendered.


The user performs some action which triggers a partial page render, for example clicking on a link or button.
JavaScript event handlers provided by UIX force a navigation in a hidden iframe.
The partial page event is sent to the application.
The application determines whether the request is a partial page event and which partial target nodes to re-
render.
The partial page rendering pass is performed.
The contents of the partial target nodes are sent back to the iframe in the browser.
The partial page replacement is performed, at which point the new contents are copied from the iframe into the
main browser window.
The browser re-flows and displays the new content to the end user.
Note that the partial page rendering process requires no custom JavaScript code.
(The source of this article is Oracle UIX documentation.)

174
www.AppsLead.com
Partial Page Rendering in OAF Page

Let us try to implement partial page rendering for a text item.

If value of TextItem1 is null then TextItem2 will not be appreared on UI.

If value of TextItem1 is not null then TextItem2 will be appreared on UI.

1. Create a New OA Workspace and Empty OA Project

File> New > General> Workspace Configured for Oracle Applications

File Name -- PPRProj

Project Name – PPRDemoProj

Default Package -- prajkumar.oracle.apps.fnd.pprdemo

2. Create Application Module AM

PPRDemoProj right click > New > ADF Business Components > Application Module

Name -- PPRAM

Package -- prajkumar.oracle.apps.fnd.pprdemo.server

Check Application Module Class: PPRAMImpl Generate JavaFile(s)

3. Create a PPRVO View Object

PPRDemoProj> New > ADF Business Components > View Objects

Name – PPRVO

Package – prajkumar.oracle.apps.fnd.pprdemo.server

In Attribute Page

Click on New button and create transient primary key attribute with the following properties:

Attribute Property

Name RowKey

Type Number

Updateable Always

Key Attribute (Checked)

179
www.AppsLead.com
Click New button again and create transient attribute with the following properties:

Attribute Property

Name TextItem2Render

Type Boolean

Updateable Always

Note – No Need to generate any JAVA files for PPRVO

4. Add Your View Object to Root UI Application Module

Right click on PPRAM > Edit PPRAM > Data Model >

Select PPRVO in Available View Objects list and shuttle to Data Model list

5. Create a OA components Page

PPRDemoProj right click > New > OA Components > Page

Name – PPRPG

Package -- prajkumar.oracle.apps.fnd.pprdemo.webui

6. Modify the Page Layout (Top-level) Region

Attribute Property

ID PageLayoutRN

Region Style pageLayout

Form Property True

Auto Footer True

Window Title PPR Demo Window Title True

Title PPR Demo Page Header

AM Definition prajkumar.oracle.apps.fnd.pprdemo.server.PPRAM

143
www.AppsLead.com
7. Create the Second Region (Main Content Region)

Right click on PageLayoutRN > New > Region

Attribute Property

ID MainRN

Region Style messageComponentLayout

8. Create Two Text Items

Create First messageTextItem --

Right click on MainRN > New > messageTextInput

Attribute Property

ID TextItem1

Region Style messageTextInput

Prompt Text Item1

Length 20

Disable Server Side Validation True

Disable Client Side Validation True

Action Type firePartialAction

Event TextItem1Change

Submit True

Note -- Disable Client Side Validation and Event property appears after you set the Action Type
property to firePartialAction

Create Second messageTextItem --

Select MainRN right click > New > messageTextInput

141
www.AppsLead.com
Attribute Property

ID TextItem2

Region Style messageTextInput

Prompt Text Item2

Length 20

Rendered ${oa.PPRVO1.TextItem2Render}

9. Add Following code in PPRAMImpl.java

import oracle.apps.fnd.framework.OARow;
import oracle.apps.fnd.framework.OAViewObject;
import oracle.apps.fnd.framework.server.OAApplicationModuleImpl;
import oracle.apps.fnd.framework.server.OAViewObjectImpl;

public void handlePPRAction()


{
Number val = 1;
OAViewObject vo = (OAViewObject)findViewObject("PPRVO1");

if (vo != null)
{
if (vo.getFetchedRowCount() == 0)
{
vo.setMaxFetchSize(0);
vo.executeQuery();
vo.insertRow(vo.createRow());
OARow row = (OARow)vo.first();

row.setAttribute("RowKey", val);
row.setAttribute("TextItem2Render", Boolean.FALSE);
}
}
}

10. Implement Controller for Page

Select PageLayoutRN in Structure pane right click > Set New Controller

Package Name -- prajkumar.oracle.apps.fnd.pprdemo.webui

Class Name – PPRCO

Write following code in processFormRequest function of PPRCO Controller

141
www.AppsLead.com
import oracle.apps.fnd.framework.OARow;
import oracle.apps.fnd.framework.OAViewObject;

public void processRequest(OAPageContext pageContext, OAWebBean webBean)


{
super.processRequest(pageContext, webBean);
PPRAMImpl am = (PPRAMImpl)pageContext.getApplicationModule(webBean);

am.invokeMethod("handlePPRAction");
}

public void processFormRequest(OAPageContext pageContext, OAWebBean webBean)


{
super.processFormRequest(pageContext, webBean);

PPRAMImpl am = (PPRAMImpl)pageContext.getApplicationModule(webBean);
OAViewObject vo = (OAViewObject)am.findViewObject("PPRVO1");
OARow row = (OARow)vo.getCurrentRow();

if ("TextItem1Change".equals(pageContext.getParameter(EVENT_PARAM)))
{
if (pageContext.getParameter("TextItem1").equals(""))
{
row.setAttribute("TextItem2Render", Boolean.FALSE);
}
else
{
row.setAttribute("TextItem2Render", Boolean.TRUE);
}
}
}

11. Congratulation you have successfully finished. Run Your PPRPG page and Test Your Work

140
www.AppsLead.com
143
www.AppsLead.com
PPR (Partial Page Rendering) in OAF

While developing pages, we may face some scenarios where the requirement is to make modifications on the
current page itself, instead of navigating to different page. Such as selecting an item from a choice list might
result in modifications to other fields or clicking a button to add a new row in table region and many more like
these.

All these tasks can be performed by simply refreshing the page however this could result in performance issues.
Another alternative is to use javaScript which will give faster results but implementing complex functions can be
a tough job using javaScript.

UIX Framework provides a solution for this: Partial Page Rendering i.e. to re-render only a limited portion of a
page.

Working of PPR :-

==========================

PPR is a three step process:

1) Partial page event

Partial page events are quite similar to full page events. However, there are two important differences between
partial and full page events. First, partial page events specify partial page rendering-specific event parameters
which are not present on the full page event equivalents. For example, partial page events may include an event
parameter which identifies the set of partial targets, or nodes that should be re-rendered.
The second difference between partial page events an full page events is how the events are sent. Unlike full
page events, partial page events must be sent in a way which does not force the browser to reload the current
page. To implement this capability, UIX PPR uses a hidden iframe as a communication channel between the
browser and the web application running on the middle-tier. Partial page events are sent by forcing a navigation
in the hidden iframe, which in turns causes a request to be sent to the application on the middle-tier. Since the
iframe is hidden, the process of sending a partial page event and rendering partial page contents can take place
behind the scenes, without discarding the contents of the current page.

2) Partial Page Rendering Pass

When the partial page event is received by the application, the application responds by determining the set of
partial targets to render and performing the partial page rendering pass. The partial page rendering pass is
similar to a full page rendering pass. In both cases, the UINode tree is traversed by calling render() on each node
in the tree. However, in the PPR case, only the contents generated by the partial targets are actually sent back to
the browser. All other contents are dropped. So, the partial page response is generally much smaller, since only
the modified contents are sent back to the browser.

3) Partial Page Replacement

When the browser receives the partial page response, the new contents for each partial target node are copied
from the hidden iframe into the main browser window, replacing the existing contents for each target node. For

142
www.AppsLead.com
example, in the table navigation case, rather than replacing the entire page, just the contents of the table itself
are replaced.

Now lets create a simple page to implement PPR. In this page, there are 3 items (employee number, employee
name & job). I have attach a PPR event on employee number field. Hence, user will enter the emp number and as
soon as he tabs out, name and job will populate on their respective fields without refreshing the page.

1) Create a new OA page:

==========================

Right click on project (xxcus) --> New --> Web Tier --> OA Components --> select 'Page' item. Click OK. (This will
open a popup window)

We are creating a page for implementing PPR, so specify the details of page as below:

Name: XxPprDemoPG

Package: xxcus.oracle.apps.fnd.pprdemo.webui

2) Create a new view objects (VO):

==========================

Right click --> New View Object (This will open a wizard having 7 steps).

Step 1

Package: xxcus.oracle.apps.fnd.pprdemo.server

Name: XxPprDemoVO

Choose the radio button 'Read-only Access' (as no DML operation).


Click Next.

Step 2

Enter the below query in 'Query Statement':

select EMPNO, ENAME, JOB from employee

Keep defaults for step3, 4, 5, 6 & 7 and click Finish. Save All.

3) Create a new Application Module (AM):

==========================

Step 1

Package: xxcus.oracle.apps.fnd.pprdemo.server

Name: XxPprDemoAM. Click Next.

146
www.AppsLead.com
Step 2

Here we will add an instance of the VO created in (2). Select XxPprDemoVO from 'Available View Objects' and
shuttle it to 'Data Model' using ">" button.

Keep defaults for all other steps (3, 4). Click Finish.

4) Create a new Controller (CO):

==========================

Right click on pageLayout region and create a new controller:

Name: XxPprDemoCO

package: xxcus.oracle.apps.fnd.pprdemo.webui

5) Creating the Page Layout & Setting its Properties :-

==========================
The page will appear as below:

1) Create a new region under pageLayout of type defaultSingleColumn.

2) Create 3 items under defaultSingleColumn region (messageTextInput, messageStyledText, messageStyledText).

Now change the properties for each field from property inspector as shown below:

pageLayout:

ID: pageLayoutRN

AM Definition: xxcus.oracle.apps.fnd.pprdemo.server.XxPprDemoAM

Window Title: PPR Demo Page

Title: PPR Demo

defaultSingleColumn:
ID: singleColRN
Text: Enter Employee Number

147
www.AppsLead.com
messageTextInput (applied PPR event on this item):
ID: Empno

Prompt: Employee Number

Action Type: firePartialAction

Event: populateFields

messageStyledText (for Employee Name):

ID: Ename

Prompt: Employee Name

View Instance: XxPprDemoVO1

View Attribute: Ename

messageStyledText (for Job):

ID: Job

Prompt: Job

View Instance: XxPprDemoVO1

View Attribute: Job

The declarative page structure in jDev will be similar to as shown below:

144
www.AppsLead.com
We will capture populateFields event (PPR event) in PFR method of controller and call the appropriate method
from AMImpl class as shown in below code snippet:

1 public void processFormRequest(OAPageContext pageContext,

2 OAWebBean webBean) {

3 super.processFormRequest(pageContext, webBean);

5 OAApplicationModule am = pageContext.getRootApplicationModule();

7 if ("populateFields".equals(pageContext.getParameter(EVENT_PARAM))) {

8 String empNum = pageContext.getParameter("Empno");

9 if (!("".equals(empNum.trim()))) {

10 Serializable[] param = { empNum };

11 String result =

12 am.invokeMethod("firePprEvent", param).toString();

13 if ("N".equals(result)) {

14 throw new OAException("Please enter valid employee number.",

15 OAException.ERROR);

16 }

17 } else {

18 String empnum = null;

19 Serializable[] param = { empnum };

20 am.invokeMethod("firePprEvent", param);

21 throw new OAException("Please enter employee number",

22 OAException.ERROR);

23 }

24 }

25}

Code for firePprEvent method in XxPprDemoAMImpl.java file:

1 public String firePprEvent(String empNum) {


2 try {

3 XxPprDemoVOImpl vo = getXxPprDemoVO1();
4 vo.setWhereClause(null);

149
www.AppsLead.com
5 vo.setWhereClauseParams(null);

6 vo.setWhereClause("EMPNO = :1");

7 vo.setWhereClauseParam(0, empNum);

8 vo.setMaxFetchSize(-1);

9 vo.executeQuery();

10 XxPprDemoVORowImpl row = (XxPprDemoVORowImpl)vo.first();

11 if (row == null) {

12 return "N";

13 }

14 } catch (Exception e) {

15 e.printStackTrace();

16 }

17 return "Y";

18}

User will enter employee number and tabs out. This will auto-populate the other two fields without full page
refresh as shown below:

193
www.AppsLead.com
Programmatic PPR in OAF
I was recently helping a friend in a customization in OAF, where through personalization, he wanted to put a ppr
action in a seeded page in a seeded item. He was trying to do that customization using fire action, which was not
acceptable by customer due to obvious reasons. Since, I think this section is missing in developers' guide, and is
quite simple to approach, here is code you can write in process request of CO to attach programmatic PPR. lets
take a simple example of attaching PPR to a message choice bean :

//In Process Request()


{
//Please attach PPR only to those UIX beans which support it
//otherwise it may not work
OAMessageChoiceBean mcb=(OAMessageChoiceBean)webBean.findChildRecursive("");
FireAction firePartialAction = new FirePartialAction("empPositionChange");
mcb.setAttributeValue(PRIMARY_CLIENT_ACTION_ATTR,firePartialAction);
}

//In process form request


if ("empPositionChange".equals(pageContext.getParameter(OAWebBeanConstants.EVENT_PARAM)))
{
//ur logic on PPR

//if PPR is attached in a table/hgrid child then we can find the row
//reference by
String rowReference =pageContext.getParameter(OAWebBeanConstants.EVENT_SOURCE_ROW_REFERENCE);
}

191
www.AppsLead.com
Partial Page Rendering in OAF Page
Method1

Let us try to implement partial page rendering for a text item.

If value of TextItem1 is null then TextItem2 will not be appeared on UI.

If value of TextItem1 is not null then TextItem2 will be appeared on UI.

1. Create a New OA Workspace and Empty OA Project


File> New > General> Workspace Configured for Oracle Applications
File Name -- PPRProj
Project Name – PPRDemoProj
Default Package -- mahi.oracle.apps.fnd.pprdemo
2. Create Application Module AM
PPRDemoProj right click > New > ADF Business Components > Application
Module
Name -- PPRAM
Package -- mahi.oracle.apps.fnd.pprdemo.server

Check Application Module Class: PPRAMImpl Generate JavaFile(s)


3. Create a PPRVO View Object
PPRDemoProj> New > ADF Business Components > View Objects
Name – PPRVO
Package – mahi.oracle.apps.fnd.pprdemo.server

In Attribute Page
Click on New button and create transient primary key attribute with the following
properties:

Attribute Property

Name RowKey

Type Number

Updateable Always

Key Attribute (Checked)

191
www.AppsLead.com
Click New button again and create transient attribute with the following properties:

Attribute Property

Name TextItem2Render

Type Boolean

Updateable Always

Note – No Need to generate any JAVA files for PPRVO

4. Add Your View Object to Root UI Application Module

Right click on PPRAM > Edit PPRAM > Data Model >

Select PPRVO in Available View Objects list and shuttle to Data Model list
5. Create a OA components Page

PPRDemoProj right click > New > OA Components > Page

Name – PPRPG

Package -- prajkumar.oracle.apps.fnd.pprdemo.webui
6. Modify the Page Layout (Top-level) Region

Attribute Property

ID PageLayoutRN

Region Style pageLayout

Form Property True

Auto Footer True

Window Title PPR Demo Window Title True

Title PPR Demo Page Header

AM Definition prajkumar.oracle.apps.fnd.pprdemo.server.PPRAM

190
www.AppsLead.com
7. Create the Second Region (Main Content Region)

Right click on PageLayoutRN > New > Region

Attribute Property

ID MainRN

Region Style messageComponentLayout

8. Create Two Text Items

Create First messageTextItem --

Right click on MainRN > New > messageTextInput

Attribute Property

ID TextItem1

Region Style messageTextInput

Property Text Item1

Length 20

Disable Server Side Validation True

Disable Client Side Validation True

Action Type firePartialAction

Event TextItem1Change

Submit True

Note -- Disable Client Side Validation and Event property appears after you set
the Action Type property to firePartialAction

Create Second messageTextItem --

193
www.AppsLead.com
Select MainRN right click > New > messageTextInput

Attribute Property

ID TextItem2

Region Style messageTextInput

Property Text Item2

Length 20

Rendered ${oa.PPRVO1.TextItem2Render}

9. Add Following code in PPRAMImpl.java

import oracle.apps.fnd.framework.OARow;
import oracle.apps.fnd.framework.OAViewObject;
import oracle.apps.fnd.framework.server.OAApplicationModuleImpl;
import oracle.apps.fnd.framework.server.OAViewObjectImpl;

public void handlePPRAction()


{
Number val = 1;
OAViewObject vo = (OAViewObject)findViewObject("PPRVO1");

if (vo != null)
{
if (vo.getFetchedRowCount() == 0)
{
vo.setMaxFetchSize(0);
vo.executeQuery();
vo.insertRow(vo.createRow());
OARow row = (OARow)vo.first();

row.setAttribute("RowKey", val);
row.setAttribute("TextItem2Render", Boolean.FALSE);
}
}
}
10. Implement Controller for Page

Select PageLayoutRN in Structure pane right click > Set New Controller

192
www.AppsLead.com
Package Name -- prajkumar.oracle.apps.fnd.pprdemo.webui

Class Name – PPRCO

Write following code in processFormRequest function of PPRCO Controller

import oracle.apps.fnd.framework.OARow;
import oracle.apps.fnd.framework.OAViewObject;

public void processRequest(OAPageContext pageContext, OAWebBean webBean)


{
super.processRequest(pageContext, webBean);
PPRAMImpl am = (PPRAMImpl)pageContext.getApplicationModule(webBean);

am.invokeMethod("handlePPRAction");
}

public void processFormRequest(OAPageContext pageContext, OAWebBean


webBean)
{
super.processFormRequest(pageContext, webBean);

PPRAMImpl am = (PPRAMImpl)pageContext.getApplicationModule(webBean);
OAViewObject vo = (OAViewObject)am.findViewObject("PPRVO1");
OARow row = (OARow)vo.getCurrentRow();

if ("TextItem1Change".equals(pageContext.getParameter(EVENT_PARAM)))
{
if (pageContext.getParameter("TextItem1").equals(""))
{
row.setAttribute("TextItem2Render", Boolean.FALSE);
}
else
{
row.setAttribute("TextItem2Render", Boolean.TRUE);
}
}
}
11. Congratulation you have successfully finished. Run Your PPRPG page and Test Your
Work

196
www.AppsLead.com
Method2

PPR (Partial Page Rendering) in OAF :

While developing pages, we may face some scenarios where the requirement is to make modifications
on the current page itself, instead of navigating to different page. Such as selecting an item from a
choice list might result in modifications to other fields or clicking a button to add a new row in table
region and many more like these.
All these tasks can be performed by simply refreshing the page however this could result in performance
issues. Another alternative is to use javaScript which will give faster results but implementing complex
functions can be a tough job using javaScript.

UIX Framework provides a solution for this: Partial Page Rendering i.e. to re-render only a limited
portion of a page.

Working of PPR :-

PPR is a three step process:

1) Partial page event

197
www.AppsLead.com
Partial page events are quite similar to full page events. However, there are two important differences
between partial and full page events. First, partial page events specify partial page rendering-specific
event parameters which are not present on the full page event equivalents. For example, partial page
events may include an event parameter which identifies the set of partial targets, or nodes that should
be re-rendered.
The second difference between partial page events an full page events is how the events are
sent. Unlike full page events, partial page events must be sent in a way which does not force the
browser to reload the current page. To implement this capability, UIX PPR uses a hidden iframe as a
communication channel between the browser and the web application running on the middle-tier. Partial
page events are sent by forcing a navigation in the hidden iframe, which in turns causes a request to be
sent to the application on the middle-tier. Since the iframe is hidden, the process of sending a partial
page event and rendering partial page contents can take place behind the scenes, without discarding
the contents of the current page.

2) Partial Page Rendering Pass

When the partial page event is received by the application, the application responds by determining the
set of partial targets to render and performing the partial page rendering pass. The partial page
rendering pass is similar to a full page rendering pass. In both cases, the UINode tree is traversed by
calling render() on each node in the tree. However, in the PPR case, only the contents generated by the
partial targets are actually sent back to the browser. All other contents are dropped. So, the partial page
response is generally much smaller, since only the modified contents are sent back to the browser.

3) Partial Page Replacement

When the browser receives the partial page response, the new contents for each partial target node are
copied from the hidden iframe into the main browser window, replacing the existing contents for each
target node. For example, in the table navigation case, rather than replacing the entire page, just the
contents of the table itself are replaced.

Now lets create a simple page to implement PPR. In this page, there are 3 items (employee number,
employee name & job). I have attach a PPR event on employee number field. Hence, user will enter the
emp number and as soon as he tabs out, name and job will populate on their respective fields without
refreshing the page.

1) Create a new OA page:


Right click on project (xxcus) --> New --> Web Tier --> OA Components --> select
'Page' item. Click OK. (This will open a popup window)
We are creating a page for implementing PPR, so specify the details of page as
below:
Name: XxPprDemoPG
Package: xxcus.oracle.apps.fnd.pprdemo.webui
2) Create a new view objects (VO):
Right click --> New View Object (This will open a wizard having 7 steps).

Step 1
Package: xxcus.oracle.apps.fnd.pprdemo.server
Name: XxPprDemoVO
Choose the radio button 'Read-only Access' (as no DML operation).
Click Next.

Step 2
Enter the below query in 'Query Statement':
select EMPNO, ENAME, JOB from employee

Keep defaults for step3, 4, 5, 6 & 7 and click Finish. Save All.

194
www.AppsLead.com
3) Create a new Application Module (AM):
Step 1
Package: xxcus.oracle.apps.fnd.pprdemo.server
Name: XxPprDemoAM. Click Next.

Step 2
Here we will add an instance of the VO created in (2). Select XxPprDemoVO
from 'Available View Objects' and shuttle it to 'Data Model' using ">" button.
Keep defaults for all other steps (3, 4). Click Finish.
4) Create a new Controller (CO):
Right click on pageLayout region and create a new controller:
Name: XxPprDemoCO
package: xxcus.oracle.apps.fnd.pprdemo.webui
5) Creating the Page Layout & Setting its Properties :-

1) Create a new region under pageLayout of type defaultSingleColumn.


2) Create 3 items under defaultSingleColumn region (messageTextInput,
messageStyledText, messageStyledText).

Now change the properties for each field from property inspector as shown below:

pageLayout:
ID: pageLayoutRN
AM Definition: xxcus.oracle.apps.fnd.pprdemo.server.XxPprDemoAM
Window Title: PPR Demo Page
Title: PPR Demo

defaultSingleColumn:
ID: singleColRN
Text: Enter Employee Number

messageTextInput (applied applied PPR event on this item):


ID: Empno
Prompt: Employee Number

199
www.AppsLead.com
Action Type: firePartialAction
Event: populateFields

messageStyledText (for Employee Name):


ID: Ename
Prompt: Employee Name
View Instance: XxPprDemoVO1
View Attribute: Ename

messageStyledText (for Job):


ID: Job
Prompt: Job
View Instance: XxPprDemoVO1
View Attribute: Job

The declarative page structure in jDev will be similar to as shown below:

We will capture populateFields event (PPR event) in PFR method of controller and
call the appropriate method from AMImpl class as shown in below code snippet:

033
www.AppsLead.com
public void processFormRequest(OAPageContext pageContext,
OAWebBean webBean) {
super.processFormRequest(pageContext, webBean);

OAApplicationModule am = pageContext.getRootApplicationModule();

if ("populateFields".equals(pageContext.getParameter(EVENT_PARAM))) {
String empNum = pageContext.getParameter("Empno");
if (!("".equals(empNum.trim()))) {
Serializable[] param = { empNum };
String result =
am.invokeMethod("firePprEvent", param).toString();
if ("N".equals(result)) {
throw new OAException("Please enter valid employee number.",
OAException.ERROR);
}
} else {
String empnum = null;
Serializable[] param = { empnum };
am.invokeMethod("firePprEvent", param);
throw new OAException("Please enter employee number",
OAException.ERROR);
}
}

Code for firePprEvent method in XxPprDemoAMImpl.java file:


public String firePprEvent(String empNum) {
try {
XxPprDemoVOImpl vo = getXxPprDemoVO1();
vo.setWhereClause(null);
vo.setWhereClauseParams(null);
vo.setWhereClause("EMPNO = :1");
vo.setWhereClauseParam(0, empNum);
vo.setMaxFetchSize(-1);
vo.executeQuery();
XxPprDemoVORowImpl row = (XxPprDemoVORowImpl)vo.first();
if (row == null) {
return "N";
}
} catch (Exception e) {
e.printStackTrace();
}
return "Y";

031
www.AppsLead.com
User will enter employee number and tabs out. This will auto-populate the other two
fields without full page refresh as shown below:

Method3

Programmatic PPR in OAF:

I was recently helping a friend in a customization in OAF, where through personalization, he wanted to
put a ppr action in a seeded page in a seeded item. He was trying to do that customization using fire
action, which was not acceptable by customer due to obvious reasons. Since, I think this section is
missing in developers' guide, and is quite simple to approach, here is code you can write in process
request of CO to attach programmatic PPR. lets take a simple example of attaching PPR to a message
choice bean :

//In Process Request()


{
//Please attach PPR only to those UIX beans which support it
//otherwise it may not work
OAMessageChoiceBean mcb=(OAMessageChoiceBean)webBean.findChildRecursive("");
FireAction firePartialAction = new FirePartialAction("empPositionChange");
mcb.setAttributeValue(PRIMARY_CLIENT_ACTION_ATTR,firePartialAction);
}

//In process form request


if ("empPositionChange".equals(pageContext.getParameter(OAWebBeanConstants.EVENT_PARAM)))
{
//ur logic on PPR

//if PPR is attached in a table/hgrid child then we can find the row
//reference by
String rowReference
=pageContext.getParameter(OAWebBeanConstants.EVENT_SOURCE_ROW_REFERENCE);
}

031
www.AppsLead.com
Adding programmatic fire Action to UIX beans which dont support it
Recently, a friend had a requirement of a customization in a seeded page where he needs to put some validation
on a table column which was actually OAMessageDateFieldBean.

This is quite simple and generic requirement , when he called me ...I told him that since , this has to be done in
seeded Oracle page and fire action elements can't be added by personalization,he just needs to extend the CO
and attach fire action programatically to the OAMessageDateFieldBean in process request and then can handle
his logic of validation in process form request.But the tricky part came when he told me his code is not
compiling since setFireActionForSubmit API is absent in OAMessageDateFieldBean class.

I just wondered how is it possible since this bean allows me to configure fireaction decalaratively, then there
should be an API of doing it programatically too in the bean. Then I remebered with each UIX bean Oracle also
gives a helper class, which can usually be instantiated by using getHelper(), on the bean instance.

Whenever you are in such situations, it’s worth while to look into bean helper classes. Ok.. so here is the code
how you can configure firection on OAMessageDateFieldBean programatically :

//In process request.

//getting table bean instance


OATableBean t=(OATableBean)webBean.findChildRecursive("< table bean id >");

//getting OAMessageDateFieldBean inside


//table bean
OAMessageDateFieldBean expDate = (OAMessageDateFieldBean)t.findChildRecursive("<
OAMessageDateFieldBean id >");

//hard-parameters for fire action


//it will help us to identify if action
//has occured or not
Hashtable params = new Hashtable (1);
params.put ("XX_ACTION","XXX");

//bound value parameters for fire action


// basically the primary key attribute of
//VO to get the row from which action has occured
//eg, lets say the VO attribute is Visit id AND
//that is primary key
Hashtable paramsWithBinds = new Hashtable(1);
paramsWithBinds.put ("XX_PRIMARY",new OADataBoundValueFireActionURL((OAWebBeanData) expDate,
"{$VisitId}"));

//Most important---
//taking helper class instance
// there we get the API to attach fire action.
expDate.getHelper().setFireActionForSubmit(expDate,"delete",params, paramsWithBinds,false,false);

//In Process form request

if(pageContext.getParameter("XX_ACTION")!=null)
{
//by this primary key we can retrieve the VO row at which
// action occured and utilise the other column data
// for validations.
String primary_key=pageContext.getParameter("XX_PRIMARY");

.......

//finally releasing the parameters from


//current pagecontext requesr
pagecontext.removeParameter("XX_ACTION");

030
www.AppsLead.com
pagecontext.removeParameter("XX_PRIMARY");
}

Alternative : There is a alternate way to attach PPR/Fireaction to any bean.Use static methods in class
OAWebBeanUtils, like
OAWebBeanUtils.getFirePartialActionForSubmit()
OAWebBeanUtils.getFireActionForSubmit()
and then use

// finally set it on your bean


bean.setAttributeValue
(PRIMARY_CLIENT_ACTION_ATTR, fireAction);

033
www.AppsLead.com
Programmatically Add Region to OA Page
Sometimes in OAF, you want to add a region to OA Page.

For example i had a requirement to add employee summary region to another page.
Employee Summary Page exists at MDS at this path
"/oracle/apps/per/selfservice/common/webui/AsgSummaryRN".

Application module that is used with this region is "oracle.apps.per.selfservice.common.server.SummaryAM"

I wrote the following code to add this page to another page at controller of OA page

ipublic void processRequest(OAPageContext pageContext, OAWebBean webBean) {


super.processRequest(pageContext, webBean);

OATableLayoutBean empSummaryBeean =
(OATableLayoutBean)this.createWebBean(pageContext,
"/oracle/apps/per/selfservice/common/webui/AsgSummaryRN",
"AsgSummaryRN", true);

empSummaryBeean.setApplicationModuleDefinitionName("oracle.apps.per.selfservice.common.server.Summar
yAM");
empSummaryBeean.setStandalone(true);
webBean.addIndexedChild(0, empSummaryBeean);
}

032
www.AppsLead.com
Implement Train in OAF Page

Let us try to implement train between three pages. Consider three pages each having Text Item

1. Create a New OA Workspace and Empty OA Project

File> New > General> Workspace Configured for Oracle Applications

File Name -- TrainProj

Project Name – TrainDemoProj

Default Package -- prajkumar.oracle.apps.fnd.traindemo

2. Create Application Module AM

TrainDemoProj right click > New > ADF Business Components > Application Module

Name -- TrainDemoAM

Package -- prajkumar.oracle.apps.fnd.traindemo.server

Check Generate JavaFile(s)

Create Three Pages TrainDemoPG1, TrainDemoPG2 and TrainDemoPG3 as similar way as mention below to
create TrainDemoPG1

3. Create a OA components Pages

TrainDemoProj right click > New > OA Components > Page

Name – TrainDemoPG1

Package -- prajkumar.oracle.apps.fnd.traindemo.webui

4. Modify the Page Layout (Top-level) Region

Attribute Property

ID PageLayoutRN

Region Style pageLayout

Form Property True

Auto Footer True

Window Title Train Demo Window Title

Title Train Demo Page Header

AM Definition prajkumar.oracle.apps.fnd.traindemo.server.TrainDemoAM

036
www.AppsLead.com
5. Create the Second Region (Main Content Region)

Select PageLayoutRN right click > New > Region

Attribute Property

ID MainRN

Region Style messageComponentLayout

Create Text Items for all three pages say TextItemPage1, TextItemPage2 and TextItemPage3 in respective
pages TrainDemoPG1, TrainDemoPG2 and TrainDemoPG3 in similar way of as mention below to create
TextItemPage1 in page TrainDemoPG1

6. Create Text Items

Select MainRN right click > New > messageTextInput

Prompt – TextItemPage1

Length -- 20

7. Create a Standalone Train Region

TrainDemoProj > New > Web Tier > OA Components > Region

Name -- TrainRN

Package – prajkumar.oracle.apps.fnd.traindemo.webui

Style – train

Select TrainRN inStructure pane and open property inspector and set Allow Interactionproperty to True

8. Add Three Train Nodes to TrainRN

Right Click on TrainRN in Structure pane > New > Link

Set the link properties as follow --

ID – TrainStep1

Item Style – link

Text – Step 1

Destination URI – OA.jsp?page=/prajkumar/oracle/apps/fnd/traindemo/webui/TrainDemoPG1

Right Click on TrainRN in Structure pane > New > Link

Set the link properties as follow --


037
www.AppsLead.com
ID – TrainStep2

Item Style – link

Text – Step 2

Destination URI – OA.jsp?page=/prajkumar/oracle/apps/fnd/traindemo/webui/TrainDemoPG2

Right Click on TrainRN in Structure pane > New > Link

Set the link properties as follow --

ID – TrainStep3

Item Style – link

Text – Step 3

Destination URI – OA.jsp?page=/prajkumar/oracle/apps/fnd/traindemo/webui/TrainDemoPG3

9. Add Train Region to each of your Pages

For each of three pages in multistep flow, right click the pageLayoutRN in structure panel, and select New >
location from page Context menu

Set following properties as follow --

ID – TrainDemoRN

Extends -- /prajkumar/oracle/apps/fnd/traindemo/webui/TrainRN

10. Create a Standalone (Shared) TrainFooterRN

TrainDemoProj > New > Web Tier > OA Components > Region

Name -- TrainFooterRN

Package -- prajkumar.oracle.apps.fnd.traindemo.webui

Region Style -- pageButtonBar

11. Add navigrationBar

Select TrainFooterRN in Structure pane right click > New > Region

Set the region properties as follows:

ID -- NavBar

Region Style – navigationBar

First Step – 1

Last Step – 3

034
www.AppsLead.com
12. Add Links to the navigrationBar

Right Click on NavBar > New > link

Set Item’s properties as follows:

ID – Step1Link

Item Style – link

Text – Step 1 of 3: Page1

Warn About Changes – False

Destination URI -- /prajkumar/oracle/apps/fnd/traindemo/webui/TrainDemoPG1

Right Click on NavBar > New > link

Set Item’s properties as follows:

ID – Step2Link

Item Style – link

Text – Step 2 of 3: Page2

Warn About Changes – False

Destination URI -- /prajkumar/oracle/apps/fnd/traindemo/webui/TrainDemoPG2

Right Click on NavBar > New > link

Set Item’s properties as follows:

ID – Step3Link

Item Style – link

Text – Step 3 of 3: Page3

Warn About Changes – False

Destination URI -- /prajkumar/oracle/apps/fnd/traindemo/webui/TrainDemoPG3

13. Initialize the Footer Region

Select TrainFooterRN in Structure pane right click > Set New Controller

Class Name -- TrainDemoCO

Package Name – prajkumar.oracle.apps.fnd.traindemo.webui

import oracle.apps.fnd.framework.webui.beans.nav.OATrainBean;
import oracle.apps.fnd.framework.webui.beans.nav.OANavigationBarBean;
...
039
www.AppsLead.com
public void processRequest(OAPageContext pageContext, OAWebBean webBean)
{
super.processRequest(pageContext, webBean);

OATrainBean trainBean =
(OATrainBean)pageContext.getPageLayoutBean().getLocation();

trainBean.prepareForRendering(pageContext);

int step = trainBean.getSelectedTrainStepRenderedIndex();

OANavigationBarBean navBean =
(OANavigationBarBean)webBean.findChildRecursive("NavBar");

navBean.setValue(step+1);

14. Add the Navigation Region to your pages

For each of three pages in the multistep flow, right click the PageLayoutRN in Structure pane and select New >
Region

Set the region’s properties as follow:

ID -- PageButtonBar

Style -- pageButtonBar

Extends -- /prajkumar/oracle/apps/fnd/traindemo/webui/TrainFooterRN

15. Congratulation you have successfully finished. Run Your TrainDemoPG1 page and Test Your Work

013
www.AppsLead.com
Cate

011
www.AppsLead.com
Execute sql script in OAF
// Required import packages
import oracle.apps.fnd.framework.server.OADBTransaction;
import oracle.apps.fnd.framework.webui.OAPageContext;
import oracle.apps.fnd.framework.server.OAApplicationModuleImpl;
import oracle.apps.fnd.framework.OAException;
import oracle.apps.fnd.framework.OAApplicationModule;
import oracle.apps.fnd.framework.webui.beans.OAWebBean;
import oracle.jbo.domain.Number;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
//

try
{
Connection conn =
paramOAPageContext.getApplicationModule(paramOAWebBean).getOADBTransaction().get
JdbcConnection();

String Query ="SELECT empId resultId,empName resultName,empPosition resultPos from


XXXXX_TABLE WHERE DeptId=:1";

PreparedStatement stmt = conn.prepareStatement(Query);

stmt.setInt(1, departmentId);

for (ResultSet resultset = stmt.executeQuery(); resultset.next(); )


{
int employeeId = resultset.getInt("resultId");
String employeeName = resultset.getstring("resultName");
String employeePosition = resultset.getString("resultPos");
}

stmt.close();

}catch(SQLException sqle)
{
throw new OAException("Exception Block"+sqle);
}

011
www.AppsLead.com
Execute PL/SQL Function from OAF Page
Here is a simple demo for how to call a PL/SQL function from OAF page.

I have created a very basic page having one LOV and a submit button. User will select employee number from
LOV field and then click on Go button.
On clicking 'Go' button, we call a PL/SQL function which taking this employee number as parameter and will
return employee name and job for that particular employee.
Finally we will display that information as a message to the user.

Below is the function which retrieves the information for an employee number:

CREATE OR REPLACE FUNCTION xx_get_emp_details (p_empnum IN VARCHAR2)


RETURN VARCHAR2
AS
v_name VARCHAR2 (10);
v_job VARCHAR2 (10);

BEGIN
SELECT ename, job
INTO v_name, v_job
FROM employee
WHERE empno = p_empnum;
RETURN ( 'Employee info :: '
|| 'Employee Number: '
|| p_empnum
|| ' Employee Name: '
|| v_name
|| ' Employee Job: '
|| v_job
);
END;

1) Create a new OA page:


====================
Right click on project (xxcus) –> New –> Web Tier –> OA Components –> select ‘Page’ item. Click OK. (This will
open a popup window)
Specify the details of page as below:
Name: XxPlSqlFuncDemoPG
Package: xxcus.oracle.apps.fnd.plsqlfuncdemo.webui

2) Create a new view object for employee number LOV (VO):


====================
Right click (plsqlfuncdemo) –> New View Object (This will open a wizard having 7 steps).

Step 1
Package: xxcus.oracle.apps.fnd.plsqlfuncdemo.lov.server
Name: XxEmpNumLovVO
Choose the radio button ‘Read-only Access’ (as there is no DML operation). Click Next.

Step 2
Enter the below query in ‘Query Statement’:
select empno from employee

As there is no need to generate VOImpl/VORowImpl, keep defaults for step3, 4, 5, 6 & 7 and click Finish. Save All.

3) Create a new Application Module (AM):


====================
Step 1
Package: xxcus.oracle.apps.fnd.plsqlfuncdemo.server
Name: XxPlSqlFuncDemoAM. Click Next.

010
www.AppsLead.com
Step 2
Here we will add an instance of the VO created in (2).
Select XxEmpNumLovVO from ‘Available View Objects’ and shuttle it to ‘Data Model’ using “>” button.

Keep defaults for all other steps (3, 4). Click Finish.

5) Create a new controller:


====================

Right click on pageLayout region –> set new controller (This will open a popup window). Enter the below details:
Package Name: xxcus.oracle.apps.fnd.plsqlfuncdemo.webui
Class Name: XxPlSqlFuncDemoCO

Creating the Page Layout & Setting its Properties:


====================
Page will appear as below:

1) Create a new region under pageLayout of type defaultSingleColumn.


2) Create 2 items under defaultSingleColumn region (messageLovInput, submitButton).

Now change the properties for each field from property inspector as shown below:

pageLayout:
ID: pageLayoutRN
AM Definition: xcus.oracle.apps.fnd.plsqlfuncdemo.server.XxPlSqlFuncDemoAM
Window Title: PL/SQL Function Demo Page
Title: PL/SQL Function Demo

defaultSingleColumn:
ID: singleColRN
Text: Choose Employee Number:

messageLovInput (for Employee Number):


ID: empNumLov
Prompt: Employee Number

submitButton:
ID: goBtn, Prompt: Go

Creating LOV regions:


Expand empNumLov LOV, right click on region1 and create a new region using wizard.

Step 1
select ‘XxPlSqlFuncDemoAM’ from Application Module drop down and select 'XxEmpNumLovVO1' in available
view usages. Click Next.

Step 2
013
www.AppsLead.com
choose region style as ‘table’ from drop down. Click Next.

Step 3
Shuttle all the fields from available to selected attributes. Click Next.
Also modify the prompt to make it more user friendly (like Employee Number).

This will create an item 'Empno' under 'XxEmpNumLovVO1' table region.


Set search allowed property to TRUE for the item created.

lovMap1:
LOV region item: Empno
Return item: empNumLov
Criteria item: empNumLov

The declarative page structure in jDev will be similar to as shown below:

We will catch go button event in PFR method of controller and call the method (callPlSqlFunction) form AM
which will retrive information for the employee number selected.
If employee LOV is empty, throw an error message 'Please choose employee numer.'

012
www.AppsLead.com
1 public void processFormRequest(OAPageContext pageContext,
2 OAWebBean webBean) {
3 super.processFormRequest(pageContext, webBean);
4 OAApplicationModule am = null;
5 am = pageContext.getRootApplicationModule();
6 if (pageContext.getParameter("goBtn") != null) {
7 if (!("".equals(pageContext.getParameter("empNumLov").trim()))) {
8 String empNum = pageContext.getParameter("empNumLov");
9 Serializable[] param = { empNum };
10 String empInfo =
11 am.invokeMethod("callPlSqlFunction", param).toString();
12 throw new OAException(empInfo, OAException.INFORMATION);
13 } else {
14 throw new OAException("Please choose employee numer.",
15 OAException.ERROR);
16 }
17 }
18}

Below is code for callPlSqlFunction method in AM class:


public String callPlSqlFunction(String empNum) {
String empInfo = "";
String stmt = "BEGIN :1 := xx_get_emp_details(:2); end;";
CallableStatement cs =
getOADBTransaction().createCallableStatement(stmt, 1);
try {
cs.registerOutParameter(1, Types.VARCHAR);
cs.setString(2, empNum);
cs.execute();
empInfo = cs.getString(1);
cs.close();
} catch (Exception e) {
e.printStackTrace();
}
return empInfo;
}

Finally, information will be displayed as shown in below screenshot:

016
www.AppsLead.com
Execute parameterized PL SQL procedure from OAF page

Let us try to call PL/SQL package from OAF page. We will try to send two interger values to one PL/SQL procedure
which will do sum of that numbers and will return back sum of that numbers

1. Create a New OA Workspace and Empty OA Project

File> New > General> Workspace Configured for Oracle Applications

File Name -- ParameterizedProcProj

Project Name – ParameterizedProcDemo

Default Package -- prajkumar.oracle.apps.fnd.parameterizedprocdemo

2. Create Application Module AM

Right click on ParameterizedProcProj > New > ADF Business Components > Application Module

Name -- ParameterizedProcDemoAM

Package -- prajkumar.oracle.apps.fnd.parameterizedprocdemo.server

Check Application Module Class: ParameterizedProcDemoAMImpl Generate JavaFile(s)

3. Create a New Page

Right click on ParameterizedProcProj > New > Web Tier > OA Components > Page

Name -- ParameterizedProcDemoPG

Package -- prajkumar.oracle.apps.fnd.parameterizedprocdemo.webui

4. Select region1 and set the following properties:

ID -- PageLayoutRN

Region Style -- PageLayout

AM Definition --prajkumar.oracle.apps.fnd.parameterizedprocdemo.server.ParameterizedProcDemoAM

Window Title – Execute Paramterized Procedure Demo Page Window

Title – Execute Paramterized Procedure Demo Page Header

Auto Footer – True

5. Add a New Region MainRN

Select PageLayoutRN right click > New > Region

ID -- MainRN

Region Style – messageComponentLayout

017
www.AppsLead.com
6. Create messageTextInput Items

Create item1

Select MainRN > New > messageTextInput

Set following Properties for Text Item1

ID – item1

Item Style – messageTextInput

Data Type -- Number

Prompt – Text Item1

Maximum Length – 20

Length -- 20

Create item2

Select MainRN > New > messageTextInput

Set following Properties for Text Item1

ID – item2

Item Style – messageTextInput

Data Type -- Number

Prompt – Text Item2

Maximum Length – 20

Length -- 20

7. Create a Submit Button

Right Click on MainRN > New > messageLayout

Select newly created messageLayout right click > New > item

Set Following Properties for newly created item

ID – Sum

Item Style – submitButton

Attribute Set -- /oracle/apps/fnd/attributesets/Buttons/Go

Prompt – Sum

8. Run Your Page UI is ready --

014
www.AppsLead.com
9. Let us create a package and package body which we will call from OAF page

This Package takes three parameters all are number. First two are IN parameters and last is OUT as sum of first
two numbers

Package Spec

CREATE OR REPLACE PACKAGE APPS.test_package AUTHID CURRENT_USER


IS
PROCEDURE data_sum
( item1 IN NUMBER,
item2 IN NUMBER,
data_sum OUT NUMBER
);
END test_package;
/
SHOW ERRORS;
EXIT;

Package Body

CREATE OR REPLACE PACKAGE BODY APPS.test_package


IS

PROCEDURE data_sum
( item1 IN NUMBER,
item2 IN NUMBER,
data_sum OUT NUMBER
)
IS
BEGIN

019
www.AppsLead.com
data_sum := item1 + item2;
END data_sum;

END test_package;
/
SHOW ERRORS;
EXIT;

10. Add Following Code in your AMImpl Class (ParameterizedProcDemoAMImpl.java)

import oracle.apps.fnd.framework.server.OADBTransaction;
import oracle.apps.fnd.framework.server.OADBTransactionImpl;
import oracle.jdbc.OracleCallableStatement;
import java.sql.Types;
import oracle.apps.fnd.framework.OAException;
...

public String dataSumAction(String item1,String item2)


{ OADBTransaction oadbtransaction = (OADBTransaction)getTransaction();
OADBTransactionImpl oadbtransactionimpl = (OADBTransactionImpl)getTransaction();

String retValues;

StringBuffer str = new StringBuffer();


str.append( " BEGIN ");
str.append( " test_package.data_sum( ");
str.append( " item1 => :1, ");
str.append( " item2 => :2, ");
str.append( " data_sum => :3 ");
str.append( " ); ");
str.append( " END; ");

OracleCallableStatement oraclecallablestatement =
(OracleCallableStatement)oadbtransaction.createCallableStatement(str.toString(), 1);

try{
oraclecallablestatement.setInt(1, Integer.parseInt(item1) );
oraclecallablestatement.setInt(2, Integer.parseInt(item2) );

oraclecallablestatement.registerOutParameter(3, Types.VARCHAR);

oraclecallablestatement.execute();

retValues = oraclecallablestatement.getString(3);
}
catch(Exception e)
{
throw OAException.wrapperException(e);
}
return retValues;
}

013
www.AppsLead.com
11. Add Controller for Page ParameterizedProcDemoPG Select PageLayoutRN right click Set New Controller

Package Name -- prajkumar.oracle.apps.fnd.parameterizedprocdemo.webui

Class Name -- ParameterizedProcDemoCO

Add Following Code in Controller

import oracle.apps.fnd.framework.OAException;
import oracle.apps.fnd.framework.OAApplicationModule;
import java.io.Serializable;
...

public void processFormRequest(OAPageContext pageContext, OAWebBean webBean)


{
super.processFormRequest(pageContext, webBean);

OAApplicationModule am = pageContext.getApplicationModule(webBean);

if (pageContext.getParameter("Sum") != null)
{
Serializable[] parameters1 = { pageContext.getParameter("item1"),
pageContext.getParameter("item2"),
};

String retVals1 = (String)am.invokeMethod("dataSumAction", parameters1);

String message = "Sum: " + retVals1;


throw new OAException(message, OAException.INFORMATION);
}
}

12. Congratulation you have successfully finished. Run Your ParameterizedProcDemoPG page and Test Your
Work

011
www.AppsLead.com
011
www.AppsLead.com
Oracle D2K to OA Framework Transformation

What is the difference between Oracle D2K form and OA Framework?

It is a very innocent but important question for someone that desires to make transition from D2K to OA
Framework. I hope you have already read and implemented OA Framework Getting Started.

I will re-visit my own experience of implementing HelloWorld program in "OA Framework". When I implemented
HelloWorld a year ago, I had no clue as to what I was doing & why I was doing those steps. I merely copied the
steps from Oracle Tutorial without understanding them.

Hence in this blog, I will try to explain in simple manner the meaning of OA Framework HelloWorld Program and
compare the steps to D2K form [where possible]. To keep things simple, only basics will be discussed.

Following key Steps were needed for HelloWorld

Step 1

Create a new Workspace and a new Project as dictated by Oracle's tutorial. When defining project, you will
specify a default package, which in this case was oracle.apps.ak.hello

This means the following: -

 ak is the short name of the Application in Oracle

[means fnd_applications.short_name]

 hello is the name of your project

Step 2

Next, you will create a OA Page within hello project

Think OA Page as the fmx file itself in D2K. I am saying so because this page gets attached to the form function.

 This page will be created within hello project, hence the package nameoracle.apps.ak.hello.webui
 Note the webui, it is a convention to have page in webui, means this page represents the Web User
Interface
 You will assign the default AM [OAApplicationModule]. Think of AM "Connection Manager" and
"Transaction State Manager" for your page

I can't co-relate this to anything in D2k, as there is no concept of Connection Pooling and that D2k is not
stateless. Reason being that as soon as you kick off a D2K Form, it connects to a single session of Oracle and
sticks to that single Oracle database session. So is not the case in OAF, hence AM is needed.

Step 3

You create Region within the Page.

Region is what will store your fields. Text input fields will be of type messageTextInput. Think of Canvas in
D2K. You can have nested regions. Stacked Canvas in D2K comes the closest to this component of OA Framework

Step 4

Add a button to one of the nested regions

010
www.AppsLead.com
 The itemStyle should be submitButton, in case you want the page to be submitted when this button is
clicked
 There is no WHEN-BUTTON-PRESSED trigger in OAF. In Framework, you will add a controller java code to
handle events like Form Submit button clicks. JDeveloper generates the default code for you. Primarily two
functions [should I call methods] will be created processRequest [for UI Rendering Handling] and
processFormRequest

Think of processRequest as WHEN-NEW-FORM-INSTANCE, though processRequest is very restrictive.

Note

What is the difference between processRequest and processFormRequest?

These two methods are available in the Default Controller class that gets created.

processFormRequest

This method is commonly used to react/respond to the event that has taken place, for example click of a button.

Some examples are

if(oapagecontext.getParameter("Cancel") != null) (Do your processing for Cancellation/ Rollback)

if(oapagecontext.getParameter("Submit") != null) (Do your validations and commit here)

if(oapagecontext.getParameter("Update") != null) (Do your validations and commit here)

In the above three examples, you could be calling oapagecontext.forwardImmediately to re-direct the page
navigation to some other page if needed.

processRequest

In this method, usually page rendering related code is written. Effectively, each GUI component is a bean that
gets initialised during processRequest. Those who are familiar with D2K forms, something like pre-query may be
written in this method.

Step 5

In the controller to access the value in field "HelloName" the command is

String userContent = pageContext.getParameter("HelloName");

In D2k, we used :block.field.

In OAFramework, at submission of page, all the field values get passed into to OAPageContext object.

 Use getParameter to access the field value


 To set the value of the field, use

OAMessageTextInputBean field

HelloName = (OAMessageTextInputBean)webBean.findChildRecursive("HelloName");
fieldHelloName.setText(pageContext,"Setting the default value" );

Note when setting field value in controller:

Note 1. Do not set the value in processFormRequest


Note 2. If the field comes from View Object, then do not use setText in controller
Note 3. For control fields [that are not based on View Objects], you can use setText to assign values in
processRequest method

Lets take some notes to expand beyond the HelloWorld Project

013
www.AppsLead.com
Note 1

In D2K-forms we sort of created a Window, attached to Canvas, and then fields within that Canvas.

However in OA Framework, think of Page being fmx/Window, think of Region being a Canvas, and fields being
within Regions.
This is not a formal/accurate understanding of analogy between D2k and Framework, but is close to being logical.

Note 2

In D2k, your Forms fmb file was compiled to fmx. It was fmx file that was deployed on mid-tier. In case of OAF,
your OA Page is nothing but a XML file. We call this MDS [meta data].

Whatever name you give to "Page" in OAF, an XML file of the same name gets created. This xml file must then be
loaded into database by using XML Importer command.

Note 3

Apart from MDS XML file, almost everything else is merely deployed to your mid-tier. Usually this is underneath
$JAVA_TOP/oracle/apps/../..
All java files will go underneath java top/oracle/apps/../.. etc.

Note 4

When building tutorial, ignore the steps for setting "Attribute Sets". These are not mandatory. Oracle might just
have developed their tutorials without including these. Think of these like Visual Attributes of D2K forms

Note 5

Controller is where you will write any java code in OA Framework. You can create a Controller per Page or have a
different Controller for each of the Regions with the same Page.

Note 6

In the method processFormRequest of the Controller, you can access the values of the page by using notation
pageContext.getParameter("<fieldname here>").

This method processFormRequest is executed when the OAF Screen/Page is submitted by click of a button.

Note 7

Inside the controller, all the Database Related interactions for example interaction with View Objects happen via
Application Module.

But why so? Because Application Module Manages the transaction state of the Application.

OAApplicationModuleImpl oaapplicationmoduleimpl =

OAApplicationModuleImpl)oapagecontext.getApplicationModule(oawebbean);

OADBTransaction oadbtransaction =

OADBTransaction)oaapplicationmoduleimpl.getDBTransaction();

Note 8

In D2K, we have control block or a block based on database view. Similarly, in OA Framework, if the field does not
have view Object attached, then it is like a control field. Hence in HelloWorld example, field HelloName is a
control field [in D2K terminology]. A view Object can either be based on a view/table, synonym or on a SQL

012
www.AppsLead.com
statement.

Note 9

I wish to access the fields in multi record block that is based on view Object. Can I do this in Controller?
Sure you can. To traverse through those records, do the below

Get the reference to the View Object using


(OAViewObject)oapagecontext.getApplicationModule(oawebbean).findViewObject("VO Name Here")

Loop through the records in View Objects using count returned from oaviewobject.getFetchedRowCount()

For each record, fetch the value of the fields within the loop as

oracle.jbo.Row row = oaviewobject.getRowAtRangeIndex(loop index here);

(String)row.getAttribute("Column name of VO here ");

Call D2K Form from OAF Page

This blog is about to call D2K form from OAF page. We will try to implement a OAF page to Call Application
Developer > Profile Form by clicking Go Button

1. Create a New OA Workspace and Empty OA Project

File> New > General> Workspace Configured for Oracle Applications

File Name -- CallformfromOAF

Project Name – Calld2kformfromOAF

Default Package -- prajkumar.oracle.apps.fnd.Calld2kformfromOAF

2. Set Run Options in OA Project Setting

Select Your Project in the Navigator and choose Project Properties

Select Oracle Applications > Run Options

Select OADeveloperMode and OADiagnostic, and move them to selected Options List

3. Create Application Module AM

Calld2kformfromOAF right click > New > ADF Business Components > Application Module

Name -- Calld2kformfromOAFAM

Package -- prajkumar.oracle.apps.fnd.Calld2kformfromOAF.server

Check Generate JavaFile(s)

4. Create a OA components Page

Calld2kformfromOAF right click > New > OA Components > Page

016
www.AppsLead.com
Name -- Calld2kformfromOAFPG

Package -- prajkumar.oracle.apps.fnd.Calld2kformfromOAF.webui

5. Modify the Page Layout (Top-level) Region

Attribute Property

ID PageLayoutRN

Region Style pageLayout

Form Property True

Auto Footer True

Window Title Call D2K from OAF Page Window Title

Title Call D2K from OAF Page Header

AM Definition prajkumar.oracle.apps.fnd.Calld2kformfromOAF.server.
Calld2kformfromOAFAM

6. Create the Second Region (Main Content Region)

Select PageLayoutRN right click > New > Region

Attribute Property

ID MainRN

Region Style messageComponentLayout

7. Create a container Region for Go-Button

Select MainRN right click > New > messageLayout

Attribute Property

Region ButtonLayout

8. Create a Second Item (Go Button)

Select ButtonLayout > New > Item

017
www.AppsLead.com
Attribute Property

ID Go

Item Style submitButton

Attribute Set /oracle/apps/fnd/attributesets/Buttons/Go

9. Add a Controller

Select MainRN right click > Set New Controller

Package Name -- prajkumar.oracle.apps.fnd.Calld2kformfromOAF.webui

Class Name -- Calld2kformfromOAFCO

10. Edit Your Controller

Add Following Code in processFormRequest

public void processFormRequest(OAPageContext pageContext, OAWebBean webBean)


{
super.processFormRequest(pageContext, webBean);

if (pageContext.getParameter("Go") != null)
{
//form:APPLICATION_SHORT_NAME:RESPONSIBILITY_KEY:DATA_GROUP_NAME
//:FORM_FUNCTION_NAME

String destination =
"form:FND:APPLICATION_DEVELOPER:STANDARD:FND_FNDPOMPO";

pageContext.forwardImmediatelyToForm(destination);
}
}

11. Congratulation you have successfully finished. Run Your page and Test Your Work

014
www.AppsLead.com
C

019
www.AppsLead.com
Call OAF Page from D2K form

This blog is about to call OAF page from D2K form. We will take one D2K form from there we will try to call our
OAF Page with parameters. In OAF page, there it will show that parameter values as message when it will open

Let us Create Our OAF Page

1. Create a New OA Workspace and Empty OA Project

File> New > General> Workspace Configured for Oracle Applications

File Name – CallOAFfromD2KForm

Project Name – CallOAFfromD2KProj

Default Package -- prajkumar.oracle.apps.fnd.CallOAFfromD2K

2. Create Application Module AM

CallOAFfromD2KProj right click > New > ADF Business Components > Application Module

Name -- CallOAFfromD2KAM

Package -- prajkumar.oracle.apps.fnd.CallOAFfromD2K.server

Check Generate JavaFile(s)

3. Create a OA components Page

CallOAFfromD2KProj right click > New > OA Components > Page

Name -- CallOAFfromD2KPG

Package -- prajkumar.oracle.apps.fnd.CallOAFfromD2K.webui

4. Modify the Page Layout (Top-level) Region

ID -- PageLayoutRN

Region Style – pageLayout

Form Property – True

Auto Footer -- True

Window Title – OAF Page Call From D2K Form Window Title

Title -- OAF Page Call From D2K Form Header

AM Definition -- prajkumar.oracle.apps.fnd.CallOAFfromD2K.server.CallOAFfromD2KAM

5. Consider following D2K form

003
www.AppsLead.com
This Form has First Name and Last Name. We will send First Name and Last Name values to our OAF page as
parameter

6. Add following Code in WHEN_BUTTON_PRESSED trigger of SUBMIT button

DECLARE
BEGIN
fnd_function.execute
( FUNCTION_NAME =>'CALL_OAF_FROM_D2K',
OPEN_FLAG =>'Y',
SESSION_FLAG =>'Y',
OTHER_PARAMS =>'FIRSTNAME=' || :CALLOAFFROMD2KBLOCK.FIRST_NAME || '&LASTNAME=' ||
:CALLOAFFROMD2KBLOCK.LAST_NAME
);
END;

Note – Here FUNCTION_NAME is OAF page function name

001
www.AppsLead.com
7. Add a Controller in OAF Page

Select PageLayoutRN right click > Set New Controller

Package Name -- prajkumar.oracle.apps.fnd.CallOAFfromD2K.webui

Class Name -- CallOAFfromD2KCO

8. Add following Code in Controller

import oracle.apps.fnd.framework.OAException;
...

public void processRequest(OAPageContext pageContext, OAWebBean webBean)


{ super.processFormRequest(pageContext, webBean);

String firstName = pageContext.getParameter("FIRSTNAME") ;


String lastName = pageContext.getParameter("LASTNAME") ;

String message = "Hello " + firstName + " " + lastName;

throw new OAException(message, OAException.INFORMATION);


}

001
www.AppsLead.com
9. Build Your Controller

10. Congratulation you have successfully finished. Run Form and Test Your Work

000
www.AppsLead.com
Get Host Name and URL of OAF Page

This blog is about to get Host name and URL of OAF page. We will try to implement one button which will give
host and URL of OAF page

1. Create a New OA Workspace and Empty OA Project

File> New > General> Workspace Configured for Oracle Applications

File Name -- HostandURL

Project Name – HostandURLProj

Default Package -- prajkumar.oracle.apps.fnd.hostandurl

2. Set Run Options in OA Project Setting

Select Your Project in the Navigator and choose Project Properties

Select Oracle Applications > Run Options

Select OADeveloperMode and OADiagnostic, and move them to selected Options List

3. Create Application Module AM

HostandURLProj right click > New > ADF Business Components > Application Module

Name -- HostandURLAM

Package -- prajkumar.oracle.apps.fnd.hostandurl.server

Check Generate JavaFile(s)

4. Create a OA components Page

HostandURLProj right click > New > OA Components > Page

Name -- HostandURLPG

Package -- prajkumar.oracle.apps.fnd.hostandurl.webui

5. Modify the Page Layout (Top-level) Region

Attribute Property

ID PageLayoutRN

Region Style pageLayout

Form Property True

003
www.AppsLead.com
Auto Footer True

Window Title Get Host and URL Window Title

Title Get Host and URL Page Header

AM Definition prajkumar.oracle.apps.fnd.hostandurl.server.HostandURLAM

6. Create the Second Region (Main Content Region)

Select PageLayoutRN right click > New > Region

Attribute Property

ID MainRN

Region Style messageComponentLayout

7. Create a container Region for Go-Button

Select MainRN right click > New > messageLayout

Attribute Property

Region ButtonLayout

8. Create a Item (Go Button)

Select ButtonLayout > New > Item

Attribute Property

ID Go

Item Style submitButton

Attribute Set /oracle/apps/fnd/attributesets/Buttons/Go

9. Add a Controller

Select MainRN right click > Set New Controller

Package Name -- prajkumar.oracle.apps.fnd.hostandurl.webui

002
www.AppsLead.com
Class Name -- HostandURLCO

10. Edit Your Controller

Add Following Code in processFormRequest

import java.net.*;
import java.io.*;
import oracle.apps.fnd.framework.OAException;
import oracle.apps.fnd.framework.webui.OAPageContext;

public void processFormRequest(OAPageContext pageContext, OAWebBean webBean)


{
super.processFormRequest(pageContext, webBean);
if (pageContext.getParameter("Go") != null)
{
// To get Host Name
try
{
InetAddress addr = InetAddress.getLocalHost();
byte[ ] ipAddr = addr.getAddress();
String hostname = "Host Name: " +addr.getHostName();
pageContext.putDialogMessage(new OAException(hostname,
OAException.WARNING));
}
catch (UnknownHostException e)
{
}
// To Get Page URL

String pageURL = "Current Page URL: " + pageContext.getCurrentUrl ();

pageContext.putDialogMessage(new OAException(pageURL,
OAException.WARNING));
}
}

11. Congratulation you have successfully finished. Run Your page and Test Your Work

006
www.AppsLead.com
Category: O

007
www.AppsLead.com
OAF Page to Upload Files into Server from local Machine

1. Create a New Workspace and Project

File > New > General > Workspace Configured for Oracle Applications

File Name – PrajkumarFileUploadDemo

Automatically a new OA Project will also be created

Project Name -- FileUploadDemo

Default Package -- prajkumar.oracle.apps.fnd.fileuploaddemo

2. Create a New Application Module (AM)

Right Click on FileUploadDemo > New > ADF Business Components > Application Module

Name -- FileUploadAM

Package -- prajkumar.oracle.apps.fnd.fileuploaddemo.server

Check Application Module Class: FileUploadAMImpl Generate JavaFile(s)

3. Create a New Page

Right click on FileUploadDemo > New > Web Tier > OA Components > Page

Name -- FileUploadPG

Package -- prajkumar.oracle.apps.fnd.fileuploaddemo.webui

4. Select the FileUploadPG and go to the strcuture pane where a default region has been created

5. Select region1 and set the following properties --

Attribute Property

ID PageLayoutRN

AM Definition prajkumar.oracle.apps.fnd.fileuploaddemo.server.FileUploadAM

Window Title Uploading File into Server from Local Machine Demo Window

Title Uploading File into Server from Local Machine Demo

6. Create messageComponentLayout Region Under Page Layout Region

Right click PageLayoutRN > New > Region

004
www.AppsLead.com
Attribute Property

ID MainRN

Item Style messageComponentLayout

7. Create a New Item messageFileUpload Bean under MainRN

Right click on MainRN > New > messageFileUpload

Set Following Properties for New Item --

Attribute Property

ID MessageFileUpload

Item Style messageFileUpload

8. Create a New Item Submit Button Bean under MainRN

Right click on MainRN > New > messageLayout

Set Following Properties for messageLayout --

Attribute Property

ID ButtonLayout

Right Click on ButtonLayout > New > Item

Attribute Property

ID Submit

Item Style submitButton

Attribute Set /oracle/apps/fnd/attributesets/Buttons/Go

9. Create Controller for page FileUploadPG

Right Click on PageLayoutRN > Set New Controller

Package Name: prajkumar.oracle.apps.fnd.fileuploaddemo.webui

Class Name: FileUploadCO

009
www.AppsLead.com
Write Following Code in FileUploadCO processFormRequest

import oracle.cabo.ui.data.DataObject;
import java.io.FileOutputStream;
import java.io.InputStream;
import oracle.jbo.domain.BlobDomain;
import java.io.File;
import oracle.apps.fnd.framework.OAException;

public void processFormRequest(OAPageContext pageContext, OAWebBean webBean)


{ super.processFormRequest(pageContext, webBean);

if(pageContext.getParameter("Submit")!=null)
{
upLoadFile(pageContext,webBean);
}
}

CODE #1 -- If Page has not deployed at instance, testing at Local Machine, use following Code

public void upLoadFile(OAPageContext pageContext,OAWebBean webBean)


{ String filePath = "D:\\PRajkumar";
System.out.println("Default File Path---->"+filePath);

String fileUrl = null;


try
{
DataObject fileUploadData = pageContext.getNamedDataObject("MessageFileUpload");

//FileUploading is my MessageFileUpload Bean Id


if(fileUploadData!=null)
{
String uFileName = (String)fileUploadData.selectValue(null, "UPLOAD_FILE_NAME");
String contentType = (String) fileUploadData.selectValue(null, "UPLOAD_FILE_MIME_TYPE");
System.out.println("User File Name---->"+uFileName);

FileOutputStream output = null;


InputStream input = null;

BlobDomain uploadedByteStream = (BlobDomain)fileUploadData.selectValue(null, uFileName);


System.out.println("uploadedByteStream---->"+uploadedByteStream);

File file = new File("D:\\PRajkumar", uFileName);


System.out.println("File output---->"+file);

output = new FileOutputStream(file);

System.out.println("output----->"+output);
input = uploadedByteStream.getInputStream();

System.out.println("input---->"+input);
byte abyte0[] = new byte[0x19000];
int i;

033
www.AppsLead.com
while((i = input.read(abyte0)) > 0)
output.write(abyte0, 0, i);

output.close();
input.close();
}
}
catch(Exception ex)
{
throw new OAException(ex.getMessage(), OAException.ERROR);
}
}

CODE #2 -- If Page has been Deployed at Instance, Use Following Code

public void upLoadFile(OAPageContext pageContext,OAWebBean webBean)


{ String filePath = "/u01/app/apnac03r12/PRajkumar/";
System.out.println("Default File Path---->"+filePath);

String fileUrl = null;


try
{
DataObject fileUploadData = pageContext.getNamedDataObject("MessageFileUpload");

//FileUploading is my MessageFileUpload Bean Id


if(fileUploadData!=null)
{
String uFileName = (String)fileUploadData.selectValue(null, "UPLOAD_FILE_NAME");
String contentType = (String) fileUploadData.selectValue(null, "UPLOAD_FILE_MIME_TYPE");
System.out.println("User File Name---->"+uFileName);

FileOutputStream output = null;


InputStream input = null;

BlobDomain uploadedByteStream = (BlobDomain)fileUploadData.selectValue(null, uFileName);


System.out.println("uploadedByteStream---->"+uploadedByteStream);

File file = new File("/u01/app/apnac03r12/PRajkumar", uFileName);


System.out.println("File output---->"+file);

output = new FileOutputStream(file);

System.out.println("output----->"+output);
input = uploadedByteStream.getInputStream();

System.out.println("input---->"+input);
byte abyte0[] = new byte[0x19000];
int i;

while((i = input.read(abyte0)) > 0)


output.write(abyte0, 0, i);

output.close();
input.close();

031
www.AppsLead.com
}
}
catch(Exception ex)
{
throw new OAException(ex.getMessage(), OAException.ERROR);
}
}

10. Congratulation you have successfully finished. Run Your page and Test Your Work

Page has deployed and Used CODE #2

Before Upload the File

031
www.AppsLead.com
After Upload the File

Page has not been deployed and Used CODE #1

Before Upload the File

030
www.AppsLead.com
After Upload the File

033
www.AppsLead.com
Import Data from Excel sheet to DB Table through OAF page

1. Create a New Workspace and Project

File > New > General > Workspace Configured for Oracle Applications

File Name – PrajkumarImportxlsDemo

Automatically a new OA Project will also be created

Project Name -- ImportxlsDemo

Default Package -- prajkumar.oracle.apps.fnd.importxlsdemo

2. Add JAR file jxl-2.6.3.jar to Apache Library

Download jxl-2.6.3.jar from following link –

http://www.findjar.com/jar/net.sourceforge.jexcelapi/jars/jxl-2.6.jar.html

Steps to add jxl.jar file in Local Machine

Right Click on ImportxlsDemo > Project Properties > Libraries > Add jar/Directory and browse to directory
where jxl-2.6.3.jar has been downloaded and select the JAR file

032
www.AppsLead.com
036
www.AppsLead.com
037
www.AppsLead.com
Click here to know Steps to Add JAR file into R12 server in OA

3. Create a New Application Module (AM)

Right Click on ImportxlsDemo > New > ADF Business Components > Application Module

Name -- ImportxlsAM

Package -- prajkumar.oracle.apps.fnd.importxlsdemo.server

Check Application Module Class: ImportxlsAMImpl Generate JavaFile(s)

4. Create Test Table in which we will insert data from excel

CREATE TABLE xx_import_excel_data_demo


( -- --------------------
-- Data Columns
-- --------------------
column1 VARCHAR2(100),
column2 VARCHAR2(100),
034
www.AppsLead.com
column3 VARCHAR2(100),
column4 VARCHAR2(100),
column5 VARCHAR2(100),
-- --------------------
-- Who Columns
-- --------------------
last_update_date DATE NOT NULL,
last_updated_by NUMBER NOT NULL,
creation_date DATE NOT NULL,
created_by NUMBER NOT NULL,
last_update_login NUMBER
);

5. Create a New Entity Object (EO)

Right click on ImportxlsDemo > New > ADF Business Components > Entity Object

Name – ImportxlsEO

Package -- prajkumar.oracle.apps.fnd.importxlsdemo.schema.server

Database Objects -- XX_IMPORT_EXCEL_DATA_DEMO

Note – By default ROWID will be the primary key if we will not make any column to be primary key

Check the Accessors, Create Method, Validation Method and Remove Method

6. Create a New View Object (VO)

Right click on ImportxlsDemo > New > ADF Business Components > View Object

Name -- ImportxlsVO

Package -- prajkumar.oracle.apps.fnd.importxlsdemo.server

In Step2 in Entity Page select ImportxlsEO and shuttle it to selected list

In Step3 in Attributes Window select all columns and shuttle them to selected list

In Java page Uncheck Generate Java file for View Object Class: ImportxlsVOImpl

Select Generate Java File for View Row Class: ImportxlsVORowImpl -> Generate Java File -> Accessors

7. Add Your View Object to Root UI Application Module

Right click on ImportxlsAM > Edit ImportxlsAM > Data Model >

Select ImportxlsVO and shuttle to Data Model list

039
www.AppsLead.com
8. Create a New Page

Right click on ImportxlsDemo > New > Web Tier > OA Components > Page

Name -- ImportxlsPG

Package -- prajkumar.oracle.apps.fnd.importxlsdemo.webui

9. Select the ImportxlsPG and go to the strcuture pane where a default region has been created

10. Select region1 and set the following properties:

Attribute Property

ID PageLayoutRN

AM Definition prajkumar.oracle.apps.fnd.importxlsdemo.server.ImportxlsAM

Window Title Import Data From Excel through OAF Page Demo Window

Title Import Data From Excel through OAF Page Demo

11. Create messageComponentLayout Region Under Page Layout Region

Right click PageLayoutRN > New > Region

Attribute Property

ID MainRN

Item Style messageComponentLayout

12. Create a New Item messageFileUpload Bean under MainRN

Right click on MainRN > New > messageFileUpload

Set Following Properties for New Item --

Attribute Property

ID MessageFileUpload

Item Style messageFileUpload

023
www.AppsLead.com
13. Create a New Item Submit Button Bean under MainRN

Right click on MainRN > New > messageLayout

Set Following Properties for messageLayout --

Attribute Property

ID ButtonLayout

Right Click on ButtonLayout > New > Item

Attribute Property

ID Go

Item Style submitButton

Attribute Set /oracle/apps/fnd/attributesets/Buttons/Go

14. Create Controller for page ImportxlsPG

Right Click on PageLayoutRN > Set New Controller

Package Name: prajkumar.oracle.apps.fnd.importxlsdemo.webui

Class Name: ImportxlsCO

Write Following Code in ImportxlsCO in processFormRequest

import oracle.apps.fnd.framework.OAApplicationModule;
import oracle.apps.fnd.framework.OAException;
import java.io.Serializable;
import oracle.apps.fnd.framework.webui.OAControllerImpl;
import oracle.apps.fnd.framework.webui.OAPageContext;
import oracle.apps.fnd.framework.webui.beans.OAWebBean;
import oracle.cabo.ui.data.DataObject;
import oracle.jbo.domain.BlobDomain;

public void processFormRequest(OAPageContext pageContext, OAWebBean webBean)


{
super.processFormRequest(pageContext, webBean);

if (pageContext.getParameter("Go") != null)
{
DataObject fileUploadData = (DataObject)pageContext.getNamedDataObject("MessageFileUpload");
String fileName = null;

021
www.AppsLead.com
try
{
fileName = (String)fileUploadData.selectValue(null, "UPLOAD_FILE_NAME");
}
catch(NullPointerException ex)
{
throw new OAException("Please Select a File to Upload", OAException.ERROR);
}

BlobDomain uploadedByteStream = (BlobDomain)fileUploadData.selectValue(null, fileName);


try
{
OAApplicationModule oaapplicationmodule = pageContext.getRootApplicationModule();
Serializable aserializable2[] = {uploadedByteStream};
Class aclass2[] = {BlobDomain.class };
oaapplicationmodule.invokeMethod("ReadExcel", aserializable2,aclass2);
}
catch (Exception ex)
{
throw new OAException(ex.toString(), OAException.ERROR);
}
}
}

Write Following Code in ImportxlsAMImpl.java

import java.io.IOException;
import java.io.InputStream;
import jxl.Cell;
import jxl.CellType;
import jxl.Sheet;
import jxl.Workbook;
import jxl.read.biff.BiffException;
import oracle.apps.fnd.framework.server.OAApplicationModuleImpl;
import oracle.jbo.Row;
import oracle.apps.fnd.framework.OAViewObject;
import oracle.apps.fnd.framework.server.OAViewObjectImpl;
import oracle.jbo.domain.BlobDomain;

public void createRecord(String[] excel_data)


{
OAViewObject vo = (OAViewObject)getImportxlsVO1();

if (!vo.isPreparedForExecution())
{
vo.executeQuery();
}

Row row = vo.createRow();


try
021
www.AppsLead.com
{
for (int i=0; i < excel_data.length; i++)
{
row.setAttribute("Column" +(i+1) ,excel_data[i]);
}
}
catch(Exception e)
{
System.out.println(e.getMessage());
}

vo.insertRow(row);
getTransaction().commit();
}

public void ReadExcel(BlobDomain fileData) throws IOException


{
String[] excel_data = new String[5];
InputStream inputWorkbook = fileData.getInputStream();
Workbook w;

try
{
w = Workbook.getWorkbook(inputWorkbook);

// Get the first sheet


Sheet sheet = w.getSheet(0);

for (int i = 0; i < sheet.getRows(); i++)


{
for (int j = 0; j < sheet.getColumns(); j++)
{
Cell cell = sheet.getCell(j, i);
CellType type = cell.getType();
if (cell.getType() == CellType.LABEL)
{
System.out.println("I got a label " + cell.getContents());
excel_data[j] = cell.getContents();
}

else if (cell.getType() == CellType.NUMBER)


{
System.out.println("I got a number " + cell.getContents());
excel_data[j] = cell.getContents();
}

else
{
excel_data[j] = "";
}

020
www.AppsLead.com
}
createRecord(excel_data);
}
}

catch (BiffException e)
{
e.printStackTrace();
}
}

15. Congratulation you have successfully finished. Run Your page and Test Your Work

Consider Excel PRAJ_TEST.xls with following data --

Lets Try to import this data into DB Table --

023
www.AppsLead.com
022
www.AppsLead.com
Improving Performance of a HGrid

Most of the pages in OAF which contain HGrid face performance issue. This is mainly because the view link query
gets executed multiple times recursively. So depending on the complexity of the view link query, the
performance of the page gets deteriorated. Hence this post is intended to provide some tips learnt to improve
the performance of a HGrid. Request the viewers to add their experiences as well.

1. Use GTT : Depending on the complexity on the query, u may use Global Temperory Table(s) to populate the
entire hierarchical data so that the base tables will not be touched every time the query is re-executed.

2. setChildPresentVOAttr : Normally, when a hgrid is rendered, it has to show a + symbol (expand icon) infront of
every node which has children. To do this, the detail VO query has to be re-executed in order to check whether a
particular node has children or not. This reduces the performance. Inorder to skip this, we can directly include an
additional attribute in the Master VO which returns ‘Y’ if that node has children and ‘N’ if it has no children. Then
we can programmatically set this view attribute on childNode of HGrid so that detail query need not be executed
again and again to check the existence of child nodes..

sample code :

OATreeChildBean childBean = (OATreeChildBean)webBean.findChildRecursive(“childNode1″);


childBean.setChildPresentVOAttr(“HasChildren”); //HasChildren is the Master VO attribute which returns ‘Y’ or
‘N’

026
www.AppsLead.com
How to display HTML in content (OAF)

Problem 1 : Some data in database has multiple spaces between words. But when that is rendered on page using
message styled text, the multiple spaces between the words are trimmed to single space by default. But you
want the number of spaces to be retained as it is.

Problem 2 : You have a varchar data which has some delimiter in between. When displaying it in page, you want
the data to appear in multiple lines based on delimiter. ex: abc-deft-lmnop should come in 3 lines : abc in one
line,deft in one line and lmnop in one line.

Solution : Use OARawTextBean (item style : rawText). rawText bean renders the data as html code. hence your
data can containg html tags in between to server your purpose.

Solution 1 : when fetching the data from database, fetch it as : select replace(column_name,’ ‘,’&nbsp;’) from
dual
If you have multiple lines in database, fetch it as : select replace(column_name,CHR(13),’</br>’) from dual

Solution 2 : when fetching the data from database, fetch it as : select replace(column_name,’-',’</br>’) from dual

027
www.AppsLead.com
EO based VO Extension in OAF

In the exercise we have taken “OAF Search Page“can be found @

https://blogs.oracle.com/prajkumar/entry/create_oaf_search_page

We are going to extend SearchVO of SearchPG page. Our business requirement is to addCreation Date attribute
in the results table region

1. Analyze the Page

Click on “About this Page” link to check that which ViewObject is associated with the table region [ResultsRN]

024
www.AppsLead.com
Here we can see that results table has SearchVO attached to it. Now click on Business Component Reference
details and check the path of SearchVO

Now click on SearchVO which is an EO based [SearchEO] to check whether it has Creation Date attribute or not
which we want to add

Here we can see that our VO does not have CreationDate attribute.
029
www.AppsLead.com
So for adding this attribute we need to perform VO Extension.

FTP this project from application server and open in JDeveloper

2. Create a New View Object (VO)

Right click on SearchDemo > New > ADF Business Components > View Object

Package -- prajkumar.oracle.apps.fnd.searchdemo.server

Name – ExtSearchVO

Extends -- prajkumar.oracle.apps.fnd.searchdemo.server.SearchVO

The next screen allows the addition or deletion of Entity Objects. No change is required here for this extension so
simply select Next

063
www.AppsLead.com
The next pane allows additional attributes to be added or attributes to be removed. In this case
add CreationDate attributes to the selected list

Note -- Please note the new attribute you would be adding will be coming as Transient

Click on Next -> Next

061
www.AppsLead.com
Modify above SQL statement with below SQL to add new attribute CREATION_DATE

SELECT SearchEO.COLUMN1,
SearchEO.COLUMN2,
SearchEO.ROWID,
SearchEO.CREATION_DATE
FROM XX_SEARCH_DEMO SearchEO

Click on Next -> Next

Generate ExtSearchVORowImpl

061
www.AppsLead.com
Click Finish

Note -- Now as our attribute created as Transient hence to fix this issue we have two options:

1. We need to correct our XML file generated as it is a known error with Jdeveloper

2. Double click on that attribute i.e CreationDate and in the View Object Attribute window, enter attribute name
in 'Expression' column i.e. CreationDate

Lets try first method --

Open your ExtSearchVO.xml file in some notepad editor.

Scroll to bottom of that file

Update

060
www.AppsLead.com
with

3. Substitute your New VO with parent VO

Right click on SearchDemo > Project Properties > Business Components > Substitutions

In Available list select SearchVO and in Substitute list select New VO ExtSearchVO and click on Add and then Ok

063
www.AppsLead.com
4. After substitution import *.jpx

In our case it will modify SearchDemo.jpx at project location i.e. --D:\xxxx\jdevhome\jdev\myclasses

Open Command Prompt and go to following location of your project

D:\xxxx\jdevbin\oaext\bin

Use this Import Command to import jpx

5. Personalize the page to create new item

On SearchPG click on Personalize Page link

Select Complete View Radio Button

062
www.AppsLead.com
Click on Create Item on Table: (ResultTable)

Set item style as messageStyledText

066
www.AppsLead.com
Set Following Properties

Id – CreationDateId

Data Type -- Date

Prompt – Creation Date

View Instance – ExtSearchVO1

View Attribute – CreationDate

067
www.AppsLead.com
Click Apply > Return to Application

6. Congratulation you have successfully finished. Run Your SearchPG page and Test Your Work

Note -- You can notice page has new Column with name Creation Date

064
www.AppsLead.com
C

069
www.AppsLead.com
Hiding an item conditionally through SPEL in OAF ( VO Extension + Personalization )

https://blogs.oracle.com/manojmadhusoodanan/tags/personalization_thru_spel

Entity Object Extension in Oracle Application R12

https://blogs.oracle.com/manojmadhusoodanan/tags/eo_extension

073
www.AppsLead.com
OAF and Oracle Workflow
Most of the custom development work I have done on OAF has required me to interact with Oracle Workflow,
specifically to handle approvals and interfaces. The class oracle.apps.fnd.framework.webui.OANavigation
provides Java wrappers for Oracle Workflow Engine's PL/SQL APIs.

The class is actually intended for use when creating and managing OA Framework Page Flows that are defined by
Oracle Workflow, but can also be used to interface with Oracle eBS Workflows.

Example Code - Launching a custom Oracle eBS Workflow from a OAF page:

import oracle.apps.fnd.framework.webui.OANavigation;
import java.math.BigDecimal;

public void launchCustomWorkFlow(OAPageContext pageContext)


{
String wfItemType = "CUSTOM";
String wfProcess = "CUSTOM_PROCESS";
String wfItemKey = "1001-1";

OANavigation wfClass = new OANavigation();

// Create Workflow Process


wfClass.createProcess(pageContext, wfItemType, wfProcess, wfItemKey);

// Set Number Attribute: ITEM_INTERFACE_ID


wfClass.setItemAttrNumber(
pageContext,
wfItemType,
wfItemKey,
"ITEM_INTERFACE_ID",
new BigDecimal(1));

// Set Text Attribute: ITEM_NAME


wfClass.setItemAttrText(pageContext, wfItemType, wfItemKey,
"ITEM_NAME", "ITEM1");

// Start Workflow Process


wfClass.startProcess(pageContext, wfItemType, wfProcess, wfItemKey);
}

071
www.AppsLead.com
Hide "Privacy Link" and "Copy right information" from dialog page!

Try the following,


Login with the user who has functional administrator and goto pesonalization tab,
query the document path,
/oracle/apps/fnd/framework/webui/OAFooter
press go, once you get the doc name /oracle/apps/fnd/framework/webui/OAFooter
click on Personalize Page icon,

Clear all other default values and uncheck the site check box,
and select OAFWK_DIALOG_PG in Function.
Then apply,

You will get personalization struction the /oracle/apps/fnd/framework/webui/OAFooter at Function


OAFWK_DIALOG_PG level,

Now change the rendered propertly to false for Privacy Link and Copy right.

Then check the dialog page.

071
www.AppsLead.com
SPEL in OAF

‘SPEL’ is used to ‘Get’ a property in an expression. Strings and Conditions can refer to
properties of objects using a SPEL syntax (Simplest Possible Expression Language).
For example, this enables to build a Condition that tests if a field is displayed or not. These
expressions take the following general format:

${objectType.objectName.Property}

Internally, the SPEL expression is a cover for Oracle Forms builtins like GET_ITEM_PROPERTY,
GET_BLOCK_PROPERTY, etc. Additionally, the SPEL expressions support retrieving
Profile values, Message Dictionary text, and Local Variables.

070
www.AppsLead.com
Entity Object Based on PL/SQL

https://blogs.oracle.com/manojmadhusoodanan/entry/entity_object_based_on_pl

Entity Object Extension in OAF

In the exercise we have taken “Create Data Entry OAF Page“can be found @

https://blogs.oracle.com/prajkumar/entry/insert_data_oaf_page

We are going to extend InsertEO. Our business requirement is to add Validation on Column1. The length of
entered data in Column1 should be more than 5 Characters.

1. FTP this project from application server and open in JDeveloper

2. Create a New Entity Object (EO)

Right click on InsertDemo > New > ADF Business Components > Entity Object

Name – ExtInsertEO

Package -- prajkumar.oracle.apps.fnd.insertdemo.schema.server

Extends -- prajkumar.oracle.apps.fnd.insertdemo.schema.server.InsertEO

073
www.AppsLead.com
Click on Next - > New from Table

072
www.AppsLead.com
Include all the attributes of parent EO

Next -> Next

Check Validation Method check box and Finish

076
www.AppsLead.com
3. Add following code in ExtInsertEOImpl.java

import oracle.apps.fnd.framework.OAException;

protected void validateEntity()


{
super.validateEntity();

String column1Value = getColumn1();

if (column1Value.length() < 5)
{
String message = "Length of String" + " " + column1Value + "is less than 5 characters";
throw new OAException(message, OAException.INFORMATION);
}
}

4. Substitute your New EO with parent EO

Right click on InsertDemo > Project Properties > Business Components > Substitutions

In Available list select InsertEO and in Substitute list select New EO ExtInsertEO and click on Add and then Ok

077
www.AppsLead.com
5. After substitution import *.jpx

In our case it will modify InsertDemo.jpx at project location

i.e. -- D:\xxxx\jdevhome\jdev\myclasses

Open Command Prompt and go to following location of your project

D:\xxxx\jdevbin\oaext\bin

Use this Import Command to import jpx

074
www.AppsLead.com
6. Bounce the server

7. Verify the substitution has applied properly

Run InsertPG page and click on About this Page link

079
www.AppsLead.com
Expand Business Component References Details

Under that section click on InsertVO which is EO based [it should be ExtInsertEO based]

043
www.AppsLead.com
8. Congratulation you have successfully finished. Run Your InsertPG page and Test Your Work

041
www.AppsLead.com
Catego

041
www.AppsLead.com
Application Module Extension in OAF

Like the Controller extension, AM extension is also not supported by Oracle. However for some business needs
we have to extend it sometimes.

In this exercise we have taken our “Data Entry OAF page” can be found
@https://blogs.oracle.com/prajkumar/entry/insert_data_oaf_page to extend application module i.e. InsertAM

This AM can be found under below BC4J packageprajkumar.oracle.apps.fnd.insertdemo.server.InsertAM

Why we are extending AM:-

This InsertAM contains an apply method which subsequently commits the transaction.

public void apply()


{
getTransaction().commit();
}

Our business need is to capture user name and user id at runtime and insert it into a custom audit table for audit
purpose

Here is Audit Table script --

CREATE TABLE xx_audit


( -- -------------------
-- Data Columns
-- --------------------
user_id VARCHAR(50),
user_name VARCHAR(50),
-- -------------------
-- Who Columns
-- -------------------
last_update_date DATE NOT NULL,
last_updated_by NUMBER NOT NULL,
creation_date DATE NOT NULL,
created_by NUMBER NOT NULL,
last_update_login NUMBER
);

Steps to Extend Application Module (AM)

1. Create a New Application Module (AM)

Right Click on InsertDemo > New > ADF Business Components > Application Module

Package -- prajkumar.oracle.apps.fnd.insertdemo.server

Name -- ExtendedAM

Extends -- prajkumar.oracle.apps.fnd.insertdemo.server.InsertAM

040
www.AppsLead.com
043
www.AppsLead.com
Write following code in ExtendedAMImpl.java

042
www.AppsLead.com
import oracle.apps.fnd.framework.OAException;
import java.sql.PreparedStatement;
import java.sql.Connection;

public class ExtendedAMImpl extends InsertAMImpl


{
....

public void apply()


{
java.sql.Date d = getOADBTransaction().getCurrentDBDate().dateValue();
try
{
Connection conn = getOADBTransaction().getJdbcConnection();
String Query = "insert into xx_audit values(:1,:2,:3,:4,:5,:6,:7)";
PreparedStatement stmt = conn.prepareStatement(Query);

stmt.setInt(1, getOADBTransaction().getUserId());
stmt.setString(2, getOADBTransaction().getUserName());
stmt.setDate(3, d);
stmt.setInt(4, getOADBTransaction().getUserId());
stmt.setDate(5, d);
stmt.setInt(6, getOADBTransaction().getUserId());
stmt.setInt(7, getOADBTransaction().getUserId());
stmt.execute();
}

catch(Exception exception)
{
throw new OAException("Error in Staffing Query"+exception, OAException.ERROR);
}
super.apply();
}
}

2. Perform AM Substitution

Double Click on InsertDemo.jpx

Business Components > Substitutions

046
www.AppsLead.com
047
www.AppsLead.com
3. After substitution it will modify *.jpx

In our case it will modify InsertDemo.jpx at project location

i.e. -- D:\xxxx\jdevhome\jdev\myclasses

4. Migrate/ Import the modified jpx

Open Command Prompt and go to following location of your projectD:\xxxx\jdevbin\oaext\bin

Use this Import Command to import jpx

044
www.AppsLead.com
5. Congratulation you have successfully finished. Run Your InsertPG page and Test Your Work

049
www.AppsLead.com
093
www.AppsLead.com
091
www.AppsLead.com
Controller Extension in OAF

Oracle does not recommend that customers extend controller objects associated with regions or webbeans in
shipped E-Business Suite product pages.

Controller class (oracle.apps.fnd.framework.webui.OAControllerImpl) methods should effectively be considered


private, since their implementation is subject to change. Controller extensions are therefore not considered to be
durable between upgrades.

If it is absolutely essential to handle custom form submit events on a shipped product page,
processFormRequest() is the only method that should be overriden in a controller class, although the risks
outlined above still apply.

Let us try to Extend Controller in OAF Page –

Create one search page as explained in below link –

https://blogs.oracle.com/prajkumar/entry/create_oaf_search_page

In this exercise I am going to extend CO of SearchPG. First lets create CO for SearchPG.

Right Click PageLayoutRN under SearchPG page > Set New Controller

Package Name -- prajkumar.oracle.apps.fnd.searchdemo.webui

Class Name -- SearchCO

Now we will extend this newly created CO under this exercise.

The purpose of this exercise is to modify the VO query of results table. I have changed
theColumn1 and Column2 fields Property Selective Search Criteria as False.

Now when we click on Go button all the records are displaying in the results table and our OBJECTIVE is to bind
the VO query of results table in such a way that in result Column1 valueval5 and Column2 value val6 should not
come as result on click Go button

091
www.AppsLead.com
Now for knowing which controller to extend we click on "About This Page" Link and select Expand All. Here we
can see the Name of the controller that we need to extend

090
www.AppsLead.com
1. Create a New Workspace and Project

File > New > General > Workspace Configured for Oracle Applications

File Name – PrajkumarCOExtensionDemo

Automatically a new OA Project will also be created

Project Name -- COExtensionDemo

Default Package -- prajkumar.oracle.apps.fnd.coextensiondemo

093
www.AppsLead.com
2. Create a New Java Class

Right Click on COExtensionDemo > New > General > Java Class

Name -- ExtendedCO

Package -- prajkumar.oracle.apps.fnd.coextensiondemo.server

Extends -- prajkumar.oracle.apps.fnd.searchdemo.webui.SearchCO

Note -- Give the Name of your Extended Class give its package path and in the extends property select base class

092
www.AppsLead.com
3. Write below logic in ExtendedCO Java Class

package prajkumar.oracle.apps.fnd.coextensiondemo.webui;

import prajkumar.oracle.apps.fnd.searchdemo.webui.SearchCO;

import oracle.apps.fnd.framework.webui.OAPageContext;
import oracle.apps.fnd.framework.webui.beans.OAWebBean;
import oracle.apps.fnd.framework.OAApplicationModule;
import oracle.apps.fnd.framework.webui.beans.layout.OAQueryBean;
import prajkumar.oracle.apps.fnd.searchdemo.server.SearchVOImpl;

public class XXItemSearchCO extends ItemSearchCO


{
public XXItemSearchCO()
{
}

public void processFormRequest(OAPageContext pageContext, OAWebBean webBean)


{
super.processFormRequest(pageContext, webBean);
OAApplicationModule am = pageContext.getApplicationModule(webBean);
OAQueryBean queryBean = (OAQueryBean)webBean.findChildRecursive("QueryRN");

//Capturing Go Button ID
String go = queryBean.getGoButtonName();

//If its Not NULL which mean user has pressed "Go" Button
if(pageContext.getParameter(go)!=null)
{
// Setting whereClause at Runtime to restrict the query

096
www.AppsLead.com
SearchVOImpl vo = (SearchVOImpl)am.findViewObject("SearchVO1");
vo.setWhereClause(null);
vo.setWhereClause("Column1 <>:1 AND Column2 <>:2");
vo.setWhereClauseParam(0,"val5");
vo.setWhereClauseParam(1,"val6");
}
}
}

4. Attach new controller to SearchPG through personalization

Click on Personalize Page link on top right hand side of your page

Note -- If you are not able to see this link then go through below link –

https://blogs.oracle.com/prajkumar/entry/how_to_enable_personalization_link

Click on Complete View -> Expand All -> Click on personalize icon next to Page Layout

097
www.AppsLead.com
Now at site level give the path of extended controller as we are extending the controller atSITE LEVEL

prajkumar.oracle.apps.fnd.coextensiondemo.webui.ExtendedCO

Click Apply -> Return to Application

094
www.AppsLead.com
5. Congratulation you have successfully finished. Run Your SearchPG page and Test Your Work

Click Go

Note – Record with Column1 value val5 and Column2 value val6 is not coming in result

099
www.AppsLead.com
Another way to Controller Extension in OAF

Here is a simple example to show personaliztion and controller extension.

I have extended the functionality of HelloWorldPG .


(oracle/apps/fnd/framework/toolbox/tutorial/webui/HelloWorldPG.xml)

Seeded functionality of this page is:


User will enter his name or any text and on press of 'Go' button, the page will show a message by append 'Hello, '
in front of the name entered. If user click on button without entering anything in text field, still page will show a
message 'hello, '.
Below is screenshot for the same:

Now we do these changes:


1) Using personalization, we will modify the prompt of text field (from 'name' to 'Enter Your Name: ').
2) Using controller extension, we will modify the message as : 'hello, ' + name + 'The message is from custom
controller.'. Also we put a validation that name filed should not be empty while clicking on 'Go' button.

Below are steps for the same:

1) Create a new java class extending from standard controller.


Right click on xxcus --> new --> java class.
Enter the details as shown below:

333
www.AppsLead.com
The package for custom controller must follow standard conventions as:
oracle.apps.fnd.framework.toolbox.tutorial.webui.HelloWorldMainCO
xxcus.oracle.apps.fnd.framework.toolbox.tutorial.webui.XxcusHelloWorldMainCO

2) Write the below code in custom controller:

1 package xxcus.oracle.apps.fnd.framework.toolbox.tutorial.webui;
2
3 import oracle.apps.fnd.framework.OAException;
4 import oracle.apps.fnd.framework.toolbox.tutorial.webui.HelloWorldMainCO;
5 import oracle.apps.fnd.framework.webui.OAPageContext;
6 import oracle.apps.fnd.framework.webui.beans.OAWebBean;
7
8 // here we are extending from HelloWorldMainCO
9 public class XxcusHelloWorldMainCO extends HelloWorldMainCO {
10
11 public void processFormRequest(OAPageContext pageContext,
12 OAWebBean webBean) {
13
14 if (pageContext.getParameter("Go") != null) {
15 String name = pageContext.getParameter("HelloName");
16 if (!("".equals(name.trim()))) {
17 String message =
18 "Hello, " + name + " This message is from custom controller.";
19 throw new OAException(message, OAException.INFORMATION);
20 }
21 } else {
22 throw new OAException("Please enter your name.",
23 OAException.ERROR);
24 }
25 }
26}

3) Compile and move to server:


Compile the file and move the class file to unix box at
$JAVA_TOP/xxcus/oracle/apps/fnd/framework/toolbox/tutorial/webui/

4) Attach this custom controller to your page:


Open HelloWorld page and click on 'Personalize Page' at the top right. This will show a page as below. Click on
personalize pencil against the 'Message Component Layout: (MainRN)':

331
www.AppsLead.com
Change the controller property as shown below and click on apply:

5) Change prompt of text field:


Click on personalize pencil against Message Text Input: Name.

Here change the prompt property to 'Enter Your Name: ' at site level as shown below and click on 'Apply':

331
www.AppsLead.com
Finally, click 'Return to Application' link and all is done. Enter your name and press 'Go' button. It will show our
custom message :

Also, the page will show error message if Go button is pressed when the field is empty:

330
www.AppsLead.com
333
www.AppsLead.com
Key Flex Fields, KFF in OAF

1. Create a New Workspace and Project

Right click Workspaces and click create New OA Workspace and name it as PRajkumarKFFDemo. Automatically a
new OA Project will also be created. Name the project as KFFDemo and package as
prajkumar.oracle.apps.fnd.kffdemo

2. Create a New Application Module (AM)

Right Click on KFFDemo > New > ADF Business Components > Application Module

Name -- KFFAM

Package -- prajkumar.oracle.apps.fnd.kffdemo.server

Check Application Module Class: KFFAMImpl Generate JavaFile(s)

3. Create a New View Object (VO)

Right click on KFFDemo > New > ADF Business Components > View Object

Name -- KFFVO

Package -- prajkumar.oracle.apps.fnd.kffdemo.server

Note - The VO is not based on any EO so click next and go to the query section and paste the query

SELECT code_combination_id
FROM gl_code_combinations_kfv

In Step8 Check Object Class: KFFVOImpl -> Generate Java File -> Bind Variable Accessors

4. Add View Object to Root UI Application Module

Right Click on KFFAM > Edit KFFAM > Data Model and shuttle KFFVO from Available View Objects to Data Model

5. Create a New Page

Right click on KFFDemo > New > Web Tier > OA Components > Page

Name -- KFFPG

Package -- prajkumar.oracle.apps.fnd.kffdemo.webui

6. Select the KFFPG and go to the strcuture pane where a default region has been created

332
www.AppsLead.com
7. Select region1 and set the following properties:

Attribute Property

ID PageLayoutRN

AM Definition prajkumar.oracle.apps.fnd.kffdemo.server.KFFAM

Window Title Key Flex Field Demo Window

Title Key Flex Field Demo

8. Create Stack Layout Region Under Page Layout Region

Right click PageLayoutRN > New > Region

Attribute Property

ID MainRN

AM Definition stackLayout

9. Create a New Item of type Flex under the Stack Layout Region

Right click on MainRN > New > Item

Set Following Properties for New Item --

Attribute Property

ID KeyFlexItem

Item Style Flex

Prompt Accounting Key Flex Field

Appl Short Name SQLGL

Name GL#

Type Key

336
www.AppsLead.com
View Instance KFFVO1

10. Create Controller for page KFFPG

Right Click on PageLayoutRN > Set New Controller

Package Name: prajkumar.oracle.apps.fnd.kffdemo.webui

Class Name: KFFCO

Write Following Code in KFFCO processRequest

public void processRequest(OAPageContext pageContext, OAWebBean webBean)


{
super.processRequest(pageContext, webBean);

OAKeyFlexBean kffId = (OAKeyFlexBean)webBean.findIndexedChildRecursive("KeyFlexItem");

// Set the code combination lov


kffId.useCodeCombinationLOV(true);

//set the structure code for the item key flex


kffId.setStructureCode("FED_AFF");

//Set the attribute name to the item


kffId.setCCIDAttributeName("CodeCombinationId");

//Execute the Query


KFFAMImpl am = (KFFAMImpl)pageContext.getApplicationModule(webBean);
KFFVOImpl vo = (KFFVOImpl)am.findViewObject("KFFVO1");

if(!vo.isPreparedForExecution())
{
vo.executeQuery();
}
}

Note -- If you do not want to see the key flex field is merging one then change the code in the controller class
as below

kffId.useCodeCombinationLOV(false);

11. Use the below Query to find the Structure Code

337
www.AppsLead.com
SELECT fif.application_id,
fif.id_flex_code,
fif.id_flex_name,
fif.application_table_name,
fif.description,
fifs.id_flex_num,
fifs.id_flex_structure_code,
fifse.segment_name,
fifse.segment_num,
fifse.flex_value_set_id
FROM fnd_id_flexs fif,
fnd_id_flex_structures fifs,
fnd_id_flex_segments fifse
WHERE fif.application_id = fifs.application_id
AND fif.id_flex_code = fifs.id_flex_code
AND fifse.application_id = fif.application_id
AND fifse.id_flex_code = fif.id_flex_code
AND fifse.id_flex_num = fifs.id_flex_num
AND fif.id_flex_code LIKE 'GL#'
AND fif.id_flex_name LIKE 'Accounting Flexfield';

12. Congratulation you have successfully finished. Run Your page and Test Your Work

334
www.AppsLead.com
339
www.AppsLead.com
Descriptive Flexfield Creation in OA Framework

1 CREATE TABLE xxDFFDemo_EmpDetails

2 (

3 Employee_ID NUMBER,

4 Employee_Name VARCHAR2(100),

5 Start_Date Date,

6 End_Date Date,

7 attribute_category VARCHAR2(100),

8 attribute1 VARCHAR2(100),

9 attribute2 VARCHAR2(100),

10 attribute3 VARCHAR2(100),

11 attribute4 VARCHAR2(100),

12 attribute5 VARCHAR2(100),

13 attribute6 VARCHAR2(100),

14 attribute7 VARCHAR2(100),

15 attribute8 VARCHAR2(100),

16 attribute9 VARCHAR2(100),

17 attribute10 VARCHAR2(100),

18 attribute11 VARCHAR2(100),

19 attribute12 VARCHAR2(100),

20 attribute13 VARCHAR2(100),

21 attribute14 VARCHAR2(100),

22 attribute15 VARCHAR2(100),

23 attribute16 VARCHAR2(100),

24 attribute17 VARCHAR2(100),

25 attribute18 VARCHAR2(100),

26 attribute19 VARCHAR2(100),

27 attribute20 VARCHAR2(100),

28 attribute21 VARCHAR2(100),

29 attribute22 VARCHAR2(100),

30 attribute23 VARCHAR2(100),

31 attribute24 VARCHAR2(100),

32 attribute25 VARCHAR2(100),

313
www.AppsLead.com
33 attribute26 VARCHAR2(100),

34 attribute27 VARCHAR2(100),

35 attribute28 VARCHAR2(100),

36 attribute29 VARCHAR2(100),

37 attribute30 VARCHAR2(100),

38 created_by NUMBER,

39 creation_date DATE,

40 last_updated_by NUMBER,

41 last_update_date DATE,

42 last_update_login NUMBER

43 );

44

45

46 Connect Apps/apps@vis

47

48

49 BEGIN

50 AD_DD.REGISTER_TABLE ('PO','xxDFFDemo_EmpDetails','T');

51 END;

52 /

53 BEGIN

54 AD_DD.REGISTER_COLUMN ('PO', 'xxDFFDemo_EmpDetails','Employee_ID', 1, 'NUMBER', 38, 'Y', 'N');

55 AD_DD.REGISTER_COLUMN ('PO', 'xxDFFDemo_EmpDetails','Employee_Name', 2, 'VARCHAR2', 100, 'Y', 'N');

56 AD_DD.REGISTER_COLUMN ('PO', 'xxDFFDemo_EmpDetails','Start_Date', 3, 'DATE', 9, 'Y', 'N');

57 AD_DD.REGISTER_COLUMN ('PO', 'xxDFFDemo_EmpDetails','End_Date', 4, 'DATE', 9, 'Y', 'N');

58 AD_DD.REGISTER_COLUMN ('PO', 'xxDFFDemo_EmpDetails','ATTRIBUTE_CATEGORY', 5, 'VARCHAR2', 100, 'Y', 'N');

59 -- DFF Columns

60 AD_DD.REGISTER_COLUMN ('PO', 'xxDFFDemo_EmpDetails','ATTRIBUTE1', 6, 'VARCHAR2', 100, 'Y', 'N');

61 AD_DD.REGISTER_COLUMN ('PO', 'xxDFFDemo_EmpDetails','ATTRIBUTE2', 7, 'VARCHAR2', 100, 'Y', 'N');

62 AD_DD.REGISTER_COLUMN ('PO', 'xxDFFDemo_EmpDetails','ATTRIBUTE3', 8, 'VARCHAR2', 100, 'Y', 'N');

63 AD_DD.REGISTER_COLUMN ('PO', 'xxDFFDemo_EmpDetails','ATTRIBUTE4', 9, 'VARCHAR2', 100, 'Y', 'N');

64 AD_DD.REGISTER_COLUMN ('PO', 'xxDFFDemo_EmpDetails','ATTRIBUTE5', 10, 'VARCHAR2', 100, 'Y', 'N');

65 AD_DD.REGISTER_COLUMN ('PO', 'xxDFFDemo_EmpDetails','ATTRIBUTE6', 11, 'VARCHAR2', 100, 'Y', 'N');

66 AD_DD.REGISTER_COLUMN ('PO', 'xxDFFDemo_EmpDetails','ATTRIBUTE7', 12, 'VARCHAR2', 100, 'Y', 'N');

311
www.AppsLead.com
67 AD_DD.REGISTER_COLUMN ('PO', 'xxDFFDemo_EmpDetails','ATTRIBUTE8', 13, 'VARCHAR2', 100, 'Y', 'N');

68 AD_DD.REGISTER_COLUMN ('PO', 'xxDFFDemo_EmpDetails','ATTRIBUTE9', 14, 'VARCHAR2', 100, 'Y', 'N');

69 AD_DD.REGISTER_COLUMN ('PO', 'xxDFFDemo_EmpDetails','ATTRIBUTE10', 15, 'VARCHAR2', 100, 'Y', 'N');

70 AD_DD.REGISTER_COLUMN ('PO', 'xxDFFDemo_EmpDetails','ATTRIBUTE11', 16, 'VARCHAR2', 100, 'Y', 'N');

71 AD_DD.REGISTER_COLUMN ('PO', 'xxDFFDemo_EmpDetails','ATTRIBUTE12', 17, 'VARCHAR2', 100, 'Y', 'N');

72 AD_DD.REGISTER_COLUMN ('PO', 'xxDFFDemo_EmpDetails','ATTRIBUTE13', 18, 'VARCHAR2', 100, 'Y', 'N');

73 AD_DD.REGISTER_COLUMN ('PO', 'xxDFFDemo_EmpDetails','ATTRIBUTE14', 19, 'VARCHAR2', 100, 'Y', 'N');

74 AD_DD.REGISTER_COLUMN ('PO', 'xxDFFDemo_EmpDetails','ATTRIBUTE15', 20, 'VARCHAR2', 100, 'Y', 'N');

75 AD_DD.REGISTER_COLUMN ('PO', 'xxDFFDemo_EmpDetails','ATTRIBUTE16', 21, 'VARCHAR2', 100, 'Y', 'N');

76 AD_DD.REGISTER_COLUMN ('PO', 'xxDFFDemo_EmpDetails','ATTRIBUTE17', 22, 'VARCHAR2', 100, 'Y', 'N');

77 AD_DD.REGISTER_COLUMN ('PO', 'xxDFFDemo_EmpDetails','ATTRIBUTE18', 23, 'VARCHAR2', 100, 'Y', 'N');

78 AD_DD.REGISTER_COLUMN ('PO', 'xxDFFDemo_EmpDetails','ATTRIBUTE19', 24, 'VARCHAR2', 100, 'Y', 'N');

79 AD_DD.REGISTER_COLUMN ('PO', 'xxDFFDemo_EmpDetails','ATTRIBUTE20', 25, 'VARCHAR2', 100, 'Y', 'N');

80 AD_DD.REGISTER_COLUMN ('PO', 'xxDFFDemo_EmpDetails','ATTRIBUTE21', 26, 'VARCHAR2', 100, 'Y', 'N');

81 AD_DD.REGISTER_COLUMN ('PO', 'xxDFFDemo_EmpDetails','ATTRIBUTE22', 27, 'VARCHAR2', 100, 'Y', 'N');

82 AD_DD.REGISTER_COLUMN ('PO', 'xxDFFDemo_EmpDetails','ATTRIBUTE23', 28, 'VARCHAR2', 100, 'Y', 'N');

83 AD_DD.REGISTER_COLUMN ('PO', 'xxDFFDemo_EmpDetails','ATTRIBUTE24', 29, 'VARCHAR2', 100, 'Y', 'N');

84 AD_DD.REGISTER_COLUMN ('PO', 'xxDFFDemo_EmpDetails','ATTRIBUTE25', 30, 'VARCHAR2', 100, 'Y', 'N');

85 AD_DD.REGISTER_COLUMN ('PO', 'xxDFFDemo_EmpDetails','ATTRIBUTE26', 31, 'VARCHAR2', 100, 'Y', 'N');

86 AD_DD.REGISTER_COLUMN ('PO', 'xxDFFDemo_EmpDetails','ATTRIBUTE27', 32, 'VARCHAR2', 100, 'Y', 'N');

87 AD_DD.REGISTER_COLUMN ('PO', 'xxDFFDemo_EmpDetails','ATTRIBUTE28', 33, 'VARCHAR2', 100, 'Y', 'N');

88 AD_DD.REGISTER_COLUMN ('PO', 'xxDFFDemo_EmpDetails','ATTRIBUTE29', 34, 'VARCHAR2', 100, 'Y', 'N');

89 AD_DD.REGISTER_COLUMN ('PO', 'xxDFFDemo_EmpDetails','ATTRIBUTE30', 35, 'VARCHAR2', 100, 'Y', 'N');

90 -- WHO Columns

91 AD_DD.REGISTER_COLUMN ('PO', 'xxDFFDemo_EmpDetails','CREATED_BY', 36, 'NUMBER', 38, 'Y', 'N');

92 AD_DD.REGISTER_COLUMN ('PO', 'xxDFFDemo_EmpDetails','CREATION_DATE', 37, 'DATE', 9, 'Y', 'N');

93 AD_DD.REGISTER_COLUMN ('PO', 'xxDFFDemo_EmpDetails','LAST_UPDATED_BY', 38, 'NUMBER', 38, 'Y', 'N');

94 AD_DD.REGISTER_COLUMN ('PO', 'xxDFFDemo_EmpDetails','LAST_UPDATE_DATE', 39, 'DATE', 9, 'Y', 'N');

95 AD_DD.REGISTER_COLUMN ('PO', 'xxDFFDemo_EmpDetails','LAST_UPDATE_LOGIN',40, 'NUMBER', 38, 'Y', 'N');

96 END;

311
www.AppsLead.com
310
www.AppsLead.com
313
www.AppsLead.com
312
www.AppsLead.com
316
www.AppsLead.com
317
www.AppsLead.com
314
www.AppsLead.com
Code in AM

Process Request Method in Controller

319
www.AppsLead.com
Process Form Request Method in Controller

313
www.AppsLead.com
311
www.AppsLead.com
311
www.AppsLead.com
Adding Descriptive Flex Field (DFF) through OAF Personalization

In this blog I will explain how to add a DFF to a existing OAF page through personalization.I am using
Supplier Quick Update Page ( /oracle/apps/pos/supplier/webui/SuppSummPG ).

If you want to see how to create DFF please click here.

In this scenario I am using a custom DFF. Following are the details.

Application -> Payables ( Code: SQLAP )


Name -> XXCUST_SUPPLIER_DFF
Title -> XXCUST - Supplier DFF
Table Name -> AP_SUPPLIERS
DFV View name -> XXCUST_SUPPLIER_DFV
Reference Fields -> ATTRIBUTE_CATEGORY

Following are the Context Field Details.

Prompt -> Supplier Type


Value Set -> XXCUST_SUP_TYPE ( Values : External and Internal )
Reference Field -> ATTRIBUTE_CATEGORY

Below table shows the segment details of XXCUST_SUPPLIER_DFF.

Code Segments Column Value Set

Global Data Elements Identification Number ATTRIBUTE1 15 Characters

External Type ATTRIBUTE2 XXCUST_EXT_SUP_TYPE

Values

Domestic

International

Internal Department ATTRIBUTE2 15 Characters

Following steps you need to perform to create flex item in the Quick Update page.

1) Click on Personalize Page.In the Personalize Page click on Complete View.

2) Click on Create Item.( Based on where you want to place the DFF choose appropriate layout).

3) Create flex item with following details.

4) If you want to arrange the item in the page click on Reorder.

Following is the output.

310
www.AppsLead.com
313
www.AppsLead.com
Creating Descriptive Flex Field (DFF) Bean in OAF

https://blogs.oracle.com/manojmadhusoodanan/entry/creating_descriptive_flex_field_dff

Creating Key Flex Field (KFF) Bean in OAF

https://blogs.oracle.com/manojmadhusoodanan/entry/creating_key_flex_field_kff

Important Adding OAF Bean Through Personalization

https://blogs.oracle.com/manojmadhusoodanan/tags/adding_oaf_bean_through_personalization

Invoking OAF through form personalization (Zoom to Another Page)

https://blogs.oracle.com/manojmadhusoodanan/tags/calling_oaf_page_through_personalization

Embeding OAF Region in Workflow Notification

https://blogs.oracle.com/manojmadhusoodanan/tags/embed_oaf_region_in_wf

Embedding Custom Region Inside Standard OAF Pages

https://blogs.oracle.com/manojmadhusoodanan/tags/embedd_cust_region

Passing Parameters, encryption, encoding


OAF: Passing Parameters between pages

Following are three common means of passing parameters between pages:

 Request
 Transaction
 Session
In addition the values set in the View Attributes are available to all pages participating in the transaction.
Request:

 Short-lived object created for each HTTP request.


 It contains following application state:
o URL Parameters
o Updatable Field values (Message Text Input etc) and Hidden Field Values (form values) in case
of post
o Event trigggering bean and the action in case of post.
 Request values are accessed using OAPageContext.getParameter() methods.
 In OAF, we don't interact with Request directly, we interact with Request through PageContext.
Ways to pass parameters in Request:

 Adding in URL: We can specify parameters as literal values or token substituted values (mapped to VO
Attributes). Following are the examples:
o OA.jsp?page=/xxabc/oracle/apps/xxabc/custommodule/webui/CustomPG&order={@OrderN
um}
o OA.jsp?OAFunc=XXABC_ADM_SUPP_ENGR&asset=123
 OAPageContext.putParameter()
o Values are not technically added to request, but are stored in a special page cache.
o Equivalent to HttpServletRequest.setAttribute()
 Hidden fields (form values)

312
www.AppsLead.com
 Passing parameters in Hashmap using setForwardUrl().
Passing parameters in Hashmap is the better approach for following reasons:

1. URL has size restrictions.


2. URL is visible to users.
3. putParamater() and hidden fields are not stored in Request as parameters, thus if we
navigate with Breadcrumbs or for other reasons in case the webBean hierarchy needs to be
reconstructed, these will not be available.
Transaction:

Transaction has wider scope than Request thus its not preferred approach.

 OAPageContext.putTransactionValue()
 OAPageContext.getTransactionValue()
 ((OADBTransactionImpl)getTransaction()).putValue()
 ((OADBTransactionImpl)getTransaction()).getValue()
Session:

Again, a wider scope than Transaction and not recommended.

 pageContext.putSessionValue();
 pageContext.getSessionValue();
Using VO Attributes for passing values

Values stored in VO attributes are available in all pages within the transaction with same Root AM.

pageContext.putSessionValue("mymap",map) and retrieve in all the pages throughout the session like

HashMap map=pageContext.getSessionValue(("mymap")

String sVal=map.get("s1")

String sVal2=map.get("s2")

URL Parameters : Encryption and Encoding

When we are passing parameters in URL, following need to be considered:

{@Attr} - encodes. Changes Prince Kapoor to Prince%20Kapoor


{!Attr} - encrypts. Encrypts sensitive information.
{$Attr} - plain token substitution (no encoding or encryption)
{@@RETURN_TO_MENU} - Used for E-Business Suite Personal Home Page. Same as
OAWebBeanConstants.RETURN_TO_MENU_URL.
{@@RETURN_TO_PORTAL} - Return the user to a launching Portal page. Same
asOAWebBeanConstants.RETURN_TO_PORTAL_URL.

316
www.AppsLead.com
Get List all Paramaters for a Page

public void processFormRequest(OAPageContext pageContext, OAWebBean webBean)


{
super.processFormRequest(pageContext, webBean);

String message = "Test Message ";


message = message + pageContext.getParameter(EVENT_PARAM);
message = message + " ";

String this_Param = "";


String this_Val = "";
Enumeration paramsEnum = pageContext.getParameterNames();
while (paramsEnum.hasMoreElements())
{
this_Param = paramsEnum.nextElement().toString();
this_Val = pageContext.getParameter (this_Param);
message = message + " (" + this_Param + "=" + this_Val + ")";
}

if (pageContext.getParameter("Go") != null)
{
message = message + "Go was submitted ";

throw new OAException(message, OAException.INFORMATION);


}

317
www.AppsLead.com
Creation Of the Anonymous page Introduction

1.1 Purpose
This document explains the OAFramework (ver 5.7 H for Apps 11.5.9 and 5.10 for Apps 11.5.10) Anonymous User
page (like registration page) development and deployment in an instance and pack for the other instances.
This document assumes that the reader has a basic knowledge of OA Frmework page creation and deployment.

1.2 Background
This document should be used for creating Guest User pages and all type of registration pages. When this
document fails to cover a topic, recommendations from OA Framework Development Team should be followed.
If you have a Guest user page to display that does not require a user to log in.

1.3 Related Documents


1. OA Framework Developers’ Guide
2 Creation Of the Anonymous page

2.1 New page with anonymous user setup.

To create a page with anonymous setup we should have a standard OAFramework page with all the components
required for the page.
We have to create the function for this page.
Let us consider a Registration page NewEmpRegistrationPG.xml and the registered function for this page is
NEW_EMP_REGN.
We have to change the following properties for the MainRN for the page.
Rendered: ${oa.FunctionSecurity. NEW_EMP_REGN}
Security Mode: selfSecured

Use the following command to upload the page to the instance,


java oracle.jrad.tools.xml.importer.XMLImporter -username -password -dbconnection
"(DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=)(PORT=))(CONNECT_DATA=(SID=)))" -rootdir ./ -rootPackage

Example.
java oracle.jrad.tools.xml.importer.XMLImporter NewEmpRegistrationPG.xml -username apps -password apps -
dbconnection

314
www.AppsLead.com
"(DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=I3SN021E.idc.oracle.com)(PORT=1610))(CONNECT_DATA=(SI
D=scmtrng)))" -rootdir ./ -rootPackage /xxt/oracle/apps/pon/registration/webui

2.2 Create a function for the new page


Use functional administrator (Self Service) or using system administrator (Forms) responsibility and create a
function for the uploaded page.

After the function creation we have to add this function to a menu and the menu has to be granted to GUEST
user.

2.3 Add the function to a new menu


Use fuctional administrator responsibility to create a new Menu. Add the created function with this new menu.

319
www.AppsLead.com
Now we are ready with the menu that is having a function, which points to a page which we want to access
without the user log in.
If you want to give access to more than one page you can add, as many functions to the menu, like below.

2.4 Create Grant for the created menu.


To create Grant for the menu we have created now, use Security Tab in the functional administrator
responsibility. Follow the below mentioned steps.

303
www.AppsLead.com
Step I: Log on to Application with Functional Administrator Responsibility and click on functional administrator
responsibility. Click on “Create Grant” button (To create a Global Grant)

Step II: Enter the Grant Name and select Grantee Type as “All Users” and click “Next”

Step III: Enter the User Menu Name of the newly created Menu and click “Next”

Step IV : Click “Finish” button

301
www.AppsLead.com
Step V: Again click on “Create Grant” (To create Guest Grant)

Step VI : Enter the Grant Name and select Grantee Type as “Specific User”. The page refreshes to display a new
field called “Grantee” (If the page fails to refresh click “Next” button to go to the next screen and click “Back”
button on the next screen to come back to this screen)
Enter “GUEST” in the “Grantee” field and click “Next”

Step VII: Enter the User Menu Name of the newly created Menu and click “Next”

301
www.AppsLead.com
Step VIII : Click “Finish” button

Step IX: Grant creations successfully completed.

3 Download and Upload the Grant


Following command used to download the created Grant.
FNDLOAD apps/apps 0 Y DOWNLOAD $FND_TOP/patch/115/import/afsload.lct XXTGUESTGRT_US.ldt GRANT
GNT_MENU_NAME= NEW_EMP_REGN_MENU
To upload this grant into a new instance upload the page and the menu as usual and upload the Grant for the
menu using the following command.
Following command used to upload the downloaded Grant.
FNDLOAD apps/apps 0 Y UPLOAD $FND_TOP/patch/115/import/afsload.lct XXTGUESTGRT_US.ldt
No we can access the newly created page without login into the applications using the following URL.
http://: /OA_HTML/OA.jsp?OAFunc=NEW_EMP_REGN

300
www.AppsLead.com
Deploying OAF Personalizations Using the Import/Export Command Line Tools
After personalizing and testing framework pages in a Development instance, you may wish to automate the
transfer of these changes to another instance, rather than manually re-doing them all again. This objective can be
achieved by exporting the personalizations from the Development instance, then importing them to a different
instance or instances
You can either use the GUI interface in “Functional Administrator” (Personalization tab) to transfer
personalizations, or can invoke the XMLImporter/XMLExporter commands directly from the command line. The
Export tool allows you to export a package or xml file (along with translation information) from the MDS
repository of a database instance to a .xml file (or .xlf file for translations). The command line Export tool is
necessary if you wish to perform bulk translations of personalization documents.
This post provides the below detailed steps how to transfer personalizations from one instance to others using
the XMLImporter/XMLExporter tool.
1. Get Document Name
Go to the page you want to copy the personalization from and click the “about this Page” link at the bottom of
the page. You will see the page name with full path which starts with /oracle/apps/<prod>.
Ex: /oracle/apps/icx/por/wf/webui/ReqLinesNotificationsRN
2. Get the Personalization Document info
Run the following command in TOAD or other tools as APPS user
1 set serveroutput on

2 exec jdr_utils.listCustomizations('<full document name from step 1>');

Example:
1 set serveroutput on

2 execjdr_utils.listCustomizations('/oracle/apps/icx/por/wf/webui/ReqLinesNotificationsRN');

Output:
anonymous block completed
/oracle/apps/icx/por/wf/webui/customizations/site/0/ReqLinesNotificationsRN
Note: If there are multiple records returned by this command, you will need to use export/import each item
individually that you wish to export. You may also find there are records returned for seeded personalizations
provided by Oracle which do not need to be exported.
3. Use XMLExporter to export personalization document
1 java oracle.jrad.tools.xml.exporter.XMLExporter <personalization document from step #2> \

2 -username "<username>" -password "<password>" \

-dbconnection
3
"(description=(address_list=(address=(protocol=tcp)(host=<host>)(port=<port)))(connect_data=(sid=<sid>)))" \

4 -rootdir "<output directory>"

Example:
1 java oracle.jrad.tools.xml.exporter.XMLExporter \

/oracle/apps/icx/por/wf/webui/customizations/site/0/ReqLinesNotificationsRN -username apps -password


2
w3lcome123 \

3 -dbconnection
"(description=(address_list=(address=(protocol=tcp)(host=myhost)(port=12345)))(connect_data=(sid=dev)))" -

303
www.AppsLead.com
rootdir "$XXSCM_TOP/install" \

Here one file named ReqLinesNotificationsRN.xml will be created in the below path:
XXSCM_TOP/install/oracle/apps/icx/por/wf/webui/customizations/site/0. Open the file and you will able to view
the personalizations that you have done.
4. Use XMLImporter to import personalization document
Run the below command in the Instance where you want to import your personalization.
1 java oracle.jrad.tools.xml.importer.XMLImporter \

2 <full path of the file you want to import> \

3 -username "<username>" -password "<password>" \

-dbconnection
4 "(description=(address_list=(address=(protocol=tcp)(host=<host>)(port=<port>)))(connect_data=(sid=<sid>)))"
-rootdir "<top level directory>" \

5 -rootPackage "/oracle/apps/<prod>"

Example:
1 java oracle.jrad.tools.xml.importer.XMLImporter \

$XXSCM_TOP/install/ReqLinesNotificationsRN.xml
2
\

3 -username apps -password w3lcome123 \

-dbconnection "(description=(address_list=(address=(protocol=tcp)(host=
4
myhost)(port=12345)))(connect_data=(sid=dev)))" -rootdir "$XXSCM_TOP/install" \

5 -rootPackage "oracle/apps/icx/por/wf/server"

302
www.AppsLead.com
SQL Transaction Control Language Commands (TCL)

(COMMIT)

Commit Transaction

As a SQL language we use transaction control language very frequently. Committing a transaction means making
permanent the changes performed by the SQL statements within the transaction. A transaction is a sequence of
SQL statements that Oracle Database treats as a single unit. This statement also erases all save points in the
transaction and releases transaction locks.

Oracle Database issues an implicit COMMIT before and after any data definition language (DDL) statement.
Oracle recommends that you explicitly end every transaction in your application programs with a COMMIT or
ROLLBACK statement, including the last transaction, before disconnecting from Oracle Database. If you do not
explicitly commit the transaction and the program terminates abnormally, then the last uncommitted transaction
is automatically rolled back.

Until you commit a transaction:

You can see any changes you have made during the transaction by querying the modified tables, but
other users cannot see the changes. After you commit the transaction, the changes are visible to other
users' statements that execute after the commit

You can roll back (undo) any changes made during the transaction with the ROLLBACK statement

Note:

Most of the people think that when we type commit data or changes of what you have made has been written to
data files, but this is wrong when you type commit it means that you are saying that your job has been
completed and respective verification will be done by oracle engine that means it checks whether your
transaction achieved consistency when it finds ok it sends a commit message to the user from log buffer but not
from data buffer, so after writing data in log buffer it insists data buffer to write data in to data files, this is how it
works.

Before a transaction that modifies data is committed, the following has occurred:

Oracle has generated undo information. The undo information contains the old data values changed
by the SQL statements of the transaction

Oracle has generated redo log entries in the redo log buffer of the System Global Area (SGA). The redo
log record contains the change to the data block and the change to the rollback block. These changes
may go to disk before a transaction is committed

The changes have been made to the database buffers of the SGA. These changes may go to disk
before a transaction is committed

306
www.AppsLead.com
Note:

The data changes for a committed transaction, stored in the database buffers of the SGA, are not necessarily
written immediately to the data files by the database writer (DBWn) background process. This writing takes place
when it is most efficient for the database to do so. It can happen before the transaction commits or,
alternatively, it can happen some times after the transaction commits.

When a transaction is committed, the following occurs:

1. The internal transaction table for the associated undo table space records that the transaction has
committed, and the corresponding unique system change number (SCN) of the transaction is assigned
and recorded in the table

2. The log writer process (LGWR) writes redo log entries in the SGA's redo log buffers to the redo log file.
It also writes the transaction's SCN to the redo log file. This atomic event constitutes the commit of the
transaction

3. Oracle releases locks held on rows and tables

4. Oracle marks the transaction complete

Note:

The default behavior is for LGWR to write redo to the online redo log files synchronously and for transactions to
wait for the redo to go to disk before returning a commit to the user. However, for lower transaction commit
latency application developers can specify that redo be written asynchronously and that transaction do not need
to wait for the redo to be on disk.

The syntax of Commit Statement is

COMMIT [WORK] [COMMENT ‘your comment’];

WORK is optional.

The WORK keyword is supported for compliance with standard SQL. The statements COMMIT and
COMMIT WORK are equivalent.

307
www.AppsLead.com
Examples

Committing an Insert

INSERT INTO table_name VALUES (val1, val2);

COMMIT WORK;

COMMENT

Comment is also optional. This clause is supported for backward compatibility. Oracle recommends
that you used named transactions instead of commit comments. Specify a comment to be associated
with the current transaction. The 'text' is a quoted literal of up to 255 bytes that Oracle Database stores
in the data dictionary view DBA_2PC_PENDING along with the transaction ID if a distributed transaction
becomes in doubt. This comment can help you diagnose the failure of a distributed transaction.

Examples

The following statement commits the current transaction and associates a comment with it:

COMMIT

COMMENT 'In-doubt transaction Code 36, Call (415) 555-2637';

WRITE Clause

Use this clause to specify the priority with which the redo information generated by the commit
operation is written to the redo log. This clause can improve performance by reducing latency, thus
eliminating the wait for an I/O to the redo log. Use this clause to improve response time in
environments with stringent response time requirements where the following conditions apply:

The volume of update transactions is large, requiring that the redo log be written to disk frequently.

The application can tolerate the loss of an asynchronously committed transaction.

The latency contributed by waiting for the redo log write to occur contributes significantly to overall
response time.

You can specify the WAIT | NOWAIT and IMMEDIATE | BATCH clauses in any order.

Examples

To commit the same insert operation and instruct the database to buffer the change to the redo log,
without initiating disk I/O, use the following COMMIT statement:

COMMIT WRITE BATCH;

Note:

If you omit this clause, then the behavior of the commit operation is controlled by the COMMIT_WRITE
initialization parameter, if it has been set. The default value of the parameter is the same as the default
for this clause. Therefore, if the parameter has not been set and you omit this clause, then commit
records are written to disk before control is returned to the user.

304
www.AppsLead.com
WAIT | NOWAIT Use these clauses to specify when control returns to the user.

The WAIT parameter ensures that the commit will return only after the corresponding redo is
persistent in the online redo log. Whether in BATCH or IMMEDIATE mode, when the client receives a
successful return from this COMMIT statement, the transaction has been committed to durable media.
A crash occurring after a successful write to the log can prevent the success message from returning to
the client. In this case the client cannot tell whether or not the transaction committed.

The NOWAIT parameter causes the commit to return to the client whether or not the write to the redo
log has completed. This behavior can increase transaction throughput. With the WAIT parameter, if the
commit message is received, then you can be sure that no data has been lost.

Caution:

With NOWAIT, a crash occurring after the commit message is received, but before the redo log
record(s) are written, can falsely indicate to a transaction that its changes are persistent.

If you omit this clause, then the transaction commits with the WAIT behavior.

IMMEDIATE | BATCH Use these clauses to specify when the redo is written to the log.

The IMMEDIATE parameter causes the log writer process (LGWR) to write the transaction's redo
information to the log. This operation option forces a disk I/O, so it can reduce transaction throughput.

The BATCH parameter causes the redo to be buffered to the redo log, along with other concurrently
executing transactions. When sufficient redo information is collected, a disk write of the redo log is
initiated. This behavior is called "group commit", as redo for multiple transactions is written to the log
in a single I/O operation.

If you omit this clause, then the transaction commits with the IMMEDIATE behavior.

FORCE Clause

Use this clause to manually commit an in-doubt distributed transaction or a corrupt transaction.

In a distributed database system, the FORCE string [, integer] clause lets you manually
commit an in-doubt distributed transaction. The transaction is identified by the 'string'
containing its local or global transaction ID. To find the IDs of such transactions, query the
data dictionary view DBA_2PC_PENDING. You can use integer to specifically assign the
transaction a system change number (SCN). If you omit integer, then the transaction is
committed using the current SCN.

The FORCE CORRUPT_XID 'string' clause lets you manually commit a single corrupt
transaction, where string is the ID of the corrupt transaction. Query the
V$CORRUPT_XID_LIST data dictionary view to find the transaction IDs of corrupt transactions.
You must have DBA privileges to view the V$CORRUPT_XID_LIST and to specify this clause.

Specify FORCE CORRUPT_XID_ALL to manually commit all corrupt transactions. You must
have DBA privileges to specify this clause.

Examples

309
www.AppsLead.com
Forcing an in doubt transaction. Example The following statement manually commits a hypothetical in-
doubt distributed transaction. Query the V$CORRUPT_XID_LIST data dictionary view to find the
transaction IDs of corrupt transactions. You must have DBA privileges to view the
V$CORRUPT_XID_LIST and to issue this statement.

COMMIT FORCE '22.57.53';

333
www.AppsLead.com
Implementing a simple watch in a OA Framework Page

I hope this is interesting ... implementing a watch in OA Framework page.There can be several other
functionalities, one can do after implementing this watch.Here i am just writing a simple function for javascript
watch,you can take an idea.... and change this function accordingly.

Just read this function.....

/* Here is the javascript function, which is self explainatory


Read this function carefully
to understand it.*/

function update()
{
//Define a new date object
var today=new Date();

var hours=today.getHours();
var minutes=today.getMinutes();
var seconds=today.getSeconds();

//for formatting output


if (hours<10)
hours="0"+hours;
if (minutes<10)
minutes="0"+minutes;
if (seconds<10)
seconds="0"+seconds;

//writing output to message text input


document.getElementByID('OAclockDisplay').value=hours+":"+minutes+":"+seconds;

//refreshing ever sec


setTimeout("update()",1000);
}

I hope this clear. Now here are the steps how you can put it in your OA Framework page.Add a message text
input to your page, say its id is "OAclockDisplay".

Now add this code in process request of controller of page:

//storing javascript function is a string


// "\" is used as escape character
String s="function update(){var today=new Date();var hours=today.getHours();var
minutes=today.getMinutes();var seconds=today.getSeconds();if(hours<10){hours=\"0\"+hours;}
if(minutes<10){minutes=\"0\"+minutes;} if(seconds<10){seconds=\"0\"+seconds;}
document.getElementById('OAclockDisplay').value=hours+\":\"+minutes+\":\"+seconds;setTimeout(\"update()\"
,1000);}";

//getting body bean


OABodyBean bodyBean = (OABodyBean)pageContext.getRootWebBean();

//attaching javascript function to page


pageContext.putJavaScriptFunction("update",s);

// calling this function on load of body bean


String javaS = "javascript:update();";
bodyBean.setOnLoad(javaS);

We are done, run this page you will be able to see a watch in oa framework page in that particular message text
input.
Cheers!

331
www.AppsLead.com
331
www.AppsLead.com
Implementing Shuttle Region in OAF

Shuttle region allows users to move items between two lists as well as reorder the items in the list. When you
implement a Shuttle region, you define two lists:

A Leading list (Available List) - from which user can select items from a given list of items
A Trailing list (Selected List) - user will select item from Leading list and move those to this trailing list.

Also we can implement a Shuttle region with just one list, to achieve only Reorder functionality, in that case only
a Leading list is required.

We can also add buttons/icons in the footer below each of the Shuttle lists. By Simply defining Leading footer
child or Trailing footer child in region creates a flowLayout region by default, to which we can add a button or
image.

Here, I have created a simple page to implement shuttle region. User will select employee name from 'Available
List' and move them to 'selected List'. A button is also added at footer of trailing list. Clicking on this button will
show all the employees selected in a message.

1) Create a new OA page:


=========================
Right click on project (xxcus) --> New --> Web Tier --> OA Components --> select 'Page' item. Click OK. (This will
open a popup window)
We are creating a page for implementing shuttle region, so specify the details of page as below:
Name: XxShuttleDemoPG
Package: xxcus.oracle.apps.fnd.shuttledemo.webui

2) Create a new view objects (VO):


=========================
Right click --> New View Object (This will open a wizard having 7 steps).

Step 1
Package: xxcus.oracle.apps.fnd.shuttledemo.server
Name: XxEmpShuttleVO
Choose the radio button 'Read-only Access' (as there is no DML operation). Click Next.

Step 2
Enter the below query in 'Query Statement':
select ename from employee

Keep defaults for step3, 4, 5, 6 & 7 and click Finish. Save All.

3) Create a new Application Module (AM):


=========================

Step 1
Package: xxcus.oracle.apps.fnd.shuttledemo.server
Name: XxShuttleDemoAM. Click Next.

Step 2
Here we will add an instance of the VO created in (2). Select XxEmpShuttleVO from 'Available View Objects'
and shuttle it to 'Data Model' using ">" button.

Keep defaults for all other steps (3, 4). Click Finish.

4) Create a new Controller (CO):


=========================
Right click on pageLayout region and create a new controller
Name: XxShuttleDemoCO
package: xxcus.oracle.apps.fnd.shuttledemo.webui

330
www.AppsLead.com
5) Creating the Page Layout & Setting its Properties :-
==========================
The page will appear as below:

1) Create a new region under pageLayout of type shuttle. This will automatically create a region for leading list.
2) Add Trailing list: right click shuttle region --> new --> Trailing.
3) Add trailing footer to display button: Again right click on shuttle region --> new --> trailingFooter. This will
create a flowLayout region under trailingFooter.
4) Add 'Display Items' button: Create an item of type submitButton under the flowLayout region.

Now change the properties for each field from property inspector as shown below:

pageLayout:
ID: pageLayoutRN
AM Definition: xxcus.oracle.apps.fnd.shuttledemo.server.XxShuttleDemoAM
Window Title: Shuttle Demo Page
Title: Shuttle Demo

shuttle:
ID: shuttleRN
Available Header: Available Employees
Selected Header: Selected Employees

leadingList:
Picklist View Definition: xxcus.oracle.apps.fnd.shuttledemo.server.XxEmpShuttleVO
Picklist View Instance: XxEmpShuttleVO1
Picklist Display Attribute: Ename
Picklist Value Attribute: Ename

list2:
Picklist Display Attribute: Ename
Picklist Value Attribute: Ename

submitButton:
ID: displayBtn
Prompt: Display Items

333
www.AppsLead.com
The declarative page structure in jDev will be similar to as shown below:

We will catch the button event (displayBtn) in PFR method of controller and display a message showing all the
employees present in selected list. If there is no item in selected list, throw an error message. Below is code for
the same:
1 public void processFormRequest(OAPageContext pageContext,
2 OAWebBean webBean) {
3 super.processFormRequest(pageContext, webBean);
4
5 String message = "";
6
7 if (pageContext.getParameter("displayBtn") != null) {
8 OADefaultShuttleBean shuttle =
9 (OADefaultShuttleBean)webBean.findChildRecursive("shuttleRN");
10 String[] items =
11 shuttle.getTrailingListOptionValues(pageContext, shuttle);
12
13 if (items != null) {
14 for (int i = 0; i < items.length - 1; i++) {
15 message = items[i] + " , " + message;
16 }
17
18 message = message + items[items.length - 1];
19 throw new OAException("Items in trailing list are: " +
20 message, OAException.INFORMATION);
21 } else {
22 throw new OAException("Please shuttle at least one item from available list.",

332
www.AppsLead.com
23 OAException.ERROR);
24 }
25 }
26}

Below is how the error message will appear:

336
www.AppsLead.com
Gruoping Radio Buttons in OAF

Hi all like in forms there is no declarative way to group Radio Buttons in OAF we have to
group them dynamically some sample working code

import oracle.apps.fnd.framework.webui.beans.message.OAMessageRadioButtonBean;
just import this package

OAMessageRadioButtonBean rb1
= (OAMessageRadioButtonBean)webBean.findIndexedChildRecursive("RadioBtn1");
OAMessageRadioButtonBean rb2
= (OAMessageRadioButtonBean)webBean.findIndexedChildRecursive("RadioBtn2");
rb1.setName("ChoiceRadioGroup");
rb2.setName("ChoiceRadioGroup");
rb1.setValue("New");
rb2.setValue("Update");
rb1.setSelected(true);

where RadioBtn1,RadioBtn2 are the id of the Radio Buttons

to get selected value


String radioGroupValue = pageContext.getParameter("ChoiceRadioGroup");
In above Example String radioGroupValue will be New,Update on selecting the First and
Second radio buttons respectively

337
www.AppsLead.com
Creating Graph in OAF
Here is an example of how to create a Bar Graph in OAF. Graphs are created with the graphTable region style.

1) Create a new OA page:


=========================
Right click on project (xxcus) --> New --> Web Tier --> OA Components --> select 'Page' item. Click OK. (This will
open a popup window)
Name: XxcusGraphDemoPG
Package: xxcus.oracle.apps.fnd.graphdemo.webui

2) Create a new view object (VO):


=========================
Right click --> New View Object (This will open a wizard having 7 steps).

Step 1
Package: xxcus.oracle.apps.fnd.graphdemo.server
Name: XxcusEmpGraphVO
Choose the radio button 'Read-only Access' (as we are not performing any DML operation). Click Next.

Step 2
Enter the below query in 'Query Statement':
select ename, sal from employee

Step 3
Generate Impl class for the view object.

Keep defaults for step 4, 5, 6 & 7 and click Finish. Save All.

3) Create a new Application Module (AM):


=========================

Step 1
Package: xxcus.oracle.apps.fnd.graphdemo.server
Name: XxcusGraphDemoAM. Click Next.

Step 2
Here we will add an instance of the VO created in (2). Select XxcusEmpGraphVO from 'Available View Objects'
and shuttle it to 'Data Model' using ">" button.
Keep defaults for all other steps (3, 4). Click Finish.

4) Create a new Controller (CO):


=========================
Right click on pageLayout region and create a new controller
Name: XxcusGraphDemoCO
package: xxcus.oracle.apps.fnd.graphdemo.webui

5) Creating the Page Layout & Setting its Properties


=========================
1) Create a new region under pageLayout of type graphTable. This will automatically create a default graphs
container. Also, it will add a graph to the graphs container along with two default graphData columns.

Now change the properties for each field from property inspector as shown below:

pageLayout:
ID: pageLayoutRN
AM Definition: xxcus.oracle.apps.fnd.graphdemo.server.XxcusGraphDemoAM
Window Title: Employee Salary Graph Page
Title: Employee Salary Graph

334
www.AppsLead.com
graphTable:
ID: graphTableRN
Graph render style: graph

set these properties for the graph:


ID: empSalGraph
Graph Type: vertical clustered bar
Title: Employee Name vs Salary
Size: Medium
X-axis label: Employee Name

set properties for graphData1:


ID: xAxisData
View Instance: XxcusEmpGraphVO1
View Attribute: Ename
Purpose in Graph: groupLabels (it represents data on X-axis)

set properties for graphData1:


ID: yAxisData
View Instance: XxcusEmpGraphVO1
View Attribute: Sal
Purpose in Graph: data (it represents data on Y axis)
Prompt: Salary

The declarative page structure in jDev will be similar to as shown below:

In PR method, we call a method of AM to intiate query:


1public void processRequest(OAPageContext pageContext, OAWebBean webBean) {
2 super.processRequest(pageContext, webBean);
3 OAApplicationModule am = pageContext.getRootApplicationModule();
4 am.invokeMethod("initQuery");
5}

Code for initQuery method in XxcusGraphDemoAMImpl.java file:

339
www.AppsLead.com
1public void initQuery() {
2 try {
3 XxcusEmpGraphVOImpl vo = getXxcusEmpGraphVO1();
4 vo.setMaxFetchSize(-1);
5 vo.executeQuery();
6 } catch (Exception e) {
7 e.printStackTrace();
8 }
9}

Below is how the page will appear:

323
www.AppsLead.com
Steps to add JSP page to Oracle Application

Following are the steps to add a JSP page to Oracle Application

1) Upload the .jsp page to $OA_HTML top


2) Run " export PATH=$PATH:$FND_TOP/patch/115/bin "
3) Run " ojspCompile.pl --compile -s 'JSPFileName.jsp' --flush " (In R12 .class file is stored in
$COMMON_TOP/_Pages and in R11 is stored in $OA_HTML).
4) Create a form function with type "SSWA jsp function" and web call as "JSPFileName.jsp".
5) Bounce the server

321
www.AppsLead.com
Calling JSP Page from OAF Page

1) Create a new JSP page. I have created the same in JDeveloper.


Right click on project --> new --> web tier --> JSP as shown below:

2) I created simple Hello World page as shown below in JSP :

3) To run the page from jDeveloper itself, we have to change the path of HTML root directory. This should point
to the directory where JSP files are stored.
We can change this from project properties --> Project Content --> Web Application.

321
www.AppsLead.com
4) Once the JSP page is created, migrate the same on server at $OA_HTML.

5) Compile the same using below command:


$FND_TOP patch/115/bin/ojspCompile.pl --compile -s <file_name>.jsp
This will compile the file on server.

6) Now we can either directly open the JSP page using this link:
http://<instancename>.<port>/OA_HTML/XXTest.jsp

or, we can call JSP page from any OAF page by simply setting destination URI of item like link or button.
for example, I created an item of type link on OAF page and set its destination URI property to
/OA_HTML/XxJspTest.jsp:

320
www.AppsLead.com
Below is how the link will work:

Click on 'Open JSP' link. This will open our JSP Page:

323
www.AppsLead.com
Dependent Dynamic message choicelists

This is one of the most common scenario in any web application page.Basically here i am just giving an idea how
to code for dependent message choicelists in OA Framework page both at page level or in a collective ui feature
like table or hgrid.

3 Message Choicelists in a Page :

Lets consider the first scenario, where we have 3 dependent message choicelists(mc1,mc2,mc3), these can be n
in number, just follow the same approach.Here mc1,mc2 and mc3 are the item ids of the message choice lists in
the page UIX file, which are attached to vo instances mc1VO1 and mc2VO1 and mc3vo1 respectively.Assuming
"Intial value" property value is blank and "Add blank value" is "true" in property inspector for all three poplists.
Lets start from controller code, please read comments, as they explain each and every line..

Controller Code

/*Code in Controller*/
import oracle.apps.fnd.framework.webui.beans.message.OAMessageChoiceBean;

//Code in process request


OAMessageChoiceBean mc1 = (OAMessageChoiceBean)webBean.findChildRecursive("mc1");
/*The poplist data object that OA Framework creates the first
* time is cached in the JVM and reused
*until you explicitly disable caching
*Hence, use setPickListCacheEnabled API to stop JVM
* from caching Poplist values, this API needs to be called on any Poplist
* where the VO where clause keeps on changing
*/
mc1.setPickListCacheEnabled(false);
//Similarly for second Poplist
OAMessageChoiceBean mc2 = (OAMessageChoiceBean)webBean.findChildRecursive("mc1");
mc2.setPickListCacheEnabled(false);

//Similarly for third Poplist


OAMessageChoiceBean mc3 = (OAMessageChoiceBean)webBean.findChildRecursive("mc3");
mc3.setPickListCacheEnabled(false);

//Code in process form request


/*If a value is selected in mc1
*"update" is the name of PPR event
* attached to poplist mc1
*/
if("update".equals(pageContext.getParamete(OAWebBeanConstants.EVENT_PARAM))) {
String value_selected=pageContext.getParameter("mc1");
//Priniting the value selected
System.out.println("value_selected in mc1>>"+value_selected);
//if the selected value is not null
if(!(("".equals(value_selected)) (value_selected==null)))
{
//then calling the method in AM which will reinitialise VO query
// in second message choicelist and not third because
//the value selected in seocond will null
//as we have turned Add blank value to true
//and initial value is null in property inspector
Serializable[] param = {value_selected};
am.invokeMethod("initmc2VOQuery", param);
// if user selects some value in first choicelist
// pass some dummy_value in mc3vo query so that it returns 0 records
//or you can put some condition in vo query like where 5=6
Serializable[] param = {dummy_value};
am.invokeMethod("initmc3VOQuery", param);
}

322
www.AppsLead.com
else
{
// if user selects null in first choicelist
// pass some dummy_value in mc2vo query so that it returns 0 records
//or you can put some condition in vo query like where 5=6
//doing this for mc2vo1 and mc3vo1
Serializable[] param = {dummy_value};
am.invokeMethod("initmc2VOQuery", param);
am.invokeMethod("initmc3VOQuery", param);
}
}

/*If a value is selected in mc2


*"update1" is the name of PPR event
* attached to poplist mc2
*/
if("update1".equals(pageContext.getParamet(OAWebBeanConstants.EVENT_PARAM)))
{
String value_selected=pageContext.getParameter("mc2");
//Priniting the value selected
System.out.println("value_selected in mc2>>"+value_selected);
//if the selected value is not null
if(!(("".equals(value_selected)) (value_selected==null)))
{
//then calling the method in AM which will reinitialise VO query
// in third message choicelist
Serializable[] param = {value_selected};
am.invokeMethod("initmc3VOQuery", param);
}
else
{
// if user selects null in second choicelist
// pass some dummy_value in mc3vo query so that it returns 0 records
//or you can put some condition in vo query like where 5=6
//doing this only for mc3vo1
Serializable[] param = {dummy_value};
am.invokeMethod("initmc3VOQuery", param);
}
}

Dependent message choicelists in Table

Controller Code :

/*Cosider two message choicelist items HeaderPoplistItem and LinePoplistItem in table with item id "XXX".We
will use setListVOBoundContainerColumn api,which is typically used for containers that repeat it's content
multiple times and want to attach different set of records for each iteration, eg table or hgrid.*/

OATableBean XXX = (OATableBean)webBean.findChildRecursive("XXX");

/*LinePoplistItem is a poplist item, in which view def is filled and not view instance this is based on initial
value in HeaderPoplistItem which is a poplistwith view instance name*/
OAMessageChoiceBean LinePoplistItem = (OAMessageChoiceBean)XXX.findChildRecursive("LinePoplistItem");
//
LinePoplistItem.setListVOBoundContainerColumn(0, XXX,"HeaderPoplistItem");

AM code
//Also note for runtime dependency of table of hgrid poplists, you have attach PPR in the LinePoplistItem and in
your event method in AM write:
getVO().setWhereClauseParam(0,);
getVO().executeQuery();
326
www.AppsLead.com
In this article , i have covered the Dependent Dynamic message choicelists in tables and independent poplists on
page. Hope this scenario is now clear.

327
www.AppsLead.com
MOAC(Multi Org Access Control) in OA Framework

Hi All,
After a long time a small and crisp article of how you can set MOAC in your custom OAF code. With release of
R12 Oracle EBS has introduced a security feature in apps for multi -org access. Lets have a quick introduction of
what is MOAC all abaout :

What is MOAC ?
---------------
The Access Control feature in Release 12 allows the user to enter or query records in one or more operating units
without changing application responsibility. It is the system administrator’s discretion to either implement the
feature or use the same multiple organizations profile option setting available before Release 12 by using the
single operating unit mode (i.e. one operating unit for a responsibility).
In Release 12, the multiple organizations context value is no longer initialized by the
FND_GLOBAL.APPS_INITIALIZE routine thereby reducing unnecessary context setting and resource consumption
for applications that do not use operating unit context for data security.
To use the single operating unit mode, you must set the value for the "Initialization SQL Statement – Custom
profile" to "mo_global.init('S',null);". This initializes the operating unit context based on the "MO: Operating
Unit" profile option and the "MO: Security Profile" profile option must not be set.
Fresh install of Release 12 Application is enabled with multiple organizations, however, the system administrator
must create operating units to use multi organizations sensitive application products. The user can create new
operating units in the Accounting Setup Manager page in addition to HRMS’s Define Organizations page.

MOAC Implementation In Apps


-----------------------------
A new or fresh installation of an Oracle Applications instance does not automatically enable multiple
organizations. Typically, the system administrator defines "MO: Operating Unit" profile at Responsibility and/or
User level. The "organization_id" of the "MO: Operating Unit" profile option value filters the transactional data.
The CLIENT_INFO application context space stores the multiple organizations context value.
Multi-Org views use the following WHERE clause to filter application records:
'org_id = substrb(userenv(''CLIENT_INFO''),1,10)'

MOAC in terms of OAF:


----------------------
Its very natural while developing extension or developing OAF custom pages , you may require quering of views,
synonyms which use MOAC via VO.Also, it is possible that you might be calling some standard Oracle PL/SQL APIs
which usually need MOAC context to be set.

Every transaction that requires multiple organizations must call the Multiple Organizations initialization in the
root Application Module (AM).
Use the following declarative mechanism to initialize the multiple organizations settings for application teams to
implement multiple organizations:
1. To enable multiple organizations for the root application module , go to the BC4J Application Module wizard -
Properties section and specify the property as MULTIORG_ENABLED and value as either S (single operating unit
mode) or M (Multiple operating unit mode).
2. Click Add, then Apply or OK.
On specifying this property, the OA Framework automatically initializes the multiple organizations context at the
following appropriate program event points:
1. When reserving or activating the application module.
2. When initializing or validating the Oracle Applications user session.
You initialize the context once for each transaction and session and not instantiate for every page. If your
transaction retains the root AM, then the above steps are the easiest to initialize multiple organizations.

If a transaction has multiple pages and the root AM is not retained, then you must call the method
OADBTransaction.setMultiOrgAccess to initialize the multiple organizations context to help the user select an
operating unit for a transaction.Here is how u can code in AM
OADBTransactionImpl trx = (OADBTransactionImpl)getOADBTransaction();
getOADBTransaction().setMultiOrgAccess(String.valueOf(trx.getOrgId()),String.valueOf(trx.getSecurityProfileId()),
trx.getApplicationShortName());

324
www.AppsLead.com
If the operating unit the user selected must appear in the subsequent pages, then pass the curr_org_id to the
page and use OADBTransaction.setMultiOrgPolicyContext method to set the operating unit context for the pages
that need multiple organizations.
OADBTransactionImpl trx = (OADBTransactionImpl)getOADBTransaction();
getOADBTransaction().setMultiOrgPolicyContext("S",trx.getMultiOrgCurrentOrgId());

There is often a case when you create a custom application in apps under $JAVA_TOP, in order to keep all your
customizations, lets say XXABC.When we make a new application in Apps like XXABC, we need to register the
application for Multi-Org as single or multiple.
This is important, if we are defining new custom responsibilities on this application and we are planning to have
custom, as well as seeded pages attached in this responsibility.If you have this scenario, where you custom
responsibility is defined on custom application and it is using seeded pages as well as custom pages, you may face
a error in your multi-org enabled seeded AM pages like :
oracle.apps.fnd.framework.OAException: Application: FND, Message Name: FND_GENERIC_MESSAGE. Tokens:
MESSAGE = java.sql.SQLException: ORA-20001: SQL_PLSQL_ERROR: N, ROUTINE, MO_GLOBAL.INIT, N, ERRNO,
-20001, N, REASON, ORA-20001: SQL_PLSQL_ERROR: N, ROUTINE, MO_GLOBAL.SET_ORG_ACCESS, N, ERRNO, -
20001, N, REASON, ORA-20001: APP-FND-02938: Multi-organization routine failed to initialize a session for the
product: &PRODUCT. Please inform your support representative.
ORA-06512: at "APPS.FND_MESSAGE", line 509
ORA-06512: at "APPS.MO_GLOBAL", line 36
ORA-06512: at "APPS.MO_GLOBAL", line 757
ORA-06512: at "APPS.MO_GLOBAL", line 700
ORA-06512: at line 1

The reason for this error is Oracle Apps seeded pages which have AM with multi-org enabled,if you will check the
AM xml file , they use MULTIORG_ENABLED as Y and not as S or M . This is because in Apps, you can directly
register an application with multi-org enabled in table fnd_mo_product_init by using API :
-- To enable MO access in a custom application:
begin
FND_MO_PRODUCT_INIT_PKG.register_application('XXABC','SEED','N');
end;

Since, seeded applications are already registered here, its not a problem, when you run seeded pages because
MULTIORG_ENABLED=Y in AM sets correct multi org access, but in case of custom application/responsibility
based on custom application running seeded pages throws error, because the custom application XXABC is not
registered in table fnd_mo_product_init. Hence , in order to run both seeded pages and custom pages fine i.e.
code work correctly in case of MULTIORG_ENABLED=Y (used by seeded pages) or MULTIORG_ENABLED=S/M
(custom pages), register the custom application using the FND_MO_PRODUCT_INIT_PKG.register_application
API.

329
www.AppsLead.com
Export Button Functionality Programatically

There is often a requirement to export a VO data or a UI table data into a CSV file. OA Framework provides export
button bean for the this functionality, which works fine in almost 99% of the cases. But sometimes, you might
face a scenario when ur table u have complex UIs like switcher/hide show columns etc, where the standard
export functionality doesn't work or you want some columns not to come in export, or you wanna change some
data on export.

In such cases, you can implement the export functionality programatically by yourself.Copy paste the following
method in the page CO and pass appropriate parameters to get exported data.You can change this method, as
per your requirement, to get data/format data or change data.

By default this method will bring all columns of fetch rows of VO instance,although you can use param
hidden_attrib_list to pass attributes which you don't want to be included in csv file.You can call this method in
the submit button event that you have made in process form request like :

//see api parameter details in the method below.


//array of Vo attr names which need not be written in csv file
String ss[]={xID,xName};
downloadCsvFile(pageContext, "XxAdatVisSearchVO",null, "MAX",ss);

/**
* @param pageContext
* @param view_inst_name is the view object instance name like VO1 etc in root AM.
* Make sure the VO instance name you have passed should be same as in Root AM.
* @param file_name_without_ext - pass for eg for abc.csv , u should pass "abc".If no
* name is passed then by default it will pick "Export.csv".
* @param max_size -pass "MAX", if u want all rows, pass null to get fetch row count
* else pass integer number like 10,20 etc , the number of rows you want to fetch.
* @param hidden_attrib_list -Array of VO attribute names which doesn't need to be shown/written in
* csv file.
*/
public void downloadCsvFile(OAPageContext pageContext,
String view_inst_name,
String file_name_without_ext,
String max_size, String[] hidden_attrib_list)
{
OAViewObject v =
(OAViewObject) pageContext.getRootApplicationModule().findViewObject(view_inst_name);

if (v == null)
{
throw new OAException("Could not find View object instance " +
view_inst_name + " in root AM.");
}
if (v.getFetchedRowCount() == 0)
{
throw new OAException("There is no data to export.");
}
String file_name = "Export";
if (!((file_name_without_ext == null) ||
("".equals(file_name_without_ext))))
{
file_name = file_name_without_ext;
}
HttpServletResponse response =
(HttpServletResponse) pageContext.getRenderingContext().getServletResponse();
response.setContentType("application/text");
response.setHeader("Content-Disposition",
"attachment; filename=" + file_name + ".csv");
PrintWriter pw = null;

363
www.AppsLead.com
try
{
pw = response.getWriter();
int j = 0;
int k = 0;
boolean bb = true;
if ((max_size == null) || ("".equals(max_size)))
{
k = Integer.parseInt(pageContext.getProfile("VO_MAX_FETCH_SIZE"));
bb = false;
}
else if ("MAX".equals(max_size))
{
bb = true;
}
else
{
k = Integer.parseInt(max_size);
bb = false;
}

//Making header
AttributeDef[] a = v.getAttributeDefs();
StringBuffer cc = new StringBuffer();
ArrayList exist_list = new ArrayList();
for (int l = 0; l < a.length; l++)
{
boolean zx = true;
if (hidden_attrib_list != null)
{
for (int z = 0; z < hidden_attrib_list.length; z++)
{
if (a[l].getName().equals(hidden_attrib_list[z]))
{
zx = false;
exist_list.add(String.valueOf(a[l].getIndex()));
}
}
}
if (zx)
{
cc.append("\"" + a[l].getName() + "\"");
cc.append(",");
}
}
String header_row = cc.toString() + "\n";
pw.write(header_row);

for (OAViewRowImpl row = (OAViewRowImpl) v.first(); row != null;


row = (OAViewRowImpl) v.next())
{
j++;
StringBuffer b = new StringBuffer();
for (int i = 0; i < v.getAttributeCount(); i++)
{
boolean cv = true;
for (int u = 0; u < exist_list.size(); u++)
{
if (String.valueOf(i).equals(exist_list.get(u).toString()))
{
cv = false;
}
361
www.AppsLead.com
}

if (cv)
{
Object o = row.getAttribute(i);

if (!(o == null))
{
if (o.getClass().equals(Class.forName("oracle.jbo.domain.Date")))
{
//formatting of date
oracle.jbo.domain.Date dt = (oracle.jbo.domain.Date) o;
java.sql.Date ts = (java.sql.Date) dt.dateValue();
java.text.SimpleDateFormat displayDateFormat =
new java.text.SimpleDateFormat("dd-MMM-yyyy");
String convertedDateString = displayDateFormat.format(ts);
b.append("\"" + convertedDateString + "\"");
}
else
{
b.append("\"" + o.toString() + "\"");
}
}
else
{
b.append("\"\"");
}
b.append(",");
}
}
String final_row = b.toString() + "\n";
pw.write(final_row);
if (!bb)
{
if (j == k)
{
break;
}
}
}
}
catch (Exception e)
{
// TODO
e.printStackTrace();
throw new OAException("Unexpected Exception occured.Exception Details :" +
e.toString());
}
finally
{
pw.flush();
pw.close();
}
}

361
www.AppsLead.com
Giving download option to user for a file at a particular location on
Application Server
Hi All,
This is a very generic scenario where a user wants to download a particular file from application server. eg- We
are storing some report output or some pdf documents in particular location in unix application server. Now in a
OAF page on press of a button/link I wanna give user download option for this file.

For this requirement you can use following method, from process form request, u need to pass pagecontext and
other parameters as described in method.

//on button click in process form request


//call this method
downloadFileFromServer(
pageContext,--pagecontext
"/xx/xxx/ssss/120devg.pdf",--full file path with file name and ext
"120devg.pdf" --file name with extension
);

Make sure that the folder/files you are giving user option to download through this method, have 777 rights in
UNIX server.

Copy these two methods in your CO for the above API to work:
/**
* @param pageContext the current OA page context
* @param file_name_with_path - this is fully qualified file name with its path on unix application
* server. eg "/xxcrp/xxapplcrp/mukul/abc.pdf"
* @param file_name_with_ext - this is file name with extension, you wanna display user
* for download. eg- i wanna display the abc.pdf file download with name five_point_someone.pdf
* then I can pass this as "five_point_someone.pdf"
*/
public void downloadFileFromServer(OAPageContext pageContext,
String file_name_with_path,
String file_name_with_ext)
{
HttpServletResponse response =
(HttpServletResponse) pageContext.getRenderingContext().getServletResponse();
if (((file_name_with_path == null) ||
("".equals(file_name_with_path))))
{
throw new OAException("File path is invalid.");
}

File fileToDownload = null;


try
{
fileToDownload = new File(file_name_with_path);
}
catch (Exception e)
{
throw new OAException("Invalid File Path or file does not exist.");
}

if (!fileToDownload.exists())
{
throw new OAException("File does not exist.");
}

if (!fileToDownload.canRead())
{
throw new OAException("Not Able to read the file.");
}
360
www.AppsLead.com
String fileType = getMimeType(file_name_with_ext);
response.setContentType(fileType);
response.setContentLength((int)fileToDownload.length());
response.setHeader("Content-Disposition",
"attachment; filename=\"" + file_name_with_ext +
"\"");

InputStream in = null;
ServletOutputStream outs = null;

try
{
outs = response.getOutputStream();
in = new BufferedInputStream(new FileInputStream(fileToDownload));
int ch;
while ((ch = in.read()) != -1)
{
outs.write(ch);
}

}
catch (IOException e)
{
// TODO
e.printStackTrace();
}
finally
{
try
{
outs.flush();
outs.close();
if (in != null)
{
in.close();
}
}
catch (Exception e)
{
e.printStackTrace();
}
}
}

/**
* @param s
* @return file mime type from its name
*/
public String getMimeType(String s)
{
int i = s.lastIndexOf(".");
if (i > 0 && i < s.length() - 1)
{
String s1 = s.substring(i + 1);
if (s1.equalsIgnoreCase("amr"))
{
return "audio/amr";
}
if (s1.equalsIgnoreCase("mid"))
{
return "audio/midi";
}
363
www.AppsLead.com
if (s1.equalsIgnoreCase("mmf"))
{
return "application/vnd.smaf";
}
if (s1.equalsIgnoreCase("qcp"))
{
return "audio/vnd.qcelp";
}
if (s1.equalsIgnoreCase("hqx"))
{
return "application/mac-binhex40";
}
if (s1.equalsIgnoreCase("cpt"))
{
return "application/mac-compactpro";
}
if (s1.equalsIgnoreCase("doc"))
{
return "application/msword";
}
if (s1.equalsIgnoreCase("jsp"))
{
return "application/jsp";
}
if (s1.equalsIgnoreCase("oda"))
{
return "application/oda";
}
if (s1.equalsIgnoreCase("pdf"))
{
return "application/pdf";
}
if (s1.equalsIgnoreCase("ai"))
{
return "application/postscript";
}
if (s1.equalsIgnoreCase("eps"))
{
return "application/postscript";
}
if (s1.equalsIgnoreCase("ps"))
{
return "application/postscript";
}
if (s1.equalsIgnoreCase("ppt"))
{
return "application/powerpoint";
}
if (s1.equalsIgnoreCase("rtf"))
{
return "application/rtf";
}
if (s1.equalsIgnoreCase("bcpio"))
{
return "application/x-bcpio";
}
if (s1.equalsIgnoreCase("vcd"))
{
return "application/x-cdlink";
}
if (s1.equalsIgnoreCase("Z"))
{
return "application/x-compress";
362
www.AppsLead.com
}
if (s1.equalsIgnoreCase("cpio"))
{
return "application/x-cpio";
}
if (s1.equalsIgnoreCase("csh"))
{
return "application/x-csh";
}
if (s1.equalsIgnoreCase("dcr"))
{
return "application/x-director";
}
if (s1.equalsIgnoreCase("dir"))
{
return "application/x-director";
}
if (s1.equalsIgnoreCase("dxr"))
{
return "application/x-director";
}
if (s1.equalsIgnoreCase("dvi"))
{
return "application/x-dvi";
}
if (s1.equalsIgnoreCase("gtar"))
{
return "application/x-gtar";
}
if (s1.equalsIgnoreCase("gz"))
{
return "application/x-gzip";
}
if (s1.equalsIgnoreCase("hdf"))
{
return "application/x-hdf";
}
if (s1.equalsIgnoreCase("cgi"))
{
return "application/x-httpd-cgi";
}
if (s1.equalsIgnoreCase("jnlp"))
{
return "application/x-java-jnlp-file";
}
if (s1.equalsIgnoreCase("skp"))
{
return "application/x-koan";
}
if (s1.equalsIgnoreCase("skd"))
{
return "application/x-koan";
}
if (s1.equalsIgnoreCase("skt"))
{
return "application/x-koan";
}
if (s1.equalsIgnoreCase("skm"))
{
return "application/x-koan";
}
if (s1.equalsIgnoreCase("latex"))
{
366
www.AppsLead.com
return "application/x-latex";
}
if (s1.equalsIgnoreCase("mif"))
{
return "application/x-mif";
}
if (s1.equalsIgnoreCase("nc"))
{
return "application/x-netcdf";
}
if (s1.equalsIgnoreCase("cdf"))
{
return "application/x-netcdf";
}
if (s1.equalsIgnoreCase("sh"))
{
return "application/x-sh";
}
if (s1.equalsIgnoreCase("shar"))
{
return "application/x-shar";
}
if (s1.equalsIgnoreCase("sit"))
{
return "application/x-stuffit";
}
if (s1.equalsIgnoreCase("sv4cpio"))
{
return "application/x-sv4cpio";
}
if (s1.equalsIgnoreCase("sv4crc"))
{
return "application/x-sv4crc";
}
if (s1.equalsIgnoreCase("tar"))
{
return "application/x-tar";
}
if (s1.equalsIgnoreCase("tcl"))
{
return "application/x-tcl";
}
if (s1.equalsIgnoreCase("tex"))
{
return "application/x-tex";
}
if (s1.equalsIgnoreCase("textinfo"))
{
return "application/x-texinfo";
}
if (s1.equalsIgnoreCase("texi"))
{
return "application/x-texinfo";
}
if (s1.equalsIgnoreCase("t"))
{
return "application/x-troff";
}
if (s1.equalsIgnoreCase("tr"))
{
return "application/x-troff";
}
if (s1.equalsIgnoreCase("roff"))
367
www.AppsLead.com
{
return "application/x-troff";
}
if (s1.equalsIgnoreCase("man"))
{
return "application/x-troff-man";
}
if (s1.equalsIgnoreCase("me"))
{
return "application/x-troff-me";
}
if (s1.equalsIgnoreCase("ms"))
{
return "application/x-troff-ms";
}
if (s1.equalsIgnoreCase("ustar"))
{
return "application/x-ustar";
}
if (s1.equalsIgnoreCase("src"))
{
return "application/x-wais-source";
}
if (s1.equalsIgnoreCase("xml"))
{
return "text/xml";
}
if (s1.equalsIgnoreCase("ent"))
{
return "text/xml";
}
if (s1.equalsIgnoreCase("cat"))
{
return "text/xml";
}
if (s1.equalsIgnoreCase("sty"))
{
return "text/xml";
}
if (s1.equalsIgnoreCase("dtd"))
{
return "text/dtd";
}
if (s1.equalsIgnoreCase("xsl"))
{
return "text/xsl";
}
if (s1.equalsIgnoreCase("zip"))
{
return "application/zip";
}
if (s1.equalsIgnoreCase("au"))
{
return "audio/basic";
}
if (s1.equalsIgnoreCase("snd"))
{
return "audio/basic";
}
if (s1.equalsIgnoreCase("mpga"))
{
return "audio/mpeg";
}
364
www.AppsLead.com
if (s1.equalsIgnoreCase("mp2"))
{
return "audio/mpeg";
}
if (s1.equalsIgnoreCase("mp3"))
{
return "audio/mpeg";
}
if (s1.equalsIgnoreCase("aif"))
{
return "audio/x-aiff";
}
if (s1.equalsIgnoreCase("aiff"))
{
return "audio/x-aiff";
}
if (s1.equalsIgnoreCase("aifc"))
{
return "audio/x-aiff";
}
if (s1.equalsIgnoreCase("ram"))
{
return "audio/x-pn-realaudio";
}
if (s1.equalsIgnoreCase("rpm"))
{
return "audio/x-pn-realaudio-plugin";
}
if (s1.equalsIgnoreCase("ra"))
{
return "audio/x-realaudio";
}
if (s1.equalsIgnoreCase("wav"))
{
return "audio/x-wav";
}
if (s1.equalsIgnoreCase("pdb"))
{
return "chemical/x-pdb";
}
if (s1.equalsIgnoreCase("xyz"))
{
return "chemical/x-pdb";
}
if (s1.equalsIgnoreCase("gif"))
{
return "image/gif";
}
if (s1.equalsIgnoreCase("ief"))
{
return "image/ief";
}
if (s1.equalsIgnoreCase("jpeg"))
{
return "image/jpeg";
}
if (s1.equalsIgnoreCase("jpg"))
{
return "image/jpeg";
}
if (s1.equalsIgnoreCase("jpe"))
{
return "image/jpeg";
369
www.AppsLead.com
}
if (s1.equalsIgnoreCase("png"))
{
return "image/png";
}
if (s1.equalsIgnoreCase("tiff"))
{
return "image/tiff";
}
if (s1.equalsIgnoreCase("tif"))
{
return "image/tiff";
}
if (s1.equalsIgnoreCase("ras"))
{
return "image/x-cmu-raster";
}
if (s1.equalsIgnoreCase("pnm"))
{
return "image/x-portable-anymap";
}
if (s1.equalsIgnoreCase("pbm"))
{
return "image/x-portable-bitmap";
}
if (s1.equalsIgnoreCase("pgm"))
{
return "image/x-portable-graymap";
}
if (s1.equalsIgnoreCase("ppm"))
{
return "image/x-portable-pixmap";
}
if (s1.equalsIgnoreCase("rgb"))
{
return "image/x-rgb";
}
if (s1.equalsIgnoreCase("xbm"))
{
return "image/x-xbitmap";
}
if (s1.equalsIgnoreCase("xpm"))
{
return "image/x-xpixmap";
}
if (s1.equalsIgnoreCase("xwd"))
{
return "image/x-xwindowdump";
}
if (s1.equalsIgnoreCase("html"))
{
return "text/html";
}
if (s1.equalsIgnoreCase("htm"))
{
return "text/html";
}
if (s1.equalsIgnoreCase("txt"))
{
return "text/plain";
}
if (s1.equalsIgnoreCase("rtx"))
{
373
www.AppsLead.com
return "text/richtext";
}
if (s1.equalsIgnoreCase("tsv"))
{
return "text/tab-separated-values";
}
if (s1.equalsIgnoreCase("etx"))
{
return "text/x-setext";
}
if (s1.equalsIgnoreCase("sgml"))
{
return "text/x-sgml";
}
if (s1.equalsIgnoreCase("sgm"))
{
return "text/x-sgml";
}
if (s1.equalsIgnoreCase("mpeg"))
{
return "video/mpeg";
}
if (s1.equalsIgnoreCase("mpg"))
{
return "video/mpeg";
}
if (s1.equalsIgnoreCase("mpe"))
{
return "video/mpeg";
}
if (s1.equalsIgnoreCase("qt"))
{
return "video/quicktime";
}
if (s1.equalsIgnoreCase("mov"))
{
return "video/quicktime";
}
if (s1.equalsIgnoreCase("avi"))
{
return "video/x-msvideo";
}
if (s1.equalsIgnoreCase("movie"))
{
return "video/x-sgi-movie";
}
if (s1.equalsIgnoreCase("ice"))
{
return "x-conference/x-cooltalk";
}
if (s1.equalsIgnoreCase("wrl"))
{
return "x-world/x-vrml";
}
if (s1.equalsIgnoreCase("vrml"))
{
return "x-world/x-vrml";
}
if (s1.equalsIgnoreCase("wml"))
{
return "text/vnd.wap.wml";
}
if (s1.equalsIgnoreCase("wmlc"))
371
www.AppsLead.com
{
return "application/vnd.wap.wmlc";
}
if (s1.equalsIgnoreCase("wmls"))
{
return "text/vnd.wap.wmlscript";
}
if (s1.equalsIgnoreCase("wmlsc"))
{
return "application/vnd.wap.wmlscriptc";
}
if (s1.equalsIgnoreCase("wbmp"))
{
return "image/vnd.wap.wbmp";
}
if (s1.equalsIgnoreCase("css"))
{
return "text/css";
}
if (s1.equalsIgnoreCase("jad"))
{
return "text/vnd.sun.j2me.app-descriptor";
}
if (s1.equalsIgnoreCase("jar"))
{
return "application/java-archive";
}
if (s1.equalsIgnoreCase("3gp"))
{
return "video/3gp";
}
if (s1.equalsIgnoreCase("3g2"))
{
return "video/3gpp2";
}
if (s1.equalsIgnoreCase("mp4"))
{
return "video/3gpp";
}
}
return "application/octet-stream";
}

371
www.AppsLead.com
PopUp Window Using PopupBean Programetically

In Process Request

OAPopupBean popupBean =(OAPopupBean)createWebBean(pageContext,POPUP_BEAN,null,"myPopup");


//Set the following properties on the pop-up:
popupBean.setID("myPopup");
popupBean.setUINodeName("myPopup");
String popupRegion= "/oracle/apps/fnd/framework/toolbox/labsolutions/webui/TestEmpDetailsRN" ;
popupBean.setRegion(popupRegion);
popupBean.setHeight("130");
popupBean.setWidth("320");
popupBean.setTitle("Test");
popupBean.setType(EMBEDDED_POPUP); /* Embedded type */

370
www.AppsLead.com
Opening a POP UP window in OAF

There was a requirement to show a POP UP window which opens a static html file when a perticular OAF page is
displayed. To achieve this sort of requirement wherein a window needs to be opened automatically each time
visiting a page do the followings,

1. Create your html file and put it in $OA_HTML in OA Application tier.


2. Bounce Apache
3. Turn on the personalization at your user level in Oracle apps through profile option: Personalize Self-Service
Defn
4. Go the the page where you want the AUTO POP UP window to be opened > Click "Personalize Page" link at
upper right corner > Select the "Complete View" radio button
5. In the Page Layout (as the POP UP window needs to be opened when this page opens) for this page click the
"Create Item" link
6. In the create Item window do the followings,
Level: Depending on your requirement (If all the time then Function level otherwise Site level)
Item Style: "Raw Text"
ID: Enter an unique item ID e.g. (XX_WELCOME)
Text:"window.open('http://YOUR_ORACLE_APP_HOST:PORT_NUMBER/OA_HTML/your_html.html','WINDOW_TI
TLE','ATTRIBUTES');"
In the above string replace the following with your implementation,
YOUR_ORACLE_APP_HOST: This will be your application URL through which you access oracle apps
PORT_NUMBER: Your Application server PORT number
your_html: This is your HTML file name
WINDOW_TITLE: Enter your window title here
ATTRIBUTES: POP UP Window attributes like scrollbars=yes, resizable=yes etc

Put the above in script tag otherwise it would not work. Somehow this site is removing those tags from my post
may be due to security reasons.

7. Save your seetings.


8. POP UP window should open now whenever you go the above page. If it does not open then check your POP
UP blocker setting and allow your application in the list.

373
www.AppsLead.com
Dynamically changing multiselect to single select in Table in OAF

I would like to share a small piece of code, which recently a friend shared with me, this is a typical requirement,
which might look too trivial at first shot, but is quite easy to implement. Suppose you have a table where in you
have a requirement to have single or multi selection based on a dynamic conditon eg, some selection or press of
a button you wanna change the multiselection to single selection and vice versa.

In such scenario, in the action of the event you redirect to same page and use following code in process request
on the base of parameter you set in session/pagecontext :
// Hiding the Multiple Select Table Action and add single selection
OAAdvancedTableBean tabBean = (OAAdvancedTableBean)webBean.
findIndexedChildRecursive("[table item id]");

//Since the multiselect is at the end, get the total count -1 for removing
int count = tabBean.getIndexedChildCount(pageContext.getRenderingContext());
System.out.println("Child Count "+count);
tabBean.removeIndexedChild(count-1);

OAMultipleSelectionBean sel = (OAMultipleSelectionBean)tabBean.getTableSelection();


OASingleSelectionBean singleSelection = new OASingleSelectionBean() ;
singleSelection.setText("Select");

//Set the attribute for the single select


singleSelection.setViewAttributeName("SelectFlag");
tabBean.setTableSelection(singleSelection);

372
www.AppsLead.com
Attaching AutoSubmit Property to a OA page.

Hi All,
I recently received couple of mails where people more or less have the requirement like :
1) Data of the page gets refresh every 10 sec automatically.
2) Data of the page should be autosaved every 10 seconds etc.

This is very similar to autosave feature of microsoft word or popular email websites like yahoo and google. A
small javascript function can do this for you.Here are the steps how, you can achieve this functionality in an OAF
page :

/**
* @param pageContext -current page context in CO
* @param evt_name - javascript event will be registered with this name.
* @param time_in_milli_sec - time in milli sec after which page will refresh
* e.g if you wanna submit page every 10 sec , enter 10000
* This api should be used in process request and not process form request.
*/
public void attachAutoSubmitPropertyToPage(OAPageContext pageContext,
String evt_name,
String time_in_milli_sec)
{
OABodyBean bodyBean = (OABodyBean) pageContext.getRootWebBean();
String javaS =
"javascript:setTimeout(\"submitForm('DefaultFormName',0,{'" +
evt_name + "':'Y'});\"," + time_in_milli_sec + ");";
bodyBean.setOnLoad(javaS);
}

/**
* @param pageContext -current page context in CO
* @param event_name - pass javascript event name that you registered
* in process request.
* @return return true/false accordinging whether the event has occured or not.
* This api call should be there in process form request.
*/
public boolean isAutoSubmitEvent(OAPageContext pageContext,
String event_name)
{
boolean b = false;
String s =
pageContext.getRenderingContext().getServletRequest().getParameter(event_name);
if (!((s == null) || ("".equals(s.trim()))))
{
if("Y".equals(s))
{
b = true;
pageContext.removeParameter(event_name);
}
}
return b;
}

Then , in process request add the api call

public void processRequest(OAPageContext pageContext, OAWebBean webBean)


{
super.processRequest(pageContext, webBean);
// see javadocs for parameter description
//10000 for 10 sec as we are paaing in millsec
attachAutoSubmitPropertyToPage(pageContext,"XX_EVT","10000");

376
www.AppsLead.com
.
.
.
}

In process form request... you can catch this event in every 10 sec:
public void processFormRequest(OAPageContext pageContext,
OAWebBean webBean)
{
super.processFormRequest(pageContext, webBean);
.
.

if(isAutoSubmitEvent(pageContext,"XX_EVT"))
{
// YOUR LOGIC TO SAVE THE PAGE CONTENTS.
//or to refresh the data... etc
}

377
www.AppsLead.com
In this article, I will explain seven different methods to debug OA Framework pages in Oracle eBusiness Suite.
Each of these methods are explained using working Audio-Video demo, hence you will need your headphones.
Some of these techniques are applicable when running the Framework pages from jDeveloper, whereas other
debugging techniques apply when debugging OA Framework Pages from eBusiness Suite responsibility.

Each method of debugging OA Framework pages has its own merits, and hence you must apply one of the
techniques that suites the most to your situation.

1. Use System.out.println
When running the OA Framework pages from jDeveloper itself, you can write debug messages using
System.out.println.
These debug messages will be displayed in the console of jDeveloper.
Pro
* Ease of use, as you simply enter free text messages
* Debug messages simply appear without the need to set any profile options
Cons
* Too much typing, which can be avoided when using the debugger of jDeveloper.
* You can debug only those pieces of code that you suspect are causing the error. Unlike to this approach,
using jDeveloper debugging, breakpoints can be set for exceptions/classes as well.

Click here to see a quick working demo for debuging OA Framework using System.out.println

2. Use jDeveloper inbuilt Debugger


This happens to be my favourite mechanism to debug OA Framework Pages, for the following reasons
Pro
* To get started just one breakpoint is required, as more and more breakpoints can be added in runtime
itself.
* You can set generic breakpoints, for example, you can set breakpoint on exceptions, which will take you
to the exact line of code from where the exception was being raised
* jDeveloper makes it possible to try different scenarios, for example, you can change the variable values at
runtime
Cons
* Given that you do not have source code of base classes, debugger usually dives into those classes without
giving many visible details. One may find this annoying.
* Some versions of OAFwk raise exceptions[caught internally by Oracle] like Classcast exception even before
the page renders.
Debugger often pauses when those exceptions are raised. This can be overcome by clicking on “resume
button” of debugger.

Click here for demo of debugging via jdeveloper debugger


The demo in above link also shows how you can change the variable values at runtime.

Click here for demo of using debugger to trap classcast exceptions


The demo in above link shows how you can set breakpoints for specific Exceptions that can be raised from OA
Framework Pages

3. Use jDeveloper debugging feature, by changing Java VM runtime option Djbo.debugoutput


Lets say, for this exercise, I wish to find the exact piece of SQL Statement that my screen fires, when doing an
update.
374
In order to do so, we can append text -Djbo.debugoutput=console to runner property
www.AppsLead.com
As shown below, I can enter the following text in Runner property of jDeveloper

Have a look at this demo to visually see this debugging technique

4. Use the FND Debug Logging feature, to see debug messages on the OA Framework Screen itself
The debug messages can either been seen on the same screen or those can be spooled into a table named
FND_LOG_MESSAGES
In jDeveloper, you must include OADiagnostic in the “Run Options”.
This is effectively similar to setting profile option “FND Diagnostics” to Yes in eBusiness Suite.
Using this option, you will be able to click on Diagnostics to enable On-Screen display of debug messages.

Pro
* The debug messages seen using this technique are exactly the same as the debug messages seen in
eBusiness Suite, once FND%Log% profile options are available.
* There is tremendous amount of debug messages in FND classes given by Oracle.
* This approach is the most useful when investigating red coloured error message “Please contact your
system administrator”
Cons
* Prior to 11.5.10, this option might bring your application session down to its knee. But I notice from 11.5.10
onwards, these debug messages are captured very efficiently.
* The debugging is limited to the debug messages in place. To maximise the listing of debug messages, try to
use statement level debugging.

Click here for the demo of doing on-screen debugging for OA Framework pages

5. SQL Trace for Oracle Framework Sessions


We often use this technique for tracing the SQL statements executed by Oracle Forms or by concurrent
programs.
The same technique can be applied to OA Framework too.
You can run the SQL*Trace either when running the application pages from “OA Framework” or when running
OA Framework pages from within eBusiness Suite.
For jDev, ensure that OA Diagnostics has been included in jDeveloper Project property “Run Options”.
Alternately ensure that profile option “FND Diagnostics” has been setup against your username.

Click here for the demo of SQL*Trace on OA Framework Pages

6. Use FND Logging profile options to capture debug messages into a table named FND_LOG_MESSAGES
Use the FND Debug Logging feature, to see debug messages.

379
www.AppsLead.com
The debug messages can either been seen on the same screen or those can be spooled into a table named
FND_LOG_MESSAGES

Please click on this link to see an article on FND Logging

7. Use raiseDeveloperException.
I had all but forgotten about this technique, until I discussed this paper with Mr Senthil prior to its publication.
He reminded of raiseDeveloperException. You can raise debug messages to be displayed in OA Framework pages
using raiseDeveloperException.
By doing so, your debug messages will be visible onto the top portion of the screen.
This is very similar to System.out.println, however the key difference being that raiseDeveloperException displays
the debug message on top portion of the page itself.
Pro
* Ease of use, as you simply enter free text messages
* Debug messages simply appear without the need to set any profile options
* Debug messages appear on the top portion of the page and hence the ease of visibility when testing your
code in jDeveloper
Cons
* Too much typing, which can be avoided when using the debugger of jDev.
* You can debug only those pieces of code that you suspect are causing the error.

Click here for the working demo of this technique to debug OA Framework Page.

Adding Custom Html code to the OAF Page

Step1: - Import the OARawTextBean in the controller so we will be able to create handles for it. Import the
OARawTextBean bean as shown below.
import oracle.apps.fnd.framework.webui.beans.OARawTextBean;
Step2: - In the processrequest method create a handle for the OARawTextBean and create a String to write the
HTML code in it.

OARawTextBean trialRawTextBean = (OARawTextBean)webBean.findChildRecursive(“xxTrialRawTextBean “);


String theHtmlCode = "<html><body><p style= \"font-family:Arial,Helvetica,Geneva,sans-serif:font-
size:10pt;color:blue\">This is an example to to show how to add the custom html code to the OAF page
"+"</p></body></html>"

Step3:- Set the String variable as the text to the OARawTextBean as shown below and run the page
trialRawTextBean.setText(theHTMLCode);

Step4:- You should be able to see the Text that you have written as shown below in your OAF Page.

343
www.AppsLead.com
Customizing Standard LOV using OAF Extension

https://blogs.oracle.com/manojmadhusoodanan/entry/customizing_standard_lov_using_oaf

341
www.AppsLead.com
Download BLOB File from Database
Below code used to download BLOB File from database.

Write Below Code Under Event ..

String MimeType=null,FileName=null;
String Rowref=pageContext.getParameter(EVENT_SOURCE_ROW_REFERENCE);
OtherReportRequestVORowImpl row=(OtherReportRequestVORowImpl)am.findRowByRef(Rowref);
try {
String Query=" SELECT 'text/plain' MIME_TYPE, xxebex.xxebex_public.CLOB_TO_BLOB(REQUEST_LOG),
'InfoRequest_'||REQUEST_ID||'_ProcessLog.html' FILE_NAME"+
" FROM xxebex.ebex_info_requests WHERE request_id ='"+row.getRequestId()+"'";
PreparedStatement
cs=(PreparedStatement)am.getOADBTransaction().getJdbcConnection().prepareStatement(Query);
ResultSet rs=cs.executeQuery();
while(rs.next())
{
java.sql.Blob blob;
blob = rs.getBlob(2);
MimeType=rs.getString(1);
FileName=rs.getString(3);
int iLength = (int)(blob.length());
System.out.println("Length:"+iLength);
response.setHeader("Content-Disposition", "attachment; filename=\""+FileName+"\"");
response.setContentType(MimeType);
response.setContentLength(iLength);
ServletOutputStream op = response.getOutputStream();
op.write(blob.getBytes(1, iLength));
op.flush();
op.close();

}
catch(Exception e) {
System.out.println(e.getMessage());
}

341
www.AppsLead.com
Create Items Programetically
If You want to Create Any Item Or Region Dynamically Code Has to be written In Only Process request.These
Items Doesn't Appear in the Structure Pane.

OAStackLayoutBean oastacklayoutbean=(OAStackLayoutBean)webBean.findIndexedChildRecursive("region2");
// Initialization of StackLayout

OAMessageTextInputBean
oamessagetextinputbean=(OAMessageTextInputBean)createWebBean(pageContext,OAWebBeanConstants.MES
SAGE_TEXT_INPUT_BEAN,null,"XX");

/*Creation MessagetextInputBean And Setting Prompt */

oamessagetextinputbean.setPrompt("YY");
oastacklayoutbean.addIndexedChild(oamessagetextinputbean);// adding item to the StackLayout
OAMessageCheckBoxBean
oamessagecheckboxbean=(OAMessageCheckBoxBean)createWebBean(pageContext,OAWebBeanConstants.MES
SAGE_CHECKBOX_BEAN,null,"YY");

oastacklayoutbean.addIndexedChild(oamessagecheckboxbean);

340
www.AppsLead.com
Color The Item Based on Employee Position in Advanced table

Step 1:

Create EO Based VO i.e,EMPVO

SELECT EMPEo.EMPNO,

EMPEo.ENAME,

EMPEo.JOB,

EMPEo.MGR,

EMPEo.HIREDATE,

EMPEo.SAL,

EMPEo.COMM,

EMPEo.DEPTNO,

EMPEo.CREATION_DATE,

EMPEo.CREATED_BY,

EMPEo.LAST_UPDATE_DATE,

EMPEo.LAST_UPDATE_LOGIN,

EMPEo.LAST_UPDATED_BY,

EMPEo.ROWID,DECODE (EMPEo.JOB

,'MANAGER', '1','2'

) color

FROM EMP EMPEo

Step 2:Under Custom.xss

add Follwing code

<style name="For_Bold">

<property name="font-weight">bold</property>

<property name="font-size">10pt</property>

</style>

<style selector=".1">

<includeStyle name="DefaultFamily"/>

<property name="font-size">11pt</property>

<property name="font-weight">Bolder</property>

<property name="color">#FFFF00</property>

343
www.AppsLead.com
<property name="text-indent">3px</property>

<property name="background-color">#FF0000</property>

</style>

<style selector=".2">

<includeStyle name="DefaultFontFamily"/>

<property name="font-size">11pt</property>

<property name="font-weight">Bolder</property>

<property name="color">#FFFF00</property>

<property name="text-indent">3px</property>

<property name="background-color">#003399</property>

</style>

the path of the custom.xss is in $OA_HTML/cabo/Styles/custom.xss

Under Process Request:

OAApplicationModule am=( OAApplicationModule) pageContext.getApplicationModule(webBean);

EMPVOImpl vo=am.getEMPVO1();

vo.executeQuery();

OAAdvancedTableBean table = (OAAdvancedTableBean)webBean.

findIndexedChildRecursive("region2");

OAColumnBean ejobcol = (OAColumnBean)webBean.

findIndexedChildRecursive("column1");

OAMessageTextInputBean job = (OAMessageTextInputBean)ejobcol.

findIndexedChildRecursive("item1");--for which item you wanted color

OADataBoundValueViewObject cssjob = new OADataBoundValueViewObject(job,"Color");

job.setAttributeValue(oracle.cabo.ui.UIConstants.STYLE_CLASS_ATTR, cssjob);

O/P will be like:

342
www.AppsLead.com
346
www.AppsLead.com
Dynamic Color change in OA Framework

I am going to create a search page which shows the details of vendor checks which we have given against his

invoices. In this I have a requirement I want to show the "Void" checks in “Red” color and rest of then in

"Yellow". We will achieve this by style sheet which is under “JDEVHOME” Directory. WE will do changes in the

“CUSTOM.xss” file. we will customize this file. I will explain this as creating a new project.

1.First we will create a work space to start our project .

WorkSpace Name:- RohitOafColor.

Right Click on "Applications".Click on "NewOAWorkspace".

Enter the name of Workspace="RohitOafColor".Click Ok

347
www.AppsLead.com
Project wizard will open as below click next.

Enter the name of the Project="RohitOafColor".

Default Package= "rohit.oracle.apps.fnd.RohitOafColor"

Package determines the directory where the java class files and other files related to this project strored.

In this directory oracle.apps.fnd must be required."fnd" is the oracle application shortname you can use other

applications like "ak" in this.

344
www.AppsLead.com
Enter the RunTime connection details as below.Enter the E-business Suit Application User Name and

Password.(already explained in the JDev installation)

349
www.AppsLead.com
Workspace and project has been created as below.

393
www.AppsLead.com
Now our next step is to create a "Application Module" for the OAF Page

Right Click on the project "RohitOafColor".Click New

Application Module wizard has open as below click next

391
www.AppsLead.com
Enter the Application Module name="RohitOafColorAM"

Defualt Package="rohit.oracle.apps.fnd.RohitOafColor.server"

we create "Application module" under the "Server" directory of the project as OAF Standard.

Click next and then finish.

391
www.AppsLead.com
Application Module has created as below

390
www.AppsLead.com
Now to create a search page we need to create a View Object(VO).

Create a View Object(VO).

Right Click on the project "RohitOafColor".Click New

Click on View Object and then OK.

393
www.AppsLead.com
Enter the View Object name="ChecksVO"

Default Package="rohit.oracle.apps.fnd.RohitOafColor.server"

we create "View Object" under the "Server" directory of the project as OAF Standard.

392
www.AppsLead.com
Click next next and go to step 5 "SQL Statement".

396
www.AppsLead.com
select BANK_ACCOUNT_NAME,VENDOR_NAME,amount,STATUS_LOOKUP_CODE,

decode(STATUS_LOOKUP_CODE,'VOIDED','1','2') STATUS from ap_checks_all

Click Next and the Finish.View Object(VO) has created as below.

Now we will attach this View Object(VO) with Application Module(AM).

So that Right Click on "Application Moduel" click "EditRohitOafColorAM".

397
www.AppsLead.com
Then Shuttle the View Object "CheckVO" to the right.

394
www.AppsLead.com
Now we create a OAF Page as below

Right Click on the Project "RohitPopList".Click New.

Click on the Page.Click on ok Button

399
www.AppsLead.com
Enter the Page Name="RohitOafColorPG"

Default Package="rohit.oracle.apps.fnd.RohitOafColor.webui"

we create the page under the Webui under the project directory

Click Ok Page has been created.

When you click the "RohitOafColorPG" Below structure pane has dispayed the region1.

233
www.AppsLead.com
Click on the "Region1".On the right hand side In the property inspector we will set the AM for the this page

AM=rohit.oracle.apps.fnd.RohitOafColor.server.RohitOafColorAM

As well as we also set other Properties.

1.Window Title=Any name

2.Title=OAF Color

231
www.AppsLead.com
Right Click on the "Region1" and then new and then click region.

231
www.AppsLead.com
Then Region2 has created under "Region1" as below.

230
www.AppsLead.com
Click on the "Region2".On the right hand side In the property inspector we will set some properties.

Region Style=query.

Construction Mode=resultsbasedsearch.

233
www.AppsLead.com
Now Right Click on the "Region2" and then new and then click region.

232
www.AppsLead.com
Then "Region3" has creted under "Region2".

Click on "Region3" and then go to right hand side in the "Property Inspector".Replace the name of "Region3" with

"ChecksVO" and region style "table".

ID=ChecksVO.

Region Style=table

236
www.AppsLead.com
Now right click on "ChecksVO".Click New=>Click Item

237
www.AppsLead.com
Then Item1 has created under region "ChecksVO".

Now Click on "Item1" and then go to right hand side in the "Property Inspector".Replace the name of "Item1"

with "BankAccountName" and Item style "messagestyledtext".

ID= BankAccountName

Item Style="messagestyledtext"

View Instance=ChecksVO

View Attribute=BankAccountName

234
www.AppsLead.com
Then Below item with named "BankAccountName" has created as below.

239
www.AppsLead.com
Same Like above create another 3 items.and set the property as below.

For Item1

ID=VendorName

Item Style=messagestyledtext.

Search Allowed=True

View Instance=ChecksVO

View Attribute=VendorName

For Item2

ID=Amount

Item Style=messagestyledtext.

View Instance=ChecksVO

View Attribute=Amount

213
www.AppsLead.com
For Item3

ID=StatusLookupCode

Item Style=messagestyledtext.

View Instance=ChecksVO

View Attribute=StatusLookupCode

Now we will start our coding Part.To write a code we have to create "Controller" as below.

Right Click on "Region1" and then Select "Set New Controller".

211
www.AppsLead.com
Enter the Controller Name="RohitOafColorCO"

Package="rohit.oracle.apps.fnd.RohitOafColor.webui"

According to the OAF standard controller has creater under the webui of the project directory as shown above.

Click Ok.

211
www.AppsLead.com
The Code is Here:-

Import Classes:

import oracle.apps.fnd.common.VersionInfo;

import oracle.apps.fnd.framework.webui.OAControllerImpl;

import oracle.apps.fnd.framework.webui.OADataBoundValueViewObject;

import oracle.apps.fnd.framework.webui.OAPageContext;

import oracle.apps.fnd.framework.webui.beans.OAWebBean;

import oracle.apps.fnd.framework.webui.beans.message.OAMessageStyledTextBean;

import oracle.apps.fnd.framework.webui.beans.table.OAAdvancedTableBean;

import oracle.apps.fnd.framework.webui.beans.table.OAColumnBean;

import oracle.apps.fnd.framework.webui.beans.table.OATableBean;

Put the below code under the "Process Request" block of the Controller.

super.processRequest(pageContext, webBean);

OATableBean table = (OATableBean)webBean.

findIndexedChildRecursive("ChecksVO");

OAMessageStyledTextBean job = (OAMessageStyledTextBean)table.

findIndexedChildRecursive("StatusLookupCode");

OADataBoundValueViewObject cssjob = new OADataBoundValueViewObject(job,"Status");

job.setAttributeValue(oracle.cabo.ui.UIConstants.STYLE_CLASS_ATTR, cssjob);

210
www.AppsLead.com
Now Right Click on Project "RohitOafColor" => Click Rebuild.

Now Right Click on Project "RohitOafColor" => Click Run.

OUTPUT IS BELOW .

213
www.AppsLead.com
212
www.AppsLead.com
Java date manipulation Notes

java.util.Date minDate = new


java.util.GregorianCalendar(2010,java.util.GregorianCalendar.MARCH,01).getTime(); // 1st mar 2010
java.util.Date maxDate = new
java.util.GregorianCalendar(2020,java.util.GregorianCalendar.MARCH,01).getTime(); // 1st mar 2020

java.util.Date defDate = new java.util.Date(); // Two months ago

Calendar cal = Calendar.getInstance();


cal.add(Calendar.MONTH,-2);
defDate = cal.getTime();

ti.setMinValue(minDate);
ti.setMaxValue(maxDate);
ti.setValue(defDate);

Use c.add(Calendar.DATE, 1); to add days

Add Year
Date nd = p_ItemLine.getDate();
java.text.DateFormat formatter = null;
formatter = new java.text.SimpleDateFormat("dd");
String sDay = formatter.format(nd);
formatter = new java.text.SimpleDateFormat("MM");
String sMon = formatter.format(nd);
formatter = new java.text.SimpleDateFormat("yyyy");
String sYear = formatter.format(nd);
Date newDate = new java.util.GregorianCalendar(Integer.parseInt(sYear),Integer.parseInt(sMon)-
1,Integer.parseInt(sDay),11,22).getTime();

Convert Date to Text


java.text.DateFormat formatter = new java.text.SimpleDateFormat("dd-MMM-yyyy");
String s = formatter.format(defDate);

Pause Delay Wait


Calendar cal = Calendar.getInstance();
cal.setTime(new Date());
cal.add(Calendar.SECOND,2);
while (new Date().compareTo(cal.getTime())<0) {};

To and From sqlite


protected String sqliteDateStatement(Date p_in) {
//YYYY-MM-DD HH:MM:SS.SSS
if (p_in==null) return "'NULL'";
SimpleDateFormat formatter = new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
return "DATETIME('" + formatter.format(p_in) + "')";
}
protected Date sqliteDateVar(String p_in) throws ParseException {
//p_in format = 2012-09-30 16:33:41
if ("NULL".equals(p_in)) return null;
SimpleDateFormat formatter = new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm");
return (Date) formatter.parse(p_in);
}

To and From xml

216
www.AppsLead.com
(Using javax.xml.bind.DatatypeConverter)

protected Date xmlDateVar(String p_in) throws ParseException {


if ("NULL".equals(p_in)) return null;
Calendar cal = DatatypeConverter.parseDateTime(p_in);
return cal.getTime();
//SimpleDateFormat formatter = new java.text.SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS");
//return (Date) formatter.parse(p_in);
}
protected String xmlDateString(Date p_in) {
//XML Date format = 2008-10-31T15:07:38.6875000-05:00
if (p_in==null) return "'NULL'";
Calendar cal=Calendar.getInstance();
cal.setTime(p_in);
return DatatypeConverter.printDateTime(cal);
//SimpleDateFormat formatter = new java.text.SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS");
//return formatter.format(p_in);
}

Cheat Sheet http://www.ecotronics.ch/webdesign/javadate.htm

Formatting
SimpleDateFormat formatter = new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");

Number Formatting in OAF

Call this method from ProcessRequest (-----,------) method

private void setNumberFormatter(OAPageContext pageContext, OAWebBean webBean)


{
Formatter formatter = new OADecimalValidater("$#,##0.00;($#,##0.00)", "$#,##0.00;($#,##0.00)");
OAMessageStyledTextBean sumOfColumn =
(OAMessageStyledTextBean)webBean.findChildRecursive("SumOfInvoices");//Id of the Item
OAColumnBean sumColumnBean =
(OAColumnBean)webBean.findIndexedChildRecursive("SumOfInvoicesColumn"); // Id of the Column
if (sumOfColumn != null)
{
sumOfColumn.setAttributeValue(ON_SUBMIT_VALIDATER_ATTR, formatter);
sumOfColumn.setAttributeValue(CURRENCY_CODE,"USD");
sumColumnBean.setAttributeValue(CURRENCY_CODE,"USD");
sumColumnBean.setAttributeValue(ON_SUBMIT_VALIDATER_ATTR, formatter);
}
OAMessageStyledTextBean totInvoiceAmount =
(OAMessageStyledTextBean)webBean.findChildRecursive("TotalInvoiceAmount");
OAColumnBean totInvoiceColumnBean =
(OAColumnBean)webBean.findIndexedChildRecursive("TotalInvoiceAmountColumn");
if (totInvoiceAmount != null)
{
totInvoiceAmount.setAttributeValue(ON_SUBMIT_VALIDATER_ATTR, formatter);
totInvoiceAmount.setAttributeValue(CURRENCY_CODE,"USD");
totInvoiceColumnBean.setAttributeValue(CURRENCY_CODE,"USD");
totInvoiceColumnBean.setAttributeValue(ON_SUBMIT_VALIDATER_ATTR, formatter);
}
}

217
www.AppsLead.com
Changing the Total Label in OAF

Call this method from processRequest(---,----) Method

private void setReportSumText(OAPageContext pageContext, OAWebBean webBean)


{
OAAdvancedTableBean advancedTableBean =
(OAAdvancedTableBean)webBean.findIndexedChildRecursive("BuyerTableRN");
advancedTableBean.prepareForRendering(pageContext);
if (advancedTableBean != null)
{
OATableFooterBean tableFooterBean = (OATableFooterBean)advancedTableBean.getFooter();
if(tableFooterBean != null)
{
OATotalRowBean totalRowBean = (OATotalRowBean)tableFooterBean.getTotal();
if(totalRowBean != null)
{
totalRowBean.setText("Report-Sum");
}
}
}
}

214
www.AppsLead.com
Record History on OAF Page

Sometimes, there is a requirement when a user wants to see data about a particular record, such as who created
the record and when, and who most recently updated the record and when (For example, a manager wants to
check when and by whom an invoice line was last updated).

This feature can be enabled on OAF page, which adds the record history icon to the component (Header, Table or
Advanced Tables). Clicking the icon opens a popup window that displays the WHO column values of the current
row.

Note: This feature works only for non-PL/SQL based updateable ViewObjects. Also, to use this feature, profile
option 'FND: Record History Enabled' must be set.

Record history information is generally saved in the "WHO columns" of the database tables and are linked to an
OAF page through BC4J Entity Objects (EOs). These WHO columns are as follows:
Name of the user who created the row (CREATED_BY)
Date of creation (CREATION_DATE)
Name of user who updated the row (LAST_UPDATED_BY)
Date when row was last updated (LAST_UPDATED).

The Header, Table and Advanced Table components have a property - Record History Enabled which can be set
to true or false. We can set this either from JDeveloper or from 'Personalize Page' link from front end as shown
below:

Now when we open the page, it will show 'Record History' icon as show below:

On clicking the icon, a popup will open showing WHO column values of the current row:

219
www.AppsLead.com
The Record History window displays the OARecordHistoryRN.xml region. The region also has an associated
controller - OARecordHistoryCO.java.
When Record History window is called, the root application module of the calling page is retained and then from
processRequest() method of OARecordHistoryCO, WHO column values are read from the EnityObject using
history methods (like eo.getAttribute("CreatedBy");).

213
www.AppsLead.com
OAException Message and Dialog Page in OA Framework
You can use OAException (or any of its subclasses) to display a message on an OA Framework page and the OA
Framework automatically displays an error message at the top of the current page.

You can display the following standard kinds of messages at the top of a page:

 Error
 Warning
 Confirmation
 Information

You can explicitly display a message box of any type using the following code in your controller.

1 OAException message = new OAException("You cannot create a new change order when a Draft version

2 already exits.",OAException.ERROR);
pageContext.putDialogMessage(message)

Here you need to construct an oracle.apps.fnd.framework.OAException object and set the kind of message you
want (other options are OAException.WARNING, OAException.INFORMATION and OAException.CONFIRMATION).
Then you can simply identify this exception for display when the page renders by calling the
OAPageContext.putDialogMessage() method.

If — after you call putDialogMessage() in your processFormRequest() method — you want to forward to the
current page or another page and display the message at the top of the new target page, you need to call the
appropriate oracle.apps.fnd.framework.webui.OAPageContext forwardImmediately*() method. The OA
Framework immediately stops processing the page and issues a forward before displaying the messages.

You can register or throw multiple exceptions; the OA Framework combines them into a single message box
using the following rules:

 Since an error is more important than a warning, the message box is titled “Error” if both errors and
warnings exist.
 Confirmations and errors cannot be shown together. In this case, the OA Framework simply ignores the
confirmation message(s).
 You can, however, show confirmations with warnings. The message box is titled “Confirmation,” and it
contains both types of messages.

Show the Exception Message on a Dialog Page

You can display an exception as a message in a dialog page using the APIs in the
oracle.apps.fnd.framework.webui.OADialogPage class and oracle.apps.fnd.framework.webui.OAPageContext
interface.

211
www.AppsLead.com
The OADialogPage class holds properties for the generic dialog page. To create a dialog page object, first use the
constructors to instantiate the basic properties, then use the setter methods provided in the class to set
additional properties.

To navigate (redirect) to a dialog page, use the OAPageContext.redirectToDialogPage methods. The


OAPageContext interface contains the context and state information specific for a client request.

// To Diaplay the Exception on a Dialog page

OAException message = new OAException("You cannot create a new change order when a Draft version already
exits.");

OADialogPage dialogPage = new OADialogPage(OAException.ERROR, message, null, "",null);

dialogPage.setOkButtonToPost(true);

dialogPage.setOkButtonLabel("Ok");

dialogPage.setPostToCallingPage(true);

java.util.Hashtable formParams = new java.util.Hashtable(1);

dialogPage.setFormParameters(formParams);

pageContext.redirectToDialogPage(dialogPage);

// To Diaplay the Exception on a Dialog page

OAException message = new OAException("You cannot create a new change order when a Draft version
already exits.");

OADialogPage dialogPage = new OADialogPage(OAException.ERROR, message, null, "",null);

dialogPage.setOkButtonToPost(true);

dialogPage.setOkButtonLabel("Ok");

dialogPage.setPostToCallingPage(true);

java.util.Hashtable formParams = new java.util.Hashtable(1);

dialogPage.setFormParameters(formParams);

pageContext.redirectToDialogPage(dialogPage);

If you want 1 buttons (Say Cancel and Ok), then put “” instead of null in the OADialogPage dialogPage = new
OADialogPage line.

211
www.AppsLead.com
How to make an OAF Page Read Only?

Sometimes we need to create our custom or seeded OAF page read only. In OAF, Certain attributes (the
Required, Rendered, Disabled, and Read Only properties in the Property Inspector) can be bound to values
declaratively using SPEL binding. And using SPEL binding, you can make any component Read only if that
component supports that feature. For seeded page, you can do that with personalization.

By using SPEL mothod, you can first create any transient attribute in a VO such as setReadOnly of type Boolean. I
also preferred to have all transient attributes to be part of a transient VO (without any query).

In AMIMPL:

public void setXXTransVO()


{
try
{
OAView Object pvobj = getXXTransVO1();

1 public void setXXTransVO()

2 {

3 try

4 {

5 OAViewObject pvobj = getXXTransVO1();

6 if(pvobj!=null)

7 {

8 if(pvobj.getFetchedRowCount()==0)

210
www.AppsLead.com
9 pvobj.setMaxFetchSize(0);

10 pvobj.executeQuery();

11 pvobj.insertRow(pvobj.createRow());

12 OARow row = (OARow)pvobj.first();

13 row.setAttribute("RowKey",new NUMBER(1));

14 }

15 }

16 catch(OAException exception)

17 {

18 throw exception;

19 }

20 }

21 /*===========================================================================+

22 Method to Set ReadOnly

23 +===========================================================================*/

24 public void setReadOnly(String event)

25 {

26 try

27 {

28 OAViewObject pvobj = getXXTransVO1();

29 if(pvobj!=null)

30 {

31 pvobj.setMaxFetchSize(0);

32 pvobj.executeQuery();

33 OARow row = (OARow)pvobj.first();

34 if(event.equals("YES"))

35 row.setAttribute("SetReadOnly",Boolean.TRUE);

36 if(event.equals("NO"))

37 row.setAttribute("SetReadOnly",Boolean.FALSE);

38 }

39 }

40 catch(OAException exception)

41 {

42 throw exception;

213
www.AppsLead.com
43 }

44 }

In Controller processRequest:

am.invokeMethod("setXXTransVO");

Serializable[] param = {"YES"};


am.invokeMethod("setReadOnly",param);

1 OAApplicationModule am = pageContext.getApplicationModule(webBean);

2 am.invokeMethod("setXXTransVO");

4 Serializable[] param = {"YES"};

5 am.invokeMethod("setReadOnly",param);

In the page, we can use the below against any component

${oa.XXTransVO1.SetReadOnly}

However, if the page has lots of components that need to set as read only dynamically, oracle has provided few
util classes for that such as:

1. oracle.apps.po.common.webui.ClientUtil;
2. com.oaframewrok.toolkit.util.webBeanUtil;

Here in this case:

Import the classes and use the function setViewOnlyRecursive.

Example:

 ClientUtil.setViewOnlyRecursive(oapagecontext, oawebbean);
 WebBeanUtil.setViewOnlyRecursive(oapagecontext, oawebbean);

1) If it is your custom page use the code directly in ProcessRequest.

2) If this is for a standard page, extend the controller and in the ProcessRequest, use this code.

3) If it is 11i, you have to get the above class from some R12 instance and decompile and make it as a util file and
you can use it in your 11i instance. Here is a similar file.

} // if (w ebBean instanceof OAWebBeanContainer)


}

1 package cl.oracle.apps.qot.core.server;

212
www.AppsLead.com
2

3 import com.sun.java.util.collections.ArrayList;

4 import com.sun.java.util.collections.HashMap;

5 import java.io.Serializable;

6 import oracle.apps.fnd.common.MessageToken;

7 import oracle.apps.fnd.common.VersionInfo;

8 import oracle.apps.fnd.framework.OAApplicationModule;

9 import oracle.apps.fnd.framework.OAException;

10 import oracle.apps.fnd.framework.webui.OABoundValueEmbedURL;

11 import oracle.apps.fnd.framework.webui.OADialogPage;

12 import oracle.apps.fnd.framework.webui.OAPageBean;

13 import oracle.apps.fnd.framework.webui.OAPageContext;

14 import oracle.apps.fnd.framework.webui.OAPartialPageRenderUtils;

15 import oracle.apps.fnd.framework.webui.OAWebBeanConstants;

16 import oracle.apps.fnd.framework.webui.TransactionUnitHelper;

17 import oracle.apps.fnd.framework.webui.beans.OABodyBean;

18 import oracle.apps.fnd.framework.webui.beans.OAImageBean;

19 import oracle.apps.fnd.framework.webui.beans.OARawTextBean;

20 import oracle.apps.fnd.framework.webui.beans.OAWebBean;

21 import oracle.apps.fnd.framework.webui.beans.form.OAFormValueBean;

22 import oracle.apps.fnd.framework.webui.beans.form.OASubmitButtonBean;

23 import oracle.apps.fnd.framework.webui.beans.message.OAMessageRadioButtonBean;

24 import oracle.apps.fnd.framework.webui.beans.message.OAMessageStyledTextBean;

25 import oracle.apps.fnd.framework.webui.beans.message.OAMessageTextInputBean;

26 import oracle.apps.fnd.framework.webui.beans.table.OAAdvancedTableBean;

27 import oracle.apps.fnd.framework.webui.beans.table.OAColumnBean;

28 import oracle.cabo.ui.UIConstants;

29 import oracle.apps.fnd.common.VersionInfo;

30 import oracle.apps.fnd.framework.webui.OAControllerImpl;

31 import oracle.apps.fnd.framework.webui.OAPageContext;

32 import oracle.apps.fnd.framework.webui.beans.OAWebBean;

33 import oracle.apps.fnd.framework.OAApplicationModule;

34 import oracle.apps.fnd.framework.webui.beans.OABodyBean;

35 import oracle.apps.fnd.framework.webui.beans.nav.OAButtonBean;

216
www.AppsLead.com
36 import oracle.apps.fnd.framework.webui.beans.message.OAMessageStyledTextBean;

37 import oracle.apps.fnd.framework.webui.beans.message.OAMessageTextInputBean;

38 import java.io.Serializable;

39 import oracle.cabo.ui.UIConstants;

40 import com.sun.java.util.collections.List;

41 import com.sun.java.util.collections.ArrayList;

42 import com.sun.java.util.collections.HashMap;

43 import com.sun.java.util.collections.Iterator;

44 import java.io.Serializable;

45 import java.sql.SQLException;

46 import java.util.Dictionary;

47 import java.util.Enumeration;

48 import oracle.apps.fnd.common.MessageToken;

49 import oracle.apps.fnd.common.VersionInfo;

50 import oracle.apps.fnd.framework.OAApplicationModule;

51 import oracle.apps.fnd.framework.OAException;

52 import oracle.apps.fnd.framework.OAFwkConstants;

53 import oracle.apps.fnd.framework.webui.OADataBoundValueViewObject;

54 import oracle.apps.fnd.framework.webui.OAPageContext;

55 import oracle.apps.fnd.framework.webui.OARenderingContext;

56 import oracle.apps.fnd.framework.webui.OAWebBeanConstants;

57 import oracle.apps.fnd.framework.webui.OAUrl;

58 import oracle.apps.fnd.framework.webui.beans.OADescriptiveFlexBean;

59 import oracle.apps.fnd.framework.webui.beans.OAKeyFlexBean;

60 import oracle.apps.fnd.framework.webui.beans.OAWebBean;

61 import oracle.apps.fnd.framework.webui.beans.OAWebBeanAttachment;

62 import oracle.apps.fnd.framework.webui.beans.OAWebBeanContainer;

63 import oracle.apps.fnd.framework.webui.beans.OAWebBeanDataAttribute;

64 import oracle.apps.fnd.framework.webui.beans.layout.OAPageLayoutBean;

65 import oracle.apps.fnd.framework.webui.beans.layout.OAQueryBean;

66 import oracle.apps.fnd.framework.webui.beans.layout.OASubTabLayoutBean;

67 import oracle.apps.fnd.framework.webui.beans.nav.OABreadCrumbsBean;

68 import oracle.apps.fnd.framework.webui.beans.nav.OALinkBean;

69 import oracle.apps.fnd.framework.webui.beans.nav.OAPageButtonBarBean;

217
www.AppsLead.com
70 import oracle.apps.fnd.framework.webui.beans.nav.OATabBarBean;

71 import oracle.apps.fnd.framework.webui.OADialogPage;

72 import oracle.apps.fnd.framework.webui.beans.table.OAAdvancedTableBean;

73 import oracle.apps.fnd.framework.webui.beans.table.OAColumnBean;

74 import oracle.apps.fnd.framework.webui.beans.table.OASortableHeaderBean;

75 import oracle.cabo.ui.UINode;

76 import oracle.cabo.ui.beans.form.FormElementBean;

77 import oracle.cabo.ui.beans.nav.ButtonBean;

78 import oracle.cabo.ui.collection.UINodeList;

79 import oracle.cabo.ui.data.BoundValue;

80 import oracle.cabo.ui.data.bind.ConcatBoundValue;

81 import oracle.cabo.ui.data.bind.FixedBoundValue;

82 import oracle.cabo.ui.data.DictionaryData;

83 import oracle.jbo.domain.Number;

84 import oracle.apps.fnd.framework.webui.beans.message.OAMessageTextInputBean;

85 import oracle.apps.fnd.framework.webui.beans.message.OAMessageLovInputBean;

86 import oracle.apps.fnd.framework.webui.beans.message.OAMessageStyledTextBean;

87

88 public class TierPricingRenderUtil

89 {

90 public TierPricingRenderUtil()

91 {

92 }

93 /**

94 * Sets view-only mode on the given web bean and all of its children

95 * (recursively).

96 * <p>

97 * Details:

98 * <ul>

99 * <li>Sets editable fields (ex. text input fields, poplists, LOVs,

100 * key/descriptive flexfields) to not required and read only.

101 * <li>Disables insert/update/delete on attachment tables and attachment

102 * fields.

103 * <li>Hides the table actions region and footer region on advanced tables.

214
www.AppsLead.com
104 * <li>Sets table column headers to not required.

105 * <li>Note: We do not process the children of a page button bar.

106 * </ul>

107 *

108 * @param pageContext the page context

109 * @param webBean the bean to set to view-only; can be a region or an item

110 */

111 public static void setViewOnlyRecursive(OAPageContext pageContext,

112 OAWebBean webBean)

113 {

114 // String d_mod = D_MODULE_setViewOnlyRecursive;

115 // if (PoLog.isProcOn(pageContext,d_mod)) {
PoLog.procBegin(pageContext,d_mod,"webBean",(webBean==null)?null:webBean.getID()); }
116

117
setViewOnlyRecursiveInternal(pageContext, webBean,
118
false, // isWithinTableColumn
119
0 // level
120
);
121

122
// if (PoLog.isProcOn(pageContext,d_mod)) { PoLog.procEnd(pageContext,d_mod); }
123
}
124

125
/**
126
* Internal logic to set view-only mode on the given web bean and all of its
127
* children (recursively).
128
*
129
* @param pageContext the page context
130
* @param webBean the bean to set to view-only; can be a region or an item
131
* @param isWithinTableColumn whether the given bean is within a table column;
132
* if false, read only fields will be set to OraDataText style
133
* @param level the current level of recursion; used for logging purposes only
134
*/
135
private static void setViewOnlyRecursiveInternal(
136
OAPageContext pageContext,
137
OAWebBean webBean,

219
www.AppsLead.com
138 boolean isWithinTableColumn,

139 int level)

140 {

141 //String d_mod = D_MODULE_setViewOnlyRecursiveInternal;

142 /* if (PoLog.isStmtOn(pageContext,d_mod)) { PoLog.stmt(pageContext,d_mod,10,level+":


"+((webBean==null)?null:webBean.getID())+" ("+webBean+"), isWithinTableColumn:
143 "+isWithinTableColumn); }

144

145 if (webBean == null)

146 {

147 return;

148 }

149 */

150 if (webBean instanceof FormElementBean)

151 {

152 // Set form elements (ex. text input fields, poplists, LOVs, etc.) to

153 // not required and read-only.

154

155 if (webBean instanceof OAWebBeanDataAttribute)

156 {

157 ((OAWebBeanDataAttribute)webBean).setRequired(

158 OAWebBeanConstants.REQUIRED_NO);

159 }

160 FormElementBean formElementBean = (FormElementBean)webBean;

161 formElementBean.setReadOnly(true);

162

163 // If the item is not inside a table, set the style class to OraDataText

164 // so that it renders in bold.

165 //if (!isWithinTableColumn)

166 //{

167 //webBean.setStyleClass("OraDataText");

168 //}

169

170 // Hide the tip text for text input and LOV fields.

171 if (webBean instanceof OAMessageTextInputBean)

203
www.AppsLead.com
172 {

173 ((OAMessageTextInputBean)webBean).setTip(null);

174 }

175 else if (webBean instanceof OAMessageLovInputBean)

176 {

177 ((OAMessageLovInputBean)webBean).setTip(null);

178 }

179 }

180 else if (webBean instanceof OADescriptiveFlexBean)

181 {

182 // Set descriptive flexfields to not required and read-only.

183 OADescriptiveFlexBean descFlexBean = (OADescriptiveFlexBean)webBean;

184 descFlexBean.setRequired(OAWebBeanConstants.REQUIRED_NO);

185 descFlexBean.setReadOnly(true);

186

187 // Bug 4893376: If the item is not inside a table, set the style class to

188 // OraDataText so that it renders in bold.

189 if (!isWithinTableColumn)

190 {

191 descFlexBean.setStyleClass("OraDataText");

192 }

193 }

194 else if (webBean instanceof OAKeyFlexBean)

195 {

196 // Set key flexfields to not required and read-only.

197 OAKeyFlexBean keyFlexBean = (OAKeyFlexBean)webBean;

198 keyFlexBean.setRequired(OAWebBeanConstants.REQUIRED_NO);

199 keyFlexBean.setReadOnly(true);

200

201 // Bug 4893376: If the item is not inside a table, set the style class to

202 // OraDataText so that it renders in bold.

203 if (!isWithinTableColumn)

204 {

205 keyFlexBean.setStyleClass("OraDataText");

201
www.AppsLead.com
206 }

207 }

208 else if (webBean instanceof OAWebBeanAttachment)

209 {

210 // For an attachment bean, disable insert/update/delete on all entity

211 // types.

212 OAWebBeanAttachment attachmentBean = (OAWebBeanAttachment)webBean;

213 Dictionary[] entityMappings = attachmentBean.getEntityMappings();

214 if (entityMappings != null)

215 {

216 for (int i=0; i<entityMappings.length; i++)

217 {

218 /* entityMappings.put(PoConstants.INSERT_ALLOWED, Boolean.FALSE);

219 entityMappings[i].put(PoConstants.DELETE_ALLOWED, Boolean.FALSE);

220 entityMappings[i].put(PoConstants.UPDATE_ALLOWED, Boolean.FALSE);*/

221 }

222 }

223 }

224 else if (webBean instanceof OAAdvancedTableBean)

225 {

226 // For an advanced table, hide the table actions region (i.e. the buttons

227 // at the top of the table) and the table footer (i.e. the buttons at the

228 // bottom of the table, like "Add 5 Rows".)

229 OAAdvancedTableBean advTableBean = (OAAdvancedTableBean)webBean;

230 UINode tableActions = advTableBean.getTableActions();

231 if (tableActions != null && tableActions instanceof OAWebBean)

232 {

233 // if (PoLog.isStmtOn(pageContext,d_mod)) { PoLog.stmt(pageContext,d_mod,20,"tableActions:


"+tableActions.getID()); }
234
((OAWebBean)tableActions).setRendered(false);
235
}
236

237
UINode tableFooter = advTableBean.getFooter();
238
if (tableFooter != null && tableFooter instanceof OAWebBean)
239
{

201
www.AppsLead.com
240 // if (PoLog.isStmtOn(pageContext,d_mod)) { PoLog.stmt(pageContext,d_mod,30,"footer:
"+tableFooter.getID()); }
241
((OAWebBean)tableFooter).setRendered(false);
242
}
243
}
244
else if (webBean instanceof OASortableHeaderBean)
245
{
246
// Set table column headers to not required.
247
OASortableHeaderBean sortableHeaderBean = (OASortableHeaderBean)webBean;
248
sortableHeaderBean.setRequired(OAWebBeanConstants.REQUIRED_NO);
249
}
250
else // Other kinds of webBeans do not need view only processing.
251
{
252
// if (PoLog.isStmtOn(pageContext,d_mod)) { PoLog.stmt(pageContext,d_mod,35,level+":
253 "+webBean.getID()+": no processing needed"); }

254 }

255

256 // If the bean is a container, call this method recursively to process

257 // its children.

258 // Note: We do not process the children of a page button bar.

259 if (webBean instanceof OAWebBeanContainer

260 && !(webBean instanceof OAPageButtonBarBean))

261 {

262 // if (PoLog.isStmtOn(pageContext,d_mod)) { PoLog.stmt(pageContext,d_mod,40,level+":

263 "+webBean.getID()+": Start process children"); }

264

265 // The children are within a column if this bean is in a column or

266 // this bean is a column bean.

267 boolean isChildWithinTableColumn = false;

268 if (isWithinTableColumn || (webBean instanceof OAColumnBean))

269 {

270 isChildWithinTableColumn = true;

271 }

272

273 // First, process the indexed children.

200
www.AppsLead.com
274 int childCount = webBean.getIndexedChildCount();

275 for (int i = 0; i < childCount; i++)

276 {

277 UINode childNode = webBean.getIndexedChild(i);

278 if (childNode instanceof OAWebBean)

279 {

280 setViewOnlyRecursiveInternal(pageContext, (OAWebBean)childNode,

281 isChildWithinTableColumn, level + 1 );

282 }

283 }

284

285 // Next, process the named children.

286 Enumeration childNames = webBean.getChildNames();

287 if (childNames != null)

288 {

289 while (childNames.hasMoreElements())

290 {

291 String childName = (String)childNames.nextElement();

292 UINode childNode = webBean.getNamedChild(childName);

293 if (childNode instanceof OAWebBean)

294 {

295 setViewOnlyRecursiveInternal(pageContext, (OAWebBean)childNode,

296 isChildWithinTableColumn, level + 1 );

297 }

298 }

299 }

300

301 // if (PoLog.isStmtOn(pageContext,d_mod)) { PoLog.stmt(pageContext,d_mod,50,level+": Container


"+webBean.getID()+": End process children"); }
302
} // if (webBean instanceof OAWebBeanContainer)

Using the above method, you can’t make all you web bean items Read Only. In that case you can write code as
below:

203
www.AppsLead.com
if(button!=null)
{
button.setDisabled(true);
}

1 //Disable pageButtonsBean

2 OAWebBean pageButtonsBean = (OAWebBean) oapagecontext.getPageLayoutBean().getPageButtons();


3 OAWebBean pageButtonBean = (OAWebBean) pageButtonsBean.findIndexedChildRecursive("Save");
4 pageButtonBean.setRendered(false);
5 pageButtonBean = (OAWebBean) pageButtonsBean.findIndexedChildRecursive("Apply");
6 pageButtonBean.setRendered(false);
7

8 //Enable Search Filters on Account Contacts table

9 formElementBean = (FormElementBean)oawebbean.findIndexedChildRecursive("ActContStatus");
10 formElementBean.setReadOnly(false);
11 formElementBean = (FormElementBean)oawebbean.findIndexedChildRecursive("ShowContResp");
12 formElementBean.setReadOnly(false);
13

14 //Disable MultiSelection in the Advanced Tables


15 OAMultipleSelectionBean multipleSelection1 = (OAMultipleSelectionBean)
16 webBean.findChildRecursive("multipleSelection");

17 if(multipleSelection1!=null)

18 {

19 multipleSelection1.setRendered(false);

20 }

21

22 // Hide a column in the Advanced Tables

23

24 OAColumnBean ColumnBean1 = (OAColumnBean) webBean.findChildRecursive("Column1");

25 if(ColumnBean1!=null)

26 {

27 ColumnBean1.setRendered(false);

28 }

29

30 // CheckBoxBean

31

202
www.AppsLead.com
32 OAMessageCheckBoxBean mtib5 =(OAMessageCheckBoxBean) webBean.findChildRecursive("chkbox");

33 if(mtib5!=null)

34 {

35 mtib5.setRendered(false);

36 }

37

38 // Set Disabled a submit button

39 OASubmitButtonBean button= (OASubmitButtonBean) webBean.findChildRecursive("Go");

40 if(button!=null)

41 {

42 button.setDisabled(true);

206
www.AppsLead.com
Make Page Readonly

import com.oaframewrok.toolkit.util.webBeanUtil

In Process Request:
After super.processFormRequest(pageContext,webBean)
WebBeanUtil.setViewOnlyRecursive(pageContext,webBean);

207
www.AppsLead.com
Embedding ADF Region into OAF Page
Here, I have created an ADF read-only form on Deapartments table having navigation buttons and then
embedded that region on Standard OAF Hello World page.
(Note: Before creating this, you must have JDeveloper 11g(for building ADF page) and correct JDeveloper patch
for Oracle E-Business Suite version.
Also, it must be release 12.1.2 or later as rich container is not available in previous versions.)

Building ADF Page

1) Using 'New gallery', create a Fusion Web Application(ADF). This will create two projects (Model and
ViewController).
2) Right click on Model and create new 'Business Components from tables'. Here, as we are creating only read-
only form, we can skip step1 & 2 of this wizard and on step3 & 4, create read-only VO and AM receptively.

3) Similarly, right click on ViewController and create a new Page under JSF/Facelets category
(RightADFDepartmentsPG.jspx)

4) Now, from data controls, drag DepartmentsVO1 and drop on the page created as ADF Read-Only Form.

204
www.AppsLead.com
5) Also, in web.xml, make the following change (change the param-value to never):
<context-param>
<param-name>oracle.adf.view.rich.security.FRAME_BUSTING</param-name>
<param-value>never</param-value>
</context-param>
If this is not done, browser will not allow ADF region to appear on OAF page and will show an error message like
'This content cannot be displayed in a frame'.
6) Now right click on the page and run.

Creating function for the above ADF page in EBS

1) Set the value of 'External ADF Application URL' profile option at appropriate level (Site, Application,
Responsibility, User) as shown below:
(ex: http://localhost:7101/ADFDemo-ViewController-context-root)

2) Go to 'Functional Administrator -> Core Services -> Functions -> Create Function' and enter the details as
shown below:

3) Click Continue and enter page path as shown below:

209
www.AppsLead.com
4) Also, attach this function to the menu of responsibility from where you want to access this ADF Page.

Personalizing the Hello World page to embed the ADF Region

1) Go to Hello World page -> 'Personalize Page' link.


2) Create a new item of type 'Rich Container' as enter details as below:

3) Click on Apply and return to main page. Now the ADF region will appear on Hello World page:

233
www.AppsLead.com
Raise Multiple Error Messages in OAF

Requirement – How to raise multiple error messages as multiline on OAF pages.

Solution – 1) Create and initialize new ArrayList object


2) Define the error messages in array list
3) Raise bundled eception method

Example -
com.sun.java.util.collections.ArrayList errMsg = new com.sun.java.util.collections.ArrayList();

errMsg.add(new OAException("Who is Lucifer"));


errMsg.add(new OAException("Ra-One will kill Lucifer"));
errMsg.add(new OAException("G-One is protector"));

OAException.raiseBundledOAException(errMsg);

Output –
1. Who is Lucifer
2. Ra-One will kill Lucifer
3. G-One is protector
------------------------------------------------------------------------------------------------------
Exception - If above method is being implemented inside a try/catch block, It might not throw
expected error message.So either implement above outside Try/catch block or use below
steps to handle this inside try/catch.

1) Create array list object at global level


com.sun.java.util.collections.ArrayList errMsg = new com.sun.java.util.collections.ArrayList();

2) Define the messages inside the try block and raise exception with custom message
try {
errMsg.add(new OAException("Who is Lucifer"));
errMsg.add(new OAException("Ra-One will kill Lucifer"));
errMsg.add(new OAException("G-One is protector"));
throw new OAException("Sandeep");
}

3) Handle this implementation inside the catch block


catch(Exception e)
{
String a="oracle.apps.fnd.framework.OAException: Sandeep";
if (a.equals(e.toString()))
{ OAException.raiseBundledOAException(errMsg); }
else
{ throw new OAException("Exception Has been found in code 28:" +e,
OAException.INFORMATION);
}

231
www.AppsLead.com
Few Useful threads
Here is the list of few useful of the many threads replied by me on OA forums:

1)Dynamic tool tip in classic table


http://forums.oracle.com/forums/thread.jspa?messageID=2056047&#2056047

2)Putting a different color message in OA Framework page for instrtuction text etc:
http://forums.oracle.com/forums/thread.jspa?messageID=1966417&#1966417

3)How to make the cursor as "Busy" (i.e. HOURGLASS) and not like the usual "ARROW"..., when ur doing lot of
tasks on an event
http://forums.oracle.com/forums/thread.jspa?messageID=1940174&#1940174

4)Delete Personilization:
http://forums.oracle.com/forums/thread.jspa?messageID=1959670&#1959670

5)Putting error message stack on OA page:


http://forums.oracle.com/forums/thread.jspa?messageID=1890435&#1890435

6)Make some rows' some columns read only in a table:


http://forums.oracle.com/forums/thread.jspa?messageID=1813973&#1813973

7)Not able to find server.xml


http://forums.oracle.com/forums/thread.jspa?messageID=1787572&#1787572

8)Runtime VO
http://forums.oracle.com/forums/thread.jspa?messageID=1886728&#1886728

9)Using alerts in OA Framework Page


http://forums.oracle.com/forums/thread.jspa?messageID=2067435&#2067435

10)Showing pl/sql exceptions in java(Also, see this thread if ur facing previous message stack retaining
probling while using OAExceptionUtils class)
http://forums.oracle.com/forums/thread.jspa?threadID=598831&start=0&tstart=0

11)Dynamic CSS class generation in a OAF Page


http://forums.oracle.com/forums/thread.jspa?threadID=598398&tstart=15

http://forums.oracle.com/forums/thread.jspa?threadID=605557&start=15&tstart=0

231
www.AppsLead.com
Using Oracle AOL Profile Options to Configure Logging

You can configure logging by setting Oracle Application Object Library (FND) profile options.

The available levels are Site, Application, Responsibility, and User. User settings override Responsibility settings,
Responsibility settings override Application settings, and Application settings override Site settings.

Here is a summary of the impacts of the different profile option levels:

 User: Affects only the given user.


 Application: Affects all users for the specific application.
 Responsibility: Affects all users in any application for that responsibility.
 Site: Affects all users, applications, and responsibilities.

Note: When setting up logging at the Site level, Oracle strongly recommend that you set the logging level to
UNEXPECTED. ERROR or EXCEPTION. Also remember to return the profiles to their usual values after debugging
has been completed.

How to Generate SQL Trace In OAF

1. Profile 'FND: Diagnostics' = Yes at user level.This will make 'Diagnostics' menu display.

2. Login to Personal Home Page as that user and select the 'Diagnostics' icon at the top of the page.

3. Select 'Set Trace Level' and click Go

4. Select the desired trace level and click Save

5. Write down the trace id number(s).

230
www.AppsLead.com
6. Perform the activity that you want to trace

7. Return to the 'Diagnostics' page.

8. Select `Set Trace Level' and click Go

9. Select 'Disable Trace' and click Go.

10. Write down the trace id number(s) if different.

11. Go to user_dump_dest for your database and collect the raw trace file(s) suffixes by the trace id number(s)

you have recorded.

Note: you can identify the user_dump_dest directory in your environment by running the following SQL:

SQL> select name, value from v$parameter where name = 'user_dump_dest';

233
www.AppsLead.com
How to Check Debug Log on OAF Pages

1. Profile 'FND: Diagnostics' = Yes at user level.This will make 'Diagnostics' menu display.

2. Login to Personal Home Page as that user and select the 'Diagnostics' icon at the top of the page.

3. in list box, Choose 'Show Log on Screen', and Select Statement

232
www.AppsLead.com
4. Once this is done, when you go to any page you would be able to see log at the bottom of the page .

-------------------------------------------------------------------------------------------------------------------------------------------------

How to write debug log in OAF page and BC4J?

Log Method in UI like:

/**

* Posts messages to FND_LOG_MESSAGES using latest logging standard.<br>

* <br>

* please see oracle.apps.fnd.common.Log

* Log levels:<br>

* 6 - Unexpected Errors<br>

* 5 - Expected Errors<br>

* 4 - Exception<br>

* 3 - Event (High Level Logging Message)<br>

* 2 - Procedure (Entry / Exit from a routine)<br>

236
www.AppsLead.com
* 1 - Statement - (Low Level Logging Message)<br>

* 0 - Performance

*/

public static void log(OAPageContext pageContext, Object pModule, String pMsg, int pMessageLevel)

String indent = getIndentString(pageContext);

String str = formatMessage(indent, pMsg, pMessageLevel);

if( pageContext.isLoggingEnabled(pMessageLevel) )

pageContext.writeDiagnostics(pModule, str, pMessageLevel);

Log Method in BC4J like:

private void writeLog(String message, String methodName)

OADBTransaction transaction = this.getOADBTransaction();

if (transaction.isLoggingEnabled(OAFwkConstants.STATEMENT))

transaction.writeDiagnostics(this, methodName+":"+message, OAFwkConstants.STATEMENT);

237
www.AppsLead.com
Debugging OA Framework - 7 Different Techniques

In this article, I will explain seven different methods to debug OA Framework pages in Oracle eBusiness Suite.
Each of these methods are explained using working Audio-Video demo, hence you will need your headphones.
Some of these techniques are applicable when running the Framework pages from jDeveloper, whereas other
debugging techniques apply when debugging OA Framework Pages from eBusiness Suite responsibility.

Each method of debugging OA Framework pages has its own merits, and hence you must apply one of the
techniques that suites the most to your situation.

1. Use System.out.println
When running the OA Framework pages from jDeveloper itself, you can write debug messages using
System.out.println.
These debug messages will be displayed in the console of jDeveloper.
Pro
* Ease of use, as you simply enter free text messages
* Debug messages simply appear without the need to set any profile options
Cons
* Too much typing, which can be avoided when using the debugger of jDeveloper.
* You can debug only those pieces of code that you suspect are causing the error. Unlike to this approach,
using jDeveloper debugging, breakpoints can be set for exceptions/classes as well.

Click here to see a quick working demo for debuging OA Framework using System.out.println

2. Use jDeveloper inbuilt Debugger


This happens to be my favourite mechanism to debug OA Framework Pages, for the following reasons
Pro
* To get started just one breakpoint is required, as more and more breakpoints can be added in runtime
itself.
* You can set generic breakpoints, for example, you can set breakpoint on exceptions, which will take you
to the exact line of code from where the exception was being raised
* jDeveloper makes it possible to try different scenarios, for example, you can change the variable values at
runtime
Cons
* Given that you do not have source code of base classes, debugger usually dives into those classes without
giving many visible details. One may find this annoying.
* Some versions of OAFwk raise exceptions[caught internally by Oracle] like Classcast exception even before
the page renders.
Debugger often pauses when those exceptions are raised. This can be overcome by clicking on “resume
button” of debugger.

Click here for demo of debugging via jdeveloper debugger


The demo in above link also shows how you can change the variable values at runtime.

Click here for demo of using debugger to trap classcast exceptions


The demo in above link shows how you can set breakpoints for specific Exceptions that can be raised from OA
234
www.AppsLead.com
Framework Pages

3. Use jDeveloper debugging feature, by changing Java VM runtime option Djbo.debugoutput


Lets say, for this exercise, I wish to find the exact piece of SQL Statement that my screen fires, when doing an
update.
In order to do so, we can append text -Djbo.debugoutput=console to runner property
As shown below, I can enter the following text in Runner property of jDeveloper

Have a look at this demo to visually see this debugging technique

4. Use the FND Debug Logging feature, to see debug messages on the OA Framework Screen itself
The debug messages can either been seen on the same screen or those can be spooled into a table named
FND_LOG_MESSAGES
In jDeveloper, you must include OADiagnostic in the “Run Options”.
This is effectively similar to setting profile option “FND Diagnostics” to Yes in eBusiness Suite.
Using this option, you will be able to click on Diagnostics to enable On-Screen display of debug messages.

Pro
* The debug messages seen using this technique are exactly the same as the debug messages seen in
eBusiness Suite, once FND%Log% profile options are available.
* There is tremendous amount of debug messages in FND classes given by Oracle.
* This approach is the most useful when investigating red coloured error message “Please contact your
system administrator”
Cons
* Prior to 11.5.10, this option might bring your application session down to its knee. But I notice from 11.5.10
onwards, these debug messages are captured very efficiently.
* The debugging is limited to the debug messages in place. To maximise the listing of debug messages, try to
use statement level debugging.

Click here for the demo of doing on-screen debugging for OA Framework pages

5. SQL Trace for Oracle Framework Sessions


We often use this technique for tracing the SQL statements executed by Oracle Forms or by concurrent
programs.
The same technique can be applied to OA Framework too.

239
www.AppsLead.com
You can run the SQL*Trace either when running the application pages from “OA Framework” or when running
OA Framework pages from within eBusiness Suite.
For jDev, ensure that OA Diagnostics has been included in jDeveloper Project property “Run Options”.
Alternately ensure that profile option “FND Diagnostics” has been setup against your username.

Click here for the demo of SQL*Trace on OA Framework Pages

6. Use FND Logging profile options to capture debug messages into a table named FND_LOG_MESSAGES
Use the FND Debug Logging feature, to see debug messages.
The debug messages can either been seen on the same screen or those can be spooled into a table named
FND_LOG_MESSAGES

Please click on this link to see an article on FND Logging

7. Use raiseDeveloperException.
I had all but forgotten about this technique, until I discussed this paper with Mr Senthil prior to its publication.
He reminded of raiseDeveloperException. You can raise debug messages to be displayed in OA Framework pages
using raiseDeveloperException.
By doing so, your debug messages will be visible onto the top portion of the screen.
This is very similar to System.out.println, however the key difference being that raiseDeveloperException displays
the debug message on top portion of the page itself.
Pro
* Ease of use, as you simply enter free text messages
* Debug messages simply appear without the need to set any profile options
* Debug messages appear on the top portion of the page and hence the ease of visibility when testing your
code in jDeveloper
Cons
* Too much typing, which can be avoided when using the debugger of jDev.
* You can debug only those pieces of code that you suspect are causing the error.

223
www.AppsLead.com
Custom Logging in Java Layer in Oracle Applications R12
I have often felt for years simple SOP (System.out.Println) is the best way of debugging in java/j2ee applications. I
have the evil habit.. of putting lots of SOPs while writing code for OAF or ADF or simple j2ee applications. I
generally create a method with sop in it eg:

private void putLog(Object o)


{
System.out.println(o);
}

and call it with the code wherever required. The benefit is at the point of deployment of code, i just need to
change this method from sop to writeDiagnostics().The worst part of diagnostic logging is when you enable
logging on the Applications... "Show Log On Screen", it shows so many logs apart from my custom log
statements, that its really difficult to debug.

The other standard way of debugging java code on server is using OACore log in OC4J server.In R12,
Goto $ORA_CONFIG_HOME/10.1.3/opmn/conf
take the backup of opmn.xml
edit opmn.xml for data id="java-options" and add the following:
-DAFLOG_ENABLED=true -DAFLOG_LEVEL=statement
-DAFLOG_MODULE=fnd%
-DAFLOG_FILENAME=/tmp/aflog.txt -Djbo.debugoutput=console

The log message should get written in,


$INST_TOP/logs/ora/10.1.3/opmn/oacore_default_group_1/oacorestd.out

But for this my code should contain SOPs, which is also a problem, because I don't wanna SOPs in my code after
deployment on server, as SOPs have huge impact on performance.

So, I need a way (probably a magic .... :) )that my debug statements become SOPs when I run my code in
jdeveloper automatically, and when I run the same code in server, these statements should go in a text file if I
enable logging on server, lets' say we make it dependent on a profile , so that I can also disable these
statements/logging in production just by changing profile value.

Ok so make this magic or logic happen I used a trick and have written a custom logger class with static methods,
let see how this class works.Ok for making this logging happen follow these steps:

STEP1
-------------
Copy this class and put in any pkg under custom directory in java top, like I have used package
xx.oracle.apps.ak.logging. Replace this pkg name with the pkg u want to put this class in.

package xx.oracle.apps.ak.logging;

import java.awt.Toolkit;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.PrintStream;
import oracle.apps.fnd.framework.OAException;
import oracle.apps.fnd.framework.server.OADBTransaction;
import oracle.apps.fnd.framework.webui.OAPageContext;
import java.io.PrintWriter;
import oracle.apps.fnd.common.WebAppsContext;
public class XxLogger
{
public XxLogger()
{
}

public static void putLog(OADBTransaction ot, Object o)


{

221
www.AppsLead.com
printLog(ot, null, null, null, o);
}

public static void putLog(OAPageContext pageContext, Object o)


{
printLog(null, null, pageContext, null, o);

public static void putLog(WebAppsContext ctx, Object o)


{
printLog(null, ctx, null, null, o);

public static void printLog(OADBTransaction ot, WebAppsContext ctx,


OAPageContext pageContext, Exception exp,
Object o)
{
FileOutputStream outFile = null;
try
{
//this line should throw headless exception on server
//due to opmn.xml configuration for oc4j node.
//and would work fine in local jdev
Toolkit.getDefaultToolkit().getScreenSize();
if (o == null)
{
exp.printStackTrace();
}
else
{
System.out.println(o);
}
}
catch (Exception e)
{
try
{
String profile = null;
if (ot != null)
{
profile = ot.getProfile("XX_LOG");
}
else if (pageContext != null)
{
profile = pageContext.getProfile("XX_LOG");
}
else if (ctx != null)
{
profile = ctx.getProfileStore().getProfile("XX_LOG");
}
if ((profile == null) || ("".equals(profile)))
{
//No logging

}
else
{
outFile = new FileOutputStream(profile + "/xx_log.log", true);
PrintStream ps = new PrintStream(outFile);

if (exp != null)
221
www.AppsLead.com
{
ps.append(new java.util.Date().toString() + " : " +
"*************************************Exception Details*****************************");
ps.append(" \n ");
exp.printStackTrace(ps);
ps.append("*************************************Exception Details End
*****************************");

}
else
{
ps.append(new java.util.Date().toString() + " : " + o);
}
ps.append(" \n ");
}
}
catch (FileNotFoundException f)
{
// TODO
e.printStackTrace();
}
}
}

public static void printStack(OADBTransaction ot, Exception e)


{
printLog(ot, null, null, e, null);
}

public static void printStack(WebAppsContext ctx, Exception e)


{
printLog(null, ctx, null, e, null);
}

public static void printStack(OAPageContext pageContext, Exception e)


{
printLog(null, null, pageContext, e, null);
}

STEP2
----------
Now create a custom profile which will store path of log file we want to get generated,please note if this
profile value is null then no log will be generated.Replace the profile name with "XX_LOG" in the code at all 3
places.

STEP3
========
set the profile value to the path where you wanna log file to be generated.Also please note you would have to
manually create "xx_log.log" file there for the first time(for that just create a simple fie and rename as
"xx_log.log"), this I have done purposely in code, so that even if by mistake profile value is not null in
production, no log should be generated.

STEP 4
===========
Use this logging in OAF/JTT/JTF/JSP file :

In CO
========
220
www.AppsLead.com
XxLogger.putLog(OAPageContext pageContext, Object o)

In AM,VO,EO
============
XxLogger.putLog(OADBTransaction ot, Object o)

In JTT/JTF
============
import oracle.apps.fnd.common.WebRequestUtil;
import oracle.apps.fnd.common.WebAppsContext;
WebAppsContext ctx = WebRequestUtil.validateContext(request, response);
XxLogger.putLog(WebAppsContext ctx, Object o)

STEP 5
===========
For printing stacktrace of exceptions :

In CO
========
XxLogger.printStack(OAPageContext pageContext, Exception e)

In AM,VO,EO
============
XxLogger.printStack(OADBTransaction ot, Exception e)

In JTT/JTF
============
import oracle.apps.fnd.common.WebRequestUtil;
import oracle.apps.fnd.common.WebAppsContext;
WebAppsContext ctx = WebRequestUtil.validateContext(request, response);
XxLogger.printStack(WebAppsContext ctx, Exception e)

We are done the log would now be generated at the position marked in profile and the these messages will
automatically converted to SOPs when you run your code in local jdev

Advantages of this logging


=============================
1) You don't need to change your code again and again while working in local or deployed on server.
2) If the development is done in a team, everybody in the team can set the profile at his/her user level so that
different log is generated for each user.
3)This code when run in jdeveloper without any change all putLog() and printStack() statements will convert into
System.out.println.
4) On server if profile value is set to null , no log is generated, else if some location is set, log is generated there.
5) Same class can be used in all OAF AND JSP components.
6) All methods putLog and printStack are static, so you need not instanciate the class, direct call of method will
work.
7) Sometimes while working at offshore, you don't have access to DBA, who can enable log.... :) this is my
personal one... u might not face it.

Logic of how code works


=========================
If you have read the code of class , in all the methods code essentially calls printLog method, which has the first
line as

Toolkit.getDefaultToolkit().getScreenSize();
This line throws headless exception on server mainly because opmn.xml file configuration by default throws
headless exception if any JAVA awt api is called, but this line works fine in jdev, so we utilise this logic to identify
whether the code is running on server or jdev. Accordingly it writes the statements in a file, if file is enabled or
else calls SOP in jdev.

223
www.AppsLead.com
Logging in OAF Pages

The Logging Framework in Oracle Apps provides the ability to store and retrieve log messages for debugging,
error reporting, and alerting purposes. We can use it for any OAF Page development and Customization.

Where is the debug message stored, once the logging is turned on?

Debug messages are stored in a table called FND_LOG_MESSAGES.

If you want to have logging from your concurrent program, you can write as below in your PL/SQL Code.

fnd_log.STRING(log_level => fnd_log.level_statement


,module => 'xxpcm.packagename.procedurename'
,message => 'You debug message here');

1 fnd_log.STRING(log_level => fnd_log.level_statement

2 ,module => 'xxpcm.packagename.procedurename'

3 ,message => 'You debug message here');

From OAF java code, you can write like

pageContext.w riteDiagnostics("xxpcm.oracle.apps.pa.ci.w ebui", "Your debug message here", 1);

1 pageContext.writeDiagnostics("xxpcm.oracle.apps.pa.ci.webui", "Your debug message here", 1);

Trace OAF Pages

Share on facebook Share on twitter Share on email Share on print More Sharing Services 7

To enable diagnostic for specific user set Profile Option FND: Diagnostics to YES
See this article about profile option

Now login at application, you will find in global buttons "Diagnostics" link, click it.
Enter the follwing
Diagnostic: Show Log on Screen
Log Level : Statement (1)
Module : %

Now Click go button

222
www.AppsLead.com
Now when opening any page at application you will find trace at button of page.

226
www.AppsLead.com
Using Logging to Screen

In addition to the above methods where log messages are written to a file or the database, Logging to Screen
provides:

 The ability to enable logging on a per HTTP request or per HTTP session basis.
 Dynamic configuration which does not require restarting any servers or changing any log profiles.
 A convenient lightweight mechanism to diagnose performance issues. Each message is timestamped to
the millisecond.

If Logging to Screen is enabled, then the Java log messages generated for a particular HTTP Request-Response are
buffered in memory and appended to the end of the generated HTML page. However this feature does not affect
any existing configurations of file or database logging. File or database logging continues to behave per the
configured middle tier log properties and/or log profile values.

Note that this mechanism currently provides only Java layer messages. Regular file or database logging should be
used if messages from other layers (e.g., PL/SQL) are needed.

Enabling Logging to Screen in Oracle Application Framework Pages

For security reasons, oracle has made this feature only accessible if the “FND: Diagnostics” Profile is set to “Yes“.

1] First go to the page and click the Diagnostics button.

After you select the Diagnostics button to navigate to the Diagnostics page, you can select:

 Show Log – It directs you to the Oracle Applications Manager where you can view a “snapshot” of your
Oracle E-Business Suite system.
 Show Log on Screen – It allows you to specify a log level and display Java log messages for a particular
HTTP Request-Response at the end of the current page.
 Set Trace Level – It displays the Set Trace page where you can specify the level of information to collect
in a database trace.
 Show Pool Monitor – It displays the Application Pool Monitor where you view different aspects of
runtime and configuration information about the JVM.

2] Select Show Log to Screen from the drop-down list.

227
www.AppsLead.com
Caution: If you set the default site-level logging level to STATEMENT or PROCEDURE, a decrease in system
performance could result. Under that configuration, the large amount of generated log messages might
significantly slow down the system. Furthermore, if the site-level logging level is set to a low severity for a long
time, then the FND_LOG_MESSAGES table could potentially run out of space.

224
www.AppsLead.com
Purging Log Messages

You should periodically delete old log messages to account for the space limitations of the database table. In
addition, you should periodically rotate log files.

There are several ways to purge log messages. They are described below:

1] Using a Concurrent Program

The concurrent program “Purge Debug Log and System Alerts” (Short name: FNDLGPRG) is the recommended
way to purge messages. This program purges all messages up to the specified date, except messages for active
transactions (new or open alerts, active ICX sessions, concurrent requests, and so on). This program is by default
scheduled to run daily and purge messages older than 7 days. Internally this concurrent program invokes the
FND_LOG_ADMIN APIs, which are described below.

2] Using PL/SQL

You can use the FND_LOG_ADMIN PL/SQL package to delete log messages.

fnd_log_admin apis:

Name Type Description

delete_by_date_i Procedure This routine is used as a concurrent program. Nobody besides the
concurrent manager should call it.

delete_by_user Function Delete all log messages for a particular user

delete_by_session Function Delete all log messages for a particular session

delete_by_user_session Function Delete all log messages for that match both user and session

delete_by_module Function Delete all log messages that are “like” module

delete_by_date_range Function Delete all messages between the specified dates. passing null
means unlimited; null for both deletes all rows.

delete_by_max_level Function Deletes messages at level and all levels below.

delete_all Function Delete all messages

delete_by_sequence Function Delete all log messages based on sequenceid

For example:

Oracle PL/SQL

SET SERVEROUTPUT ON
declare
l_del_row s_cnt NUMBER;
BEGIN
l_del_row s_cnt := fnd_log_admin.delete_all;

1 SET SERVEROUTPUT ON

2 declare

3 l_del_rows_cnt NUMBER;

229
www.AppsLead.com
4 BEGIN

5 l_del_rows_cnt := fnd_log_admin.delete_all;

6 DBMS_OUTPUT.PUT_LINE(l_del_rows_cnt || ' rows deleted');

7 END;

263
www.AppsLead.com
Open Workflow status monitor diagram page in OAF
Create a VO for the query which is given below through this you can get the current diagram url,

select
WF_MONITOR.GetDiagramURL(WF_CORE.Translate('WF_WEB_AGENT'),NtfEO.MESSAGE_TYPE,NtfEO.ITEM_KEY,'
NO') monitor_url from
(SELECT ITEM_KEY,MESSAGE_TYPE FROM WF_NOTIFICATIONS WHERE NOTIFICATION_ID = :1) NtfEO

First find the button component of your page.


call VO with the input parameters which will return the diagram url.
Put that url into the java script function.

Through the java script you can open a new popup window which will display the status monitor diagram

OASubmitButtonBean reAssignBea1n = (OASubmitButtonBean)


paramOAWebBean.findChildRecursive("WfMonDiagramCtrl");

Serializable[] parameters1 = { NotificationId };


Serializable aa1 = am.invokeMethod("getMonitorURL", parameters1);
if (aa1 != null && !aa1.toString().equals(""))
{
String url = "window.open('" + aa1.toString() + "')";
paramOAPageContext.putJavaScriptFunction("LaunchMonitor", url);
}

261
www.AppsLead.com
JavaScript In OA Framework
“To be or not to be…… is the question…..!” The famous soliloquy by William Shakespeare in Hamlet…. a similar
scenario we have in OA Framework for JavaScript!
The exact lines of Developers’ guide for use JavaScript are as follows:
“UIX and the OA Framework are rapidly adding new features to provide a more interactive user experience
(partial page rendering, automatic table totaling, and so on). You are certainly encouraged to leverage these
features as they are released, however, you should not attempt to implement them yourself before they're
ready.
In short, JavaScript is prohibited without explicit permission from the OA Framework team. Furthermore, you
must have confirmation from the corporate UI design team that a Javascript implementation is essential for
your product.”

But this is really funny, if you are developing some web pages for your application, so expect all web features in
the framework, and if they are missing definitely you have to use JavaScript to implement them, you cannot wait
, for the framework team to implement them.

So, if you are developing some custom pages for your application, you can go ahead with JavaScript. I will advice
to refrain from JavaScript if your extending standard OA pages, because, Oracle may not support it, in that case.
In case of custom pages, anyways oracle will not support customization, so you dam care for support.

Another interesting thing in OA Framework is that you will methods for JavaScript usage method in almost every
UIX beans; in fact, framework team must be using them in development of various features in OA Framework.

What is JavaScript?

JavaScript is the Netscape-developed object scripting language used in millions of web pages and server
applications worldwide. Netscape's JavaScript is a superset of the ECMA-262 Edition 3 (ECMAScript) standard
scripting language, with only mild differences from the published standard.

Contrary to popular misconception, JavaScript is not "Interpretive Java". In a nutshell, JavaScript is a dynamic
scripting language supporting prototype based object construction.

For those who are interested and new to concept of javascript, should explore this link
http://www.javascriptmall.com/learn/

I will like to stress on one point before starting the various scenarios where JavaScript can be used, is that
JavaScript is a browser specific script and may behave different in different browsers, so you must test your
application code on various browsers like internet explorer, mozilla firefox, Netscape etc.

Scenarios in OA Framework, where you are bound to use javascript.


Various Pop Up Window scenarios
Closing a Window
Timely refresh of a OA Page
Client side events on different beans

Various Pop Up Window scenarios:


This is the most common scenario in OA Framework, as framework does not provide anything for pop windows,
except standard LOVs, which may or may not suit your requirement.I think I have replied this thread several
times on OA Framework forum, in fact, thought of writing this article, after I replied the thread so many times J.
Lets, take the most common scenario:
You need to fire a custom page as a pop up window , do some processing(say add some new values in one of the
VO) and on returning back to base page, reflect the changes on base page(say the base page VO should reflect
the changes done on pop up page).
Follow these steps for the solution:
1. To open a custom page..... as a modal window.... u can have a link or button(button of type button and not
submit button) on base page with destination url property as following javascript:
261
www.AppsLead.com
javascript:var a = window.open('OA.jsp?page=/XXX/oracle/apps/xxx/......&retainAM=Y',
'a','height=500,width=900,status=yes,toolbar=no,menubar=no,location=no'); a.focus();

Meaning of each parameter in this javascript:


· RetainAM:If this is equal to “Y”, AM will be retained when child window is opened.
· Height: Height of the pop up or child window.
· Width: Width of pop up or child window
· Status: String, Specifies a priority or transient message in the window's status bar (This property is not
readable.).
· Toolbar: Object, Represents the browser window's tool bar.
· Menubar: Object, Represents the browser window's
menu bar.
· Location:Location of window on the sceen
· Resizable: if resizable=yes, is included in above api, then child window size can be maximized.By default the
child window size is fixed user cannot, increase or decrease the size.
· Scrollbar: if scrollbar=yes, is included in above api, scrollbars will appear in the child window.

Please Note : While trying to run a pop up page you get errors like:
"You are trying to access a page which is no longer active....."

The root cause of this error are the profile options:


1) FND_VALIDATION_LEVEL - None
2) FND_FUNCTION_VALIDATION_LEVEL - None
3)Framework Validation Level- None
They should be none in order to avoid the error.The root cause of the error is MAC key url validation, which is
governed by the above 3 profiles.There can be scenarios when your DBA/Admin would not allow you to set
these profiles at site level in order to maintain security of Apps from cross site scripting attacks.

In such scenarios, or I will say in all scenarios, its better to use a utility class in OAF called
OABoundValueEmbedURL which secures your js function by bypassing the MAC key validation.You can use
following code to attach js url programatically to a button/image bean :
OAImageBean img = (OAImageBean) webBean.findChildRecursive("");
//url of the page
String url ="/XXX/oracle/apps/xxx/......"
//retain am parameter
string amMode ="true";
//additional parameters i want to pass to to pop up page
String params="order_id={@workorder_id}";

//Computing page_url
String page =
url + "&retainAM=" + amMode + "&fndOAJSPinEmbeddedMode=y" + "&" +
params;
//Computing final url
String destURL =
OAWebBeanConstants.APPS_HTML_DIRECTORY + OAWebBeanConstants.APPLICATION_JSP +
"?" + OAWebBeanConstants.JRAD_PAGE_URL_CONSTANT + "=" + page;

//Securing js function from MAC key validation


OABoundValueEmbedURL jsBound =
new OABoundValueEmbedURL(img, "openWindow(self, '", destURL,
"' , 'longTipWin', {width:" + width +
", height:" + height +
"}, true); return false;");

//Attaching bound value embed url to on click of image.


img.setAttributeValue(OAWebBeanConstants.ON_CLICK_ATTR, jsBound);

260
www.AppsLead.com
There are 3 important points to understand here :
1) This code has to be written in process request and not process form request, because as per OA Developer
standards bean properties can only be set in process request and not process form request.

2)The additional parameters you want to pass can be passed at runtime, this is especially in case of
tables/hgrids where lets say a particular column has link and each row has different parameter values to pass,
you can send VO attributes as parameters like @Vo_attr_name.This will make your pop window link to be
dynamic as each row js url will have different parameter values depending upron row of VO.

3)If you see the final url computed here I have used an additional parameter like
fndOAJSPinEmbeddedMode=y, this is especially in case of pages which use jtfchrome.jsp where in the JTF/JTT
and OAF flows are integrated.This parameter will take care that the JS URL OF LOV page, should not be
changed to jtfcrmchrome.jsp from OA.jsp which results in error of lov page.

In one of the 2 approaches you would be able to open the pop up page.

2. Now, you can do your pop up page processing by the pop page controller.
3. Now your child window should have two buttons, one for select(submit button) and another for
close(button).On press of select button you will have all vaues in your trasient VO, and you can also show user a
message like, " values created successfully....".The second button will be of type "button", whose destination url
property will be

javascript:opener.submitForm('DefaultFormName',0,{XXX:' abc'});window.close();
(In this api you can pass n number of attributes, the second parameter will be correspondingly n-1, e.g you have
to pass three attr, then second parameter of api will be 2
javascript:opener.submitForm('DefaultFormName',2,{'XXX':' abc','XXX1':'efg','XXX2':'ijk'});window.close(); )
Now in the process request of the base page CO, u can get parametre 'XXX' from the pagecontext....so
if((("abc").equals(pageContext.getParameter("XXX"))))
{///LOGIC to initialize or not to intialize some components of base page}

Please Note :
1)From Apps R12.1, the framework is also validating parameter security, so getting js parameter values by
pageContext.getParameter("XXX"), can throw security exception error
FND_FORM_POST_SECURITY_FAILED. To bypass this parameter security validation , you need to take js
parameter values directly from http request using following code:
pageContext.getRenderingContext().getServletRequest().getParameter("XXX");

2)Also, if you are getting error in doing a page submit on pop up page confirm:
FND: Framework Compatibility Mode profile option should have value greater than or equal to "11.5.10".

Closing a Window
To open a custom page..... as a modal window.... u can have a link or button(button of type button and not
submit button) on base page with destination url property as following javascript:window.close();

Timely refresh of a OA Page


Lets, consider a scenario when you want a page refresh after every 10 seconds.Here is javascript for
it:javascript:setTimeout(window.location.reload(),10000);where 10,000-->10 sec(10,000 milli sec)

What you need to do is attach with onLoad method of OABody bean, so that when the page is rendered, this
javascript is triggered.You can code like this:

OABodyBean bodyBean = (OABodyBean) oapagecontext.getRootWebBean();

String javaS = “javascript:setTimeout('window.location.reload()',13333)”;


bodyBean.setOnLoad(javaS);

Client side events on different beans:

263
www.AppsLead.com
Above I have given a few of million possible situations of javascript in OA Framework.In almost all ui beans u will
find methods like setOnLoad *, setOnClick* etc., where you can attach a javascript function to the bean.

262
www.AppsLead.com
Alert Using JavaScript in OAF

if(pageContext.getParameter("SubmitButton")!=null)
{
StringBuffer l_buffer = new StringBuffer();
l_buffer.append("javascript:alert('hello')");
pageContext.putJavaScriptFunction("SomeName",l_buffer.toString());
}

Here SubmitButton is the id name of submitbutton

l_buffer is the variable name of StringBuffer

266
www.AppsLead.com
Invoking Web Service from OA Framework Pages
Introduction

Invoking a web service from within E-Business Suite has always been a open topic (A BPEL process's entry point
itself is a web service so initiating a BPEL process is nothing but invoking the web service endpoint). There were
different mechanisms used in different implementations from 11i to R12 and there are some nice articles on
internet from E-Business Suite experts. Some of the methods used are

1. Generate Axis client code and call from within OA Framework controller
2. Use Business Event through EBS Adapter to trigger a BPEL Process on middle tier

However, invoking a web service dynamically without writing a single line of code specific to web service
invocation is sure to save a lot of time and effort. We already discussed about R12.1 feature Service Invocation
Framework (SIF) in one of the earlier posts on this blog Invoking Web Service from Oracle Workflow.

Synchronous or Asynchronous

SIF setup is already covered in the aforementioned blog post. A web service may be invoked using SIF either
synchronously or asynchronously based on the SIF setup. The synchronous or asynchronous invocation of the
web service using SIF should not be confused with the request pattern supported by the target web service being
invoked.

Synchronous or Asynchronous invocation with SIF

Whether you want to invoke a web service synchronously or asynchronously using SIF in respect to your code
depends on whether your "Invoke Web Service" event subscription has phase < 100 or >= 100.

If the event subscription has phase < 100, and the event is raised from Java code (for example OA Framework
page controller) then the web service is invoked synchronously and the response is available immediately to the
calling code. If the event subscription has phase >= 100 and the event is raised from Java code (for example OA
Framework page controller) then the web service invocation is deferred to WF_JAVA_DEFERRED queue and is
executed by Workflow Java Deferred Agent Listener. In order to capture the response from the web service it is
required to define a callback business event and subscription.

More information on how an business event subscription is executed for different phases is explained in the blog
post PLSQL vs Java Business Event System.

Synchronous or Asynchronous request pattern of target web service

If the web service itself is defined to be synchronous or asynchronous is determined based on the WSDL
operation definition. This means whether the response from the web service is available immediately or at a later
time after the initial request was sent to the service. Some of the prominent industry standards for asynchronous
web service patterns are WS-Addressing and WS-Polling. At this point SIF does not have out-of-the-box support
for invoking web services that return response asynchronously.

Invoking Web Service from OA Framework

Invoking a web service from OA Framework is nothing but raising a business event using Java API
oracle.apps.fnd.wf.BusinessEvent.raise(). Only difference with web service invocation is that after the event raise
API, you could call String respData = (String)event.getResponseData();.

Following sample could be used in AMImpl.java for invocation.

// invoker business event


String eventName = "oracle.apps.prod.xxxx.invoke.service";
// unique key for the web service invocation
String eventKey = "key1";
267
www.AppsLead.com
// event data - XML payload sent to web service as input
// String evtData = ....
Connection conn = ((OADBTransactionImpl)getOADBTransaction()).getJdbcConnection();
BusinessEvent event = null;
try{
event = new BusinessEvent(eventName, eventKey);
event.setData(evtData);
event.raise(conn);
}
catch (BusinessEventException e) {
throw new OAException("Exception occured when invoking web service - "+e.getMessage());
} finally {
getOADBTransaction().commit();
}
String respData = (String)event.getResponseData();
return respData;

Extending SIF

Service Invocation Framework internally uses a Java subscription rule function


oracle.apps.fnd.wf.bes.WebServiceInvokerSubscription that implements interface
oracle.apps.fnd.wf.bes.SubscriptionInterface. Like any Java rule function the entry point from Business Event
System to the rule function is onBusinessEvent method. In order to perform Custom processing during web
service invocation, you could write your own Java rule function by implementing SubscriptionInterface and
extending WebServiceInvokeSubscription class to override the required methods. The custom rule function can
then be used in place of oracle.apps.fnd.wf.bes.WebServiceInvokerSubscription while consuming the web service
in the Invoke Web Service subscription wizard.

public class MyWebServiceInvoker


extends WebServiceInvokerSubscription
implements SubscriptionInterface
{
}
Click Here view a sample sub-class that extends SIF's default processing.

Extensible Methods

1. preInvokeService
2. postInvokeService
3. invokeService
4. addWSSecurityHeader
5. setInputParts

For more information on these extensible methods please refer to Integrated SOA Gateway Developer's Guide.

Rule function substitution

Once the Custom rule function is developed to extend SIF's processing, the class should be used at the time of
"Invoke Web Service" subscription definition as follows.

264
www.AppsLead.com
269
www.AppsLead.com
Clearing Profile Cache
It's a royal pain in the **** to bounce the apache everytime you change a profile value, especially during OA
page development. Well here is an easy way to clear the profile cache.

1. Login to APPS
2. Choose "Functional Administrator" responsibility
3. Navigate Core Services > Caching Framework > Cache Components
4. Search for %PROFILE%
5. Select "PROFILE_OPTION_CACHE" and "PROFILE_OPTION_CACHE_VALUES".
6. Press Clear Cache button.

273
www.AppsLead.com
Bounce Apache Server

R 12

Stop Server

sh $INST_TOP/admin/scripts/adoacorectl.sh stop

Start Server

sh $INST_TOP/admin/scripts/adoacorectl.sh start

R11

Stop Server

sh $COMMON_TOP/admin/scripts/KTPLDEV_trishul/adapcctl.sh stop

Start Server

sh $COMMON_TOP/admin/scripts/KTPLDEV_trishul/adapcctl.sh start

271
www.AppsLead.com
OAF Related Migrations from one Instance to Another

Migration of fully custom OAF page

Assuming that the custom page is created and running fine from JDeveloper, we need to perform below steps for
migrating the same to any instance:

1) From JDeveloper, rebuild the parent package corresponding to the page(s). This will compile all the files and
will be stored at <JDEV_USER_HOME>\myclasses. For example in below screenshot, on compiling emprec
package, corresponding class files get generated at
<JDEV_USER_HOME>\myclasses\xxcus\oracle\apps\fnd\emprec :

2) Connect to unix server and move files from classes folder to $JAVA_TOP.

Note: <JDEV_USER_HOME>\myclasses folder on local is equivalent to $JAVA_TOP on unix box.

So all files at <JDEV_USER_HOME>\myclasses\xxcus\oracle\apps\fnd\emprec will be moved to


$JAVA_TOP/xxcus/oracle/apps/fnd/emprec. If this folder structure is not present at $JAVA_TOP, we have create
those manually else we can simply move .class and .xml files.

3) Once all the files are moved, final step is to import the pages. Either we can import using Command Prompt
from local or we can do this on unix server as well.

Here are commands for both: Page Import Commands

For migration from one instance to another, only difference is that we need to copy files from $JAVA_TOP of one
instance and then move to $JAVA_TOP of other instance.

Migration of Personalization

1) Firstly do the personalization (like create item, change prompt, attach custom CO.. etc) on the page using
'Personalize page' link.

2) Copy path of the page from 'About this page' link. (for ex:
/oracle/apps/fnd/framework/toolbox/tutorial/webui/PoSearchPG)

3) Once you are done with personalization, go to 'Functional Administrator -> Personalization -> Import/Export'

4) Expand the directory structure upto /oracle/apps/fnd/framework/toolbox/tutorial/webui.

Under webui, if personalization is done at site level, its personalization file will be there at customizations/site/0.
271
www.AppsLead.com
At responsibility level -> customizations/responsibility/<resp_id>.

At function level -> customizations/function/<function_code>

5) So expand the appropriate folder under webui, select the file and click on 'Export to File System' button. It
should show a confirmation message as below:

6) This generates xml file on unix server with the same name as that of page having all details of personalization
on that page.

(Path on unix comes from profile 'FND: Personalization Document Root Path')

7) In order to migrate, move this file to unix server of another instance at path <profile 'FND: Personalization
Document Root Path'>/ followed by same directory structure.

8) Now login to another instance and go to 'Functional Administrator -> Personalization -> Import/Export ->
Exported Personalizations'.

9) Again expand the directory structure as we did in step4, select the file and this time click on 'Import from File
System' button.

Note: If the personalization is done at responsibility level, resp_id may vary from instance to instance. So we
have to change to folders and xml file accordingly.

270
www.AppsLead.com
Migration of Controller Extension

1) Assuming that controller is extended and compiled in JDeveloper. Also the custom controller is attached to the
page using personalization. (Controller Extension)

2) Firstly, move the class file of custom controller from <JDEV_USER_HOME>\myclasses to $JAVA_TOP followed
by similar path.

3) Then migrate the personalization part of attaching the custom controller to the page. (Same steps as
mentioned above in Migration of Personalization).

Migration of Substitutions

1) Extend BC4J component like VO, AM.. in JDeveloper and rebuild the same.

2) Once done with extension, go to project properties -> Business Components -> Substitutions

3) Select the base BC4J component on Available side and extended component on Substitute side and click on
add as shown below:

4) This will be added in the <proj>.jpx file.

5) In order to migrate this to instance, first move the xml and .class file related to extended BC4J component
from <JDEV_USER_HOME>\myclasses to $JAVA_TOP.

6) Import substitution using this jpx import command.

This is only one time process and for further migration from instance to instance, we can do this from 'Functional
Administrator -> Personalization -> Import/Export'.

If the migration is done first time to any instance, there is no need to bounce the server. However, if we are
remigrating files at $JAVA_TOP, we have to bounce OA core and apache server using below commands:

cd $ADMIN_SCRIPTS_HOME
adapcctl.sh stop

adoacorectl.sh stop

adapcctl.sh start

273
www.AppsLead.com
adoacorectl.sh start

272
www.AppsLead.com
Deploy OAF page

1. Copy all files from local machine to appropriate $JAVA_TOP directory

2. Compile all java files (Controller Files) with command javac <file_name>.java

3, Call java importer to import all xml files

java oracle.jrad.tools.xml.importer.XMLImporter
$JAVA_TOP/prajkumar/oracle/apps/fnd/webui/HelloWorldPG.xml -username apps -password apps -
dbconnection "(DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST= <name of
HOST>)(PORT=<port_number>))(CONNECT_DATA=(SID=<SID_NAME>)))" -rootdir $JAVA_TOP

4. Print Documents to check imported XML page content (Optional)

jdr_utils.printDocument('/prajkumar/oracle/apps/fnd/webui/HelloWorldPG',1000)

Example –

DECLARE

BEGIN

jdr_utils.printDocument('/prajkumar/oracle/apps/fnd/webui/HelloWorldPG',1000);

EXCEPTION

WHEN OTHERS THEN

DBMS_OUTPUT.PUT_LINE(SQLERRM);

END;

5. Create form function with property "SSWA jsp function" and


webhtml "OA.jsp?page=/prajkumar/oracle/apps/fnd/webui/HelloWorldPG"

276
www.AppsLead.com
277
www.AppsLead.com
6. Add function to menu

274
www.AppsLead.com
7. Add menu to responsibility

279
www.AppsLead.com
Register OAF page in Oracle Applications

We have already seen in our earlier articles about how to configure the OAF and steps to build Hello World page

using OAF. In this Tutorial we are going to see how to attach a Hello World Page to Oracle E-Bussiness Suite.

1. Move OAF files to Oracle Apps Server

2. Register the OAF page to Oracle E-Business suite

Step: 1 Follow below steps to move OAF project files into Oracle Apps server.

1. Find the server path where exactly to place the OAF project files into Oracle Applications server

I. Login to Putty

II. Execute cd $JAVA_TOP command to go to the JAVA TOP directory

III. Now execute pwdcommand to get the path where exactly the JAVA TOP is located in your sever.

example: /home/apps/apps/apps_st/comn/java/classes

243
www.AppsLead.com
2. Copy OAF Project Files into Oracle APPS Server

IV. Login to SecureFX or Winscpand go to the JAVA_TOP directory

V. Copy all the classfiles from local machine to appropriate $JAVA_TOP directory using SecureFX. On project

compilation in jDeveloper, the class files along with xml files are generated in Myclasses folder

(D:\OAF\jdevhome\jdev\myclasses) in local machine.

241
www.AppsLead.com
3. Run Import Script

VI. Switch to Putty window

VII. Run the below import scripts for each and every Page and External Regions to redirect them to MDS(Meta

Data Service) directory.

javaoracle.jrad.tools.xml.importer.XMLImporter

$JAVA_TOP/xxhw/oracle/apps/fnd/helloworld/webui/HelloWorldPG.xml -username apps -password password -

rootdir $JAVA_TOP -dbconnection “(DESCRIPTION=

(ADDRESS=(PROTOCOL=tcp)(HOST=r11.erpschools.com)(PORT=9076)) (CONNECT_DATA= (SID=VIS)))”

Step: 2 Register the OAF page to Oracle E-Business suite

1. Login to Oracle Application E-Business Suite. Got to System Administrator responsibility to create function. The

below image shows the navigation in System Administrator.

241
www.AppsLead.com
2. Function window will get opens. Give the details in each tab as shown below.

Description:

240
www.AppsLead.com
Properties:

Web HTML:

243
www.AppsLead.com
Save it.

3. Navigate to create menu. Application -> Menu

Give Menu name and function name. Design the menu structure according to the Oracle Applications.

242
www.AppsLead.com
4. Create a responsibility and add menu to responsibility, the below shows the responsibility navigation in System

Administration.

5. Now assign the menu to Responsibility as shown in the below image

246
www.AppsLead.com
6. Attach Responsibility to the User .

247
www.AppsLead.com
Now Bounce the server to reflect the changes.

The below image shows the example navigation of responsibility which we attached to E-business suite

244
www.AppsLead.com
Moving setup from one instance to another in oracle R12

The Generic Loader (FNDLOAD) is a concurrent program that can transfer Oracle Application entity data between
database and text file. The loader reads a configuration file to determine which entity to access. In simple words
FNDLOAD is used to transfer entity data from one instance/database to other. for example if you want to move a
concurrent program/menu/valuesets developed in DEVELOPMENT instance to PRODUCTION instance you can
direct use this command.

Steps to Move a Personalization from one instance(Database) to other

Define your Personalization and save it in first instance


Connect to your UNIX box on first instance and run the following command to download the .ldt file

FNDLOAD apps/apps 0 Y DOWNLOAD $FND_TOP/patch/115/import/affrmcus.lct file_name.ldt


FND_FORM_CUSTOM_RULES function_name=FUNCTION_NAME

Move the downloaded .ldf file to new instance(Use FTP)


Connect to your UNIX box on second instance and run the following command to upload the .ldt file

FNDLOAD apps/apps 0 Y UPLOAD $FND_TOP/patch/115/import/affrmcus.lct file_name.ldt

Note: Make sure you are giving proper .lct file in the commands and don’t confuse with .lct and .ldt files
These following are the other entity data types that we can move with FNDLOAD

1 - Printer Styles
FNDLOAD apps/apps O Y DOWNLOAD $FND_TOP/patch/115/import/afcppstl.lct file_name.ldt STYLE
PRINTER_STYLE_NAME="printer style name"

2 - Lookups
FNDLOAD apps/apps O Y DOWNLOAD $FND_TOP/patch/115/import/aflvmlu.lct file_name.ldt
FND_LOOKUP_TYPE APPLICATION_SHORT_NAME="FND"
LOOKUP_TYPE="lookup name"

3 - Descriptive Flexfield with all of specific Contexts


FNDLOAD apps/apps O Y DOWNLOAD $FND_TOP/patch/115/import/afffload.lct file_name.ldt DESC_FLEX
P_LEVEL=’COL_ALL:REF_ALL:CTX_ONE:SEG_ALL’ APPLICATION_SHORT_NAME="FND"
DESCRIPTIVE_FLEXFIELD_NAME="desc flex name" P_CONTEXT_CODE="context name"

4 - Key Flexfield Structures


FNDLOAD apps/apps O Y DOWNLOAD $FND_TOP/patch/115/import/afffload.lct file_name.ldt KEY_FLEX
P_LEVEL=’COL_ALL:FQL_ALL:SQL_ALL:STR_ONE:WFP_ALL:SHA_ALL:CVR_ALL:SEG_ALL’
APPLICATION_SHORT_NAME="FND" ID_FLEX_CODE="key flex code" P_STRUCTURE_CODE="structure name"

5 - Concurrent Programs
FNDLOAD apps/apps O Y DOWNLOAD $FND_TOP/patch/115/import/afcpprog.lct file_name.ldt PROGRAM
APPLICATION_SHORT_NAME="FND" CONCURRENT_PROGRAM_NAME="concurrent name"

6 - Value Sets
FNDLOAD apps/apps O Y DOWNLOAD $FND_TOP/patch/115/import/afffload.lct file_name.ldt
VALUE_SET_VALUE FLEX_VALUE_SET_NAME="value set name"

7 - Value Sets with values


FNDLOAD apps/apps O Y DOWNLOAD $FND_TOP/patch/115/import/afffload.lct file_name.ldt VALUE_SET
FLEX_VALUE_SET_NAME="value set name"

8 - Profile Options
FNDLOAD apps/apps O Y DOWNLOAD $FND_TOP/patch/115/import/afscprof.lct file_name.ldt PROFILE
PROFILE_NAME="profile option" APPLICATION_SHORT_NAME="FND"

9 - Request Groups
FNDLOAD apps/apps O Y DOWNLOAD $FND_TOP/patch/115/import/afcpreqg.lct file_name.ldt REQUEST_GROUP
REQUEST_GROUP_NAME="request group" APPLICATION_SHORT_NAME="FND"

249
www.AppsLead.com
10 - Request Sets
FNDLOAD apps/apps O Y DOWNLOAD $FND_TOP/patch/115/import/afcprset.lct file_name.ldt REQ_SET
APPLICATION_SHORT_NAME="FND" REQUEST_SET_NAME="request set"

11 - Responsibilities
FNDLOAD apps/apps O Y DOWNLOAD $FND_TOP/patch/115/import/afscursp.lct file_name.ldt
FND_RESPONSIBILITY RESP_KEY="responsibility"

12 - Menus
FNDLOAD apps/apps O Y DOWNLOAD $FND_TOP/patch/115/import/afsload.lct file_name.ldt MENU
MENU_NAME="menu_name"

13 - Forms Personalization
FNDLOAD apps/apps 0 Y DOWNLOAD $FND_TOP/patch/115/import/affrmcus.lct file_name.ldt
FND_FORM_CUSTOM_RULES function_name=FUNCTION_NAME

293
www.AppsLead.com
Deploying OAF Personalizations Using the Import/Export Command Line Tools

After personalizing and testing framework pages in a Development instance, you may wish to automate the
transfer of these changes to another instance, rather than manually re-doing them all again. This objective can be
achieved by exporting the personalizations from the Development instance, then importing them to a different
instance or instances

You can either use the GUI interface in “Functional Administrator” (Personalization tab) to transfer
personalizations, or can invoke the XMLImporter/XMLExporter commands directly from the command line. The
Export tool allows you to export a package or xml file (along with translation information) from the MDS
repository of a database instance to a .xml file (or .xlf file for translations). The command line Export tool is
necessary if you wish to perform bulk translations of personalization documents.

This post provides the below detailed steps how to transfer personalizations from one instance to others using
the XMLImporter/XMLExporter tool.

1. Get Document Name

Go to the page you want to copy the personalization from and click the “about this Page” link at the bottom of
the page. You will see the page name with full path which starts with /oracle/apps/ .

Ex: /oracle/apps/icx/por/wf/webui/ReqLinesNotificationsRN

2. Get the Personalization Document info

Run the following command in TOAD or other tools as APPS user

set serveroutput on
exec jdr_utils.listCustomizations('<full document name from step 1>');

1 set serveroutput on

2 exec jdr_utils.listCustomizations('<full document name from step 1>');

Example:

set serveroutput on
exec jdr_utils.listCustomizations('/oracle/apps/icx/por/w f/w ebui/ReqLinesNotificationsRN');

1 set serveroutput on

2 exec jdr_utils.listCustomizations('/oracle/apps/icx/por/wf/webui/ReqLinesNotificationsRN');

Output:

anonymous block completed

/oracle/apps/icx/por/wf/webui/customizations/site/0/ReqLinesNotificationsRN

291
www.AppsLead.com
Note: If there are multiple records returned by this command, you will need to use export/import each item
individually that you wish to export. You may also find there are records returned for seeded personalizations
provided by Oracle which do not need to be exported.

3. Use XMLExporter to export personalization document


java
oracle.jrad.tools.xml.exporter.XMLExporter <personalization document
from step #2> \
-username "<username>" -passw ord "<passw ord>" \
-dbconnection

java oracle.jrad.tools.xml.exporter.XMLExporter <personalization document from step #2> \


1
-username "<username>" -password "<password>" \
2
-dbconnection
3
"(description=(address_list=(address=(protocol=tcp)(host=<host>)(port=<port)))(connect_data=(sid=<sid>)))" \
4
-rootdir "<output directory>"

Example:

java
oracle.jrad.tools.xml.exporter.XMLExporter \
/oracle/apps/icx/por/w f/w ebui/customizations/site/0/ReqLinesNotificationsRN
-username apps -passw ord w 3lcome123 \
-dbconnection

java oracle.jrad.tools.xml.exporter.XMLExporter \
1 /oracle/apps/icx/por/wf/webui/customizations/site/0/ReqLinesNotificationsRN -username apps -password
w3lcome123 \
2
-dbconnection
3
"(description=(address_list=(address=(protocol=tcp)(host=myhost)(port=12345)))(connect_data=(sid=dev)))" -
rootdir "$XXSCM_TOP/install" \

Here one file named ReqLinesNotificationsRN.xml will be created in the below path:
XXSCM_TOP/install/oracle/apps/icx/por/wf/webui/customizations/site/0. Open the file and you will able to view
the personalizations that you have done.

4. Use XMLImporter to import personalization document

Run the below command in the Instance where you want to import your personalization.

java
oracle.jrad.tools.xml.importer.XMLImporter \
<full path of the file you w ant to import> \
-username "<username>" -passw ord "<passw ord>" \
-dbconnection

java oracle.jrad.tools.xml.importer.XMLImporter \
1
<full path of the file you want to import> \
2
-username "<username>" -password "<password>" \
3
-dbconnection

291
www.AppsLead.com
4 "(description=(address_list=(address=(protocol=tcp)(host=<host>)(port=<port>)))(connect_data=(sid=<sid>)))"
-rootdir "<top level directory>" \
5
-rootPackage "/oracle/apps/<prod>"

Example:

java
oracle.jrad.tools.xml.importer.XMLImporter \
$XXSCM_TOP/install/ReqLinesNotificationsRN.xml \
-username apps -passw ord w 3lcome123 \
-dbconnection "(description=(address_list=(address=(protocol=tcp)(host=

java oracle.jrad.tools.xml.importer.XMLImporter \
1
$XXSCM_TOP/install/ReqLinesNotificationsRN.xml \
2
-username apps -password w3lcome123 \
3
-dbconnection "(description=(address_list=(address=(protocol=tcp)(host=
4
myhost)(port=12345)))(connect_data=(sid=dev)))" -rootdir "$XXSCM_TOP/install" \
5
-rootPackage "oracle/apps/icx/por/wf/server"

290
www.AppsLead.com
Migrating Personalization from one instance to another.

http://digitalspace.wordpress.com/2010/07/13/migrating-personalization-from-one-instance-to-another/

How to avoid Integration Problems in OAF???

Identify an owner for each component or module. – The Integrator!

Responsibilitites of an integrator :

Be a single point of contact to do the following :

Integrate

Test

Deploy

Maintain code Versions

Proper documentation can reduce integration problems.

Mention the author name, date of creation and purpose before writing each and every method or newly written
code block in common objects like Application Module, Entity Object etc. This will not only make the integration
easy but also helps in easy debugging at later stages.

Never replace an existing file (other than PG.xml file) with the updated file while integrating the code. And if u
are adding any new VOs directly into the folder structure (not from jdeveloper) ensure that u are updating the
server.xml file also.

293
www.AppsLead.com
How to deploy JAR file into R12 server in OA

Steps to add JAR file into R12 server in OA --

1. Deploy your JAR file at some custom location in R12 server

i.e. –

/u01/app/apnac03r12/XX_TEST/

1. Open “orion-application.xml” file present at path –

$ORA_CONFIG_HOME/10.1.3/j2ee/oacore/application-deployments/oacore/

3. Edit “orion-application.xml” file to add JAR file path

i.e. –

<library path="/u01/app/apnac03r12/XX_TEST/jxl.jar" />

292
www.AppsLead.com
4. Bounce Apache Server

296
www.AppsLead.com
OA Framework Interview Questions

1) What is BC4J and what are all the components of BC4J?


Business Components for Java is JDeveloper's programming framework for building multitier database
applications from reusable business components. Such applications typically consist of:
• A client-side user interface written in Java and/or HTML.
• One or more business logic tier components that provide business logic and views of business objects.
• Tables on the database server that store the underlying data.
Components of BC4J:
• Entity Object - EO encapsulates the business logic and rules. EO’s are used for Inserting, Updating and Deleting
data. This is used for validating across the applications.
• View Object - View object encapsulates the database query. It is used for selecting data. It provides iteration
over a query result set. VO’s are primarily based on EO’s. It can be used on multiple EO’s if the UI is for update.
• Application Module - Application Modules serve as containers for related BC4J components. The pages are
related by participating in the same task. It also defines the logical data model and business methods needed.
2) What is an EO?
EO encapsulates the business logic and rules.EO’s are used for Inserting, Updating and Deleting data. This is used
for validating across the applications. We can also link to other EO’s and create a Association object.
3) What is an VO?
View object encapsulates the database query. It is used for selecting data. It provides iteration over a query
result set.VO’s are primarily based on Eo’s. It can be used on multiple EO’s if the UI is for update. It provides a
single point of contact for getting and setting entity object values. It can be linked together to form View Links.
4) What is an AO?
An association object is created where we link EO’s. For example take the search page where we link the same
EO to form a association between the manager and employee. Every employee should have a manager
associated. But if it President then no there is no manager associated. This is a perfect example to understand
the AO.
5) What is an VL?
A view link is an active link between view links. A view link can be created by providing the source and
destination views and source and destination attributes. There are two modes of View link operation that can be
performed. A document and Master/Detail operation.
6). What is UIX?
UIX is an extensible, J2EE-based framework for building web applications. It is based on the Model-View-
Controller (MVC) design pattern, which provides the foundation for building scalable enterprise web applications.
7). VO is located in the View Layer in MVC which is responsible for presenting the data to the user.
9) Which package should include EO and AO.
The EO and AO will be present in the schema.server package.
10) What is the difference between inline lov and external lov.
Inline lov is a lov which is used only for that particular page for which it was created and cannot be used by any
other page.
External lov is a common lov which can be used by any page. It is a common component for any page to use it. It
can be used by giving the full path of the lov in the properties section “External LOV” of the item.
11) what is a Javabean?
JavaBeans is an object-oriented programming interface that lets you build re-useable applications or program
building blocks called components that can be deployed in a network on any major operating system platform.
12) What is query Bean?
QueryBean is used to execute and return the results of a query on behalf of the QueryPortlet application.
13) what is the difference between autocustomization criteria and result based search?
Results based search generates search items automatically based on the columns on the results table.
In Autocustomization search we need to set what all fields are required to display as a search criteria.
14) what is MDS?
MDS is MetaData Service. When a web page is broken into small units like buttons,fields etc they are stored in a
database. These are not stored as binary files but as data in tables. The data are present in JDR tables. MDS
provides service to store & return page definitions. MDS collects those definitions in components/fields in a
meaningful manner to build a page.
15) What is XML?
XML is a markup language for documents containing structured information.
Structured information contains both content (words, pictures, etc.) and some indication of what role that

297
www.AppsLead.com
content plays (for example, content in a section heading has a different meaning from content in a footnote,
which means something different than content in a figure caption or content in a database table, etc.).

16) What is the difference between customization and extension?


Customization is under direct user control. The user explicitly selects between certain options. Some
customization examples include:
Altering the functionality of an application
Altering existing UI
Altering existing business logic

Extension is about extending the functionality of an application beyond what can be done through
personalization. Some extensibility examples include:

Add new functional flows


Extend or override existing business logic
New application/module
New page
New attribute
Extend/Override defaults & validations

17) What is Personalization?


Personalization enables you to declaratively tailor the UI look-and-feel, layout or visibility of page content to suit
a business need or a user preference. Some personalization examples include:
• Tailor the order in which table columns are displayed.
• Tailor a query result.
• Tailor the color scheme of the UI.
• Folder Forms
• Forms Personalization
• Oracle Application Framework (OAF)

20) What is rootAM?


The application module which is associated with the top-level page region (the pageLayout region) is root
application module.

21) Why Should we give retainAM=Y?


The AM should be retained whenever you are navigating away from a page and when you know that there is a
possibility to come back to the page again and data is to be retained. Example : Any navigation link that opens in
a new page or any navigation which has a back button to come back to the initial page.
The AM should not be retained for two independent pages, especially if they have common VOs which fetch
different result sets. In such cases, retaining the AM may not remove the cache of VOs and so the result may not
be as expected.

22) What is the significance of addBreadCrumb=Y


The basic intention of the breadcrumb is to let the user know of the navigation path he took to reach the current
page.

23) How do you find right jdev patch for your oracle application version.
Search in oracle.metalink.com as Jdev with OA Extension.

24) What are the tools you had used for decompiling java class?
Jad is one of the tool for decompiling the java class.

Posted by Anuj Kumar at 3:04 AM 2 comments:

294
www.AppsLead.com
OA Framework Best Practices

AM Retention : Retaining the AM where not required, Not retaining it wherever required – both are
dangerous!!

The AM should be retained whenever you are navigating away from a page and when you know that

there is a possibility to come back to the page again and data is to be retained. Example : Any

navigation link that opens in a new page or any navigation which has a back button to come back to the
initial page.

The AM should not be retained for two independent pages, especially if they have common VOs which

fetch different result sets. In such cases, retaining the AM may not remove the cache of VOs and so the
result may not be as expected.

Setting dynamic whereClause : Avoid setting where clauses dynamically as far as possible. And when

required, set the where clause and where clause params to null before setting your new where clause.

Remember that the where clause once set will be retained through out. So it’s a best practice to make

it null wherever it is not required. Creating two VOs is always better than using a single VO with two
dynamic where clauses.

Fetch Profile Value : Fetching the values like profile , orgId, testFunction etc can be done in two ways.

1. Fetching it from pageContext.

Syntax : pageContext.getProfile(‘XXWHO_ENTITY’);
2. Write a VO to query the values directly from the data base.

Syntax: SELECT FND_PROFILE.VALUE(‘XXWHO_ENTITY’) FROM DUAL

The first option brings the data from the cache, so it takes time for the changed values to be

reflected in front-end. But the second option is costly performance wise. So its better to invalidate
cache regularly and use the first option to fetch such kind of values.

Whenever you are executing a VO or creating rows in a VO in the process request, do it conditionally.
Let it not get executed every time the process request is called.

Ex: if(fromPage == “CorrectPage”) {

vo.executeQuery();

299
www.AppsLead.com
This avoids duplicate data or data loss whenever your page is rendered from a dialog page or back
button etc.

If you want any values of your CO to be available in your EO, put those values in transaction. Do this

only if it is very much required. Should not create unnecessary transactions anywhere. Only get the
already existing transaction object from AM using getTransaction() Method.

Make it a point to remove all the session parameters and transaction parameters soon after their

utilization. Should be very careful with session parameters because they result in unnecessary data and
it’s often difficult to debug.

Passing too many parameters through hashmap not only effects the performance but it also effects the
UI

Avoid writing huge code in CO. No business logic should be written in the CO or AM. Try creating private
methods in controller wherever you have redundant code.

Create separate interface per module for declaring all your constant variables rather than hardcoding
the values in the code.

Ex : You want to use a lookup name n number of times in your coding. Instead of hardcoding it

everywhere, declare it in your constants interface and use the constant in your code. Tomorrow, If you

have to change the lookup, you can change it at a single place (in the constants interface) and save
time.

Whenever you have to get or set values of a VO use get/set<Attribute_name> method instead of

getAttribute(index) method. Because the getAttribute(index) traverses through the entire attributeset
in order to find the required attribute which is a performance issue

Ex: Say, you have an attribute called SelectFlag with attribute index as n . To get the value, use
getSelectFlag instead of getAttribute(n).

633
www.AppsLead.com
HGrid cache: Hgrid is one of the components in OAF which gives major surprises to the developer

everytime. Should be very careful while creating the viewlink. Remember to clear the cache of the hgrid
each time the hgrid is rendered or the hgrid query is executed.

Syntax : hgridBean.clearCache();

To expand the hgrid upto nth level by default (i.e to expand the tree structure upto nth child), use the
following syntax :

hgridBean.setAutoExpansionMaxLevels(n);

Better to call sequences from the create method of EO rather than calling them from custom methods
in AM. Infact, set all the default values or who columns for attributes here only.

Always reset a VO before iterating it. Especially when getting the values of a radio button selection etc.

Ex :

vo.reset();

while(vo.hasNext()){

// get handle of the vo’s current row and perform ur operations;

// break the loop after reaching the last record of the current rowset.

Set any VO’s where clause and where clause params in VOImpl class rather than creating directly in CO.

This increases reusability and modularity. But you don’t have to set any where clause or where clause

params and should directly execute the query, then need not use VOImpl for calling the executeQuery()
method.

Exception Handling : Proper exception handling is a must. Put your code in proper try –catch blocks
wherever possible.

If your code ,which is in try-catch block, have to throw OAException anywhere, that will be caught and

will not be shown to the user. Hence use the following statement in the catch block to throw the

OAExceptions to the user :

try{

throw new OAException(“APP_CODE”, “ERROR_MSG”);


}catch(Exception _exception) {

631
www.AppsLead.com
throw OAException.wrapperException(_exception);

Use the following syntax for logging your exception in the log file

if(pageContext.isLoggingEnabled(4)) {

pageContext.writeDiagnostics(getClass().getName()+”.processFormRequest”, “Exception Details : “, 4);

Do not catch your exceptions wherever they occurred (ex in AM). The exception must always be

thrown back to the calling method . So all the exceptions must be finally caught in the CO.

Calling AM methods in CO : Those of you who have used invokeMethod() in CO to call the AM methods

might have observed that it’s the most tedious way of calling methods, especially when you have to

send serialized parameters. Importing the AMImpl class in your controller allows you to access the AM

methods directly without the use of invokeMethod() but it breaks the basic OAF standards coz u r

accessing a class in the server package from a class in the webui package. To overcome the above, the

best practice is to create an Interface of the AMImpl (which neither belongs to server nor webui) and

use this AM Interface in your CO rather than AMImpl class. To create an interface in Jdeveloper, double

click on the AM , select ‘client methods’ and shuttle the required methods to right side. It automatically
creates an interface for you with the selected methods.

Example for getting the object of the interface :

XXWPHomeWorkPlanAM workPlanHomeAM =

(XXWPHomeWorkPlanAM)pageContext.getApplicationModule(webBean).findApplicationModule(“XXWPHomeW

orkPlanAM

 Understanding Query Regions


When you add a query region to a pageLayout region, OA Framework automatically generates an
oracle.apps.fnd.framework.webui.beans.layout.OAQueryBean which, depending on its configuration, works in
concert with a child table, advanced table or HGrid to implement any combination of simple search, advanced
search and view panels. OA Framework automatically generates buttons as appropriate for toggling between the
applicable regions.

 Construction Modes:
There are three construction modes available. In the above example we have
used ‘resultBasedSearch’construction mode. Here is a brief comparison of the three modes.

1] resultsBasedSearch:

 OA Framework automatically renders both the Simple and Advanced search regions based on the
designated queryable items in the associated table.
 The search regions automatically include both a Go and a Clear button.
 OA Framework automatically executes the underlying search when the user selects the Go button.
2] autoCustomizationCriteria:

631
www.AppsLead.com
 OA Framework automatically renders both the Simple and Advanced search regions based on the
corresponding Simple search and Advanced search regions that you define and specify as named
children of the query region.
 The search regions automatically include a Go button. In addition, the Advanced search region includes
a Clear button.
 OA Framework automatically executes the underlying search when the user selects the Go button.
However, developers must explicitly define mappings between items in the Search panel and items in
the table region.
3] none

 The Search regions are rendered based on the Simple Search and Advanced Search regions that you
define and specify as named children of the query region.
 You must implement your own Go button in this mode.
 The underlying search must be executed by the developer.

630
www.AppsLead.com
Best Blog

http://apps2fusion.com/apps/oa-framework/oa-framework-training

https://blogs.oracle.com/prajkumar/entry/controller_extension_in_oaf

https://blogs.oracle.com/manojmadhusoodanan/entry/entity_object_based_on_pl

http://iwidi.org/index.php/oaf

http://oracle.anilpassi.com/

http://mukx.blogspot.com/2007/11/setting-default-selected-date-for.html

http://sushantsharmaa.blogspot.in/2013/09/19-embedding-adf-region-into-oaf-page.html

http://myoraclecafe.com/category/oracle/oracle-technologies/oa-framework/

http://ramumble.blogspot.in/2008/03/oaf-lov-overriding-default-where-clause.html

633
www.AppsLead.com
Video
http://www.youtube.com/watch?v=BaW6KbhfvNg&context=C3a223caADOEgsToPDskKLVDq1cmksjkRYhfNTe-8D
http://www.youtube.com/watch?v=_xTfRIRPsNU&list=UULojfddCqU-UMJ0u0oyRg4Q&index=8&feature=plcp
http://www.youtube.com/watch?v=Yqoj2TvoQYk&list=UUDMHy-rJiplTyNPYIm4AQ1w&index=32&feature=plcp

http://www.youtube.com/watch?v=Sv9K1usOeWk&list=UUDMHy-rJiplTyNPYIm4AQ1w&index=33&feature=plcp

http://www.youtube.com/watch?v=keSzvhliOZ0&list=UUDMHy-rJiplTyNPYIm4AQ1w&index=34&feature=plcp

http://www.youtube.com/watch?v=QImS8gIWTF4&list=UUjdkzv8ai9H4LT1jwkJTgBA&index=14&feature=plcp

http://www.youtube.com/watch?v=Rn9uRDCge0E&context=C337b365ADOEgsToPDskIPjJuOk-m9yiYwp4IRLbsu

http://www.youtube.com/watch?v=h9lncOBUviw&context=C368bedfADOEgsToPDskITfNWDHGUMw51bdoYc9N
WJ

http://www.youtube.com/watch?v=2sZya4PciYE&context=C36b2330ADOEgsToPDskJZ-U8l4w61c5EJ_mNyYA5N

http://www.youtube.com/watch?v=AP1HbKS1JsY&context=C39928c1ADOEgsToPDskLmCW6T8jn141uICcUJZi4h

http://www.youtube.com/watch?v=BaW6KbhfvNg&context=C3a223caADOEgsToPDskKLVDq1cmksjkRYhfNTe

http://www.youtube.com/watch?v=1nDOMQOOzrw&list=UULojfddCqU-
UMJ0u0oyRg4Q&index=13&feature=plcp

632
www.AppsLead.com

You might also like