View
122
Download
1
Category
Tags:
Preview:
DESCRIPTION
OA
Citation preview
Bolton Carroll
Management Consultant
ROLTA
carrollb@tusc.com
Agenda
• OA Framework Extensions Overview
• OA Framework Extension vs Personalization
• OA Framework Extension Examples
• Some Tips and Techniques
• Best Practices
• Questions
OA Framework Overview
• OA Framework is a technology stack, which allows
extensions to the “self-service” or html style pages within
Oracle E-Business Suite.
• It is based on the industry standard model-view-
controller (MVC) architecture and includes the following
technologies/tools: UI XML (UIX), Business Components
for Java (BC4J), Application Object Library (AOL), Meta
Data Service (MDS), and Jdeveloper 9i or 10g.
• OA Framework was used to build the html web pages in
Oracle E-Business Suite for both Release 11i and
Release 12, and it is the Oracle recommended
technology for customizing or extending the Oracle E-
Business Suite.
Model – View - Controller
Model – View - Controller
• Model-View-Controller is a design pattern which separates an
application into 3 basic layers
• The Model represents the data model and the business logic,
which are managed in xml definition files and java classes.
The model includes entity objects, view objects, and
application modules. These different types of objects are all
part of the Business Components for Java (BC4J).
• The View is what the user sees. The page definition is a
hierarchy of web beans, with each web bean corresponding
to either a region or an item object.
• The Controller is a java class file that is tied to either a page
or region level, and is responsible for rendering the page or
region, handling the user actions, and determining the flow of
pages
Key Profile Options
• Personalize Self-Service Defn
• Yes enables personalization link on all pages
• FND: Personalization Region Link Enabled
• Yes displays all regional links
• Minimal displays key regional links
• Disable Self-Service Personal
• Turn off all personalizations
• FND: Personalization Document Root Path
• Used for importing/exporting personalizations
Key Profile Options
• FND: Diagnostics
• Activates the link called About this Page at
bottom left of page and allows logging to screen
• FND:OA:Enable Defaults
• Allows defaulting through personalizations to take
place
• Fnd Xliff Export Root Path
• Sets root path for translation files
Personalizations vs Extensions
• Personalizations do not involve the use of
JDeveloper
• Personalizations are for simple modifications to
the web pages
• Personalizations can be accomplished by
functional users
• Extensions involve using Jdeveloper
• Extensions often involve the use of
Personalizations
Personalizations vs Extensions
• Most common personalizations are rendering,
read only, required, and prompt
• Custom Views are also considered
personalizations and allow changing the display
of table data for specific responsibilities
• Basic Steps for a personalization: Click on
Personalize page link, find item, click on
personalize icon for the item, select item
property to modify, and modify appropriate level
with new setting
Personalizations vs Extensions: Buttons
• Personalizations can be used to create a button
or link with a url as a destination
• Personalizations can be used to create an
export button which allows exporting of table
data
• Personalizations can not create a submit button
• An extension would be needed to create a
submit button and the logic to handle the submit
process
Personalizations vs Extensions: Flexfields
• Personalizations can be used to add flexfields to
a page
• Personalizations can specify which segments of
a flexfield to display (independent of the flexfield
definition)
• Extensions are needed to default values in a
flexfield
• Extensions are needed to make specific
segments of a flexfield conditionally mandatory,
independent of the flexfield definition
Examples of Possible Extensions
• Setting properties of flexfield context value or
flexfield segments (conditional properties based
on other fields or actions on the page)
• Setting initial properties of any field on the page
based on the value of another field on the page
• Changing properties of a field based on a
change to another field on the page
• Adding a special checkbox which will trigger
special validation
Examples of Possible Extensions
• Force upper case characters in a particular field
• Only allow characters and numbers in a
particular field
• Modify an lov on a page
• Write information to a custom table based on
user actions
• Change the navigation flow, such as skipping
over a page or restricting access to a page
• Combine the information from multiple tabs on a
page into one tab on that page
Personalization Example
• Step 1: Click on personalize link
Personalization Example
• Step 2: Find item to personalize and click
personalize icon
Personalization Example
• Examples of setting different properties
Personalization Example
• Setting default value
Personalization Possibilities
Personalization Possibilities
Personalization Possibilities
Adding a Field To a Page
• Through Personalization
• When field is already part of VO
• Just add an item and set VO Name and attribute
name
• Through an Extension
• When field is not part of VO
• Extend VO to add extra field and modify the sql
statement of the VO
• Add a personalization to display the new field
Adding a Field to a Table
• Click on personalize link on the page or region
Adding a Field to a Table
• Click About this Page, and then expand all to see all the
fields and to determine the name of the View Object for
the table
Adding a Field to a Table
• In expanded mode, find the View Object for the table
where you want to add an extra field (AllReqsVO)
• In this example, we will add EmergencyPoNum (actually
it’s just hidden at this point, but we are adding it as an
example)
Adding a Field to a Table
• Find the view object attribute for the field you need
Adding a Field to a Table
• Create new item within the table
Adding a Field to a Table
• Created item type of message styled text and give a
custom name to the id
Adding a Field to a Table
• Specify name of View attribute, View Object, and prompt
for your new column, then click Apply
Adding a Field to a Table
• View results of new field
Extension to Add a Field
• Move class file directories needed by page you are modifying from
apps server to myclasses directory on your client (e.g. for purchase
order you will need $JAVA_TOP/oracle/apps/po directory)
• Move xml files of pages you are modifying from $Product_TOP/mds/
directory on server to client myprojects directory
• Move VO xml and class files of VO you are modifying from
myclasses directory on your client to myprojects directory on your
client
• Create a new VO as an extension of the original
• While creating new VO, add extra field as a new attribute and
modify SQL statement of VO
• Create substitution rule in project properties to substitute new VO
• Set project properties to use substitution rule
• Add new field to page using a personalization
Extension to Add a Field – detailed steps
1. Right click on project and select New, Business Tier, ADF
Business Components, View Object
2. Enter or browse for package for custom VO:
xxapl.oracle.apps…..
3. Enter name of VO Object xxaplObjectVO
4. Browse for original VO that is being extended
5. Click Next
6. Click Back immediately after (this allows us to change
updateable box)
7. Click on checkbox for updateable access
8. Click Next
9. Click Next to get to Step 3 (Attributes)
10. Under list on right, click New button
11. Type attribute name for new field
Extension to Add a Field – detailed steps
12. Click Mapped to Column or SQL checkbox
13. Enter Alias and Expression (alias is sql alias, expression is sql
database column)
14. Click OK
15. Click Finish
16. Find new VO you created and right click to edit
17. Go to SQL Statement
18. Change sql to add your column (expression and alias must
match your attribute)
19. Click Apply
20. Click Attribute Mappings
21. Check to make sure attribute is mapped to sql column
22. Click OK
Extension to Validate a Field
• Validation can be done through an Entity Object
extension or a Controller extension
• Entity Object: Advantage is that 1 extension will
do validation for any VO accessing that entity
object, even if there are multiple VO’s
• Controller: Good way to do extension when
there is no entity object on the page and you
need to call a sql statement for validation
• Oracle Developer’s Guide does not recommend
putting validation rules in VO or in Application
Module
Entity Object Extension - Validation
• Validation can be done on either the
field level or record level
• Field level validation: insert custom
code in “setter” of the specific field
• Record level validation: insert custom
code in validateEntity() method
Entity Object Extension - Validation
• Field level validation example (in EOImpl class):public void setUnitPrice(Number value)
{
if (value != null)
{
If (value.compareTo(10000) > 0)
{ throw new
OAAttrValException(OAException.TYP_ENTITY_OBJECT,
getEntityDef().getFullName(), // EO name
getPrimaryKey(), // EO PK
"UnitPrice", // Attribute Name
value, // Attribute value
"AK", // Message product short name
"FWK_TBX_T_PO_PRICE_EXCEEDED"); // Message name
}
}
super.setUnitPrice(value);
}
Entity Object Extension - Validation
• Record level validation example (in EOImpl class):
protected void validateEntity()
{
super.validateEntity();
if (condition)
{
throw new OARowValException(OARowValException.TYP_ENTITY_OBJECT,
getEntityDef().getFullName(),
getPrimaryKey(),
"AK", // Message product short name,
"FWK_TBX_T_PO_NO_DELETE"); // Message name
}
}
Entity Object Extension - Validation
• Import statements that may be needed
import oracle.apps.fnd.framework.OAAttrValException;
import oracle.apps.fnd.framework.OAException;
import oracle.apps.fnd.framework.OARowValException;
Controller Extension - Validation
• Identify the controller that gets called when
Apply or Save is pressed (use About this page)
• If there are multiple controllers, look at Oracle’s
code to see which one handles Apply button
• Create a new java file which extends the
standard controller
• Create your validation in the
processFormRequest method
• Personalize the page to point to your custom
controller
Controller Extension - Validation
• Extend the standard controller
public class xxcusBasicInformationCO extends
BasicInformationCO {
public xxcusBasicInformationCO() {
}
public void processFormRequest(OAPageContext
oapagecontext, OAWebBean oawebbean)
{
…………
Controller Extension - Validation
• Logic to put into processFormRequest method
• Check for an Apply or Save button
action
• Get a handle on the field
• Check the value against an expected
value
• If necessary throw an OAException
• Call super.processFormRequest
Controller Extension - Validation
• Example (validate length of a field):
if(oapagecontext.getParameter("Apply") != null)
{
String longName =
oapagecontext.getParameter("LongName");
if (longName != null && longName.length() > 70) {
throw new OAException("Error with Long Name: " +
longName + " Length: " + longName.length() +
" Error: " + longNameError);
}
}
super.processFormRequest(oapagecontext,
oawebbean);
Controller Extension - Validation
• Adding custom controller through
personalization
Setting Default Values
• Personalization: Only works for following items:
MessageTextInput, MessageLOVInput,
MessageCheckBox, MessageChoice,
MessageRadioButton, MessageRadioGroup
• Change property called Initial Value
• Only works if profile option FND:OA:Enable
Defaults is set to Yes
• In some cases, a “default” personalization will
not take effect due to defaulting logic of Oracle
Defaulting through Personalization
• Setting default value
Defaulting Values in Entity Object
• Extend EO and override create method in the
EOImpl class
• Call a “setter” method
• Example:import oracle.jbo.AttributeList;
…..
public void create(AttributeList attributeList)
{
super.create(attributeList);
// Add or change the default values here.
// EXAMPLE: setPaymentTermsCode("NET_60");
}
Defaulting Values in View Object
• Extend the VO
• Add a method to override the insertRow method
in the VORowImpl class
• Use this code:
super.insertRow();
row.setAttribute(“<attributename>”,<attributevalue>);
• Mainly used when there is not an entity object to
extend (e.g. when VO is based on
OAPlsqlViewRowImpl)
Defaulting Values in Controller
• Extend Controller and override ProcessRequest
method
• Find the web bean you want to default
• Set the value on the web bean using the
appropriate “set” method
• Include logic so that you are only setting the
value when the appropriate button has been
pressed (such as a Create Button)
• Create a personalization to point to the new
custom controller
Complex Extension Example
• Buyer Work Center: A change to the purchase order line
item category should change the line type and the item
class automatically. Then the flexfield should
automatically change since the item class is the context
of the flexfield
• Solution: Controller extension
• processFormRequest method: • check the lov input source for a change in category
• Based on category, find line type and item class
• Store new values in page parameters
• Refresh the page
• processRequest method: • Check page parameters for new values
• Populate line type and item class with new values if they exist
• If item class changed, refresh the flexfield
Tip: Simple SQL Validation
• Simple sql lookup in a controller
• Standard practice would be to
• create a custom VO for that sql statement,
• extend the AM to include the custom VO and an init routine
• Add an init routine in the controller to call the init routine in the
AM
• Another option is to dynamically create a VO
• Advantages:
• No need to extend AM
• No need to create a custom VO
• All custom code is in a controller, and this can easily be turned
off by turning off the personalization that points to the custom
controller
Tip: Simple SQL Validation
• Steps are:
• Define variable to hold query
• Look for VO, if it does not exist, create it
• Set where clause parameters
• Execute query
• Get result
Tip: Simple SQL Validation (con.)
In processRequest or in processFormRequest
String xxcusCatQuery = "select value from …..where id = :1 ";
OAApplicationModule am = pageContext.getRootApplicationModule();
ViewObject catVO = (ViewObject)am.findViewObject("xxcusCategoryVO");
if (catVO == null) {
catVO =
am.createViewObjectFromQueryStmt("xxcusCategoryVO",xxcusCatQuery);
}
catVO.setWhereClauseParams(null);
if (newCategory != null) {
catVO.setWhereClauseParam(0,newCategory);
catVO.executeQuery();
oracle.jbo.Row row = catVO.first();
if (row != null)
{ xxcusAttCategory = (String)row.getAttribute(0);
}}
Tip: Adding a custom AM
• Technique to automatically attach your custom
code to the current AM without extending the
current AM
• Steps involved:
• Create your custom routines in a custom
application module
• Extend the controller
• Get handle on current application module
• Look for the custom application module, if it does not
exist create it within the current application module
• Call your routines in the custom application module
Tip: Adding a custom AM (con.)
if(oapagecontext.getParameter("Apply") != null){
String taskNumber = oapagecontext.getParameter("paElementNumber");
OAApplicationModule oaapplicationmodule =
oapagecontext.getApplicationModule(oawebbean);
OAApplicationModule nam =
(OAApplicationModule)oaapplicationmodule.findApplicationModule("xxcusTabSetupA
M");
if (nam == null)
nam = (OAApplicationModule)oaapplicationmodule.createApplicationModule
("xxcusTabSetupAM",
"oracle.apps.xxcus.pa.util.server.xxcusTabSetupAM");
……
Serializable aserializable2[] = { taskNumber };
String validResult = (String)nam.invokeMethod("validateCreateTask", aserializable2);
if (validResult != null && !"".equals(validResult))
{
throw new OAException("Error with Task Number: " + taskNumber + " Error: " +
validResult);
} }
super.processFormRequest(oapagecontext, oawebbean);
Tip: Displaying all the page parameters
• Page parameters can be displayed through
logging on screen, but that is not always
successful
• Sometimes it is useful to error out a page at time
of a submit or save to see all the parameters
• Parameters can be very useful to determine
where the user is coming from and to see some
key values
Tip: Displaying all the page parameters (con.)
import java.util.Enumeration;
public void processFormRequest(OAPageContext oapagecontext, OAWebBean
oawebbean)
{
if(oapagecontext.getParameter("Apply") != null)
{
StringBuffer buf = new StringBuffer("Params: ");
Enumeration enumer = oapagecontext.getParameterNames();
String key = "";
while ( enumer.hasMoreElements() )
{ key = (String) enumer.nextElement();
if( oapagecontext.getParameter( key ) != null)
{
buf.append("--"+ key+ ":" +
oapagecontext.getParameter(key));
}
}
throw new OAException(buf.toString(),OAException.ERROR);
Tip: Displaying all the page parameters (con.)
• Result of throwing error with parameter values
Tip: Using jdr_utils package
• Jdr_utils.listCustomizations to show all
customizations on a specific page
• jdr_utils.printDocument to show a page, a
region, or a personalization
• Identify personalizations with listCustomizations
and then each personalization can be displayed
(in xml format) with printDocument
• Customizations include personalizations,
extensions of BC4J objects, and views (Oracle
seeded and your custom views)
Tip: Using jdr_utils package
• Example: to see customizations on Purchase Order
page
• jdr_utils.listCustomizations
('/oracle/apps/po/document/order/webui/OrderPG');
• Result:
• /oracle/apps/po/document/order/webui/customizations/re
sponsibility/50645/OrderPG
• Then run jdr_utils.printDocument to see details
• jdr_utils.printdocument('/oracle/apps/po/document/order/
webui/customizations/responsibility/50645/OrderPG');
Tip: Using jdr_utils package
• Result of printDocument on a personalization<?xml version='1.0' encoding='UTF-8'?>
<customization xmlns="http://xmlns.oracle.com/jrad" version="9.0.6.0.0_35"
xml:lang="en-US" customizes="/oracle/apps/po/document/order/webui/OrderPG"
xmlns:user="http://xmlns.oracle.com/jrad/user"
user:responsibilityKey=“CUSTOM_RESPONSIBILITY"
user:responsibilityAppId="201">
<modifications>
<modify element="LinesRN.LinesTableRN"
controllerClass="oracle.apps.xxcus.po.document.order.webui.xxcusOrderLinesTable
RNCO"/>
<modify element="PageLayoutRN"
controllerClass="oracle.apps.xxcus.po.document.order.webui.xxcusOrderCO"/>
<modify element="HeaderRN.DetailsRN" rendered="true"/>
</modifications>
</customization>
Tip: Using jdr_utils package
• Jdr_utils can be used to see extension of view
objects, entity objects, and AM
• To see an extension on a view object, use the
printdocument procedure:
jdr_utils.printdocument('/oracle/apps/pa/structure/s
erver/customizations/site/0/CreateTasksVO');
Tip: Using jdr_utils package
• Result of displaying a view object extension
<?xml version='1.0' encoding='UTF-8'?>
<customization xmlns="http://xmlns.oracle.com/jrad"
xmlns:ui="http://xmlns.oracle.com/uix/ui"
xmlns:oa="http://xmlns.oracle.com/oa"
xmlns:user="http://xmlns.oracle.com/user" version="10.1.3_1305"
xml:lang="en-US"
customizes="/oracle/apps/pa/structure/server/CreateTasksVO">
<replace
with="/oracle/apps/xxcus/pa/structure/server/xxcusCreateTasksVO"/
>
</customization>
Tip: View Log
• View log on screen to see request parameters,
code that is running and view objects (VO’s) on
page
• Displays view object queries, VO parameter
values, and order by clauses
• Requires profile option FND:Diagnostics to be
set to Yes
• Click on Diagnostics link at top right of any page
• In next screen, select option to show log on
screen
Tip: View Log on Screen
Tip: View Log on Screen
• Select Log Level and click Go
Tip: View Log on Screen
• Log Displays below each page
Tip: Logging Custom Messages
• Use OAPageContext.writeDiagnostics method
• Can be used in controller to log messages
• Set log level and a custom identifier to easily
searchif(pageContext.isLoggingEnabled(1))
{
pageContext.writeDiagnostics(this, "xxcus Param
xxcusCatAtt: "+ xxcusCatChange, 1);
pageContext.writeDiagnostics(this, "xxcusParam
xxcusNewLineType: "+ xxcusNewLineType, 1);
}
Tip: Logging Custom Messages
• Result of custom logging on screen:
Tip: Logging Custom Messages
• For AM, VO, and EO use OADBTransaction and
writeDiagnostics method
import
oracle.apps.fnd.framework.server.OADBTransaction;
OADBTransaction oadbtransaction :=
getOADBTransaction();
if (oadbtransaction.isLoggingEnabled(1))
oadbtransaction.writeDiagnostics(this, "your message",
1);
Tip: Logging to Database
• Database logging is controlled by profile options:
• FND: Debug Log Enabled
• FND: Debug Log Level
• FND: Debug Log Module
• Writes data to table fnd_log_messages
• Can restrict messages to a particular module for
ease of troubleshooting
Tip: Migrating Personalizations
• Use Functional Administrator, Personalization,
Import/Export
• Exports to directory specified in profile option
FND: Personalization Document Root Path
• Move exported xml file to target server
• Import into target instance with Functional
Administrator
Tip: Migrating Personalizations
• Manual creation of a personalization xml file can
save time
• Example: if you have many personalizations on
a page tied to one responsibility and you need
to include them on 6 other responsibilities
• Export an xml file for the one responsibility,
manually create (through copy and paste) 5
other files for the other 5 responsibilities
changing responsibility key in each file
• Put the new files in appropriate directory
structure (based on responsibility id) and import
using Functional Administrator
Best Practices
• Naming convention:
• xxabc/oracle/apps/po/…./webui/xxabcOrderCO.java
• Exception is when using ACP (Oracle’s tool for
migration)
oracle/apps/xxabc/po/…/webui/xxabcOrderCO.java
• Root Application Module should not be extended
• AM Retention: only if next page needs
transaction information from first, or if the user
may be switching back and forth between
pages, not if 2 pages are independent
Best Practices
• View Object Performance: Use different VO’s for
different purposes, don’t use VO’s with dynamic
where clauses if possible
• View Object Classes: No need to generate View
Object Class if you have no custom code, good
to generate VORow class for performance
purposes.
• View Object Setter/Getter: use
set<AttributeName>, not setAttribute(index), for
performance reasons
Best Practices (con.)
• VO where clause and parameters should be set
in VO, not in controller
• Business Logic: put business logic in Entity
Object whenever possible, not in controller or
view object
• Avoid using JDBC calls directly, use
OADBTransaction object to connect to database
• Avoid Javascript
Reality Sets In
• Jdeveloper can be quirky
• Example of clicking Next, then Back, to be able to
update a property
• Sometimes it’s necessary to close Jdeveloper and
reopen to see latest changes
• Sometimes it’s necessary to modify files on file
system and then reopen in Jdeveloper
• Oracle does not always follow its own standards
(e.g. many examples of OAPlsqlViewRowImpl,
which is deprecated)
• Though Oracle does not encourage extending
controllers, this may be the only way to
accomplish certain changes
References
• Oracle Application Framework Personalization Guide,
Release 12
• OA Component Reference
• Oracle Applications Framework Developer’s Guide,
Release 12.1.2
• Oracle Tutorials
• C:\<JDEVinstall>\jdevdoc\index.htm (after you have
installed Jdeveloper)
• “Harnessing the Full Power of OA Framework:
Personalizations in the E-Business Suite”
• http://www.ncoaug.org/NCOAUG%20Training%20Day%20Feb%
202010/OAUG2010v3.pdf
Questions
Presenter:
Bolton Carroll
ROLTA
carrollb@tusc.comhttp://www.linkedin.com/pub/bolton-carroll/1/a87/243
www.tusc.com
http://www.roltasolutions.com/
Recommended